v0.7.1: UI-overhaul, ribbon vervangen door de indeling van CAD/BIM-pakketten met elke functie op één plek: bovenbalk met menu Bestand (nieuw, openen, opslaan, exporteren, projectgegevens, kosten & tijden) · Beeld · Help, de ontwerpen als tabs en de knop Opslaan; links de structuur met inklapbare groepen (onthouden, groep met de selectie klapt vanzelf open); werkbalk boven de viewports met gereedschap (Selecteren V, Binnenwand W, Ruimte R, Inrichting I, opties van het gereedschap ernaast, Unit toevoegen) en weergave (één Lagen-menu met bouwfase voor 2D en 3D, Omgeving, Doorsnede X, Render, Lopen L, Rapport 4, 2D + 3D / 2D / 3D met 1/2/3); rechts het eigenschappenpaneel (Inspector: selectie met kruimelpad, of de woning met kerncijfers en inklapbare secties Gevel, Dak, Binnen, Verlichting, Elektra, Constructie); statusbalk met hint en meldingen; wand- en vloer/dak-editor in dezelfde indeling (paneel rechts met tab Resultaat, terug met ← Woning of Esc); sneltoetsenoverzicht (?), Ctrl+O, Ctrl+\ panelen verbergen; rapport als masonry; dubbele functies weg (lagenbalk, Beeld-tab en Weergave-filter, export en kosten op twee plekken, Snel nieuw); oude onderdelen gelijkgetrokken (dialoogknoppen, materiaalknoppen, chassis als schakelaar, eenheden); weergavelagen (ViewLayers) i.p.v. bouwfasen, elk los aan/uit; render-export met Blender-script voor de lampen; elektraleidingen boven een vals plafond en haaks binnen de units bij een L/T-vorm
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
adb3c74f85
commit
ab0dca9bb5
+50
-10
@@ -128,16 +128,56 @@ window.UI = (() => {
|
||||
if (el) el.addEventListener('change', (e) => { fn(e.target.checked); after && after(); });
|
||||
}
|
||||
|
||||
function cycle3D(el) {
|
||||
el.classList.remove('fullscreen-2d');
|
||||
if (!el.classList.contains('fullscreen-3d')) el.classList.add('fullscreen-3d');
|
||||
else if (!el.classList.contains('render-only')) el.classList.add('render-only');
|
||||
else el.classList.remove('fullscreen-3d', 'render-only');
|
||||
}
|
||||
function toggle2D(el) {
|
||||
el.classList.remove('fullscreen-3d', 'render-only');
|
||||
el.classList.toggle('fullscreen-2d');
|
||||
// Weergave van een editor: klassen fullscreen-2d/-3d op het editor-element (de looptocht bewaart en herstelt className).
|
||||
const VIEWS = [
|
||||
{ key: 'split', icon: 'layout-split', label: '2D + 3D', key1: '1' },
|
||||
{ key: '2d', icon: 'square', label: 'Alleen 2D', key1: '2' },
|
||||
{ key: '3d', icon: 'box', label: 'Alleen 3D', key1: '3' }
|
||||
];
|
||||
const viewOf = (el) => el.classList.contains('fullscreen-3d') ? '3d' : el.classList.contains('fullscreen-2d') ? '2d' : 'split';
|
||||
function setView(el, mode) {
|
||||
el.classList.toggle('fullscreen-3d', mode === '3d');
|
||||
el.classList.toggle('fullscreen-2d', mode === '2d');
|
||||
el.classList.remove('render-only');
|
||||
el.querySelectorAll('[data-view]').forEach(b => b.classList.toggle('active', b.dataset.view === mode));
|
||||
}
|
||||
|
||||
return { esc, icon, hint, num, range, onRange, setRange, sel, toggle, color, onColor, text, onText, section, info, warn, grid, button, actions, tabs, wireTabs, specCard, onNum, onSel, onToggle, cycle3D, toggle2D };
|
||||
const tb = (label, iconName, attrs, cls) =>
|
||||
`<button type="button" class="tb-btn${cls ? ' ' + cls : ''}" ${attrs || ''}>${iconName ? icon(iconName) : ''}${label ? `<span>${label}</span>` : ''}</button>`;
|
||||
const tbSep = () => '<span class="tb-sep"></span>';
|
||||
const viewSeg = (mode) => `<div class="tb-seg" role="group" aria-label="Weergave">${VIEWS.map(v =>
|
||||
tb('', v.icon, `data-view="${v.key}" title="${v.label} (${v.key1})"`, v.key === mode ? 'active' : '')).join('')}</div>`;
|
||||
|
||||
// Uitklappaneel onder een knop; sluit bij klik buiten, Esc of een andere popover.
|
||||
let openPop = null;
|
||||
function popover(btn, panel) {
|
||||
const close = () => { panel.classList.remove('open'); btn.classList.remove('open'); if (openPop === close) openPop = null; };
|
||||
btn.addEventListener('click', (e) => {
|
||||
e.stopPropagation();
|
||||
const was = panel.classList.contains('open');
|
||||
if (openPop) openPop();
|
||||
if (!was) { panel.classList.add('open'); btn.classList.add('open'); openPop = close; }
|
||||
});
|
||||
panel.addEventListener('click', (e) => e.stopPropagation());
|
||||
return close;
|
||||
}
|
||||
const closePopovers = () => { if (openPop) { openPop(); return true; } return false; };
|
||||
document.addEventListener('click', () => closePopovers());
|
||||
|
||||
// Kaarten verdelen over kolommen van min. minW breed; telkens in de kortste kolom. Opnieuw aanroepen bij een andere breedte.
|
||||
function masonry(el, minW, gap) {
|
||||
if (!el) return;
|
||||
gap = gap === undefined ? 12 : gap;
|
||||
const cards = el._cards || (el._cards = [...el.children]);
|
||||
const n = Math.max(1, Math.floor((el.clientWidth + gap) / (minW + gap)));
|
||||
if (el._cols === n) return;
|
||||
el._cols = n;
|
||||
el.classList.add('ui-masonry');
|
||||
const cols = Array.from({ length: n }, () => { const c = document.createElement('div'); c.className = 'ui-masonry-col'; return c; });
|
||||
el.replaceChildren(...cols);
|
||||
cards.forEach(card => cols.reduce((a, b) => b.offsetHeight < a.offsetHeight ? b : a).appendChild(card));
|
||||
}
|
||||
|
||||
return { esc, icon, hint, num, range, onRange, setRange, sel, toggle, color, onColor, text, onText, section, info, warn, grid, button, actions, tabs, wireTabs, specCard, onNum, onSel, onToggle,
|
||||
VIEWS, viewOf, setView, tb, tbSep, viewSeg, popover, closePopovers, masonry };
|
||||
})();
|
||||
|
||||
Reference in New Issue
Block a user