forked from FOSS/BangleApps
198 lines
6.2 KiB
JavaScript
198 lines
6.2 KiB
JavaScript
/**
|
|
* @param {function} back Use back() to return to settings menu
|
|
*/
|
|
(function(back) {
|
|
const names = {};
|
|
const settings = require("Storage").readJSON("wid_edit.json", 1) || {};
|
|
if (!('custom' in settings)) settings.custom = {};
|
|
global._WIDGETS = global._WIDGETS || {};
|
|
|
|
let cleanup = false;
|
|
for (const id in settings.custom) {
|
|
if (!(id in global.WIDGETS)) {
|
|
// widget which no longer exists
|
|
cleanup = true;
|
|
delete settings.custom[id];
|
|
}
|
|
}
|
|
if (cleanup) {
|
|
if (!Object.keys(settings.custom).length) delete settings.custom;
|
|
require("Storage").writeJSON("wid_edit.json", settings);
|
|
}
|
|
|
|
/**
|
|
* Sort & redraw all widgets
|
|
*/
|
|
function redrawWidgets() {
|
|
let W = global.WIDGETS;
|
|
global.WIDGETS = {};
|
|
Object.keys(W)
|
|
.sort() // see comment in boot.js
|
|
.sort((a, b) => (0|W[b].sortorder)-(0|W[a].sortorder))
|
|
.forEach(k => {global.WIDGETS[k] = W[k];});
|
|
Bangle.drawWidgets();
|
|
}
|
|
|
|
/**
|
|
* Try to find app name for widget
|
|
* @param {string} widget WIDGETS key
|
|
* @return {string} widget name
|
|
*/
|
|
function name(widget) {
|
|
if (!(widget in names)) {
|
|
let infoFile = widget+".info";
|
|
// widget names don't always correspond to appid :-(
|
|
// so we try both with and without 'wid'-prefix
|
|
if (!require("Storage").list(new RegExp(`^${infoFile}$`)).length) {
|
|
infoFile = (widget.substr(0, 3)==="wid") ? infoFile.substr(3) : ("wid"+infoFile);
|
|
}
|
|
names[widget] = (require("Storage").readJSON(infoFile, 1) || {}).name || widget;
|
|
}
|
|
return names[widget];
|
|
}
|
|
|
|
function edit(id) {
|
|
let WIDGET = global.WIDGETS[id],
|
|
def = {area: WIDGET.area, sortorder: WIDGET.sortorder|0}; // default values
|
|
Object.assign(def, global._WIDGETS[id]||{}); // defaults were saved in _WIDGETS
|
|
|
|
settings.custom = settings.custom||{};
|
|
let saved = settings.custom[id] || {},
|
|
area = saved.area || def.area,
|
|
sortorder = ("sortorder" in saved) ? saved.sortorder : def.sortorder;
|
|
|
|
/**
|
|
* Draw highlighted widget
|
|
*/
|
|
function highlight() {
|
|
if (WIDGET.width > 0) {
|
|
// draw widget, then draw a highlighted border on top
|
|
WIDGET.draw(WIDGET);
|
|
g.setColor(g.theme.fgH)
|
|
.drawRect(WIDGET.x, WIDGET.y, WIDGET.x+WIDGET.width-1, WIDGET.y+23);
|
|
} else {
|
|
// hidden widget: fake a width and provide our own draw()
|
|
const draw = WIDGET.draw, width = WIDGET.width;
|
|
WIDGET.width = 24;
|
|
WIDGET.draw = function() {
|
|
g.setColor(g.theme.bgH).setColor(g.theme.fgH)
|
|
.clearRect(this.x, this.y, this.x+23, this.y+23)
|
|
.drawRect(this.x, this.y, this.x+23, this.y+23)
|
|
.drawLine(this.x, this.y, this.x+23, this.y+23)
|
|
.drawLine(this.x, this.y+23, this.x+23, this.y);
|
|
};
|
|
// re-layout+draw all widgets with our placeholder in between
|
|
redrawWidgets();
|
|
// and restore original values
|
|
WIDGET.draw = draw;
|
|
WIDGET.width = width;
|
|
}
|
|
}
|
|
highlight();
|
|
|
|
/**
|
|
* Save widget and redraw with new settings
|
|
*/
|
|
function save() {
|
|
// we only save non-default values
|
|
saved = {};
|
|
if ((area!==def.area) || (sortorder!==def.sortorder)) {
|
|
if (area!==def.area) saved.area = area;
|
|
if (sortorder!==def.sortorder) saved.sortorder = sortorder;
|
|
settings.custom = settings.custom || {};
|
|
settings.custom[id] = saved;
|
|
} else if (settings.custom) {
|
|
delete settings.custom[id];
|
|
}
|
|
if (!Object.keys(settings.custom).length) delete settings.custom;
|
|
require("Storage").writeJSON("wid_edit.json", settings);
|
|
Object.assign(WIDGET, def, saved);
|
|
if (WIDGET.sortorder === undefined) delete WIDGET.sortorder; // default can be undefined, but don't put that in the widget
|
|
// if we assigned custom values, store defaults in _WIDGETS
|
|
let _W = {};
|
|
if (saved.area) _W.area = def.area;
|
|
if ('sortorder' in saved) _W.sortorder = def.sortorder;
|
|
if (Object.keys(_W).length) global._WIDGETS[id] = _W;
|
|
else delete global._WIDGETS[id];
|
|
|
|
// drawWidgets won't clear e.g. bottom bar if we just disabled the last bottom widget
|
|
redrawWidgets();
|
|
|
|
highlight();
|
|
m.draw();
|
|
}
|
|
|
|
const AREA_NAMES = [ "Top left", "Top right", "Bottom left", "Bottom right" ];
|
|
const AREAS = [ "tl", "tr", "bl", "br" ];
|
|
|
|
const menu = {
|
|
"": {"title": name(id),
|
|
back: () => {
|
|
redrawWidgets();
|
|
mainMenu();
|
|
} },
|
|
/*LANG*/"Position": {
|
|
value: AREAS.indexOf(area),
|
|
format: v => AREA_NAMES[v],
|
|
min: 0,
|
|
max: AREAS.length - 1,
|
|
onchange: v => {
|
|
print("v", v);
|
|
area = AREAS[v];
|
|
save();
|
|
}
|
|
},
|
|
/*LANG*/"Sort Order": {
|
|
value: sortorder,
|
|
onchange: o => {
|
|
sortorder = o;
|
|
save();
|
|
}
|
|
},
|
|
/*LANG*/"Reset": () => {
|
|
area = def.area;
|
|
sortorder = def.sortorder;
|
|
save();
|
|
mainMenu(); // changing multiple values made the rest of the menu wrong, so take the easy out
|
|
}
|
|
};
|
|
|
|
let m = E.showMenu(menu);
|
|
}
|
|
|
|
|
|
function mainMenu() {
|
|
let menu = {
|
|
"": {
|
|
"title": /*LANG*/"Widgets",
|
|
back: ()=>{
|
|
if (!Object.keys(global._WIDGETS).length) delete global._WIDGETS; // no defaults to remember
|
|
back();
|
|
}},
|
|
};
|
|
Object.keys(global.WIDGETS).forEach(id=>{
|
|
// mark customized widgets with asterisk
|
|
menu[name(id)+((id in global._WIDGETS) ? " *" : "")] = () => edit(id);
|
|
});
|
|
if (Object.keys(global._WIDGETS).length) { // only show reset if there is anything to reset
|
|
menu[/*LANG*/"Reset All"] = () => {
|
|
E.showPrompt(/*LANG*/"Reset all widgets?").then(confirm => {
|
|
if (confirm) {
|
|
delete settings.custom;
|
|
require("Storage").writeJSON("wid_edit.json", settings);
|
|
for(let id in global._WIDGETS) {
|
|
Object.assign(global.WIDGETS[id], global._WIDGETS[id]); // restore defaults
|
|
}
|
|
global._WIDGETS = {};
|
|
redrawWidgets();
|
|
}
|
|
mainMenu(); // reload with reset widgets
|
|
});
|
|
};
|
|
}
|
|
|
|
E.showMenu(menu);
|
|
}
|
|
mainMenu();
|
|
})
|