Zurueck zum Vectorworks-Look — Custom Pill-Chrome statt raw native HTML
User-Klaerung: erwartet wird der polierte Vectorworks-Style, nicht rohe macOS-HTML-Form-Elemente. Vectorworks ist custom-gestylt um nativ auszusehen, aber mit konsistentem Toolbar-Polish. Zurueckgerollt: - BarSelect: Pill-Container (bg-item, border, border-radius 999) + Custom-SVG-Caret aus --select-arrow. appearance:none. Icon roh links (Userpraferenz). joinedRight macht rechte Pill-Kante flach. - BarButton: Pill-Container mit border + border-radius 999. active=true setzt accent-Background + bg-panel-Iconfarbe (klare Toggle-Anzeige). joinedLeft macht linke Kante flach fuer Verkettung. - View-Toggle (Top/Front/Right/Iso/Persp): Segmented-Pill-Gruppe analog Vectorworks. Innere Kanten ohne Border, Aussenkanten gerundet. Active-Button: accent-fill + Bold. - Custom-Massstab-Input: Pill-Chrome zurueck. .native-control CSS-Klasse bleibt definiert (zukuenftige Verwendung), wird aber in der Oberleiste nicht mehr referenziert. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
+66
-39
@@ -84,14 +84,10 @@ const pillSelect = {
|
|||||||
fontSize: 10,
|
fontSize: 10,
|
||||||
}
|
}
|
||||||
|
|
||||||
// BarSelect: Icon roh links + komplett system-natives <select>.
|
// BarSelect: Icon roh links + custom-pill <select>. Vectorworks-Stil —
|
||||||
// Kein Background, kein Border, kein Border-Radius — WebKit/macOS rendert
|
// dunkler Pill-Container, Caret rechts, joinedRight macht die rechte Kante
|
||||||
// seinen eigenen Combobox-Look auch im Ruhezustand (gewölbtes Feld mit
|
// flach fuer die Verkettung mit BarButton.
|
||||||
// Caret-Indikator rechts). `colorScheme: dark` triggert die Dark-Variante.
|
function BarSelect({ icon, value, onChange, title, disabled, width, children, joinedRight }) {
|
||||||
//
|
|
||||||
// joinedRight bleibt als Prop drin aber als no-op — native Felder koennen
|
|
||||||
// nicht visuell mit unseren Custom-Buttons verkettet werden.
|
|
||||||
function BarSelect({ icon, value, onChange, title, disabled, width, children }) {
|
|
||||||
return (
|
return (
|
||||||
<div title={title} style={{
|
<div title={title} style={{
|
||||||
display: 'inline-flex', alignItems: 'center', gap: 5,
|
display: 'inline-flex', alignItems: 'center', gap: 5,
|
||||||
@@ -102,38 +98,53 @@ function BarSelect({ icon, value, onChange, title, disabled, width, children })
|
|||||||
style={{ color: 'var(--text-muted)', flexShrink: 0 }} />
|
style={{ color: 'var(--text-muted)', flexShrink: 0 }} />
|
||||||
)}
|
)}
|
||||||
<select
|
<select
|
||||||
className="native-control"
|
|
||||||
value={value || ''}
|
value={value || ''}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
onChange={(e) => onChange(e.target.value)}
|
onChange={(e) => onChange(e.target.value)}
|
||||||
style={{
|
style={{
|
||||||
height: BAR_H, width,
|
height: BAR_H, width,
|
||||||
fontSize: 11,
|
background: 'var(--bg-item)',
|
||||||
colorScheme: 'dark',
|
color: 'var(--text-primary)',
|
||||||
flexShrink: 0,
|
border: '1px solid var(--border)',
|
||||||
|
borderTopLeftRadius: 999, borderBottomLeftRadius: 999,
|
||||||
|
borderTopRightRadius: joinedRight ? 0 : 999,
|
||||||
|
borderBottomRightRadius: joinedRight ? 0 : 999,
|
||||||
|
borderRight: joinedRight ? 'none' : '1px solid var(--border)',
|
||||||
|
padding: '0 26px 0 12px',
|
||||||
|
fontSize: 11, fontFamily: 'var(--font)',
|
||||||
|
appearance: 'none', WebkitAppearance: 'none',
|
||||||
|
backgroundImage: 'var(--select-arrow)',
|
||||||
|
backgroundRepeat: 'no-repeat',
|
||||||
|
backgroundPosition: 'right 10px center',
|
||||||
|
cursor: disabled ? 'not-allowed' : 'pointer',
|
||||||
|
flexShrink: 0, outline: 'none',
|
||||||
|
letterSpacing: 0,
|
||||||
}}
|
}}
|
||||||
>{children}</select>
|
>{children}</select>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// BarButton: bare <button class="native-control"> — macOS Push-Button
|
// BarButton: pill-foermiger Icon-Button im selben Stil wie BarSelect.
|
||||||
// Look (gewölbt, rounded). active=true setzt is-active fuer Bold-Text
|
// joinedLeft = linke Kante flach (dockt rechts an einen BarSelect-joinedRight).
|
||||||
// und Icon-Tint.
|
function BarButton({ icon, onClick, title, disabled, active, joinedLeft }) {
|
||||||
function BarButton({ icon, onClick, title, disabled, active }) {
|
|
||||||
return (
|
return (
|
||||||
<button
|
<button onClick={onClick} disabled={disabled} title={title}
|
||||||
className={`native-control${active ? ' is-active' : ''}`}
|
|
||||||
onClick={onClick} disabled={disabled} title={title}
|
|
||||||
style={{
|
style={{
|
||||||
height: BAR_H,
|
height: BAR_H, width: BAR_H,
|
||||||
fontSize: 11,
|
background: active ? 'var(--accent)' : 'var(--bg-item)',
|
||||||
colorScheme: 'dark',
|
border: '1px solid var(--border)',
|
||||||
flexShrink: 0,
|
borderTopLeftRadius: joinedLeft ? 0 : 999,
|
||||||
|
borderBottomLeftRadius: joinedLeft ? 0 : 999,
|
||||||
|
borderTopRightRadius: 999, borderBottomRightRadius: 999,
|
||||||
|
borderLeft: joinedLeft ? 'none' : '1px solid var(--border)',
|
||||||
|
display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
|
||||||
|
cursor: disabled ? 'not-allowed' : 'pointer',
|
||||||
|
opacity: disabled ? 0.5 : 1, flexShrink: 0,
|
||||||
|
padding: 0,
|
||||||
}}>
|
}}>
|
||||||
<Icon name={icon} size={13}
|
<Icon name={icon} size={13}
|
||||||
style={{ color: active ? 'var(--accent)' : undefined,
|
style={{ color: active ? 'var(--bg-panel)' : 'var(--text-muted)' }} />
|
||||||
verticalAlign: 'middle' }} />
|
|
||||||
</button>
|
</button>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -317,25 +328,38 @@ export default function OberleisteApp() {
|
|||||||
</button>
|
</button>
|
||||||
<div style={sep} />
|
<div style={sep} />
|
||||||
{/* ====== VIEW (Top/Front/Right/Iso/Persp + Kamera) ======
|
{/* ====== VIEW (Top/Front/Right/Iso/Persp + Kamera) ======
|
||||||
Individuelle native Push-Buttons. Active-State via is-active
|
Segmented-Pill-Gruppe analog Vectorworks. Active = accent fill. */}
|
||||||
(Bold + Icon-Tint). Kein Pill-Container. */}
|
<div style={{ display: 'inline-flex', flexShrink: 0 }}>
|
||||||
{VIEWS.map(v => (
|
{VIEWS.map((v, idx) => {
|
||||||
|
const isFirst = idx === 0
|
||||||
|
const isLast = idx === VIEWS.length - 1
|
||||||
|
const isActive = matchView(v.value)
|
||||||
|
return (
|
||||||
<button
|
<button
|
||||||
key={v.value}
|
key={v.value}
|
||||||
className={`native-control${matchView(v.value) ? ' is-active' : ''}`}
|
|
||||||
onClick={() => setView(v.value)}
|
onClick={() => setView(v.value)}
|
||||||
title={`Ansicht ${v.label}`}
|
title={`Ansicht ${v.label}`}
|
||||||
style={{
|
style={{
|
||||||
height: BAR_H, fontSize: 11,
|
height: BAR_H, padding: '0 10px',
|
||||||
colorScheme: 'dark', flexShrink: 0,
|
background: isActive ? 'var(--accent)' : 'var(--bg-item)',
|
||||||
|
color: isActive ? 'var(--bg-panel)' : 'var(--text-primary)',
|
||||||
|
border: '1px solid var(--border)',
|
||||||
|
borderLeft: isFirst ? '1px solid var(--border)' : 'none',
|
||||||
|
borderTopLeftRadius: isFirst ? 999 : 0,
|
||||||
|
borderBottomLeftRadius: isFirst ? 999 : 0,
|
||||||
|
borderTopRightRadius: isLast ? 999 : 0,
|
||||||
|
borderBottomRightRadius: isLast ? 999 : 0,
|
||||||
|
display: 'inline-flex', alignItems: 'center', gap: 4,
|
||||||
|
fontSize: 10, fontWeight: isActive ? 600 : 500,
|
||||||
|
cursor: 'pointer', flexShrink: 0,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Icon name={v.icon} size={13}
|
<Icon name={v.icon} size={13} />
|
||||||
style={{ verticalAlign: 'middle', marginRight: 4,
|
<span>{v.label}</span>
|
||||||
color: matchView(v.value) ? 'var(--accent)' : undefined }} />
|
|
||||||
{v.label}
|
|
||||||
</button>
|
</button>
|
||||||
))}
|
)
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
<BarButton icon="videocam" onClick={() => openKameraPanel()}
|
<BarButton icon="videocam" onClick={() => openKameraPanel()}
|
||||||
title="Kamera-Einstellungen (Position, Target, Linse, Presets)" />
|
title="Kamera-Einstellungen (Position, Target, Linse, Presets)" />
|
||||||
|
|
||||||
@@ -393,7 +417,6 @@ export default function OberleisteApp() {
|
|||||||
{customMode ? (
|
{customMode ? (
|
||||||
<input
|
<input
|
||||||
ref={customInputRef}
|
ref={customInputRef}
|
||||||
className="native-control"
|
|
||||||
disabled={isPerspective}
|
disabled={isPerspective}
|
||||||
type="text" placeholder="1:N"
|
type="text" placeholder="1:N"
|
||||||
value={draft}
|
value={draft}
|
||||||
@@ -405,9 +428,13 @@ export default function OberleisteApp() {
|
|||||||
onBlur={applyDraft}
|
onBlur={applyDraft}
|
||||||
style={{
|
style={{
|
||||||
height: BAR_H, width: 100,
|
height: BAR_H, width: 100,
|
||||||
fontSize: 11,
|
background: 'var(--bg-item)',
|
||||||
|
color: 'var(--text-primary)',
|
||||||
|
border: '1px solid var(--border)',
|
||||||
|
borderRadius: 999,
|
||||||
|
padding: '0 12px', fontSize: 11,
|
||||||
fontFamily: 'DM Mono, monospace',
|
fontFamily: 'DM Mono, monospace',
|
||||||
colorScheme: 'dark',
|
outline: 'none',
|
||||||
}}
|
}}
|
||||||
title="Massstab eingeben (Enter = uebernehmen, Esc = abbrechen)"
|
title="Massstab eingeben (Enter = uebernehmen, Esc = abbrechen)"
|
||||||
/>
|
/>
|
||||||
|
|||||||
Reference in New Issue
Block a user