BangleApps/modules/widget_utils.js

148 lines
4.3 KiB
JavaScript
Raw Normal View History

2022-10-26 10:51:30 +00:00
/// hide any visible widgets
exports.hide = function() {
exports.cleanup();
2022-10-26 10:51:30 +00:00
if (!global.WIDGETS) return;
g.reset(); // reset colors
for (var w of global.WIDGETS) {
if (w._draw) return; // already hidden
w._draw = w.draw;
w.draw = () => {};
w._area = w.area;
w.area = "";
if (w.x!=undefined) g.clearRect(w.x,w.y,w.x+w.width-1,w.y+23);
}
};
/// Show any hidden widgets
exports.show = function() {
exports.cleanup();
if (!global.WIDGETS) return;
2022-10-26 10:51:30 +00:00
for (var w of global.WIDGETS) {
if (!w._draw) return; // not hidden
w.draw = w._draw;
w.area = w._area;
delete w._draw;
delete w._area;
w.draw(w);
}
};
/// Remove any intervals/handlers/etc that we might have added. Does NOT re-show widgets that were hidden
exports.cleanup = function() {
delete exports.autohide;
delete Bangle.appRect;
if (exports.swipeHandler) {
Bangle.removeListener("swipe", exports.swipeHandler);
delete exports.swipeHandler;
}
if (exports.animInterval) {
clearInterval(exports.animInterval);
delete exports.animInterval;
}
if (exports.hideTimeout) {
clearTimeout(exports.hideTimeout);
delete exports.hideTimeout;
}
if (exports.origDraw) {
Bangle.drawWidgets = exports.origDraw;
delete exports.origDraw;
}
};
/** Put widgets offscreen, and allow them to be swiped
back onscreen with a downwards swipe. Use .show to undo.
First parameter controls automatic hiding time, 0 equals not hiding at all.
Default value is 2000ms until hiding.
Bangle.js 2 only at the moment. On Bangle.js 1 widgets will be hidden permanently.
Note: On Bangle.js 1 is is possible to draw widgets in an offscreen area of the LCD
and use Bangle.setLCDOffset. However we can't detect a downward swipe so how to
actually make this work needs some thought.
*/
exports.swipeOn = function(autohide) {
if (process.env.HWVERSION!==2) return exports.hide();
exports.cleanup();
if (!global.WIDGETS) return;
exports.autohide=autohide===undefined?2000:autohide;
/* TODO: maybe when widgets are offscreen we don't even
store them in an offscreen buffer? */
// force app rect to be fullscreen
Bangle.appRect = { x: 0, y: 0, w: g.getWidth(), h: g.getHeight(), x2: g.getWidth()-1, y2: g.getHeight()-1 };
// setup offscreen graphics for widgets
let og = Graphics.createArrayBuffer(g.getWidth(),26,16,{msb:true});
og.theme = g.theme;
og._reset = og.reset;
og.reset = function() {
return this._reset().setColor(g.theme.fg).setBgColor(g.theme.bg);
};
og.reset().clearRect(0,0,og.getWidth(),23).fillRect(0,24,og.getWidth(),25);
let _g = g;
let offset = -24; // where on the screen are we? -24=hidden, 0=full visible
function queueDraw() {
Bangle.appRect.y = offset+24;
Bangle.appRect.h = 1 + Bangle.appRect.y2 - Bangle.appRect.y;
if (offset>-24) Bangle.setLCDOverlay(og, 0, offset);
else Bangle.setLCDOverlay();
}
for (var w of global.WIDGETS) if (!w._draw) { // already hidden
w._draw = w.draw;
w.draw = function() {
g=og;
this._draw(this);
g=_g;
if (offset>-24) queueDraw();
};
w._area = w.area;
if (w.area.startsWith("b"))
w.area = "t"+w.area.substr(1);
}
exports.origDraw = Bangle.drawWidgets;
Bangle.drawWidgets = ()=>{
g=og;
exports.origDraw();
g=_g;
};
function anim(dir, callback) {
if (exports.animInterval) clearInterval(exports.animInterval);
exports.animInterval = setInterval(function() {
offset += dir;
let stop = false;
if (dir>0 && offset>=0) { // fully down
stop = true;
offset = 0;
} else if (dir<0 && offset<-23) { // fully up
stop = true;
offset = -24;
}
if (stop) {
clearInterval(exports.animInterval);
delete exports.animInterval;
if (callback) callback();
}
queueDraw();
}, 50);
}
// On swipe down, animate to show widgets
exports.swipeHandler = function(lr,ud) {
if (exports.hideTimeout) {
clearTimeout(exports.hideTimeout);
delete exports.hideTimeout;
}
let cb;
if (exports.autohide > 0) cb = function() {
exports.hideTimeout = setTimeout(function() {
anim(-4);
}, exports.autohide);
};
if (ud>0 && offset<0) anim(4, cb);
if (ud<0 && offset>-24) anim(-4);
};
Bangle.on("swipe", exports.swipeHandler);
Bangle.drawWidgets();
};