diff --git a/apps/widalarmeta/ChangeLog b/apps/widalarmeta/ChangeLog new file mode 100644 index 000000000..37b619f7f --- /dev/null +++ b/apps/widalarmeta/ChangeLog @@ -0,0 +1,4 @@ +0.01: New App! +0.02: Change font to 5x9 7 segment-style + Add settings page + Add option to show seconds diff --git a/apps/widalarmeta/metadata.json b/apps/widalarmeta/metadata.json index ef9f55ba8..79387c1c5 100644 --- a/apps/widalarmeta/metadata.json +++ b/apps/widalarmeta/metadata.json @@ -2,8 +2,8 @@ "id": "widalarmeta", "name": "Alarm & Timer ETA", "shortName": "Alarm ETA", - "version": "0.01", - "description": "A widget that displays the time to the next Alarm or Timer in hours and minutes, maximum 24h", + "version": "0.02", + "description": "A widget that displays the time to the next Alarm or Timer in hours and minutes, maximum 24h (configurable).", "icon": "widget.png", "type": "widget", "tags": "widget", @@ -11,6 +11,8 @@ "provides_widgets" : ["alarm"], "screenshots" : [ { "url":"screenshot.png" } ], "storage": [ - {"name":"widalarmeta.wid.js","url":"widget.js"} - ] + {"name":"widalarmeta.wid.js","url":"widget.js"}, + {"name":"widalarmeta.settings.js","url":"settings.js"} + ], + "data": [{"name":"widalarmeta.json"}] } diff --git a/apps/widalarmeta/screenshot.png b/apps/widalarmeta/screenshot.png index 41a109557..3a23b757a 100644 Binary files a/apps/widalarmeta/screenshot.png and b/apps/widalarmeta/screenshot.png differ diff --git a/apps/widalarmeta/settings.js b/apps/widalarmeta/settings.js new file mode 100644 index 000000000..5922d159d --- /dev/null +++ b/apps/widalarmeta/settings.js @@ -0,0 +1,45 @@ +(function(back) { + const CONFIGFILE = "widalarmeta.json"; + // Load settings + const settings = Object.assign({ + maxhours: 24, + drawBell: false, + showSeconds: 0, // 0=never, 1=only when display is unlocked, 2=for less than a minute + }, require("Storage").readJSON(CONFIGFILE,1) || {}); + + function writeSettings() { + require('Storage').writeJSON(CONFIGFILE, settings); + } + + // Show the menu + E.showMenu({ + "" : { "title" : "Alarm & Timer ETA" }, + "< Back" : () => back(), + /*LANG*/'Maximum hours': { + format: v => v === 0 ? /*LANG*/'disabled' : v, + value: settings.maxhours, + min: 0, max: 24, + onchange: v => { + settings.maxhours = v; + writeSettings(); + } + }, + /*LANG*/'Draw bell': { + value: !!settings.drawBell, + format: v => v?/*LANG*/"Yes":/*LANG*/"No", + onchange: v => { + settings.drawBell = v; + writeSettings(); + } + }, + /*LANG*/'Show seconds': { + value: settings.showSeconds, + min: 0, max: 2, + format: v => [/*LANG*/"Never", /*LANG*/"Unlocked", /*LANG*/"Last minute"][v || 0], + onchange: v => { + settings.showSeconds = v; + writeSettings(); + } + }, + }); +}); diff --git a/apps/widalarmeta/widget.js b/apps/widalarmeta/widget.js index 0cddf953a..ff3390d89 100644 --- a/apps/widalarmeta/widget.js +++ b/apps/widalarmeta/widget.js @@ -1,35 +1,68 @@ (() => { + require("Font5x9Numeric7Seg").add(Graphics); const alarms = require("Storage").readJSON("sched.json",1) || []; + const config = Object.assign({ + maxhours: 24, + drawBell: false, + showSeconds: 0, // 0=never, 1=only when display is unlocked, 2=for less than a minute + }, require("Storage").readJSON("widalarmeta.json",1) || {}); function draw() { const times = alarms.map(alarm => require("sched").getTimeToAlarm(alarm)).filter(a => a !== undefined); const next = Math.min.apply(null, times); - if (next > 0 && next < 86400000) { - const hours = Math.floor((next % 86400000) / 3600000).toString(); - const minutes = Math.floor(((next % 86400000) % 3600000) / 60000).toString(); + let calcWidth = 0; + let drawSeconds = false; + + 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(0,0); // center fonts g.clearRect(this.x, this.y, this.x+this.width-1, this.y+23); var text = hours.padStart(2, '0') + ":" + minutes.padStart(2, '0'); - g.setFont("6x8:1x2"); - g.drawString(text, this.x+this.width/2, this.y+12); - if (this.width === 0) { - this.width = 6*5+2; - Bangle.drawWidgets(); // width changed, re-layout + if (drawSeconds) { + text += ":" + seconds.padStart(2, '0'); } + g.setFont("5x9Numeric7Seg:1x2"); + g.drawString(text, this.x+this.width/2, this.y+12); + + calcWidth = 5*5+2; + if (drawSeconds) { + calcWidth += 3*5; + } + } else if (times.length > 0 && config.drawBell) { + // next alarm too far in future, draw only widalarm bell + g.reset().drawImage(atob("GBgBAAAAAAAAABgADhhwDDwwGP8YGf+YMf+MM//MM//MA//AA//AA//AA//AA//AA//AB//gD//wD//wAAAAADwAABgAAAAAAAAA"),this.x,this.y); + calcWidth = 24; } + + if (this.width !== calcWidth) { + // width changed, re-layout + this.width = calcWidth; + Bangle.drawWidgets(); + } + + // redraw next full minute or second + const period = drawSeconds ? 1000 : 60000; + let timeout = next > 0 ? next % period : period - (Date.now() % period); + if (timeout === 0) { + timeout += period; + } + setTimeout(()=>{ + WIDGETS["widalarmeta"].draw(WIDGETS["widalarmeta"]); + }, timeout); + } /* draw */ + + if (config.maxhours > 0) { + // add your widget + WIDGETS["widalarmeta"]={ + area:"tl", + width: 0, // hide by default = assume no timer + draw:draw + }; } - - setInterval(function() { - WIDGETS["widalarmeta"].draw(WIDGETS["widalarmeta"]); - }, 30000); // update every half minute - - // add your widget - WIDGETS["widalarmeta"]={ - area:"tl", - width: 0, // hide by default = assume no timer - draw:draw - }; })();