Skip to content

Commit 51dcba7

Browse files
committed
✨ 多窗口
1 parent 52b9717 commit 51dcba7

File tree

10 files changed

+584
-248
lines changed

10 files changed

+584
-248
lines changed

app/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
},
1818
"dependencies": {
1919
"@generouted/react-router": "^1.19.9",
20+
"@headlessui/react": "^2.2.4",
2021
"@marsidev/react-turnstile": "^1.1.0",
2122
"@msgpack/msgpack": "^3.1.2",
2223
"@octokit/rest": "^21.0.2",

app/src/core/dataStruct/shape/Rectangle.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import { Line } from "./Line";
21
import { Renderer } from "../../render/canvas2d/renderer";
32
import { Camera } from "../../stage/Camera";
43
import { Vector } from "../Vector";
4+
import { Line } from "./Line";
55
import { Shape } from "./Shape";
66

77
export class Rectangle extends Shape {
@@ -382,6 +382,10 @@ export class Rectangle extends Shape {
382382
}
383383
}
384384

385+
public translate(offset: Vector): Rectangle {
386+
return new Rectangle(this.location.add(offset), this.size);
387+
}
388+
385389
public transformWorld2View(): Rectangle {
386390
return new Rectangle(
387391
Renderer.transformWorld2View(this.location),

app/src/core/service/SubWindow.tsx

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
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+
}

app/src/index.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,10 @@
9292
--color-settings-text: var(--color-appmenu-item-text);
9393
--color-field-group-bg: var(--color-field-group-bg);
9494
--color-field-group-hover-bg: var(--color-field-group-hover-bg);
95+
--color-sub-window-bg: var(--color-sub-window-bg);
96+
--color-sub-window-text: var(--color-sub-window-text);
97+
--color-sub-window-border: var(--color-sub-window-border);
98+
--color-sub-window-shadow: var(--color-sub-window-shadow);
9599
}
96100

97101
@layer base {

0 commit comments

Comments
 (0)