transforming zones to nodes
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { emitter, type GridEvent, useScene } from "@pascal-app/core";
|
||||
import { useScene, type ZoneNode } from "@pascal-app/core";
|
||||
import { useViewer } from "@pascal-app/viewer";
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||
import {
|
||||
@@ -27,10 +27,11 @@ type DragState = {
|
||||
export const ZoneBoundaryEditor: React.FC = () => {
|
||||
const { gl, camera } = useThree();
|
||||
const selectedZoneId = useViewer((state) => state.selection.zoneId);
|
||||
const zone = useScene((state) =>
|
||||
selectedZoneId ? state.zones[selectedZoneId] : null
|
||||
const zoneNode = useScene((state) =>
|
||||
selectedZoneId ? state.nodes[selectedZoneId] : null
|
||||
);
|
||||
const updateZone = useScene((state) => state.updateZone);
|
||||
const zone = zoneNode?.type === "zone" ? (zoneNode as ZoneNode) : null;
|
||||
const updateNode = useScene((state) => state.updateNode);
|
||||
|
||||
// Local state for dragging
|
||||
const [dragState, setDragState] = useState<DragState | null>(null);
|
||||
@@ -89,11 +90,11 @@ export const ZoneBoundaryEditor: React.FC = () => {
|
||||
// Commit polygon changes
|
||||
const commitPolygonChange = useCallback(() => {
|
||||
if (previewPolygon && selectedZoneId) {
|
||||
updateZone(selectedZoneId, { polygon: previewPolygon });
|
||||
updateNode(selectedZoneId, { polygon: previewPolygon });
|
||||
}
|
||||
setPreviewPolygon(null);
|
||||
setDragState(null);
|
||||
}, [previewPolygon, selectedZoneId, updateZone]);
|
||||
}, [previewPolygon, selectedZoneId, updateNode]);
|
||||
|
||||
// Handle adding a new vertex at midpoint
|
||||
const handleAddVertex = useCallback(
|
||||
@@ -122,10 +123,10 @@ export const ZoneBoundaryEditor: React.FC = () => {
|
||||
if (basePolygon.length <= 3) return; // Need at least 3 points
|
||||
|
||||
const newPolygon = basePolygon.filter((_, i) => i !== index);
|
||||
updateZone(selectedZoneId, { polygon: newPolygon });
|
||||
updateNode(selectedZoneId, { polygon: newPolygon });
|
||||
setPreviewPolygon(null);
|
||||
},
|
||||
[zone, selectedZoneId, previewPolygon, updateZone]
|
||||
[zone, selectedZoneId, previewPolygon, updateNode]
|
||||
);
|
||||
|
||||
// Set up pointer move/up listeners for dragging
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { emitter, type GridEvent, useScene, ZoneSchema } from "@pascal-app/core";
|
||||
import { emitter, type GridEvent, useScene, ZoneNode, type LevelNode } from "@pascal-app/core";
|
||||
import { useViewer } from "@pascal-app/viewer";
|
||||
import { useEffect, useMemo, useRef, useState } from "react";
|
||||
import { BufferGeometry, DoubleSide, type Line, type Mesh, Shape, Vector3 } from "three";
|
||||
@@ -61,26 +61,25 @@ const calculateSnapPoint = (
|
||||
* Creates a zone with the given polygon points
|
||||
*/
|
||||
const commitZoneDrawing = (
|
||||
levelId: string,
|
||||
levelId: LevelNode["id"],
|
||||
points: Array<[number, number]>
|
||||
) => {
|
||||
const { createZone, zoneIds } = useScene.getState();
|
||||
const { createNode, nodes } = useScene.getState();
|
||||
|
||||
// Get next zone number
|
||||
const zoneCount = zoneIds.length;
|
||||
// Count existing zones for naming and color cycling
|
||||
const zoneCount = Object.values(nodes).filter((n) => n.type === "zone").length;
|
||||
const name = `Zone ${zoneCount + 1}`;
|
||||
|
||||
// Cycle through colors
|
||||
const color = ZONE_COLORS[zoneCount % ZONE_COLORS.length];
|
||||
|
||||
const zone = ZoneSchema.parse({
|
||||
levelId,
|
||||
const zone = ZoneNode.parse({
|
||||
name,
|
||||
polygon: points,
|
||||
color,
|
||||
});
|
||||
|
||||
createZone(zone);
|
||||
createNode(zone, levelId);
|
||||
|
||||
// Select the newly created zone
|
||||
useViewer.getState().setSelection({ zoneId: zone.id });
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useScene, type Zone } from "@pascal-app/core";
|
||||
import { useScene, type ZoneNode } from "@pascal-app/core";
|
||||
import { useViewer } from "@pascal-app/viewer";
|
||||
import { Hexagon, Trash2 } from "lucide-react";
|
||||
import { cn } from "@/lib/utils";
|
||||
@@ -21,9 +21,9 @@ const PRESET_COLORS = [
|
||||
"#06b6d4", // cyan
|
||||
];
|
||||
|
||||
function ZoneItem({ zone }: { zone: Zone }) {
|
||||
const deleteZone = useScene((state) => state.deleteZone);
|
||||
const updateZone = useScene((state) => state.updateZone);
|
||||
function ZoneItem({ zone }: { zone: ZoneNode }) {
|
||||
const deleteNode = useScene((state) => state.deleteNode);
|
||||
const updateNode = useScene((state) => state.updateNode);
|
||||
const selectedZoneId = useViewer((state) => state.selection.zoneId);
|
||||
const setSelection = useViewer((state) => state.setSelection);
|
||||
|
||||
@@ -35,14 +35,14 @@ function ZoneItem({ zone }: { zone: Zone }) {
|
||||
|
||||
const handleDelete = (e: React.MouseEvent) => {
|
||||
e.stopPropagation();
|
||||
deleteZone(zone.id);
|
||||
deleteNode(zone.id);
|
||||
if (isSelected) {
|
||||
setSelection({ zoneId: null });
|
||||
}
|
||||
};
|
||||
|
||||
const handleColorChange = (color: string) => {
|
||||
updateZone(zone.id, { color });
|
||||
updateNode(zone.id, { color });
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -96,20 +96,17 @@ function ZoneItem({ zone }: { zone: Zone }) {
|
||||
}
|
||||
|
||||
export function ZonePanel() {
|
||||
const zones = useScene((state) => state.zones);
|
||||
const zoneIds = useScene((state) => state.zoneIds);
|
||||
const nodes = useScene((state) => state.nodes);
|
||||
const currentLevelId = useViewer((state) => state.selection.levelId);
|
||||
const setPhase = useEditor((state) => state.setPhase);
|
||||
const setMode = useEditor((state) => state.setMode);
|
||||
const setTool = useEditor((state) => state.setTool);
|
||||
|
||||
// Filter zones to only show those for the current level
|
||||
const levelZones = zoneIds
|
||||
.map((id) => zones[id])
|
||||
.filter(
|
||||
(zone): zone is Zone =>
|
||||
zone !== undefined && zone.levelId === currentLevelId
|
||||
);
|
||||
// Filter nodes to get zones for the current level
|
||||
const levelZones = Object.values(nodes).filter(
|
||||
(node): node is ZoneNode =>
|
||||
node.type === "zone" && node.parentId === currentLevelId
|
||||
);
|
||||
|
||||
const handleAddZone = () => {
|
||||
if (currentLevelId) {
|
||||
|
||||
Reference in New Issue
Block a user