保存一下
This commit is contained in:
47
src/core/window/css/window-form.scss
Normal file
47
src/core/window/css/window-form.scss
Normal file
@@ -0,0 +1,47 @@
|
||||
/* 窗体容器 */
|
||||
.window {
|
||||
width: 400px;
|
||||
border: 1px solid #666;
|
||||
box-shadow: 0 0 10px rgba(0,0,0,0.5);
|
||||
background-color: #ffffff;
|
||||
overflow: hidden;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
/* 标题栏 */
|
||||
.title-bar {
|
||||
color: white;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
user-select: none;
|
||||
|
||||
.window-controls {
|
||||
display: flex;
|
||||
gap: 2px;
|
||||
flex-shrink: 0;
|
||||
|
||||
.btn {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
padding: 0;
|
||||
cursor: pointer;
|
||||
font-size: 24px;
|
||||
color: black;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
transition: background-color 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
@apply bg-gray-200;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 窗体内容 */
|
||||
.window-content {
|
||||
padding: 15px;
|
||||
background-color: #e0e0e0;
|
||||
}
|
||||
@@ -6,6 +6,7 @@ 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 { DraggableResizableWindow } from '@/core/utils/DraggableResizableWindow.ts'
|
||||
import '../css/window-form.scss'
|
||||
|
||||
export default class WindowFormImpl implements IWindowForm {
|
||||
private readonly _id: string = uuidV4();
|
||||
@@ -40,49 +41,13 @@ export default class WindowFormImpl implements IWindowForm {
|
||||
}
|
||||
|
||||
private createWindowFrom() {
|
||||
this.dom = document.createElement('div');
|
||||
this.dom = this.windowFormEle();
|
||||
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', () => {
|
||||
this.drw.minimize();
|
||||
setTimeout(() => {
|
||||
this.drw.restore();
|
||||
}, 2000)
|
||||
})
|
||||
header.appendChild(bt1)
|
||||
const bt2 = document.createElement('button');
|
||||
bt2.innerText = '最大化';
|
||||
bt2.addEventListener('click', () => {
|
||||
this.drw.maximize();
|
||||
})
|
||||
header.appendChild(bt2)
|
||||
const bt3 = document.createElement('button');
|
||||
bt3.innerText = '关闭';
|
||||
bt3.addEventListener('click', () => {
|
||||
this.closeWindowForm();
|
||||
})
|
||||
header.appendChild(bt3)
|
||||
const bt4 = document.createElement('button');
|
||||
bt4.innerText = '恢复';
|
||||
bt4.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation()
|
||||
this.drw.restore();
|
||||
})
|
||||
header.appendChild(bt4)
|
||||
|
||||
this.dom.style.zIndex = '10';
|
||||
|
||||
const header = this.dom.querySelector('.title-bar') as HTMLElement;
|
||||
this.drw = new DraggableResizableWindow({
|
||||
target: this.dom,
|
||||
handle: header,
|
||||
@@ -90,6 +55,13 @@ export default class WindowFormImpl implements IWindowForm {
|
||||
snapThreshold: 20,
|
||||
boundary: 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);
|
||||
@@ -100,4 +72,43 @@ export default class WindowFormImpl implements IWindowForm {
|
||||
this.desktopRootDom.removeChild(this.dom);
|
||||
this.proc?.event.notifyEvent('onProcessWindowFormExit', this.id)
|
||||
}
|
||||
|
||||
private windowFormEle() {
|
||||
const template = document.createElement('template');
|
||||
template.innerHTML = `
|
||||
<div class="window">
|
||||
<div class="title-bar">
|
||||
<div class="title">我的窗口</div>
|
||||
<div class="window-controls">
|
||||
<div class="minimize btn" title="最小化"">-</div>
|
||||
<div class="maximize btn" title="最大化">□</div>
|
||||
<div class="close btn" title="关闭">×</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="window-content">
|
||||
<p>这是一个纯静态的 Windows 风格窗体示例。</p>
|
||||
<p>你可以在这里放置任何内容。</p>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
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.windowState === 'maximized') {
|
||||
this.drw.restore()
|
||||
} else {
|
||||
this.drw.maximize()
|
||||
}
|
||||
});
|
||||
|
||||
windowElement.querySelector('.btn.close')
|
||||
?.addEventListener('click', () => this.closeWindowForm());
|
||||
|
||||
return windowElement
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user