From c22aef6b65730c5ef5b41a33c3ca1c668b842ee9 Mon Sep 17 00:00:00 2001 From: karim Date: Wed, 20 May 2026 21:52:36 +0200 Subject: [PATCH] Oberleiste Vectorworks-Style: Icon links + rechteckige Bar-Widgets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit User-Referenz: Vectorworks Topbar. Drei Cues uebernommen: - Icon-Kompartiment links im Dropdown (statt UPPERCASE Group-Label oben) - Rechteckige Form mit dezenter Trennlinie zwischen Icon-Box und Inhalt - Verbundene Widgets (Select + Settings-Gear) als eine visuelle Einheit Neue Komponenten in OberleisteApp.jsx: - BarSelect: [Icon | Native-Select | Caret] in einer 24px-Container-Box. appearance:none entfernt den nativen Pfeil, eigener arrow_drop_down rechts. joinedRight-Flag fuer nahtloses Anschliessen an einen BarButton. - BarButton: quadratischer Icon-Button, joinedLeft kein doppelter Border, active=true → Accent-Background (fuer Toggles wie Print-View). Migrierte Gruppen: - View: 5 Toggle-Buttons in einem zusammenhaengenden Rahmen (kein Group-Label), selektierter Button accent-gefuellt analog VW Custom-View-Highlight - Display: BarSelect (lightbulb icon) - Masse: BarSelect joinedRight + BarButton joinedLeft (zahnrad) - Massstab: Live-Zoom-Chip (eigene Box), BarSelect (straighten icon), BarButton (percent / fit_screen / center_focus_strong) - Print/Edit-Toggle: BarButton mit active-State Stack-Block (Overrides + Kombi) bleibt erst — separate Architektur, nicht im Vectorworks-Vergleich enthalten. Migration spaeter wenn Bedarf. PILL_H bleibt fuer nicht-migrierte Stellen, BAR_H = 24 fuer die neuen. Co-Authored-By: Claude Opus 4.7 --- src/OberleisteApp.jsx | 246 +++++++++++++++++++++++++++--------------- 1 file changed, 157 insertions(+), 89 deletions(-) diff --git a/src/OberleisteApp.jsx b/src/OberleisteApp.jsx index 25f3420..eedf03c 100644 --- a/src/OberleisteApp.jsx +++ b/src/OberleisteApp.jsx @@ -59,15 +59,17 @@ function parseScale(input) { } // --------------------------------------------------------------------------- -// Material-UI-Style: alle Pills auf einheitliche Hoehe (PILL_H) -// nutzt globale Klassen aus index.css fuer Look (border-radius, colors) +// Vectorworks-inspirierte Bar-Widgets: Icon links, Label/Select Mitte, +// Caret rechts — alle in einem rechteckigen Container, sichtbare Trennung +// zwischen Icon-Kompartiment und Inhalt. -const PILL_H = 20 // Einheits-Hoehe fuer alle Bar-Elemente +const PILL_H = 20 // alte Pill-Hoehe (Buttons/Chips die nicht migriert sind) +const BAR_H = 24 // neue Widget-Hoehe (BarSelect, BarButton, BarGroup) const sep = { - width: 1, height: 18, + width: 1, height: 22, background: 'var(--border)', flexShrink: 0, - margin: '0 2px', + margin: '0 4px', } const groupLabel = { fontSize: 9, color: 'var(--text-muted)', textTransform: 'uppercase', @@ -80,6 +82,71 @@ const pillSelect = { padding: '0 20px 0 10px', boxSizing: 'border-box', fontSize: 10, } + +// BarSelect: Icon-Kompartiment links | Native-Select Mitte | Caret rechts +function BarSelect({ icon, value, onChange, title, disabled, width, children, joinedRight }) { + return ( +
+
+ +
+ + +
+ ) +} + +// BarButton: quadratischer Icon-Button, gleiche Hoehe wie BarSelect. +// joinedLeft: wenn rechts von einem BarSelect sitzt (kein doppelter Border). +function BarButton({ icon, onClick, title, disabled, joinedLeft, active }) { + return ( + + ) +} const pillInput = { height: PILL_H, lineHeight: PILL_H + 'px', padding: '0 8px', boxSizing: 'border-box', @@ -265,87 +332,86 @@ export default function OberleisteApp() {
- {/* ====== GRUPPE: VIEW ====== */} - View - {VIEWS.map(v => ( - setView(v.value)} - active={matchView(v.value)} - icon={v.icon} - label={v.label} - title={`Ansicht ${v.label}`} - /> - ))} - + {/* ====== VIEW (Top/Front/Right/Iso/Persp + Kamera) ====== + Kein Group-Label — die Buttons selber kommunizieren ihren Zweck. */} +
+ {VIEWS.map((v, idx) => ( + + ))} +
+ openKameraPanel()} + title="Kamera-Einstellungen (Position, Target, Linse, Presets)" />
- {/* ====== GRUPPE: DISPLAY-MODE ====== */} - Display - +
- {/* ====== GRUPPE: MASSE ====== */} - Masse - - + + openMasseSettings()} + title="Masse bearbeiten / neues anlegen" joinedLeft />
- {/* ====== GRUPPE: MASSSTAB ====== */} - Massstab - - {/* Live-Zoom des Viewports — immer sichtbar bei Parallelprojektion, - unabhaengig davon ob ein Massstab im Dropdown gepinnt ist oder - nicht. Nur in Perspective ist die Anzeige nicht sinnvoll. */} + {/* ====== MASSSTAB ====== */} + {/* Live-Zoom Chip mit Mass-Icon */} +
{isPerspective ? '—' : fmtScale(scaleVal)} - +
{customMode ? ( ) : ( - + )} - = 10 ? Math.round(appliedScale) : appliedScale})` : 'Erst einen Massstab wählen'} - /> - - - setShowLineweights(!state.showLineweights)} - active={state.showLineweights} - label={state.showLineweights ? 'Print' : 'Edit'} - title={state.showLineweights ? 'Print-View aktiv — klick zum Ausschalten' : 'Strichstärken anzeigen (Print-View)'} + + + + setShowLineweights(!state.showLineweights)} + title={state.showLineweights + ? 'Print-View aktiv — klick zum Ausschalten' + : 'Strichstärken anzeigen (Print-View)'} />