From 9b6374fae535ae9a1292866234d5b13eac209e2d Mon Sep 17 00:00:00 2001 From: Martin Boonk Date: Thu, 27 Oct 2022 18:09:01 +0200 Subject: [PATCH 1/5] quicklaunch - Only scan for missing apps on changes --- apps/quicklaunch/boot.js | 88 ++++++++++-------------------------- apps/quicklaunch/settings.js | 12 +++-- 2 files changed, 33 insertions(+), 67 deletions(-) diff --git a/apps/quicklaunch/boot.js b/apps/quicklaunch/boot.js index 3670c4776..54f261fdf 100644 --- a/apps/quicklaunch/boot.js +++ b/apps/quicklaunch/boot.js @@ -1,67 +1,29 @@ -(function() { - var settings = Object.assign(require("Storage").readJSON("quicklaunch.json", true) || {}); +{ + let settings = Object.assign(require("Storage").readJSON("quicklaunch.json", true) || {}); - //list all sources - var apps = require("Storage").list(/\.info$/).map(app=>{var a=require("Storage").readJSON(app,1);return a&&{src:a.src};}); - - //populate empty app list - - if (!settings.leftapp) { - settings["leftapp"] = {"name":"(none)"}; - require("Storage").write("quicklaunch.json",settings); - } - if (!settings.rightapp) { - settings["rightapp"] = {"name":"(none)"}; - require("Storage").write("quicklaunch.json",settings); - } - if (!settings.upapp) { - settings["upapp"] = {"name":"(none)"}; - require("Storage").write("quicklaunch.json",settings); - } - if (!settings.downapp) { - settings["downapp"] = {"name":"(none)"}; - require("Storage").write("quicklaunch.json",settings); - } - if (!settings.tapapp) { - settings["tapapp"] = {"name":"(none)"}; - require("Storage").write("quicklaunch.json",settings); - } + let hash = require("Storage").hash(/\.info/); + if (settings.hash!=hash) { + //apps changed, rescan and remove no longer existing apps + let apps = require("Storage").list(/\.info$/).map(app=>{var a=require("Storage").readJSON(app,1);return a&&{src:a.src};}); - //activate on clock faces - var sui = Bangle.setUI; - Bangle.setUI = function(mode, cb) { - sui(mode,cb); - if(!mode) return; - if ("object"==typeof mode) mode = mode.mode; - if (!mode.startsWith("clock")) return; - - function tap() { - //tap, check if source exists, launch - if ((settings.tapapp.src) && apps.some(e => e.src === settings.tapapp.src)) load (settings.tapapp.src); - } - - let drag; - let e; - - Bangle.on("touch",tap); - Bangle.on("drag", e => { - if (!drag) { // start dragging - drag = {x: e.x, y: e.y}; - } else if (!e.b) { // released - const dx = e.x-drag.x, dy = e.y-drag.y; - drag = null; - //horizontal swipes, check if source exists, launch - if (Math.abs(dx)>Math.abs(dy)+10) { - if ((settings.leftapp.src) && apps.some(e => e.src === settings.leftapp.src) && dx<0) load(settings.leftapp.src); - if ((settings.rightapp.src) && apps.some(e => e.src === settings.rightapp.src) && dx>0) load(settings.rightapp.src); - } - //vertical swipes, check if source exists, launch - else if (Math.abs(dy)>Math.abs(dx)+10) { - if ((settings.upapp.src) && apps.some(e => e.src === settings.upapp.src) && dy<0) load(settings.upapp.src); - if ((settings.downapp.src) && apps.some(e => e.src === settings.downapp.src) && dy>0) load(settings.downapp.src); - } + for (let c of ["leftapp","rightapp","upapp","downapp","tapapp"]){ + if (!settings[c]) settings[c] = {"name":"(none)"}; + if (!require("Storage").read(settings[c].src)) settings[c] = {"name":"(none)"}; } - }); + require("Storage").write("quicklaunch.json",settings); + settings.hash = hash; + } - }; -})(); + Bangle.on("touch", () => { + if (!Bangle.CLOCK) return; + if (settings.tapapp.src) load(settings.tapapp.src); + }); + Bangle.on("swipe", (lr,ud) => { + if (!Bangle.CLOCK) return; + + if (lr == -1 && settings.leftapp.src) load(settings.leftapp.src); + if (lr == 1 && settings.rightapp.src) load(settings.rightapp.src); + if (ud == 1 && settings.upapp.src) load(settings.upapp.src); + if (ud == -1 && settings.downapp.src) load(settings.downapp.src); + }); +} diff --git a/apps/quicklaunch/settings.js b/apps/quicklaunch/settings.js index ac4cc5805..7aac60a94 100644 --- a/apps/quicklaunch/settings.js +++ b/apps/quicklaunch/settings.js @@ -1,6 +1,10 @@ (function(back) { var settings = Object.assign(require("Storage").readJSON("quicklaunch.json", true) || {}); +for (let c of ["leftapp","rightapp","upapp","downapp","tapapp"]){ + if (!settings[c]) settings[c] = {"name":"(none)"}; +} + var apps = require("Storage").list(/\.info$/).map(app=>{var a=require("Storage").readJSON(app,1);return a&&{name:a.name,type:a.type,sortorder:a.sortorder,src:a.src};}).filter(app=>app && (app.type=="app" || app.type=="launch" || app.type=="clock" || !app.type)); apps.sort((a,b)=>{ @@ -29,11 +33,11 @@ function showMainMenu() { mainmenu["Up: "+settings.upapp.name] = function() { E.showMenu(upmenu); }; mainmenu["Down: "+settings.downapp.name] = function() { E.showMenu(downmenu); }; mainmenu["Tap: "+settings.tapapp.name] = function() { E.showMenu(tapmenu); }; - + return E.showMenu(mainmenu); } - -//Left swipe menu + +//Left swipe menu var leftmenu = { "" : { "title" : "Left Swipe" }, "< Back" : showMainMenu @@ -119,4 +123,4 @@ apps.forEach((a)=>{ }); showMainMenu(); -}); \ No newline at end of file +}) From 4e187004a820d81a0829a50c8a8d1c174af49cff Mon Sep 17 00:00:00 2001 From: Martin Boonk Date: Thu, 27 Oct 2022 18:10:00 +0200 Subject: [PATCH 2/5] quicklaunch - Bump version --- apps/quicklaunch/ChangeLog | 1 + apps/quicklaunch/metadata.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/quicklaunch/ChangeLog b/apps/quicklaunch/ChangeLog index ae1d4a848..80334b57d 100644 --- a/apps/quicklaunch/ChangeLog +++ b/apps/quicklaunch/ChangeLog @@ -1,2 +1,3 @@ 0.01: Initial version 0.02: Moved settings from launcher to settings->apps menu +0.03: Better performance by not scanning on every boot diff --git a/apps/quicklaunch/metadata.json b/apps/quicklaunch/metadata.json index 49eafdd35..dd0362324 100644 --- a/apps/quicklaunch/metadata.json +++ b/apps/quicklaunch/metadata.json @@ -2,7 +2,7 @@ "id": "quicklaunch", "name": "Quick Launch", "icon": "app.png", - "version":"0.02", + "version":"0.03", "description": "Tap or swipe left/right/up/down on your clock face to launch up to five apps of your choice. Configurations can be accessed through Settings->Apps.", "type": "bootloader", "tags": "tools, system", From 6f8bff566945f32b15c5dedb6a79a7e2c8aa2e17 Mon Sep 17 00:00:00 2001 From: Martin Boonk Date: Fri, 28 Oct 2022 08:16:42 +0200 Subject: [PATCH 3/5] quicklaunch - Actually store the hash in settings file --- apps/quicklaunch/boot.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/quicklaunch/boot.js b/apps/quicklaunch/boot.js index 54f261fdf..bc2408e78 100644 --- a/apps/quicklaunch/boot.js +++ b/apps/quicklaunch/boot.js @@ -10,8 +10,8 @@ if (!settings[c]) settings[c] = {"name":"(none)"}; if (!require("Storage").read(settings[c].src)) settings[c] = {"name":"(none)"}; } - require("Storage").write("quicklaunch.json",settings); settings.hash = hash; + require("Storage").write("quicklaunch.json",settings); } Bangle.on("touch", () => { From ac6f7b1521c0d806f48351abb5256a656b44d85f Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Fri, 28 Oct 2022 12:21:27 +0100 Subject: [PATCH 4/5] widclk/close/etc - allow turning on/off when quick-switching apps https://github.com/espruino/BangleApps/commit/f6b38b34437572498b9ab8403dc333164b0b193a#r88164680 --- apps/widclk/ChangeLog | 1 + apps/widclk/metadata.json | 2 +- apps/widclk/widget.js | 11 +++++--- apps/widclkbttm/ChangeLog | 2 +- apps/widclkbttm/metadata.json | 4 +-- apps/widclkbttm/widclkbttm.wid.js | 45 +++++++++++-------------------- apps/widclose/ChangeLog | 3 ++- apps/widclose/metadata.json | 2 +- apps/widclose/widget.js | 21 ++++++++------- apps/widcloselaunch/ChangeLog | 3 ++- apps/widcloselaunch/metadata.json | 2 +- apps/widcloselaunch/widget.js | 15 ++++++----- 12 files changed, 54 insertions(+), 57 deletions(-) diff --git a/apps/widclk/ChangeLog b/apps/widclk/ChangeLog index c74857ab4..1a89e2780 100644 --- a/apps/widclk/ChangeLog +++ b/apps/widclk/ChangeLog @@ -3,3 +3,4 @@ 0.04: Fix regression stopping correct widget updates 0.05: Don't show clock widget if already showing clock app 0.06: Use 7 segment font, update *on* the minute, use less memory +0.07: allow turning on/off when quick-switching apps diff --git a/apps/widclk/metadata.json b/apps/widclk/metadata.json index 6996f4080..b7bc74e11 100644 --- a/apps/widclk/metadata.json +++ b/apps/widclk/metadata.json @@ -1,7 +1,7 @@ { "id": "widclk", "name": "Digital clock widget", - "version": "0.06", + "version": "0.07", "description": "A simple digital clock widget", "icon": "widget.png", "type": "widget", diff --git a/apps/widclk/widget.js b/apps/widclk/widget.js index 9e035ca9a..7c281f761 100644 --- a/apps/widclk/widget.js +++ b/apps/widclk/widget.js @@ -1,10 +1,13 @@ /* Simple clock that appears in the widget bar if no other clock is running. We update once per minute, but don't bother stopping if the */ - -// don't show widget if we know we have a clock app running -if (!Bangle.CLOCK) WIDGETS["wdclk"]={area:"tl",width:52/* g.stringWidth("00:00") */,draw:function() { - g.reset().setFontCustom(atob("AAAAAAAAAAIAAAQCAQAAAd0BgMBdwAAAAAAAdwAB0RiMRcAAAERiMRdwAcAQCAQdwAcERiMRBwAd0RiMRBwAAEAgEAdwAd0RiMRdwAcERiMRdwAFAAd0QiEQdwAdwRCIRBwAd0BgMBAAABwRCIRdwAd0RiMRAAAd0QiEQAAAAAAAAAA="), 32, atob("BgAAAAAAAAAAAAAAAAYCAAYGBgYGBgYGBgYCAAAAAAAABgYGBgYG"), 512+9); +WIDGETS["wdclk"]={area:"tl",width:Bangle.CLOCK?0:52/* g.stringWidth("00:00") */,draw:function() { + if (!Bangle.CLOCK == !this.width) { // if we're the wrong size for if we have a clock or not... + this.width = Bangle.CLOCK?0:52; + return setTimeout(Bangle.drawWidgets,1); // widget changed size - redraw + } + if (!this.width) return; // if size not right, return +g.reset().setFontCustom(atob("AAAAAAAAAAIAAAQCAQAAAd0BgMBdwAAAAAAAdwAB0RiMRcAAAERiMRdwAcAQCAQdwAcERiMRBwAd0RiMRBwAAEAgEAdwAd0RiMRdwAcERiMRdwAFAAd0QiEQdwAdwRCIRBwAd0BgMBAAABwRCIRdwAd0RiMRAAAd0QiEQAAAAAAAAAA="), 32, atob("BgAAAAAAAAAAAAAAAAYCAAYGBgYGBgYGBgYCAAAAAAAABgYGBgYG"), 512+9); var time = require("locale").time(new Date(),1); g.drawString(time, this.x, this.y+3, true); // 5 * 6*2 = 60 // queue draw in one minute diff --git a/apps/widclkbttm/ChangeLog b/apps/widclkbttm/ChangeLog index 326169af5..9dc8f8d2c 100644 --- a/apps/widclkbttm/ChangeLog +++ b/apps/widclkbttm/ChangeLog @@ -1,4 +1,4 @@ 0.01: Fork of widclk v0.04 github.com/espruino/BangleApps/tree/master/apps/widclk 0.02: Modification for bottom widget area and text color 0.03: based in widclk v0.05 compatible at same time, bottom area and color - +0.04: refactored to use less memory, and allow turning on/off when quick-switching apps diff --git a/apps/widclkbttm/metadata.json b/apps/widclkbttm/metadata.json index 9e92f7c46..7c5fe4b63 100644 --- a/apps/widclkbttm/metadata.json +++ b/apps/widclkbttm/metadata.json @@ -2,8 +2,8 @@ "id": "widclkbttm", "name": "Digital clock (Bottom) widget", "shortName": "Digital clock Bottom Widget", - "version": "0.03", - "description": "Displays time in the bottom area.", + "version": "0.04", + "description": "Displays time in the bottom of the screen (may not be compatible with some apps)", "icon": "widclkbttm.png", "type": "widget", "tags": "widget", diff --git a/apps/widclkbttm/widclkbttm.wid.js b/apps/widclkbttm/widclkbttm.wid.js index c27906786..c5e85318c 100644 --- a/apps/widclkbttm/widclkbttm.wid.js +++ b/apps/widclkbttm/widclkbttm.wid.js @@ -1,31 +1,16 @@ -(function() { - // don't show widget if we know we have a clock app running - if (Bangle.CLOCK) return; - - let intervalRef = null; - var width = 5 * 6*2; - var text_color=0x07FF;//cyan - - function draw() { - g.reset().setFont("6x8", 2).setFontAlign(-1, 0).setColor(text_color); - var time = require("locale").time(new Date(),1); - g.drawString(time, this.x, this.y+11, true); // 5 * 6*2 = 60 +WIDGETS["wdclkbttm"]={area:"br",width:Bangle.CLOCK?0:60,draw:function() { + if (!Bangle.CLOCK == !this.width) { // if we're the wrong size for if we have a clock or not... + this.width = Bangle.CLOCK?0:60; + return setTimeout(Bangle.drawWidgets,1); // widget changed size - redraw } - function clearTimers(){ - if(intervalRef) { - clearInterval(intervalRef); - intervalRef = null; - } - } - function startTimers(){ - intervalRef = setInterval(()=>WIDGETS["wdclkbttm"].draw(), 60*1000); - WIDGETS["wdclkbttm"].draw(); - } - Bangle.on('lcdPower', (on) => { - clearTimers(); - if (on) startTimers(); - }); - - WIDGETS["wdclkbttm"]={area:"br",width:width,draw:draw}; - if (Bangle.isLCDOn) intervalRef = setInterval(()=>WIDGETS["wdclkbttm"].draw(), 60*1000); -})() + if (!this.width) return; // if size not right, return + g.reset().setFont("6x8", 2).setFontAlign(-1, 0).setColor("#0ff"); // cyan + var time = require("locale").time(new Date(),1); + g.drawString(time, this.x, this.y+11, true); // 5 * 6*2 = 60 + // queue draw in one minute + if (this.drawTimeout) clearTimeout(this.drawTimeout); + this.drawTimeout = setTimeout(()=>{ + this.drawTimeout = undefined; + this.draw(); + }, 60000 - (Date.now() % 60000)); +}}; diff --git a/apps/widclose/ChangeLog b/apps/widclose/ChangeLog index 4be6afb16..1e0c86fc6 100644 --- a/apps/widclose/ChangeLog +++ b/apps/widclose/ChangeLog @@ -1 +1,2 @@ -0.01: New widget! \ No newline at end of file +0.01: New widget! +0.02: allow turning on/off when quick-switching apps diff --git a/apps/widclose/metadata.json b/apps/widclose/metadata.json index e044a2d39..19009fd82 100644 --- a/apps/widclose/metadata.json +++ b/apps/widclose/metadata.json @@ -1,7 +1,7 @@ { "id": "widclose", "name": "Close Button", - "version": "0.01", + "version": "0.02", "description": "A button to close the current app", "readme": "README.md", "icon": "icon.png", diff --git a/apps/widclose/widget.js b/apps/widclose/widget.js index 3a354018b..aeba1de00 100644 --- a/apps/widclose/widget.js +++ b/apps/widclose/widget.js @@ -1,14 +1,17 @@ -if (!Bangle.CLOCK) WIDGETS.close = { - area: "tr", width: 24, sortorder: 10, // we want the right-most spot please +WIDGETS.close = { + area: "tr", width: Bangle.CLOCK?0:24, sortorder: 10, // we want the right-most spot please draw: function() { - Bangle.removeListener("touch", this.touch); - Bangle.on("touch", this.touch); - g.reset().setColor("#f00").drawImage(atob( // hardcoded red to match setUI back button + if (!Bangle.CLOCK == !this.width) { // if we're the wrong size for if we have a clock or not... + this.width = Bangle.CLOCK?0:24; + return setTimeout(Bangle.drawWidgets,1); // widget changed size - redraw + } + if (this.width) g.reset().setColor("#f00").drawImage(atob( // red to match setUI back button // b/w version of preview.png, 24x24 "GBgBABgAAf+AB//gD//wH//4P//8P//8fn5+fjx+fxj+f4H+/8P//8P/f4H+fxj+fjx+fn5+P//8P//8H//4D//wB//gAf+AABgA" ), this.x, this.y); - }, touch: function(_, c) { - const w = WIDGETS.close; - if (w && c.x>=w.x && c.x<=w.x+24 && c.y>=w.y && c.y<=w.y+24) load(); + }, touch: function(_, c) { // if touched + const w = WIDGETS.close; // if in range, go back to the clock + if (w && c.x>=w.x && c.x=w.y && c.y<=w.y+24) load(); } -}; \ No newline at end of file +}; +Bangle.on("touch", WIDGETS.close.touch); diff --git a/apps/widcloselaunch/ChangeLog b/apps/widcloselaunch/ChangeLog index 4be6afb16..1e0c86fc6 100644 --- a/apps/widcloselaunch/ChangeLog +++ b/apps/widcloselaunch/ChangeLog @@ -1 +1,2 @@ -0.01: New widget! \ No newline at end of file +0.01: New widget! +0.02: allow turning on/off when quick-switching apps diff --git a/apps/widcloselaunch/metadata.json b/apps/widcloselaunch/metadata.json index 36d06bd91..b5c83e37e 100644 --- a/apps/widcloselaunch/metadata.json +++ b/apps/widcloselaunch/metadata.json @@ -1,7 +1,7 @@ { "id": "widcloselaunch", "name": "Close Button to launcher", - "version": "0.01", + "version": "0.02", "description": "A button to close the current app and go to launcher", "readme": "README.md", "icon": "icon.png", diff --git a/apps/widcloselaunch/widget.js b/apps/widcloselaunch/widget.js index ee5a9a7e3..2c9147d16 100644 --- a/apps/widcloselaunch/widget.js +++ b/apps/widcloselaunch/widget.js @@ -1,14 +1,17 @@ -if (!Bangle.CLOCK) WIDGETS.close = { - area: "tr", width: 24, sortorder: 10, // we want the right-most spot please +WIDGETS.close = { + area: "tr", width: Bangle.CLOCK?0:24, sortorder: 10, // we want the right-most spot please draw: function() { - Bangle.removeListener("touch", this.touch); - Bangle.on("touch", this.touch); - g.reset().setColor("#f00").drawImage(atob( // hardcoded red to match setUI back button + if (!Bangle.CLOCK == !this.width) { // if we're the wrong size for if we have a clock or not... + this.width = Bangle.CLOCK?0:24; + return setTimeout(Bangle.drawWidgets,1); // widget changed size - redraw + } + if (this.width) g.reset().setColor("#f00").drawImage(atob( // red to match setUI back button // b/w version of preview.png, 24x24 "GBgBABgAAf+AB//gD//wH//4P//8P//8fn5+fjx+fxj+f4H+/8P//8P/f4H+fxj+fjx+fn5+P//8P//8H//4D//wB//gAf+AABgA" ), this.x, this.y); }, touch: function(_, c) { const w = WIDGETS.close; - if (w && c.x>=w.x && c.x<=w.x+24 && c.y>=w.y && c.y<=w.y+24) Bangle.showLauncher(); + if (w && c.x>=w.x && c.x=w.y && c.y<=w.y+24) Bangle.showLauncher(); } }; +Bangle.on("touch", WIDGETS.close.touch); From ad3c9f8f0c0e0d1e99badbf924ab1ca6fdfeef57 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Fri, 28 Oct 2022 14:48:39 +0100 Subject: [PATCH 5/5] Move the updated Anton Clock to 'Anton Clock Plus' and revert to the default Anton Clock being super minimal. This provides an easy starting point for new users but is also almost 2x faster, making the watch feel far faster for new users and making the battery last longer --- apps/antonclk/ChangeLog | 2 + apps/antonclk/app.js | 230 ++----------------- apps/antonclk/app.png | Bin 1989 -> 13817 bytes apps/antonclk/metadata.json | 9 +- apps/antonclk/screenshot.png | Bin 1617 -> 2906 bytes apps/antonclkplus/ChangeLog | 15 ++ apps/{antonclk => antonclkplus}/README.md | 14 +- apps/antonclkplus/app-icon.js | 1 + apps/antonclkplus/app.js | 238 ++++++++++++++++++++ apps/antonclkplus/app.png | Bin 0 -> 1989 bytes apps/antonclkplus/metadata.json | 20 ++ apps/antonclkplus/screenshot.png | Bin 0 -> 1617 bytes apps/{antonclk => antonclkplus}/settings.js | 0 13 files changed, 305 insertions(+), 224 deletions(-) create mode 100644 apps/antonclkplus/ChangeLog rename apps/{antonclk => antonclkplus}/README.md (87%) create mode 100644 apps/antonclkplus/app-icon.js create mode 100644 apps/antonclkplus/app.js create mode 100644 apps/antonclkplus/app.png create mode 100644 apps/antonclkplus/metadata.json create mode 100644 apps/antonclkplus/screenshot.png rename apps/{antonclk => antonclkplus}/settings.js (100%) diff --git a/apps/antonclk/ChangeLog b/apps/antonclk/ChangeLog index 9e75d889a..4ef0cee75 100644 --- a/apps/antonclk/ChangeLog +++ b/apps/antonclk/ChangeLog @@ -12,3 +12,5 @@ 0.08: fixed calendar weeknumber not shortened to two digits 0.09: Use default Bangle formatter for booleans 0.10: Use Bangle.setUI({remove:...}) to allow loading the launcher without a full reset on 2v16 +0.11: Moved enhanced Anton clock to 'Anton Clock Plus' and stripped this clock back down to make it faster for new users (270ms -> 170ms) + Modified to avoid leaving functions defined when using setUI({remove:...}) diff --git a/apps/antonclk/app.js b/apps/antonclk/app.js index 07f67f696..528866588 100644 --- a/apps/antonclk/app.js +++ b/apps/antonclk/app.js @@ -4,234 +4,42 @@ Graphics.prototype.setFontAnton = function(scale) { g.setFontCustom(atob("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAAAAAAAAAA/gAAAAAAAAAAP/gAAAAAAAAAH//gAAAAAAAAB///gAAAAAAAAf///gAAAAAAAP////gAAAAAAD/////gAAAAAA//////gAAAAAP//////gAAAAH///////gAAAB////////gAAAf////////gAAP/////////gAD//////////AA//////////gAA/////////4AAA////////+AAAA////////gAAAA///////wAAAAA//////8AAAAAA//////AAAAAAA/////gAAAAAAA////4AAAAAAAA///+AAAAAAAAA///gAAAAAAAAA//wAAAAAAAAAA/8AAAAAAAAAAA/AAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//////AAAAAB///////8AAAAH////////AAAAf////////wAAA/////////4AAB/////////8AAD/////////+AAH//////////AAP//////////gAP//////////gAP//////////gAf//////////wAf//////////wAf//////////wAf//////////wA//8AAAAAB//4A//wAAAAAAf/4A//gAAAAAAP/4A//gAAAAAAP/4A//gAAAAAAP/4A//wAAAAAAf/4A///////////4Af//////////wAf//////////wAf//////////wAf//////////wAP//////////gAP//////////gAH//////////AAH//////////AAD/////////+AAB/////////8AAA/////////4AAAP////////gAAAD///////+AAAAAf//////4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/gAAAAAAAAAAP/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/AAAAAAAAAAA//AAAAAAAAAAA/+AAAAAAAAAAB/8AAAAAAAAAAD//////////gAH//////////gAP//////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH/4AAAAB/gAAD//4AAAAf/gAAP//4AAAB//gAA///4AAAH//gAB///4AAAf//gAD///4AAA///gAH///4AAD///gAP///4AAH///gAP///4AAP///gAf///4AAf///gAf///4AB////gAf///4AD////gA////4AH////gA////4Af////gA////4A/////gA//wAAB/////gA//gAAH/////gA//gAAP/////gA//gAA///8//gA//gAD///w//gA//wA////g//gA////////A//gA///////8A//gA///////4A//gAf//////wA//gAf//////gA//gAf/////+AA//gAP/////8AA//gAP/////4AA//gAH/////gAA//gAD/////AAA//gAB////8AAA//gAA////wAAA//gAAP///AAAA//gAAD//8AAAA//gAAAP+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB/+AAAAAD/wAAB//8AAAAP/wAAB///AAAA//wAAB///wAAB//wAAB///4AAD//wAAB///8AAH//wAAB///+AAP//wAAB///+AAP//wAAB////AAf//wAAB////AAf//wAAB////gAf//wAAB////gA///wAAB////gA///wAAB////gA///w//AAf//wA//4A//AAA//wA//gA//AAAf/wA//gB//gAAf/wA//gB//gAAf/wA//gD//wAA//wA//wH//8AB//wA///////////gA///////////gA///////////gA///////////gAf//////////AAf//////////AAP//////////AAP/////////+AAH/////////8AAH///+/////4AAD///+f////wAAA///8P////gAAAf//4H///+AAAAH//gB///wAAAAAP4AAH/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/wAAAAAAAAAA//wAAAAAAAAAP//wAAAAAAAAB///wAAAAAAAAf///wAAAAAAAH////wAAAAAAA/////wAAAAAAP/////wAAAAAB//////wAAAAAf//////wAAAAH///////wAAAA////////wAAAP////////wAAA///////H/wAAA//////wH/wAAA/////8AH/wAAA/////AAH/wAAA////gAAH/wAAA///4AAAH/wAAA//+AAAAH/wAAA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gAAAAAAAAH/4AAAAAAAAAAH/wAAAAAAAAAAH/wAAAAAAAAAAH/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB//8AAA/////+B///AAA/////+B///wAA/////+B///4AA/////+B///8AA/////+B///8AA/////+B///+AA/////+B////AA/////+B////AA/////+B////AA/////+B////gA/////+B////gA/////+B////gA/////+A////gA//gP/gAAB//wA//gf/AAAA//wA//gf/AAAAf/wA//g//AAAAf/wA//g//AAAA//wA//g//gAAA//wA//g//+AAP//wA//g////////gA//g////////gA//g////////gA//g////////gA//g////////AA//gf///////AA//gf//////+AA//gP//////+AA//gH//////8AA//gD//////4AA//gB//////wAA//gA//////AAAAAAAH////8AAAAAAAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//////gAAAAB///////+AAAAH////////gAAAf////////4AAB/////////8AAD/////////+AAH//////////AAH//////////gAP//////////gAP//////////gAf//////////wAf//////////wAf//////////wAf//////////wAf//////////4A//wAD/4AAf/4A//gAH/wAAP/4A//gAH/wAAP/4A//gAP/wAAP/4A//gAP/4AAf/4A//wAP/+AD//4A///wP//////4Af//4P//////wAf//4P//////wAf//4P//////wAf//4P//////wAP//4P//////gAP//4H//////gAH//4H//////AAH//4D/////+AAD//4D/////8AAB//4B/////4AAA//4A/////wAAAP/4AP////AAAAB/4AD///4AAAAAAAAAH/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//AAAAAAAAAAA//gAAAAAAAAAA//gAAAAAAAAAA//gAAAAAAADgA//gAAAAAAP/gA//gAAAAAH//gA//gAAAAB///gA//gAAAAP///gA//gAAAD////gA//gAAAf////gA//gAAB/////gA//gAAP/////gA//gAB//////gA//gAH//////gA//gA///////gA//gD///////gA//gf///////gA//h////////gA//n////////gA//////////gAA/////////AAAA////////wAAAA///////4AAAAA///////AAAAAA//////4AAAAAA//////AAAAAAA/////4AAAAAAA/////AAAAAAAA////8AAAAAAAA////gAAAAAAAA///+AAAAAAAAA///4AAAAAAAAA///AAAAAAAAAA//4AAAAAAAAAA/+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//gB///wAAAAP//4H///+AAAA///8P////gAAB///+f////4AAD///+/////8AAH/////////+AAH//////////AAP//////////gAP//////////gAf//////////gAf//////////wAf//////////wAf//////////wA///////////wA//4D//wAB//4A//wB//gAA//4A//gA//gAAf/4A//gA//AAAf/4A//gA//gAAf/4A//wB//gAA//4A///P//8AH//4Af//////////wAf//////////wAf//////////wAf//////////wAf//////////gAP//////////gAP//////////AAH//////////AAD/////////+AAD///+/////8AAB///8f////wAAAf//4P////AAAAH//wD///8AAAAA/+AAf//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH//gAAAAAAAAB///+AA/+AAAAP////gA//wAAAf////wA//4AAB/////4A//8AAD/////8A//+AAD/////+A///AAH/////+A///AAP//////A///gAP//////A///gAf//////A///wAf//////A///wAf//////A///wAf//////A///wA///////AB//4A//4AD//AAP/4A//gAB//AAP/4A//gAA//AAP/4A//gAA/+AAP/4A//gAB/8AAP/4A//wAB/8AAf/4Af//////////wAf//////////wAf//////////wAf//////////wAf//////////wAP//////////gAP//////////gAH//////////AAH/////////+AAD/////////8AAB/////////4AAAf////////wAAAP////////AAAAB///////4AAAAAD/////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf/AAB/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="), 46, atob("EiAnGicnJycnJycnEw=="), 78 + (scale << 8) + (1 << 16)); }; -Graphics.prototype.setFontAntonSmall = function(scale) { - // Actual height 53 (52 - 0) - g.setFontCustom(atob("AAAAAAAAAAAAAAAAAAAAAAAAAAf8AAAAAAAAf8AAAAAAAAf8AAAAAAAAf8AAAAAAAAf8AAAAAAAAf8AAAAAAAAf8AAAAAAAAf8AAAAAAAAf8AAAAAAAAf8AAAAAAAAf8AAAAAAAAAAAAAAAAAAAAMAAAAAAAAD8AAAAAAAA/8AAAAAAAf/8AAAAAAH//8AAAAAB///8AAAAA////8AAAAP////8AAAD/////8AAB//////8AAf//////8AH///////4A///////+AA///////AAA//////wAAA/////8AAAA////+AAAAA////gAAAAA///4AAAAAA//8AAAAAAA//AAAAAAAA/wAAAAAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH/////wAAA//////8AAB//////+AAH///////gAH///////gAP///////wAf///////4Af///////4A////////8A////////8A////////8A//AAAAD/8A/8AAAAA/8A/8AAAAA/8A/8AAAAA/8A/+AAAAB/8A////////8A////////8A////////8Af///////4Af///////4AP///////wAP///////wAH///////gAD///////AAA//////8AAAP/////wAAAAAAAAAAAAAAAAAAAAAAAfwAAAAAAAA/4AAAAAAAA/4AAAAAAAB/wAAAAAAAB/wAAAAAAAD/wAAAAAAAD/gAAAAAAAH///////8AP///////8A////////8A////////8A////////8A////////8A////////8A////////8A////////8A////////8A////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH/4AAAP8AA//4AAA/8AB//4AAH/8AH//4AAP/8AP//4AA//8AP//4AB//8Af//4AD//8Af//4AP//8A///4Af//8A///4A///8A///4D///8A//AAH///8A/8AAP///8A/8AA//+/8A/8AD//8/8A/+Af//w/8A//////g/8A/////+A/8A/////8A/8Af////4A/8Af////wA/8AP////AA/8AP///+AA/8AH///8AA/8AD///wAA/8AA///AAA/8AAP/4AAA/8AAAAAAAAAAAAAAAAAAAAAAH4AAf/gAAA/4AAf/8AAD/4AAf//AAH/4AAf//gAP/4AAf//wAP/4AAf//wAf/4AAf//4Af/4AAf//4A//4AAf//8A//4AAf//8A//4AAP//8A//A/8AB/8A/8A/8AA/8A/8B/8AA/8A/8B/8AA/8A/+D//AB/8A////////8A////////8A////////8Af///////4Af///////4Af///////wAP///////gAH//9////gAD//4///+AAB//wf//4AAAP/AH//gAAAAAAAAAAAAAAAAAAAAAAAAAAAH/wAAAAAAB//wAAAAAAP//wAAAAAD///wAAAAA////wAAAAH////wAAAB/////wAAAf/////wAAD//////wAA///////wAA/////h/wAA////wB/wAA///8AB/wAA///AAB/wAA//gAAB/wAA////////8A////////8A////////8A////////8A////////8A////////8A////////8A////////8A////////8A////////8A////////8AAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAAAAAAAAAAAAAAAAAAAAAP/4AA////4P/+AA////4P//AA////4P//gA////4P//wA////4P//wA////4P//4A////4P//4A////4P//8A////4P//8A////4P//8A/8H/AAB/8A/8H+AAA/8A/8P+AAA/8A/8P+AAA/8A/8P/gAD/8A/8P/////8A/8P/////8A/8P/////8A/8P/////4A/8H/////4A/8H/////wA/8D/////wA/8B/////gA/8A////+AA/8AP///4AAAAAB///AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////wAAAf/////8AAB///////AAH///////gAP///////wAP///////wAf///////4Af///////4A////////8A////////8A////////8A/+AH/AB/8A/8AP+AA/8A/4Af+AA/8A/8Af+AA/8A/8Af/gH/8A//4f////8A//4f////8A//4f////8Af/4f////4Af/4f////4AP/4P////wAP/4P////gAH/4H////AAD/4D///+AAB/4B///4AAAP4AP//gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/8AAAAAAAA/8AAAAAAAA/8AAAAAB8A/8AAAAB/8A/8AAAAf/8A/8AAAH//8A/8AAA///8A/8AAH///8A/8AA////8A/8AD////8A/8Af////8A/8B/////8A/8P/////8A/8//////8A////////AA///////AAA//////gAAA/////4AAAA/////AAAAA////4AAAAA////AAAAAA///8AAAAAA///gAAAAAA//+AAAAAAA//wAAAAAAA/+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH/gD//gAAA//4P//8AAD//8f///AAH//+////gAH///////wAP///////4AP///////8Af///////8Af///////+Af///////+A////////+A//B//AB/+A/+A/+AA/+A/8Af+AA/+A/+Af+AA/+A//A//AB/+A////////+Af///////+Af///////+Af///////8Af///////8AP///////4AH///////4AH//+////wAD//+////AAA//4P//+AAAP/gH//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH//gAfgAAA///8A/8AAB///+A//AAH////A//gAH////g//wAP////g//wAf////w//4Af////w//4A/////w//8A/////w//8A/////w//8A//gP/wA/8A/8AD/wA/8A/8AD/wAf8A/8AD/gA/8A/+AH/AB/8A////////8A////////8A////////8Af///////4Af///////4Af///////wAP///////wAH///////gAD//////+AAA//////4AAAP/////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+AA/4AAAAP+AA/4AAAAP+AA/4AAAAP+AA/4AAAAP+AA/4AAAAP+AA/4AAAAP+AA/4AAAAP+AA/4AAAAP+AA/4AAAAP+AA/4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="), 46, atob("DhgeFB4eHh4eHh4eDw=="), 60 + (scale << 8) + (1 << 16)); -}; - { // must be inside our own scope here so that when we are unloaded everything disappears - -const SETTINGSFILE = "antonclk.json"; -const isBangle1 = (process.env.HWVERSION == 1); - -// variables defined from settings -let secondsMode; -let secondsColoured; -let secondsWithColon; -let dateOnMain; -let dateOnSecs; -let weekDay; -let calWeek; -let upperCase; -let vectorFont; - -// dynamic variables + // we also define functions using 'let fn = function() {..}' for the same reason. function decls are global let drawTimeout; -let queueMillis = 1000; -let secondsScreen = true; +// 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("Anton").drawString(timeStr, x, y); + // Show date and day of week + var dateStr = require("locale").date(date, 0).toUpperCase()+"\n"+ + require("locale").dow(date, 0).toUpperCase(); + g.setFontAlign(0, 0).setFont("6x8", 2).drawString(dateStr, x, y+48); - -//For development purposes -/* -require('Storage').writeJSON(SETTINGSFILE, { - secondsMode: "Unlocked", // "Never", "Unlocked", "Always" - secondsColoured: true, - secondsWithColon: true, - dateOnMain: "Long", // "Short", "Long", "ISO8601" - dateOnSecs: "Year", // "No", "Year", "Weekday", LEGACY: true/false - weekDay: true, - calWeek: true, - upperCase: true, - vectorFont: true, -}); -*/ - -// OR (also for development purposes) -/* -require('Storage').erase(SETTINGSFILE); -*/ - -// Load settings -function loadSettings() { - // Helper function default setting - function def (value, def) {return value !== undefined ? value : def;} - - var settings = require('Storage').readJSON(SETTINGSFILE, true) || {}; - secondsMode = def(settings.secondsMode, "Never"); - secondsColoured = def(settings.secondsColoured, true); - secondsWithColon = def(settings.secondsWithColon, true); - dateOnMain = def(settings.dateOnMain, "Long"); - dateOnSecs = def(settings.dateOnSecs, "Year"); - weekDay = def(settings.weekDay, true); - calWeek = def(settings.calWeek, false); - upperCase = def(settings.upperCase, true); - vectorFont = def(settings.vectorFont, false); - - // Legacy - if (dateOnSecs === true) - dateOnSecs = "Year"; - if (dateOnSecs === false) - dateOnSecs = "No"; -} - -// schedule a draw for the next second or minute -function queueDraw() { + // queue next draw if (drawTimeout) clearTimeout(drawTimeout); drawTimeout = setTimeout(function() { drawTimeout = undefined; draw(); - }, queueMillis - (Date.now() % queueMillis)); -} + }, 60000 - (Date.now() % 60000)); +}; -function updateState() { - if (Bangle.isLCDOn()) { - if ((secondsMode === "Unlocked" && !Bangle.isLocked()) || secondsMode === "Always") { - secondsScreen = true; - queueMillis = 1000; - } else { - secondsScreen = false; - queueMillis = 60000; - } - draw(); // draw immediately, queue redraw - } else { // stop draw timer - if (drawTimeout) clearTimeout(drawTimeout); - drawTimeout = undefined; - } -} - -function isoStr(date) { - return date.getFullYear() + "-" + ("0" + (date.getMonth() + 1)).slice(-2) + "-" + ("0" + date.getDate()).slice(-2); -} - -let calWeekBuffer = [false,false,false]; //buffer tz, date, week no (once calculated until other tz or date is requested) -function ISO8601calWeek(date) { //copied from: https://gist.github.com/IamSilviu/5899269#gistcomment-3035480 - dateNoTime = date; dateNoTime.setHours(0,0,0,0); - if (calWeekBuffer[0] === date.getTimezoneOffset() && calWeekBuffer[1] === dateNoTime) return calWeekBuffer[2]; - calWeekBuffer[0] = date.getTimezoneOffset(); - calWeekBuffer[1] = dateNoTime; - var tdt = new Date(date.valueOf()); - var dayn = (date.getDay() + 6) % 7; - tdt.setDate(tdt.getDate() - dayn + 3); - var firstThursday = tdt.valueOf(); - tdt.setMonth(0, 1); - if (tdt.getDay() !== 4) { - tdt.setMonth(0, 1 + ((4 - tdt.getDay()) + 7) % 7); - } - calWeekBuffer[2] = 1 + Math.ceil((firstThursday - tdt) / 604800000); - return calWeekBuffer[2]; -} - -function doColor() { - return !isBangle1 && !Bangle.isLocked() && secondsColoured; -} - -// Actually draw the watch face -function draw() { - var x = g.getWidth() / 2; - var y = g.getHeight() / 2 - (secondsMode !== "Never" ? 24 : (vectorFont ? 12 : 0)); - g.reset(); - /* This is to mark the widget areas during development. - g.setColor("#888") - .fillRect(0, 0, g.getWidth(), 23) - .fillRect(0, g.getHeight() - 23, g.getWidth(), g.getHeight()).reset(); - /* */ - g.clearRect(0, 24, g.getWidth(), g.getHeight() - 24); // clear whole background (w/o widgets) - var date = new Date(); // Actually the current date, this one is shown - var timeStr = require("locale").time(date, 1); // Hour and minute - g.setFontAlign(0, 0).setFont("Anton").drawString(timeStr, x, y); // draw time - if (secondsScreen) { - y += 65; - var secStr = (secondsWithColon ? ":" : "") + ("0" + date.getSeconds()).slice(-2); - if (doColor()) - g.setColor(0, 0, 1); - g.setFont("AntonSmall"); - if (dateOnSecs !== "No") { // A bit of a complex drawing with seconds on the right and date on the left - g.setFontAlign(1, 0).drawString(secStr, g.getWidth() - (isBangle1 ? 32 : 2), y); // seconds - y -= (vectorFont ? 15 : 13); - x = g.getWidth() / 4 + (isBangle1 ? 12 : 4) + (secondsWithColon ? 0 : g.stringWidth(":") / 2); - var dateStr2 = (dateOnMain === "ISO8601" ? isoStr(date) : require("locale").date(date, 1)); - var year; - var md; - var yearfirst; - if (dateStr2.match(/\d\d\d\d$/)) { // formatted date ends with year - year = (dateOnSecs === "Year" ? dateStr2.slice(-4) : require("locale").dow(date, 1)); - md = dateStr2.slice(0, -4); - if (!md.endsWith(".")) // keep separator before the year only if it is a dot (31.12. but 31/12) - md = md.slice(0, -1); - yearfirst = false; - } else { // formatted date begins with year - if (!dateStr2.match(/^\d\d\d\d/)) // if year position cannot be detected... - dateStr2 = isoStr(date); // ...use ISO date format instead - year = (dateOnSecs === "Year" ? dateStr2.slice(0, 4) : require("locale").dow(date, 1)); - md = dateStr2.slice(5); // never keep separator directly after year - yearfirst = true; - } - if (dateOnSecs === "Weekday" && upperCase) - year = year.toUpperCase(); - g.setFontAlign(0, 0); - if (vectorFont) - g.setFont("Vector", 24); - else - g.setFont("6x8", 2); - if (doColor()) - g.setColor(1, 0, 0); - g.drawString(md, x, (yearfirst ? y + (vectorFont ? 26 : 16) : y)); - g.drawString(year, x, (yearfirst ? y : y + (vectorFont ? 26 : 16))); - } else { - g.setFontAlign(0, 0).drawString(secStr, x, y); // Just the seconds centered - } - } else { // No seconds screen: Show date and optionally day of week - y += (vectorFont ? 50 : (secondsMode !== "Never") ? 52 : 40); - var dateStr = (dateOnMain === "ISO8601" ? isoStr(date) : require("locale").date(date, (dateOnMain === "Long" ? 0 : 1))); - if (upperCase) - dateStr = dateStr.toUpperCase(); - g.setFontAlign(0, 0); - if (vectorFont) - g.setFont("Vector", 24); - else - g.setFont("6x8", 2); - g.drawString(dateStr, x, y); - if (calWeek || weekDay) { - var dowcwStr = ""; - if (calWeek) - dowcwStr = " #" + ("0" + ISO8601calWeek(date)).slice(-2); - if (weekDay) - dowcwStr = require("locale").dow(date, calWeek ? 1 : 0) + dowcwStr; //weekDay e.g. Monday or weekDayShort # e.g. Mon #01 - else //week #01 - dowcwStr = /*LANG*/"week" + dowcwStr; - if (upperCase) - dowcwStr = dowcwStr.toUpperCase(); - g.drawString(dowcwStr, x, y + (vectorFont ? 26 : 16)); - } - } - - // queue next draw - queueDraw(); -} - -// Init the settings of the app -loadSettings(); -// Clear the screen once, at startup -g.clear(); -// Set dynamic state and perform initial drawing -updateState(); -// Register hooks for LCD on/off event and screen lock on/off event -Bangle.on('lcdPower', updateState); -Bangle.on('lock', updateState); // Show launcher when middle button pressed -Bangle.setUI({ +Bangle.setUI({ mode : "clock", remove : function() { // Called to unload all of the clock app - Bangle.removeListener('lcdPower', updateState); - Bangle.removeListener('lock', updateState); if (drawTimeout) clearTimeout(drawTimeout); drawTimeout = undefined; delete Graphics.prototype.setFontAnton; - delete Graphics.prototype.setFontAntonSmall; }}); // Load widgets Bangle.loadWidgets(); -Bangle.drawWidgets(); +draw(); +setTimeout(Bangle.drawWidgets,0); } diff --git a/apps/antonclk/app.png b/apps/antonclk/app.png index a38093c5f3b6f88dbc9b75017422dbe237d4407f..bb764d2a1b7d4c7e219b9001f8e3f2e2869e1d82 100644 GIT binary patch literal 13817 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 E2b;2#%>V!Z delta 1986 zcmV;z2R-=tYsC+c8Gix*007uvZqNV#2aHKXK~z}7?O0t*Q&$}S(aJ|1h>ls;g4h+@ zB+AGl)8UNHxGbA|xTyGG;sOsoEFnM;B+-{a7Q@E_V_6nMW&&<;@}SXB3>rlzVu;X< zRWXwk`@zScE!aY#?d`|e!>RXPZf_BAEI#a?lbioJ=XcKe-G6(||Kr>ULI_?bk>E9x z{|Wt1=v8G^xDKDsH!(3`G#X=LV-*U8TrOXDqLGmilgUK&#Kc6EN+kdc4-cEoX0}QQ z*}i?dOePafM8w2kFdRO7m=7x{DH$0V5e0j_-m_=V3Z|{9s&YD=eAwyJrv(^`#S%K3 z2qBxzmYSLx`hN`y3JT`t=0fr3&YhD;M7F-UxtYZ<46||L#$^(^di83!ed+D(C4@{& zOjs-yi^VcGH|KCTl9H16n23l7R(HGIbWWX4$8TSNkjR^LcXzY8Ua#-%?PaT@qoV@@ z0~H&dOV(ykrCQkT3X65OnG@Zi=UX7pnuAvM~@a65=02q*VnUpQc}{o zb?ew_S63H*UcpOeWMo7}M)E(H!{MOHjT<+pQd3j2Oe+(oFOl#G1p(}#J#>U2O z-@eU%9{^UX^}>Y<0168WUuvx{Ar!jtTeog?yWPRTtL6=FZEYMVBWjNgS_V&)sPS%G}B_$%Z5oY6qtTenW{1Nu^g`m} z<4>G8QB+jKf{jMwlP6E8URztc{8*NimDSVJLv{8QshCWryu3WB-@kuHJ4%z_z)>FVmDx>~KaTCMyOIXO8QA0HnT74;HACXwg7ckH-_vDjOOaLMP{&$oTm9qN2UoY*s3j zp$k-3SBvIDeSLkQ;GCQstJS(Np~a>jgpg;?o|ToA30{|B7!pRFK7CqOSGQ-+9vU&4 zo0~=15JIkBzg|&MQBhHG^5n^>si{yvL^#7CggBi}n!+lT%5dRAkoEfg{-~&^mwyJV zg`(%{c5_{|Li5heVRRH03*>SnCSvt!A;4yX)rzSpC=^gC5figulK+bG%P%A?jR3)- zRuhee>z$q^RaIOsK(=io_wFrts9#0e+U70BmOFQXfFFJk2WYhdLRKr$>4@J?2q6v! z`Qs1b^%6qJ>@4Z+CDg1@L7z6pDG^{(i2SkbpPdKwMlnD;pTVci*9=hFgSs zgt0MHSEIZfVy=i!h!F4{kf=Wi^-z~Cfu=;}wcszLg7?YD27=M7%NyqKl1-Cm`wryLQYX}5_n<$Y$t;Rd=@Cijlp`igT z7pA8X8;jgrI2<^029c4dtqtxYA+Xy~SqZxxem@;2l_EMiSR_mQl~P#=wHoig549R) zWtf>+0YAjI`L;Gf2&t&xTJ(C-(h}Cne*HDfRr)^@l?oqxz*T?xiGSU)*;zC{H zE;Kda=byp9j!jSF`|t7mIj3K~jM-Uw_S)K@(Lke_XY-4Z^XGBv7Lt>LRjn4!pHo7A z{t3Gs9uLjDk)4gKEL^_K4gLLhIGynM0N~CYeEB6*D%`pSU~mw5dC1L0ZZ0gAr4fpb z#+z^A-FJgkyB$6sHGlhEyD&AyUdQ2bp|us6nb7Oe-Hnew#wVYEy>UvVFc>g11H1h{ ziS|=dXl%rhBS=q&%Y_36AV}0d{S^-&q4nIc68v%6&MW2&W1#Sn>XQf;(x2J0BqTUEnC3*|HA1l zEy&D-(a5<(Lh$z69KdWwOblM!|B#xBHEXEZd%eW%CT=(JdO4k+urdq>AVk>96Q`5N z<>FSIpHBh-Vlss_`<9lKNk2L}#ngwjPIXiTSuzz@0DyR1QVY3BO*tgz-R4N2842(v2JWwjJb}a{Z?UMX|0QIbl USs20!PXGV_07*qoM6N<$g4q$wNdN!< diff --git a/apps/antonclk/metadata.json b/apps/antonclk/metadata.json index b6134d1a1..b8242f11a 100644 --- a/apps/antonclk/metadata.json +++ b/apps/antonclk/metadata.json @@ -1,9 +1,8 @@ { "id": "antonclk", "name": "Anton Clock", - "version": "0.10", - "description": "A clock using the bold Anton font, optionally showing seconds and date in ISO-8601 format.", - "readme":"README.md", + "version": "0.11", + "description": "A simple clock using the bold Anton font. See `Anton Clock Plus` for an enhanced version", "icon": "app.png", "screenshots": [{"url":"screenshot.png"}], "type": "clock", @@ -12,8 +11,6 @@ "allow_emulator": true, "storage": [ {"name":"antonclk.app.js","url":"app.js"}, - {"name":"antonclk.settings.js","url":"settings.js"}, {"name":"antonclk.img","url":"app-icon.js","evaluate":true} - ], - "data": [{"name":"antonclk.json"}] + ] } diff --git a/apps/antonclk/screenshot.png b/apps/antonclk/screenshot.png index e949b8a24a4eac5cbd8f8a01ffdd57b3660b939c..9b38e90d5f4971de3630aeb2d871d88c5b349620 100644 GIT binary patch literal 2906 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 delta 1611 zcmV-R2DJIw7SRll8Gix*001D>a|r+d00v@9M??Vs0RI60puMM)00009a7bBm000XU z000XU0RWnu7ytkO2XskIMF-^!69_Lh-n7ZB000HvNklbO{l7h$vV@ z^bk*Al4oc>pj%2?N;iH&+w8Z)olD$Q3dQh@OvLdM`%fyN!Pifut;PPw*63ZxA*|Dd z;LjI8goqAL=6<$uQQp8;ZB8eWb#)U4Ef$av?E#0za2E;*)4GQr|jEE>MgPlWIg$fmf6 zshtWlvgg=3Rwde#%EB2ZCZ_CZaPtrhc0d|j{4_}=iN*gE;u{bi0>vmhZ-Zhq7gZR! zWpBGPT@bvP-QB*I3%vNK9g^4e^95YR9HNJMOGEc3^M9Rp>wW_kIYj4|OextET_U}h z-R+P`rJ!}Rtt{LA98BcMCRVjF)AN*_>NGSo8;#36rIqJHZ9E`U4MDIcWGoSn0-~82 zEhGn!I+2SQ{ckd4Do-Ln+a=Q-yP13kV~w>oZs%f_V7N&rbE1p+`I zL%6;C6MsM;fIy+jPEy6l$q*hQVlm}NEkIDf^bPk$BBy&+x%v0e^kIBJavbBN6Umq2VxOd)_kP9X!CRVA07YsN!Re-biK zLJ_%bI&*}l2s5giU{C*2$K0lYmFTfs|F^s zAb%y5wd4`4jP#6?u^o~J0xM5rioBqe!IzMMdoTw=&lVajkJ9GY9%3vj6NW58##mMs z+_FIqF^QG?w{A|BqPlI=31#Jm8=kdPNzu*-4r1ur+g_nwO_pDBSt|nsBB?|GfdB#l z1Of;I5C{PT`Vi+s2vQ>YSV5qY5%Yf+xOx%M+m~D8zc4(NJ3AK;` z4TKC(00_VG&*(%cM!Yj*oFC$5bAR6EHX~wv%ZJ(o!9=nvbN=)NI_LW23!uf*lSV&J@e_5g633jF7eC3ymTNk(bKT_2)Few0ZYgFE;#Hj!TvdbaR;7$S{ z5I~@3Cjk%$AP_*HLNRqckJ@$z)d1nO#UIx@&#k8g zW-0~b@*7OGlbEH8i~wN(hqjFc7kvQ&kwYMWKmdUN0s#b))gKUl&htS@a(Vy&002ov JPDHLkV1kDl<*@(& diff --git a/apps/antonclkplus/ChangeLog b/apps/antonclkplus/ChangeLog new file mode 100644 index 000000000..3b0a3d8b8 --- /dev/null +++ b/apps/antonclkplus/ChangeLog @@ -0,0 +1,15 @@ +0.01: New App! +0.02: Load widgets after setUI so widclk knows when to hide +0.03: Clock now shows day of week under date. +0.04: Clock can optionally show seconds, date optionally in ISO-8601 format, weekdays and uppercase configurable, too. +0.05: Clock can optionally show ISO-8601 calendar weeknumber (default: Off) + when weekday name "Off": week #: + when weekday name "On": weekday name is cut at 6th position and .# is added +0.06: fixes #1271 - wrong settings name + when weekday name and calendar weeknumber are on then display is # + week is buffered until date or timezone changes +0.07: align default settings with app.js (otherwise the initial displayed settings will be confusing to users) +0.08: fixed calendar weeknumber not shortened to two digits +0.09: Use default Bangle formatter for booleans +0.10: Use Bangle.setUI({remove:...}) to allow loading the launcher without a full reset on 2v16 + Modified to avoid leaving functions defined when using setUI({remove:...}) diff --git a/apps/antonclk/README.md b/apps/antonclkplus/README.md similarity index 87% rename from apps/antonclk/README.md rename to apps/antonclkplus/README.md index 28a38f5fd..25b478dd9 100644 --- a/apps/antonclk/README.md +++ b/apps/antonclkplus/README.md @@ -1,6 +1,6 @@ -# Anton Clock - Large font digital watch with seconds and date +# Anton Clock Plus - Large font digital watch with seconds and date -Anton clock uses the "Anton" bold font to show the time in a clear, easily readable manner. On the Bangle.js 2, the time can be read easily even if the screen is locked and unlit. +Anton Clock Plus uses the "Anton" bold font to show the time in a clear, easily readable manner. On the Bangle.js 2, the time can be read easily even if the screen is locked and unlit. ## Features @@ -16,16 +16,16 @@ The basic time representation only shows hours and minutes of the current time. ## Usage -Install Anton clock through the Bangle.js app loader. -Configure it through the default Bangle.js configuration mechanism +* Install Anton Clock Plus through the Bangle.js app loader. +* Configure it through the default Bangle.js configuration mechanism (Settings app, "Apps" menu, "Anton clock" submenu). -If you like it, make it your default watch face +* If you like it, make it your default watch face (Settings app, "System" menu, "Clock" submenu, select "Anton clock"). ## Configuration -Anton clock is configured by the standard settings mechanism of Bangle.js's operating system: -Open the "Settings" app, then the "Apps" submenu and below it the "Anton clock" menu. +Anton Clock is configured by the standard settings mechanism of Bangle.js's operating system: +Open the `Settings` app, then the `Apps` submenu and below it the `Anton Clock+` menu. You configure Anton clock through several "on/off" switches in two menus. ### The main menu diff --git a/apps/antonclkplus/app-icon.js b/apps/antonclkplus/app-icon.js new file mode 100644 index 000000000..0c3aeb210 --- /dev/null +++ b/apps/antonclkplus/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwgf/AH4At/l/Aofgh4DB+EAj4REQoM/AgP4AoeACIoLCg4FB4AFDCIwLCgAROgYIB8EBAoUH/gVBCIxQBCKYHBCJp9DI4ICBLJYRCn4RQEYMOR5ARDIgIRMYQZZBgARGZwZBDCKQrCgEDR5AdBUIQRJDoLXFCJD7J/xrICIQFCn4RH/4LDAoTaCCI4Ar/LLDCBfypMkCgMkyV/CJOSCIOf5IRGFwOfCJNP//JnmT588z/+pM/BYIRCk4RC/88+f/n4RCngRCz1JCIf5/nzGoQRIHwXPCIPJI4f8CJHJGQJKCCI59LCI5ZCCJ/+v/kBoM/+V/HIJrHBYJWB/JKB5x9JEYP8AQKdBpwRL841Dp41KZoTxBHYTXBWY77PCKKhJ/4/CcgMkXoQAiA=")) diff --git a/apps/antonclkplus/app.js b/apps/antonclkplus/app.js new file mode 100644 index 000000000..409d7d487 --- /dev/null +++ b/apps/antonclkplus/app.js @@ -0,0 +1,238 @@ +// Clock with large digits using the "Anton" bold font +Graphics.prototype.setFontAnton = function(scale) { + // Actual height 69 (68 - 0) + g.setFontCustom(atob("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAAAAAAAAAA/gAAAAAAAAAAP/gAAAAAAAAAH//gAAAAAAAAB///gAAAAAAAAf///gAAAAAAAP////gAAAAAAD/////gAAAAAA//////gAAAAAP//////gAAAAH///////gAAAB////////gAAAf////////gAAP/////////gAD//////////AA//////////gAA/////////4AAA////////+AAAA////////gAAAA///////wAAAAA//////8AAAAAA//////AAAAAAA/////gAAAAAAA////4AAAAAAAA///+AAAAAAAAA///gAAAAAAAAA//wAAAAAAAAAA/8AAAAAAAAAAA/AAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//////AAAAAB///////8AAAAH////////AAAAf////////wAAA/////////4AAB/////////8AAD/////////+AAH//////////AAP//////////gAP//////////gAP//////////gAf//////////wAf//////////wAf//////////wAf//////////wA//8AAAAAB//4A//wAAAAAAf/4A//gAAAAAAP/4A//gAAAAAAP/4A//gAAAAAAP/4A//wAAAAAAf/4A///////////4Af//////////wAf//////////wAf//////////wAf//////////wAP//////////gAP//////////gAH//////////AAH//////////AAD/////////+AAB/////////8AAA/////////4AAAP////////gAAAD///////+AAAAAf//////4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/gAAAAAAAAAAP/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/AAAAAAAAAAA//AAAAAAAAAAA/+AAAAAAAAAAB/8AAAAAAAAAAD//////////gAH//////////gAP//////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH/4AAAAB/gAAD//4AAAAf/gAAP//4AAAB//gAA///4AAAH//gAB///4AAAf//gAD///4AAA///gAH///4AAD///gAP///4AAH///gAP///4AAP///gAf///4AAf///gAf///4AB////gAf///4AD////gA////4AH////gA////4Af////gA////4A/////gA//wAAB/////gA//gAAH/////gA//gAAP/////gA//gAA///8//gA//gAD///w//gA//wA////g//gA////////A//gA///////8A//gA///////4A//gAf//////wA//gAf//////gA//gAf/////+AA//gAP/////8AA//gAP/////4AA//gAH/////gAA//gAD/////AAA//gAB////8AAA//gAA////wAAA//gAAP///AAAA//gAAD//8AAAA//gAAAP+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB/+AAAAAD/wAAB//8AAAAP/wAAB///AAAA//wAAB///wAAB//wAAB///4AAD//wAAB///8AAH//wAAB///+AAP//wAAB///+AAP//wAAB////AAf//wAAB////AAf//wAAB////gAf//wAAB////gA///wAAB////gA///wAAB////gA///w//AAf//wA//4A//AAA//wA//gA//AAAf/wA//gB//gAAf/wA//gB//gAAf/wA//gD//wAA//wA//wH//8AB//wA///////////gA///////////gA///////////gA///////////gAf//////////AAf//////////AAP//////////AAP/////////+AAH/////////8AAH///+/////4AAD///+f////wAAA///8P////gAAAf//4H///+AAAAH//gB///wAAAAAP4AAH/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/wAAAAAAAAAA//wAAAAAAAAAP//wAAAAAAAAB///wAAAAAAAAf///wAAAAAAAH////wAAAAAAA/////wAAAAAAP/////wAAAAAB//////wAAAAAf//////wAAAAH///////wAAAA////////wAAAP////////wAAA///////H/wAAA//////wH/wAAA/////8AH/wAAA/////AAH/wAAA////gAAH/wAAA///4AAAH/wAAA//+AAAAH/wAAA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gAAAAAAAAH/4AAAAAAAAAAH/wAAAAAAAAAAH/wAAAAAAAAAAH/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB//8AAA/////+B///AAA/////+B///wAA/////+B///4AA/////+B///8AA/////+B///8AA/////+B///+AA/////+B////AA/////+B////AA/////+B////AA/////+B////gA/////+B////gA/////+B////gA/////+A////gA//gP/gAAB//wA//gf/AAAA//wA//gf/AAAAf/wA//g//AAAAf/wA//g//AAAA//wA//g//gAAA//wA//g//+AAP//wA//g////////gA//g////////gA//g////////gA//g////////gA//g////////AA//gf///////AA//gf//////+AA//gP//////+AA//gH//////8AA//gD//////4AA//gB//////wAA//gA//////AAAAAAAH////8AAAAAAAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//////gAAAAB///////+AAAAH////////gAAAf////////4AAB/////////8AAD/////////+AAH//////////AAH//////////gAP//////////gAP//////////gAf//////////wAf//////////wAf//////////wAf//////////wAf//////////4A//wAD/4AAf/4A//gAH/wAAP/4A//gAH/wAAP/4A//gAP/wAAP/4A//gAP/4AAf/4A//wAP/+AD//4A///wP//////4Af//4P//////wAf//4P//////wAf//4P//////wAf//4P//////wAP//4P//////gAP//4H//////gAH//4H//////AAH//4D/////+AAD//4D/////8AAB//4B/////4AAA//4A/////wAAAP/4AP////AAAAB/4AD///4AAAAAAAAAH/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//AAAAAAAAAAA//gAAAAAAAAAA//gAAAAAAAAAA//gAAAAAAADgA//gAAAAAAP/gA//gAAAAAH//gA//gAAAAB///gA//gAAAAP///gA//gAAAD////gA//gAAAf////gA//gAAB/////gA//gAAP/////gA//gAB//////gA//gAH//////gA//gA///////gA//gD///////gA//gf///////gA//h////////gA//n////////gA//////////gAA/////////AAAA////////wAAAA///////4AAAAA///////AAAAAA//////4AAAAAA//////AAAAAAA/////4AAAAAAA/////AAAAAAAA////8AAAAAAAA////gAAAAAAAA///+AAAAAAAAA///4AAAAAAAAA///AAAAAAAAAA//4AAAAAAAAAA/+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//gB///wAAAAP//4H///+AAAA///8P////gAAB///+f////4AAD///+/////8AAH/////////+AAH//////////AAP//////////gAP//////////gAf//////////gAf//////////wAf//////////wAf//////////wA///////////wA//4D//wAB//4A//wB//gAA//4A//gA//gAAf/4A//gA//AAAf/4A//gA//gAAf/4A//wB//gAA//4A///P//8AH//4Af//////////wAf//////////wAf//////////wAf//////////wAf//////////gAP//////////gAP//////////AAH//////////AAD/////////+AAD///+/////8AAB///8f////wAAAf//4P////AAAAH//wD///8AAAAA/+AAf//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH//gAAAAAAAAB///+AA/+AAAAP////gA//wAAAf////wA//4AAB/////4A//8AAD/////8A//+AAD/////+A///AAH/////+A///AAP//////A///gAP//////A///gAf//////A///wAf//////A///wAf//////A///wAf//////A///wA///////AB//4A//4AD//AAP/4A//gAB//AAP/4A//gAA//AAP/4A//gAA/+AAP/4A//gAB/8AAP/4A//wAB/8AAf/4Af//////////wAf//////////wAf//////////wAf//////////wAf//////////wAP//////////gAP//////////gAH//////////AAH/////////+AAD/////////8AAB/////////4AAAf////////wAAAP////////AAAAB///////4AAAAAD/////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf/AAB/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="), 46, atob("EiAnGicnJycnJycnEw=="), 78 + (scale << 8) + (1 << 16)); +}; + +Graphics.prototype.setFontAntonSmall = function(scale) { + // Actual height 53 (52 - 0) + g.setFontCustom(atob("AAAAAAAAAAAAAAAAAAAAAAAAAAf8AAAAAAAAf8AAAAAAAAf8AAAAAAAAf8AAAAAAAAf8AAAAAAAAf8AAAAAAAAf8AAAAAAAAf8AAAAAAAAf8AAAAAAAAf8AAAAAAAAf8AAAAAAAAAAAAAAAAAAAAMAAAAAAAAD8AAAAAAAA/8AAAAAAAf/8AAAAAAH//8AAAAAB///8AAAAA////8AAAAP////8AAAD/////8AAB//////8AAf//////8AH///////4A///////+AA///////AAA//////wAAA/////8AAAA////+AAAAA////gAAAAA///4AAAAAA//8AAAAAAA//AAAAAAAA/wAAAAAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH/////wAAA//////8AAB//////+AAH///////gAH///////gAP///////wAf///////4Af///////4A////////8A////////8A////////8A//AAAAD/8A/8AAAAA/8A/8AAAAA/8A/8AAAAA/8A/+AAAAB/8A////////8A////////8A////////8Af///////4Af///////4AP///////wAP///////wAH///////gAD///////AAA//////8AAAP/////wAAAAAAAAAAAAAAAAAAAAAAAfwAAAAAAAA/4AAAAAAAA/4AAAAAAAB/wAAAAAAAB/wAAAAAAAD/wAAAAAAAD/gAAAAAAAH///////8AP///////8A////////8A////////8A////////8A////////8A////////8A////////8A////////8A////////8A////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH/4AAAP8AA//4AAA/8AB//4AAH/8AH//4AAP/8AP//4AA//8AP//4AB//8Af//4AD//8Af//4AP//8A///4Af//8A///4A///8A///4D///8A//AAH///8A/8AAP///8A/8AA//+/8A/8AD//8/8A/+Af//w/8A//////g/8A/////+A/8A/////8A/8Af////4A/8Af////wA/8AP////AA/8AP///+AA/8AH///8AA/8AD///wAA/8AA///AAA/8AAP/4AAA/8AAAAAAAAAAAAAAAAAAAAAAH4AAf/gAAA/4AAf/8AAD/4AAf//AAH/4AAf//gAP/4AAf//wAP/4AAf//wAf/4AAf//4Af/4AAf//4A//4AAf//8A//4AAf//8A//4AAP//8A//A/8AB/8A/8A/8AA/8A/8B/8AA/8A/8B/8AA/8A/+D//AB/8A////////8A////////8A////////8Af///////4Af///////4Af///////wAP///////gAH//9////gAD//4///+AAB//wf//4AAAP/AH//gAAAAAAAAAAAAAAAAAAAAAAAAAAAH/wAAAAAAB//wAAAAAAP//wAAAAAD///wAAAAA////wAAAAH////wAAAB/////wAAAf/////wAAD//////wAA///////wAA/////h/wAA////wB/wAA///8AB/wAA///AAB/wAA//gAAB/wAA////////8A////////8A////////8A////////8A////////8A////////8A////////8A////////8A////////8A////////8A////////8AAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAAAAAAAAAAAAAAAAAAAAAP/4AA////4P/+AA////4P//AA////4P//gA////4P//wA////4P//wA////4P//4A////4P//4A////4P//8A////4P//8A////4P//8A/8H/AAB/8A/8H+AAA/8A/8P+AAA/8A/8P+AAA/8A/8P/gAD/8A/8P/////8A/8P/////8A/8P/////8A/8P/////4A/8H/////4A/8H/////wA/8D/////wA/8B/////gA/8A////+AA/8AP///4AAAAAB///AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////wAAAf/////8AAB///////AAH///////gAP///////wAP///////wAf///////4Af///////4A////////8A////////8A////////8A/+AH/AB/8A/8AP+AA/8A/4Af+AA/8A/8Af+AA/8A/8Af/gH/8A//4f////8A//4f////8A//4f////8Af/4f////4Af/4f////4AP/4P////wAP/4P////gAH/4H////AAD/4D///+AAB/4B///4AAAP4AP//gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/8AAAAAAAA/8AAAAAAAA/8AAAAAB8A/8AAAAB/8A/8AAAAf/8A/8AAAH//8A/8AAA///8A/8AAH///8A/8AA////8A/8AD////8A/8Af////8A/8B/////8A/8P/////8A/8//////8A////////AA///////AAA//////gAAA/////4AAAA/////AAAAA////4AAAAA////AAAAAA///8AAAAAA///gAAAAAA//+AAAAAAA//wAAAAAAA/+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH/gD//gAAA//4P//8AAD//8f///AAH//+////gAH///////wAP///////4AP///////8Af///////8Af///////+Af///////+A////////+A//B//AB/+A/+A/+AA/+A/8Af+AA/+A/+Af+AA/+A//A//AB/+A////////+Af///////+Af///////+Af///////8Af///////8AP///////4AH///////4AH//+////wAD//+////AAA//4P//+AAAP/gH//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH//gAfgAAA///8A/8AAB///+A//AAH////A//gAH////g//wAP////g//wAf////w//4Af////w//4A/////w//8A/////w//8A/////w//8A//gP/wA/8A/8AD/wA/8A/8AD/wAf8A/8AD/gA/8A/+AH/AB/8A////////8A////////8A////////8Af///////4Af///////4Af///////wAP///////wAH///////gAD//////+AAA//////4AAAP/////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+AA/4AAAAP+AA/4AAAAP+AA/4AAAAP+AA/4AAAAP+AA/4AAAAP+AA/4AAAAP+AA/4AAAAP+AA/4AAAAP+AA/4AAAAP+AA/4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="), 46, atob("DhgeFB4eHh4eHh4eDw=="), 60 + (scale << 8) + (1 << 16)); +}; + +{ // 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 + +const SETTINGSFILE = "antonclk.json"; +const isBangle1 = (process.env.HWVERSION == 1); + +// variables defined from settings +let secondsMode; +let secondsColoured; +let secondsWithColon; +let dateOnMain; +let dateOnSecs; +let weekDay; +let calWeek; +let upperCase; +let vectorFont; + +// dynamic variables +let drawTimeout; +let queueMillis = 1000; +let secondsScreen = true; + + + +//For development purposes +/* +require('Storage').writeJSON(SETTINGSFILE, { + secondsMode: "Unlocked", // "Never", "Unlocked", "Always" + secondsColoured: true, + secondsWithColon: true, + dateOnMain: "Long", // "Short", "Long", "ISO8601" + dateOnSecs: "Year", // "No", "Year", "Weekday", LEGACY: true/false + weekDay: true, + calWeek: true, + upperCase: true, + vectorFont: true, +}); +*/ + +// OR (also for development purposes) +/* +require('Storage').erase(SETTINGSFILE); +*/ + +// Load settings +let loadSettings = function() { + // Helper function default setting + function def (value, def) {return value !== undefined ? value : def;} + + var settings = require('Storage').readJSON(SETTINGSFILE, true) || {}; + secondsMode = def(settings.secondsMode, "Never"); + secondsColoured = def(settings.secondsColoured, true); + secondsWithColon = def(settings.secondsWithColon, true); + dateOnMain = def(settings.dateOnMain, "Long"); + dateOnSecs = def(settings.dateOnSecs, "Year"); + weekDay = def(settings.weekDay, true); + calWeek = def(settings.calWeek, false); + upperCase = def(settings.upperCase, true); + vectorFont = def(settings.vectorFont, false); + + // Legacy + if (dateOnSecs === true) + dateOnSecs = "Year"; + if (dateOnSecs === false) + dateOnSecs = "No"; +} + +// schedule a draw for the next second or minute +let queueDraw = function() { + if (drawTimeout) clearTimeout(drawTimeout); + drawTimeout = setTimeout(function() { + drawTimeout = undefined; + draw(); + }, queueMillis - (Date.now() % queueMillis)); +} + +let updateState = function() { + if (Bangle.isLCDOn()) { + if ((secondsMode === "Unlocked" && !Bangle.isLocked()) || secondsMode === "Always") { + secondsScreen = true; + queueMillis = 1000; + } else { + secondsScreen = false; + queueMillis = 60000; + } + draw(); // draw immediately, queue redraw + } else { // stop draw timer + if (drawTimeout) clearTimeout(drawTimeout); + drawTimeout = undefined; + } +} + +let isoStr = function(date) { + return date.getFullYear() + "-" + ("0" + (date.getMonth() + 1)).slice(-2) + "-" + ("0" + date.getDate()).slice(-2); +} + +let calWeekBuffer = [false,false,false]; //buffer tz, date, week no (once calculated until other tz or date is requested) +let ISO8601calWeek = function(date) { //copied from: https://gist.github.com/IamSilviu/5899269#gistcomment-3035480 + dateNoTime = date; dateNoTime.setHours(0,0,0,0); + if (calWeekBuffer[0] === date.getTimezoneOffset() && calWeekBuffer[1] === dateNoTime) return calWeekBuffer[2]; + calWeekBuffer[0] = date.getTimezoneOffset(); + calWeekBuffer[1] = dateNoTime; + var tdt = new Date(date.valueOf()); + var dayn = (date.getDay() + 6) % 7; + tdt.setDate(tdt.getDate() - dayn + 3); + var firstThursday = tdt.valueOf(); + tdt.setMonth(0, 1); + if (tdt.getDay() !== 4) { + tdt.setMonth(0, 1 + ((4 - tdt.getDay()) + 7) % 7); + } + calWeekBuffer[2] = 1 + Math.ceil((firstThursday - tdt) / 604800000); + return calWeekBuffer[2]; +} + +let doColor = function() { + return !isBangle1 && !Bangle.isLocked() && secondsColoured; +} + +// Actually draw the watch face +let draw = function() { + var x = g.getWidth() / 2; + var y = g.getHeight() / 2 - (secondsMode !== "Never" ? 24 : (vectorFont ? 12 : 0)); + g.reset(); + /* This is to mark the widget areas during development. + g.setColor("#888") + .fillRect(0, 0, g.getWidth(), 23) + .fillRect(0, g.getHeight() - 23, g.getWidth(), g.getHeight()).reset(); + /* */ + g.clearRect(0, 24, g.getWidth(), g.getHeight() - 24); // clear whole background (w/o widgets) + var date = new Date(); // Actually the current date, this one is shown + var timeStr = require("locale").time(date, 1); // Hour and minute + g.setFontAlign(0, 0).setFont("Anton").drawString(timeStr, x, y); // draw time + if (secondsScreen) { + y += 65; + var secStr = (secondsWithColon ? ":" : "") + ("0" + date.getSeconds()).slice(-2); + if (doColor()) + g.setColor(0, 0, 1); + g.setFont("AntonSmall"); + if (dateOnSecs !== "No") { // A bit of a complex drawing with seconds on the right and date on the left + g.setFontAlign(1, 0).drawString(secStr, g.getWidth() - (isBangle1 ? 32 : 2), y); // seconds + y -= (vectorFont ? 15 : 13); + x = g.getWidth() / 4 + (isBangle1 ? 12 : 4) + (secondsWithColon ? 0 : g.stringWidth(":") / 2); + var dateStr2 = (dateOnMain === "ISO8601" ? isoStr(date) : require("locale").date(date, 1)); + var year; + var md; + var yearfirst; + if (dateStr2.match(/\d\d\d\d$/)) { // formatted date ends with year + year = (dateOnSecs === "Year" ? dateStr2.slice(-4) : require("locale").dow(date, 1)); + md = dateStr2.slice(0, -4); + if (!md.endsWith(".")) // keep separator before the year only if it is a dot (31.12. but 31/12) + md = md.slice(0, -1); + yearfirst = false; + } else { // formatted date begins with year + if (!dateStr2.match(/^\d\d\d\d/)) // if year position cannot be detected... + dateStr2 = isoStr(date); // ...use ISO date format instead + year = (dateOnSecs === "Year" ? dateStr2.slice(0, 4) : require("locale").dow(date, 1)); + md = dateStr2.slice(5); // never keep separator directly after year + yearfirst = true; + } + if (dateOnSecs === "Weekday" && upperCase) + year = year.toUpperCase(); + g.setFontAlign(0, 0); + if (vectorFont) + g.setFont("Vector", 24); + else + g.setFont("6x8", 2); + if (doColor()) + g.setColor(1, 0, 0); + g.drawString(md, x, (yearfirst ? y + (vectorFont ? 26 : 16) : y)); + g.drawString(year, x, (yearfirst ? y : y + (vectorFont ? 26 : 16))); + } else { + g.setFontAlign(0, 0).drawString(secStr, x, y); // Just the seconds centered + } + } else { // No seconds screen: Show date and optionally day of week + y += (vectorFont ? 50 : (secondsMode !== "Never") ? 52 : 40); + var dateStr = (dateOnMain === "ISO8601" ? isoStr(date) : require("locale").date(date, (dateOnMain === "Long" ? 0 : 1))); + if (upperCase) + dateStr = dateStr.toUpperCase(); + g.setFontAlign(0, 0); + if (vectorFont) + g.setFont("Vector", 24); + else + g.setFont("6x8", 2); + g.drawString(dateStr, x, y); + if (calWeek || weekDay) { + var dowcwStr = ""; + if (calWeek) + dowcwStr = " #" + ("0" + ISO8601calWeek(date)).slice(-2); + if (weekDay) + dowcwStr = require("locale").dow(date, calWeek ? 1 : 0) + dowcwStr; //weekDay e.g. Monday or weekDayShort # e.g. Mon #01 + else //week #01 + dowcwStr = /*LANG*/"week" + dowcwStr; + if (upperCase) + dowcwStr = dowcwStr.toUpperCase(); + g.drawString(dowcwStr, x, y + (vectorFont ? 26 : 16)); + } + } + + // queue next draw + queueDraw(); +} + +// Init the settings of the app +loadSettings(); +// Clear the screen once, at startup +g.clear(); +// Set dynamic state and perform initial drawing +updateState(); +// Register hooks for LCD on/off event and screen lock on/off event +Bangle.on('lcdPower', updateState); +Bangle.on('lock', updateState); +// Show launcher when middle button pressed +Bangle.setUI({ + mode : "clock", + remove : function() { + // Called to unload all of the clock app + Bangle.removeListener('lcdPower', updateState); + Bangle.removeListener('lock', updateState); + if (drawTimeout) clearTimeout(drawTimeout); + drawTimeout = undefined; + delete Graphics.prototype.setFontAnton; + delete Graphics.prototype.setFontAntonSmall; + }}); +// Load widgets +Bangle.loadWidgets(); +Bangle.drawWidgets(); +} diff --git a/apps/antonclkplus/app.png b/apps/antonclkplus/app.png new file mode 100644 index 0000000000000000000000000000000000000000..a38093c5f3b6f88dbc9b75017422dbe237d4407f GIT binary patch literal 1989 zcmV;$2RitPP)jLx_$n|!#a_+a7!4?Zj*KoBI+mq8Z8#{*+o z7DHwNZgKLU(NGK;MJHm2(2Z3wlN9^G$Dl3PLZR*L$JxWF_g-#q5pXO%?4OgH|2gM( z&iUPY&i~`w2to*6Cz0Salm7|*Pv});Rk#kH&o?nKVKf?JV`CKxgR&1SYr2-&`UyG$k%PDI4SU@#m$e3%a_DJdBl84(40z238D&kClk zs;Y82oqX8o)29U(i^UQ;n+PGB&6b*)8u|?i3JT`t=0fr3&YhD;M7F-UxtYZ<46||L z#$^(^di83!ed+D(C4@{&Ojs-yi^VcGH|KCTl9H16n23l7R(HGIbWWX4$8TSNkjR^L zcXzY8Ua#-%?PaT@qoV@@0~H&dOV(ykrCQkT3X65OnG@Zi=UX7pvt31 zj}{pcL)2{nR~LU?!AoakWJE?r@;{iv;h@Tm8#ky@Q&Y1{D-)+L zk?;ux0)h4G*YjJ(#>Q^nzRiCh09LE@!i5U}3JVKgYOOCJ6uR+Sw{CU2-NC`D<_&Lc zZ7nJ)ve|63T3A>ZA0H23aBz^e?A^OJbi$<(>ged0o}Lzbr0D2qQLxA3VcF#5df&c%%k%pC z_wR3NYGVEE(W6Hhh8Y?fqAfC+OyD3EODH`({lS9=J9q8`AeBm6T3YzMGcz-7ZEYHj zMx)V~&1Q$gG4w*>jhws#}m#f8yXryC+C~U z`1tsuqP^K{Rw|XD3shHEi{?XpeSM+eoSYo1)w(dD#ik#GkY~@Hm6eqVUYB7Q5=Ndr zeOgynw`b2D8Znxin?>0WLatxGUQtm|QBiU7#}wE{v` zE79qQ-%ki34hQ+;590L_Ldfha>Fp)d!~y~G@F9PBpO089!Qyrkhl5){BH^9@$<8K( zknwSGHUObsMZ!iMoIj7rNmN(E>qSis+-{VX!tckAKO!Om1qJYW@$I*me+7H^5OR62 z3=ZN&Qctf5g8}2?{1^qN6CZvUtlqoFPd{WbR8}H06H+N04!rjsKKcl1 zHT-^*mm?zsDJcj9aOMowuALuH=N;9*{^ImQhp>7z6pDG^{(i2SkbpPdKwMlnD;pTV zci*9=hFgSsgt0MHSEIZfVy=i!h!F4{kf=Wi^-z~Cfu=;}wcszLg7?YD27=Y7B$L-n$w>wz2ZCjda2n2$gD3L&|#yjuu z2}MPrp#d%zrl%1bi`-l|95{0Zk&&pa4elc$u-j2t3A-JBKOHBPB04%)Buo62QdtSL z8t=akwHjq*n3-7tKg75Bwl+ctsi@#u^m@|L64uIo{WZ*0`actu3LkvHRe$=4-LlzP zG&h4@(OoVyHR0!>Q z7SEqkLVx}VyB!`6&AgGFjjSwOzRV5%{dYK>@c97X&K-RDB~&Whx&>fx5P5mX%|&i5 zES9AaijKycZ{po|gH^j7J|8vvUAr(f#a_qZa-p>qnVHb*(cO)YKgK7YfW2`_r7##U zGXuN*KZ*8JQ)q0&kt0Y?hs%Wn2Ovn)Km8PaeXKu8NC11$U9)D%%lmw+13^*}qN6FH z-+sfTOGr$_fdjDHVKCt4O^lA>^Up#50d{oY$`u$4$j*jDf}1ztbmFV80BqTUEnC3* z|HA1lEy&D-(a5<(Lh$z69KdWwOblM!|B#xBHEXEZd%eW%CT=(JdO4k+urdq>AVk>9 z6Q`5N<>FSIpHBh-Vlss_`<9lKNk2L}#ngwjPIdq7ye|T3ar}q0{vjtPwx88zODg-bLj7E4oP%5!@EeCk*lKg)F X^{k9p7{Urq00000NkvXXu0mjf6Vk;2 literal 0 HcmV?d00001 diff --git a/apps/antonclkplus/metadata.json b/apps/antonclkplus/metadata.json new file mode 100644 index 000000000..05c59a4fb --- /dev/null +++ b/apps/antonclkplus/metadata.json @@ -0,0 +1,20 @@ +{ + "id": "antonclkplus", + "name": "Anton Clock Plus", + "shortName": "Anton Clock+", + "version": "0.10", + "description": "A clock using the bold Anton font, optionally showing seconds and date in ISO-8601 format.", + "readme":"README.md", + "icon": "app.png", + "screenshots": [{"url":"screenshot.png"}], + "type": "clock", + "tags": "clock", + "supports": ["BANGLEJS","BANGLEJS2"], + "allow_emulator": true, + "storage": [ + {"name":"antonclkplus.app.js","url":"app.js"}, + {"name":"antonclkplus.settings.js","url":"settings.js"}, + {"name":"antonclkplus.img","url":"app-icon.js","evaluate":true} + ], + "data": [{"name":"antonclkplus.json"}] +} diff --git a/apps/antonclkplus/screenshot.png b/apps/antonclkplus/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..e949b8a24a4eac5cbd8f8a01ffdd57b3660b939c GIT binary patch literal 1617 zcmV-X2Cn&uP)Q+S zK~#9!?VZUMqaYAPh2#JKvc1UZv~4tDs0p}l)q??3Tx$R!={SxJp})$Q0G+jC0!O8^ zZQJ(gqtoj@Omqnmc!(%iMD!3(V3KEOKA>AlTS_;6Lfh=O!<|dqR0_rLj7-Gw6Z=mp zp~2Trq^-sN$JXdw$RVuLh2YN@K!k`6Pvr(ctjI(h8vf-F??mA#V@N4cYlvqI5okD% z_;DP$JZ&Vq6!#OKe-2k=TnY^!SWV;*Zso@9p8;ZB8eWb#)U4Ef$av?E#0za2E;*)4 zGQr|jEE>MgPlWIg$fmf6shtWlvgg=3Rwde#%EB2ZCZ_CZaPtrhc0d|j{4_}=iN*gE z;u{bi0>vmhZ-Zhq7gZR!WpBGPT@bvP-QB*I3%vNK9g^4e^95YR9HNJMOGEc3^PP9= zeghUcMCX@GDcKZVBE6X1?T|^OpmnsZEZhDZOytNWR<$zI^OT+HG&D3DjmtcxmFGik zJRnpJL9i!eED?_aqL~>jBoBmvl^IAI?bAQ&EayfCLS!S5jl)pgvlP?kIp+`qJ-$`9 zI&Of=#-z_m07)eU0ze=`xV`)nKp=oXp~_BD#mLDJ9wK5fE z#1PK_NhKK)K)?h*keQkSK^pPXNsQt-Sls%7_-cz=S=@s2k+GEj%NkD=(Y+yF1hHNY zWjJb$33G_!II4DCYVYQgVzm5w4K066RQR$vmhmvwd4`4jP#6?u^o~J0xM5rioBqe!IzMMdoTw=&lVajkJ9GY z9%3vj6NW58##mMs+_FIqF^QG?w{A|BqPlI=31#Jm8=kdPNzu*-4r1ur+g_nwO_pDB zSt|nsBB?|GfdB#l1Of;I5C{PT`Vi+s2Euz_W#>-KgN-VUDq z#UUT`_r2FnJ@tTi{%rF%-L<}@?8QSJM06gQ<1o7S3rWrW=F(^C@-1(NO7CJ^d6bax zGyqiu-d<&OgG88Z zc)oUMn41Z;kO2*Z3{U_Fzw*!ML@7qRGi00};%0N+<~AZNBToysfdB#l1d`Ps5P#0|K}m9Y P00000NkvXXu0mjfUbx{% literal 0 HcmV?d00001 diff --git a/apps/antonclk/settings.js b/apps/antonclkplus/settings.js similarity index 100% rename from apps/antonclk/settings.js rename to apps/antonclkplus/settings.js