Panels poliert: Ebenenkombi in Oberleiste, Satelliten-Dialoge, Caps weg, Perf
- Ebenenkombination raus aus Ebenen-Panel, in Oberleiste-Topbar + Editor-Satellite (AusschnittLayerDialog embedded). doc.Strings haelt active_comb_name, auto-clear bei manueller Eye/Lock-Aenderung. - EbenenSettingsDialog jetzt Satellite mit Ebene-Picker-Dropdown (auto-save on switch via SAVE_KEEP). - Per-Ausschnitt Einstellungen-Satellite (Massstab, Display, Overrides, Ebenenkombi). Alte 'Sichtbarkeit bearbeiten'-Option entfernt. - Layouts/Ausschnitte: Top-Header weg, Sticky-Footer mit Anzahl + Aktionen. LayoutDialog ist jetzt Satellite mit Format-Live-Preview. - Panel-Captions + Default-Ebenen-Namen auf Mixed-Case (Ausschnitte, Ebenen, Waende ...). Nur DOSSIER bleibt caps. - DimensionenApp: Card-Optik raus, REF-Wuerfel mit Kreisen statt Quadraten + Hover-Scale. - GeschossManager angeglichen an EbenenManager: Rechtsklick-Menue, Lock-Button, Delete-X, Duplizieren. layer_builder honoriert z.locked. - Active Sublayer folgt jetzt dem Geschoss-Wechsel (gleicher Code unter neuem Parent). Performance Geschoss-Wechsel: - elemente._send_state() ersetzt durch _notify_active_geschoss() (Partial-Push statt 200+ Elements re-enumerieren). - _apply_visibility dedupe via sticky last-applied-signature (STATE_SYNC-Echo loopt nicht mehr durch alle Layer). - _update_clipping nur wenn alt oder neu hasClipping=True. - Redundante doc.Views.Redraw() im CPlane-Pfad entfernt — die folgende apply_visibility-Roundtrip redrawt 30ms spaeter ohnehin. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -255,9 +255,6 @@ function SortHeader({ label, sortKey, sortBy, sortDir, onSort, style }) {
|
||||
|
||||
export default function EbenenManager({
|
||||
ebenen, activeCode, onActiveChange, onChange, mode, onModeChange, hatchPatterns,
|
||||
combinations = [], activeCombName = null,
|
||||
onPickCombination, onSaveCurrentCombination, onDeleteCombination,
|
||||
onEditCombinations, onUserVisibilityChange,
|
||||
}) {
|
||||
const [sortBy, setSortBy] = useState('code')
|
||||
const [sortDir, setSortDir] = useState('asc')
|
||||
@@ -306,12 +303,10 @@ export default function EbenenManager({
|
||||
const handleToggleVisible = (code) => {
|
||||
const cur = ebenen.find(e => e.code === code)
|
||||
if (cur) updateByCode(code, { visible: !(cur.visible !== false) })
|
||||
if (onUserVisibilityChange) onUserVisibilityChange()
|
||||
}
|
||||
const handleToggleLock = (code) => {
|
||||
const cur = ebenen.find(e => e.code === code)
|
||||
if (cur) updateByCode(code, { locked: !cur.locked })
|
||||
if (onUserVisibilityChange) onUserVisibilityChange()
|
||||
}
|
||||
const handleColorChange = (code, color) => {
|
||||
updateByCode(code, { color })
|
||||
@@ -426,58 +421,6 @@ export default function EbenenManager({
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* Ebenenkombinationen — Label + Dropdown + Save-As-Plus */}
|
||||
<div style={{
|
||||
display: 'flex', flexDirection: 'column', gap: 4,
|
||||
padding: '6px 14px',
|
||||
background: 'var(--bg-section)',
|
||||
borderBottom: '1px solid var(--border-light)',
|
||||
}}>
|
||||
<span className="label-xs">Ebenenkombination</span>
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
|
||||
<select
|
||||
value={activeCombName || '__custom__'}
|
||||
onChange={(ev) => {
|
||||
const v = ev.target.value
|
||||
if (v === '__custom__') return
|
||||
if (v === '__delete__') {
|
||||
if (activeCombName && onDeleteCombination) onDeleteCombination(activeCombName)
|
||||
return
|
||||
}
|
||||
if (onPickCombination) onPickCombination(v)
|
||||
}}
|
||||
style={{ flex: 1, minWidth: 0 }}
|
||||
title={activeCombName ? `Aktiv: ${activeCombName}` : 'Eigene Sichtbarkeit (keine Kombination)'}
|
||||
>
|
||||
<option value="__custom__">{activeCombName ? activeCombName : 'Eigene'}</option>
|
||||
{combinations.length > 0 && <option disabled>──────────</option>}
|
||||
{combinations.map(p => (
|
||||
<option key={p.name} value={p.name}>{p.name}</option>
|
||||
))}
|
||||
{activeCombName && combinations.some(p => p.name === activeCombName) && (
|
||||
<>
|
||||
<option disabled>──────────</option>
|
||||
<option value="__delete__">🗑 Aktuelle löschen</option>
|
||||
</>
|
||||
)}
|
||||
</select>
|
||||
<button
|
||||
className="btn-icon-sm"
|
||||
onClick={() => onSaveCurrentCombination && onSaveCurrentCombination()}
|
||||
title="Aktuelle Sichtbarkeit als neue Kombination speichern"
|
||||
>
|
||||
<Icon name="add" size={14} />
|
||||
</button>
|
||||
<button
|
||||
className="btn-icon-sm"
|
||||
onClick={() => onEditCombinations && onEditCombinations()}
|
||||
title="Alle Kombinationen bearbeiten (Dialog)"
|
||||
>
|
||||
<Icon name="edit" size={13} />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style={{
|
||||
display: 'flex', flexDirection: 'column', gap: 4,
|
||||
padding: '6px 14px',
|
||||
@@ -512,7 +455,6 @@ export default function EbenenManager({
|
||||
const anyVisible = ebenen.some(e => e.visible !== false)
|
||||
// Wenn irgendeine sichtbar -> alle aus. Wenn keine sichtbar -> alle an.
|
||||
onChange(ebenen.map(e => ({ ...e, visible: !anyVisible })))
|
||||
if (onUserVisibilityChange) onUserVisibilityChange()
|
||||
}}
|
||||
title={ebenen.every(e => e.visible !== false)
|
||||
? 'Alle Ebenen ausblenden'
|
||||
@@ -534,7 +476,6 @@ export default function EbenenManager({
|
||||
onClick={() => {
|
||||
const anyLocked = ebenen.some(e => e.locked === true)
|
||||
onChange(ebenen.map(e => ({ ...e, locked: !anyLocked })))
|
||||
if (onUserVisibilityChange) onUserVisibilityChange()
|
||||
}}
|
||||
title={ebenen.every(e => e.locked === true)
|
||||
? 'Alle Ebenen entsperren'
|
||||
|
||||
Reference in New Issue
Block a user