gravity/tool/modes.js
2025-12-27 18:02:56 -06:00

88 lines
2.3 KiB
JavaScript

// Mode Switcher
import { Tool } from '../tool.js';
import {
MODE_MASS_GENERATION,
MODE_PAN_VIEW,
MODE_OBJECT_SELECT,
EVENT_MODE_LEAVE,
EVENT_MODE_ENTER,
} from '../config.js';
export class ModeSwitch extends Tool {
currentMode = undefined;
modes = [
[MODE_MASS_GENERATION, 'Generate Mass'],
[MODE_PAN_VIEW, 'Pan View'],
[MODE_OBJECT_SELECT, 'Select'],
];
buttons = [];
constructor(toolbar) {
super(toolbar);
const modesDiv = document.createElement('div');
this.div.appendChild(modesDiv);
modesDiv.style.display = 'flex';
modesDiv.style.flexDirection = 'column';
for (let [modeID, modeTitle] of this.modes) {
const button = document.createElement('button');
this.buttons.push(button);
button.modeID = modeID;
modesDiv.appendChild(button);
button.innerHTML = `<h3>${modeTitle}</h3>`;
button.classList.add('wide');
button.addEventListener('click', () => this.setCurrentMode(modeID));
}
// First listed mode is the default
const [[currentModeID, ]] = this.modes;
this.setCurrentMode(currentModeID);
// Add global method to set/get current mode
this.sim.setCurrentMode = (modeID) => this.setCurrentMode(modeID);
this.sim.getCurrentMode = () => this.currentMode;
this.sim.isCurrentMode = (modeID) => modeID === this.currentMode;
this.sim.onModeLeave = (modeID, cb) => this.onModeLeave(modeID, cb);
this.sim.onModeEnter = (modeID, cb) => this.onModeEnter(modeID, cb);
}
setModesOpacity() {
for (let button of this.buttons) {
button.style.opacity = button.modeID === this.currentMode ? '50%' : '100%';
}
}
setCurrentMode(modeID) {
if (modeID === this.currentMode) return;
const leave = new CustomEvent(EVENT_MODE_LEAVE, {detail: {modeID: this.currentMode}});
const enter = new CustomEvent(EVENT_MODE_LEAVE, {detail: {modeID}});
this.currentMode = modeID;
this.setModesOpacity();
this.div.dispatchEvent(leave);
this.div.dispatchEvent(enter);
}
// cb: () => {}
onModeLeave(modeID, cb) {
this.div.addEventListener(EVENT_MODE_LEAVE, (e) => {
if (e.detail?.modeID === modeID) {
cb();
}
});
}
// cb: () => {}
onModeEnter(modeID, cb) {
this.div.addEventListener(EVENT_MODE_ENTER, (e) => {
if (e.detail?.modeID === modeID) {
cb();
}
});
}
}