From 6a306182f1064457ff121583f5ab7123612aa938 Mon Sep 17 00:00:00 2001 From: Karim Date: Wed, 22 Jul 2026 00:35:12 +0200 Subject: [PATCH] Zeichenwerkzeug-Zustand aus App.tsx in useDrawingToolState() extrahiert MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bündelt aktives Werkzeug, Wandtyp/Linienstil, Snap-Einstellungen, Werkzeug-Zustand-Ref, Draft-Vorschau, aktive Transformation (Bewegen/Spiegeln/Drehen) und die Kopienanzahl für Array/Distribute (Teil der laufenden App.tsx-Verkleinerung). --- src/App.tsx | 58 ++++++++++--------------- src/state/useDrawingToolState.ts | 74 ++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+), 36 deletions(-) create mode 100644 src/state/useDrawingToolState.ts diff --git a/src/App.tsx b/src/App.tsx index 11288b9..4d687f4 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -139,11 +139,9 @@ import { transformPreview, } from "./tools/transform"; import type { CopyMode, TransformOp, TransformSelection } from "./tools/transform"; -import { DEFAULT_SNAP } from "./tools/types"; import type { MeasurementReadout, SnapResult, - SnapSettings, ToolContext, ToolDraft, ToolHandlers, @@ -159,6 +157,7 @@ import { InlineEditor } from "./views/InlineEditor"; import { Content } from "./views/viewportContent"; import { useDialogState } from "./state/useDialogState"; import { useTopBarState } from "./state/useTopBarState"; +import { useDrawingToolState } from "./state/useDrawingToolState"; import { useThemeModeState } from "./theme/useThemeMode"; import { CommandLine } from "./ui/CommandLine"; import type { CommandLineHandle, CommandLineField, CommandLineOption } from "./ui/CommandLine"; @@ -433,40 +432,27 @@ export default function App() { // Aktives Werkzeug, Werkzeug-Parameter (Wandtyp/Kategorie/Linienstil), Snap- // Einstellungen sowie der laufende Werkzeug-Zustand (Ref, kein Re-Render je // Mausbewegung) und die Live-Vorschau (Draft → Overlay in PlanView). - const [activeTool, setActiveTool] = useState("select"); - const [activeWallTypeId, setActiveWallTypeId] = useState( - project.wallTypes[0].id, - ); - const activeCategoryCode = useStore((s) => s.activeCategoryCode); - const setActiveCategoryCode = useStore((s) => s.setActiveCategoryCode); - const [activeLineStyleId] = useState(project.lineStyles[0].id); - const [snap, setSnap] = useState(DEFAULT_SNAP); - const toolStateRef = useRef(getTool("select").init()); - const [draft, setDraft] = useState(null); - // Aktive Transformation (Bewegen/Spiegeln/Drehen) auf der Auswahl — Vectorworks- - // Stil mit U/I/O/P-Modusleiste. null = keine Transformation läuft. - const [activeTransform, setActiveTransform] = useState<{ - op: TransformOp; - copyMode: CopyMode; - count: number; - points: Vec2[]; - } | null>(null); - // Letzter gesnappter Cursor der laufenden Transformation — für das Live-Feld - // (Winkel/Distanz) der Befehlszeile (analog gripDragInfoRef beim Vertex-Drag). - const transformDragInfoRef = useRef<{ cursor: Vec2 } | null>(null); - // Kopienanzahl für array/distribute wird über einen PromptDialog erfasst - // (window.prompt ist im Tauri-WKWebView deaktiviert) — `pendingCopyMode` - // hält den Modus, während der Dialog offen ist. - const [pendingCopyMode, setPendingCopyMode] = useState<"array" | "distribute" | null>(null); - const requestCopyCount = (mode: "array" | "distribute") => setPendingCopyMode(mode); - const commitCopyCount = (input: string) => { - const n = Math.round(Number(input)); - if (Number.isFinite(n) && n >= 1 && pendingCopyMode) { - const mode = pendingCopyMode; - setActiveTransform((t) => (t ? { ...t, copyMode: mode, count: n } : t)); - } - setPendingCopyMode(null); - }; + const { + activeTool, + setActiveTool, + activeWallTypeId, + setActiveWallTypeId, + activeCategoryCode, + setActiveCategoryCode, + activeLineStyleId, + snap, + setSnap, + toolStateRef, + draft, + setDraft, + activeTransform, + setActiveTransform, + transformDragInfoRef, + pendingCopyMode, + setPendingCopyMode, + requestCopyCount, + commitCopyCount, + } = useDrawingToolState(project.wallTypes[0].id, project.lineStyles[0].id); // ── Auswahl (Store-Slice) ───────────────────────────────────────────────── const selectedWallIds = useStore((s) => s.selectedWallIds); diff --git a/src/state/useDrawingToolState.ts b/src/state/useDrawingToolState.ts new file mode 100644 index 0000000..7392957 --- /dev/null +++ b/src/state/useDrawingToolState.ts @@ -0,0 +1,74 @@ +// Bündelt den Zeichenwerkzeug-Zustand (transienter View-State; bleibt lokal): +// aktives Werkzeug, Werkzeug-Parameter (Wandtyp/Kategorie/Linienstil), Snap- +// Einstellungen sowie der laufende Werkzeug-Zustand (Ref, kein Re-Render je +// Mausbewegung), die Live-Vorschau (Draft → Overlay in PlanView) und die +// aktive Transformation (Bewegen/Spiegeln/Drehen) auf der Auswahl. Nur aus +// App() herausgezogen, um die Funktion zu entlasten — reine Zustands- +// Bündelung, keine Verhaltensänderung. +// +// Extrahiert aus App.tsx. Bezeichner englisch, Kommentare deutsch (CONVENTIONS.md). + +import { useRef, useState } from "react"; +import { useStore } from "./appStore"; +import { getTool } from "../tools/tools"; +import type { CopyMode, TransformOp } from "../tools/transform"; +import { DEFAULT_SNAP } from "../tools/types"; +import type { SnapSettings, ToolDraft, ToolId, ToolState } from "../tools/types"; +import type { Vec2 } from "../model/types"; + +export function useDrawingToolState(initialWallTypeId: string, initialLineStyleId: string) { + const [activeTool, setActiveTool] = useState("select"); + const [activeWallTypeId, setActiveWallTypeId] = useState(initialWallTypeId); + const activeCategoryCode = useStore((s) => s.activeCategoryCode); + const setActiveCategoryCode = useStore((s) => s.setActiveCategoryCode); + const [activeLineStyleId] = useState(initialLineStyleId); + const [snap, setSnap] = useState(DEFAULT_SNAP); + const toolStateRef = useRef(getTool("select").init()); + const [draft, setDraft] = useState(null); + // Aktive Transformation (Bewegen/Spiegeln/Drehen) auf der Auswahl — Vectorworks- + // Stil mit U/I/O/P-Modusleiste. null = keine Transformation läuft. + const [activeTransform, setActiveTransform] = useState<{ + op: TransformOp; + copyMode: CopyMode; + count: number; + points: Vec2[]; + } | null>(null); + // Letzter gesnappter Cursor der laufenden Transformation — für das Live-Feld + // (Winkel/Distanz) der Befehlszeile (analog gripDragInfoRef beim Vertex-Drag). + const transformDragInfoRef = useRef<{ cursor: Vec2 } | null>(null); + // Kopienanzahl für array/distribute wird über einen PromptDialog erfasst + // (window.prompt ist im Tauri-WKWebView deaktiviert) — `pendingCopyMode` + // hält den Modus, während der Dialog offen ist. + const [pendingCopyMode, setPendingCopyMode] = useState<"array" | "distribute" | null>(null); + const requestCopyCount = (mode: "array" | "distribute") => setPendingCopyMode(mode); + const commitCopyCount = (input: string) => { + const n = Math.round(Number(input)); + if (Number.isFinite(n) && n >= 1 && pendingCopyMode) { + const mode = pendingCopyMode; + setActiveTransform((t) => (t ? { ...t, copyMode: mode, count: n } : t)); + } + setPendingCopyMode(null); + }; + + return { + activeTool, + setActiveTool, + activeWallTypeId, + setActiveWallTypeId, + activeCategoryCode, + setActiveCategoryCode, + activeLineStyleId, + snap, + setSnap, + toolStateRef, + draft, + setDraft, + activeTransform, + setActiveTransform, + transformDragInfoRef, + pendingCopyMode, + setPendingCopyMode, + requestCopyCount, + commitCopyCount, + }; +}