Move menu building to Stimulus (WIP)
TODO: cache menu container, build ontology and load templates from external HTML source.
This commit is contained in:
107
js/ui.js
107
js/ui.js
@@ -1,42 +1,9 @@
|
||||
import AppState from "./state.js";
|
||||
import { changeLightDirection, toggleAmbientOcclusion } from "./utils/environment.js";
|
||||
import { resetClipping, addClippingPlane } from "./utils/clipping.js";
|
||||
import { traverseOntology } from "./ontology.js";
|
||||
|
||||
/**
|
||||
* @module UI
|
||||
*/
|
||||
|
||||
const domParser = new DOMParser;
|
||||
|
||||
const contentMenuTabs = `
|
||||
<!-- Nav tabs -->
|
||||
<ul class="nav nav-pills" id="content-tabs" role="tablist">
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link active" id="layer-tab" data-bs-toggle="tab" data-bs-target="#layer" type="button" role="tab" aria-controls="layer" aria-selected="false">
|
||||
<i class="bi bi-boxes me-1"></i> Elementi 3D
|
||||
</button>
|
||||
</li>
|
||||
<li class="nav-item" role="presentation">
|
||||
<button class="nav-link" id="media-tab" data-bs-toggle="tab" data-bs-target="#content" type="button" role="tab" aria-controls="media" aria-selected="true">
|
||||
<i class="bi bi-diagram-3 me-1"></i> Contenuti
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<!-- Tab panes -->
|
||||
<div class="tab-content ps-4 ms-3 overflow-y-auto">
|
||||
<div class="tab-pane active p-3 ms-2" id="layer" role="tabpanel" aria-labelledby="layer-tab" tabindex="0"></div>
|
||||
<div class="tab-pane pt-3" id="content" role="tabpanel" aria-labelledby="media-tab" tabindex="0"></div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
const audioExample = `
|
||||
<button type="button" id="audio-example" class="text-left btn aton-btn fs-6 mx-2" data-bs-toggle="modal" data-bs-target="#audio1">
|
||||
<i class="bi bi-play-btn me-2"></i> Esempio audio (<em>Che fiero costume</em>)
|
||||
</button>
|
||||
`;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {String} triggerSelector - Usually, the close modal trigger element(s) selector
|
||||
@@ -54,73 +21,6 @@ export function pauseAudio(triggerSelector) {
|
||||
});
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Resets the UI state (essentially hides the clipper toolbar if visible...)
|
||||
* @todo Other elements to reset?? Restore inital lighting conditions and viewpoint...
|
||||
*/
|
||||
function reset() {
|
||||
document.querySelector('#clipper-bar')?.classList.add('d-none');
|
||||
document.querySelector('#clipper')?.classList.remove('border', 'border-2', 'border-white');
|
||||
}
|
||||
/**
|
||||
* Right-side main menu panel
|
||||
* @param {String} triggerId - The menu button id
|
||||
* @param {String} ontologyJsonPath
|
||||
*/
|
||||
function toggleContentMenu(triggerId, ontologyJsonPath) {
|
||||
const btn = document.querySelector(`#${triggerId}`);
|
||||
|
||||
btn.addEventListener('click', async () => {
|
||||
ATON.UI.setSidePanelRight();
|
||||
ATON.UI.showSidePanel({header: 'Menu'});
|
||||
// Append tabs, then tab panes
|
||||
const tabs = domParser.parseFromString(contentMenuTabs, 'text/html');
|
||||
ATON.UI.elSidePanel.appendChild(tabs.querySelector('#content-tabs'));
|
||||
ATON.UI.elSidePanel.appendChild(tabs.querySelector('.tab-content'));
|
||||
buildLayersMenu(AppState.normalizedNodes, ATON.UI.elSidePanel.querySelector('#layer'));
|
||||
buildOntologyMenu(await traverseOntology(ontologyJsonPath), ATON.UI.elSidePanel.querySelector('#content'));
|
||||
});
|
||||
}
|
||||
/**
|
||||
* @todo Don't rebuild it every time the side panel is shown...
|
||||
* @param {Array} nodes The normalized scene nodes (IDs and status)
|
||||
* @param {HTMLElement} sidePanel ATON's side panel element
|
||||
*/
|
||||
function buildLayersMenu(nodes, sidePanel) {
|
||||
for(let node of nodes) {
|
||||
const menuItem = document.createElement('div');
|
||||
menuItem.className = `form-check form-switch ms-${node.depth} ps-${node.depth} mt-2`;
|
||||
const checkbox = document.createElement('input');
|
||||
checkbox.type = 'checkbox';
|
||||
checkbox.className = "form-check-input";
|
||||
checkbox.checked = node.active;
|
||||
checkbox.role = 'switch';
|
||||
checkbox.title = "Mostra / nascondi layer";
|
||||
|
||||
menuItem.appendChild(checkbox);
|
||||
|
||||
const label = document.createElement('label');
|
||||
label.className = "form-check-label";
|
||||
label.textContent = node.id;
|
||||
|
||||
menuItem.appendChild(label);
|
||||
|
||||
sidePanel.appendChild(menuItem);
|
||||
// Will this ever work??
|
||||
menuItem.addEventListener('change', event => toggleNode(node.id, event.target.checked));
|
||||
}
|
||||
|
||||
/**
|
||||
* This is terrible...
|
||||
* @param {String} id
|
||||
* @param {Boolean} status
|
||||
*/
|
||||
const toggleNode = (id, status) => {
|
||||
ATON.getSceneNode(id).toggle(status);
|
||||
AppState.normalizedNodes.find(n => n.id === id).active = status;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see traverseOntology
|
||||
* @param {Object} ontology The traversed ontology object (temp)
|
||||
@@ -146,11 +46,4 @@ function buildOntologyMenu(ontology, sidePanel) {
|
||||
mainNode.appendChild(domainList);
|
||||
list.appendChild(mainNode);
|
||||
sidePanel.appendChild(list);
|
||||
}
|
||||
/**
|
||||
* Initialize required components for scene UI
|
||||
* @param {String} ontologyJsonPath
|
||||
*/
|
||||
export async function initUI(ontologyJsonPath) {
|
||||
toggleContentMenu('menu', ontologyJsonPath);
|
||||
}
|
||||
Reference in New Issue
Block a user