diff --git a/apps/entonclk/ChangeLog b/apps/entonclk/ChangeLog index 62e2d0c20..e16defa54 100644 --- a/apps/entonclk/ChangeLog +++ b/apps/entonclk/ChangeLog @@ -1 +1,2 @@ -0.1: New App! \ No newline at end of file +0.1: New App! +0.2: Now with timer function diff --git a/apps/entonclk/README.md b/apps/entonclk/README.md index 8c788c7a5..c67cc19c8 100644 --- a/apps/entonclk/README.md +++ b/apps/entonclk/README.md @@ -6,4 +6,16 @@ Things I changed: - The main font for the time is now Audiowide - Removed the written out day name and replaced it with steps and bpm -- Changed the date string to a (for me) more readable string \ No newline at end of file +- Changed the date string to a (for me) more readable string + +Timer function: +- Touch the right side, to start the timer +- Initial timer timeout is 300s/5min +- Right touch again, add 300s/5min to timeout +- Left touch, decrease timeout by 60s/1min +- So it is easy, to add timeouts like 7min/3min or 12min +- Special thanks to the maintainer of the a_clock_timer app from which I borrowed the code. + +Todo: +- Make displayed information configurable, after https://github.com/espruino/BangleApps/issues/2226 +- Clean up code diff --git a/apps/entonclk/app.js b/apps/entonclk/app.js index 69fdea479..292030b86 100644 --- a/apps/entonclk/app.js +++ b/apps/entonclk/app.js @@ -1,67 +1,127 @@ +// Fonts Graphics.prototype.setFontAudiowide = function() { - // Actual height 33 (36 - 4) var widths = atob("CiAsESQjJSQkHyQkDA=="); var font = atob("AAAAAAAAAAAAAAAAAAAAAPAAAAAAAfgAAAAAAfgAAAAAAfgAAAAAAfgAAAAAAPAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAADgAAAAAAHgAAAAAAfgAAAAAA/gAAAAAD/gAAAAAH/gAAAAAf/AAAAAB/8AAAAAD/4AAAAAP/gAAAAAf/AAAAAB/8AAAAAD/4AAAAAP/gAAAAAf+AAAAAB/8AAAAAH/wAAAAAP/gAAAAA/+AAAAAB/8AAAAAD/wAAAAAD/gAAAAAD+AAAAAAD4AAAAAADwAAAAAADAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/AAAAAA//+AAAAB///AAAAH///wAAAP///4AAAf///8AAA////+AAA/4AP+AAB/gAD/AAB/AA9/AAD+AB+/gAD+AD+/gAD+AD+/gAD8AH+fgAD8AP8fgAD8AP4fgAD8Af4fgAD8A/wfgAD8A/gfgAD8B/gfgAD8D/AfgAD8D+AfgAD8H+AfgAD8P8AfgAD8P4AfgAD8f4AfgAD8/wAfgAD8/gAfgAD+/gA/gAD+/AA/gAB/eAB/AAB/sAD/AAB/wAH/AAA////+AAAf///8AAAP///4AAAH///wAAAD///gAAAA//+AAAAAP/4AAAAAAAAAAAAAAAAAAAAAAAAAAAD8AAAAAAD8AAAAAAD8AAAAAAD8AAAAAAD8AAAAAAD8AAAAAAD/////gAD/////gAD/////gAD/////gAD/////gAD/////gAD/////gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//gAAAAH//gAAAAP//gAD8Af//gAD8A///gAD8B///gAD8B///gAD8B/AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD+D+AfgAD//+AfgAD//+AfgAB//8AfgAA//4AfgAAf/wAfgAAP/gAfgAAB8AAfgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD+B+A/gAD/////gAB/////AAB/////AAA////+AAAf///8AAAP///4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//4AAAAD//8AAAAD//+AAAAD//+AAAAD//+AAAAD//+AAAAD//+AAAAAAB+AAAAAAB+AAAAAAB+AAAAAAB+AAAAAAB+AAAAAAB+AAAAAAB+AAAAAAB+AAAAAAB+AAAAAAB+AAAAAAB+AAAAAAB+AAAAAAB+AAAAAAB+AAAAAAB+AAAAAAB+AAAAAAB+AAAAAAB+AAAAD/////gAD/////gAD/////gAD/////gAD/////gAD/////gAD/////gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//AAfgAD//wAfgAD//4AfgAD//8AfgAD//8AfgAD//+AfgAD8D+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B/A/gAD8B///gAD8B///gAD8A///AAD8A///AAAAAf/+AAAAAP/4AAAAAD/gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB///AAAAH///wAAAf///8AAAf///8AAA////+AAB/////AAB/h+H/AAD/B+B/gAD+B+A/gAD+B+A/gAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B/A/gAD8B///gAD8B///gAD8A///AAAAAf//AAAAAf/+AAAAAH/4AAAAAB/gAAAAAAAAAAAAAAAAAAAAAAAAAAD8AAAAAAD8AAAAAAD8AAAAAAD8AAAAAAD8AAAAgAD8AAABgAD8AAAHgAD8AAAfgAD8AAA/gAD8AAD/gAD8AAP/gAD8AA//gAD8AB//AAD8AH/8AAD8Af/wAAD8A//AAAD8D/+AAAD8P/4AAAD8f/gAAAD9//AAAAD//8AAAAD//wAAAAD//gAAAAD/+AAAAAD/4AAAAAD/wAAAAAD/AAAAAAD8AAAAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/gAAAAAH/4AAAAAP/8AAAH+f/+AAAf////AAA/////gAB/////gAB///A/gAD//+AfgAD//+AfgAD+D+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD+D+AfgAD//+AfgAD//+AfgAB///A/gAB/////gAA/////AAAP////AAAD+f/+AAAAAP/8AAAAAH/4AAAAAA+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH/AAAAAAf/wAAAAA//4AAAAB//8AAAAB//8AfgAD//+AfgAD/D+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD8B+AfgAD+B+A/gAD+B+A/gAD/B+B/gAB/////AAB/////AAA////+AAAf///8AAAP///4AAAH///wAAAB///AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAeAAPAAAA/AAfgAAA/AAfgAAA/AAfgAAA/AAfgAAAeAAPAAAAAAAAAAAAAAAAAAAAAAAAAA"); var scale = 1; // size multiplier for this font g.setFontCustom(font, 46, widths, 48+(scale<<8)+(1<<16)); }; +// Globals variables +var timervalue = 0; +var istimeron = false; +var timertick; + +// Functions function getSteps() { - var steps = 0; - try{ - if (WIDGETS.wpedom !== undefined) { - steps = WIDGETS.wpedom.getSteps(); - } else if (WIDGETS.activepedom !== undefined) { - steps = WIDGETS.activepedom.getSteps(); - } else { - steps = Bangle.getHealthStatus("day").steps; - } + var steps = 0; + try{ + if (WIDGETS.wpedom !== undefined) { + steps = WIDGETS.wpedom.getSteps(); + } else if (WIDGETS.activepedom !== undefined) { + steps = WIDGETS.activepedom.getSteps(); + } else { + steps = Bangle.getHealthStatus("day").steps; + } } catch(ex) { - // In case we failed, we can only show 0 steps. - return "?"; + // In case we failed, we can only show 0 steps. + return "?"; } - return Math.round(steps); + return Math.round(steps); } +function timeToString(duration) { + var hrs = ~~(duration / 3600); + var mins = ~~((duration % 3600) / 60); + var secs = ~~duration % 60; + var ret = ""; + if (hrs > 0) { + ret += "" + hrs + ":" + (mins < 10 ? "0" : ""); + } + ret += "" + mins + ":" + (secs < 10 ? "0" : ""); + ret += "" + secs; + return ret; +} + +function countDown() { + timervalue--; + + g.reset().clearRect(0, 40, 44+99, g.getHeight()/2-25); + + g.setFontAlign(0, -1, 0); + g.setFont("6x8", 2).drawString(timeToString(timervalue), 95, g.getHeight()/2-50); + + if (timervalue <= 0) { + istimeron = false; + clearInterval(timertick); + + Bangle.buzz().then(()=>{ + return new Promise(resolve=>setTimeout(resolve, 500)); + }).then(()=>{ + return Bangle.buzz(1000); + }); + } + else + if ((timervalue <= 30) && (timervalue % 10 == 0)) { Bangle.buzz(); } +} + +// Touch +Bangle.on('touch',t => { + if (t == 1) { + // Touch on the left, reduce timervalue about 60s + Bangle.buzz(30); + if (timervalue < 60) { timervalue = 1 ; } + else { timervalue -= 60; } + } + // Touch on the right, raise timervaule about 300s + else if (t == 2) { + Bangle.buzz(30); + if (!istimeron) { + istimeron = true; + timertick = setInterval(countDown, 1000); + } + timervalue += 60*5; + } +}); + { // must be inside our own scope here so that when we are unloaded everything disappears // we also define functions using 'let fn = function() {..}' for the same reason. function decls are global -let drawTimeout; + let drawTimeout; -// Actually draw the watch face -let draw = function() { - var x = g.getWidth() / 2; - var y = g.getHeight() / 2; - g.reset().clearRect(Bangle.appRect); // clear whole background (w/o widgets) - var date = new Date(); - var timeStr = require("locale").time(date, 1); // Hour and minute - g.setFontAlign(0, 0).setFont("Audiowide").drawString(timeStr, x, y); - var dateStr = require("locale").date(date, 1).toUpperCase(); - g.setFontAlign(0, 0).setFont("6x8", 2).drawString(dateStr, x, y+28); - g.setFontAlign(0, 0).setFont("6x8", 2); - g.drawString(getSteps(), 50, y+70); - g.drawString(Math.round(Bangle.getHealthStatus("last").bpm), g.getWidth() -37, y + 70); + // Actually draw the watch face + let draw = function() { + var x = g.getWidth() / 2; + var y = g.getHeight() / 2; + g.reset().clearRect(Bangle.appRect); // clear whole background (w/o widgets) + var date = new Date(); + var timeStr = require("locale").time(date, 1); // Hour and minute + g.setFontAlign(0, 0).setFont("Audiowide").drawString(timeStr, x, y); + var dateStr = require("locale").date(date, 1).toUpperCase(); + g.setFontAlign(0, 0).setFont("6x8", 2).drawString(dateStr, x, y+28); + g.setFontAlign(0, 0).setFont("6x8", 2); + g.drawString(getSteps(), 50, y+70); + g.drawString(Math.round(Bangle.getHealthStatus("last").bpm), g.getWidth() -37, y + 70); - // queue next draw - if (drawTimeout) clearTimeout(drawTimeout); - drawTimeout = setTimeout(function() { - drawTimeout = undefined; - draw(); - }, 60000 - (Date.now() % 60000)); -}; - -// Show launcher when middle button pressed -Bangle.setUI({ - mode : "clock", - remove : function() { - // Called to unload all of the clock app + // queue next draw if (drawTimeout) clearTimeout(drawTimeout); - drawTimeout = undefined; - delete Graphics.prototype.setFontAnton; - }}); -// Load widgets -Bangle.loadWidgets(); -draw(); -setTimeout(Bangle.drawWidgets,0); -} + drawTimeout = setTimeout(function() { + drawTimeout = undefined; + draw(); + }, 60000 - (Date.now() % 60000)); + }; + + // Show launcher when middle button pressed + Bangle.setUI({ + mode : "clock", + remove : function() { + // Called to unload all of the clock app + if (drawTimeout) clearTimeout(drawTimeout); + drawTimeout = undefined; + delete Graphics.prototype.setFontAnton; + }}); + // Load widgets + Bangle.loadWidgets(); + draw(); + setTimeout(Bangle.drawWidgets,0); +} \ No newline at end of file diff --git a/apps/entonclk/metadata.json b/apps/entonclk/metadata.json index 7e4947406..4b7174263 100644 --- a/apps/entonclk/metadata.json +++ b/apps/entonclk/metadata.json @@ -1,8 +1,8 @@ { "id": "entonclk", "name": "Enton Clock", - "version": "0.1", - "description": "A simple clock using the Audiowide font. ", + "version": "0.2", + "description": "A simple clock using the Audiowide font with timer. ", "icon": "app.png", "screenshots": [{"url":"screenshot.png"}], "type": "clock",