保存一下
This commit is contained in:
156
src/core/desktop/ui/hooks/useDesktopInit.ts
Normal file
156
src/core/desktop/ui/hooks/useDesktopInit.ts
Normal file
@@ -0,0 +1,156 @@
|
||||
import XSystem from '@/core/XSystem.ts'
|
||||
import type { IDesktopAppIcon } from '@/core/desktop/types/IDesktopAppIcon.ts'
|
||||
import {
|
||||
computed,
|
||||
nextTick,
|
||||
onMounted,
|
||||
onUnmounted,
|
||||
reactive,
|
||||
ref,
|
||||
toRaw,
|
||||
toRefs,
|
||||
toValue,
|
||||
useTemplateRef,
|
||||
watch,
|
||||
watchEffect,
|
||||
} from 'vue'
|
||||
import { DesktopEventEnum } from '@/core/events/EventTypes.ts'
|
||||
import { useDraggable } from '@vueuse/core'
|
||||
import type { IGridTemplateParams } from '@/core/desktop/types/IGridTemplateParams.ts'
|
||||
|
||||
export function useDesktopInit(containerStr: string) {
|
||||
let container:HTMLElement
|
||||
// 初始值
|
||||
const gridTemplate = reactive<IGridTemplateParams>({
|
||||
cellExpectWidth: 90,
|
||||
cellExpectHeight: 110,
|
||||
cellRealWidth: 90,
|
||||
cellRealHeight: 110,
|
||||
gapX: 4,
|
||||
gapY: 4,
|
||||
colCount: 1,
|
||||
rowCount: 1
|
||||
})
|
||||
|
||||
const ro = new ResizeObserver(entries => {
|
||||
const entry= entries[0]
|
||||
const containerRect = entry.contentRect
|
||||
gridTemplate.colCount = Math.floor((containerRect.width + gridTemplate.gapX) / (gridTemplate.cellExpectWidth + gridTemplate.gapX));
|
||||
gridTemplate.rowCount = Math.floor((containerRect.height + gridTemplate.gapY) / (gridTemplate.cellExpectHeight + gridTemplate.gapY));
|
||||
|
||||
const w = containerRect.width - (gridTemplate.gapX * (gridTemplate.colCount - 1))
|
||||
const h = containerRect.height - (gridTemplate.gapY * (gridTemplate.rowCount - 1))
|
||||
gridTemplate.cellRealWidth = Number((w / gridTemplate.colCount).toFixed(2))
|
||||
gridTemplate.cellRealHeight = Number((h / gridTemplate.rowCount).toFixed(2))
|
||||
})
|
||||
|
||||
const gridStyle = computed(() => ({
|
||||
gridTemplateColumns: `repeat(${gridTemplate.colCount}, minmax(${gridTemplate.cellExpectWidth}px, 1fr))`,
|
||||
gridTemplateRows: `repeat(${gridTemplate.rowCount}, minmax(${gridTemplate.cellExpectHeight}px, 1fr))`,
|
||||
gap: `${gridTemplate.gapX}px ${gridTemplate.gapY}px`
|
||||
}))
|
||||
|
||||
onMounted(() => {
|
||||
container = document.querySelector(containerStr)!
|
||||
ro.observe(container)
|
||||
})
|
||||
onUnmounted(() => {
|
||||
ro.unobserve(container)
|
||||
ro.disconnect()
|
||||
})
|
||||
|
||||
// 有桌面图标的app
|
||||
const appInfos = XSystem.instance.processManages.processInfos.filter(processInfo => !processInfo.isJustProcess)
|
||||
const oldAppIcons: IDesktopAppIcon[] = JSON.parse(localStorage.getItem('desktopAppIconInfo') || '[]')
|
||||
const appIcons: IDesktopAppIcon[] = appInfos.map((processInfo, index) => {
|
||||
const oldAppIcon = oldAppIcons.find(oldAppIcon => oldAppIcon.name === processInfo.name)
|
||||
|
||||
// 左上角坐标原点,从上到下从左到右 索引从1开始
|
||||
const x = Math.floor(index / gridTemplate.rowCount) + 1
|
||||
const y = index % gridTemplate.rowCount + 1
|
||||
|
||||
return {
|
||||
name: processInfo.name,
|
||||
icon: processInfo.icon,
|
||||
path: processInfo.startName,
|
||||
x: oldAppIcon ? oldAppIcon.x : x,
|
||||
y: oldAppIcon ? oldAppIcon.y : y
|
||||
}
|
||||
})
|
||||
|
||||
const appIconsRef = ref(appIcons)
|
||||
|
||||
watch(() => [gridTemplate.rowCount, gridTemplate.colCount], ([nRows, nCols], [oRows, oCols]) => {
|
||||
if (oCols == 1 && oRows == 1) return
|
||||
appIconsRef.value = rearrangeIcons(toRaw(appIconsRef.value), nCols, nRows, oCols, oRows)
|
||||
})
|
||||
|
||||
XSystem.instance.eventManages.addEventListener(DesktopEventEnum.onDesktopAppIconPos, (iconInfo) => {
|
||||
localStorage.setItem('desktopAppIconInfo', JSON.stringify(toValue(appIconsRef.value)))
|
||||
})
|
||||
|
||||
return {
|
||||
gridTemplate,
|
||||
appIconsRef,
|
||||
gridStyle
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 重新安排图标位置
|
||||
* @param appIcons 图标信息
|
||||
* @param newCols 新的列数
|
||||
* @param newRows 新的行数
|
||||
* @param oldCols 旧的列数
|
||||
* @param oldRows 旧的行数
|
||||
*/
|
||||
function rearrangeIcons(
|
||||
appIcons: IDesktopAppIcon[],
|
||||
newCols: number,
|
||||
newRows: number,
|
||||
oldCols: number,
|
||||
oldRows: number
|
||||
): IDesktopAppIcon[] {
|
||||
if (oldCols === newCols && oldRows === newRows) {
|
||||
return appIcons;
|
||||
}
|
||||
const occupied = new Set<string>();
|
||||
|
||||
function key(x: number, y: number) {
|
||||
return `${x},${y}`;
|
||||
}
|
||||
|
||||
const result: IDesktopAppIcon[] = []
|
||||
const exceed: IDesktopAppIcon[] = []
|
||||
|
||||
for (const appIcon of appIcons) {
|
||||
const { x, y } = appIcon;
|
||||
|
||||
if (x <= newCols && y <= newRows) {
|
||||
if (!occupied.has(key(x, y))) {
|
||||
occupied.add(key(x, y))
|
||||
result.push({ ...appIcon, x, y })
|
||||
}
|
||||
} else {
|
||||
exceed.push(appIcon)
|
||||
}
|
||||
}
|
||||
|
||||
for (const appIcon of exceed) {
|
||||
// 最后格子也被占 → 从 (1,1) 开始找空位
|
||||
let placed = false;
|
||||
for (let c = 1; c <= newCols; c++) {
|
||||
for (let r = 1; r <= newRows; r++) {
|
||||
if (!occupied.has(key(c, r))) {
|
||||
occupied.add(key(c, r));
|
||||
result.push({ ...appIcon, x: c, y: r });
|
||||
placed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (placed) break;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
Reference in New Issue
Block a user