From f9b202ac25110a730c9b09312c085fd769c7b138 Mon Sep 17 00:00:00 2001 From: Karim Date: Fri, 21 Aug 2026 23:13:02 +0200 Subject: [PATCH] =?UTF-8?q?2D:=20Zifferntasten=20w=C3=A4hrend=20Punkt-Grif?= =?UTF-8?q?f-Bearbeitung=20nicht=20mehr=20als=20Werkzeug-Wechsel?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bug (Nutzer-Report direkt nach dem vorigen Commit): sobald man nach Tab einen Länge-/Winkel-Wert eintippte, wechselte die App mitten in die Griff-Bearbeitung ins Zeichenwerkzeug (z.B. "3" -> Kreis-Werkzeug). Ursache: useToolNumberShortcuts (Vectorworks-Zifferntasten fürs Werkzeug wählen) erlaubt Zifferntasten auch bei fokussiertem, leerem Befehlsfeld, SOFERN die Zeichen-Engine gerade keinen Befehl mit Feldern laufen hat (`!eng.hasFields() && !eng.acceptsFreeText()`). Genau das trifft während der Griff-Bearbeitung IMMER zu, da dort gar keine Engine-Befehl läuft, sondern der separate Feld-Controller aus useGripEditing.ts -- der Wächter kannte diesen zweiten Fall nicht. Fix: gripDragInfoRef (schon vorhanden, zeigt "ein Punkt-Griff ist bewaffnet" an) wird von useGripEditing zurückgegeben und an useToolNumberShortcuts durchgereicht; dessen Handler bricht jetzt ganz vorne ab, wenn ein Griff bewaffnet ist -- unabhängig davon, ob/wo gerade Fokus liegt. Der useToolNumberShortcuts-Aufruf in App.tsx musste dafür hinter den useGripEditing()-Aufruf wandern (Reihenfolge war vorher umgekehrt, gripDragInfoRef existierte an der alten Stelle noch nicht). --- src/App.tsx | 17 ++++++++++++----- src/state/useGripEditing.ts | 5 +++++ src/state/useKeyboardShortcuts.ts | 8 ++++++++ 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 5d7c9d8..b8894a7 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -949,11 +949,11 @@ export default function App() { // Globaler Undo/Redo-Shortcut — siehe state/useKeyboardShortcuts.ts. useUndoRedoShortcut(undo, redo); - // Nummern-Shortcuts für Zeichenwerkzeuge (Vectorworks-Stil): 1 Text, 2 Linie, - // 3 Kreis, 4 Rechteck, 5 Polylinie, 6 Wand, 7 Decke, 8 Fenster, 9 Türe, 0 Raum - // — sowie Esc/Enter/Backspace für das aktive Zeichenwerkzeug. Siehe - // state/useKeyboardShortcuts.ts. - useToolNumberShortcuts(onSelectTool, activeLevel.kind === "floor", engineRef); + // Esc/Enter/Backspace für das aktive Zeichenwerkzeug. Siehe + // state/useKeyboardShortcuts.ts. Die Zifferntasten-Werkzeugwahl + // (useToolNumberShortcuts) folgt weiter unten, NACH useGripEditing() — sie + // braucht dessen gripDragInfoRef, um Zifferntasten während einer Griff- + // Bearbeitung nicht als Werkzeug-Wechsel misszuverstehen. useActiveToolKeys(activeTool, toolCtx, engineRef, toolStateRef, setDraft, setActiveTool, setProject); // ── Editier-Griffe (Grips) des einzeln selektierten Elements ────────────── @@ -1294,6 +1294,7 @@ export default function App() { gripEditFields, cycleGripEditField, submitGripEditValue, + gripDragInfoRef, } = useGripEditing({ project, selectedDrawing, @@ -1327,6 +1328,12 @@ export default function App() { moveElementByOf, }); + // Nummern-Shortcuts für Zeichenwerkzeuge (Vectorworks-Stil): 1 Text, 2 Linie, + // 3 Kreis, 4 Rechteck, 5 Polylinie, 6 Wand, 7 Decke, 8 Fenster, 9 Türe, 0 Raum. + // Siehe state/useKeyboardShortcuts.ts. Braucht gripDragInfoRef (s. o.), daher + // erst hier nach useGripEditing() registriert. + useToolNumberShortcuts(onSelectTool, activeLevel.kind === "floor", engineRef, gripDragInfoRef); + // Feld-Zustand fürs Cursor-HUD (neben der Maus, VW-Stil): läuft ein // Punkt-Griff-Drag, hat er Vorrang (dieselben Felder wie unten in der // Befehlszeile — Länge/Winkel-Tab-Zyklus), sonst die Befehls-Engine-Felder diff --git a/src/state/useGripEditing.ts b/src/state/useGripEditing.ts index d2276c2..f2230aa 100644 --- a/src/state/useGripEditing.ts +++ b/src/state/useGripEditing.ts @@ -751,5 +751,10 @@ export function useGripEditing(opts: { gripEditFields, cycleGripEditField, submitGripEditValue, + // Für useToolNumberShortcuts: solange ein Griff bewaffnet ist, dürfen + // Zifferntasten NICHT als Werkzeug-Wechsel interpretiert werden (auch + // nicht, wenn das Befehlsfeld fokussiert und leer ist — die Zeichen- + // Engine selbst läuft ja nicht, daher griff dieser Wächter sonst nicht). + gripDragInfoRef, }; } diff --git a/src/state/useKeyboardShortcuts.ts b/src/state/useKeyboardShortcuts.ts index 90616de..929cd65 100644 --- a/src/state/useKeyboardShortcuts.ts +++ b/src/state/useKeyboardShortcuts.ts @@ -124,6 +124,7 @@ export function useToolNumberShortcuts( onSelectTool: (id: ToolId) => void, isFloor: boolean, engineRef: RefObject, + gripDragInfoRef?: RefObject<{ index: number; raw: Vec2 } | null>, ): void { const toolShortcutRef = useRef({ onSelectTool, floor: isFloor }); toolShortcutRef.current = { onSelectTool, floor: isFloor }; @@ -142,6 +143,13 @@ export function useToolNumberShortcuts( }; const onKey = (e: KeyboardEvent) => { if (e.ctrlKey || e.metaKey || e.altKey) return; + // Ein Punkt-Griff ist bewaffnet (s. useGripEditing.ts) — Zifferntasten + // gehören dann IMMER dessen Länge/Winkel-Feld, nie dem Werkzeug-Wechsel. + // Die `eng?.hasFields()`-Prüfung unten greift hier nicht, weil während + // der Griff-Bearbeitung gar kein Zeichenbefehl der Engine läuft (Bug: + // getippter Wert schaltete auf das per Ziffer gemappte Zeichenwerkzeug + // um, sobald das leere, fokussierte Befehlsfeld erkannt wurde). + if (gripDragInfoRef?.current) return; const el = e.target as HTMLElement | null; const isInput = !!el && (el.tagName === "INPUT" || el.tagName === "TEXTAREA" || el.isContentEditable);