WindowFormElement
This commit is contained in:
@@ -80,8 +80,8 @@ export default class WindowFormImpl implements IWindowForm {
|
|||||||
const wf = document.createElement('window-form-element')
|
const wf = document.createElement('window-form-element')
|
||||||
wf.dragContainer = document.body
|
wf.dragContainer = document.body
|
||||||
wf.snapDistance = 20
|
wf.snapDistance = 20
|
||||||
wf.addEventListener('onDragStart', (e) => {
|
wf.addEventListener('windowForm:dragStart', (e) => {
|
||||||
console.log('dragstart')
|
console.log('dragstart', e)
|
||||||
})
|
})
|
||||||
this.desktopRootDom.appendChild(wf)
|
this.desktopRootDom.appendChild(wf)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,6 +47,16 @@ interface IElementRect {
|
|||||||
left: number;
|
left: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface WindowFormEventMap {
|
||||||
|
'windowForm:dragStart': CustomEvent<TDragStartCallback>;
|
||||||
|
'windowForm:dragMove': CustomEvent<TDragMoveCallback>;
|
||||||
|
'windowForm:dragEnd': CustomEvent<TDragEndCallback>;
|
||||||
|
'windowForm:resizeStart': CustomEvent<IResizeCallbackData>;
|
||||||
|
'windowForm:resizeMove': CustomEvent<IResizeCallbackData>;
|
||||||
|
'windowForm:resizeEnd': CustomEvent<IResizeCallbackData>;
|
||||||
|
'windowForm:stateChange': CustomEvent<{ state: TWindowFormState }>;
|
||||||
|
}
|
||||||
|
|
||||||
@customElement('window-form-element')
|
@customElement('window-form-element')
|
||||||
export class WindowFormElement extends LitElement {
|
export class WindowFormElement extends LitElement {
|
||||||
// ==== 公共属性 ====
|
// ==== 公共属性 ====
|
||||||
@@ -84,6 +94,7 @@ export class WindowFormElement extends LitElement {
|
|||||||
private width = 640;
|
private width = 640;
|
||||||
private height = 360;
|
private height = 360;
|
||||||
private animationFrame?: number;
|
private animationFrame?: number;
|
||||||
|
private resizing = false;
|
||||||
|
|
||||||
private minimized = false;
|
private minimized = false;
|
||||||
private maximized = false;
|
private maximized = false;
|
||||||
@@ -97,6 +108,14 @@ export class WindowFormElement extends LitElement {
|
|||||||
|
|
||||||
static override styles = css`${unsafeCSS(wfStyle)}`;
|
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() {
|
override firstUpdated() {
|
||||||
window.addEventListener('pointerup', this.onPointerUp);
|
window.addEventListener('pointerup', this.onPointerUp);
|
||||||
window.addEventListener('pointermove', this.onPointerMove);
|
window.addEventListener('pointermove', this.onPointerMove);
|
||||||
@@ -177,7 +196,9 @@ export class WindowFormElement extends LitElement {
|
|||||||
this.resizeUp(e);
|
this.resizeUp(e);
|
||||||
}
|
}
|
||||||
this.dragging = false;
|
this.dragging = false;
|
||||||
|
this.resizing = false;
|
||||||
this.resizeDir = null;
|
this.resizeDir = null;
|
||||||
|
document.body.style.cursor = ''
|
||||||
try { this.releasePointerCapture?.(e.pointerId); } catch {}
|
try { this.releasePointerCapture?.(e.pointerId); } catch {}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -287,6 +308,7 @@ export class WindowFormElement extends LitElement {
|
|||||||
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
this.resizing = true;
|
||||||
this.resizeDir = dir;
|
this.resizeDir = dir;
|
||||||
this.startX = e.clientX;
|
this.startX = e.clientX;
|
||||||
this.startY = e.clientY;
|
this.startY = e.clientY;
|
||||||
@@ -297,6 +319,9 @@ export class WindowFormElement extends LitElement {
|
|||||||
this.startX_host = rect.left;
|
this.startX_host = rect.left;
|
||||||
this.startY_host = rect.top;
|
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.setPointerCapture?.(e.pointerId);
|
||||||
this.dispatchEvent(new CustomEvent('windowForm:resizeStart', {
|
this.dispatchEvent(new CustomEvent('windowForm:resizeStart', {
|
||||||
detail: { x: this.x, y: this.y, width: this.width, height: this.height, dir },
|
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) {
|
private performResize(e: PointerEvent) {
|
||||||
if (!this.resizeDir) return;
|
if (!this.resizeDir || !this.resizing) return;
|
||||||
|
|
||||||
let newWidth = this.startWidth;
|
let newWidth = this.startWidth;
|
||||||
let newHeight = this.startHeight;
|
let newHeight = this.startHeight;
|
||||||
|
|||||||
@@ -18,8 +18,6 @@
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
min-width: 200px;
|
|
||||||
min-height: 80px;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|||||||
20
src/core/window/ui/window-form-helper.ts
Normal file
20
src/core/window/ui/window-form-helper.ts
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
import type { WindowFormEventMap } from '@/core/window/ui/WindowFormElement.ts'
|
||||||
|
|
||||||
|
export function addWindowFormEventListener<K extends keyof WindowFormEventMap>(
|
||||||
|
el: HTMLElement,
|
||||||
|
type: K,
|
||||||
|
listener: (ev: WindowFormEventMap[K]) => any,
|
||||||
|
options?: boolean | AddEventListenerOptions
|
||||||
|
) {
|
||||||
|
// 强制类型转换,保证 TS 不报错
|
||||||
|
el.addEventListener(type, listener as EventListener, options);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function removeWindowFormEventListener<K extends keyof WindowFormEventMap>(
|
||||||
|
el: HTMLElement,
|
||||||
|
type: K,
|
||||||
|
listener: (ev: WindowFormEventMap[K]) => any,
|
||||||
|
options?: boolean | EventListenerOptions
|
||||||
|
) {
|
||||||
|
el.removeEventListener(type, listener as EventListener, options);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user