diff --git a/src/stores/useModelStore.ts b/src/stores/useModelStore.ts index 8eeae17..11182e9 100644 --- a/src/stores/useModelStore.ts +++ b/src/stores/useModelStore.ts @@ -505,9 +505,48 @@ export const useModelStore = create((set, get) => ({ resetChecklist: () => set({ checklist: defaultChecklist.map(i => ({ ...i })) }), measureMode: false, - setMeasureMode: (measureMode) => set((s) => ({ measureMode, measurePoints: [], positionMode: measureMode ? false : s.positionMode })), + setMeasureMode: (measureMode) => set((s) => ({ measureMode, measurePoints: [], positionMode: measureMode ? false : s.positionMode, selectionMode: measureMode ? false : s.selectionMode })), positionMode: false, - setPositionMode: (positionMode) => set((s) => ({ positionMode, measureMode: positionMode ? false : s.measureMode })), + setPositionMode: (positionMode) => set((s) => ({ positionMode, measureMode: positionMode ? false : s.measureMode, selectionMode: positionMode ? false : s.selectionMode })), + + // ── Selection state ───────────────────────────────────── + selectionMode: false, + setSelectionMode: (on) => set((s) => ({ + selectionMode: on, + measureMode: on ? false : s.measureMode, + positionMode: on ? false : s.positionMode, + selectedElementKeys: on ? s.selectedElementKeys : new Set(), + })), + selectedElementKeys: new Set(), + hiddenElementKeys: new Set(), + isolatedElementKeys: null, + visibilityNonce: 0, + toggleElementSelection: (key) => set((s) => { + const next = new Set(s.selectedElementKeys); + if (next.has(key)) next.delete(key); else next.add(key); + return { selectedElementKeys: next, visibilityNonce: s.visibilityNonce + 1 }; + }), + clearElementSelection: () => set((s) => ({ selectedElementKeys: new Set(), visibilityNonce: s.visibilityNonce + 1 })), + hideSelectedElements: () => set((s) => { + if (s.selectedElementKeys.size === 0) return {} as Partial; + const hidden = new Set(s.hiddenElementKeys); + s.selectedElementKeys.forEach(k => hidden.add(k)); + const active = s.models.find(m => m.id === s.activeModelId); + if (active) saveVisibility(active.fileName, hidden, s.isolatedElementKeys); + return { hiddenElementKeys: hidden, selectedElementKeys: new Set(), visibilityNonce: s.visibilityNonce + 1 }; + }), + isolateSelectedElements: () => set((s) => { + if (s.selectedElementKeys.size === 0) return {} as Partial; + const iso = new Set(s.selectedElementKeys); + const active = s.models.find(m => m.id === s.activeModelId); + if (active) saveVisibility(active.fileName, s.hiddenElementKeys, iso); + return { isolatedElementKeys: iso, selectedElementKeys: new Set(), visibilityNonce: s.visibilityNonce + 1 }; + }), + showAllElements: () => set((s) => { + const active = s.models.find(m => m.id === s.activeModelId); + if (active) saveVisibility(active.fileName, new Set(), null); + return { hiddenElementKeys: new Set(), isolatedElementKeys: null, selectedElementKeys: new Set(), visibilityNonce: s.visibilityNonce + 1 }; + }), measurePoints: [], addMeasurePoint: (p) => set((state) => { const points = [...state.measurePoints, p];