diff --git a/apps/sched/ChangeLog b/apps/sched/ChangeLog index eab8dd3053..019ec8467a 100644 --- a/apps/sched/ChangeLog +++ b/apps/sched/ChangeLog @@ -31,3 +31,4 @@ 0.28: Added an icon for disabled events 0.29: Improve clkinfo startup time by 10ms 0.30: Fix possible bug in toggling an alarm to on, from clkinfo +0.31: Pressing BTN1 behaves the same as pressing Stop diff --git a/apps/sched/README.md b/apps/sched/README.md index 1216a1a11f..5546b138d1 100644 --- a/apps/sched/README.md +++ b/apps/sched/README.md @@ -20,6 +20,7 @@ Global Settings - `Buzz Count` - The number of buzzes before the watch goes silent, or "forever" to buzz until stopped. - `Buzz Interval` - The interval between one buzz and the next - `Default Alarm/Timer Pattern` - Default vibration pattern for newly created alarms/timers +- `BTN1 to Stop` - If `Yes` a button press will register the same as pressing `Stop`. Internals / Library ------------------- diff --git a/apps/sched/lib.js b/apps/sched/lib.js index e11448a184..387e8306bb 100644 --- a/apps/sched/lib.js +++ b/apps/sched/lib.js @@ -112,7 +112,8 @@ exports.getSettings = function () { buzzCount: 10, buzzIntervalMillis: 3000, // 3 seconds defaultAlarmPattern: "::", - defaultTimerPattern: "::" + defaultTimerPattern: "::", + btnToStop: false }, require("Storage").readJSON("sched.settings.json", true) || {} ); diff --git a/apps/sched/metadata.json b/apps/sched/metadata.json index 7e3458ae6c..8a52068c1c 100644 --- a/apps/sched/metadata.json +++ b/apps/sched/metadata.json @@ -1,7 +1,7 @@ { "id": "sched", "name": "Scheduler", - "version": "0.30", + "version": "0.31", "description": "Scheduling library for alarms and timers", "icon": "app.png", "type": "scheduler", diff --git a/apps/sched/sched.js b/apps/sched/sched.js index 04cd38718e..cdba60495a 100644 --- a/apps/sched/sched.js +++ b/apps/sched/sched.js @@ -1,5 +1,100 @@ // Chances are boot0.js got run already and scheduled *another* // 'load(sched.js)' - so let's remove it first! + +function showPromptBtnCancel(msg,options) { + if (!options) options={}; + if (!options.buttons) + options.buttons = {"Yes":true,"No":false}; + var btns = Object.keys(options.buttons); + var btnPos; + function draw(highlightedButton) { + g.reset().setFont("6x8:2").setFontAlign(0,-1); + var Y = Bangle.appRect.y; + var W = g.getWidth(), H = g.getHeight()-Y, FH=g.getFontHeight(); + var titleLines = g.wrapString(options.title, W-2); + var msgLines = g.wrapString(msg||"", W-2); + var y = Y + (H + (titleLines.length - msgLines.length)*FH )/2 - 24; + if (options.img) { + var im = g.imageMetrics(options.img); + g.drawImage(options.img,(W-im.width)/2,y - im.height/2); + y += 4+im.height/2; + } + if (titleLines) + g.setColor(g.theme.fgH).setBgColor(g.theme.bgH). + clearRect(0,Y,W-1,Y+4+titleLines.length*FH). + drawString(titleLines.join("\n"),W/2,Y+2); + g.setColor(g.theme.fg).setBgColor(g.theme.bg). + drawString(msgLines.join("\n"),W/2,y); + y += msgLines.length*FH+32; + + var buttonWidths = 0; + var buttonPadding = 24; + g.setFontAlign(0,0); + btns.forEach(btn=>buttonWidths += buttonPadding+g.stringWidth(btn)); + if (buttonWidths>W) { // if they don't fit, use smaller font + g.setFont("6x8"); + buttonWidths = 0; + btns.forEach(btn=>buttonWidths += buttonPadding+g.stringWidth(btn)); + } + var x = (W-buttonWidths)/2; + btnPos = []; + btns.forEach((btn,idx)=>{ + var w = g.stringWidth(btn); + x += (buttonPadding+w)/2; + var bw = 6+w/2; + var poly = [x-bw,y-16, + x+bw,y-16, + x+bw+4,y-12, + x+bw+4,y+12, + x+bw,y+16, + x-bw,y+16, + x-bw-4,y+12, + x-bw-4,y-12, + x-bw,y-16]; + btnPos.push({x1:x-bw-buttonPadding/2, x2:x+bw+buttonPadding/2, + y1:y-30, y2:y+30, + poly: poly}); + g.setColor(idx===highlightedButton ? g.theme.bgH : g.theme.bg2).fillPoly(poly). + setColor(idx===highlightedButton ? g.theme.fgH : g.theme.fg2).drawPoly(poly).drawString(btn,x,y+1); + x += (buttonPadding+w)/2; + }); + Bangle.setLCDPower(1); // ensure screen is on + } + g.reset().clearRect(Bangle.appRect); // clear screen + if (!msg) { + Bangle.setUI(); // remove watches + return Promise.resolve(); + } + draw(); + return new Promise(resolve=>{ + Bangle.setUI({mode:"custom", remove: options.remove, redraw: draw, back:options.back, + btn: () => { // Handle physical buttons explicitly + showPromptBtnCancel(); + resolve(options.buttons.No); + }, + touch:(_,e)=>{ + btnPos.forEach((b,i)=>{ + if (e.x > b.x1 && e.x < b.x2 && + e.y > b.y1 && e.y < b.y2) { + draw(i); // highlighted button + g.flip(); // write to screen + showPromptBtnCancel(); // remove + resolve(options.buttons[btns[i]]); + } + }); + }}); + }); +} + +function showCustomPrompt(message, options, btnToStop) { + const BANGLEJS2 = process.env.HWVERSION==2; + if (BANGLEJS2 && btnToStop) { + return showPromptBtnCancel(message, options); + } else { + return E.showPrompt(message, options); + } +} + if (Bangle.SCHED) { clearInterval(Bangle.SCHED); delete Bangle.SCHED; @@ -25,10 +120,10 @@ function showAlarm(alarm) { let buzzCount = settings.buzzCount; - E.showPrompt(message, { + showCustomPrompt(message, { title: alarm.timer ? /*LANG*/"TIMER!" : /*LANG*/"ALARM!", buttons: { /*LANG*/"Snooze": true, /*LANG*/"Stop": false } // default is sleep so it'll come back in some mins - }).then(function (sleep) { + }, settings.btnToStop).then(function (sleep) { buzzCount = 0; if (sleep) { diff --git a/apps/sched/settings.js b/apps/sched/settings.js index c03cd6679e..b734c26c62 100644 --- a/apps/sched/settings.js +++ b/apps/sched/settings.js @@ -1,7 +1,8 @@ (function (back) { let settings = require("sched").getSettings(); + const BANGLEJS2 = process.env.HWVERSION == 2; - E.showMenu({ + let menu = { "": { "title": /*LANG*/"Scheduler" }, "< Back": () => back(), @@ -70,10 +71,21 @@ settings.defaultAlarmPattern = v; require("sched").setSettings(settings); }), - /*LANG*/"Default Timer Pattern": require("buzz_menu").pattern(settings.defaultTimerPattern, v => { settings.defaultTimerPattern = v; require("sched").setSettings(settings); }) - }); + }; + + if (BANGLEJS2) { + menu[/*LANG*/"BTN1 to Stop"] = { + value: settings.btnToStop, + onchange: v => { + settings.btnToStop = v; + require("sched").setSettings(settings); + } + }; + } + + E.showMenu(menu); }) diff --git a/typescript/types/sched.d.ts b/typescript/types/sched.d.ts index 1bcffb6325..5d9ab2d064 100644 --- a/typescript/types/sched.d.ts +++ b/typescript/types/sched.d.ts @@ -93,6 +93,7 @@ declare module Sched { buzzIntervalMillis: number, defaultAlarmPattern: string, defaultTimerPattern: string, + btnToStop: boolean, }; function getAlarms(): Sched[];