UNPKG

@simple-and-crude/multi-window

Version:

Magnetic adsorbable window for HTML Application (HTA)

577 lines (576 loc) 25.1 kB
/** * |简·陋| 多窗体控制器 * @version 0.9.0 * @license GPL-3.0-or-later * @see https://github.com/simple-and-crude/multi-window */ "use strict"; var SCMultiWindow; (function (SCMultiWindow) { /**************************************************************************\ |******************************* 初始化环境 *******************************| \**************************************************************************/ var _a; /**是否使用数字传递位置。如果您的屏幕分辨率大于四位数,请改为false */ SCMultiWindow.GET_POSDATA_BY_NUMBER = true; var DialogConfig = /** @class */ (function () { function DialogConfig( /**分窗的配置 */ obj) { if (!obj) return; for (var i in obj) this[i] = obj[i]; if (!obj.dialogLeft && this.dialogLeft == "auto") this.dialogLeft = SCMultiWindow.XYpos.x + "px"; if (!obj.dialogTop && this.dialogTop == "auto") this.dialogTop = SCMultiWindow.XYpos.y + "px"; } return DialogConfig; }()); SCMultiWindow.DialogConfig = DialogConfig; /**分窗配置类原型 */ DialogConfig.prototype = { dialogHeight: "300px", dialogWidth: "300px", dialogLeft: "auto", dialogTop: "auto", unadorned: "yes", center: "no", help: "no", resizeable: "no", status: "no", scroll: "no", dialogHide: "no", edge: "raised", getFeat: function () { var attr = { getFeat: true }; var feat = []; for (var i in DialogConfig.prototype) i in attr || (attr[i] = true, feat.push(i + ":" + this[i] + ";")); for (var i in this) i in attr || feat.push(i + ":" + this[i] + ";"); return feat.join(''); } }; var SCMW_DialogElement = /** @class */ (function () { function SCMW_DialogElement( /**分窗的各属性 */ obj) { this.config = new DialogConfig(obj.config); this.id = typeof obj.id == "undefined" ? SCMultiWindow.PARENT_GLOBAL.windowList.length : obj.id; SCMultiWindow.PARENT_GLOBAL.windowList.push(null); if (obj.uri) this.uri = obj.uri; SCMultiWindow.PARENT_GLOBAL.windowList[this.id] = this.window = WIN.showModelessDialog(this.uri, [this.id, SCMultiWindow.PARENT_GLOBAL, WIN, this.name], this.config.getFeat()); } return SCMW_DialogElement; }()); SCMultiWindow.SCMW_DialogElement = SCMW_DialogElement; /**分窗元素类原型 */ SCMW_DialogElement.prototype = { id: -1, name: "subWindow", uri: "http://www.baidu.com/", window: { closed: true }, config: new DialogConfig() }; var XYPair = /** @class */ (function () { function XYPair(x, y) { typeof x === 'number' && (this.x = x); typeof y === 'number' && (this.y = y); } return XYPair; }()); SCMultiWindow.XYPair = XYPair; /**XY值对类原型 */ XYPair.prototype = { x: NaN, y: NaN, log: function () { return this.x + "," + this.y; } }; /**能够安全使用的 {@link dialogArguments} */ var diaArgs = window.dialogArguments; /**本地全局变量 */ SCMultiWindow.GLOBAL = { /**屏幕信息 */ Screen: { /**信息版本 */ changed: 0, /**屏幕大小 */ XYsiz: new XYPair(), /**任务栏信息 */ taskbar: { /**任务栏方向(横或纵) */ rule: new XYPair(), /**任务栏位置值 */ value: 0 } }, /**磁力吸附范围 */ magRange: 10, /**各分窗尺寸 */ windowSiz: ['dialogArguments' in window ? new XYPair(diaArgs[1].windowSiz[0].x, diaArgs[1].windowSiz[0].y) : new XYPair()], /**新建分窗尺寸XY值对 */ newSiz: function ( /**新建的id */ id) { SCMultiWindow.GLOBAL.windowSiz[id] = new XYPair(); }, /**各分窗位置 */ windowPos: [new XYPair()], /**分窗位置版本 */ windowChanged: [], /**分窗位置是否已被更新 */ alreadyChanged: [false], /**各分窗window对象 */ windowList: [], /**各分窗名称 */ windowName: ["mainWindow"] }; /**窗口id */ var WINDOW_ID = typeof dialogArguments !== 'undefined' ? dialogArguments[0] : 0; /**窗口名称 */ var WINDOW_NAME = typeof dialogArguments !== 'undefined' ? (_a = dialogArguments[3]) !== null && _a !== void 0 ? _a : "subWindow" : "mainWindow"; /**祖先窗口的全局变量 */ SCMultiWindow.PARENT_GLOBAL = typeof dialogArguments !== 'undefined' ? dialogArguments[1] : SCMultiWindow.GLOBAL; /**父窗口 */ SCMultiWindow.PARENT_WINDOW = typeof dialogArguments !== 'undefined' ? dialogArguments[2] : SCMultiWindow.GLOBAL.windowList[0] = window; /**祖先窗口 */ SCMultiWindow.ANCESTOR_WINDOW = typeof dialogArguments !== 'undefined' ? SCMultiWindow.PARENT_GLOBAL.windowList[0] : window; /**当前窗口window对象 */ var WIN = window; /**是否开启磁力 */ var magnetic = true; SCMultiWindow.PARENT_GLOBAL.windowPos[WINDOW_ID] = new XYPair(); SCMultiWindow.PARENT_GLOBAL.windowSiz[WINDOW_ID] = new XYPair(); /**当前窗口id */ var ID = WINDOW_ID; /**************************************************************************\ |***************************** 用户配置性函数 *****************************| \**************************************************************************/ /**初始化分窗 */ function initDialog() { /**分窗的属性 */ var dialogs = []; for ( /**分窗的属性 */ var _i = 0; /**分窗的属性 */ _i < arguments.length; /**分窗的属性 */ _i++) { /**分窗的属性 */ dialogs[_i] = arguments[_i]; } for (var i = 0; i < dialogs.length; i++) new SCMW_DialogElement(dialogs[i]); } SCMultiWindow.initDialog = initDialog; /**检测加载计时器 */ var loadTimer = void 0; /**全部加载完成 */ function allLoad() { for (var i = 1; i < SCMultiWindow.GLOBAL.windowList.length; i++) if (!SCMultiWindow.GLOBAL.windowList[i].closed) SCMultiWindow.GLOBAL.windowList[i].SCMultiWindow.copyGlobal(); SCMultiWindow.event.allLoad(); } /**加载完向主窗口报告 */ SCMultiWindow.upLoaded = ID ? SCMultiWindow.ANCESTOR_WINDOW.SCMultiWindow.upLoaded : function () { clearTimeout(loadTimer); loadTimer = setTimeout(allLoad, 200); }; /**初始化 */ function initialize() { getSiz(), getPos(), SCMultiWindow.upLoaded(); /*test*/ htano.innerText = '' + WINDOW_ID; /*test*/ htaname.innerText = WINDOW_NAME; } SCMultiWindow.initialize = initialize; /**重新获取屏幕各项参数 */ function regetScreen() { var scr = SCMultiWindow.PARENT_GLOBAL.Screen; var x = screen.availWidth; var y = screen.availHeight; var b = getBorder(new XYPair()); SCMultiWindow.PARENT_GLOBAL.Screen.changed++, scr.XYsiz.x = screen.width, scr.XYsiz.y = screen.height; scr.taskbar.value = (scr.taskbar.rule.x = Number(!(scr.taskbar.rule.y = Number(x == scr.XYsiz.x)))) ? b.x != 0 ? b.x : x : b.y != 0 ? b.y : y; } SCMultiWindow.regetScreen = regetScreen; if (!ID) regetScreen(); /**获取或重设磁力范围 */ function magneticRange( /**新的磁力范围(px),为空则不操作 */ n) { return typeof n == "undefined" ? SCMultiWindow.GLOBAL.magRange : SCMultiWindow.PARENT_GLOBAL.magRange = n; } SCMultiWindow.magneticRange = magneticRange; /**获取或重设磁力开启状态 */ function magneticStatus( /**是否开启磁力。为空则不操作 */ n) { if (typeof n == "undefined") return magnetic; if (n) updateToAll(); else for (var i = 0; i < SCMultiWindow.GLOBAL.windowList.length; i++) SCMultiWindow.GLOBAL.windowList[i].SCMultiWindow.GLOBAL.alreadyChanged[ID] = false; return magnetic = n; } SCMultiWindow.magneticStatus = magneticStatus; /**获取窗口id */ function windowID() { return WINDOW_ID; } SCMultiWindow.windowID = windowID; /**获取或重设窗口名称 */ function windowName( /**新名称,为空则不操作 */ n) { if (typeof n == "undefined") return WINDOW_NAME; for (var i = 0; i < SCMultiWindow.GLOBAL.windowList.length; i++) if (!SCMultiWindow.GLOBAL.windowList[i].closed) SCMultiWindow.GLOBAL.windowList[i].SCMultiWindow.GLOBAL.windowName[ID] = n; return WINDOW_NAME = n; } SCMultiWindow.windowName = windowName; /**需要跟随当前窗口的分窗列表 */ SCMultiWindow.dragList = {}; /**简单分窗对象 */ var subWin = { name: "", id: -1 }; // /** // * 添加需要跟随当前窗口的分窗 // * @param {...subWin} subWindows 要添加的分窗的数组,忽略为空的参数 // * @example // * //添加所有分窗 // * addDragging({}); // * // * //添加id为1的分窗,若没有则添加失败 // * addDragging({id: 1}); // * // * //添加名称为IloveU的分窗,若没有则添加失败 // * addDragging({name: "IloveU"}); // * // * //添加id为1且名称为IloveU的分窗,若没有则添加失败 // * addDragging({name: "IloveU", id: 1}); // */ // function addDragging() { // for (var param = arguments, i = 0; i < param.length; i++) { // if (typeof param[i].id == "undefined") { // if (!param[i].name) for (var j = 0; j < GLOBAL.windowList.length; j++) dragList[j] = true; // else for (var j = 0; j < GLOBAL.windowList.length; j++) if (GLOBAL.windowName[j] == param[i].name) dragList[j] = true; // } else if (!param[i].name) dragList[param[i].id] = true; // else if (GLOBAL.windowName[param[i].id] == param[i].name) dragList[param[i].id] = true; // } // } // /** // * 获取需要跟随当前窗口的分窗的数组 // * @returns {subWin[]} 分窗的数组 // */ // function getDragging() { // var list = []; // for (var i in dragList) { // list.push({ // name: GLOBAL.windowName[i], // id: Number(i) // }); // } // return list; // } // /** // * 抛弃需要跟随当前窗口的分窗 // * @param {...subWin} subWindows 要抛弃的分窗的数组,忽略为空的参数 // */ // function delDragging() { // for (var param = arguments, i = 0; i < param.length; i++) { // if (typeof param[i].id == "undefined") { // if (!param[i].name) { // dragList = {}; // return; // } // else for (var j = 0; j < GLOBAL.windowList.length; j++) if (GLOBAL.windowName[j] == param[i].name) dragList[j] = true; // } else if (!param[i].name) dragList[param[i].id] = true; // else if (GLOBAL.windowName[param[i].id] == param[i].name) dragList[param[i].id] = true; // } // } /**************************************************************************\ |*************************** 数据拷贝及上传函数 ***************************| \**************************************************************************/ /**复制窗体位置信息 */ function copyPos( /**窗体id */ id, /**窗体位置信息 */ data) { var i; if (data) delete closedList[id], i = data.indexOf(','), SCMultiWindow.GLOBAL.windowPos[id].x = Number(data.substring(0, i++)), SCMultiWindow.GLOBAL.windowPos[id].y = Number(data.substring(i, data.length)); else closedList[id] = true; } SCMultiWindow.copyPos = copyPos; // copyPos = ID ? function (id, changed) { // if (changed != -1) delete closedList[id], changed != GLOBAL.windowChanged[id] ? (GLOBAL.windowPos[id].x = PARENT_GLOBAL.windowPos[id].x, GLOBAL.windowPos[id].y = PARENT_GLOBAL.windowPos[id].y, GLOBAL.windowChanged[id] = changed) : void (0); // else closedList[id] = true; // } : function (id, changed) { // if (changed != -1) delete closedList[id], changed != GLOBAL.windowChanged[id] ? GLOBAL.windowChanged[id] = changed : void (0); // else closedList[id] = true; // }; /**刷新本地全局变量 */ function reloadGlobal( /**窗体数 */ len) { for (var i = 0; i < len; i++) if (i != ID) SCMultiWindow.GLOBAL.alreadyChanged[i] ? SCMultiWindow.GLOBAL.alreadyChanged[i] = false : SCMultiWindow.GLOBAL.windowList[i].closed ? closedList[i] = true : copyPos(i, SCMultiWindow.GLOBAL.windowList[i].SCMultiWindow.update()); } /**拷贝祖先全局变量到本地 */ function copyGlobal() { var real = SCMultiWindow.PARENT_GLOBAL; var sham = SCMultiWindow.GLOBAL; var reallen = real.windowList.length; var shamlen = sham.windowList.length; sham.magRange = real.magRange; if (sham.Screen.changed != real.Screen.changed) sham.Screen.taskbar.value = real.Screen.taskbar.value, sham.Screen.taskbar.rule.x = real.Screen.taskbar.rule.x, sham.Screen.taskbar.rule.y = real.Screen.taskbar.rule.y, sham.Screen.XYsiz.x = real.Screen.XYsiz.x, sham.Screen.XYsiz.y = real.Screen.XYsiz.y, sham.Screen.changed = real.Screen.changed; for (var i = shamlen; i < reallen; i++) { if (!sham.windowSiz[i]) sham.windowSiz[i] = new XYPair(real.windowSiz[i].x, real.windowSiz[i].y); sham.windowPos[i] = new XYPair(), sham.windowList[i] = real.windowList[i], sham.windowName[i] = real.windowName[i]; } reloadGlobal(reallen); } SCMultiWindow.copyGlobal = copyGlobal; /**已关闭的分窗列表 */ var closedList = {}; /**上一次上传的数据记录 */ var updateMem = [NaN, NaN, NaN, NaN]; // /**当前位置信息版本 */ // const updateNo; /**定时上传计时器对象 */ var updateTimer = void 0; /**鼠标是否按下 */ SCMultiWindow.bolMove = false; /**传递窗口位置信息 */ function update() { // return magnetic ? updateMem[0] == XYpos.x ? updateMem[1] == XYpos.y ? updateNo : (updateMem[1] = XYpos.y, PARENT_GLOBAL.windowPos[ID].y = XYpos.y, updateNo += 1) : (updateMem[1] == XYpos.y ? (updateMem[0] = XYpos.x, PARENT_GLOBAL.windowPos[ID].x = XYpos.x) : (updateMem[0] = XYpos.x, PARENT_GLOBAL.windowPos[ID].x = XYpos.x, updateMem[1] = XYpos.y, PARENT_GLOBAL.windowPos[ID].y = XYpos.y), updateNo += 1) : -1; return magnetic ? SCMultiWindow.XYpos.log() : false; } SCMultiWindow.update = update; function updateToAll() { for (var i = 0, data = update(); i < SCMultiWindow.GLOBAL.windowList.length; i++) if (i != ID && !closedList[i]) SCMultiWindow.GLOBAL.windowList[i].SCMultiWindow.copyPos(ID, data), SCMultiWindow.GLOBAL.windowList[i].SCMultiWindow.GLOBAL.alreadyChanged[ID] = true; } /**开启自动检测上传 */ function updateStart( /**两次上传间隔时间(ms) */ n) { update(), updateTimer = setInterval(function () { if (!SCMultiWindow.bolMove) update(); }, n); } SCMultiWindow.updateStart = updateStart; /**上传窗口尺寸 */ function updateSiz() { for (var i = 0; i < SCMultiWindow.PARENT_GLOBAL.windowList.length; i++) { if ((updateMem[3] == SCMultiWindow.XYsiz.x && updateMem[4] == SCMultiWindow.XYsiz.y) || SCMultiWindow.PARENT_GLOBAL.windowList[i].closed) continue; var shamGlobal = SCMultiWindow.PARENT_GLOBAL.windowList[i].SCMultiWindow.GLOBAL; if (!shamGlobal.windowSiz[ID]) shamGlobal.newSiz(ID); if (updateMem[3] != SCMultiWindow.XYsiz.x) shamGlobal.windowSiz[ID].x = SCMultiWindow.XYsiz.x, updateMem[3] = SCMultiWindow.XYsiz.x; if (updateMem[4] != SCMultiWindow.XYsiz.y) shamGlobal.windowSiz[ID].y = SCMultiWindow.XYsiz.y, updateMem[4] = SCMultiWindow.XYsiz.y; } } SCMultiWindow.updateSiz = updateSiz; /**************************************************************************\ |*************************** 窗口尺寸及位置相关 ***************************| \**************************************************************************/ /**窗口尺寸 */ SCMultiWindow.XYsiz = new XYPair(); /**窗口位置 */ SCMultiWindow.XYpos = new XYPair(); /**获取窗口尺寸 */ function getSiz() { return SCMultiWindow.XYsiz.x = WIN.document.body.offsetWidth, SCMultiWindow.XYsiz.y = WIN.document.body.offsetHeight, updateSiz(), SCMultiWindow.XYsiz; } SCMultiWindow.getSiz = getSiz; /**获取窗口位置 */ function getPos() { return SCMultiWindow.XYpos.x = WIN.screenLeft, SCMultiWindow.XYpos.y = WIN.screenTop, SCMultiWindow.XYpos; } SCMultiWindow.getPos = getPos; /**设置窗口尺寸 */ SCMultiWindow.setSiz = ID ? function (x, y) { WIN.dialogWidth = (SCMultiWindow.XYpos.x = x) + "px", WIN.dialogHeight = (SCMultiWindow.XYpos.y = y) + "px", updateSiz(); } : function (x, y) { vbs_resizeto(SCMultiWindow.XYsiz.x = x, SCMultiWindow.XYsiz.y = y), updateSiz(); }; /**设置窗口位置 */ SCMultiWindow.setPos = ID ? function (x, y) { WIN.dialogLeft = (SCMultiWindow.XYpos.x = x) + "px", WIN.dialogTop = (SCMultiWindow.XYpos.y = y) + "px"; } : function (x, y) { vbs_moveto(SCMultiWindow.XYpos.x = x, SCMultiWindow.XYpos.y = y); }; /**吸附的范围 */ var calcValue = 0; /**窗口需要移动的距离 */ var distList = []; /**每段距离对应的分窗id */ var nameList = []; /**用来计算的位置 */ var XYcalc = new XYPair(); /**当前正在计算的方向 */ var magSign; /**当前不在计算的方向 */ var magCosign; /**当前正在计算的分窗id */ var calcName = 0; /**已经吸附上的分窗列表 */ SCMultiWindow.engaList = {}; /**判断一个边是否在吸附范围以内 */ function magJudge( /**要判断的距离 */ dist) { if (Math.abs(dist) <= calcValue) nameList.push(calcName), distList.push(dist); } /**判断一个窗口是否在吸附范围以内 */ function magJudges( /**要判断的窗口的位置 */ pos, /**要判断的窗口的尺寸 */ siz) { magJudge(XYcalc[magSign] - pos); magJudge(XYcalc[magSign] + SCMultiWindow.XYsiz[magSign] - pos); magJudge(XYcalc[magSign] - pos - siz); magJudge(XYcalc[magSign] + SCMultiWindow.XYsiz[magSign] - pos - siz); } /**列出能够吸附上的边和对应的分窗名称 */ function magEnga() { calcName = "screen", magJudges(0, SCMultiWindow.GLOBAL.Screen.XYsiz[magSign]); if (SCMultiWindow.GLOBAL.Screen.taskbar.rule[magSign]) { calcName = "taskbar"; magJudge(XYcalc[magSign] - SCMultiWindow.GLOBAL.Screen.taskbar.value); magJudge(XYcalc[magSign] + SCMultiWindow.XYsiz[magSign] - SCMultiWindow.GLOBAL.Screen.taskbar.value); } for (calcName = 0; calcName < SCMultiWindow.GLOBAL.windowList.length; calcName++) if (calcName != ID && !closedList[calcName]) { var dmin = SCMultiWindow.GLOBAL.windowPos[calcName][magCosign], dsiz = SCMultiWindow.GLOBAL.windowSiz[calcName][magCosign], dmax = dmin + dsiz, now = SCMultiWindow.XYpos[magCosign]; if ((now == dmin) || (now < dmin && dmin <= now + SCMultiWindow.XYsiz[magCosign]) || (now > dmin && now <= dmax)) magJudges(SCMultiWindow.GLOBAL.windowPos[calcName][magSign], SCMultiWindow.GLOBAL.windowSiz[calcName][magSign]); } } /**移动窗口的一个方向 */ function magtion() { var min = Math.abs(distList[0]); var mini = 0; var t = Infinity; magEnga(); for (var i = 0; i < distList.length; t = Math.abs(distList[++i])) if (t < min) min = t, mini = i; for (var i = 0; i < distList.length; i++) if (distList[i] == distList[mini]) SCMultiWindow.engaList[nameList[i]] = true; XYcalc[magSign] -= typeof distList[0] == "undefined" ? 0 : distList[mini], distList = [], nameList = []; } /**移动窗口 */ function moveWindow( /**要移动到的横坐标 */ x, /**要移动到的纵坐标 */ y) { if (magnetic) { SCMultiWindow.engaList = {}, calcValue = SCMultiWindow.GLOBAL.magRange, XYcalc.x = x, XYcalc.y = y; magSign = 'x', magCosign = 'y', magtion(); magSign = 'y', magCosign = 'x', magtion(); x = XYcalc.x, y = XYcalc.y; } // if (!WINDOW_ID) { // GLOBAL.windowList[2].SCMultiWindow.moveWindow(x + XYsiz.x, y); // } SCMultiWindow.setPos(x, y); /*test*/ con.innerText = ""; /*test*/ for (var i in SCMultiWindow.engaList) con.innerText += i + " "; } SCMultiWindow.moveWindow = moveWindow; /**列出窗口当前正在吸附的分窗 */ function engaCalc() { copyGlobal(), SCMultiWindow.engaList = {}, XYcalc.x = SCMultiWindow.XYpos.x, XYcalc.y = SCMultiWindow.XYpos.y, calcValue = 0; magSign = 'x', magCosign = 'y', magEnga(); for (var i = 0; i < nameList.length; i++) SCMultiWindow.engaList[nameList[i]] = true; distList = [], nameList = []; magSign = 'y', magCosign = 'x', magEnga(); for (var i = 0; i < nameList.length; i++) SCMultiWindow.engaList[nameList[i]] = true; distList = [], nameList = []; /*test*/ con.innerText = ""; /*test*/ for (var i in SCMultiWindow.engaList) con.innerText += i + " "; } SCMultiWindow.engaCalc = engaCalc; /**************************************************************************\ |******************************** 事件相关 ********************************| \**************************************************************************/ /**当前的鼠标位置 */ var mouseNow = new XYPair(); /**点击时鼠标与窗口左上方的距离 */ SCMultiWindow.mouseOffset = new XYPair(); /**事件函数对象 */ SCMultiWindow.event = { /**鼠标点下 */ down: function (event) { if (SCMultiWindow.bolMove) return; event = event || window.event; SCMultiWindow.bolMove = true, SCMultiWindow.mouseOffset.x = event.clientX, SCMultiWindow.mouseOffset.y = event.clientY; if (magnetic) ID ? copyGlobal() : reloadGlobal(SCMultiWindow.GLOBAL.windowList.length); // need 让相邻窗口 copyGlobal }, /**鼠标移动 */ move: function (event) { event = event || window.event; getMouse(mouseNow, event.clientX, event.clientY); if (SCMultiWindow.bolMove) moveWindow(mouseNow.x - SCMultiWindow.mouseOffset.x, mouseNow.y - SCMultiWindow.mouseOffset.y); }, /**鼠标抬起 */ up: function () { if (!SCMultiWindow.bolMove) return; SCMultiWindow.bolMove = false; if (magnetic) updateToAll(); }, /**全部加载完成 */ allLoad: function () { } }; })(SCMultiWindow || (SCMultiWindow = {})); var SCMW_DialogElement = SCMultiWindow.SCMW_DialogElement;