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
@@ -0,0 +1,61 @@
|
||||
/*!
|
||||
* Tectum
|
||||
* Copyright © 2026 Machiel Heinen.
|
||||
* Alle rechten voorbehouden. Gebruik uitsluitend met schriftelijke toestemming.
|
||||
* Zie LICENTIE.md.
|
||||
*/
|
||||
// Menubalk: menu = { label, items: [{ label, icon, keys, run, enabled(), checked() } | { sep: true } | { head }] }.
|
||||
// Beschikbaarheid wordt bij het openen bepaald; is een menu open, dan opent hover het buurmenu.
|
||||
|
||||
window.Menubar = (() => {
|
||||
let root = null, menus = [], openIdx = -1;
|
||||
|
||||
function itemHtml(it, mi, ii) {
|
||||
if (it.sep) return '<div class="mb-sep"></div>';
|
||||
if (it.head) return `<div class="mb-head">${it.head}</div>`;
|
||||
const off = it.enabled && !it.enabled();
|
||||
const on = it.checked && it.checked();
|
||||
return `<button type="button" class="mb-item${on ? ' checked' : ''}" data-mi="${mi}" data-ii="${ii}"${off ? ' disabled' : ''}>
|
||||
<span class="mb-ico">${on ? '<i class="bi bi-check2"></i>' : it.icon ? `<i class="bi bi-${it.icon}"></i>` : ''}</span>
|
||||
<span class="mb-label">${it.label}</span><span class="mb-keys">${it.keys || ''}</span></button>`;
|
||||
}
|
||||
|
||||
function close() {
|
||||
if (openIdx < 0) return false;
|
||||
openIdx = -1;
|
||||
root.querySelectorAll('.mb-menu').forEach(m => m.classList.remove('open'));
|
||||
root.querySelectorAll('.mb-drop').forEach(d => { d.innerHTML = ''; });
|
||||
return true;
|
||||
}
|
||||
|
||||
function openMenu(i) {
|
||||
close();
|
||||
openIdx = i;
|
||||
const wrap = root.querySelectorAll('.mb-menu')[i];
|
||||
wrap.classList.add('open');
|
||||
wrap.querySelector('.mb-drop').innerHTML = menus[i].items.map((it, ii) => itemHtml(it, i, ii)).join('');
|
||||
}
|
||||
|
||||
function init(el, list) {
|
||||
root = el;
|
||||
menus = list;
|
||||
el.innerHTML = menus.map((m, i) => `<div class="mb-menu"><button type="button" class="mb-top" data-menu="${i}">${m.label}</button><div class="mb-drop" role="menu"></div></div>`).join('');
|
||||
el.addEventListener('click', (e) => {
|
||||
e.stopPropagation();
|
||||
const top = e.target.closest('[data-menu]');
|
||||
if (top) { const i = Number(top.dataset.menu); if (openIdx === i) close(); else openMenu(i); return; }
|
||||
const item = e.target.closest('.mb-item');
|
||||
if (!item || item.disabled) return;
|
||||
const it = menus[Number(item.dataset.mi)].items[Number(item.dataset.ii)];
|
||||
close();
|
||||
it.run();
|
||||
});
|
||||
el.addEventListener('mouseover', (e) => {
|
||||
const top = e.target.closest('[data-menu]');
|
||||
if (top && openIdx >= 0 && Number(top.dataset.menu) !== openIdx) openMenu(Number(top.dataset.menu));
|
||||
});
|
||||
document.addEventListener('click', close);
|
||||
}
|
||||
|
||||
return { init, close };
|
||||
})();
|
||||
Reference in New Issue
Block a user