forked from espruino/BangleApps
-
Notifications
You must be signed in to change notification settings - Fork 0
/
widget_utils.js
164 lines (154 loc) · 4.78 KB
/
widget_utils.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
exports.offset = 0;
exports.hide = function() {
exports.cleanup();
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;
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 anything not needed if the overlay was removed
exports.cleanupOverlay = function() {
exports.offset = -24;
Bangle.setLCDOverlay(undefined, {id: "widget_utils"});
delete exports.autohide;
delete Bangle.appRect;
if (exports.animInterval) {
clearInterval(exports.animInterval);
delete exports.animInterval;
}
if (exports.hideTimeout) {
clearTimeout(exports.hideTimeout);
delete exports.hideTimeout;
}
};
/// Remove any intervals/handlers/etc that we might have added. Does NOT re-show widgets that were hidden
exports.cleanup = function() {
exports.cleanupOverlay();
delete exports.offset;
if (exports.swipeHandler) {
Bangle.removeListener("swipe", exports.swipeHandler);
delete exports.swipeHandler;
}
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;
exports.offset = -24; // where on the screen are we? -24=hidden, 0=full visible
function queueDraw() {
const o = exports.offset;
Bangle.appRect.y = o+24;
Bangle.appRect.h = 1 + Bangle.appRect.y2 - Bangle.appRect.y;
if (o>-24) {
Bangle.setLCDOverlay(og, 0, o, {
id:"widget_utils",
remove:()=>{
require("widget_utils").cleanupOverlay();
}
});
} else {
Bangle.setLCDOverlay(undefined, {id: "widget_utils"});
}
}
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 (exports.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() {
exports.offset += dir;
let stop = false;
if (dir>0 && exports.offset>=0) { // fully down
stop = true;
exports.offset = 0;
} else if (dir<0 && exports.offset<-23) { // fully up
stop = true;
exports.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 && exports.offset<0) anim(4, cb);
if (ud<0 && exports.offset>-24) anim(-4);
};
Bangle.on("swipe", exports.swipeHandler);
Bangle.drawWidgets();
};