diff --git a/src/core/window/impl/WindowFormImpl.ts b/src/core/window/impl/WindowFormImpl.ts index efba156..b36a9b7 100644 --- a/src/core/window/impl/WindowFormImpl.ts +++ b/src/core/window/impl/WindowFormImpl.ts @@ -80,8 +80,8 @@ export default class WindowFormImpl implements IWindowForm { const wf = document.createElement('window-form-element') wf.dragContainer = document.body wf.snapDistance = 20 - wf.addEventListener('onDragStart', (e) => { - console.log('dragstart') + wf.addEventListener('windowForm:dragStart', (e) => { + console.log('dragstart', e) }) this.desktopRootDom.appendChild(wf) } diff --git a/src/core/window/ui/WindowFormElement.ts b/src/core/window/ui/WindowFormElement.ts index 793b019..04fc0d2 100644 --- a/src/core/window/ui/WindowFormElement.ts +++ b/src/core/window/ui/WindowFormElement.ts @@ -47,6 +47,16 @@ interface IElementRect { left: number; } +export interface WindowFormEventMap { + 'windowForm:dragStart': CustomEvent; + 'windowForm:dragMove': CustomEvent; + 'windowForm:dragEnd': CustomEvent; + 'windowForm:resizeStart': CustomEvent; + 'windowForm:resizeMove': CustomEvent; + 'windowForm:resizeEnd': CustomEvent; + 'windowForm:stateChange': CustomEvent<{ state: TWindowFormState }>; +} + @customElement('window-form-element') export class WindowFormElement extends LitElement { // ==== 公共属性 ==== @@ -84,6 +94,7 @@ export class WindowFormElement extends LitElement { private width = 640; private height = 360; private animationFrame?: number; + private resizing = false; private minimized = false; private maximized = false; @@ -97,6 +108,14 @@ export class WindowFormElement extends LitElement { static override styles = css`${unsafeCSS(wfStyle)}`; + protected override createRenderRoot() { + const root = this.attachShadow({ mode: 'closed' }); + const sheet = new CSSStyleSheet(); + sheet.replaceSync(wfStyle); + root.adoptedStyleSheets = [sheet]; + return root + } + override firstUpdated() { window.addEventListener('pointerup', this.onPointerUp); window.addEventListener('pointermove', this.onPointerMove); @@ -177,7 +196,9 @@ export class WindowFormElement extends LitElement { this.resizeUp(e); } this.dragging = false; + this.resizing = false; this.resizeDir = null; + document.body.style.cursor = '' try { this.releasePointerCapture?.(e.pointerId); } catch {} }; @@ -287,6 +308,7 @@ export class WindowFormElement extends LitElement { e.preventDefault(); e.stopPropagation(); + this.resizing = true; this.resizeDir = dir; this.startX = e.clientX; this.startY = e.clientY; @@ -297,6 +319,9 @@ export class WindowFormElement extends LitElement { this.startX_host = rect.left; this.startY_host = rect.top; + const target = e.target as HTMLElement; + document.body.style.cursor = target.style.cursor || window.getComputedStyle(target).cursor; + this.setPointerCapture?.(e.pointerId); this.dispatchEvent(new CustomEvent('windowForm:resizeStart', { detail: { x: this.x, y: this.y, width: this.width, height: this.height, dir }, @@ -306,7 +331,7 @@ export class WindowFormElement extends LitElement { }; private performResize(e: PointerEvent) { - if (!this.resizeDir) return; + if (!this.resizeDir || !this.resizing) return; let newWidth = this.startWidth; let newHeight = this.startHeight; diff --git a/src/core/window/ui/wf.scss b/src/core/window/ui/wf.scss index a0b0997..f6b99ca 100644 --- a/src/core/window/ui/wf.scss +++ b/src/core/window/ui/wf.scss @@ -18,8 +18,6 @@ overflow: hidden; display: flex; flex-direction: column; - min-width: 200px; - min-height: 80px; width: 100%; height: 100%; } diff --git a/src/core/window/ui/window-form-helper.ts b/src/core/window/ui/window-form-helper.ts new file mode 100644 index 0000000..957cde9 --- /dev/null +++ b/src/core/window/ui/window-form-helper.ts @@ -0,0 +1,20 @@ +import type { WindowFormEventMap } from '@/core/window/ui/WindowFormElement.ts' + +export function addWindowFormEventListener( + el: HTMLElement, + type: K, + listener: (ev: WindowFormEventMap[K]) => any, + options?: boolean | AddEventListenerOptions +) { + // 强制类型转换,保证 TS 不报错 + el.addEventListener(type, listener as EventListener, options); +} + +export function removeWindowFormEventListener( + el: HTMLElement, + type: K, + listener: (ev: WindowFormEventMap[K]) => any, + options?: boolean | EventListenerOptions +) { + el.removeEventListener(type, listener as EventListener, options); +}