wm 1.0.0, wm demo, project structure
This commit is contained in:
parent
c6c8ebb945
commit
349a9ddc0f
12 changed files with 478 additions and 1 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -7,6 +7,7 @@ yarn-debug.log*
|
||||||
yarn-error.log*
|
yarn-error.log*
|
||||||
lerna-debug.log*
|
lerna-debug.log*
|
||||||
.pnpm-debug.log*
|
.pnpm-debug.log*
|
||||||
|
pnpm-lock.yaml
|
||||||
|
|
||||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
# neofunkin
|
# neofunkin
|
||||||
|
|
||||||
[planned] Electron-based Friday Night Funkin' engine with multi-window capabilities
|
[RAW WIP] Electron-based Friday Night Funkin' engine with multi-window capabilities
|
29
package.json
Normal file
29
package.json
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
{
|
||||||
|
"name": "neofunkin-1",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"build": "tsc && node scripts/finalizeBuild.js",
|
||||||
|
"electron": "electron dist"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "AGPL-3.0-only",
|
||||||
|
"packageManager": "pnpm@10.4.1",
|
||||||
|
"dependencies": {
|
||||||
|
"electron": "^35.0.0",
|
||||||
|
"express": "^4.21.2"
|
||||||
|
},
|
||||||
|
"pnpm": {
|
||||||
|
"onlyBuiltDependencies": [
|
||||||
|
"electron"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/electron": "^1.6.12",
|
||||||
|
"@types/node": "^22.13.9",
|
||||||
|
"fs-extra": "^11.3.0",
|
||||||
|
"typescript": "^5.8.2"
|
||||||
|
}
|
||||||
|
}
|
19
scripts/finalizeBuild.js
Normal file
19
scripts/finalizeBuild.js
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
const fs = require('fs-extra');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
const srcDir = path.join(process.cwd(), 'src');
|
||||||
|
const destDir = path.join(process.cwd(), 'dist');
|
||||||
|
|
||||||
|
const copyAssets = async () => {
|
||||||
|
try {
|
||||||
|
await fs.copy(srcDir, destDir, {
|
||||||
|
filter: (file) => !file.endsWith('.ts')
|
||||||
|
});
|
||||||
|
console.log('[info] Built Neofunkin');
|
||||||
|
} catch (err) {
|
||||||
|
console.error('[error] Uh oh.');
|
||||||
|
console.error(err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
copyAssets();
|
60
src/index.ts
Normal file
60
src/index.ts
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
import wm from './lib/windowManager';
|
||||||
|
import { easeInOutQuad } from './lib/animations';
|
||||||
|
import { app } from 'electron';
|
||||||
|
|
||||||
|
app.on('ready', () => {
|
||||||
|
try {
|
||||||
|
const mw = wm.create({
|
||||||
|
w: 10,
|
||||||
|
h: 10,
|
||||||
|
whp: true,
|
||||||
|
onCreate: (win: any) => {
|
||||||
|
win.loadURL('https://example.com');
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const wait = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));
|
||||||
|
|
||||||
|
(async () => {
|
||||||
|
await wait(200);
|
||||||
|
wm.resize({ id: mw, w: 25, h: 25, smooth: true, p: true, fromCenter: true, ease: easeInOutQuad});
|
||||||
|
await wait(1000);
|
||||||
|
wm.resize({ id: mw, w: 50, h: 50, smooth: true, p: true, fromCenter: true, ease: easeInOutQuad});
|
||||||
|
await wait(650);
|
||||||
|
wm.move({ id: mw, x: 0, y: 50, p: true, fromCenter: true});
|
||||||
|
wm.resize({ id: mw, w: 33, h: 100, p: true });
|
||||||
|
wm.resize({ id: mw, w: 33, h: 10, smooth: true, p: true, ease: easeInOutQuad, anchor: 'bottom'});
|
||||||
|
await wait(500);
|
||||||
|
wm.move({ id: mw, x: 50, y: 50, p: true, fromCenter: true});
|
||||||
|
wm.resize({ id: mw, w: 33, h: 100, p: true });
|
||||||
|
wm.resize({ id: mw, w: 33, h: 10, smooth: true, p: true, ease: easeInOutQuad, anchor: 'bottom'});
|
||||||
|
await wait(500);
|
||||||
|
wm.move({ id: mw, x: 100, y: 50, p: true, fromCenter: true});
|
||||||
|
wm.resize({ id: mw, w: 33, h: 100, p: true });
|
||||||
|
wm.resize({ id: mw, w: 33, h: 10, smooth: true, p: true, ease: easeInOutQuad, anchor: 'bottom'});
|
||||||
|
await wait(500);
|
||||||
|
wm.resize({ id: mw, w: 100, h: 100, smooth: true, p: true, fromCenter: true, ease: easeInOutQuad});
|
||||||
|
await wait(550);
|
||||||
|
wm.resize({ id: mw, w: 100, h: 10, smooth: true, p: true, ease: easeInOutQuad, anchor: 'bottom'});
|
||||||
|
await wait(550);
|
||||||
|
wm.resize({ id: mw, w: 33, h: 10, smooth: true, p: true, fromCenter: true, ease: easeInOutQuad, anchor: 'bottom'});
|
||||||
|
await wait(500);
|
||||||
|
wm.move({ id: mw, x: 50, y: 50, p: true, fromCenter: true, ease: easeInOutQuad, smooth: true});
|
||||||
|
await wait(500);
|
||||||
|
wm.resize({ id: mw, w: 50, h: 50, smooth: true, p: true, fromCenter: true, ease: easeInOutQuad});
|
||||||
|
await wait(510);
|
||||||
|
wm.eval(mw, `document.querySelector('body').innerHTML = '<h1>NeoFunkin</h1>'`);
|
||||||
|
await wait(500);
|
||||||
|
wm.eval(mw, `document.querySelector('body').innerHTML = '<h1>MrpGimlom</h1>'`);
|
||||||
|
await wait(100);
|
||||||
|
wm.eval(mw, `document.querySelector('body').innerHTML = '<h1>NeoFunkin: Window manager</h1>'`);
|
||||||
|
await wait(500);
|
||||||
|
wm.eval(mw, `document.querySelector('body').innerHTML = '<h1>NeoFunkin: Window manager</h1><br>DEMO BY @TRUE1ANN, NEOFUNKIN IS PROPERTY OF ASPER'`);
|
||||||
|
await wait(1500);
|
||||||
|
wm.eval(mw, `document.querySelector('body').innerHTML = '<h1>NeoFunkin: Window manager</h1><br>DEMO BY @TRUE1ANN, NEOFUNKIN IS PROPERTY OF ASPER<br><small>this took so much to do omfg</small>'`);
|
||||||
|
})();
|
||||||
|
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
});
|
4
src/lib/animations.ts
Normal file
4
src/lib/animations.ts
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
export type EasingFunction = (t: number) => number;
|
||||||
|
export const easeInQuad: EasingFunction = (t) => t * t;
|
||||||
|
export const easeOutQuad: EasingFunction = (t) => t * (2 - t);
|
||||||
|
export const easeInOutQuad: EasingFunction = (t) => t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
|
229
src/lib/windowManager.ts
Normal file
229
src/lib/windowManager.ts
Normal file
|
@ -0,0 +1,229 @@
|
||||||
|
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 };
|
9
src/screens/crash/index.html
Normal file
9
src/screens/crash/index.html
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>NeoFunkin</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Uh oh.</h1>
|
||||||
|
</body>
|
||||||
|
</html>
|
9
src/screens/mainmenu/test.html
Normal file
9
src/screens/mainmenu/test.html
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Electron</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Hello, World!</h1>
|
||||||
|
</body>
|
||||||
|
</html>
|
60
src/types/wm.d.ts
vendored
Normal file
60
src/types/wm.d.ts
vendored
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
import { BrowserWindow } from 'electron';
|
||||||
|
|
||||||
|
export type wm_create_conf = {
|
||||||
|
w?: number; // Width
|
||||||
|
h?: number; // Height
|
||||||
|
x?: number; // X start pos
|
||||||
|
y?: number; // Y start pos
|
||||||
|
whp?: boolean; // is w and h in percentages
|
||||||
|
xyp?: boolean; // is x and y in percentages
|
||||||
|
noBorder?: boolean; // Hide OS window decorations
|
||||||
|
noBackground?: boolean; // Hide window background
|
||||||
|
onCreate?: Function; // wm.create(...)
|
||||||
|
onMinimize?: Function; // USER pressed '_'
|
||||||
|
onMaximize?: Function; // USER pressed '[]'
|
||||||
|
onRestore?: Function; // USER pressed '[]]'
|
||||||
|
onUnfocus?: Function; // USER unfocused on the window
|
||||||
|
onFocus?: Function; // USER focused on the window
|
||||||
|
onClose?: Function; // USER pressed 'x'
|
||||||
|
onDestroy?: Function; // USER pressed 'x' OR wm.destroy(...)
|
||||||
|
};
|
||||||
|
|
||||||
|
export type wm_move_conf = {
|
||||||
|
id: string; // ID of the window to perform everythin on
|
||||||
|
x?: number; // New X
|
||||||
|
y?: number; // New Y
|
||||||
|
p?: boolean; // Use percentages
|
||||||
|
fromCenter?: boolean; // Should be performed from the center of the window?
|
||||||
|
smooth?: boolean; // Should it be smooth?
|
||||||
|
ease?: Function; // Calculates the easing (lib/animations.ts)
|
||||||
|
duration?: number; // (ms) The total duration of the animation
|
||||||
|
tick?: number; // (ms) Delay between window movenments
|
||||||
|
}
|
||||||
|
|
||||||
|
export type wm_resize_conf = {
|
||||||
|
id: string; // ID of the window to perform everythin on
|
||||||
|
w?: number; // New width
|
||||||
|
h?: number; // New height
|
||||||
|
p?: boolean; // Use percentages
|
||||||
|
fromCenter?: boolean; // Should be performed from the center of the window?
|
||||||
|
smooth?: boolean; // Should it be smooth?
|
||||||
|
ease?: Function; // Calculates the easing (lib/animations.ts)
|
||||||
|
duration?: number; // (ms) The total duration of the animation
|
||||||
|
tick?: number; // (ms) Delay between window resizings
|
||||||
|
}
|
||||||
|
|
||||||
|
interface WindowData {
|
||||||
|
win: BrowserWindow;
|
||||||
|
conf: wm_create_conf;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare const wm: {
|
||||||
|
create: (c: wm_create_conf) => string;
|
||||||
|
destroy: (id: string) => Promise<void>;
|
||||||
|
move: (c: wm_move_conf) => void;
|
||||||
|
resize: (c: wm_resize_conf) => void;
|
||||||
|
eval: (id: string, code: Function) => Promise<any>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default wm;
|
||||||
|
export { WindowData, wm };
|
43
src/types/wm.ts
Normal file
43
src/types/wm.ts
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
export type wm_create_conf = {
|
||||||
|
w?: number; // Width
|
||||||
|
h?: number; // Height
|
||||||
|
x?: number; // X start pos
|
||||||
|
y?: number; // Y start pos
|
||||||
|
whp?: boolean; // is w and h in percentages
|
||||||
|
xyp?: boolean; // is x and y in percentages
|
||||||
|
noBorder?: boolean; // Hide OS window decorations
|
||||||
|
noBackground?: boolean; // Hide window background
|
||||||
|
onCreate?: Function; // wm.create(...)
|
||||||
|
onMinimize?: Function; // USER pressed '_'
|
||||||
|
onMaximize?: Function; // USER pressed '[]'
|
||||||
|
onRestore?: Function; // USER pressed '[]]'
|
||||||
|
onUnfocus?: Function; // USER unfocused on the window
|
||||||
|
onFocus?: Function; // USER focused on the window
|
||||||
|
onClose?: Function; // USER pressed 'x'
|
||||||
|
onDestroy?: Function; // USER pressed 'x' OR wm.destroy(...)
|
||||||
|
};
|
||||||
|
|
||||||
|
export type wm_move_conf = {
|
||||||
|
id: string; // ID of the window to perform everythin on
|
||||||
|
x?: number; // New X
|
||||||
|
y?: number; // New Y
|
||||||
|
p?: boolean; // Use percentages
|
||||||
|
fromCenter?: boolean; // Should be performed from the center of the window?
|
||||||
|
smooth?: boolean; // Should it be smooth?
|
||||||
|
ease?: Function; // Calculates the easing (lib/animations.ts)
|
||||||
|
duration?: number; // (ms) The total duration of the animation
|
||||||
|
tick?: number; // (ms) Delay between window movenments
|
||||||
|
}
|
||||||
|
|
||||||
|
export type wm_resize_conf = {
|
||||||
|
id: string; // ID of the window to perform everythin on
|
||||||
|
w?: number; // New width
|
||||||
|
h?: number; // New height
|
||||||
|
p?: boolean; // Use percentages
|
||||||
|
fromCenter?: boolean; // Should be performed from the center of the window?
|
||||||
|
smooth?: boolean; // Should it be smooth?
|
||||||
|
ease?: Function; // Calculates the easing (lib/animations.ts)
|
||||||
|
duration?: number; // (ms) The total duration of the animation
|
||||||
|
tick?: number; // (ms) Delay between window resizings
|
||||||
|
anchor?: string; // bottom, top, left, right
|
||||||
|
}
|
14
tsconfig.json
Normal file
14
tsconfig.json
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "es6",
|
||||||
|
"module": "commonjs",
|
||||||
|
"strict": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"outDir": "./dist",
|
||||||
|
"rootDir": "./src"
|
||||||
|
},
|
||||||
|
"include": ["src/**/*"],
|
||||||
|
"exclude": ["node_modules", "**/*.spec.ts"]
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue