2020-05-22 10:25:19 +02:00
|
|
|
import {BrowserWindow, BrowserWindowConstructorOptions, ipcMain, IpcMainEvent} from "electron";
|
|
|
|
import Application from "./Application";
|
|
|
|
import Config from "./Config";
|
|
|
|
|
|
|
|
export default abstract class Window {
|
2020-09-29 20:43:41 +02:00
|
|
|
private readonly listeners: {
|
|
|
|
[channel: string]: ((event: IpcMainEvent, ...args: unknown[]) => void)[] | undefined
|
|
|
|
} = {};
|
2020-05-22 10:25:19 +02:00
|
|
|
private readonly onCloseListeners: (() => void)[] = [];
|
|
|
|
|
|
|
|
protected readonly application: Application;
|
|
|
|
protected readonly config: Config;
|
|
|
|
protected readonly parent?: Window;
|
|
|
|
protected window?: BrowserWindow;
|
|
|
|
|
|
|
|
protected constructor(application: Application, parent?: Window) {
|
|
|
|
this.application = application;
|
|
|
|
this.parent = parent;
|
|
|
|
this.config = this.application.getConfig();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2020-09-29 20:43:41 +02:00
|
|
|
public setup(options: BrowserWindowConstructorOptions): void {
|
2020-05-22 10:25:19 +02:00
|
|
|
console.log('Creating window', this.constructor.name);
|
|
|
|
|
|
|
|
if (this.parent) {
|
|
|
|
options.parent = this.parent.getWindow();
|
|
|
|
}
|
|
|
|
|
|
|
|
this.window = new BrowserWindow(options);
|
|
|
|
this.window.on('close', () => {
|
|
|
|
this.teardown();
|
|
|
|
this.window = undefined;
|
|
|
|
});
|
2021-03-06 18:43:45 +01:00
|
|
|
|
|
|
|
this.onIpc('close-window', (
|
|
|
|
event,
|
|
|
|
constructorName: string,
|
|
|
|
) => {
|
|
|
|
if (constructorName === this.constructor.name) {
|
|
|
|
console.log('Closing', this.constructor.name);
|
|
|
|
const window = this.getWindow();
|
|
|
|
if (window.closable) {
|
|
|
|
window.close();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
2020-05-22 10:25:19 +02:00
|
|
|
}
|
|
|
|
|
2020-09-29 20:43:41 +02:00
|
|
|
public teardown(): void {
|
2020-05-22 10:25:19 +02:00
|
|
|
console.log('Tearing down window', this.constructor.name);
|
|
|
|
|
|
|
|
for (const listener of this.onCloseListeners) {
|
|
|
|
listener();
|
|
|
|
}
|
|
|
|
|
|
|
|
for (const channel in this.listeners) {
|
2020-09-29 20:43:41 +02:00
|
|
|
const listeners = this.listeners[channel];
|
|
|
|
if (!listeners) continue;
|
|
|
|
|
|
|
|
for (const listener of listeners) {
|
2020-05-22 10:25:19 +02:00
|
|
|
ipcMain.removeListener(channel, listener);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
this.window = undefined;
|
|
|
|
}
|
|
|
|
|
2020-09-29 20:43:41 +02:00
|
|
|
// This is the spec of ipcMain.on()
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
2020-05-22 10:25:19 +02:00
|
|
|
protected onIpc(channel: string, listener: (event: IpcMainEvent, ...args: any[]) => void): this {
|
|
|
|
ipcMain.on(channel, listener);
|
|
|
|
if (!this.listeners[channel]) this.listeners[channel] = [];
|
2020-09-29 20:43:41 +02:00
|
|
|
this.listeners[channel]?.push(listener);
|
2020-05-22 10:25:19 +02:00
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
2020-09-29 20:43:41 +02:00
|
|
|
public onClose(listener: () => void): void {
|
2020-05-22 10:25:19 +02:00
|
|
|
this.onCloseListeners.push(listener);
|
|
|
|
}
|
|
|
|
|
2020-09-29 20:43:41 +02:00
|
|
|
public toggle(): void {
|
2020-05-22 10:25:19 +02:00
|
|
|
if (this.window) {
|
|
|
|
if (!this.window.isFocused()) {
|
|
|
|
console.log('Showing window', this.constructor.name);
|
|
|
|
this.window.show();
|
|
|
|
} else {
|
|
|
|
console.log('Hiding window', this.constructor.name);
|
|
|
|
this.window.hide();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public getWindow(): BrowserWindow {
|
|
|
|
if (!this.window) throw Error('Window not initialized.');
|
2021-03-06 18:43:45 +01:00
|
|
|
else if (this.window.isDestroyed()) throw Error('Window destroyed.');
|
2020-05-22 10:25:19 +02:00
|
|
|
return this.window;
|
|
|
|
}
|
2020-09-29 20:43:41 +02:00
|
|
|
}
|