diff --git a/src/App.tsx b/src/App.tsx index 0adb4ba..566d19d 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -93,7 +93,7 @@ import { Viewport3D } from "./viewport/Viewport3D"; import type { DisplayResolver, ViewportContextInfo } from "./viewport/Viewport3D"; import type { Pick3dHit } from "./viewport/Wasm3DViewport"; import { ResourceManager } from "./ui/ResourceManager"; -import type { ResourceManagerHandlers } from "./ui/ResourceManager"; +import type { ResourceManagerHandlers, TabId as ResourceTabId } from "./ui/ResourceManager"; import { LayoutSheetView } from "./ui/LayoutSheet"; import { createLayout, @@ -408,6 +408,9 @@ export default function App() { // bleibt lokal. Wird über die Oberleiste geöffnet und über X / Hintergrund- // Klick / Esc geschlossen. const [resourcesOpen, setResourcesOpen] = useState(false); + // Angeforderter Start-Tab des Ressourcen-Fensters (z. B. „doorStyles", wenn man + // von einer gewählten Tür in den Typeditor springt). + const [resourcesTab, setResourcesTab] = useState("components"); // Aktives Layout-Blatt im HAUPT-Viewport (DOSSIER A3, Phase 2b): Id des offenen // Layouts oder null (= normale Modell-Ansicht). Transienter UI-State; das @@ -3109,6 +3112,10 @@ export default function App() { if (selection?.kind === "opening") updateOpening(selection.id, { typeId: typeId || undefined }); }, + onEditOpeningType: (kind) => { + setResourcesTab(kind === "door" ? "doorStyles" : "windowStyles"); + setResourcesOpen(true); + }, // ── Treppen-Attribute (nur bei selektierter Treppe) ──────────────────── onSetStairShape: (shape) => { if (selection?.kind === "stair") updateStair(selection.id, { shape }); @@ -4910,6 +4917,7 @@ export default function App() { setResourcesOpen(false)} /> )} diff --git a/src/i18n/de.ts b/src/i18n/de.ts index 2c092fa..2232612 100644 --- a/src/i18n/de.ts +++ b/src/i18n/de.ts @@ -340,6 +340,7 @@ export const de = { // ── Öffnungs-Attribute (Object-Info-Panel) ────────────────────────────── "objinfo.opening.section": "Öffnung", "objinfo.opening.type": "Typ", + "objinfo.opening.editType": "Typ bearbeiten (Ressourcen)", "objinfo.stair.type": "Typ", "objinfo.type.none": "(kein Typ)", "objinfo.opening.kind": "Art", diff --git a/src/i18n/en.ts b/src/i18n/en.ts index 00ff0e8..8014719 100644 --- a/src/i18n/en.ts +++ b/src/i18n/en.ts @@ -340,6 +340,7 @@ export const en: Record = { // ── Opening attributes (object info panel) ────────────────────────────── "objinfo.opening.section": "Opening", "objinfo.opening.type": "Type", + "objinfo.opening.editType": "Edit type (Resources)", "objinfo.stair.type": "Type", "objinfo.type.none": "(no type)", "objinfo.opening.kind": "Type", diff --git a/src/panels/ObjectInfoPanel.tsx b/src/panels/ObjectInfoPanel.tsx index 7516472..049ce44 100644 --- a/src/panels/ObjectInfoPanel.tsx +++ b/src/panels/ObjectInfoPanel.tsx @@ -578,7 +578,8 @@ export function OpeningSection({
{t("objinfo.opening.section")}
- {/* Tür-/Fenstertyp (Bibliothek) — je nach Art aus doorTypes bzw. windowTypes. */} + {/* Tür-/Fenstertyp (Bibliothek) — je nach Art aus doorTypes bzw. windowTypes. + Der ⚙-Knopf springt direkt in den Typeditor (Ressourcen-Fenster). */}
{t("objinfo.opening.type")} ({ value: ty.id, label: ty.name })), ]} title={t("objinfo.opening.type")} - width={130} + width={106} /> +
{/* Art-Segment Fenster/Tür. */} diff --git a/src/panels/host.ts b/src/panels/host.ts index e17f1fa..556cdfc 100644 --- a/src/panels/host.ts +++ b/src/panels/host.ts @@ -294,6 +294,11 @@ export interface PanelHostValue { onSetOpeningLintelLines: (lintelLines: "keine" | "innen" | "aussen" | "beide") => void; /** Weist der Öffnung einen Tür-/Fenstertyp (Bibliothek) zu; "" löst die Zuweisung. */ onSetOpeningType: (typeId: string) => void; + /** + * Öffnet das Ressourcen-Fenster direkt beim Tür- bzw. Fenstertyp-Editor + * (Discoverability: von der gewählten Öffnung in den Typeditor springen). + */ + onEditOpeningType: (kind: "door" | "window") => void; // ── Treppen-Attribute (Object-Info-Panel; nur die selektierte Treppe) ─── /** Setzt die Grundform (gerade/L/Wendel). */ diff --git a/src/styles.css b/src/styles.css index 103080b..5586c4e 100644 --- a/src/styles.css +++ b/src/styles.css @@ -4044,6 +4044,24 @@ body { letter-spacing: 0.04em; margin: 2px 2px 4px; } +/* „Typ bearbeiten"-Knopf (⚙) neben dem Öffnungstyp-Dropdown. */ +.objinfo-typebtn { + margin-left: 4px; + width: 22px; + height: 22px; + padding: 0; + border: 1px solid var(--border, #444); + border-radius: 4px; + background: transparent; + color: var(--fg, inherit); + cursor: pointer; + font-size: 12px; + line-height: 1; +} +.objinfo-typebtn:hover { + background: var(--hover, rgba(127, 127, 127, 0.18)); +} + /* Mess-Werkzeug: Live-Messwerte im Objekt-Info-Panel. */ .objinfo-measure { margin: 2px 2px 8px; diff --git a/src/ui/ResourceManager.tsx b/src/ui/ResourceManager.tsx index dfb4e46..27a06e6 100644 --- a/src/ui/ResourceManager.tsx +++ b/src/ui/ResourceManager.tsx @@ -2951,7 +2951,7 @@ function EmptyState({ text }: { text: string }) { // ── Manager-Schublade ────────────────────────────────────────────────────── -type TabId = +export type TabId = | "components" | "hatches" | "lines" @@ -3064,12 +3064,20 @@ export function ResourceManager({ project, onClose, handlers, + initialTab, }: { project: Project; onClose: () => void; handlers: ResourceManagerHandlers; + /** Beim Öffnen (bzw. bei erneutem Sprung) direkt aktiver Tab, z. B. „doorStyles". */ + initialTab?: TabId; }) { - const [tab, setTab] = useState("components"); + const [tab, setTab] = useState(initialTab ?? "components"); + // Erneuter Sprung aus einem Element heraus (z. B. „Typ bearbeiten" an einer + // Öffnung): auf den angeforderten Tab wechseln, auch wenn das Fenster schon offen ist. + useEffect(() => { + if (initialTab) setTab(initialTab); + }, [initialTab]); const [rect, setRect] = useState(initialRect); // Verschieben über die Kopfzeile: Cursor − linke/obere Kante festhalten und die