editor: improve selection drag parity, ignore locked nodes

This commit is contained in:
clawdbot 2026-01-27 22:17:44 +08:00
parent 01e43a0021
commit 5e21e87696
2 changed files with 20 additions and 0 deletions

View File

@ -436,6 +436,18 @@ export function Canvas(props: CanvasProps) {
return; return;
} }
// If the node is already in the current selection, keep the selection as-is.
// This matches goView-ish multi-selection behavior (drag moves the whole selection).
if (props.selectionIds.includes(node.id)) {
if (node.locked) {
// Locked nodes are selectable, but should not start a move drag.
props.onSelectSingle(node.id);
return;
}
props.onBeginMove(e);
return;
}
// Locked nodes should still be selectable, but not movable. // Locked nodes should still be selectable, but not movable.
if (node.locked) { if (node.locked) {
props.onSelectSingle(node.id); props.onSelectSingle(node.id);

View File

@ -584,12 +584,18 @@ export function editorReducer(state: EditorState, action: EditorAction): EditorS
snapshot: new Map<string, Rect>(), snapshot: new Map<string, Rect>(),
}; };
// Only snapshot movable nodes.
// Locked/hidden nodes can remain selected (for context-menu ops), but they should not move.
for (const id of state.selection.ids) { for (const id of state.selection.ids) {
const node = state.doc.screen.nodes.find((n) => n.id === id); const node = state.doc.screen.nodes.find((n) => n.id === id);
if (!node) continue; if (!node) continue;
if (node.locked || node.hidden) continue;
drag.snapshot.set(id, { ...node.rect }); drag.snapshot.set(id, { ...node.rect });
} }
// Nothing movable selected → no-op (avoid entering a dragging state).
if (!drag.snapshot.size) return state;
return { return {
...state, ...state,
canvas: { canvas: {
@ -630,6 +636,8 @@ export function editorReducer(state: EditorState, action: EditorAction): EditorS
const nodes = state.doc.screen.nodes.map((n) => { const nodes = state.doc.screen.nodes.map((n) => {
if (!state.selection.ids.includes(n.id)) return n; if (!state.selection.ids.includes(n.id)) return n;
// Locked/hidden nodes should not move, even if selected.
if (n.locked || n.hidden) return n;
const snap0 = drag.snapshot.get(n.id); const snap0 = drag.snapshot.get(n.id);
if (!snap0) return n; if (!snap0) return n;