+ )}
+ >
+ )}
{/* Die element-spezifischen Abschnitte (Wand/Decke/Öffnung/Treppe/Raum)
werden jetzt im Attribute-Panel gerendert (AttributesPanel importiert
die exportierten *Section-Komponenten). */}
@@ -393,6 +422,20 @@ export function SectionLineSection({
{t("objinfo.sectionLine.flip")}
+ {/* 3D-Live-Schnitt an diese Linie binden (nur mit gesetzter Linie sinnvoll):
+ der Viewport clippt dann vertikal entlang dieser Ebene. */}
+ {line && (
+
diff --git a/src/panels/ToolsPanel.tsx b/src/panels/ToolsPanel.tsx
index 6fbbdfa..d8441f7 100644
--- a/src/panels/ToolsPanel.tsx
+++ b/src/panels/ToolsPanel.tsx
@@ -1,18 +1,23 @@
-// Inhalts-Panel „Werkzeuge" — die vertikale Werkzeug-Palette (ArchiCAD-/
-// Vectorworks-Stil): eine Zeile je Zeichenwerkzeug, jeweils Icon + Name, das
-// aktive Werkzeug hervorgehoben. Darunter — wenn das Wand-Werkzeug aktiv ist —
-// ein Wandtyp-Auswahlfeld, und ein kompakter Fang-Abschnitt mit Checkboxen.
+// Inhalts-Panel „Werkzeuge" — die Werkzeug-Palette (ArchiCAD-/Vectorworks-Stil).
+// Oben ein Umschalter „Liste ↔ Symbole" (Icon+Name als Zeilen ODER kompaktes
+// Icon-Raster). Darunter drei einheitlich gestylte Rubriken: 2D (Zeichnen),
+// 3D (BIM-Bauteile) und Bearbeiten (Ändern-Aktionen) — Werkzeuge UND Befehle
+// teilen denselben Knopf-Look (`.tp-item`), damit „Ändern" nicht mehr optisch
+// aus der Reihe fällt.
//
-// Daten/Handler kommen über usePanelHost (kein Prop-Drilling). Die Werkzeug-
-// Liste und ihre Metadaten stammen aus der Tools-Registry (TOOL_ORDER/getTool).
+// Daten/Handler kommen über usePanelHost (kein Prop-Drilling). Werkzeug-Metadaten
+// aus der Tools-Registry (getTool), Befehls-Labels aus der Command-Registry.
//
// Bezeichner englisch, UI-Text/Kommentare deutsch (CONVENTIONS.md). Alle sichtbaren
// Texte über t(...).
+import { useState } from "react";
import { t } from "../i18n";
import { usePanelHost } from "./host";
import type { ToolId } from "./host";
-import { TOOL_ORDER, getTool } from "../tools/tools";
+import { getTool } from "../tools/tools";
+import { getCommand } from "../commands/registry";
+import { CommandIcon } from "../ui/ribbon/CommandIcon";
// ── Icons ──────────────────────────────────────────────────────────────────
// Keine echten Asset-Icons vorhanden: schlichte Inline-SVG-Glyphen je Werkzeug
@@ -31,18 +36,17 @@ export function ToolIcon({ id }: { id: ToolId }) {
};
switch (id) {
case "select":
- // Pfeil-Cursor.
+ // Pfeil-Cursor (klassischer Zeiger mit Schweif).
return (
-
);
case "window":
- // Fenster: Rahmen-Rechteck mit Mittelsprosse (Verglasung).
+ // Fenster (SIA-Aufsicht): Wandöffnung mit doppelter Glaslinie.
return (
-
-
+
+
+
+
+
);
case "door":
- // Tür: Pfosten + Türblatt mit Schwenkbogen.
+ // Tür (SIA-Aufsicht): Türblatt aufrecht + Viertelkreis-Schwenkbogen.
return (
-
-
-
+
+
+
);
case "stair":
- // Treppensymbol: gestufte Linie (Tritte) + Lauflinie mit Pfeil.
+ // Treppe (SIA-Aufsicht): Wangen, gleichmäßige Tritte, Lauflinie mit
+ // Aufwärts-Pfeil (Idee: Vollbogen ersetzt durch eine echte Treppe).
return (
-
-
-
+
+
+
+
+
+
+
);
case "room":
@@ -118,10 +130,12 @@ export function ToolIcon({ id }: { id: ToolId }) {
);
case "arc":
- // Offener Halbbogen.
+ // Offener Bogen (gut 180°) mit Endpunkt-Markierungen.
return (
-
+
+
+
);
case "text":
@@ -147,44 +161,131 @@ export function ToolIcon({ id }: { id: ToolId }) {
}
}
+// ── Kategorien ───────────────────────────────────────────────────────────────
+// Werkzeuge/Befehle in drei Rubriken sortiert (Nutzerwunsch: „sortiere nach 2D
+// und 3D und Bearbeiten"). Befehlsnamen spiegeln die Ribbon-Registry
+// (ui/ribbon/ribbonItems.ts) — dort liegt die kanonische Liste; hier nur die
+// Panel-Gruppierung (2D-Zeichnen · 3D/BIM-Bauteile · Bearbeiten-Aktionen).
+const TOOLS_2D: ToolId[] = ["line", "polyline", "rect", "circle", "arc", "text", "textbox"];
+const TOOLS_3D: ToolId[] = ["wall", "ceiling", "window", "door", "stair", "room"];
+const COMMANDS_3D = ["column", "ceilingopening", "roof", "extrude", "sectionline", "viewline"];
+const COMMANDS_EDIT = ["move", "copy", "rotate", "mirror", "offset", "trim", "join", "measure"];
+
+type ToolsView = "list" | "icons";
+const VIEW_STORAGE_KEY = "dossier.toolsPanel.view";
+
+function loadView(): ToolsView {
+ try {
+ return localStorage.getItem(VIEW_STORAGE_KEY) === "icons" ? "icons" : "list";
+ } catch {
+ return "list";
+ }
+}
+
// ── Panel ────────────────────────────────────────────────────────────────────
export function ToolsPanel() {
const host = usePanelHost();
+ const [view, setView] = useState(loadView);
+
+ const chooseView = (v: ToolsView) => {
+ setView(v);
+ try {
+ localStorage.setItem(VIEW_STORAGE_KEY, v);
+ } catch {
+ /* Persistenz ist Best-Effort (privater Modus o. ä.). */
+ }
+ };
+
+ // Ein Werkzeug-Knopf (Icon + Name). Boden-gebundene (`floorOnly`) Werkzeuge
+ // sind ohne aktives Geschoss gesperrt; freie 2D-Werkzeuge bleiben nutzbar.
+ const toolButton = (id: ToolId) => {
+ const tool = getTool(id);
+ const active = host.activeTool === id;
+ const disabled = !!tool.floorOnly && !host.toolsEnabled;
+ const label = t(tool.labelKey);
+ const title = disabled ? t("tool.floorOnlyDisabled") : t(tool.hintKey(tool.init()));
+ return (
+
+ );
+ };
+
+ // Ein Befehls-Knopf (Ändern-/BIM-Kommando ohne eigenen Werkzeug-Modus) —
+ // gleicher Look wie die Werkzeuge (Nutzerwunsch: nicht „ganz anders").
+ const commandButton = (name: string) => {
+ const cmd = getCommand(name);
+ const label = cmd ? t(cmd.labelKey) : t(`cmd.${name}.label`);
+ const active = host.activeCommand === name;
+ return (
+
+ );
+ };
+
+ const bodyClass = "tp-body" + (view === "icons" ? " icons" : "");
return (
- {/* Werkzeug-Zeilen: Icon + Name, aktives hervorgehoben. */}
- {TOOL_ORDER.map((id) => {
- const tool = getTool(id);
- const active = host.activeTool === id;
- // Nur Boden-gebundene (`floorOnly`) Werkzeuge sind ohne aktives Geschoss
- // gesperrt; freie 2D-Werkzeuge (Linie/Kreis/Text/…) bleiben auf
- // Zeichnungsebenen nutzbar — Parität mit dem Ribbon (RibbonBar).
- const disabled = !!tool.floorOnly && !host.toolsEnabled;
- const title = disabled
- ? t("tool.floorOnlyDisabled")
- : t(tool.hintKey(tool.init()));
- const cls =
- "tool-row" + (active ? " active" : "") + (disabled ? " disabled" : "");
- return (
+ {/* Anzeige-Umschalter: nur Symbole ODER Symbol + Name (Liste). */}
+
+
- );
- })}
+
+
+
- {/* Wandtyp-/Deckentyp-Auswahl ist ins Attribute-Panel gewandert (Ribbon-UI
- Phase 3: Werkzeug-Sidebar nicht mehr im Default-Layout). Der Picker
- erscheint dort bei aktivem Wand-/Decken-Werkzeug. */}
+ {/* Auswahl-Werkzeug: immer als volle Zeile zuoberst (meistgenutzt). */}
+