From 476f31ccadf5f4601f288c2345e19a83b19e99ae Mon Sep 17 00:00:00 2001 From: Karim Date: Tue, 21 Jul 2026 19:31:19 +0200 Subject: [PATCH] =?UTF-8?q?Kontextmen=C3=BC-/Editor-State=20aus=20App.tsx?= =?UTF-8?q?=20in=20useContextMenuState()=20extrahiert?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bündelt layerClipboard, menu, editor, nativeLayerSettingsCode, stampEditorRoomId und editTextId in einem eigenen Hook (Teil der laufenden App.tsx-Verkleinerung). --- src/App.tsx | 38 +++++++++++---------------- src/menus/contextMenu.tsx | 6 +++++ src/menus/useContextMenuState.ts | 45 ++++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+), 23 deletions(-) create mode 100644 src/menus/useContextMenuState.ts diff --git a/src/App.tsx b/src/App.tsx index 2d6d884..4ab657c 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -154,7 +154,7 @@ import type { } from "./tools/types"; import { ContextMenu } from "./ui/ContextMenu"; import { buildMenuItems, menuTitle } from "./menus/contextMenu"; -import type { MenuState } from "./menus/contextMenu"; +import { useContextMenuState } from "./menus/useContextMenuState"; import { InlineEditor } from "./views/InlineEditor"; import { Content } from "./views/viewportContent"; import { useDialogState } from "./state/useDialogState"; @@ -237,12 +237,6 @@ import { deriveDrawings } from "./DrawingTabs"; * • "plan" — Rechtsklick im Grundriss (optional getroffene Wand). * • "viewport" — Rechtsklick im 3D (optional getroffene Wand). */ -/** Offener Inline-Editor (aus einem Menüpunkt). `x/y` = Anker in Viewport-Px. */ -type EditorState = - | { kind: "layer"; code: string; x: number; y: number } - | { kind: "level"; id: string; x: number; y: number } - | null; - /** * GUI-Werkzeug → Befehlsname der Engine. Die Zeichen-Werkzeuge der Palette sind * in Wahrheit Engine-Befehle: ein Klick auf das Werkzeug startet diesen Befehl @@ -549,22 +543,20 @@ export default function App() { const setSelectedContextObjectIds = useStore((s) => s.setSelectedContextObjectIds); // ── Kontextmenüs (transienter UI-State, bleibt lokal) ───────────────────── - // Eigenschaften-Zwischenablage des Ebenen-Kontextmenüs (Farbe + Linienstärke). - const [layerClipboard, setLayerClipboard] = useState<{ - color: string; - lw: number; - } | null>(null); - // Offenes Kontextmenü (genau eines) — Quelle bestimmt die Einträge. - const [menu, setMenu] = useState(null); - // Offener Inline-Editor (Ebene bzw. Geschoss) — aus einem Menüpunkt geöffnet. - const [editor, setEditor] = useState(null); - // Welcher Ebenen-Code aktuell im nativen Ebeneneinstellungs-Fenster offen - // ist (Tauri) — Pendant zu `editor?.kind === "layer"` im Browser-Fallback. - const [nativeLayerSettingsCode, setNativeLayerSettingsCode] = useState(null); - // Offener Raum-Stempel-Editor (Rich-Text) — per Doppelklick/Button geöffnet. - const [stampEditorRoomId, setStampEditorRoomId] = useState(null); - // Text-Inhalt-Editor: Id des per Doppelklick bearbeiteten Text-2D-Elements. - const [editTextId, setEditTextId] = useState(null); + const { + layerClipboard, + setLayerClipboard, + menu, + setMenu, + editor, + setEditor, + nativeLayerSettingsCode, + setNativeLayerSettingsCode, + stampEditorRoomId, + setStampEditorRoomId, + editTextId, + setEditTextId, + } = useContextMenuState(); // Beim Geschosswechsel die Wand-Auswahl + offene Overlays zurücksetzen (die // Wände eines anderen Geschosses sind eine andere Menge). Der Ansichtswechsel diff --git a/src/menus/contextMenu.tsx b/src/menus/contextMenu.tsx index 5d95190..97dd859 100644 --- a/src/menus/contextMenu.tsx +++ b/src/menus/contextMenu.tsx @@ -22,6 +22,12 @@ export type MenuState = | { kind: "viewport"; wallId: string | null; x: number; y: number } | null; +/** Offener Inline-Editor (aus einem Menüpunkt). `x/y` = Anker in Viewport-Px. */ +export type EditorState = + | { kind: "layer"; code: string; x: number; y: number } + | { kind: "level"; id: string; x: number; y: number } + | null; + /** Titel des Kontextmenüs je Quelle (Ebenenname / Geschossname / Wand/Ansicht). */ export function menuTitle(menu: NonNullable, project: Project): string { switch (menu.kind) { diff --git a/src/menus/useContextMenuState.ts b/src/menus/useContextMenuState.ts new file mode 100644 index 0000000..a7004d7 --- /dev/null +++ b/src/menus/useContextMenuState.ts @@ -0,0 +1,45 @@ +// Transienter UI-State der Kontextmenüs/Inline-Editoren — bleibt lokal (kein +// Store-Slice: keine Undo/Redo-Relevanz). Bündelt nur die useState- +// Deklarationen; die Reset-Effekte (Geschoss-/Ansichtswechsel) bleiben in +// App(), da sie zusammen mit globalem Auswahl-State aus dem Store laufen. +// +// Extrahiert aus App.tsx. Bezeichner englisch, Kommentare deutsch (CONVENTIONS.md). + +import { useState } from "react"; +import type { EditorState, MenuState } from "./contextMenu"; + +export function useContextMenuState() { + // Eigenschaften-Zwischenablage des Ebenen-Kontextmenüs (Farbe + Linienstärke). + const [layerClipboard, setLayerClipboard] = useState<{ + color: string; + lw: number; + } | null>(null); + // Offenes Kontextmenü (genau eines) — Quelle bestimmt die Einträge. + const [menu, setMenu] = useState(null); + // Offener Inline-Editor (Ebene bzw. Geschoss) — aus einem Menüpunkt geöffnet. + const [editor, setEditor] = useState(null); + // Welcher Ebenen-Code aktuell im nativen Ebeneneinstellungs-Fenster offen + // ist (Tauri) — Pendant zu `editor?.kind === "layer"` im Browser-Fallback. + const [nativeLayerSettingsCode, setNativeLayerSettingsCode] = useState( + null, + ); + // Offener Raum-Stempel-Editor (Rich-Text) — per Doppelklick/Button geöffnet. + const [stampEditorRoomId, setStampEditorRoomId] = useState(null); + // Text-Inhalt-Editor: Id des per Doppelklick bearbeiteten Text-2D-Elements. + const [editTextId, setEditTextId] = useState(null); + + return { + layerClipboard, + setLayerClipboard, + menu, + setMenu, + editor, + setEditor, + nativeLayerSettingsCode, + setNativeLayerSettingsCode, + stampEditorRoomId, + setStampEditorRoomId, + editTextId, + setEditTextId, + }; +}