ui/scene: lift state signals to allow external access
This commit is contained in:
@@ -38,10 +38,38 @@ function garbageCollectGroup(group: THREE.Group) {
|
|||||||
group.clear(); // Clear the group
|
group.clear(); // Clear the group
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Can be imported by others via wrappers below
|
||||||
|
// Global signal for last clicked machine
|
||||||
|
const [lastClickedMachine, setLastClickedMachine] = createSignal<string | null>(
|
||||||
|
null,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Exported so others could also emit the signal if needed
|
||||||
|
// And for testing purposes
|
||||||
|
export function emitMachineClick(id: string | null) {
|
||||||
|
setLastClickedMachine(id);
|
||||||
|
if (id) {
|
||||||
|
// Clear after a short delay to allow re-clicking the same machine
|
||||||
|
setTimeout(() => {
|
||||||
|
setLastClickedMachine(null);
|
||||||
|
}, 100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Hook for components to subscribe */
|
||||||
|
export function useMachineClick() {
|
||||||
|
return lastClickedMachine;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*Gloabl signal*/
|
||||||
|
const [worldMode, setWorldMode] = createSignal<
|
||||||
|
"default" | "select" | "service" | "create"
|
||||||
|
>("default");
|
||||||
|
export { worldMode, setWorldMode };
|
||||||
|
|
||||||
export function CubeScene(props: {
|
export function CubeScene(props: {
|
||||||
cubesQuery: MachinesQueryResult;
|
cubesQuery: MachinesQueryResult;
|
||||||
onCreate: () => Promise<{ id: string }>;
|
onCreate: () => Promise<{ id: string }>;
|
||||||
onAddService: () => Promise<{ id: string }>;
|
|
||||||
selectedIds: Accessor<Set<string>>;
|
selectedIds: Accessor<Set<string>>;
|
||||||
onSelect: (v: Set<string>) => void;
|
onSelect: (v: Set<string>) => void;
|
||||||
sceneStore: Accessor<SceneData>;
|
sceneStore: Accessor<SceneData>;
|
||||||
@@ -74,8 +102,6 @@ export function CubeScene(props: {
|
|||||||
"grid",
|
"grid",
|
||||||
);
|
);
|
||||||
|
|
||||||
const [worldMode, setWorldMode] = createSignal<"view" | "create">("view");
|
|
||||||
|
|
||||||
const [cursorPosition, setCursorPosition] = createSignal<[number, number]>();
|
const [cursorPosition, setCursorPosition] = createSignal<[number, number]>();
|
||||||
|
|
||||||
const [cameraInfo, setCameraInfo] = createSignal({
|
const [cameraInfo, setCameraInfo] = createSignal({
|
||||||
@@ -222,6 +248,7 @@ export function CubeScene(props: {
|
|||||||
controls = new MapControls(camera, renderer.domElement);
|
controls = new MapControls(camera, renderer.domElement);
|
||||||
controls.enableDamping = true; // an animation loop is required when either damping or auto-rotation are enabled
|
controls.enableDamping = true; // an animation loop is required when either damping or auto-rotation are enabled
|
||||||
controls.mouseButtons.RIGHT = null;
|
controls.mouseButtons.RIGHT = null;
|
||||||
|
// controls.rotateSpeed = -0.8;
|
||||||
// controls.enableRotate = false;
|
// controls.enableRotate = false;
|
||||||
controls.minZoom = 1.2;
|
controls.minZoom = 1.2;
|
||||||
controls.maxZoom = 3.5;
|
controls.maxZoom = 3.5;
|
||||||
@@ -370,7 +397,7 @@ export function CubeScene(props: {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Click handler:
|
// Click handler:
|
||||||
// - Select/deselects a cube in "view" mode
|
// - Select/deselects a cube in mode
|
||||||
// - Creates a new cube in "create" mode
|
// - Creates a new cube in "create" mode
|
||||||
const onClick = (event: MouseEvent) => {
|
const onClick = (event: MouseEvent) => {
|
||||||
if (worldMode() === "create") {
|
if (worldMode() === "create") {
|
||||||
@@ -391,7 +418,7 @@ export function CubeScene(props: {
|
|||||||
.finally(() => {
|
.finally(() => {
|
||||||
if (initBase) initBase.visible = false;
|
if (initBase) initBase.visible = false;
|
||||||
|
|
||||||
setWorldMode("view");
|
setWorldMode("default");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -409,8 +436,13 @@ export function CubeScene(props: {
|
|||||||
if (intersects.length > 0) {
|
if (intersects.length > 0) {
|
||||||
console.log("Clicked on cube:", intersects);
|
console.log("Clicked on cube:", intersects);
|
||||||
const id = intersects[0].object.userData.id;
|
const id = intersects[0].object.userData.id;
|
||||||
toggleSelection(id);
|
|
||||||
|
if (worldMode() === "select") toggleSelection(id);
|
||||||
|
|
||||||
|
emitMachineClick(id); // notify subscribers
|
||||||
} else {
|
} else {
|
||||||
|
emitMachineClick(null);
|
||||||
|
|
||||||
props.onSelect(new Set<string>()); // Clear selection if clicked outside cubes
|
props.onSelect(new Set<string>()); // Clear selection if clicked outside cubes
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -560,14 +592,15 @@ export function CubeScene(props: {
|
|||||||
description="Select machine"
|
description="Select machine"
|
||||||
name="Select"
|
name="Select"
|
||||||
icon="Cursor"
|
icon="Cursor"
|
||||||
onClick={() => setWorldMode("view")}
|
onClick={() =>
|
||||||
selected={worldMode() === "view"}
|
setWorldMode((v) => (v === "select" ? "default" : "select"))
|
||||||
|
}
|
||||||
|
selected={worldMode() === "select"}
|
||||||
/>
|
/>
|
||||||
<ToolbarButton
|
<ToolbarButton
|
||||||
description="Create new machine"
|
description="Create new machine"
|
||||||
name="new-machine"
|
name="new-machine"
|
||||||
icon="NewMachine"
|
icon="NewMachine"
|
||||||
disabled={positionMode() === "circle"}
|
|
||||||
onClick={onAddClick}
|
onClick={onAddClick}
|
||||||
selected={worldMode() === "create"}
|
selected={worldMode() === "create"}
|
||||||
/>
|
/>
|
||||||
@@ -576,7 +609,10 @@ export function CubeScene(props: {
|
|||||||
description="Add new Service"
|
description="Add new Service"
|
||||||
name="modules"
|
name="modules"
|
||||||
icon="Services"
|
icon="Services"
|
||||||
onClick={props.onAddService}
|
selected={worldMode() === "service"}
|
||||||
|
onClick={() => {
|
||||||
|
setWorldMode((v) => (v === "service" ? "default" : "service"));
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
<ToolbarButton
|
<ToolbarButton
|
||||||
icon="Reload"
|
icon="Reload"
|
||||||
|
|||||||
Reference in New Issue
Block a user