forked from espruino/BangleApps
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathwidget.js
More file actions
153 lines (135 loc) · 5.1 KB
/
widget.js
File metadata and controls
153 lines (135 loc) · 5.1 KB
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
(() => {
let config;
function loadSettings() {
config = Object.assign({
maxhours: 24,
drawBell: false,
padHours: true,
showSeconds: 0, // 0=never, 1=only when display is unlocked, 2=for less than a minute
font: 1, // 0=segment style font, 1=teletext font, 2=6x8:1x2, 3=VGA8
whenToShow: 0, // 0=always, 1=on clock only
}, require("Storage").readJSON("widalarmeta.json",1) || {});
if (config.font == 0) {
require("Font5x9Numeric7Seg").add(Graphics);
} else if (config.font == 1) {
require("FontTeletext5x9Ascii").add(Graphics);
} else if (config.font == 2) {
require("Font6x8").add(Graphics);
} else if (config.font == 3) {
require("FontVGA8").add(Graphics);
}
}
loadSettings();
function getNextAlarm(date) {
const alarms = require("sched")
.getAlarms()
// more precise filtering is done using getTimeToAlarm() below
.filter(alarm => alarm.on && alarm.hidden !== true);
WIDGETS["widalarmeta"].numActiveAlarms = alarms.length;
if (alarms.length > 0) {
const times = alarms.map(alarm => require("sched").getTimeToAlarm(alarm, date) || Number.POSITIVE_INFINITY);
const eta = Math.min.apply(null, times);
if (eta !== Number.POSITIVE_INFINITY) {
const idx = times.indexOf(eta);
const alarm = alarms[idx];
delete alarm.msg; delete alarm.id; delete alarm.data; // free some memory
return alarm;
}
}
} // getNextAlarm
function draw(_w, fromInterval) {
// If only show on clock and not on clock
if (config.whenToShow === 1 && !Bangle.CLOCK) {
this.nextAlarm = undefined; // make sure to reload later
return;
}
if (this.nextAlarm === undefined) {
let alarm = getNextAlarm();
if (alarm === undefined) {
// try again with next hour
const nextHour = new Date();
nextHour.setHours(nextHour.getHours()+1);
alarm = getNextAlarm(nextHour);
}
if (alarm !== undefined) {
this.nextAlarm = alarm;
}
}
const next = this.nextAlarm !== undefined ? require("sched").getTimeToAlarm(this.nextAlarm) : 0;
let calcWidth = 0;
let drawSeconds = false;
// Determine text and width
if (next > 0 && next <= config.maxhours*60*60*1000) {
const hours = Math.floor((next-1) / 3600000).toString();
const minutes = Math.floor(((next-1) % 3600000) / 60000).toString();
const seconds = Math.floor(((next-1) % 60000) / 1000).toString();
drawSeconds = (config.showSeconds & 0b01 && !Bangle.isLocked()) || (config.showSeconds & 0b10 && next <= 1000*60);
g.reset(); // reset the graphics context to defaults (color/font/etc)
g.setFontAlign(-1,0); // center font in y direction
g.clearRect(this.x, this.y, this.x+this.width-1, this.y+23);
var text = "";
if (config.padHours) {
text += hours.padStart(2, '0');
} else {
text += hours;
}
text += (config.font == 3 ? "\n" : ":") + minutes.padStart(2, '0');
if (drawSeconds) {
text += (config.font == 3 ? "\n" : ":") + seconds.padStart(2, '0');
}
if (config.font == 0) {
g.setFont("5x9Numeric7Seg:1x2");
} else if (config.font == 1) {
g.setFont("Teletext5x9Ascii:1x2");
} else if (config.font == 2) {
g.setFont("6x8:1x2");
} else if (config.font == 3) {
g.setFont("VGA8");
}
g.drawString(text, this.x+1, this.y+12);
calcWidth = g.stringWidth(text) + 2; // One pixel on each side
this.bellVisible = false;
} else if (config.drawBell && this.numActiveAlarms > 0) {
calcWidth = 24;
// next alarm too far in future, draw only widalarm bell
if (this.bellVisible !== true || fromInterval !== true) {
g.reset().drawImage(atob("GBgBAAAAAAAAABgADhhwDDwwGP8YGf+YMf+MM//MM//MA//AA//AA//AA//AA//AA//AB//gD//wD//wAAAAADwAABgAAAAAAAAA"),this.x,this.y);
this.bellVisible = true;
}
}
if (this.width !== calcWidth) {
// width changed, re-layout
this.width = calcWidth;
Bangle.drawWidgets();
}
// redraw next hour when no alarm else full minute or second
const period = next === 0 ? 3600000 : (drawSeconds ? 1000 : 60000);
let timeout = next > 0 ? next % period : period - (Date.now() % period);
if (timeout === 0) {
timeout += period;
}
if (this.timeoutId !== undefined) {
clearTimeout(this.timeoutId);
}
this.timeoutId = setTimeout(()=>{
var w = WIDGETS["widalarmeta"];
w.timeoutId = undefined;
w.draw(w, true);
}, timeout);
} /* draw */
if (config.maxhours > 0) {
WIDGETS["widalarmeta"]={
area:"tl",
width: 0, // hide by default = assume no timer
draw:draw,
reload: function () {
this.nextAlarm = undefined;
loadSettings();
Bangle.drawWidgets();
},
};
Bangle.on("alarmReload", () => WIDGETS["widalarmeta"].reload());
Bangle.on("lock", () => WIDGETS["widalarmeta"].draw(WIDGETS["widalarmeta"]))
Bangle.on("lcdPower", () => WIDGETS["widalarmeta"].draw(WIDGETS["widalarmeta"]))
}
})();