add prefs dialog, dark mode
This commit is contained in:
parent
853816e921
commit
536da7acbf
6 changed files with 87 additions and 23 deletions
|
|
@ -112,7 +112,7 @@ function restore_space() {
|
||||||
store_matrices();
|
store_matrices();
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
// restore preferences after models are restored
|
// restore preferences after models are restored
|
||||||
api.prefs.load().then(() => {
|
return api.prefs.load().then(() => {
|
||||||
let { map } = api.prefs;
|
let { map } = api.prefs;
|
||||||
let { space, mode } = map;
|
let { space, mode } = map;
|
||||||
api.grid(space.grid);
|
api.grid(space.grid);
|
||||||
|
|
@ -123,10 +123,13 @@ function restore_space() {
|
||||||
api.selection.set([...smodel, ...sgroup]);
|
api.selection.set([...smodel, ...sgroup]);
|
||||||
// restore edit mode
|
// restore edit mode
|
||||||
api.mode.set(mode);
|
api.mode.set(mode);
|
||||||
|
// restore dark mode
|
||||||
|
set_darkmode(map.space.dark);
|
||||||
});
|
});
|
||||||
|
}).finally(() => {
|
||||||
|
// hide loading curtain
|
||||||
|
$d('curtain','none');
|
||||||
});
|
});
|
||||||
// hide loading curtain
|
|
||||||
$d('curtain','none');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// toggle edit/split temporary mode (present plane on hover)
|
// toggle edit/split temporary mode (present plane on hover)
|
||||||
|
|
@ -254,8 +257,13 @@ function space_init(data) {
|
||||||
if (api.modal.showing) {
|
if (api.modal.showing) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (evt.key === '?') {
|
||||||
|
return api.help();
|
||||||
|
}
|
||||||
let { shiftKey, metaKey, ctrlKey, code } = evt;
|
let { shiftKey, metaKey, ctrlKey, code } = evt;
|
||||||
switch (code) {
|
switch (code) {
|
||||||
|
case 'KeyQ':
|
||||||
|
return api.settings();
|
||||||
case 'KeyI':
|
case 'KeyI':
|
||||||
return api.file.import();
|
return api.file.import();
|
||||||
case 'KeyX':
|
case 'KeyX':
|
||||||
|
|
@ -454,6 +462,29 @@ function object_destroy(id) {
|
||||||
store_matrices();
|
store_matrices();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// listen for changes like dark mode toggle
|
||||||
|
function set_darkmode(dark) {
|
||||||
|
let { prefs } = mesh.api;
|
||||||
|
let { sky, platform } = moto.Space;
|
||||||
|
if (dark) {
|
||||||
|
mesh.material.wireframe.color.set(0xeeeeee);
|
||||||
|
} else {
|
||||||
|
mesh.material.wireframe.color.set(0,0,0);
|
||||||
|
}
|
||||||
|
sky.set({ color: dark ? 0 : 0xffffff });
|
||||||
|
platform.set({
|
||||||
|
grid: dark ? {
|
||||||
|
colorMajor: 0x666666,
|
||||||
|
colorMinor: 0x333333,
|
||||||
|
} : {
|
||||||
|
colorMajor: 0xcccccc,
|
||||||
|
colorMinor: 0xeeeeee,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
prefs.map.space.dark = dark;
|
||||||
|
prefs.save();
|
||||||
|
}
|
||||||
|
|
||||||
// bind functions to topics
|
// bind functions to topics
|
||||||
broker.listeners({
|
broker.listeners({
|
||||||
load_files,
|
load_files,
|
||||||
|
|
@ -461,6 +492,7 @@ broker.listeners({
|
||||||
space_load,
|
space_load,
|
||||||
object_matrix,
|
object_matrix,
|
||||||
object_destroy,
|
object_destroy,
|
||||||
|
set_darkmode,
|
||||||
edit_split
|
edit_split
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -420,6 +420,10 @@ let mode = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// cache pref signature so we know when it changes
|
||||||
|
let prefsig;
|
||||||
|
let prefsignew;
|
||||||
|
|
||||||
// persisted preference map
|
// persisted preference map
|
||||||
let prefs = {
|
let prefs = {
|
||||||
map: {
|
map: {
|
||||||
|
|
@ -433,14 +437,18 @@ let prefs = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
put(key, val) {
|
// look for changes in pref signature
|
||||||
prefs.map[key] = val;
|
changed() {
|
||||||
prefs.update();
|
prefsignew = JSON.stringify(prefs.map);
|
||||||
|
return prefsignew !== prefsig;
|
||||||
},
|
},
|
||||||
|
|
||||||
// persist to data store
|
// persist to data store
|
||||||
save() {
|
save() {
|
||||||
mesh.db.admin.put("prefs", prefs.map);
|
if (prefs.changed()) {
|
||||||
|
mesh.db.admin.put("prefs", prefs.map);
|
||||||
|
prefsig = prefsignew;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// reload from data store
|
// reload from data store
|
||||||
|
|
@ -546,6 +554,6 @@ broker.wrapObject(model, 'model');
|
||||||
broker.wrapObject(group, 'group');
|
broker.wrapObject(group, 'group');
|
||||||
|
|
||||||
// optimize db writes by merging updates
|
// optimize db writes by merging updates
|
||||||
prefs.save = util.deferWrap(prefs.save);
|
prefs.save = util.deferWrap(prefs.save, 100);
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|
|
||||||
|
|
@ -169,6 +169,18 @@ let log = api.log = {
|
||||||
// bind endpoint for worker to log in the ui
|
// bind endpoint for worker to log in the ui
|
||||||
gapp.broker.subscribe("mesh.log", log.emit);
|
gapp.broker.subscribe("mesh.log", log.emit);
|
||||||
|
|
||||||
|
// bind settings endpoint to api
|
||||||
|
api.settings = function() {
|
||||||
|
modal.show('settings', h.div([
|
||||||
|
h.label('dark mode'),
|
||||||
|
h.input({
|
||||||
|
type: "checkbox",
|
||||||
|
onchange: ev => call.set_darkmode(ev.target.checked),
|
||||||
|
[ api.prefs.map.space.dark ? 'checked' : 'unchecked' ] : 1
|
||||||
|
})
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
|
||||||
// create html elements
|
// create html elements
|
||||||
function ui_build() {
|
function ui_build() {
|
||||||
// set app version
|
// set app version
|
||||||
|
|
@ -177,8 +189,12 @@ function ui_build() {
|
||||||
|
|
||||||
// add a help button
|
// add a help button
|
||||||
h.bind($('top-right'), [
|
h.bind($('top-right'), [
|
||||||
h.div({ id: "help", onclick: api.help },
|
h.div({ id: "top-settings", onclick: api.settings }, [
|
||||||
[ h.div({ class: "far fa-question-circle" }) ])
|
h.div({ class: "fas fa-sliders-h" }),
|
||||||
|
]),
|
||||||
|
h.div({ id: "top-help", onclick: api.help }, [
|
||||||
|
h.div({ class: "far fa-question-circle" }),
|
||||||
|
]),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// create top level app areas
|
// create top level app areas
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ let util = mesh.util = {
|
||||||
rec.timer = setTimeout(() => {
|
rec.timer = setTimeout(() => {
|
||||||
deferFn.remove(rec);
|
deferFn.remove(rec);
|
||||||
fn();
|
fn();
|
||||||
});
|
}, time);
|
||||||
deferFn.push(rec);
|
deferFn.push(rec);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -458,8 +458,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
function setGridColor(opt = {}) {
|
function setGridColor(opt = {}) {
|
||||||
grid.colorMajor = valueOr(opt.major, grid.colorMajor);
|
grid.colorMajor = valueOr(opt.major || opt.colorMajor, grid.colorMajor);
|
||||||
grid.colorMinor = valueOr(opt.minor, grid.colorMinor);
|
grid.colorMinor = valueOr(opt.minor || opt.colorMinor, grid.colorMinor);
|
||||||
grid.colorX = valueOr(opt.colorX, grid.colorX);
|
grid.colorX = valueOr(opt.colorX, grid.colorX);
|
||||||
grid.colorY = valueOr(opt.colorY, grid.colorY);
|
grid.colorY = valueOr(opt.colorY, grid.colorY);
|
||||||
updateGrid();
|
updateGrid();
|
||||||
|
|
@ -921,8 +921,8 @@
|
||||||
function setSky(opt = {}) {
|
function setSky(opt = {}) {
|
||||||
let { grid, color, gridColor } = opt;
|
let { grid, color, gridColor } = opt;
|
||||||
if (grid) Space.sky.showGrid(grid);
|
if (grid) Space.sky.showGrid(grid);
|
||||||
if (color) Space.sky.setColor(color);
|
if (color !== undefined) Space.sky.setColor(color);
|
||||||
if (gridColor) Space.sky.setGridColor(gridColor);
|
if (gridColor !== undefined) Space.sky.setGridColor(gridColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
function setPlatform(opt = {}) {
|
function setPlatform(opt = {}) {
|
||||||
|
|
@ -945,7 +945,7 @@
|
||||||
let { colorX, colorY, colorMajor, colorMinor } = grid;
|
let { colorX, colorY, colorMajor, colorMinor } = grid;
|
||||||
platform.setGrid(major, minor);
|
platform.setGrid(major, minor);
|
||||||
platform.setGridColor({ colorX, colorY, colorMajor, colorMinor });
|
platform.setGridColor({ colorX, colorY, colorMajor, colorMinor });
|
||||||
platform.setGridZOff(zOffset);
|
if (zOffset !== undefined) platform.setGridZOff(zOffset);
|
||||||
}
|
}
|
||||||
if (origin) {
|
if (origin) {
|
||||||
let { x, y, z, show } = origin;
|
let { x, y, z, show } = origin;
|
||||||
|
|
|
||||||
|
|
@ -109,7 +109,7 @@ body, div {
|
||||||
padding: 3px 0 3px 0;
|
padding: 3px 0 3px 0;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
font-family: 'Russo One', sans-serif;
|
font-family: 'Russo One', sans-serif;
|
||||||
background-color: rgba(255,255,255,0.75);
|
background-color: rgba(255,255,255,0.55);
|
||||||
}
|
}
|
||||||
|
|
||||||
#top-sep {
|
#top-sep {
|
||||||
|
|
@ -168,20 +168,26 @@ button:hover {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
padding: 3px;
|
padding: 3px;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
right: 0;
|
right: 3px;
|
||||||
top: 0;
|
top: 0;
|
||||||
|
gap: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#help {
|
#top-right > div {
|
||||||
|
flex-direction: row;
|
||||||
|
color: #888;
|
||||||
|
}
|
||||||
|
|
||||||
|
#top-right > div:hover {
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
#top-settings, #top-help {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center
|
align-items: center
|
||||||
}
|
}
|
||||||
|
|
||||||
#help:hover {
|
|
||||||
color: #888;
|
|
||||||
}
|
|
||||||
|
|
||||||
.export {
|
.export {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
font-family: monospace;
|
font-family: monospace;
|
||||||
|
|
@ -236,6 +242,8 @@ button:hover {
|
||||||
border-top-right-radius: 4px;
|
border-top-right-radius: 4px;
|
||||||
border-bottom: 1px solid gray;
|
border-bottom: 1px solid gray;
|
||||||
background-color: rgba(0,0,0,0.2);
|
background-color: rgba(0,0,0,0.2);
|
||||||
|
font-family: 'Russo One', monospace;
|
||||||
|
font-size: smaller;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue