2D: Enter in der Befehlszeile bestätigt Punkt-Griff jetzt auch ohne neuen Wert
Nutzer-Report: Enter sollte den Punkt gemäss Maus-/Feld-Stand platzieren
("die Maus steuert bis man Werte eingibt, dann übernimmt es im Feld den
aktuellen Wert, man kann eigene Werte per Tab eingeben") -- aber Enter
tat nach dem Tippen eines Werts (oder auch ganz ohne Tippen) nichts.
Ursache: die Befehlszeile fokussiert sich selbst, sobald man Tab drückt
(Feld-Controller öffnen). Der GLOBALE Enter/Escape-Tastatur-Handler aus
dem vorigen Commit überspringt bewusst fokussierte Eingabefelder (damit
er sich nicht mit der Befehlszeilen-eigenen Enter-Behandlung beisst) --
aber die Befehlszeile selbst kannte für die Griff-Bearbeitung nur den
Fall "Text eingetippt, als Zahl geparst" (submitGripEditValue). Bei
LEERER Eingabe (Enter ohne neuen Wert -- der Normalfall, wenn man nur
bestätigen will) geschah dadurch schlicht nichts.
Fix: PlanViewHandle bekommt eine neue Methode confirmGripEdit() (liest
den bewaffneten Griff aus der lokalen gripDrag-Ref, ruft
gripHandlers.onGripEnd() -- dieselbe Aktion wie ein bestätigender Klick
auf der Zeichenfläche). Die Befehlszeilen-Eingabe in App.tsx ruft sie
jetzt bei leerem/nicht parsbarem Text während der Griff-Bearbeitung auf.
Da das Imperativ-Handle mit leeren Deps memoisiert ist (stabil für die
Oberleiste), braucht es einen frischen gripHandlersRef-Spiegel statt die
gripHandlers-Prop direkt zu schließen (sonst stale closure vom ersten
Render).
This commit is contained in:
@@ -2819,6 +2819,11 @@ export default function App() {
|
|||||||
if (gripEdit) {
|
if (gripEdit) {
|
||||||
const v = parseFloat(text.replace(",", "."));
|
const v = parseFloat(text.replace(",", "."));
|
||||||
if (isFinite(v)) submitGripEditValue(v);
|
if (isFinite(v)) submitGripEditValue(v);
|
||||||
|
// Leere Eingabe: kein neuer Wert zu locken — Enter bestätigt
|
||||||
|
// stattdessen die aktuelle Position (Maus- oder bereits
|
||||||
|
// gelockte Werte) und schließt die Griff-Bearbeitung ab. Vorher
|
||||||
|
// ein Totdruck (Nutzer-Report: Enter tat nichts).
|
||||||
|
else planViewRef.current?.confirmGripEdit();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (activeTransform) {
|
if (activeTransform) {
|
||||||
|
|||||||
@@ -111,6 +111,14 @@ export interface PlanViewHandle {
|
|||||||
* Leere Punktmenge → No-op (kein Fit, kein Crash).
|
* Leere Punktmenge → No-op (kein Fit, kein Crash).
|
||||||
*/
|
*/
|
||||||
fitBounds: (pts: Vec2[]) => void;
|
fitBounds: (pts: Vec2[]) => void;
|
||||||
|
/**
|
||||||
|
* Einen bewaffneten Punkt-Griff (s. gripDrag) an seiner AKTUELLEN Position
|
||||||
|
* abschließen — dieselbe Aktion wie ein bestätigender Klick/Enter auf der
|
||||||
|
* Zeichenfläche, aber von der Befehlszeile aus angestoßen (Enter dort MIT
|
||||||
|
* leerem Eingabetext: kein neuer Wert zu locken, nur „fertig, so lassen").
|
||||||
|
* No-op ohne bewaffneten Griff.
|
||||||
|
*/
|
||||||
|
confirmGripEdit: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Ergebnis eines Links-Klicks (Auswahl) an einer Modellposition. */
|
/** Ergebnis eines Links-Klicks (Auswahl) an einer Modellposition. */
|
||||||
@@ -707,12 +715,28 @@ export const PlanView = forwardRef<PlanViewHandle, PlanViewProps>(
|
|||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [resetKey]);
|
}, [resetKey]);
|
||||||
|
|
||||||
|
// Frischer Spiegel der gripHandlers-Prop für das (unten stabil mit leeren
|
||||||
|
// Deps memoisierte) Imperativ-Handle — direkt referenzieren würde die Prop
|
||||||
|
// vom ERSTEN Render einfrieren (stale closure, s. Kommentar dort).
|
||||||
|
const gripHandlersRef = useRef(gripHandlers);
|
||||||
|
gripHandlersRef.current = gripHandlers;
|
||||||
|
|
||||||
// Imperatives Steuerhandle für die Oberleiste (Einpassen / Auswahl / Massstab).
|
// Imperatives Steuerhandle für die Oberleiste (Einpassen / Auswahl / Massstab).
|
||||||
// Stabil (leere Deps); liest den frischen Ausschnitt + die Auswahl aus Refs.
|
// Stabil (leere Deps); liest den frischen Ausschnitt + die Auswahl aus Refs.
|
||||||
useImperativeHandle(
|
useImperativeHandle(
|
||||||
ref,
|
ref,
|
||||||
() => ({
|
() => ({
|
||||||
fit: () => setView(defaultViewRef.current),
|
fit: () => setView(defaultViewRef.current),
|
||||||
|
confirmGripEdit: () => {
|
||||||
|
// Von der Befehlszeile aus angestoßen (Enter mit leerem Eingabetext,
|
||||||
|
// s. App.tsx) — dieselbe Aktion wie ein bestätigender Klick auf der
|
||||||
|
// Zeichenfläche (siehe onPointerDown-Kopf unten), nur eben nicht über
|
||||||
|
// ein Pointer-Event.
|
||||||
|
if (gripDrag.current) {
|
||||||
|
gripDrag.current = null;
|
||||||
|
gripHandlersRef.current?.onGripEnd();
|
||||||
|
}
|
||||||
|
},
|
||||||
fitSelection: () => {
|
fitSelection: () => {
|
||||||
const sel = selectedRef.current;
|
const sel = selectedRef.current;
|
||||||
const prim = sel !== null ? planRef.current.primitives[sel] : undefined;
|
const prim = sel !== null ? planRef.current.primitives[sel] : undefined;
|
||||||
|
|||||||
Reference in New Issue
Block a user