This commit is contained in:
2025-09-19 11:49:04 +08:00
parent fd4f9aa66b
commit e3ff2045ea
8 changed files with 129 additions and 34 deletions

View File

@@ -1,9 +1,5 @@
import ProcessImpl from './process/impl/ProcessImpl.ts'
import { isUndefined } from 'lodash'
import { BasicSystemProcess } from '@/core/system/BasicSystemProcess.ts' import { BasicSystemProcess } from '@/core/system/BasicSystemProcess.ts'
import { DesktopProcess } from '@/core/desktop/DesktopProcess.ts' import { DesktopProcess } from '@/core/desktop/DesktopProcess.ts'
import type { IProcess } from '@/core/process/IProcess.ts'
import type { IProcessInfo } from '@/core/process/IProcessInfo.ts'
import { ObservableWeakRefImpl } from '@/core/state/impl/ObservableWeakRefImpl.ts' import { ObservableWeakRefImpl } from '@/core/state/impl/ObservableWeakRefImpl.ts'
import type { IObservable } from '@/core/state/IObservable.ts' import type { IObservable } from '@/core/state/IObservable.ts'
import { NotificationService } from '@/core/service/services/NotificationService.ts' import { NotificationService } from '@/core/service/services/NotificationService.ts'
@@ -44,35 +40,10 @@ export default class XSystem {
public initialization(dom: HTMLDivElement) { public initialization(dom: HTMLDivElement) {
this._desktopRootDom = dom this._desktopRootDom = dom
this.run('basic-system', BasicSystemProcess).then(() => { processManager.runProcess('basic-system', BasicSystemProcess).then(() => {
this.run('desktop', DesktopProcess).then((proc) => { processManager.runProcess('desktop', DesktopProcess).then((proc) => {
proc.mount(dom) proc.mount(dom)
// console.log(dom.querySelector('.desktop-root'))
}) })
}) })
} }
// 运行进程
public async run<T extends IProcess = IProcess>(
proc: string | IProcessInfo,
constructor?: new (info: IProcessInfo) => T,
): Promise<T> {
let info = typeof proc === 'string' ? processManager.findProcessInfoByName(proc)! : proc
if (isUndefined(info)) {
throw new Error(`未找到进程信息:${proc}`)
}
// 是单例应用
if (info.singleton) {
let process = processManager.findProcessByName(info.name)
if (process) {
return process as T
}
}
// 创建进程
let process = isUndefined(constructor) ? new ProcessImpl(info) : new constructor(info)
return process as T
}
} }

View File

@@ -7,6 +7,7 @@ import { debounce } from 'lodash'
import type { IProcessInfo } from '@/core/process/IProcessInfo.ts' import type { IProcessInfo } from '@/core/process/IProcessInfo.ts'
import { eventManager } from '@/core/events/EventManager.ts' import { eventManager } from '@/core/events/EventManager.ts'
import { processManager } from '@/core/process/ProcessManager.ts' import { processManager } from '@/core/process/ProcessManager.ts'
import './ui/DesktopElement.ts'
export class DesktopProcess extends ProcessImpl { export class DesktopProcess extends ProcessImpl {
private _desktopRootDom: HTMLElement; private _desktopRootDom: HTMLElement;
@@ -91,6 +92,13 @@ export class DesktopProcess extends ProcessImpl {
app.use(naiveUi) app.use(naiveUi)
app.mount(dom) app.mount(dom)
// this.initDesktop(dom)
this._isMounted = true this._isMounted = true
} }
private initDesktop(dom: HTMLDivElement) {
const d = document.createElement('desktop-element')
dom.appendChild(d)
}
} }

View File

@@ -22,13 +22,13 @@
<script setup lang="ts"> <script setup lang="ts">
import type { DesktopProcess } from '@/core/desktop/DesktopProcess.ts' import type { DesktopProcess } from '@/core/desktop/DesktopProcess.ts'
import XSystem from '@/core/XSystem.ts'
import { notificationApi } from '@/core/common/naive-ui/discrete-api.ts' import { notificationApi } from '@/core/common/naive-ui/discrete-api.ts'
import { configProviderProps } from '@/core/common/naive-ui/theme.ts' import { configProviderProps } from '@/core/common/naive-ui/theme.ts'
import { useDesktopInit } from '@/core/desktop/ui/hooks/useDesktopInit.ts' import { useDesktopInit } from '@/core/desktop/ui/hooks/useDesktopInit.ts'
import AppIcon from '@/core/desktop/ui/components/AppIcon.vue' import AppIcon from '@/core/desktop/ui/components/AppIcon.vue'
import type { IDesktopAppIcon } from '@/core/desktop/types/IDesktopAppIcon.ts' import type { IDesktopAppIcon } from '@/core/desktop/types/IDesktopAppIcon.ts'
import { eventManager } from '@/core/events/EventManager.ts' import { eventManager } from '@/core/events/EventManager.ts'
import { processManager } from '@/core/process/ProcessManager.ts'
const props = defineProps<{ process: DesktopProcess }>() const props = defineProps<{ process: DesktopProcess }>()
@@ -50,7 +50,7 @@ const onContextMenu = (e: MouseEvent) => {
} }
const runApp = (appIcon: IDesktopAppIcon) => { const runApp = (appIcon: IDesktopAppIcon) => {
XSystem.instance.run(appIcon.name) processManager.runProcess(appIcon.name)
} }
</script> </script>

View File

@@ -0,0 +1,35 @@
import { css, html, LitElement, unsafeCSS } from 'lit'
import { customElement } from 'lit/decorators.js'
import desktopStyle from './css/desktop.scss?inline'
@customElement('desktop-element')
export class DesktopElement extends LitElement {
static override styles = css`
${unsafeCSS(desktopStyle)}
`
private onContextMenu = (e: MouseEvent) => {
e.preventDefault()
e.stopPropagation()
console.log('contextmenu')
}
override render() {
return html`
<div class="desktop-root" @contextmenu=${this.onContextMenu}>
<div class="desktop-container">
<div class="desktop-icons-container"
:style="gridStyle">
<AppIcon v-for="(appIcon, i) in appIconsRef" :key="i"
:iconInfo="appIcon" :gridTemplate="gridTemplate"
@dblclick="runApp(appIcon)"
/>
</div>
</div>
<div class="task-bar">
<div id="taskbar" class="w-[80px] h-full flex justify-center items-center bg-blue">测试</div>
</div>
</div>
`
}
}

View File

@@ -0,0 +1,17 @@
import { css, html, LitElement } from 'lit'
export class DesktopAppIconElement extends LitElement {
static override styles = css`
:host {
width: 100%;
height: 100%;
@apply flex flex-col items-center justify-center bg-gray-200;
}
`
override render() {
return html`<div class="desktop-app-icon">
<slot></slot>
</div>`
}
}

View File

@@ -0,0 +1,31 @@
*,
*::before,
*::after {
box-sizing: border-box; /* 使用更直观的盒模型 */
margin: 0;
padding: 0;
}
$taskBarHeight: 40px;
.desktop-root {
@apply w-full h-full flex flex-col;
.desktop-container {
@apply w-full h-full flex-1 p-2 pos-relative;
background-image: url("../imgs/desktop-bg-2.jpeg");
background-repeat: no-repeat;
background-size: cover;
height: calc(100% - #{$taskBarHeight});
}
.desktop-icons-container {
@apply w-full h-full flex-1 grid grid-auto-flow-col pos-relative;
}
.task-bar {
@apply w-full bg-gray-200 flex justify-center items-center;
height: $taskBarHeight;
flex-shrink: 0;
}
}

View File

@@ -1,4 +1,4 @@
import type ProcessImpl from './ProcessImpl.ts' import ProcessImpl from './ProcessImpl.ts'
import { ProcessInfoImpl } from '@/core/process/impl/ProcessInfoImpl.ts' import { ProcessInfoImpl } from '@/core/process/impl/ProcessInfoImpl.ts'
import { BasicSystemProcessInfo } from '@/core/system/BasicSystemProcessInfo.ts' import { BasicSystemProcessInfo } from '@/core/system/BasicSystemProcessInfo.ts'
import { DesktopProcessInfo } from '@/core/desktop/DesktopProcessInfo.ts' import { DesktopProcessInfo } from '@/core/desktop/DesktopProcessInfo.ts'
@@ -6,6 +6,8 @@ import type { IAppProcessInfoParams } from '@/core/process/types/IAppProcessInfo
import type { IProcessManager } from '@/core/process/IProcessManager.ts' import type { IProcessManager } from '@/core/process/IProcessManager.ts'
import type { IProcess } from '@/core/process/IProcess.ts' import type { IProcess } from '@/core/process/IProcess.ts'
import type { IProcessInfo } from '@/core/process/IProcessInfo.ts' import type { IProcessInfo } from '@/core/process/IProcessInfo.ts'
import { processManager } from '@/core/process/ProcessManager.ts'
import { isUndefined } from 'lodash'
/** /**
* 进程管理 * 进程管理
@@ -35,6 +37,29 @@ export default class ProcessManagerImpl implements IProcessManager {
this._processInfos.push(...internalProcessInfos) this._processInfos.push(...internalProcessInfos)
} }
public async runProcess<T extends IProcess = IProcess>(
proc: string | IProcessInfo,
constructor?: new (info: IProcessInfo) => T,
): Promise<T> {
let info = typeof proc === 'string' ? this.findProcessInfoByName(proc) : proc
if (isUndefined(info)) {
throw new Error(`未找到进程信息:${proc}`)
}
// 是单例应用
if (info.singleton) {
let process = this.findProcessByName(info.name)
if (process) {
return process as T
}
}
// 创建进程
let process = isUndefined(constructor) ? new ProcessImpl(info) : new constructor(info)
return process as T
}
// 添加进程 // 添加进程
public registerProcess(process: ProcessImpl) { public registerProcess(process: ProcessImpl) {
this._processPool.set(process.id, process); this._processPool.set(process.id, process);

View File

@@ -1,3 +1,11 @@
*,
*::before,
*::after {
box-sizing: border-box; /* 使用更直观的盒模型 */
margin: 0;
padding: 0;
}
:host { :host {
position: absolute; position: absolute;
top: 0; top: 0;