From 7cbb37d54230ca7751cecad4e694a9c8e33b4c0e Mon Sep 17 00:00:00 2001 From: Azure <983547216@qq.com> Date: Tue, 9 Sep 2025 12:03:09 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=9D=E5=AD=98=E4=B8=80=E4=B8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/core/process/IProcess.ts | 3 + src/core/process/impl/ProcessImpl.ts | 18 +++++ .../{TAppProcessEvent.ts => ProcessEvent.ts} | 14 +++- src/core/window/impl/WindowFormImpl.ts | 65 ++++++++++--------- 4 files changed, 67 insertions(+), 33 deletions(-) rename src/core/process/types/{TAppProcessEvent.ts => ProcessEvent.ts} (56%) diff --git a/src/core/process/IProcess.ts b/src/core/process/IProcess.ts index 602182a..c70b8ca 100644 --- a/src/core/process/IProcess.ts +++ b/src/core/process/IProcess.ts @@ -1,5 +1,7 @@ import type { IProcessInfo } from '@/core/process/IProcessInfo.ts' import type { IWindowForm } from '@/core/window/IWindowForm.ts' +import type { IEventBuilder } from '@/core/events/IEventBuilder.ts' +import type { IProcessEvent } from '@/core/process/types/ProcessEvent.ts' /** * 进程接口 @@ -11,6 +13,7 @@ export interface IProcess { get processInfo(): IProcessInfo; /** 进程的窗体列表 */ get windowForms(): Map; + get event(): IEventBuilder; /** * 打开窗体 * @param startName 窗体启动名 diff --git a/src/core/process/impl/ProcessImpl.ts b/src/core/process/impl/ProcessImpl.ts index ce343b1..bbfe57f 100644 --- a/src/core/process/impl/ProcessImpl.ts +++ b/src/core/process/impl/ProcessImpl.ts @@ -4,6 +4,9 @@ import type { IProcess } from '@/core/process/IProcess.ts' import type { IProcessInfo } from '@/core/process/IProcessInfo.ts' import type { IWindowForm } from '@/core/window/IWindowForm.ts' import { processManager } from '@/core/process/ProcessManager.ts' +import { EventBuilderImpl } from '@/core/events/impl/EventBuilderImpl.ts' +import type { IEventBuilder } from '@/core/events/IEventBuilder.ts' +import type { IProcessEvent } from '@/core/process/types/ProcessEvent.ts' /** * 进程 @@ -13,6 +16,7 @@ export default class ProcessImpl implements IProcess { private readonly _processInfo: IProcessInfo; // 当前进程的窗体集合 private _windowForms: Map = new Map(); + private _event: IEventBuilder = new EventBuilderImpl() public get id() { return this._id; @@ -23,6 +27,9 @@ export default class ProcessImpl implements IProcess { public get windowForms() { return this._windowForms; } + public get event() { + return this._event; + } constructor(info: IProcessInfo) { console.log(`AppProcess: ${info.name}`) @@ -30,6 +37,8 @@ export default class ProcessImpl implements IProcess { const startName = info.startName; + this.initEvent(); + processManager.registerProcess(this); // 通过设置 isJustProcess 为 true,则不会创建窗体 if (!info.isJustProcess) { @@ -37,6 +46,15 @@ export default class ProcessImpl implements IProcess { } } + private initEvent() { + this.event.addEventListener('onProcessWindowFormExit', (id: string) => { + this.windowForms.delete(id) + if(this.windowForms.size === 0) { + processManager.removeProcess(this) + } + }) + } + public openWindowForm(startName: string) { const info = this._processInfo.windowFormConfigs.find(item => item.name === startName); if (!info) throw new Error(`未找到窗体:${startName}`); diff --git a/src/core/process/types/TAppProcessEvent.ts b/src/core/process/types/ProcessEvent.ts similarity index 56% rename from src/core/process/types/TAppProcessEvent.ts rename to src/core/process/types/ProcessEvent.ts index b0254fc..d6bb3b5 100644 --- a/src/core/process/types/TAppProcessEvent.ts +++ b/src/core/process/types/ProcessEvent.ts @@ -1,3 +1,5 @@ +import type { IEventMap } from '@/core/events/IEventBuilder.ts' + /** * 进程的事件 *

onProcessExit - 进程退出

@@ -6,9 +8,17 @@ *

onProcessWindowFormFocus - 进程的窗体获取焦点

* */ -type TAppProcessEvent = +type TProcessEvent = 'onProcessExit' | 'onProcessWindowFormOpen' | 'onProcessWindowFormExit' | 'onProcessWindowFormFocus' | - 'onProcessWindowFormBlur' \ No newline at end of file + 'onProcessWindowFormBlur' + +export interface IProcessEvent extends IEventMap { + /** + * 进程的窗体退出 + * @param id 窗体id + */ + onProcessWindowFormExit: (id: string) => void +} \ No newline at end of file diff --git a/src/core/window/impl/WindowFormImpl.ts b/src/core/window/impl/WindowFormImpl.ts index c15028d..3e1fdcf 100644 --- a/src/core/window/impl/WindowFormImpl.ts +++ b/src/core/window/impl/WindowFormImpl.ts @@ -5,12 +5,13 @@ import type { IWindowForm } from '@/core/window/IWindowForm.ts' import type { IWindowFormConfig } from '@/core/window/types/IWindowFormConfig.ts' import type { WindowFormPos } from '@/core/window/types/WindowFormTypes.ts' import { processManager } from '@/core/process/ProcessManager.ts' -import { DraggableResizable } from '@/core/utils/DraggableResizable.ts' import { DraggableResizableWindow } from '@/core/utils/DraggableResizableWindow.ts' export default class WindowFormImpl implements IWindowForm { private readonly _id: string = uuidV4(); private readonly _procId: string; + private dom: HTMLElement; + private drw: DraggableResizableWindow; private pos: WindowFormPos = { x: 0, y: 0 }; private width: number = 0; private height: number = 0; @@ -38,63 +39,65 @@ export default class WindowFormImpl implements IWindowForm { this.createWindowFrom(); } - public createWindowFrom() { - const dom = document.createElement('div'); - dom.style.position = 'absolute'; - dom.style.left = `${this.pos.x}px`; - dom.style.top = `${this.pos.y}px`; - dom.style.width = `${this.width}px`; - dom.style.height = `${this.height}px`; - dom.style.zIndex = '100'; - dom.style.backgroundColor = 'white'; - const div = document.createElement('div'); - div.style.width = '100%'; - div.style.height = '20px'; - div.style.backgroundColor = 'red'; - dom.appendChild(div) + private createWindowFrom() { + this.dom = document.createElement('div'); + this.dom.style.position = 'absolute'; + this.dom.style.width = `${this.width}px`; + this.dom.style.height = `${this.height}px`; + this.dom.style.zIndex = '100'; + this.dom.style.backgroundColor = 'white'; + this.dom.classList.add('flex', 'flex-col', 'rd-[4px]') + const header = document.createElement('div'); + header.style.width = '100%'; + header.style.height = '20px'; + header.style.backgroundColor = 'red'; + this.dom.appendChild(header) const bt1 = document.createElement('button'); bt1.innerText = '最小化'; bt1.addEventListener('click', () => { - win.minimize(); + this.drw.minimize(); setTimeout(() => { - win.restore(); + this.drw.restore(); }, 2000) }) - div.appendChild(bt1) + header.appendChild(bt1) const bt2 = document.createElement('button'); bt2.innerText = '最大化'; bt2.addEventListener('click', () => { - win.maximize(); + this.drw.maximize(); }) - div.appendChild(bt2) + header.appendChild(bt2) const bt3 = document.createElement('button'); bt3.innerText = '关闭'; bt3.addEventListener('click', () => { - this.desktopRootDom.removeChild(dom) - win.destroy(); - this.proc?.windowForms.delete(this.id); - processManager.removeProcess(this.proc!) + this.closeWindowForm(); }) - div.appendChild(bt3) + header.appendChild(bt3) const bt4 = document.createElement('button'); bt4.innerText = '恢复'; bt4.addEventListener('click', (e) => { e.preventDefault(); e.stopPropagation() - win.restore(); + this.drw.restore(); }) - div.appendChild(bt4) + header.appendChild(bt4) - const win = new DraggableResizableWindow({ - target: dom, - handle: div, + this.drw = new DraggableResizableWindow({ + target: this.dom, + handle: header, snapAnimation: true, snapThreshold: 20, boundary: document.body, taskbarElementId: '#taskbar', }) - this.desktopRootDom.appendChild(dom); + this.desktopRootDom.appendChild(this.dom); + } + + private closeWindowForm() { + this.drw.destroy(); + this.desktopRootDom.removeChild(this.dom); + this.proc?.event.notifyEvent('onProcessWindowFormExit', this.id) } }