gravity/tool/options.js

90 lines
2.7 KiB
JavaScript

// Options picker
import {
TOOL_INFO_CLASSNAME,
WIDE_CLASSNAME,
} from '../config.js';
import { Tool } from '../tool.js';
import { Options, optionsLayout } from '../options.js';
export class OptionsTool extends Tool {
visitItem(item, path) {
path = [path, item.name].filter(x => !!x).join('.');
switch (item.type) {
case 'group': {
const group = document.createElement('div');
if (item.title) {
const heading = document.createElement('h3');
heading.innerHTML = item.title;
group.appendChild(heading);
}
for (const next of item.items) {
const child = this.visitItem(next, path);
group.appendChild(child);
}
return group;
}
case 'boolean': {
const button = document.createElement('button');
button.innerHTML = item.title;
if (item.wide === true) {
button.classList.add(WIDE_CLASSNAME);
}
this.sim.setOption(path, item.default);
button.style.opacity = this.sim.getOption(path) ? '100%' : '50%';
button.addEventListener('click', () => {
this.sim.setOption(path, !this.sim.getOption(path));
button.style.opacity = this.sim.getOption(path) ? '100%' : '50%';
});
this.sim.onOptionSet(path, value => {
button.style.opacity = value ? '100%' : '50%';
});
return button;
}
case 'number': {
const div = document.createElement('div');
const title = document.createElement('button');
const input = document.createElement('input');
const maxLength = item.maxLength || 8;
div.appendChild(title);
div.appendChild(input);
div.classList.add(WIDE_CLASSNAME);
title.classList.add(TOOL_INFO_CLASSNAME);
if (item.wide) {
title.classList.add(WIDE_CLASSNAME);
input.classList.add(WIDE_CLASSNAME);
}
title.innerHTML = item.title;
input.value = item.default;
this.sim.setOption(path, item.default);
input.addEventListener('input', () => {
input.value = input.value.slice(0, maxLength);
});
input.addEventListener('change', () => {
this.sim.setOption(path, input.value);
});
this.sim.onOptionSet(path, value => {
input.value = value;
});
return div;
}
default:
console.error('Unknown option type', item);
throw new Error('Unknown option type');
}
}
constructor(toolbar, sections) {
super(toolbar);
for (const sectionName of sections) {
const item = Options.getSection(optionsLayout, sectionName);
const child = this.visitItem(item);
this.div.appendChild(child);
}
}
}