229 lines
No EOL
7 KiB
TypeScript
229 lines
No EOL
7 KiB
TypeScript
import { BrowserWindow, screen } from 'electron';
|
|
import { wm_create_conf, wm_move_conf, wm_resize_conf } from './../types/wm';
|
|
|
|
interface WindowData {
|
|
win: BrowserWindow;
|
|
conf: wm_create_conf;
|
|
}
|
|
|
|
let wdata: { [key: string]: WindowData } = {};
|
|
|
|
function toP(value: number, percentage: number) {
|
|
return value * (percentage / 100) as number;
|
|
}
|
|
|
|
const wm = {
|
|
create: function (c: wm_create_conf) {
|
|
const wid = Array.from({ length: 8 }, () => '0123456789abcdef'[Math.floor(Math.random() * 16)]).join('');
|
|
const { width: sw, height: sh } = screen.getPrimaryDisplay().bounds;
|
|
console.log('[wm] create', wid);
|
|
const win = new BrowserWindow({
|
|
width: c.whp ? toP(sw, c.w!) : c.w,
|
|
height: c.whp ? toP(sh, c.h!) : c.h,
|
|
x: c.xyp ? toP(sw, c.x!) : c.x,
|
|
y: c.xyp ? toP(sh, c.y!) : c.x,
|
|
frame: !c.noBorder,
|
|
transparent: c.noBackground,
|
|
webPreferences: {
|
|
nodeIntegration: true,
|
|
contextIsolation: false,
|
|
},
|
|
});
|
|
|
|
wdata[wid] = { win: win, conf: c }; // for further pullin
|
|
win.setMenuBarVisibility(false); // tell me WHY should i NOT make this the default
|
|
|
|
if (typeof c.onMinimize === 'function') win.on('minimize', () => c.onMinimize!(win));
|
|
if (typeof c.onMaximize === 'function') win.on('maximize', () => c.onMaximize!(win));
|
|
if (typeof c.onRestore === 'function') win.on('restore', () => c.onRestore!(win));
|
|
if (typeof c.onFocus === 'function') win.on('focus', () => c.onFocus!(win));
|
|
if (typeof c.onUnfocus === 'function') win.on('blur', () => c.onUnfocus!(win));
|
|
if (typeof c.onClose === 'function') win.on('close', () => c.onClose!(win));
|
|
|
|
if (c.onCreate) c.onCreate(win);
|
|
return wid // just so you can reference it later on
|
|
},
|
|
destroy: async function (id: number) {
|
|
console.log('[wm] destroy', id);
|
|
const win = wdata[id];
|
|
if (typeof win.conf.onDestroy === 'function') await win.conf.onDestroy!(win.win);
|
|
win.win.destroy();
|
|
delete wdata[id];
|
|
},
|
|
move: function (c: wm_move_conf) {
|
|
console.log('[wm] move', c.id);
|
|
const win = wdata[c.id];
|
|
const { width: sw, height: sh } = screen.getPrimaryDisplay().bounds;
|
|
let wb = win.win.getBounds();
|
|
|
|
const sX = wb.x;
|
|
const sY = wb.y;
|
|
c.x = c.x === undefined ? sX : c.x;
|
|
c.y = c.y === undefined ? sY : c.y;
|
|
|
|
const duration = c.duration || 500;
|
|
const tick = c.tick || 16;
|
|
const totalSteps = Math.floor(duration / tick);
|
|
|
|
let targetX = toP(c.p ? sw : 1, c.x);
|
|
let targetY = toP(c.p ? sh : 1, c.y);
|
|
|
|
if (c.fromCenter) {
|
|
wb = win.win.getBounds();
|
|
targetX = targetX - wb.width * 0.5;
|
|
targetY = targetY - wb.height * 0.5;
|
|
}
|
|
|
|
const animate = () => {
|
|
let currentStep = 0;
|
|
const startX = sX;
|
|
const startY = sY;
|
|
|
|
const step = () => {
|
|
currentStep++;
|
|
const t = currentStep / totalSteps;
|
|
const eT = c.ease ? c.ease(t) : t;
|
|
|
|
const newX = startX + (targetX - startX) * eT;
|
|
const newY = startY + (targetY - startY) * eT;
|
|
|
|
win.win.setPosition(Math.round(newX), Math.round(newY));
|
|
|
|
if (currentStep < totalSteps) {
|
|
setTimeout(step, tick);
|
|
} else {
|
|
win.win.setPosition(Math.round(targetX), Math.round(targetY));
|
|
}
|
|
};
|
|
|
|
step();
|
|
};
|
|
|
|
if (c.smooth) {
|
|
animate();
|
|
} else {
|
|
win.win.setPosition(Math.round(targetX), Math.round(targetY));
|
|
}
|
|
},
|
|
resize: function (c: wm_resize_conf) {
|
|
console.log('[wm] resize', c.id);
|
|
const win = wdata[c.id];
|
|
let wb = win.win.getBounds();
|
|
const sW = wb.width, sH = wb.height;
|
|
c.w = c.w === undefined ? sW : c.w;
|
|
c.h = c.h === undefined ? sH : c.h;
|
|
const duration = c.duration || 500;
|
|
const tick = c.tick || 16;
|
|
const totalSteps = Math.floor(duration / tick);
|
|
const { width: sw, height: sh } = screen.getPrimaryDisplay().bounds;
|
|
let targetW = toP(c.p ? sw : 1, c.w);
|
|
let targetH = toP(c.p ? sh : 1, c.h);
|
|
const centerX = wb.x + wb.width / 2;
|
|
const centerY = wb.y + wb.height / 2;
|
|
const getAnchoredPosition = (curWidth: number, curHeight: number) => {
|
|
let newX = wb.x;
|
|
let newY = wb.y;
|
|
if (!c.fromCenter && c.anchor) {
|
|
switch (c.anchor) {
|
|
case 'top':
|
|
newX = wb.x;
|
|
newY = wb.y;
|
|
break;
|
|
case 'bottom':
|
|
newX = wb.x;
|
|
newY = wb.y + wb.height - curHeight;
|
|
break;
|
|
case 'left':
|
|
newX = wb.x;
|
|
newY = wb.y;
|
|
break;
|
|
case 'right':
|
|
newX = wb.x + wb.width - curWidth;
|
|
newY = wb.y;
|
|
break;
|
|
default:
|
|
newX = wb.x;
|
|
newY = wb.y;
|
|
}
|
|
}
|
|
return { newX, newY };
|
|
};
|
|
const animate = () => {
|
|
let currentStep = 0;
|
|
const startW = wb.width;
|
|
const startH = wb.height;
|
|
const step = () => {
|
|
currentStep++;
|
|
const t = currentStep / totalSteps;
|
|
const eT = c.ease ? c.ease(t) : t;
|
|
const newW = startW + (targetW - startW) * eT;
|
|
const newH = startH + (targetH - startH) * eT;
|
|
let newX: number, newY: number;
|
|
if (c.fromCenter) {
|
|
newX = Math.round(centerX - newW / 2);
|
|
newY = Math.round(centerY - newH / 2);
|
|
} else {
|
|
const pos = getAnchoredPosition(Math.round(newW), Math.round(newH));
|
|
newX = pos.newX;
|
|
newY = pos.newY;
|
|
}
|
|
win.win.setBounds({
|
|
x: newX,
|
|
y: newY,
|
|
width: Math.round(newW),
|
|
height: Math.round(newH)
|
|
});
|
|
if (currentStep < totalSteps) {
|
|
setTimeout(step, tick);
|
|
} else {
|
|
let finalX: number, finalY: number;
|
|
if (c.fromCenter) {
|
|
finalX = Math.round(centerX - targetW / 2);
|
|
finalY = Math.round(centerY - targetH / 2);
|
|
} else {
|
|
const pos = getAnchoredPosition(Math.round(targetW), Math.round(targetH));
|
|
finalX = pos.newX;
|
|
finalY = pos.newY;
|
|
}
|
|
win.win.setBounds({
|
|
x: finalX,
|
|
y: finalY,
|
|
width: Math.round(targetW),
|
|
height: Math.round(targetH)
|
|
});
|
|
}
|
|
};
|
|
step();
|
|
};
|
|
if (c.smooth) {
|
|
animate();
|
|
} else {
|
|
let finalX: number, finalY: number;
|
|
if (c.fromCenter) {
|
|
finalX = Math.round(centerX - targetW / 2);
|
|
finalY = Math.round(centerY - targetH / 2);
|
|
} else {
|
|
const pos = getAnchoredPosition(Math.round(targetW), Math.round(targetH));
|
|
finalX = pos.newX;
|
|
finalY = pos.newY;
|
|
}
|
|
win.win.setBounds({
|
|
x: finalX,
|
|
y: finalY,
|
|
width: Math.round(targetW),
|
|
height: Math.round(targetH)
|
|
});
|
|
}
|
|
},
|
|
eval: async function (id: string, code: string) {
|
|
console.log('[wm] eval', id);
|
|
try {
|
|
return await wdata[id].win.webContents.executeJavaScript(code);
|
|
} catch (error) {
|
|
console.error('Error executing JavaScript:', error);
|
|
}
|
|
}
|
|
};
|
|
|
|
export default wm;
|
|
export { wdata, wm }; |