Skip to content

Commit d10e7f6

Browse files
authored
Add details about snooze menu, add boot.js if you cont want cutting-edge fw
1 parent 47cbde9 commit d10e7f6

File tree

1 file changed

+101
-11
lines changed

1 file changed

+101
-11
lines changed

apps/sched/README.md

Lines changed: 101 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,111 @@
1-
Sched: Scheduling library for alarms and timers
2-
====================================
1+
# Sched: Scheduling library for alarms and timers
2+
33

44
This provides boot code, a library and tools for alarms and timers.
55

66
Other apps can use this to provide alarm functionality.
77

8-
App
9-
---
8+
## App
9+
10+
11+
The `Alarms & Timers` app allows you to add/modify any running alarms and timers.
12+
13+
14+
### Snooze Menu
1015

11-
The **Alarms & Timers** app allows you to add/modify any running alarms and timers.
16+
With sched version 0.35 or later, when an alarm or timer is triggered, and you have the latest cutting-edge firmware (will be 2v28 when released), you can long press on the snooze button that pops up to go to a snooze menu, for finer control over snooze amounts. If you do not have the latest firmware or use the code below, you will not notice any changes.
1217

13-
When an alarm or timer is triggered, and you have the latest cutting edge firmware (will be 2v28 when released), you can long press on the snooze button that pops up to go to a snooze menu, for finer control over snooze amounts.
18+
If you want the functionality, but don't want to use cutting-edge firmware, you can upload this code to the bangle from the Web IDE instead, as `2v28_sim.boot.js`:
1419

15-
For timers, the last option in the snooze menu is the timer length itself.
20+
```
21+
E.showPrompt=(function(message,options) {
22+
if (!options) options={};
23+
if (!options.buttons)
24+
options.buttons = {"Yes":true,"No":false};
25+
var btns = Object.keys(options.buttons);
26+
if (btns.length>6) throw new Error(">6 buttons");
27+
var btnPos;
28+
function draw(highlightedButton) {
29+
g.reset().setFontAlign(0,0);
30+
var R = Bangle.appRect, Y = R.y, W = R.w;
31+
var title = g.findFont(options.title||"", {w:W-2,wrap:1,max:24});
32+
if (title.text) {
33+
g.setColor(g.theme.fgH).setBgColor(g.theme.bgH).
34+
clearRect(0,Y,W-1,Y+4+title.h).
35+
drawString(title.text,W/2,Y+4+title.h/2);
36+
Y += title.h+4;
37+
} else Y+=4;
38+
var BX = 0|"0123233"[btns.length],
39+
BY = Math.ceil(btns.length / BX),
40+
BW = (W-1)/BX, BH = options.buttonHeight || ((BY>1 || options.img)?40:50);
41+
var H = R.y2-(Y + BY*BH);
42+
if (options.img) {
43+
var im = g.imageMetrics(options.img);
44+
g.drawImage(options.img,(W-im.width)/2, Y + 6);
45+
H -= im.height;
46+
Y += im.height;
47+
}
48+
var msg = g.findFont(message, {w:W-2,h:H,wrap:1,trim:1,min:16});
49+
g.setColor(g.theme.fg).setBgColor(g.theme.bg).
50+
drawString(msg.text,W/2,Y+H/2);
51+
btnPos = [];
52+
btns.forEach((btn,idx)=>{
53+
var ix=idx%BX,iy=0|(idx/BX),x = ix*BW + 2, y = R.y2-(BY-iy)*BH + 1,
54+
bw = BW-4, bh = BH-2, poly = [x+4,y,
55+
x+bw-4,y,
56+
x+bw,y+4,
57+
x+bw,y+bh-4,
58+
x+bw-4,y+bh,
59+
x+4,y+bh,
60+
x,y+bh-4,
61+
x,y+4,
62+
x+4,y];
63+
btnPos.push({x1:x-2, x2:x+BW-2,
64+
y1:y, y2:y+BH});
65+
var btnText = g.findFont(btn, {w:bw-4,h:BH-4,wrap:1});
66+
g.setColor(idx===highlightedButton ? g.theme.bgH : g.theme.bg2).fillPoly(poly).
67+
setColor(idx===highlightedButton ? g.theme.fgH : g.theme.fg2).drawPoly(poly).drawString(btnText.text,x+bw/2,y+2+BH/2);
68+
if (idx&1) y+=BH;
69+
});
70+
Bangle.setLCDPower(1); // ensure screen is on
71+
}
72+
g.reset().clearRect(Bangle.appRect); // clear screen
73+
if (!message) {
74+
Bangle.setUI(); // remove watches
75+
return Promise.resolve();
76+
}
77+
draw();
78+
return new Promise(resolve=>{
79+
var ui = {mode:"custom", remove: options.remove, redraw: draw, back:options.back, touch:(_,e)=>{
80+
btnPos.forEach((b,i)=>{
81+
if (e.x >= b.x1 && e.x <= b.x2 &&
82+
e.y >= b.y1 && e.y <= b.y2 && !e.hit) {
83+
e.hit = true; // ensure we don't call twice if the buttons overlap
84+
draw(i); // highlighted button
85+
g.flip(); // write to screen
86+
E.showPrompt(); // remove
87+
if (e.type===2 /*long press*/ && options.buttonsLong && options.buttonsLong[btns[i]])
88+
resolve(options.buttonsLong[btns[i]]);
89+
else
90+
resolve(options.buttons[btns[i]]);
91+
}
92+
});
93+
}};
94+
if (btns.length==1 && !options.back) ui.btn = () => {
95+
draw(0); // highlighted button
96+
g.flip(); // write to screen
97+
E.showPrompt(); // remove
98+
resolve(options.buttons[btns[0]]);
99+
};
100+
Bangle.setUI(ui);
101+
});
102+
})
103+
104+
```
105+
That mimics the change in `E.showPrompt` needed to make the function work.
106+
107+
## Global Settings
16108

17-
Global Settings
18-
---------------
19109

20110
- `Unlock at Buzz` - If `Yes` the alarm/timer will unlock the watch
21111
- `Delete Expired Timers` - Default for whether expired timers are removed after firing.
@@ -25,8 +115,8 @@ Global Settings
25115
- `Buzz Interval` - The interval between one buzz and the next
26116
- `Default Alarm/Timer Pattern` - Default vibration pattern for newly created alarms/timers
27117

28-
Internals / Library
29-
-------------------
118+
## Internals / Library
119+
30120

31121
Alarms are stored in an array in `sched.json`, and take the form:
32122

0 commit comments

Comments
 (0)