gravity/options.js
2025-12-31 01:28:32 -06:00

94 lines
2.3 KiB
JavaScript

import {
EVENT_OPTION_SET,
} from './config.js';
export class Options {
sim = undefined;
options = undefined;
values = {};
getStorageKey(path) {
return `${path}:options`;
}
constructor(sim, options) {
this.sim = sim;
this.options = options;
// Global methods to get/set current option values
this.sim.getOption = (path) => this.getOption(path);
this.sim.setOption = (path, value) => this.setOption(path, value);
this.sim.onOptionSet = (path, cb) => this.onOptionSet(path, cb);
// Initialize values from localStorage
for (const groupName of Object.keys(options)) {
for (const [name, [, , defaultValue]] of Object.entries(this.options[groupName])) {
const path = [groupName, name].join('.');
let value = this.getFromLocalStorage(path);
if (value === undefined) {
value = defaultValue;
}
this.values[path] = value;
}
}
}
toStored(value) {
return JSON.stringify(value);
}
fromStored(value) {
return JSON.parse(value);
}
getFromLocalStorage(path) {
const storageKey = this.getStorageKey(path);
const value = this.fromStored(window.localStorage.getItem(storageKey));
this.values[path] = value;
return value;
}
getOption(path) {
return this.values[path];
}
setOption(path, value) {
this.values[path] = value;
const storageKey = this.getStorageKey(path);
window.localStorage.setItem(storageKey, this.toStored(value));
const e = new CustomEvent(EVENT_OPTION_SET, {detail: {path, value}});
this.sim.div.dispatchEvent(e);
}
// cb: (value) => undefined
onOptionSet(path, cb) {
this.sim.div.addEventListener(EVENT_OPTION_SET, (e) => {
if (path === e.detail.path) {
cb(e.detail.value);
}
});
}
getSection(sectionName) {
const section = this.options[sectionName];
const group = {
type: 'group',
name: sectionName,
title: section._title,
items: [],
};
for (const name in section) {
if (name.startsWith('_')) continue;
const [title, type, defaultValue, opts] = section[name];
group.items.push({
name,
type,
title,
default: defaultValue,
...opts
})
}
return group;
}
}