|
| 1 | +import { atom, useAtomValue } from "jotai"; |
| 2 | +import { store } from "../../state"; |
| 3 | +import { Rectangle } from "../dataStruct/shape/Rectangle"; |
| 4 | +import { Vector } from "../dataStruct/Vector"; |
| 5 | + |
| 6 | +export namespace SubWindow { |
| 7 | + export enum IdEnum {} |
| 8 | + export interface Window { |
| 9 | + /** |
| 10 | + * 唯一的id,不能重复,如果创建了已经存在的id,会聚焦到已存在的窗口 |
| 11 | + * 可以是负数,可以不连续 |
| 12 | + */ |
| 13 | + id: number; |
| 14 | + title: string; |
| 15 | + children: React.ReactNode; |
| 16 | + rect: Rectangle; |
| 17 | + maximized: boolean; |
| 18 | + minimized: boolean; |
| 19 | + opacity: number; |
| 20 | + focused: boolean; |
| 21 | + zIndex: number; |
| 22 | + } |
| 23 | + const subWindowsAtom = atom<Window[]>([]); |
| 24 | + export const use = () => useAtomValue(subWindowsAtom); |
| 25 | + function getMaxZIndex() { |
| 26 | + return store.get(subWindowsAtom).reduce((maxZIndex, window) => Math.max(maxZIndex, window.zIndex), 0); |
| 27 | + } |
| 28 | + export function create(options: Partial<Window>): Window { |
| 29 | + if (options.id && store.get(subWindowsAtom).some((window) => window.id === options.id)) { |
| 30 | + // 如果已经存在的id,聚焦到已存在的窗口 |
| 31 | + focus(options.id); |
| 32 | + return store.get(subWindowsAtom).find((window) => window.id === options.id)!; |
| 33 | + } |
| 34 | + const win: Window = { |
| 35 | + id: store.get(subWindowsAtom).reduce((maxId, window) => Math.max(maxId, window.id), 0) + 1, |
| 36 | + title: "", |
| 37 | + children: <></>, |
| 38 | + rect: new Rectangle(Vector.getZero(), Vector.same(100)), |
| 39 | + maximized: false, |
| 40 | + minimized: false, |
| 41 | + opacity: 1, |
| 42 | + focused: false, |
| 43 | + zIndex: getMaxZIndex() + 1, |
| 44 | + ...options, |
| 45 | + }; |
| 46 | + store.set(subWindowsAtom, [...store.get(subWindowsAtom), win]); |
| 47 | + return win; |
| 48 | + } |
| 49 | + export function update(id: number, options: Partial<Omit<Window, "id">>) { |
| 50 | + store.set( |
| 51 | + subWindowsAtom, |
| 52 | + store.get(subWindowsAtom).map((window) => (window.id === id ? { ...window, ...options } : window)), |
| 53 | + ); |
| 54 | + } |
| 55 | + export function close(id: number) { |
| 56 | + store.set( |
| 57 | + subWindowsAtom, |
| 58 | + store.get(subWindowsAtom).filter((window) => window.id !== id), |
| 59 | + ); |
| 60 | + } |
| 61 | + export function focus(id: number) { |
| 62 | + update(id, { focused: true, zIndex: getMaxZIndex() + 1 }); |
| 63 | + } |
| 64 | +} |
0 commit comments