diff --git a/src/components/floorplan-editor/FloorplanEditorView.tsx b/src/components/floorplan-editor/FloorplanEditorView.tsx
index c57ff6c..2e27638 100644
--- a/src/components/floorplan-editor/FloorplanEditorView.tsx
+++ b/src/components/floorplan-editor/FloorplanEditorView.tsx
@@ -234,7 +234,7 @@ export const FloorplanEditorView: FC = () =>
onUndo={ undo }
onRedo={ redo }
panMode={ panMode }
- onTogglePanMode={ () => setPanMode(v => !v) }
+ setPanMode={ setPanMode }
/>
diff --git a/src/components/floorplan-editor/views/FloorplanToolbar.tsx b/src/components/floorplan-editor/views/FloorplanToolbar.tsx
index d941722..8f24f9a 100644
--- a/src/components/floorplan-editor/views/FloorplanToolbar.tsx
+++ b/src/components/floorplan-editor/views/FloorplanToolbar.tsx
@@ -12,7 +12,14 @@ type Props = {
onUndo?: () => void;
onRedo?: () => void;
panMode?: boolean;
- onTogglePanMode?: () => void;
+ /**
+ * Imperative setter for pan mode. Receiving the explicit
+ * value (not a toggle) lets every tool button switch the
+ * hand off on click without needing to know its current
+ * state — the hand is part of the same exclusive tool group
+ * as the brushes, so picking any brush has to clear it.
+ */
+ setPanMode?: (next: boolean) => void;
};
const BRUSH_BUTTONS: { id: string; mode: FloorActionMode; iconClass: string }[] = [
@@ -23,45 +30,71 @@ const BRUSH_BUTTONS: { id: string; mode: FloorActionMode; iconClass: string }[]
{ id: 'tool-door', mode: 'DOOR', iconClass: 'icon-set-door' }
];
-export const FloorplanToolbar: FC = ({ state, dispatch, canUndo, canRedo, onUndo, onRedo, panMode, onTogglePanMode }) =>
+export const FloorplanToolbar: FC = ({ state, dispatch, canUndo, canRedo, onUndo, onRedo, panMode, setPanMode }) =>
{
+ // The hand and the brush buttons form a single exclusive tool
+ // group. Picking ANY other tool clears pan mode so the user
+ // never ends up in 'I clicked SET but the canvas still pans'.
+ const exitPan = () =>
+ {
+ if(panMode && setPanMode) setPanMode(false);
+ };
+
return (
- { LocalizeText('floor.plan.editor.draw.mode') }
- { BRUSH_BUTTONS.map(b => (
- dispatch({ type: 'BRUSH_SET', action: b.mode }) }
- />
- )) }
- 0 ? 'icon-set-deselect' : 'icon-set-select' }` }
- onClick={ () => dispatch({ type: 'SELECT_ALL' }) }
- />
- dispatch({ type: 'SQUARE_SELECT_TOGGLE' }) }
- />
- { onTogglePanMode && (
+ { setPanMode && (
setPanMode(!panMode) }
>
) }
+ { LocalizeText('floor.plan.editor.draw.mode') }
+ { BRUSH_BUTTONS.map(b =>
+ {
+ const active = state.brush.action === b.mode && !panMode;
+
+ return (
+
+ {
+ exitPan();
+ dispatch({ type: 'BRUSH_SET', action: b.mode });
+ } }
+ />
+ );
+ }) }
+ 0 ? 'icon-set-deselect' : 'icon-set-select' }` }
+ onClick={ () =>
+ {
+ exitPan();
+ dispatch({ type: 'SELECT_ALL' });
+ } }
+ />
+
+ {
+ exitPan();
+ dispatch({ type: 'SQUARE_SELECT_TOGGLE' });
+ } }
+ />
{ (onUndo || onRedo) && (