diff --git a/src/core/events/WindowFormEventManager.ts b/src/core/events/WindowFormEventManager.ts index db82647..d4b144d 100644 --- a/src/core/events/WindowFormEventManager.ts +++ b/src/core/events/WindowFormEventManager.ts @@ -36,6 +36,10 @@ export interface WindowFormEvent extends IEventMap { * @param data 窗口数据 */ windowFormDataUpdate: (data: IWindowFormDataUpdateParams) => void; + /** + * 窗口创建完成 + */ + windowFormCreated: () => void; } interface IWindowFormDataUpdateParams { diff --git a/src/core/window/impl/WindowFormImpl.ts b/src/core/window/impl/WindowFormImpl.ts index 1a67d16..92b6590 100644 --- a/src/core/window/impl/WindowFormImpl.ts +++ b/src/core/window/impl/WindowFormImpl.ts @@ -4,10 +4,8 @@ import type { IProcess } from '@/core/process/IProcess.ts' import type { IWindowForm } from '@/core/window/IWindowForm.ts' import type { IWindowFormConfig } from '@/core/window/types/IWindowFormConfig.ts' import type { TWindowFormState, WindowFormPos } from '@/core/window/types/WindowFormTypes.ts' -import { processManager } from '@/core/process/ProcessManager.ts' import { DraggableResizableWindow } from '@/core/utils/DraggableResizableWindow.ts' import '../css/window-form.scss' -import { serviceManager } from '@/core/service/kernel/ServiceManager.ts' import '../ui/WindowFormElement.ts' import { wfem } from '@/core/events/WindowFormEventManager.ts' import type { IObservable } from '@/core/state/IObservable.ts' @@ -20,6 +18,8 @@ export interface IWindowFormDataState { procId: string; /** 进程名称唯一 */ name: string; + /** 窗体标题 */ + title: string; /** 窗体位置x (左上角) */ x: number; /** 窗体位置y (左上角) */ @@ -65,6 +65,7 @@ export default class WindowFormImpl implements IWindowForm { id: this.id, procId: proc.id, name: proc.processInfo.name, + title: config.title ?? '未命名', x: config.left ?? 0, y: config.top ?? 0, width: config.width ?? 200, @@ -83,106 +84,30 @@ export default class WindowFormImpl implements IWindowForm { this.closeWindowForm() this._proc.closeWindowForm(this.id) }) - - // this._data.subscribeKey(['x', 'y'], (state) => { - // console.log('x,y', state) - // }) } private createWindowFrom() { - // this.dom = this.createWindowFormEle(); - // this.dom.style.position = 'absolute'; - // this.dom.style.width = `${this.width}px`; - // this.dom.style.height = `${this.height}px`; - // this.dom.style.zIndex = '10'; - // - // const header = this.dom.querySelector('.title-bar') as HTMLElement; - // const content = this.dom.querySelector('.window-content') as HTMLElement; - // this.drw = new DraggableResizableWindow({ - // target: this.dom, - // handle: header, - // snapAnimation: true, - // snapThreshold: 20, - // boundaryElement: document.body, - // taskbarElementId: '#taskbar', - // onWindowStateChange: (state) => { - // if (state === 'maximized') { - // this.dom.style.borderRadius = '0px'; - // } else { - // this.dom.style.borderRadius = '5px'; - // } - // }, - // }) - - // this.desktopRootDom.appendChild(this.dom); const wf = document.createElement('window-form-element') wf.wid = this.id wf.wfData = this._data + wf.title = this._data.state.title wf.dragContainer = document.body wf.snapDistance = 20 wf.taskbarElementId = '#taskbar' - wf.addManagedEventListener('windowForm:stateChange:minimize', (e) => { - console.log('windowForm:stateChange:minimize', e) - }) - wf.addManagedEventListener('windowForm:stateChange:maximize', (e) => { - console.log('windowForm:stateChange:maximize', e) - }) - wf.addManagedEventListener('windowForm:stateChange:restore', (e) => { - console.log('windowForm:stateChange:restore', e) - }) - wf.addManagedEventListener('windowForm:close', () => { - // this.closeWindowForm() - }) this.dom = wf this.desktopRootDom.appendChild(this.dom) - wfem.notifyEvent('windowFormFocus', this.id) + Promise.resolve().then(() => { + wfem.notifyEvent('windowFormCreated') + wfem.notifyEvent('windowFormFocus', this.id) + }) } private closeWindowForm() { - // this.drw.destroy(); this.desktopRootDom.removeChild(this.dom) this._data.dispose() - // wfem.notifyEvent('windowFormClose', this.id) } public minimize() {} public maximize() {} public restore() {} - - private createWindowFormEle() { - const template = document.createElement('template') - template.innerHTML = ` -
-
-
我的窗口
-
-
-
-
-
×
-
-
-
-
- ` - const fragment = template.content.cloneNode(true) as DocumentFragment - const windowElement = fragment.firstElementChild as HTMLElement - - windowElement - .querySelector('.btn.minimize') - ?.addEventListener('click', () => this.drw.minimize()) - - windowElement.querySelector('.btn.maximize')?.addEventListener('click', () => { - if (this.drw.windowFormState === 'maximized') { - this.drw.restore() - } else { - this.drw.maximize() - } - }) - - windowElement - .querySelector('.btn.close') - ?.addEventListener('click', () => this.closeWindowForm()) - - return windowElement - } } diff --git a/src/core/window/ui/WindowFormElement.ts b/src/core/window/ui/WindowFormElement.ts index 4987b38..b1015ac 100644 --- a/src/core/window/ui/WindowFormElement.ts +++ b/src/core/window/ui/WindowFormElement.ts @@ -50,7 +50,7 @@ interface IElementRect { left: number; } -export interface WindowFormEventMap { +export interface WindowFormEventMap extends HTMLElementEventMap { 'windowForm:dragStart': CustomEvent; 'windowForm:dragMove': CustomEvent; 'windowForm:dragEnd': CustomEvent; @@ -87,7 +87,7 @@ export class WindowFormElement extends LitElement { @property({ type: String }) taskbarElementId?: string @property({ type: Object }) wfData: IObservable; - private _listeners: Array<{ type: string; handler: EventListener }> = [] + private _listeners: Array<{ type: string; original: Function; wrapped: EventListener }> = [] // ==== 拖拽/缩放状态(内部变量,不触发渲染) ==== private dragging = false @@ -141,22 +141,58 @@ export class WindowFormElement extends LitElement { return root } + public addManagedEventListener( + type: K, + handler: (this: WindowFormElement, ev: WindowFormEventMap[K]) => any, + options?: boolean | AddEventListenerOptions + ): void + public addManagedEventListener( + type: K, + handler: (ev: WindowFormEventMap[K]) => any, + options?: boolean | AddEventListenerOptions + ): void /** * 添加受管理的事件监听 * @param type 事件类型 * @param handler 事件处理函数 */ - public addManagedEventListener(type: string, handler: EventListener) { - this.addEventListener(type, handler) - this._listeners.push({ type, handler }) + public addManagedEventListener( + type: K, + handler: + | ((this: WindowFormElement, ev: WindowFormEventMap[K]) => any) + | ((ev: WindowFormEventMap[K]) => any), + options?: boolean | AddEventListenerOptions + ) { + const wrapped: EventListener = (ev: Event) => { + (handler as any).call(this, ev as WindowFormEventMap[K]) + } + + this.addEventListener(type, wrapped, options) + this._listeners.push({ type, original: handler, wrapped }) + } + + public removeManagedEventListener( + type: K, + handler: + | ((this: WindowFormElement, ev: WindowFormEventMap[K]) => any) + | ((ev: WindowFormEventMap[K]) => any) + ) { + const index = this._listeners.findIndex( + l => l.type === type && l.original === handler + ) + if (index !== -1) { + const { type: t, wrapped } = this._listeners[index] + this.removeEventListener(t, wrapped) + this._listeners.splice(index, 1) + } } /** * 移除所有受管理事件监听 */ public removeAllManagedListeners() { - for (const { type, handler } of this._listeners) { - this.removeEventListener(type, handler) + for (const { type, wrapped } of this._listeners) { + this.removeEventListener(type, wrapped) } this._listeners = [] } @@ -863,4 +899,6 @@ declare global { interface HTMLElementTagNameMap { 'window-form-element': WindowFormElement; } + + interface WindowFormElementEventMap extends WindowFormEventMap {} }