v0.7.2: fixes uit de code-review van v0.7.1: elektraleidingen nemen niet langer het valse plafond van de buurruimte door de wand heen over (gebied zonder functie = geen vals plafond) en meten begin/eind 50 mm de ruimte in, zodat de zigzag bij een overgang vals plafond/dak verdwijnt (Amstel 249,9 → 246,8 m, 16 van 68 leidingen strakker); elektra en schoorsteen snijden mee met de doorsnede (geen zwevende buizen); PDF en de plaatfase van de IFC bouwen geen buizen meer; schoorsteen in 2D en 3D op de laag Gevelbekleding; Esc sluit elke dialoog via Annuleren en sneltoetsen gaan niet meer naar de editor erachter; toets 3 sluit het rapport; menu en popovers sluiten elkaar (één uitklapper tegelijk); paneelkop ge-escaped; na slepen/pannen buiten de plattegrond wordt de volgende klik niet meer ingeslikt en blijft de cursor van het gereedschap; "Alles" in Lagen zet ook beplating binnen/buiten terug; laag uit met een selectie erin werkt het paneel bij; opgeruimd: gedeelde werkbalk (UI.editorBar) voor woning, wand en vloer, één knopbouwer (UI.btnOf), dichte paneelsecties pas opgebouwd bij openen, dode knopacties weg, binnenwand verwijderen op één plek, doorgestuurde acties uit één lijst, render-export "alleen afgewerkt" volledig in HouseModel (finishedOnly), structuurboom springt alleen bij een andere selectie
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
ab0dca9bb5
commit
89cadbebf7
+70
-94
@@ -41,7 +41,7 @@ const HOUSE_TEMPLATE = `
|
||||
</div>
|
||||
<div class="material-info">Geldt voor elk blad van de woning-PDF. Titel en elementnummer worden per blad automatisch ingevuld.</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" id="house-project-cancel" class="ui-btn">Annuleren</button>
|
||||
<button type="button" id="house-project-cancel" class="ui-btn" data-esc>Annuleren</button>
|
||||
<button type="button" id="house-project-save" class="ui-btn ui-btn-primary">Opslaan</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -198,6 +198,7 @@ function mountHouseEditor(container, callbacks) {
|
||||
|
||||
// Structuur: groepen in-/uitklapbaar (onthouden); een groep met het actieve onderdeel of de selectie klapt vanzelf open.
|
||||
const NAV_PREF = 'tectum.nav.closed';
|
||||
let navActiveKey = null;
|
||||
let navClosed;
|
||||
try { navClosed = new Set(JSON.parse(localStorage.getItem(NAV_PREF) || 'null') || ['iw', 'rooms', 'fixtures']); } catch (e) { navClosed = new Set(['iw', 'rooms', 'fixtures']); }
|
||||
function renderNav(parts) {
|
||||
@@ -262,8 +263,11 @@ function mountHouseEditor(container, callbacks) {
|
||||
}
|
||||
const tree = document.getElementById('house-nav-tree');
|
||||
tree.innerHTML = html;
|
||||
// Alleen in beeld schuiven als de selectie of het onderdeel verandert, niet bij elke herberekening.
|
||||
const key = activePart + '|' + JSON.stringify(selection);
|
||||
const act = tree.querySelector('.hn-item.active');
|
||||
if (act) act.scrollIntoView({ block: 'nearest' });
|
||||
if (act && key !== navActiveKey) act.scrollIntoView({ block: 'nearest' });
|
||||
navActiveKey = key;
|
||||
}
|
||||
|
||||
document.getElementById('house-nav-tree').addEventListener('click', (e) => {
|
||||
@@ -418,23 +422,25 @@ function mountHouseEditor(container, callbacks) {
|
||||
['room', 'Ruimte', 'paint-bucket', 'R', 'Functie kiezen en in een ruimte klikken; de ruimte loopt tot de wanden'],
|
||||
['fixture', 'Inrichting', 'lamp', 'I', 'Stuk kiezen en in de plattegrond klikken (D = draaien)']
|
||||
];
|
||||
toolbar.innerHTML = `<div class="tb-group tb-tools" role="group" aria-label="Gereedschap">${TOOLS.map(([k, label, ic, key, hint]) =>
|
||||
UI.tb(label, ic, `data-ho-tool="${k}" title="${label} (${key}): ${hint}"`)).join('')}</div>
|
||||
${UI.tbSep()}${UI.tb('Unit', 'plus-square', 'data-tb="add-unit" title="Unit toevoegen aan de geselecteerde (of laatste) unit"')}
|
||||
<div class="tb-group tb-options" id="ho-tool-options"></div>
|
||||
<div class="tb-spacer"></div>
|
||||
<div class="tb-group tb-view" id="ho-view-group"></div>
|
||||
<div class="tb-group tb-section" id="ho-section-group">
|
||||
${UI.tb('Doorsnede', 'scissors', 'data-tb="section" title="Horizontale doorsnede (X)"')}
|
||||
<span class="tb-range"><input type="range" id="ho-section" min="100" max="4000" step="50" value="${view3D.sectionMM}" aria-label="Hoogte doorsnede"><span id="ho-section-val"></span></span>
|
||||
</div>
|
||||
${UI.tb('', 'camera', 'data-tb="render" title="Render: elke lamp en spot als echte lichtbron"')}
|
||||
${UI.tb('', 'person-walking', 'data-tb="walk" title="Lopen (L): W/S vooruit/achteruit, A/D opzij, slepen = rondkijken, E = deur/schakelaar"')}
|
||||
${UI.tbSep()}
|
||||
${UI.tb('Rapport', 'clipboard-data', 'data-tb="report" title="Rapport in plaats van de plattegrond (4): transport, gewicht, kosten, hout en plaatwerk"')}
|
||||
${UI.viewSeg(UI.viewOf(document.getElementById('house-overview')))}`;
|
||||
const bar = UI.editorBar(toolbar, document.getElementById('house-overview'), {
|
||||
left: `<div class="tb-group tb-tools" role="group" aria-label="Gereedschap">${TOOLS.map(([k, label, ic, key, hint]) =>
|
||||
UI.tb(label, ic, `data-ho-tool="${k}" title="${label} (${key}): ${hint}"`)).join('')}</div>
|
||||
${UI.tbSep()}${UI.tb('Unit', 'plus-square', 'data-tb="add-unit" title="Unit toevoegen aan de geselecteerde (of laatste) unit"')}
|
||||
<div class="tb-group tb-options" id="ho-tool-options"></div>`,
|
||||
after: `<div class="tb-group tb-section" id="ho-section-group">
|
||||
${UI.tb('Doorsnede', 'scissors', 'data-tb="section" title="Horizontale doorsnede (X)"')}
|
||||
<span class="tb-range"><input type="range" id="ho-section" min="100" max="4000" step="50" value="${view3D.sectionMM}" aria-label="Hoogte doorsnede"><span id="ho-section-val"></span></span>
|
||||
</div>
|
||||
${UI.tb('', 'camera', 'data-tb="render" title="Render: elke lamp en spot als echte lichtbron"')}
|
||||
${UI.tb('', 'person-walking', 'data-tb="walk" title="Lopen (L): W/S vooruit/achteruit, A/D opzij, slepen = rondkijken, E = deur/schakelaar"')}
|
||||
${UI.tbSep()}
|
||||
${UI.tb('Rapport', 'clipboard-data', 'data-tb="report" title="Rapport in plaats van de plattegrond (4): transport, gewicht, kosten, hout en plaatwerk"')}`,
|
||||
onResize,
|
||||
layers: { layers: view3D.layers, onChange: setLayers },
|
||||
onSky: (m) => { skyMode = m; applyRenderMode(); },
|
||||
beforeView: (mode) => { setWalk(false); if (mode === '3d') toggleReport(false); view3D.mode = mode; }
|
||||
});
|
||||
toolbar.querySelectorAll('[data-ho-tool]').forEach(b => b.addEventListener('click', () => setTool(b.dataset.hoTool)));
|
||||
toolbar.querySelectorAll('[data-view]').forEach(b => b.addEventListener('click', () => setView(b.dataset.view)));
|
||||
toolbar.addEventListener('click', (e) => {
|
||||
const b = e.target.closest('[data-tb]');
|
||||
if (!b) return;
|
||||
@@ -446,9 +452,6 @@ function mountHouseEditor(container, callbacks) {
|
||||
else if (a === 'report') toggleReport();
|
||||
b.blur();
|
||||
});
|
||||
const viewGroup = document.getElementById('ho-view-group');
|
||||
const layerMenu = ViewLayers.createMenu(viewGroup, { layers: view3D.layers, onChange: setLayers });
|
||||
Skybox.createToggle(viewGroup, (m) => { skyMode = m; applyRenderMode(); });
|
||||
function syncToolbar() {
|
||||
const q = (a) => toolbar.querySelector(`[data-tb="${a}"]`);
|
||||
q('section').classList.toggle('active', view3D.section);
|
||||
@@ -464,10 +467,10 @@ function mountHouseEditor(container, callbacks) {
|
||||
function setLayers(l) {
|
||||
view3D.layers = ViewLayers.normalize(l);
|
||||
const L = view3D.layers;
|
||||
if (selection && ((!L.ruimtes && (selection.type === 'room' || selection.type === 'region')) ||
|
||||
(!L.inrichting && selection.type === 'fixture') || (!L.elektra && selection.type === 'elektra'))) selection = null;
|
||||
layerMenu.set(L);
|
||||
scheduleRefresh({ keepProps: true });
|
||||
const hidden = selection && ((!L.ruimtes && (selection.type === 'room' || selection.type === 'region')) ||
|
||||
(!L.inrichting && selection.type === 'fixture') || (!L.elektra && selection.type === 'elektra'));
|
||||
if (hidden) selection = null;
|
||||
scheduleRefresh({ keepProps: !hidden }); // vervalt de selectie, dan ook het paneel bijwerken
|
||||
}
|
||||
const sectionInput = document.getElementById('ho-section');
|
||||
function syncSectionRow() {
|
||||
@@ -667,7 +670,7 @@ function mountHouseEditor(container, callbacks) {
|
||||
tool = t;
|
||||
drawStart = null;
|
||||
document.querySelectorAll('[data-ho-tool]').forEach(b => b.classList.toggle('active', b.dataset.hoTool === t));
|
||||
canvas.style.cursor = t === 'iw' || t === 'fixture' ? 'crosshair' : t === 'room' ? 'cell' : 'default';
|
||||
canvas.style.cursor = toolCursor();
|
||||
roomHover = null;
|
||||
fxHover = null;
|
||||
renderToolOptions();
|
||||
@@ -675,6 +678,7 @@ function mountHouseEditor(container, callbacks) {
|
||||
drawPlan();
|
||||
}
|
||||
|
||||
const toolCursor = () => tool === 'iw' || tool === 'fixture' ? 'crosshair' : tool === 'room' ? 'cell' : 'default';
|
||||
function updateHint() {
|
||||
document.getElementById('ho-hint').textContent = tool === 'iw'
|
||||
? (drawStart ? 'Klik het eindpunt (Esc = annuleren). Snapt op 50 mm, haaks, en op wandvlakken.' : 'Klik het beginpunt van de binnenwand.')
|
||||
@@ -728,13 +732,13 @@ function mountHouseEditor(container, callbacks) {
|
||||
: ElektraModel.snapToWall(parts.elektra, w.x, w.z);
|
||||
drawPlan();
|
||||
});
|
||||
function onElektraDrop() {
|
||||
function onElektraDrop(e) {
|
||||
if (!elDrag) return;
|
||||
const d = elDrag;
|
||||
elDrag = null;
|
||||
canvas.style.cursor = tool === 'iw' ? 'crosshair' : tool === 'room' ? 'cell' : 'default';
|
||||
canvas.style.cursor = toolCursor();
|
||||
if (!d.moved || !d.snap) return;
|
||||
suppressClick = true;
|
||||
if (e.target === canvas) suppressClick = true;
|
||||
if (d.snap.floor) {
|
||||
const rc = parts.rects.find(q => d.snap.x > q.x0 && d.snap.x < q.x1 && d.snap.z > q.z0 && d.snap.z < q.z1);
|
||||
const vw = state.settings.elektra.vloerWcd.find(o => 'vwcd:' + o.id === d.key);
|
||||
@@ -769,13 +773,13 @@ function mountHouseEditor(container, callbacks) {
|
||||
if (it) fxDrag.pose = fxPose(it, w.x + fxDrag.dx, w.z + fxDrag.dz, e.altKey);
|
||||
drawPlan();
|
||||
});
|
||||
function onFixtureDrop() {
|
||||
function onFixtureDrop(e) {
|
||||
if (!fxDrag) return;
|
||||
const d = fxDrag;
|
||||
fxDrag = null;
|
||||
canvas.style.cursor = 'default';
|
||||
canvas.style.cursor = toolCursor();
|
||||
if (!d.moved || !d.pose) return;
|
||||
suppressClick = true;
|
||||
if (e.target === canvas) suppressClick = true;
|
||||
const fs = fixtureState(d.id);
|
||||
if (fs) placeFixture(fs, d.pose.x, d.pose.z, d.pose.rot);
|
||||
selection = { type: 'fixture', id: d.id };
|
||||
@@ -801,13 +805,13 @@ function mountHouseEditor(container, callbacks) {
|
||||
if (ch) chDrag.snap = ChimneyModel.snapToFacade(parts.rects, w.x, w.z, ch.w);
|
||||
drawPlan();
|
||||
});
|
||||
window.addEventListener('mouseup', () => {
|
||||
window.addEventListener('mouseup', (e) => {
|
||||
if (!chDrag) return;
|
||||
const d = chDrag;
|
||||
chDrag = null;
|
||||
canvas.style.cursor = 'default';
|
||||
canvas.style.cursor = toolCursor();
|
||||
if (!d.moved || !d.snap) return;
|
||||
suppressClick = true;
|
||||
if (e.target === canvas) suppressClick = true;
|
||||
const cs = (state.chimneys || []).find(c => c.id === d.id);
|
||||
if (cs) Object.assign(cs, { unitId: d.snap.unitId, side: d.snap.side, u: d.snap.u });
|
||||
const u = parts.units.find(q => q.id === d.snap.unitId), wl = u && u.walls.find(q => q.side === d.snap.side), pc = wl && wl.pieces.find(p => !p.baseY);
|
||||
@@ -887,11 +891,12 @@ function mountHouseEditor(container, callbacks) {
|
||||
if (selection.type === 'fixture') removeFixture(selection.id);
|
||||
else if (selection.type === 'room') removeRoom(selection.id);
|
||||
else if (selection.type === 'elektra' && selection.id !== 'mk') removeSelectedElektra();
|
||||
else if (selection.type === 'iw') {
|
||||
state.interiorWalls = state.interiorWalls.filter(w => w.id !== selection.id);
|
||||
selection = null;
|
||||
refresh();
|
||||
}
|
||||
else if (selection.type === 'iw') removeInteriorWall(selection.id);
|
||||
}
|
||||
function removeInteriorWall(id) {
|
||||
state.interiorWalls = state.interiorWalls.filter(w => w.id !== id);
|
||||
selection = null;
|
||||
refresh();
|
||||
}
|
||||
function onKey(e) {
|
||||
if (['INPUT', 'SELECT', 'TEXTAREA'].includes(document.activeElement.tagName)) return;
|
||||
@@ -962,9 +967,10 @@ function mountHouseEditor(container, callbacks) {
|
||||
plan2D.cz = (canvas.height / 2 - (pan.oy + e.clientY - pan.sy)) / view.scale;
|
||||
drawPlan();
|
||||
}
|
||||
function onPanEnd() {
|
||||
// Na een sleep de klik op de plattegrond overslaan, maar alleen als die klik er ook komt (loslaten op de plattegrond).
|
||||
function onPanEnd(e) {
|
||||
if (!pan) return;
|
||||
if (pan.moved) { canvas.style.cursor = 'default'; if (!pan.mid) suppressClick = true; }
|
||||
if (pan.moved) { canvas.style.cursor = toolCursor(); if (!pan.mid && e.target === canvas) suppressClick = true; }
|
||||
pan = null;
|
||||
}
|
||||
window.addEventListener('mousemove', onPanMove);
|
||||
@@ -1339,24 +1345,12 @@ function mountHouseEditor(container, callbacks) {
|
||||
const stucColors = Object.fromEntries(Object.entries(WallModel.STUC_COLORS).map(([k, c]) => [k, c.label]));
|
||||
const swatchOf = (hex) => `<div class="ins-swatch" style="background:${hex}"></div>`;
|
||||
function wireButtons(body) {
|
||||
body.querySelectorAll('[data-ho-tool]').forEach(b => b.addEventListener('click', () => setTool(b.dataset.hoTool)));
|
||||
body.querySelectorAll('[data-go]').forEach(b => b.addEventListener('click', () => showPart(b.dataset.go)));
|
||||
body.querySelectorAll('[data-ho-act]').forEach(b => b.addEventListener('click', () => {
|
||||
const a = b.dataset.hoAct;
|
||||
if (a === 'add-unit') addUnit();
|
||||
else if (a === 'project') openProjectProperties();
|
||||
else if (a === 'save') exportDesign();
|
||||
else if (a === 'dxf') exportDxf();
|
||||
else if (a === 'ifc') exportIfc();
|
||||
else if (a === 'obj') exportObj();
|
||||
else if (a === 'costs') CostSettings.open();
|
||||
else if (a === 'add-seams') { HouseModel.ensureSeamWalls(state, b.dataset.unit); refresh(); }
|
||||
if (a === 'add-seams') { HouseModel.ensureSeamWalls(state, b.dataset.unit); refresh(); }
|
||||
else if (a === 'remove-unit') removeUnit(b.dataset.unit);
|
||||
else if (a === 'remove-iw') {
|
||||
state.interiorWalls = state.interiorWalls.filter(w => w.id !== Number(b.dataset.iw));
|
||||
selection = null;
|
||||
refresh();
|
||||
}
|
||||
else if (a === 'remove-iw') removeInteriorWall(Number(b.dataset.iw));
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -2295,12 +2289,6 @@ function mountHouseEditor(container, callbacks) {
|
||||
syncToolbar();
|
||||
requestAnimationFrame(onResize);
|
||||
}
|
||||
function setView(mode) {
|
||||
setWalk(false);
|
||||
UI.setView(overviewEl, view3D.mode = mode);
|
||||
requestAnimationFrame(onResize);
|
||||
}
|
||||
|
||||
const esc = UI.esc;
|
||||
function stackedBars(title, iconName, series, rows, fmtVal, note) {
|
||||
const max = Math.max(1, ...rows.map(r => r.total));
|
||||
@@ -2442,28 +2430,24 @@ function mountHouseEditor(container, callbacks) {
|
||||
parts.units.forEach(u => houseGroup.add(u.roof.group));
|
||||
if (parts.roofEdgeGroup) houseGroup.add(parts.roofEdgeGroup);
|
||||
if (parts.postsGroup) houseGroup.add(parts.postsGroup);
|
||||
if (parts.chimneysGroup) houseGroup.add(parts.chimneysGroup);
|
||||
}
|
||||
// Alles wat binnen de wanden of onder het plafond zit, snijdt mee met de doorsnede (anders zweeft het boven de snede).
|
||||
const clipGroup = (g) => {
|
||||
if (!g) return;
|
||||
g.traverse(o => {
|
||||
if (!o.material || (o.material.clippingPlanes || []).length === clip.length) return;
|
||||
o.material.clippingPlanes = clip;
|
||||
o.material.needsUpdate = true;
|
||||
});
|
||||
houseGroup.add(g);
|
||||
};
|
||||
if (parts.sandwichGroup) houseGroup.add(parts.sandwichGroup);
|
||||
if (parts.lightingGroup && !section) houseGroup.add(parts.lightingGroup);
|
||||
if (parts.elektraGroup) houseGroup.add(parts.elektraGroup);
|
||||
if (parts.roomsGroup) {
|
||||
parts.roomsGroup.userData.ceilings.visible = !section;
|
||||
parts.roomsGroup.traverse(o => {
|
||||
if (!o.material || (o.material.clippingPlanes || []).length === clip.length) return;
|
||||
o.material.clippingPlanes = clip;
|
||||
o.material.needsUpdate = true;
|
||||
});
|
||||
houseGroup.add(parts.roomsGroup);
|
||||
}
|
||||
if (parts.fixturesGroup) {
|
||||
parts.fixturesGroup.traverse(o => {
|
||||
if (!o.material || (o.material.clippingPlanes || []).length === clip.length) return;
|
||||
o.material.clippingPlanes = clip;
|
||||
o.material.needsUpdate = true;
|
||||
});
|
||||
houseGroup.add(parts.fixturesGroup);
|
||||
}
|
||||
clipGroup(parts.elektraGroup);
|
||||
clipGroup(parts.chimneysGroup); // laag Gevelbekleding, net als in de plattegrond
|
||||
if (parts.roomsGroup) parts.roomsGroup.userData.ceilings.visible = !section;
|
||||
clipGroup(parts.roomsGroup);
|
||||
clipGroup(parts.fixturesGroup);
|
||||
scene.add(houseGroup);
|
||||
|
||||
const bx0 = Math.min(...parts.rects.map(r => r.x0)), bx1 = Math.max(...parts.rects.map(r => r.x1));
|
||||
@@ -2777,7 +2761,7 @@ function mountHouseEditor(container, callbacks) {
|
||||
refresh,
|
||||
select,
|
||||
setTool,
|
||||
setView,
|
||||
setView: bar.setView,
|
||||
toggleReport: () => toggleReport(),
|
||||
toggleSection,
|
||||
fitView: () => fitPlan(),
|
||||
@@ -2863,7 +2847,7 @@ function mountHouseEditor(container, callbacks) {
|
||||
const exportIfc = () => exportAs('ifc', 'BIM-export (IFC)', (f) => HouseIfc.generate(state).save(f), 'IFC4: balken, platen en elektra');
|
||||
|
||||
// Render-export (sfeerimpressie): alleen wat in de afgewerkte woning te zien is, los van de gekozen lagen, doorsnede
|
||||
// en weergave-opties; geen buizen, dozen, binnenste vloerbalken, latten en isolatie achter de gevel, lichtkegels.
|
||||
// en weergave-opties (HouseModel.computeParts met finishedOnly).
|
||||
// Lampen als echte lichtbronnen via een Blender-script in de ZIP.
|
||||
// Eigen materiaalsets (steen, riet, rabat en tegels komen uit gedeelde caches); maaiveld onder het midden = oorsprong.
|
||||
const exportObj = () => exportAs('zip', 'render-export (OBJ + texturen + lampen, ZIP)', (filename) => {
|
||||
@@ -2873,13 +2857,9 @@ function mountHouseEditor(container, callbacks) {
|
||||
const full = HouseModel.computeParts(state, {
|
||||
wallMaterials, floorMaterials: FloorModel.createMaterials(), roofMaterials, lightingMaterials: LightingModel.createMaterials(),
|
||||
sandwichMaterials: SandwichModel.createMaterials(), postMaterials: PostModel.createMaterials(), chimneyMaterials: ChimneyModel.createMaterials(),
|
||||
elektraMaterials: ElektraModel.createMaterials(), layers: ViewLayers.all(), elektraRough: false, finishedOnly: true
|
||||
elektraMaterials: ElektraModel.createMaterials(), layers: ViewLayers.all(), finishedOnly: true
|
||||
});
|
||||
HouseModel.placeGroups(full);
|
||||
HouseModel.allWallPieces(full).forEach(p => ViewLayers.hideByMaterial(p.group,
|
||||
[wallMaterials.isolatieMaterial, wallMaterials.battenMaterial, wallMaterials.doekMaterial]));
|
||||
if (full.lightingGroup) full.lightingGroup.traverse(o => { if (o.userData.beam) o.visible = false; });
|
||||
if (full.roomsGroup && full.roomsGroup.userData.ceilings) full.roomsGroup.userData.ceilings.visible = true;
|
||||
const roots = full.units.map(u => u.floorGroup).concat(HouseModel.allWallPieces(full).map(p => p.group), full.units.map(u => u.roof.group),
|
||||
[full.roofEdgeGroup, full.postsGroup, full.chimneysGroup, full.sandwichGroup, full.lightingGroup, full.elektraGroup, full.roomsGroup, full.fixturesGroup]).filter(Boolean);
|
||||
const bx0 = Math.min(...full.rects.map(r => r.x0)), bx1 = Math.max(...full.rects.map(r => r.x1));
|
||||
@@ -2932,6 +2912,7 @@ function mountHouseEditor(container, callbacks) {
|
||||
return (...args) => { if (activeEditor && typeof activeEditor[fn] === 'function') return activeEditor[fn](...args); };
|
||||
}
|
||||
const has = (fn) => !!(activeEditor && typeof activeEditor[fn] === 'function');
|
||||
// Acties die naar de actieve onderdeel-editor gaan; de API hieronder wordt uit deze lijst opgebouwd.
|
||||
const FORWARDED = ['mirrorHorizontal', 'setView', 'toggleReport', 'toggleSection', 'fitView', 'toggleWalk'];
|
||||
|
||||
function onPartKey(e) {
|
||||
@@ -2953,12 +2934,7 @@ function mountHouseEditor(container, callbacks) {
|
||||
exportIfc,
|
||||
exportObj,
|
||||
triggerImport,
|
||||
mirrorHorizontal: forward('mirrorHorizontal'),
|
||||
setView: forward('setView'),
|
||||
toggleReport: forward('toggleReport'),
|
||||
toggleSection: forward('toggleSection'),
|
||||
fitView: forward('fitView'),
|
||||
toggleWalk: forward('toggleWalk'),
|
||||
...Object.fromEntries(FORWARDED.map(fn => [fn, forward(fn)])),
|
||||
viewState: () => forward('viewState')() || {},
|
||||
// Doorgestuurde acties bestaan alleen als de actieve onderdeel-editor ze kent (bijv. Rapport alleen in de woning).
|
||||
can: (fn) => !FORWARDED.includes(fn) || has(fn),
|
||||
|
||||
Reference in New Issue
Block a user