hover / selection manager
This commit is contained in:
@@ -1,28 +1,123 @@
|
||||
import {
|
||||
type BuildingNode,
|
||||
emitter,
|
||||
type GridEvent,
|
||||
type ItemEvent,
|
||||
type ItemNode,
|
||||
sceneRegistry,
|
||||
useScene,
|
||||
type WallEvent,
|
||||
type WallNode,
|
||||
} from "@pascal-app/core";
|
||||
import { useViewer } from "@pascal-app/viewer";
|
||||
|
||||
import { useEffect, useRef } from "react";
|
||||
import useEditor from "@/store/use-editor";
|
||||
|
||||
export const SelectionManager = () => {
|
||||
const selectedItemId = useRef<ItemNode["id"] | WallNode["id"]>(null);
|
||||
const itemSelectedAt = useRef<number>(0);
|
||||
const phase = useEditor((state) => state.phase);
|
||||
const mode = useEditor((state) => state.mode);
|
||||
useEffect(() => {
|
||||
emitter.on("building:enter", (event) => {
|
||||
// console.log("Entered building:", event.node.id);
|
||||
const itemMesh = sceneRegistry.nodes.get(event.node.id);
|
||||
useViewer.getState().outliner.hoveredObjects.length = 0;
|
||||
useViewer.getState().outliner.hoveredObjects.push(itemMesh);
|
||||
});
|
||||
emitter.on("building:leave", (event) => {
|
||||
// console.log("Leaving building:", event.node.id);
|
||||
useViewer.getState().outliner.hoveredObjects.length = 0;
|
||||
});
|
||||
if (mode !== "select") {
|
||||
return;
|
||||
}
|
||||
|
||||
if (phase === "site") {
|
||||
const onBuildingEnter = (event: { node: BuildingNode }) => {
|
||||
const itemMesh = sceneRegistry.nodes.get(event.node.id);
|
||||
useViewer.getState().outliner.hoveredObjects.length = 0;
|
||||
useViewer.getState().outliner.hoveredObjects.push(itemMesh);
|
||||
};
|
||||
const onBuildingLeave = (event: { node: BuildingNode }) => {
|
||||
useViewer.getState().outliner.hoveredObjects.length = 0;
|
||||
};
|
||||
emitter.on("building:enter", onBuildingEnter);
|
||||
emitter.on("building:leave", onBuildingLeave);
|
||||
return () => {
|
||||
emitter.off("building:enter", onBuildingEnter);
|
||||
emitter.off("building:leave", onBuildingLeave);
|
||||
};
|
||||
}
|
||||
|
||||
if (phase === "furnish") {
|
||||
const onItemEnter = (event: ItemEvent) => {
|
||||
const itemMesh = sceneRegistry.nodes.get(event.node.id);
|
||||
useViewer.getState().outliner.hoveredObjects.length = 0;
|
||||
useViewer.getState().outliner.hoveredObjects.push(itemMesh);
|
||||
};
|
||||
|
||||
const onItemLeave = (event: ItemEvent) => {
|
||||
useViewer.getState().outliner.hoveredObjects.length = 0;
|
||||
};
|
||||
|
||||
const onItemClick = (event: ItemEvent) => {
|
||||
event.stopPropagation();
|
||||
useViewer
|
||||
.getState()
|
||||
.outliner.selectedObjects.push(
|
||||
sceneRegistry.nodes.get(event.node.id),
|
||||
);
|
||||
};
|
||||
|
||||
emitter.on("item:enter", onItemEnter);
|
||||
emitter.on("item:leave", onItemLeave);
|
||||
emitter.on("item:click", onItemClick);
|
||||
return () => {
|
||||
emitter.off("item:enter", onItemEnter);
|
||||
emitter.off("item:leave", onItemLeave);
|
||||
emitter.off("item:click", onItemClick);
|
||||
};
|
||||
}
|
||||
|
||||
if (phase === "structure") {
|
||||
const onGridClick = (event: GridEvent) => {
|
||||
useViewer.getState().outliner.selectedObjects.length = 0;
|
||||
};
|
||||
const onWallEnter = (event: WallEvent) => {
|
||||
event.stopPropagation();
|
||||
const itemMesh = sceneRegistry.nodes.get(event.node.id);
|
||||
useViewer.getState().outliner.hoveredObjects.length = 0;
|
||||
useViewer.getState().outliner.hoveredObjects.push(itemMesh);
|
||||
};
|
||||
const onWallLeave = (event: WallEvent) => {
|
||||
useViewer.getState().outliner.hoveredObjects.length = 0;
|
||||
};
|
||||
|
||||
const onWallClick = (event: WallEvent) => {
|
||||
event.stopPropagation();
|
||||
if (!event.nativeEvent.shiftKey) {
|
||||
useViewer.getState().outliner.selectedObjects.length = 0;
|
||||
useViewer
|
||||
.getState()
|
||||
.outliner.selectedObjects.push(
|
||||
sceneRegistry.nodes.get(event.node.id),
|
||||
);
|
||||
} else {
|
||||
// check if already selected
|
||||
const selectedObjects = useViewer.getState().outliner.selectedObjects;
|
||||
const wallMesh = sceneRegistry.nodes.get(event.node.id);
|
||||
const index = selectedObjects.indexOf(wallMesh);
|
||||
if (index > -1) {
|
||||
// already selected, deselect
|
||||
selectedObjects.splice(index, 1);
|
||||
} else {
|
||||
// not selected, add to selection
|
||||
selectedObjects.push(wallMesh);
|
||||
}
|
||||
}
|
||||
};
|
||||
emitter.on("grid:click", onGridClick);
|
||||
emitter.on("wall:enter", onWallEnter);
|
||||
emitter.on("wall:leave", onWallLeave);
|
||||
emitter.on("wall:click", onWallClick);
|
||||
return () => {
|
||||
emitter.off("wall:enter", onWallEnter);
|
||||
emitter.off("wall:leave", onWallLeave);
|
||||
emitter.off("wall:click", onWallClick);
|
||||
emitter.off("grid:click", onGridClick);
|
||||
};
|
||||
}
|
||||
|
||||
// emitter.on("item:click", (event) => {
|
||||
// event.stopPropagation();
|
||||
@@ -87,7 +182,7 @@ export const SelectionManager = () => {
|
||||
event.position,
|
||||
);
|
||||
});
|
||||
}, []);
|
||||
}, [mode, phase]);
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user