From 911c0e454c0525b83a3d3888cb6311b4de0ff6e2 Mon Sep 17 00:00:00 2001 From: msdeibel Date: Sun, 16 Feb 2020 09:42:39 +0100 Subject: [PATCH 01/59] Initial checkin --- apps/wohrm/ChangeLog | 1 + apps/wohrm/add_to_apps.json | 13 +++ apps/wohrm/app-icon.js | 1 + apps/wohrm/wohrm.js | 166 ++++++++++++++++++++++++++++++++++++ apps/wohrm/wohrm.json | 5 ++ apps/wohrm/wohrm.png | Bin 0 -> 1925 bytes 6 files changed, 186 insertions(+) create mode 100644 apps/wohrm/ChangeLog create mode 100644 apps/wohrm/add_to_apps.json create mode 100644 apps/wohrm/app-icon.js create mode 100644 apps/wohrm/wohrm.js create mode 100644 apps/wohrm/wohrm.json create mode 100644 apps/wohrm/wohrm.png diff --git a/apps/wohrm/ChangeLog b/apps/wohrm/ChangeLog new file mode 100644 index 000000000..bc13085a4 --- /dev/null +++ b/apps/wohrm/ChangeLog @@ -0,0 +1 @@ +0.01: Only tested on the emulator. diff --git a/apps/wohrm/add_to_apps.json b/apps/wohrm/add_to_apps.json new file mode 100644 index 000000000..96ffe838c --- /dev/null +++ b/apps/wohrm/add_to_apps.json @@ -0,0 +1,13 @@ +// Create an entry in apps.json as follows: +{ "id": "wohrm", + "name": "Workout Heart Rate Monitor", + "icon": "wohrm.png", + "version":"0.01", + "description": "Workout heart rate monitor notifies you with a buzz if your heart rate goes above or below the set limits.", + "tags": "hrm workout app", + "storage": [ + {"name":"+wohrm","url":"wohrm.json"}, + {"name":"-wohrm","url":"wohrm.js"}, + {"name":"*wohrm","url":"wohrm-icon.js","evaluate":true} + ] +} diff --git a/apps/wohrm/app-icon.js b/apps/wohrm/app-icon.js new file mode 100644 index 000000000..36663d0ed --- /dev/null +++ b/apps/wohrm/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("MDCI/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+wsK7u8HC/v7+/v7+/v7+/v7+/v7Cwbu7wsL+/v7+/v7+/v7+/v7+/v7+/v7+ybu7u7u7u7u7u7vI/v7+/v7+/v7Iu7u7u7u7u7u7u8n+/v7+/v7+/v7+/v7+/v67u7u7u7u7u7u7u7u7u/7+/v7+/ru7u7u7u7u7u7u7u7u7/v7+/v7+/v7+/v7+/ru7u7u7u7u7u7u7u7u7u7v+/v7+u7u7u7u7u7u7u7u7u7u7u/7+/v7+/v7+/v7+u7u7u7u7u7u7u7u7u7u7u7u7/v67u7u7u7u7u7u7u7u7u7u7u7v+/v7+/v7+/v67u7u7u7u7u7u7wci7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7/v7+/v7+/sm7u7u7u7u7u7u7wsm7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7yf7+/v7+/ru7u7u7u7u7u7u7ydC7u7u7u7u7u7u7u7u7u7u7u8LQ19DCu7u7u7u7u/7+/v7+/ru7u7u7u7u7u7u70NfCu7u7u7u7u7u7u7u7u7u7u9DX19fQu7u7u7u7u/7+/v7+wru7u7u7u7u7u7vC19fJu7u7u7u7u7u7u7u7u7u7u9fX19fXu7u7u7u7u8L+/v7+wru7u7u7u7u7u7vJ19fJu7u7u7u7u7u7u7u7u7u7u9DX19fQu7u7u7u7u8L+/v7+u7u7u7u7u7u7u7vQ19fQu7u7u7u7u7u7u7u7u7u7u8nX19DCu7u7u7u7u7v+/v7+wbu7u7u7ybu7u7vX19DXwru7u7u7u7u7u7u7wcnQ19fX0Lu7u7u7u7u7u8H+/v7+wru7u7vC18K7u8LX0MnXybu7u7vCu7u7wc/Q19fX19fX18K7u7u7u7u7u8L+/v7+yLu7u7vJ18m7u8nXycnXybu7u7vJu7u7wtfX19DJydfX19C7u7u7u7u7u8j+/v7+/ru7u8HR19HBu9DXwsLX0Lu7u7vQu7u7wdfX0Lu70NfJ0NfJu7u7u7u7u/7+/v7+/ru7u8nX19fJwtfQu7vQ18K7u8LXu7u7u8HQ18LC19fBwtfXycm7u7u7u/7+/v7+/tDX19fXydfQydfJu7vJ18m7u8nXu7u7u7vBwrvQ18m7u9DX19e7u7u7yf7+/v7+/v7Q19fQu9DX0NfIu7vJ18m7u9DXu7u7u7u7u8HX18K7u8HJycm7u7u7/v7+/v7+/v7+u7u7u8nX19fBu7vC19C7wtfQu7u7u7u7u8nX0Lu7u7u7u7u7u7v+/v7+/v7+/v7+wru7u8HR19C7u7u70NfCz9fJu7u7wru7u9fX18nCu7u7u7u7u8L+/v7+/v7+/v7+/sG7u7vJ18m7u7u7ydfJ0dfBu8HC19C7yNfX19fX0MK7u7u7wf7+/v7+/v7+/v7+/v67u7vC18K7u7u7ydfQ19C7u7vB0NfQ0NfJws/X18G7u7u7/v7+/v7+/v7+/v7+/v7+u7u70Lu7u7u7wtfX18m7u7u7wdDX19e7u8LX18K7u7v+/v7+/v7+/v7+/v7+/v7+/ru7wbu7u7u7u9DX18G7u7u7u8HJ18m7wdDX0Lu7u/7+/v7+/v7+/v7+/v7+/v7+/v67u7u7u7u7u8nX0Lu7u7u7u7u7wcG70NfQu7u7/v7+/v7+/v7+/v7+/v7+/v7+/v7+wbu7u7u7u8nXyLu7u7u7u7u7u7vJ19fCu7v+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/sG7u7u7u8LXwbu7u7u7u7u7u8HX18K7wf7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7Cu7u7u7vJu7u7u7u7u7u7u7vCybvC/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+ybu7u7vBu7u7u7u7u7u7u7u7u8L+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v67u7u7u7u7u7u7u7u7u7u7/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+wru7u7u7u7u7u7u7u8L+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/sm7u7u7u7u7u7u7yf7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+wru7u7u7u8L+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v67u7u7yf7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+wsL+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/g==")) diff --git a/apps/wohrm/wohrm.js b/apps/wohrm/wohrm.js new file mode 100644 index 000000000..d5f2c1c03 --- /dev/null +++ b/apps/wohrm/wohrm.js @@ -0,0 +1,166 @@ +upperLimit = 130; +lowerLimit = 100; +limitSetter = "lower"; +currentHeartRate = 220; +hrConfidence = 49; + +function drawTrainingHeartRate() { + renderUpperLimit(); + + renderCurrentHeartRate(); + + renderLowerLimit(); + + renderConfidenceBars(); + + buzz(); +} + +function renderUpperLimit() { + g.setColor(255,0,0); + g.fillRect(140,40, 230, 70); + g.fillRect(200,70, 230, 210); + + if(limitSetter === "upper"){ + g.setColor(255,255, 255); + g.drawPoly([140,40,230,40,230,210,200,210,200,70,140,70], true); + } + + g.setColor(255,255,255); + g.setFontVector(10); + g.drawString("Upper : " + upperLimit, 150,50); +} + +function renderCurrentHeartRate() { + g.setColor(0,255,0); + g.fillRect(55, 110, 175, 140); + g.setColor(0,0,0); + g.setFontVector(13); + g.drawString("Current: " + currentHeartRate, 75,117); +} + +function renderLowerLimit() { + g.setColor(0,0,255); + g.fillRect(10, 180, 100, 210); + g.fillRect(10, 40, 40, 180); + + if(limitSetter === "lower"){ + g.setColor(255,255, 255); + g.drawPoly([10,40,40,40,40,180,100,180,100,210,10,210], true); + } + + g.setColor(255,255,255); + g.setFontVector(10); + g.drawString("Lower : " + lowerLimit, 20,190); +} + +function renderConfidenceBars(){ + if(hrConfidence >= 85){ + g.setColor(0, 255, 0); + } else if (hrConfidence >= 50) { + g.setColor(255, 255, 0); + } else if(hrConfidence >= 0){ + g.setColor(255, 0, 0); + } else { + g.setColor(0, 0, 0); + } + + g.fillRect(55, 110, 65, 140); + g.fillRect(175, 110, 185, 140); +} + +function buzz() +{ + if(currentHeartRate > upperLimit) + { + Bangle.buzz(70); + setTimeout(() => { Bangle.buzz(70); }, 70); + setTimeout(() => { Bangle.buzz(70); }, 70); + } + + if(currentHeartRate < upperLimit) + { + Bangle.buzz(140); + setTimeout(() => { Bangle.buzz(140); }, 140); + } +} + +function onHrm(hrm){ + currentHeartRate = hrm.bpm; + hrConfidence = hrm.confidence; +} + +function setLimitSetterToLower() { + limitSetter = "lower"; + console.log("Limit setter is lower"); + renderUpperLimit(); + renderLowerLimit(); +} + +function setLimitSetterToUpper() { + limitSetter = "upper"; + console.log("Limit setter is upper"); + renderLowerLimit(); + renderUpperLimit(); +} + +function incrementLimit(){ + if(limitSetter === "upper"){ + upperLimit++; + renderUpperLimit(); + console.log("Upper limit: " + upperLimit); + } else { + lowerLimit++; + renderLowerLimit(); + console.log("Lower limit: " + lowerLimit); + } +} + +function decrementLimit(){ + if(limitSetter === "upper"){ + upperLimit--; + renderUpperLimit(); + console.log("Upper limit: " + upperLimit); + } else { + lowerLimit--; + renderLowerLimit(); + console.log("Lower limit: " + lowerLimit); + } +} + +// Show launcher when middle button pressed +function switchOfWidget(){ + Bangle.setHRMPower(0); + Bangle.showLauncher(); +} + +// special function to handle display switch on +Bangle.on('lcdPower', (on) => { + g.clear(); + if (on) { + Bangle.drawWidgets(); + // call your app function here + drawTrainingHeartRate(); + } +}); + +Bangle.setHRMPower(1); +Bangle.on('HRM', onHrm); + +// refesh every sec +setInterval(drawTrainingHeartRate, 1000); + +g.clear(); +Bangle.loadWidgets(); +Bangle.drawWidgets(); +drawTrainingHeartRate(); + +setWatch(switchOfWidget, BTN2, {repeat:false,edge:"falling"}); + +setWatch(incrementLimit, BTN1, {edge:"rising", debounce:50, repeat:true}); + +setWatch(decrementLimit, BTN3, {edge:"rising", debounce:50, repeat:true}); + +setWatch(setLimitSetterToLower, BTN4, {edge:"rising", debounce:50, repeat:true}); + +setWatch(setLimitSetterToUpper, BTN5, {edge:"rising", debounce:50, repeat:true}); \ No newline at end of file diff --git a/apps/wohrm/wohrm.json b/apps/wohrm/wohrm.json new file mode 100644 index 000000000..9b212bfd4 --- /dev/null +++ b/apps/wohrm/wohrm.json @@ -0,0 +1,5 @@ +{ + "name":"Workout HRM", + "icon":"*wohrm", + "src":"-wohrm" +} diff --git a/apps/wohrm/wohrm.png b/apps/wohrm/wohrm.png new file mode 100644 index 0000000000000000000000000000000000000000..8f9c0ea5dc9baa64f7b6586eaba4773699b33b72 GIT binary patch literal 1925 zcmeHH`8(7J82^rOrA9nbvWZeco1+|sax)m$xbKmp+!NzLmunR38dlU~SFI?Kt5gzE zVzr(X5y_FG=MIN6e<6r}(FAlZ?vs6y5G z0ZF2eX%kyoghEK5+FAhhfA3io4x(qw9nArtsc9lkQW8=ra->Vu%9awK!pR`;6N%I=mrJ3Lo^SV<_QIRL8rZ-5N|ld7Yg-- z!~NiJe>fr#jy{dVgdwqENL)A^9|0#sA_-A&Vib}TgCxZv$+1YvIpjPYxo{4-5RYC? zLQ|6w=0)VnWi%rN&A5POUPQA}k?b@ikBJmyp;yz;>~v0c1}7&I%}qyhh0NsSUP1Gi zoPumlVGgG#m-A~rT9S`mD?m#NIVCK#tcY{Hh;yTubF+k7ejUBd=2ZU1t^R{oUCFz9 zhgVa@t*zqJRrBgT6St)id(y&v`jFT5nAg#YwYT%S zo?~5|SobTe=M}H7hu7c7@B0%Ia(_QIG=RMu#72hr!^8N<2sZW}`!I@+PvDbN*z_bm zHH}Yw!l!5WGt>CYoM3hypZmg}pB2o15qw?{EG!DXF7ubZ3KmxcORIwAHU8QvzW$B> zeI4K2z+ni7VH`zp6veq*9OK~_hU2(EAQ0~Q|N2(~%Ch>B!aD&NR3|rKME~Ui+z^R_ z!g#jO$vz1HApPnG2)%LlLWQOR!`hqS78lM)3XTs0=)n=O46WEOhKin+j+TB{*3mEk z5Sg;GGIu9Cd@k|vk~5ddipd~T%rabURHZ~;XJ#DEK0LcO$z?cG@m!a@t3N$IJI%pe z=9-9@<(#qKCDu3dJcD62X`cRJ=g8Rjn?ZANYKrpou?>UU>BDgn+Z#204xK9w zlqdAI-g>kkebXl~n{Y;(`BcACt?G?Jk7hokL$kS4PVj#H-gTR7$O`Fgr)pJXnrgIC zjmdtVlA`)T(U4DCp4xejjZZEzn|jvsgP@DL1!d|Fx))qjthNGr4b1I( zb%Dsy$0Ck?-*ecC6wxL6l1+)!*4@d~Lv$ss(_lP9&QM>a&UY{$VJ3GU8th5KMBbK- zN@O-VXG>1Vb1F!;SfcljkR}U;v{Ch10-vr&%qx|2t!9r&Yo`QNqAwMS3lwR&isBtF zqcm%K7f(G>cbnTarAuLqIgg4f>8EY0u`u?pK7UAWdttpy`gqRuRBfmIY855a_U;3_ zS%F4vj(W1`&TlK%Jokj~lk1zKH0=ahg_#B_BOgq>&CG6$H;07Qp~~3muBbzDk*=6c z8vq4rS1Gj1nUerU?i$0Mx zgo8~Rtt;w8mdBnE`ygozIo9Ct)m5D`f3_IwX!Pu76Uw`~G#s37X?FJ7X|^`r7hc^= e@X?nbXb1>8u*t*8XN-v-AH>eu$*SIhmhlgSO4arN literal 0 HcmV?d00001 From e5624843605dfbf71d57d929031e3ff3ff2ea58e Mon Sep 17 00:00:00 2001 From: Markus Deibel Date: Sun, 16 Feb 2020 09:48:07 +0100 Subject: [PATCH 02/59] Adds Workout Heart Rate Monitor App --- apps.json | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/apps.json b/apps.json index 0c47a9377..212ece336 100644 --- a/apps.json +++ b/apps.json @@ -809,6 +809,17 @@ {"name":"-flagrse","url":"app.js"}, {"name":"*flagrse","url":"app-icon.js","evaluate":true} ] + }, + { "id": "wohrm", + "name": "Workout Heart Rate Monitor", + "icon": "wohrm.png", + "version":"0.01", + "description": "Workout heart rate monitor notifies you with a buzz if your heart rate goes above or below the set limits.", + "tags": "hrm workout app", + "storage": [ + {"name":"+wohrm","url":"wohrm.json"}, + {"name":"-wohrm","url":"wohrm.js"}, + {"name":"*wohrm","url":"wohrm-icon.js","evaluate":true} + ] } - ] From 18c69b9e677e22436e3263182b2c52884c54155f Mon Sep 17 00:00:00 2001 From: Markus Deibel Date: Sun, 16 Feb 2020 09:52:06 +0100 Subject: [PATCH 03/59] Fixes type and tags for wohrm --- apps.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps.json b/apps.json index 212ece336..cb98281fc 100644 --- a/apps.json +++ b/apps.json @@ -815,7 +815,8 @@ "icon": "wohrm.png", "version":"0.01", "description": "Workout heart rate monitor notifies you with a buzz if your heart rate goes above or below the set limits.", - "tags": "hrm workout app", + "tags": "hrm,workout,app", + "type": "app", "storage": [ {"name":"+wohrm","url":"wohrm.json"}, {"name":"-wohrm","url":"wohrm.js"}, From 7386330f599165378a1a0a9251f58e56c8ee9a64 Mon Sep 17 00:00:00 2001 From: Markus Deibel Date: Sun, 16 Feb 2020 09:56:01 +0100 Subject: [PATCH 04/59] Allow running in the emulator for wohrm --- apps.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps.json b/apps.json index cb98281fc..ca784bd37 100644 --- a/apps.json +++ b/apps.json @@ -815,8 +815,9 @@ "icon": "wohrm.png", "version":"0.01", "description": "Workout heart rate monitor notifies you with a buzz if your heart rate goes above or below the set limits.", - "tags": "hrm,workout,app", + "tags": "hrm,workout", "type": "app", + "allow_emulator":true, "storage": [ {"name":"+wohrm","url":"wohrm.json"}, {"name":"-wohrm","url":"wohrm.js"}, From f01133bf571abed7082679cf0f36d33be5b7bb2d Mon Sep 17 00:00:00 2001 From: Markus Deibel Date: Mon, 17 Feb 2020 21:54:12 +0100 Subject: [PATCH 05/59] Uses enum for limit setter values --- apps/wohrm/wohrm.js | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/apps/wohrm/wohrm.js b/apps/wohrm/wohrm.js index d5f2c1c03..7d39f5e63 100644 --- a/apps/wohrm/wohrm.js +++ b/apps/wohrm/wohrm.js @@ -1,8 +1,13 @@ +const Setter = { + UPPER: 'upper', + LOWER: 'lower' +}; + upperLimit = 130; lowerLimit = 100; -limitSetter = "lower"; -currentHeartRate = 220; -hrConfidence = 49; +limitSetter = Setter.LOWER; +currentHeartRate = 0; +hrConfidence = -1; function drawTrainingHeartRate() { renderUpperLimit(); @@ -21,7 +26,7 @@ function renderUpperLimit() { g.fillRect(140,40, 230, 70); g.fillRect(200,70, 230, 210); - if(limitSetter === "upper"){ + if(limitSetter === Setter.UPPER){ g.setColor(255,255, 255); g.drawPoly([140,40,230,40,230,210,200,210,200,70,140,70], true); } @@ -44,7 +49,7 @@ function renderLowerLimit() { g.fillRect(10, 180, 100, 210); g.fillRect(10, 40, 40, 180); - if(limitSetter === "lower"){ + if(limitSetter === Setter.LOWER){ g.setColor(255,255, 255); g.drawPoly([10,40,40,40,40,180,100,180,100,210,10,210], true); } @@ -91,21 +96,21 @@ function onHrm(hrm){ } function setLimitSetterToLower() { - limitSetter = "lower"; + limitSetter = Setter.LOWER; console.log("Limit setter is lower"); renderUpperLimit(); renderLowerLimit(); } function setLimitSetterToUpper() { - limitSetter = "upper"; + limitSetter = Setter.UPPER; console.log("Limit setter is upper"); renderLowerLimit(); renderUpperLimit(); } function incrementLimit(){ - if(limitSetter === "upper"){ + if(limitSetter === Setter.UPPER){ upperLimit++; renderUpperLimit(); console.log("Upper limit: " + upperLimit); @@ -117,7 +122,7 @@ function incrementLimit(){ } function decrementLimit(){ - if(limitSetter === "upper"){ + if(limitSetter === Setter.UPPER){ upperLimit--; renderUpperLimit(); console.log("Upper limit: " + upperLimit); @@ -163,4 +168,4 @@ setWatch(decrementLimit, BTN3, {edge:"rising", debounce:50, repeat:true}); setWatch(setLimitSetterToLower, BTN4, {edge:"rising", debounce:50, repeat:true}); -setWatch(setLimitSetterToUpper, BTN5, {edge:"rising", debounce:50, repeat:true}); \ No newline at end of file +setWatch(setLimitSetterToUpper, BTN5, {edge:"rising", debounce:50, repeat:true}); From d3711e6ae9067777a53fb404a6c41a2bce35bd79 Mon Sep 17 00:00:00 2001 From: msdeibel Date: Tue, 18 Feb 2020 21:47:20 +0100 Subject: [PATCH 06/59] Icon renamed. --- apps/wohrm/{app-icon.js => wohrm-icon.js} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename apps/wohrm/{app-icon.js => wohrm-icon.js} (100%) diff --git a/apps/wohrm/app-icon.js b/apps/wohrm/wohrm-icon.js similarity index 100% rename from apps/wohrm/app-icon.js rename to apps/wohrm/wohrm-icon.js From 173d9a2dae7885051ff044ec6399d8aaa96f85f5 Mon Sep 17 00:00:00 2001 From: msdeibel Date: Sun, 1 Mar 2020 12:10:17 +0100 Subject: [PATCH 07/59] Adds rounded corners for upper limit button --- apps/wohrm/.gitignore | 4 ++++ apps/wohrm/wohrm.js | 41 ++++++++++++++++++++++++++++++++++++----- 2 files changed, 40 insertions(+), 5 deletions(-) create mode 100644 apps/wohrm/.gitignore diff --git a/apps/wohrm/.gitignore b/apps/wohrm/.gitignore new file mode 100644 index 000000000..2060ed3f3 --- /dev/null +++ b/apps/wohrm/.gitignore @@ -0,0 +1,4 @@ +/node_modules +/.eslintrc.js +/package.json +/package-lock.json \ No newline at end of file diff --git a/apps/wohrm/wohrm.js b/apps/wohrm/wohrm.js index 7d39f5e63..c30c62eb6 100644 --- a/apps/wohrm/wohrm.js +++ b/apps/wohrm/wohrm.js @@ -1,13 +1,14 @@ +/* eslint-disable no-undef */ const Setter = { UPPER: 'upper', LOWER: 'lower' }; -upperLimit = 130; -lowerLimit = 100; -limitSetter = Setter.LOWER; -currentHeartRate = 0; -hrConfidence = -1; +let upperLimit = 130; +let lowerLimit = 100; +let limitSetter = Setter.LOWER; +let currentHeartRate = 0; +let hrConfidence = -1; function drawTrainingHeartRate() { renderUpperLimit(); @@ -26,6 +27,36 @@ function renderUpperLimit() { g.fillRect(140,40, 230, 70); g.fillRect(200,70, 230, 210); + //Round top left corner + g.setColor(0,0,0); + g.fillRect(140,40, 145, 45); + g.setColor(255,0,0); + g.fillCircle(150,50, 10); + + //Round top right corner + g.setColor(0,0,0); + g.fillRect(225,40, 230, 45); + g.setColor(255,0,0); + g.fillCircle(220,50, 10); + + //Round middle left corner + g.setColor(0,0,0); + g.fillRect(140,65, 145, 70); + g.setColor(255,0,0); + g.fillCircle(150,60, 10); + + //Round bottom left corner + g.setColor(0,0,0); + g.fillRect(200,205, 205, 210); + g.setColor(255,0,0); + g.fillCircle(210,200, 10); + + //Round bottom right corner + g.setColor(0,0,0); + g.fillRect(225,205, 230, 210); + g.setColor(255,0,0); + g.fillCircle(220,200, 10); + if(limitSetter === Setter.UPPER){ g.setColor(255,255, 255); g.drawPoly([140,40,230,40,230,210,200,210,200,70,140,70], true); From 73dc1d0a7306e489d3a3186ea874240b00daf064 Mon Sep 17 00:00:00 2001 From: msdeibel Date: Sun, 1 Mar 2020 21:14:35 +0100 Subject: [PATCH 08/59] UI fixes and code cleanup --- apps/wohrm/wohrm.js | 58 ++++++++++++++++++++------------------------- 1 file changed, 26 insertions(+), 32 deletions(-) diff --git a/apps/wohrm/wohrm.js b/apps/wohrm/wohrm.js index c30c62eb6..2d9553473 100644 --- a/apps/wohrm/wohrm.js +++ b/apps/wohrm/wohrm.js @@ -1,12 +1,16 @@ /* eslint-disable no-undef */ const Setter = { - UPPER: 'upper', - LOWER: 'lower' -}; + NONE: "none", + UPPER: 'upper', + LOWER: 'lower' + }; + +const shortBuzzTimeInMs = 100; +const longBuzzTimeInMs = 200; let upperLimit = 130; let lowerLimit = 100; -let limitSetter = Setter.LOWER; +let limitSetter = Setter.NONE; let currentHeartRate = 0; let hrConfidence = -1; @@ -24,38 +28,28 @@ function drawTrainingHeartRate() { function renderUpperLimit() { g.setColor(255,0,0); - g.fillRect(140,40, 230, 70); - g.fillRect(200,70, 230, 210); + g.fillRect(145,40, 230, 70); + g.fillRect(200,70, 230, 200); - //Round top left corner - g.setColor(0,0,0); - g.fillRect(140,40, 145, 45); + //Round middle left corner g.setColor(255,0,0); - g.fillCircle(150,50, 10); + g.fillEllipse(135,40,155,70); //Round top right corner g.setColor(0,0,0); g.fillRect(225,40, 230, 45); g.setColor(255,0,0); - g.fillCircle(220,50, 10); + g.fillEllipse(210,40,230,50); - //Round middle left corner - g.setColor(0,0,0); - g.fillRect(140,65, 145, 70); + //Round inner corner g.setColor(255,0,0); - g.fillCircle(150,60, 10); - - //Round bottom left corner + g.fillRect(194,71, 199, 76); g.setColor(0,0,0); - g.fillRect(200,205, 205, 210); - g.setColor(255,0,0); - g.fillCircle(210,200, 10); + g.fillEllipse(180,71,199,82); - //Round bottom right corner - g.setColor(0,0,0); - g.fillRect(225,205, 230, 210); + //Round bottom g.setColor(255,0,0); - g.fillCircle(220,200, 10); + g.fillEllipse(200,190, 230, 210); if(limitSetter === Setter.UPPER){ g.setColor(255,255, 255); @@ -68,7 +62,7 @@ function renderUpperLimit() { } function renderCurrentHeartRate() { - g.setColor(0,255,0); + g.setColor(255,255,255); g.fillRect(55, 110, 175, 140); g.setColor(0,0,0); g.setFontVector(13); @@ -109,15 +103,15 @@ function buzz() { if(currentHeartRate > upperLimit) { - Bangle.buzz(70); - setTimeout(() => { Bangle.buzz(70); }, 70); - setTimeout(() => { Bangle.buzz(70); }, 70); + Bangle.buzz(shortBuzzTimeInMs); + setTimeout(() => { Bangle.buzz(shortBuzzTimeInMs); }, shortBuzzTimeInMs); + setTimeout(() => { Bangle.buzz(shortBuzzTimeInMs); }, shortBuzzTimeInMs); } if(currentHeartRate < upperLimit) { - Bangle.buzz(140); - setTimeout(() => { Bangle.buzz(140); }, 140); + Bangle.buzz(longBuzzTimeInMs); + setTimeout(() => { Bangle.buzz(longBuzzTimeInMs); }, longBuzzTimeInMs); } } @@ -165,7 +159,7 @@ function decrementLimit(){ } // Show launcher when middle button pressed -function switchOfWidget(){ +function switchOffApp(){ Bangle.setHRMPower(0); Bangle.showLauncher(); } @@ -191,7 +185,7 @@ Bangle.loadWidgets(); Bangle.drawWidgets(); drawTrainingHeartRate(); -setWatch(switchOfWidget, BTN2, {repeat:false,edge:"falling"}); +setWatch(switchOffApp, BTN2, {repeat:false,edge:"falling"}); setWatch(incrementLimit, BTN1, {edge:"rising", debounce:50, repeat:true}); From 74dc9e5cbcd1ffa7d7e0435a208de8197ce68175 Mon Sep 17 00:00:00 2001 From: msdeibel Date: Sat, 7 Mar 2020 07:18:33 +0100 Subject: [PATCH 09/59] Rounds button corners and adds HW button icons --- apps/wohrm/wohrm.js | 86 +++++++++++++++++++++++++++++++++------------ 1 file changed, 63 insertions(+), 23 deletions(-) diff --git a/apps/wohrm/wohrm.js b/apps/wohrm/wohrm.js index 2d9553473..199fe9261 100644 --- a/apps/wohrm/wohrm.js +++ b/apps/wohrm/wohrm.js @@ -15,6 +15,8 @@ let currentHeartRate = 0; let hrConfidence = -1; function drawTrainingHeartRate() { + renderButtonIcons(); + renderUpperLimit(); renderCurrentHeartRate(); @@ -28,56 +30,76 @@ function drawTrainingHeartRate() { function renderUpperLimit() { g.setColor(255,0,0); - g.fillRect(145,40, 230, 70); - g.fillRect(200,70, 230, 200); + g.fillRect(135,40, 220, 70); + g.fillRect(190,70, 220, 200); - //Round middle left corner + //Round top left corner g.setColor(255,0,0); - g.fillEllipse(135,40,155,70); + g.fillEllipse(125,40,145,70); //Round top right corner g.setColor(0,0,0); - g.fillRect(225,40, 230, 45); + g.fillRect(215,40, 220, 45); g.setColor(255,0,0); - g.fillEllipse(210,40,230,50); + g.fillEllipse(200,40,220,50); //Round inner corner g.setColor(255,0,0); - g.fillRect(194,71, 199, 76); + g.fillRect(184,71, 189, 76); g.setColor(0,0,0); - g.fillEllipse(180,71,199,82); + g.fillEllipse(170,71,189,82); //Round bottom g.setColor(255,0,0); - g.fillEllipse(200,190, 230, 210); + g.fillEllipse(190,190, 220, 210); - if(limitSetter === Setter.UPPER){ - g.setColor(255,255, 255); - g.drawPoly([140,40,230,40,230,210,200,210,200,70,140,70], true); - } + // if(limitSetter === Setter.UPPER){ + // g.setColor(255,255, 255); + // g.drawPoly([140,40,230,40,230,210,200,210,200,70,140,70], false); + // } g.setColor(255,255,255); g.setFontVector(10); - g.drawString("Upper : " + upperLimit, 150,50); + g.drawString("Upper : " + upperLimit, 140,50); } function renderCurrentHeartRate() { g.setColor(255,255,255); - g.fillRect(55, 110, 175, 140); + g.fillRect(45, 110, 165, 140); g.setColor(0,0,0); g.setFontVector(13); - g.drawString("Current: " + currentHeartRate, 75,117); + g.drawString("Current: " + currentHeartRate, 65,117); } function renderLowerLimit() { g.setColor(0,0,255); g.fillRect(10, 180, 100, 210); - g.fillRect(10, 40, 40, 180); + g.fillRect(10, 50, 40, 180); - if(limitSetter === Setter.LOWER){ - g.setColor(255,255, 255); - g.drawPoly([10,40,40,40,40,180,100,180,100,210,10,210], true); - } + //Rounded top + g.setColor(0,0,255); + g.fillEllipse(10,40, 40, 60); + + //Round bottom right corner + g.setColor(0,0,255); + g.fillEllipse(90,180,110,210); + + //Round inner corner + g.setColor(0,0,255); + g.fillRect(40,175,45,180); + g.setColor(0,0,0); + g.fillEllipse(41,170,60,179); + + //Round bottom left corner + g.setColor(0,0,0); + g.fillRect(10,205, 15, 210); + g.setColor(0,0,255); + g.fillEllipse(10,200,30,210); + + // if(limitSetter === Setter.LOWER){ + // g.setColor(255,255, 255); + // g.drawPoly([10,40,40,40,40,180,100,180,100,210,10,210], true); + // } g.setColor(255,255,255); g.setFontVector(10); @@ -95,8 +117,26 @@ function renderConfidenceBars(){ g.setColor(0, 0, 0); } - g.fillRect(55, 110, 65, 140); - g.fillRect(175, 110, 185, 140); + g.fillRect(45, 110, 55, 140); + g.fillRect(165, 110, 175, 140); +} + +function renderButtonIcons() { + g.setColor(255,255,255); + g.setFontVector(14); + + // + for Btn1 + g.drawString("+", 227,50); + + // Home for Btn2 + g.drawLine(225, 118, 232, 110); + g.drawLine(232, 110, 239, 118); + + g.drawPoly([227,117,227,125,237,125,237,117], false); + g.drawRect(231,120,234,125); + + // - for Btn3 + g.drawString("-", 227,190); } function buzz() From 3ea8201714ad166fc801bff36eedd0c4822e88a0 Mon Sep 17 00:00:00 2001 From: msdeibel Date: Sat, 7 Mar 2020 07:33:16 +0100 Subject: [PATCH 10/59] Changes button positioning --- apps/wohrm/wohrm.js | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/apps/wohrm/wohrm.js b/apps/wohrm/wohrm.js index 199fe9261..a32fded30 100644 --- a/apps/wohrm/wohrm.js +++ b/apps/wohrm/wohrm.js @@ -30,28 +30,28 @@ function drawTrainingHeartRate() { function renderUpperLimit() { g.setColor(255,0,0); - g.fillRect(135,40, 220, 70); - g.fillRect(190,70, 220, 200); + g.fillRect(125,40, 210, 70); + g.fillRect(180,70, 210, 200); //Round top left corner g.setColor(255,0,0); - g.fillEllipse(125,40,145,70); + g.fillEllipse(115,40,135,70); //Round top right corner g.setColor(0,0,0); - g.fillRect(215,40, 220, 45); + g.fillRect(205,40, 210, 45); g.setColor(255,0,0); - g.fillEllipse(200,40,220,50); + g.fillEllipse(190,40,210,50); //Round inner corner g.setColor(255,0,0); - g.fillRect(184,71, 189, 76); + g.fillRect(174,71, 179, 76); g.setColor(0,0,0); - g.fillEllipse(170,71,189,82); + g.fillEllipse(160,71,179,82); //Round bottom g.setColor(255,0,0); - g.fillEllipse(190,190, 220, 210); + g.fillEllipse(180,190, 210, 210); // if(limitSetter === Setter.UPPER){ // g.setColor(255,255, 255); @@ -60,7 +60,7 @@ function renderUpperLimit() { g.setColor(255,255,255); g.setFontVector(10); - g.drawString("Upper : " + upperLimit, 140,50); + g.drawString("Upper : " + upperLimit, 130,50); } function renderCurrentHeartRate() { @@ -114,7 +114,7 @@ function renderConfidenceBars(){ } else if(hrConfidence >= 0){ g.setColor(255, 0, 0); } else { - g.setColor(0, 0, 0); + g.setColor(255, 255, 0); } g.fillRect(45, 110, 55, 140); @@ -126,17 +126,17 @@ function renderButtonIcons() { g.setFontVector(14); // + for Btn1 - g.drawString("+", 227,50); + g.drawString("+", 222,50); // Home for Btn2 - g.drawLine(225, 118, 232, 110); - g.drawLine(232, 110, 239, 118); + g.drawLine(220, 118, 227, 110); + g.drawLine(227, 110, 234, 118); - g.drawPoly([227,117,227,125,237,125,237,117], false); - g.drawRect(231,120,234,125); + g.drawPoly([222,117,222,125,232,125,232,117], false); + g.drawRect(226,120,229,125); // - for Btn3 - g.drawString("-", 227,190); + g.drawString("-", 222,165); } function buzz() From 79e70fc023d5c9f49711eed486640178f7e3c92e Mon Sep 17 00:00:00 2001 From: msdeibel Date: Sat, 7 Mar 2020 07:35:20 +0100 Subject: [PATCH 11/59] Fixes initial color for confidence bars --- apps/wohrm/wohrm.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/wohrm/wohrm.js b/apps/wohrm/wohrm.js index a32fded30..306824c79 100644 --- a/apps/wohrm/wohrm.js +++ b/apps/wohrm/wohrm.js @@ -114,7 +114,7 @@ function renderConfidenceBars(){ } else if(hrConfidence >= 0){ g.setColor(255, 0, 0); } else { - g.setColor(255, 255, 0); + g.setColor(255, 255, 255); } g.fillRect(45, 110, 55, 140); From f740b4f57751343500ec85fd61e5fc951d3e7e75 Mon Sep 17 00:00:00 2001 From: msdeibel Date: Sun, 8 Mar 2020 09:32:20 +0100 Subject: [PATCH 12/59] Improves UX for highlighting the selected limit --- apps/wohrm/wohrm.js | 341 ++++++++++++++++++++++++-------------------- 1 file changed, 183 insertions(+), 158 deletions(-) diff --git a/apps/wohrm/wohrm.js b/apps/wohrm/wohrm.js index 306824c79..e4d31cb27 100644 --- a/apps/wohrm/wohrm.js +++ b/apps/wohrm/wohrm.js @@ -3,8 +3,8 @@ const Setter = { NONE: "none", UPPER: 'upper', LOWER: 'lower' - }; - +}; + const shortBuzzTimeInMs = 100; const longBuzzTimeInMs = 200; @@ -14,223 +14,248 @@ let limitSetter = Setter.NONE; let currentHeartRate = 0; let hrConfidence = -1; +let setterHighlightTimeout; + function drawTrainingHeartRate() { - renderButtonIcons(); - - renderUpperLimit(); - - renderCurrentHeartRate(); - - renderLowerLimit(); - - renderConfidenceBars(); - - buzz(); + renderButtonIcons(); + + renderUpperLimit(); + + renderCurrentHeartRate(); + + renderLowerLimit(); + + renderConfidenceBars(); + + buzz(); } function renderUpperLimit() { - g.setColor(255,0,0); - g.fillRect(125,40, 210, 70); - g.fillRect(180,70, 210, 200); + g.setColor(255,0,0); + g.fillRect(125,40, 210, 70); + g.fillRect(180,70, 210, 200); - //Round top left corner - g.setColor(255,0,0); - g.fillEllipse(115,40,135,70); + //Round top left corner + g.fillEllipse(115,40,135,70); - //Round top right corner - g.setColor(0,0,0); - g.fillRect(205,40, 210, 45); - g.setColor(255,0,0); - g.fillEllipse(190,40,210,50); + //Round top right corner + g.setColor(0,0,0); + g.fillRect(205,40, 210, 45); + g.setColor(255,0,0); + g.fillEllipse(190,40,210,50); - //Round inner corner - g.setColor(255,0,0); - g.fillRect(174,71, 179, 76); - g.setColor(0,0,0); - g.fillEllipse(160,71,179,82); + //Round inner corner + g.fillRect(174,71, 179, 76); + g.setColor(0,0,0); + g.fillEllipse(160,71,179,82); - //Round bottom - g.setColor(255,0,0); - g.fillEllipse(180,190, 210, 210); - - // if(limitSetter === Setter.UPPER){ - // g.setColor(255,255, 255); - // g.drawPoly([140,40,230,40,230,210,200,210,200,70,140,70], false); - // } + //Round bottom + g.setColor(255,0,0); + g.fillEllipse(180,190, 210, 210); + if(limitSetter === Setter.UPPER){ + g.setColor(255,255, 0); + } else { g.setColor(255,255,255); - g.setFontVector(10); - g.drawString("Upper : " + upperLimit, 130,50); + } + g.setFontVector(10); + g.drawString("Upper : " + upperLimit, 130,50); } - -function renderCurrentHeartRate() { - g.setColor(255,255,255); - g.fillRect(45, 110, 165, 140); - g.setColor(0,0,0); - g.setFontVector(13); - g.drawString("Current: " + currentHeartRate, 65,117); -} - -function renderLowerLimit() { - g.setColor(0,0,255); - g.fillRect(10, 180, 100, 210); - g.fillRect(10, 50, 40, 180); - - //Rounded top - g.setColor(0,0,255); - g.fillEllipse(10,40, 40, 60); - - //Round bottom right corner - g.setColor(0,0,255); - g.fillEllipse(90,180,110,210); - - //Round inner corner - g.setColor(0,0,255); - g.fillRect(40,175,45,180); - g.setColor(0,0,0); - g.fillEllipse(41,170,60,179); - //Round bottom left corner - g.setColor(0,0,0); - g.fillRect(10,205, 15, 210); - g.setColor(0,0,255); - g.fillEllipse(10,200,30,210); +function renderCurrentHeartRate() { + g.setColor(255,255,255); + g.fillRect(45, 110, 165, 140); + g.setColor(0,0,0); + g.setFontVector(13); - // if(limitSetter === Setter.LOWER){ - // g.setColor(255,255, 255); - // g.drawPoly([10,40,40,40,40,180,100,180,100,210,10,210], true); - // } + g.drawString("Current:" , 65,117); + g.setFontAlign(1, -1, 0); + g.drawString(currentHeartRate, 155, 117); + //Reset alignment to defaults + g.setFontAlign(-1, -1, 0); +} + +function renderLowerLimit() { + g.setColor(0,0,255); + g.fillRect(10, 180, 100, 210); + g.fillRect(10, 50, 40, 180); + + //Rounded top + g.setColor(0,0,255); + g.fillEllipse(10,40, 40, 60); + + //Round bottom right corner + g.setColor(0,0,255); + g.fillEllipse(90,180,110,210); + + //Round inner corner + g.setColor(0,0,255); + g.fillRect(40,175,45,180); + g.setColor(0,0,0); + g.fillEllipse(41,170,60,179); + + //Round bottom left corner + g.setColor(0,0,0); + g.fillRect(10,205, 15, 210); + g.setColor(0,0,255); + g.fillEllipse(10,200,30,210); + + if(limitSetter === Setter.LOWER){ + g.setColor(255,255, 0); + } else { g.setColor(255,255,255); - g.setFontVector(10); - g.drawString("Lower : " + lowerLimit, 20,190); + } + g.setFontVector(10); + g.drawString("Lower : " + lowerLimit, 20,190); } - + function renderConfidenceBars(){ - if(hrConfidence >= 85){ - g.setColor(0, 255, 0); - } else if (hrConfidence >= 50) { - g.setColor(255, 255, 0); - } else if(hrConfidence >= 0){ - g.setColor(255, 0, 0); - } else { - g.setColor(255, 255, 255); - } + if(hrConfidence >= 85){ + g.setColor(0, 255, 0); + } else if (hrConfidence >= 50) { + g.setColor(255, 255, 0); + } else if(hrConfidence >= 0){ + g.setColor(255, 0, 0); + } else { + g.setColor(255, 255, 255); + } - g.fillRect(45, 110, 55, 140); - g.fillRect(165, 110, 175, 140); + g.fillRect(45, 110, 55, 140); + g.fillRect(165, 110, 175, 140); } - + function renderButtonIcons() { g.setColor(255,255,255); g.setFontVector(14); - + // + for Btn1 g.drawString("+", 222,50); - + // Home for Btn2 g.drawLine(220, 118, 227, 110); g.drawLine(227, 110, 234, 118); - + g.drawPoly([222,117,222,125,232,125,232,117], false); g.drawRect(226,120,229,125); - + // - for Btn3 g.drawString("-", 222,165); } - + function buzz() { - if(currentHeartRate > upperLimit) - { - Bangle.buzz(shortBuzzTimeInMs); - setTimeout(() => { Bangle.buzz(shortBuzzTimeInMs); }, shortBuzzTimeInMs); - setTimeout(() => { Bangle.buzz(shortBuzzTimeInMs); }, shortBuzzTimeInMs); - } + if(currentHeartRate > upperLimit) + { + Bangle.buzz(shortBuzzTimeInMs); + setTimeout(() => { Bangle.buzz(shortBuzzTimeInMs); }, shortBuzzTimeInMs); + setTimeout(() => { Bangle.buzz(shortBuzzTimeInMs); }, shortBuzzTimeInMs); + } - if(currentHeartRate < upperLimit) - { - Bangle.buzz(longBuzzTimeInMs); - setTimeout(() => { Bangle.buzz(longBuzzTimeInMs); }, longBuzzTimeInMs); - } + if(currentHeartRate < upperLimit) + { + Bangle.buzz(longBuzzTimeInMs); + setTimeout(() => { Bangle.buzz(longBuzzTimeInMs); }, longBuzzTimeInMs); + } } - + function onHrm(hrm){ - currentHeartRate = hrm.bpm; - hrConfidence = hrm.confidence; + currentHeartRate = hrm.bpm; + hrConfidence = hrm.confidence; } - + function setLimitSetterToLower() { - limitSetter = Setter.LOWER; - console.log("Limit setter is lower"); - renderUpperLimit(); - renderLowerLimit(); -} + resetHighlightTimeout(); + limitSetter = Setter.LOWER; + console.log("Limit setter is lower"); + renderUpperLimit(); + renderLowerLimit(); +} + function setLimitSetterToUpper() { - limitSetter = Setter.UPPER; - console.log("Limit setter is upper"); - renderLowerLimit(); - renderUpperLimit(); -} + resetHighlightTimeout(); + limitSetter = Setter.UPPER; + console.log("Limit setter is upper"); + renderLowerLimit(); + renderUpperLimit(); +} + +function setLimitSetterToNone() { + limitSetter = Setter.NONE; + console.log("Limit setter is none"); + renderLowerLimit(); + renderUpperLimit(); +} + function incrementLimit(){ - if(limitSetter === Setter.UPPER){ - upperLimit++; - renderUpperLimit(); - console.log("Upper limit: " + upperLimit); - } else { - lowerLimit++; - renderLowerLimit(); - console.log("Lower limit: " + lowerLimit); - } -} + resetHighlightTimeout(); + if (limitSetter === Setter.UPPER) { + upperLimit++; + renderUpperLimit(); + console.log("Upper limit: " + upperLimit); + } else if(limitSetter === Setter.LOWER) { + lowerLimit++; + renderLowerLimit(); + console.log("Lower limit: " + lowerLimit); + } +} + function decrementLimit(){ - if(limitSetter === Setter.UPPER){ - upperLimit--; - renderUpperLimit(); - console.log("Upper limit: " + upperLimit); - } else { - lowerLimit--; - renderLowerLimit(); - console.log("Lower limit: " + lowerLimit); - } -} + resetHighlightTimeout(); + if (limitSetter === Setter.UPPER) { + upperLimit--; + renderUpperLimit(); + console.log("Upper limit: " + upperLimit); + } else if(limitSetter === Setter.LOWER) { + lowerLimit--; + renderLowerLimit(); + console.log("Lower limit: " + lowerLimit); + } +} + +function resetHighlightTimeout() { + if(setterHiglightTimeout !== undefined) + clearTimeout(setterHighlightTimeout); + setterHighlightTimeout = setTimeout(setLimitSetterToNone, 5000); +} + // Show launcher when middle button pressed function switchOffApp(){ - Bangle.setHRMPower(0); - Bangle.showLauncher(); + Bangle.setHRMPower(0); + Bangle.showLauncher(); } - + // special function to handle display switch on Bangle.on('lcdPower', (on) => { - g.clear(); - if (on) { - Bangle.drawWidgets(); - // call your app function here - drawTrainingHeartRate(); - } + g.clear(); + if (on) { + Bangle.drawWidgets(); + // call your app function here + drawTrainingHeartRate(); + } }); - + Bangle.setHRMPower(1); Bangle.on('HRM', onHrm); - + // refesh every sec setInterval(drawTrainingHeartRate, 1000); - + g.clear(); Bangle.loadWidgets(); Bangle.drawWidgets(); drawTrainingHeartRate(); - + setWatch(switchOffApp, BTN2, {repeat:false,edge:"falling"}); - + setWatch(incrementLimit, BTN1, {edge:"rising", debounce:50, repeat:true}); - + setWatch(decrementLimit, BTN3, {edge:"rising", debounce:50, repeat:true}); - + setWatch(setLimitSetterToLower, BTN4, {edge:"rising", debounce:50, repeat:true}); - -setWatch(setLimitSetterToUpper, BTN5, {edge:"rising", debounce:50, repeat:true}); + +setWatch(setLimitSetterToUpper, BTN5, { edge: "rising", debounce: 50, repeat: true }); From 054a0c2142c64409787625221b1ef6693df311f3 Mon Sep 17 00:00:00 2001 From: msdeibel Date: Sun, 8 Mar 2020 09:36:19 +0100 Subject: [PATCH 13/59] Fixes resetHighlightTimeout method --- apps/wohrm/wohrm.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/wohrm/wohrm.js b/apps/wohrm/wohrm.js index e4d31cb27..f37483910 100644 --- a/apps/wohrm/wohrm.js +++ b/apps/wohrm/wohrm.js @@ -218,9 +218,11 @@ function decrementLimit(){ } function resetHighlightTimeout() { - if(setterHiglightTimeout !== undefined) + if (setterHighlightTimeout) { clearTimeout(setterHighlightTimeout); - setterHighlightTimeout = setTimeout(setLimitSetterToNone, 5000); + } + + setterHighlightTimeout = setTimeout(setLimitSetterToNone, 2000); } // Show launcher when middle button pressed From cf64c1c2c088c29ca2f80126dbde6d87ed5d5a95 Mon Sep 17 00:00:00 2001 From: msdeibel Date: Tue, 24 Mar 2020 17:27:13 +0100 Subject: [PATCH 14/59] Adapt to new code layout --- apps.json | 8 ++++---- apps/wohrm/ChangeLog | 1 + apps/wohrm/{wohrm-icon.js => app-icon.js} | 0 apps/wohrm/{wohrm.js => app.js} | 0 apps/wohrm/{wohrm.png => app.png} | Bin 5 files changed, 5 insertions(+), 4 deletions(-) rename apps/wohrm/{wohrm-icon.js => app-icon.js} (100%) rename apps/wohrm/{wohrm.js => app.js} (100%) rename apps/wohrm/{wohrm.png => app.png} (100%) diff --git a/apps.json b/apps.json index 3ffdbe5d4..bbc40a7fd 100644 --- a/apps.json +++ b/apps.json @@ -815,15 +815,15 @@ }, { "id": "wohrm", "name": "Workout Heart Rate Monitor", - "icon": "wohrm.png", - "version":"0.01", + "icon": "app.png", + "version":"0.02", "description": "Workout heart rate monitor notifies you with a buzz if your heart rate goes above or below the set limits.", "tags": "hrm,workout", "type": "app", "allow_emulator":true, "storage": [ - {"name":"wohrm.app.js","url":"wohrm.js"}, - {"name":"wohrm.img","url":"wohrm-icon.js","evaluate":true} + {"name":"wohrm.app.js","url":"app.js"}, + {"name":"wohrm.img","url":"app-icon.js","evaluate":true} ] }, { "id": "widid", diff --git a/apps/wohrm/ChangeLog b/apps/wohrm/ChangeLog index bc13085a4..101ac1146 100644 --- a/apps/wohrm/ChangeLog +++ b/apps/wohrm/ChangeLog @@ -1 +1,2 @@ +0.02: Adapted to new App code layout 0.01: Only tested on the emulator. diff --git a/apps/wohrm/wohrm-icon.js b/apps/wohrm/app-icon.js similarity index 100% rename from apps/wohrm/wohrm-icon.js rename to apps/wohrm/app-icon.js diff --git a/apps/wohrm/wohrm.js b/apps/wohrm/app.js similarity index 100% rename from apps/wohrm/wohrm.js rename to apps/wohrm/app.js diff --git a/apps/wohrm/wohrm.png b/apps/wohrm/app.png similarity index 100% rename from apps/wohrm/wohrm.png rename to apps/wohrm/app.png From 83ffb617f26b3857d40fa8481a2b020b06b8888a Mon Sep 17 00:00:00 2001 From: msdeibel Date: Tue, 24 Mar 2020 17:34:27 +0100 Subject: [PATCH 15/59] Energy saving --- apps/wohrm/app.js | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/apps/wohrm/app.js b/apps/wohrm/app.js index f37483910..f6e9baba4 100644 --- a/apps/wohrm/app.js +++ b/apps/wohrm/app.js @@ -17,16 +17,19 @@ let hrConfidence = -1; let setterHighlightTimeout; function drawTrainingHeartRate() { - renderButtonIcons(); - - renderUpperLimit(); - - renderCurrentHeartRate(); - - renderLowerLimit(); - - renderConfidenceBars(); - + //Only redraw if the display is on + if (Bangle.isLCDOn()) { + renderButtonIcons(); + + renderUpperLimit(); + + renderCurrentHeartRate(); + + renderLowerLimit(); + + renderConfidenceBars(); + } + buzz(); } From 08cc44ce9671fd1b7afcf29fbf237a47d6bb6448 Mon Sep 17 00:00:00 2001 From: msdeibel Date: Wed, 25 Mar 2020 18:14:48 +0100 Subject: [PATCH 16/59] Render the background only once --- apps/wohrm/add_to_apps.json | 13 ---- apps/wohrm/app.js | 122 +++++++++++++++++++----------------- apps/wohrm/wohrm.json | 5 -- 3 files changed, 66 insertions(+), 74 deletions(-) delete mode 100644 apps/wohrm/add_to_apps.json delete mode 100644 apps/wohrm/wohrm.json diff --git a/apps/wohrm/add_to_apps.json b/apps/wohrm/add_to_apps.json deleted file mode 100644 index 96ffe838c..000000000 --- a/apps/wohrm/add_to_apps.json +++ /dev/null @@ -1,13 +0,0 @@ -// Create an entry in apps.json as follows: -{ "id": "wohrm", - "name": "Workout Heart Rate Monitor", - "icon": "wohrm.png", - "version":"0.01", - "description": "Workout heart rate monitor notifies you with a buzz if your heart rate goes above or below the set limits.", - "tags": "hrm workout app", - "storage": [ - {"name":"+wohrm","url":"wohrm.json"}, - {"name":"-wohrm","url":"wohrm.js"}, - {"name":"*wohrm","url":"wohrm-icon.js","evaluate":true} - ] -} diff --git a/apps/wohrm/app.js b/apps/wohrm/app.js index f6e9baba4..c80434ae7 100644 --- a/apps/wohrm/app.js +++ b/apps/wohrm/app.js @@ -16,24 +16,7 @@ let hrConfidence = -1; let setterHighlightTimeout; -function drawTrainingHeartRate() { - //Only redraw if the display is on - if (Bangle.isLCDOn()) { - renderButtonIcons(); - - renderUpperLimit(); - - renderCurrentHeartRate(); - - renderLowerLimit(); - - renderConfidenceBars(); - } - - buzz(); -} - -function renderUpperLimit() { +function renderUpperLimitBackground() { g.setColor(255,0,0); g.fillRect(125,40, 210, 70); g.fillRect(180,70, 210, 200); @@ -55,31 +38,16 @@ function renderUpperLimit() { //Round bottom g.setColor(255,0,0); g.fillEllipse(180,190, 210, 210); - - if(limitSetter === Setter.UPPER){ - g.setColor(255,255, 0); - } else { - g.setColor(255,255,255); - } - g.setFontVector(10); - g.drawString("Upper : " + upperLimit, 130,50); } - -function renderCurrentHeartRate() { + +function renderCurrentHearRateBackground() { g.setColor(255,255,255); g.fillRect(45, 110, 165, 140); g.setColor(0,0,0); g.setFontVector(13); - - g.drawString("Current:" , 65,117); - g.setFontAlign(1, -1, 0); - g.drawString(currentHeartRate, 155, 117); - - //Reset alignment to defaults - g.setFontAlign(-1, -1, 0); } - -function renderLowerLimit() { + +function renderLowerLimitBackground() { g.setColor(0,0,255); g.fillRect(10, 180, 100, 210); g.fillRect(10, 50, 40, 180); @@ -103,7 +71,63 @@ function renderLowerLimit() { g.fillRect(10,205, 15, 210); g.setColor(0,0,255); g.fillEllipse(10,200,30,210); +} +function renderButtonIcons() { + g.setColor(255,255,255); + g.setFontVector(14); + + // + for Btn1 + g.drawString("+", 222,50); + + // Home for Btn2 + g.drawLine(220, 118, 227, 110); + g.drawLine(227, 110, 234, 118); + + g.drawPoly([222,117,222,125,232,125,232,117], false); + g.drawRect(226,120,229,125); + + // - for Btn3 + g.drawString("-", 222,165); +} + +function drawTrainingHeartRate() { + //Only redraw if the display is on + if (Bangle.isLCDOn()) { + renderButtonIcons(); + + renderUpperLimit(); + + renderCurrentHeartRate(); + + renderLowerLimit(); + + renderConfidenceBars(); + } + + buzz(); +} + +function renderUpperLimit() { + if(limitSetter === Setter.UPPER){ + g.setColor(255,255, 0); + } else { + g.setColor(255,255,255); + } + g.setFontVector(10); + g.drawString("Upper : " + upperLimit, 130,50); +} + +function renderCurrentHeartRate() { + g.drawString("Current:" , 65,117); + g.setFontAlign(1, -1, 0); + g.drawString(currentHeartRate, 155, 117); + + //Reset alignment to defaults + g.setFontAlign(-1, -1, 0); +} + +function renderLowerLimit() { if(limitSetter === Setter.LOWER){ g.setColor(255,255, 0); } else { @@ -128,24 +152,6 @@ function renderConfidenceBars(){ g.fillRect(165, 110, 175, 140); } -function renderButtonIcons() { - g.setColor(255,255,255); - g.setFontVector(14); - - // + for Btn1 - g.drawString("+", 222,50); - - // Home for Btn2 - g.drawLine(220, 118, 227, 110); - g.drawLine(227, 110, 234, 118); - - g.drawPoly([222,117,222,125,232,125,232,117], false); - g.drawRect(226,120,229,125); - - // - for Btn3 - g.drawString("-", 222,165); -} - function buzz() { if(currentHeartRate > upperLimit) @@ -253,7 +259,11 @@ setInterval(drawTrainingHeartRate, 1000); g.clear(); Bangle.loadWidgets(); Bangle.drawWidgets(); -drawTrainingHeartRate(); + +renderLowerLimitBackground()); +renderCurrentHearRateBackground(); +renderUpperLimitBackground(); +renderButtonIcons(); setWatch(switchOffApp, BTN2, {repeat:false,edge:"falling"}); diff --git a/apps/wohrm/wohrm.json b/apps/wohrm/wohrm.json deleted file mode 100644 index 9b212bfd4..000000000 --- a/apps/wohrm/wohrm.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "name":"Workout HRM", - "icon":"*wohrm", - "src":"-wohrm" -} From 1d3248882cd97deb1194febb830514e7f5e3902a Mon Sep 17 00:00:00 2001 From: msdeibel Date: Wed, 25 Mar 2020 18:16:37 +0100 Subject: [PATCH 17/59] Changelog updated --- apps/wohrm/ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/wohrm/ChangeLog b/apps/wohrm/ChangeLog index 101ac1146..36c08b9fd 100644 --- a/apps/wohrm/ChangeLog +++ b/apps/wohrm/ChangeLog @@ -1,2 +1,3 @@ +0.03: Optimized rendering for the background 0.02: Adapted to new App code layout 0.01: Only tested on the emulator. From 1d339c825c443e7c0c15f28e0a82ad9c79adf5c2 Mon Sep 17 00:00:00 2001 From: msdeibel Date: Wed, 25 Mar 2020 18:36:45 +0100 Subject: [PATCH 18/59] Typo --- apps/wohrm/app.js | 52 +++++++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/apps/wohrm/app.js b/apps/wohrm/app.js index c80434ae7..30f872066 100644 --- a/apps/wohrm/app.js +++ b/apps/wohrm/app.js @@ -17,7 +17,7 @@ let hrConfidence = -1; let setterHighlightTimeout; function renderUpperLimitBackground() { - g.setColor(255,0,0); + g.setColor(1,0,0); g.fillRect(125,40, 210, 70); g.fillRect(180,70, 210, 200); @@ -27,7 +27,7 @@ function renderUpperLimitBackground() { //Round top right corner g.setColor(0,0,0); g.fillRect(205,40, 210, 45); - g.setColor(255,0,0); + g.setColor(1,0,0); g.fillEllipse(190,40,210,50); //Round inner corner @@ -36,32 +36,33 @@ function renderUpperLimitBackground() { g.fillEllipse(160,71,179,82); //Round bottom - g.setColor(255,0,0); + g.setColor(1,0,0); g.fillEllipse(180,190, 210, 210); } function renderCurrentHearRateBackground() { - g.setColor(255,255,255); + g.setColor(1,1,1); g.fillRect(45, 110, 165, 140); g.setColor(0,0,0); g.setFontVector(13); + g.drawString("Current:" , 65,117); } function renderLowerLimitBackground() { - g.setColor(0,0,255); + g.setColor(0,0,1); g.fillRect(10, 180, 100, 210); g.fillRect(10, 50, 40, 180); //Rounded top - g.setColor(0,0,255); + g.setColor(0,0,1); g.fillEllipse(10,40, 40, 60); //Round bottom right corner - g.setColor(0,0,255); + g.setColor(0,0,1); g.fillEllipse(90,180,110,210); //Round inner corner - g.setColor(0,0,255); + g.setColor(0,0,1); g.fillRect(40,175,45,180); g.setColor(0,0,0); g.fillEllipse(41,170,60,179); @@ -69,12 +70,12 @@ function renderLowerLimitBackground() { //Round bottom left corner g.setColor(0,0,0); g.fillRect(10,205, 15, 210); - g.setColor(0,0,255); + g.setColor(0,0,1); g.fillEllipse(10,200,30,210); } function renderButtonIcons() { - g.setColor(255,255,255); + g.setColor(1,1,1); g.setFontVector(14); // + for Btn1 @@ -88,14 +89,12 @@ function renderButtonIcons() { g.drawRect(226,120,229,125); // - for Btn3 - g.drawString("-", 222,165); + g.drawString("-", 222,170); } function drawTrainingHeartRate() { //Only redraw if the display is on if (Bangle.isLCDOn()) { - renderButtonIcons(); - renderUpperLimit(); renderCurrentHeartRate(); @@ -110,16 +109,17 @@ function drawTrainingHeartRate() { function renderUpperLimit() { if(limitSetter === Setter.UPPER){ - g.setColor(255,255, 0); + g.setColor(1, 1, 0); } else { - g.setColor(255,255,255); + g.setColor(1, 1, 1); } + g.setFontVector(10); - g.drawString("Upper : " + upperLimit, 130,50); + g.drawString("Upper : " + upperLimit, 130,50); } function renderCurrentHeartRate() { - g.drawString("Current:" , 65,117); + g.setFontVector(13); g.setFontAlign(1, -1, 0); g.drawString(currentHeartRate, 155, 117); @@ -246,21 +246,19 @@ Bangle.on('lcdPower', (on) => { if (on) { Bangle.drawWidgets(); // call your app function here + renderLowerLimitBackground(); + renderCurrentHearRateBackground(); + renderUpperLimitBackground(); + renderButtonIcons(); drawTrainingHeartRate(); } }); -Bangle.setHRMPower(1); -Bangle.on('HRM', onHrm); - -// refesh every sec -setInterval(drawTrainingHeartRate, 1000); - g.clear(); Bangle.loadWidgets(); Bangle.drawWidgets(); -renderLowerLimitBackground()); +renderLowerLimitBackground(); renderCurrentHearRateBackground(); renderUpperLimitBackground(); renderButtonIcons(); @@ -274,3 +272,9 @@ setWatch(decrementLimit, BTN3, {edge:"rising", debounce:50, repeat:true}); setWatch(setLimitSetterToLower, BTN4, {edge:"rising", debounce:50, repeat:true}); setWatch(setLimitSetterToUpper, BTN5, { edge: "rising", debounce: 50, repeat: true }); + +Bangle.setHRMPower(1); +Bangle.on('HRM', onHrm); + +// refesh every sec +setInterval(drawTrainingHeartRate, 1000); \ No newline at end of file From 8427b492ee05c2aae14f906f88cd3861bbde3958 Mon Sep 17 00:00:00 2001 From: msdeibel Date: Wed, 25 Mar 2020 18:39:42 +0100 Subject: [PATCH 19/59] Wohrm version updated --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index bbc40a7fd..28403787f 100644 --- a/apps.json +++ b/apps.json @@ -829,7 +829,7 @@ { "id": "widid", "name": "Bluetooth ID Widget", "icon": "widget.png", - "version":"0.02", + "version":"0.03", "description": "Display the last two tuple of your Bangle.js MAC address in the widget section. This is useful for figuring out which Bangle.js to connect to if you have more than one Bangle.js!", "tags": "widget,address,mac", "type":"widget", From 84f56faadfd8acdbb49acb5d2085d573447db4c6 Mon Sep 17 00:00:00 2001 From: msdeibel Date: Wed, 25 Mar 2020 18:42:43 +0100 Subject: [PATCH 20/59] Fixed version for widid after errneous edit --- apps.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps.json b/apps.json index 28403787f..ba72123c9 100644 --- a/apps.json +++ b/apps.json @@ -816,7 +816,7 @@ { "id": "wohrm", "name": "Workout Heart Rate Monitor", "icon": "app.png", - "version":"0.02", + "version":"0.03", "description": "Workout heart rate monitor notifies you with a buzz if your heart rate goes above or below the set limits.", "tags": "hrm,workout", "type": "app", @@ -829,7 +829,7 @@ { "id": "widid", "name": "Bluetooth ID Widget", "icon": "widget.png", - "version":"0.03", + "version":"0.02", "description": "Display the last two tuple of your Bangle.js MAC address in the widget section. This is useful for figuring out which Bangle.js to connect to if you have more than one Bangle.js!", "tags": "widget,address,mac", "type":"widget", From e799dfd2061d430da73c75dc33b11a09cf830717 Mon Sep 17 00:00:00 2001 From: Markus Deibel Date: Fri, 27 Mar 2020 06:23:43 +0100 Subject: [PATCH 21/59] Slight improvements to rendering --- apps/wohrm/app.js | 238 +++++++++++++++++++++++++--------------------- 1 file changed, 128 insertions(+), 110 deletions(-) diff --git a/apps/wohrm/app.js b/apps/wohrm/app.js index 30f872066..5a9264f0b 100644 --- a/apps/wohrm/app.js +++ b/apps/wohrm/app.js @@ -5,96 +5,29 @@ const Setter = { LOWER: 'lower' }; -const shortBuzzTimeInMs = 100; +const shortBuzzTimeInMs = 50; const longBuzzTimeInMs = 200; -let upperLimit = 130; -let lowerLimit = 100; +let upperLimit = 90; +let upperLimitChanged = true; + +let lowerLimit = 50; +let lowerLimitChanged = true; + let limitSetter = Setter.NONE; + let currentHeartRate = 0; let hrConfidence = -1; +let hrOrConfidenceChanged = true; + let setterHighlightTimeout; -function renderUpperLimitBackground() { - g.setColor(1,0,0); - g.fillRect(125,40, 210, 70); - g.fillRect(180,70, 210, 200); - - //Round top left corner - g.fillEllipse(115,40,135,70); - - //Round top right corner - g.setColor(0,0,0); - g.fillRect(205,40, 210, 45); - g.setColor(1,0,0); - g.fillEllipse(190,40,210,50); - - //Round inner corner - g.fillRect(174,71, 179, 76); - g.setColor(0,0,0); - g.fillEllipse(160,71,179,82); - - //Round bottom - g.setColor(1,0,0); - g.fillEllipse(180,190, 210, 210); -} - -function renderCurrentHearRateBackground() { - g.setColor(1,1,1); - g.fillRect(45, 110, 165, 140); - g.setColor(0,0,0); - g.setFontVector(13); - g.drawString("Current:" , 65,117); -} - -function renderLowerLimitBackground() { - g.setColor(0,0,1); - g.fillRect(10, 180, 100, 210); - g.fillRect(10, 50, 40, 180); - - //Rounded top - g.setColor(0,0,1); - g.fillEllipse(10,40, 40, 60); - - //Round bottom right corner - g.setColor(0,0,1); - g.fillEllipse(90,180,110,210); - - //Round inner corner - g.setColor(0,0,1); - g.fillRect(40,175,45,180); - g.setColor(0,0,0); - g.fillEllipse(41,170,60,179); - - //Round bottom left corner - g.setColor(0,0,0); - g.fillRect(10,205, 15, 210); - g.setColor(0,0,1); - g.fillEllipse(10,200,30,210); -} - -function renderButtonIcons() { - g.setColor(1,1,1); - g.setFontVector(14); - - // + for Btn1 - g.drawString("+", 222,50); - - // Home for Btn2 - g.drawLine(220, 118, 227, 110); - g.drawLine(227, 110, 234, 118); - - g.drawPoly([222,117,222,125,232,125,232,117], false); - g.drawRect(226,120,229,125); - - // - for Btn3 - g.drawString("-", 222,170); -} - function drawTrainingHeartRate() { //Only redraw if the display is on if (Bangle.isLCDOn()) { + renderButtonIcons(); + renderUpperLimit(); renderCurrentHeartRate(); @@ -108,18 +41,50 @@ function drawTrainingHeartRate() { } function renderUpperLimit() { - if(limitSetter === Setter.UPPER){ - g.setColor(1, 1, 0); - } else { - g.setColor(1, 1, 1); - } + if(!upperLimitChanged) { return; } + + g.setColor(255,0,0); + g.fillRect(125,40, 210, 70); + g.fillRect(180,70, 210, 200); + //Round top left corner + g.fillEllipse(115,40,135,70); + + //Round top right corner + g.setColor(0,0,0); + g.fillRect(205,40, 210, 45); + g.setColor(255,0,0); + g.fillEllipse(190,40,210,50); + + //Round inner corner + g.fillRect(174,71, 179, 76); + g.setColor(0,0,0); + g.fillEllipse(160,71,179,82); + + //Round bottom + g.setColor(255,0,0); + g.fillEllipse(180,190, 210, 210); + + if(limitSetter === Setter.UPPER){ + g.setColor(255,255, 0); + } else { + g.setColor(255,255,255); + } g.setFontVector(10); - g.drawString("Upper : " + upperLimit, 130,50); + g.drawString("Upper : " + upperLimit, 130,50); + + upperLimitChanged = false; } function renderCurrentHeartRate() { + if(!hrOrConfidenceChanged) { return; } + + g.setColor(255,255,255); + g.fillRect(45, 110, 165, 140); + g.setColor(0,0,0); g.setFontVector(13); + + g.drawString("Current:" , 65,117); g.setFontAlign(1, -1, 0); g.drawString(currentHeartRate, 155, 117); @@ -128,6 +93,32 @@ function renderCurrentHeartRate() { } function renderLowerLimit() { + if(!lowerLimitChanged) { return; } + + g.setColor(0,0,255); + g.fillRect(10, 180, 100, 210); + g.fillRect(10, 50, 40, 180); + + //Rounded top + g.setColor(0,0,255); + g.fillEllipse(10,40, 40, 60); + + //Round bottom right corner + g.setColor(0,0,255); + g.fillEllipse(90,180,110,210); + + //Round inner corner + g.setColor(0,0,255); + g.fillRect(40,175,45,180); + g.setColor(0,0,0); + g.fillEllipse(41,170,60,179); + + //Round bottom left corner + g.setColor(0,0,0); + g.fillRect(10,205, 15, 210); + g.setColor(0,0,255); + g.fillEllipse(10,200,30,210); + if(limitSetter === Setter.LOWER){ g.setColor(255,255, 0); } else { @@ -135,9 +126,13 @@ function renderLowerLimit() { } g.setFontVector(10); g.drawString("Lower : " + lowerLimit, 20,190); + + lowerLimitChanged = false; } function renderConfidenceBars(){ + if(!hrOrConfidenceChanged) { return; } + if(hrConfidence >= 85){ g.setColor(0, 255, 0); } else if (hrConfidence >= 50) { @@ -152,6 +147,24 @@ function renderConfidenceBars(){ g.fillRect(165, 110, 175, 140); } +function renderButtonIcons() { + g.setColor(255,255,255); + g.setFontVector(14); + + // + for Btn1 + g.drawString("+", 222,50); + + // Home for Btn2 + g.drawLine(220, 118, 227, 110); + g.drawLine(227, 110, 234, 118); + + g.drawPoly([222,117,222,125,232,125,232,117], false); + g.drawRect(226,120,229,125); + + // - for Btn3 + g.drawString("-", 222,165); +} + function buzz() { if(currentHeartRate > upperLimit) @@ -161,7 +174,7 @@ function buzz() setTimeout(() => { Bangle.buzz(shortBuzzTimeInMs); }, shortBuzzTimeInMs); } - if(currentHeartRate < upperLimit) + if(currentHeartRate < lowerLimit) { Bangle.buzz(longBuzzTimeInMs); setTimeout(() => { Bangle.buzz(longBuzzTimeInMs); }, longBuzzTimeInMs); @@ -169,6 +182,7 @@ function buzz() } function onHrm(hrm){ + hrOrConfidenceChanged = (currentHeartRate !== hrm.bpm || hrConfidence !== hrm.confidence); currentHeartRate = hrm.bpm; hrConfidence = hrm.confidence; } @@ -178,6 +192,10 @@ function setLimitSetterToLower() { limitSetter = Setter.LOWER; console.log("Limit setter is lower"); + + upperLimitChanged = true; + lowerLimitChanged = true; + renderUpperLimit(); renderLowerLimit(); } @@ -187,6 +205,10 @@ function setLimitSetterToUpper() { limitSetter = Setter.UPPER; console.log("Limit setter is upper"); + + upperLimitChanged = true; + lowerLimitChanged = true; + renderLowerLimit(); renderUpperLimit(); } @@ -194,6 +216,10 @@ function setLimitSetterToUpper() { function setLimitSetterToNone() { limitSetter = Setter.NONE; console.log("Limit setter is none"); + + upperLimitChanged = true; + lowerLimitChanged = true; + renderLowerLimit(); renderUpperLimit(); } @@ -205,10 +231,12 @@ function incrementLimit(){ upperLimit++; renderUpperLimit(); console.log("Upper limit: " + upperLimit); + upperLimitChanged = true; } else if(limitSetter === Setter.LOWER) { lowerLimit++; renderLowerLimit(); console.log("Lower limit: " + lowerLimit); + lowerLimitChanged = true; } } @@ -219,10 +247,12 @@ function decrementLimit(){ upperLimit--; renderUpperLimit(); console.log("Upper limit: " + upperLimit); + upperLimitChanged = true; } else if(limitSetter === Setter.LOWER) { lowerLimit--; renderLowerLimit(); console.log("Lower limit: " + lowerLimit); + lowerLimitChanged = true; } } @@ -246,35 +276,23 @@ Bangle.on('lcdPower', (on) => { if (on) { Bangle.drawWidgets(); // call your app function here - renderLowerLimitBackground(); - renderCurrentHearRateBackground(); - renderUpperLimitBackground(); - renderButtonIcons(); drawTrainingHeartRate(); } }); -g.clear(); -Bangle.loadWidgets(); -Bangle.drawWidgets(); - -renderLowerLimitBackground(); -renderCurrentHearRateBackground(); -renderUpperLimitBackground(); -renderButtonIcons(); - -setWatch(switchOffApp, BTN2, {repeat:false,edge:"falling"}); - -setWatch(incrementLimit, BTN1, {edge:"rising", debounce:50, repeat:true}); - -setWatch(decrementLimit, BTN3, {edge:"rising", debounce:50, repeat:true}); - -setWatch(setLimitSetterToLower, BTN4, {edge:"rising", debounce:50, repeat:true}); - -setWatch(setLimitSetterToUpper, BTN5, { edge: "rising", debounce: 50, repeat: true }); - Bangle.setHRMPower(1); Bangle.on('HRM', onHrm); +setWatch(incrementLimit, BTN1, {edge:"rising", debounce:50, repeat:true}); +setWatch(switchOffApp, BTN2, {repeat:false,edge:"falling"}); +setWatch(decrementLimit, BTN3, {edge:"rising", debounce:50, repeat:true}); +setWatch(setLimitSetterToLower, BTN4, {edge:"rising", debounce:50, repeat:true}); +setWatch(setLimitSetterToUpper, BTN5, { edge: "rising", debounce: 50, repeat: true }); + +g.clear(); +Bangle.loadWidgets(); +Bangle.drawWidgets(); +drawTrainingHeartRate(); + // refesh every sec -setInterval(drawTrainingHeartRate, 1000); \ No newline at end of file +setInterval(drawTrainingHeartRate, 1000); From 1a7fb5d2cc33d2712497ca5525ff34c0e3d94dc6 Mon Sep 17 00:00:00 2001 From: Markus Deibel Date: Fri, 27 Mar 2020 06:49:16 +0100 Subject: [PATCH 22/59] Minor tweaks --- apps/wohrm/app.js | 125 ++++++++++++++++++++++++++-------------------- 1 file changed, 70 insertions(+), 55 deletions(-) diff --git a/apps/wohrm/app.js b/apps/wohrm/app.js index 5a9264f0b..75c51a578 100644 --- a/apps/wohrm/app.js +++ b/apps/wohrm/app.js @@ -23,6 +23,56 @@ let hrOrConfidenceChanged = true; let setterHighlightTimeout; +function renderUpperLimitBackground() { + g.setColor(1,0,0); + g.fillRect(125,40, 210, 70); + g.fillRect(180,70, 210, 200); + + //Round top left corner + g.fillEllipse(115,40,135,70); + + //Round top right corner + g.setColor(0,0,0); + g.fillRect(205,40, 210, 45); + g.setColor(1,0,0); + g.fillEllipse(190,40,210,50); + + //Round inner corner + g.fillRect(174,71, 179, 76); + g.setColor(0,0,0); + g.fillEllipse(160,71,179,82); + + //Round bottom + g.setColor(1,0,0); + g.fillEllipse(180,190, 210, 210); +} + +function renderLowerLimitBackground() { + g.setColor(0,0,1); + g.fillRect(10, 180, 100, 210); + g.fillRect(10, 50, 40, 180); + + //Rounded top + g.setColor(0,0,1); + g.fillEllipse(10,40, 40, 60); + + //Round bottom right corner + g.setColor(0,0,1); + g.fillEllipse(90,180,110,210); + + //Round inner corner + g.setColor(0,0,1); + g.fillRect(40,175,45,180); + g.setColor(0,0,0); + g.fillEllipse(41,170,60,179); + + //Round bottom left corner + g.setColor(0,0,0); + g.fillRect(10,205, 15, 210); + g.setColor(0,0,1); + g.fillEllipse(10,200,30,210); +} + function drawTrainingHeartRate() { //Only redraw if the display is on if (Bangle.isLCDOn()) { @@ -37,40 +87,21 @@ function drawTrainingHeartRate() { renderConfidenceBars(); } - buzz(); + //buzz(); } function renderUpperLimit() { if(!upperLimitChanged) { return; } - g.setColor(255,0,0); + g.setColor(1,0,0); g.fillRect(125,40, 210, 70); - g.fillRect(180,70, 210, 200); - - //Round top left corner - g.fillEllipse(115,40,135,70); - - //Round top right corner - g.setColor(0,0,0); - g.fillRect(205,40, 210, 45); - g.setColor(255,0,0); - g.fillEllipse(190,40,210,50); - - //Round inner corner - g.fillRect(174,71, 179, 76); - g.setColor(0,0,0); - g.fillEllipse(160,71,179,82); - - //Round bottom - g.setColor(255,0,0); - g.fillEllipse(180,190, 210, 210); - + if(limitSetter === Setter.UPPER){ g.setColor(255,255, 0); } else { g.setColor(255,255,255); } - g.setFontVector(10); + g.setFontVector(13); g.drawString("Upper : " + upperLimit, 130,50); upperLimitChanged = false; @@ -80,13 +111,12 @@ function renderCurrentHeartRate() { if(!hrOrConfidenceChanged) { return; } g.setColor(255,255,255); - g.fillRect(45, 110, 165, 140); - g.setColor(0,0,0); - g.setFontVector(13); + g.fillRect(45, 110, 165, 150); - g.drawString("Current:" , 65,117); + g.setColor(0,0,0); + g.setFontVector(24); g.setFontAlign(1, -1, 0); - g.drawString(currentHeartRate, 155, 117); + g.drawString(currentHeartRate, 130, 117); //Reset alignment to defaults g.setFontAlign(-1, -1, 0); @@ -95,36 +125,15 @@ function renderCurrentHeartRate() { function renderLowerLimit() { if(!lowerLimitChanged) { return; } - g.setColor(0,0,255); + g.setColor(0,0,1); g.fillRect(10, 180, 100, 210); - g.fillRect(10, 50, 40, 180); - - //Rounded top - g.setColor(0,0,255); - g.fillEllipse(10,40, 40, 60); - - //Round bottom right corner - g.setColor(0,0,255); - g.fillEllipse(90,180,110,210); - - //Round inner corner - g.setColor(0,0,255); - g.fillRect(40,175,45,180); - g.setColor(0,0,0); - g.fillEllipse(41,170,60,179); - - //Round bottom left corner - g.setColor(0,0,0); - g.fillRect(10,205, 15, 210); - g.setColor(0,0,255); - g.fillEllipse(10,200,30,210); - + if(limitSetter === Setter.LOWER){ g.setColor(255,255, 0); } else { g.setColor(255,255,255); } - g.setFontVector(10); + g.setFontVector(13); g.drawString("Lower : " + lowerLimit, 20,190); lowerLimitChanged = false; @@ -143,8 +152,8 @@ function renderConfidenceBars(){ g.setColor(255, 255, 255); } - g.fillRect(45, 110, 55, 140); - g.fillRect(165, 110, 175, 140); + g.fillRect(45, 110, 55, 150); + g.fillRect(165, 110, 175, 150); } function renderButtonIcons() { @@ -276,6 +285,10 @@ Bangle.on('lcdPower', (on) => { if (on) { Bangle.drawWidgets(); // call your app function here + renderLowerLimitBackground(); + renderUpperLimitBackground(); + lowerLimitChanged = true; + upperLimitChanged = true; drawTrainingHeartRate(); } }); @@ -292,7 +305,9 @@ setWatch(setLimitSetterToUpper, BTN5, { edge: "rising", debounce: 50, repeat: tr g.clear(); Bangle.loadWidgets(); Bangle.drawWidgets(); -drawTrainingHeartRate(); +//drawTrainingHeartRate(); // refesh every sec +renderLowerLimitBackground(); +renderUpperLimitBackground(); setInterval(drawTrainingHeartRate, 1000); From 0bfdb86fcb7a08edd20aeb2a3319b08a68b09b97 Mon Sep 17 00:00:00 2001 From: Markus Deibel Date: Sun, 29 Mar 2020 08:04:30 +0200 Subject: [PATCH 23/59] Fix remove unnecessary file and trim down App name --- apps.json | 2 +- apps/wohrm/.gitignore | 4 - apps/wohrm/app.js | 462 +++++++++++++++++++++--------------------- 3 files changed, 233 insertions(+), 235 deletions(-) delete mode 100644 apps/wohrm/.gitignore diff --git a/apps.json b/apps.json index 9f8b31f1d..e5b0ab15e 100644 --- a/apps.json +++ b/apps.json @@ -814,7 +814,7 @@ ] }, { "id": "wohrm", - "name": "Workout Heart Rate Monitor", + "name": "Workout HRM", "icon": "app.png", "version":"0.03", "description": "Workout heart rate monitor notifies you with a buzz if your heart rate goes above or below the set limits.", diff --git a/apps/wohrm/.gitignore b/apps/wohrm/.gitignore deleted file mode 100644 index 2060ed3f3..000000000 --- a/apps/wohrm/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -/node_modules -/.eslintrc.js -/package.json -/package-lock.json \ No newline at end of file diff --git a/apps/wohrm/app.js b/apps/wohrm/app.js index 75c51a578..8323779c9 100644 --- a/apps/wohrm/app.js +++ b/apps/wohrm/app.js @@ -1,160 +1,160 @@ -/* eslint-disable no-undef */ -const Setter = { - NONE: "none", - UPPER: 'upper', - LOWER: 'lower' -}; +// /* eslint-disable no-undef */ +// const Setter = { +// NONE: "none", +// UPPER: 'upper', +// LOWER: 'lower' +// }; -const shortBuzzTimeInMs = 50; -const longBuzzTimeInMs = 200; +// const shortBuzzTimeInMs = 50; +// const longBuzzTimeInMs = 200; -let upperLimit = 90; -let upperLimitChanged = true; +// let upperLimit = 90; +// let upperLimitChanged = true; -let lowerLimit = 50; -let lowerLimitChanged = true; +// let lowerLimit = 50; +// let lowerLimitChanged = true; -let limitSetter = Setter.NONE; +// let limitSetter = Setter.NONE; -let currentHeartRate = 0; -let hrConfidence = -1; -let hrOrConfidenceChanged = true; +// let currentHeartRate = 0; +// let hrConfidence = -1; +// let hrOrConfidenceChanged = true; -let setterHighlightTimeout; +// let setterHighlightTimeout; -function renderUpperLimitBackground() { - g.setColor(1,0,0); - g.fillRect(125,40, 210, 70); - g.fillRect(180,70, 210, 200); +// function renderUpperLimitBackground() { +// g.setColor(1,0,0); +// g.fillRect(125,40, 210, 70); +// g.fillRect(180,70, 210, 200); - //Round top left corner - g.fillEllipse(115,40,135,70); +// //Round top left corner +// g.fillEllipse(115,40,135,70); - //Round top right corner - g.setColor(0,0,0); - g.fillRect(205,40, 210, 45); - g.setColor(1,0,0); - g.fillEllipse(190,40,210,50); +// //Round top right corner +// g.setColor(0,0,0); +// g.fillRect(205,40, 210, 45); +// g.setColor(1,0,0); +// g.fillEllipse(190,40,210,50); - //Round inner corner - g.fillRect(174,71, 179, 76); - g.setColor(0,0,0); - g.fillEllipse(160,71,179,82); +// //Round inner corner +// g.fillRect(174,71, 179, 76); +// g.setColor(0,0,0); +// g.fillEllipse(160,71,179,82); - //Round bottom - g.setColor(1,0,0); - g.fillEllipse(180,190, 210, 210); -} +// //Round bottom +// g.setColor(1,0,0); +// g.fillEllipse(180,190, 210, 210); +// } -function renderLowerLimitBackground() { - g.setColor(0,0,1); - g.fillRect(10, 180, 100, 210); - g.fillRect(10, 50, 40, 180); +// function renderLowerLimitBackground() { +// g.setColor(0,0,1); +// g.fillRect(10, 180, 100, 210); +// g.fillRect(10, 50, 40, 180); - //Rounded top - g.setColor(0,0,1); - g.fillEllipse(10,40, 40, 60); +// //Rounded top +// g.setColor(0,0,1); +// g.fillEllipse(10,40, 40, 60); - //Round bottom right corner - g.setColor(0,0,1); - g.fillEllipse(90,180,110,210); +// //Round bottom right corner +// g.setColor(0,0,1); +// g.fillEllipse(90,180,110,210); - //Round inner corner - g.setColor(0,0,1); - g.fillRect(40,175,45,180); - g.setColor(0,0,0); - g.fillEllipse(41,170,60,179); +// //Round inner corner +// g.setColor(0,0,1); +// g.fillRect(40,175,45,180); +// g.setColor(0,0,0); +// g.fillEllipse(41,170,60,179); - //Round bottom left corner - g.setColor(0,0,0); - g.fillRect(10,205, 15, 210); - g.setColor(0,0,1); - g.fillEllipse(10,200,30,210); -} +// //Round bottom left corner +// g.setColor(0,0,0); +// g.fillRect(10,205, 15, 210); +// g.setColor(0,0,1); +// g.fillEllipse(10,200,30,210); +// } -function drawTrainingHeartRate() { - //Only redraw if the display is on - if (Bangle.isLCDOn()) { - renderButtonIcons(); +// function drawTrainingHeartRate() { +// //Only redraw if the display is on +// if (Bangle.isLCDOn()) { +// renderButtonIcons(); - renderUpperLimit(); +// renderUpperLimit(); - renderCurrentHeartRate(); +// renderCurrentHeartRate(); - renderLowerLimit(); +// renderLowerLimit(); - renderConfidenceBars(); - } +// renderConfidenceBars(); +// } - //buzz(); -} +// //buzz(); +// } -function renderUpperLimit() { - if(!upperLimitChanged) { return; } +// function renderUpperLimit() { +// if(!upperLimitChanged) { return; } - g.setColor(1,0,0); - g.fillRect(125,40, 210, 70); +// g.setColor(1,0,0); +// g.fillRect(125,40, 210, 70); - if(limitSetter === Setter.UPPER){ - g.setColor(255,255, 0); - } else { - g.setColor(255,255,255); - } - g.setFontVector(13); - g.drawString("Upper : " + upperLimit, 130,50); +// if(limitSetter === Setter.UPPER){ +// g.setColor(255,255, 0); +// } else { +// g.setColor(255,255,255); +// } +// g.setFontVector(13); +// g.drawString("Upper : " + upperLimit, 130,50); - upperLimitChanged = false; -} +// upperLimitChanged = false; +// } -function renderCurrentHeartRate() { - if(!hrOrConfidenceChanged) { return; } +// function renderCurrentHeartRate() { +// if(!hrOrConfidenceChanged) { return; } - g.setColor(255,255,255); - g.fillRect(45, 110, 165, 150); +// g.setColor(255,255,255); +// g.fillRect(45, 110, 165, 150); - g.setColor(0,0,0); - g.setFontVector(24); - g.setFontAlign(1, -1, 0); - g.drawString(currentHeartRate, 130, 117); +// g.setColor(0,0,0); +// g.setFontVector(24); +// g.setFontAlign(1, -1, 0); +// g.drawString(currentHeartRate, 130, 117); - //Reset alignment to defaults - g.setFontAlign(-1, -1, 0); -} +// //Reset alignment to defaults +// g.setFontAlign(-1, -1, 0); +// } -function renderLowerLimit() { - if(!lowerLimitChanged) { return; } +// function renderLowerLimit() { +// if(!lowerLimitChanged) { return; } - g.setColor(0,0,1); - g.fillRect(10, 180, 100, 210); +// g.setColor(0,0,1); +// g.fillRect(10, 180, 100, 210); - if(limitSetter === Setter.LOWER){ - g.setColor(255,255, 0); - } else { - g.setColor(255,255,255); - } - g.setFontVector(13); - g.drawString("Lower : " + lowerLimit, 20,190); +// if(limitSetter === Setter.LOWER){ +// g.setColor(255,255, 0); +// } else { +// g.setColor(255,255,255); +// } +// g.setFontVector(13); +// g.drawString("Lower : " + lowerLimit, 20,190); - lowerLimitChanged = false; -} +// lowerLimitChanged = false; +// } -function renderConfidenceBars(){ - if(!hrOrConfidenceChanged) { return; } +// function renderConfidenceBars(){ +// if(!hrOrConfidenceChanged) { return; } - if(hrConfidence >= 85){ - g.setColor(0, 255, 0); - } else if (hrConfidence >= 50) { - g.setColor(255, 255, 0); - } else if(hrConfidence >= 0){ - g.setColor(255, 0, 0); - } else { - g.setColor(255, 255, 255); - } +// if(hrConfidence >= 85){ +// g.setColor(0, 255, 0); +// } else if (hrConfidence >= 50) { +// g.setColor(255, 255, 0); +// } else if(hrConfidence >= 0){ +// g.setColor(255, 0, 0); +// } else { +// g.setColor(255, 255, 255); +// } - g.fillRect(45, 110, 55, 150); - g.fillRect(165, 110, 175, 150); -} +// g.fillRect(45, 110, 55, 150); +// g.fillRect(165, 110, 175, 150); +// } function renderButtonIcons() { g.setColor(255,255,255); @@ -174,140 +174,142 @@ function renderButtonIcons() { g.drawString("-", 222,165); } -function buzz() -{ - if(currentHeartRate > upperLimit) - { - Bangle.buzz(shortBuzzTimeInMs); - setTimeout(() => { Bangle.buzz(shortBuzzTimeInMs); }, shortBuzzTimeInMs); - setTimeout(() => { Bangle.buzz(shortBuzzTimeInMs); }, shortBuzzTimeInMs); - } +// function buzz() +// { +// if(currentHeartRate > upperLimit) +// { +// Bangle.buzz(shortBuzzTimeInMs); +// setTimeout(() => { Bangle.buzz(shortBuzzTimeInMs); }, shortBuzzTimeInMs); +// setTimeout(() => { Bangle.buzz(shortBuzzTimeInMs); }, shortBuzzTimeInMs); +// } - if(currentHeartRate < lowerLimit) - { - Bangle.buzz(longBuzzTimeInMs); - setTimeout(() => { Bangle.buzz(longBuzzTimeInMs); }, longBuzzTimeInMs); - } -} +// if(currentHeartRate < lowerLimit) +// { +// Bangle.buzz(longBuzzTimeInMs); +// setTimeout(() => { Bangle.buzz(longBuzzTimeInMs); }, longBuzzTimeInMs); +// } +// } -function onHrm(hrm){ - hrOrConfidenceChanged = (currentHeartRate !== hrm.bpm || hrConfidence !== hrm.confidence); - currentHeartRate = hrm.bpm; - hrConfidence = hrm.confidence; -} +// function onHrm(hrm){ +// hrOrConfidenceChanged = (currentHeartRate !== hrm.bpm || hrConfidence !== hrm.confidence); +// currentHeartRate = hrm.bpm; +// hrConfidence = hrm.confidence; +// } -function setLimitSetterToLower() { - resetHighlightTimeout(); +// function setLimitSetterToLower() { +// resetHighlightTimeout(); - limitSetter = Setter.LOWER; - console.log("Limit setter is lower"); +// limitSetter = Setter.LOWER; +// console.log("Limit setter is lower"); - upperLimitChanged = true; - lowerLimitChanged = true; +// upperLimitChanged = true; +// lowerLimitChanged = true; - renderUpperLimit(); - renderLowerLimit(); -} +// renderUpperLimit(); +// renderLowerLimit(); +// } -function setLimitSetterToUpper() { - resetHighlightTimeout(); +// function setLimitSetterToUpper() { +// resetHighlightTimeout(); - limitSetter = Setter.UPPER; - console.log("Limit setter is upper"); +// limitSetter = Setter.UPPER; +// console.log("Limit setter is upper"); - upperLimitChanged = true; - lowerLimitChanged = true; +// upperLimitChanged = true; +// lowerLimitChanged = true; - renderLowerLimit(); - renderUpperLimit(); -} +// renderLowerLimit(); +// renderUpperLimit(); +// } -function setLimitSetterToNone() { - limitSetter = Setter.NONE; - console.log("Limit setter is none"); +// function setLimitSetterToNone() { +// limitSetter = Setter.NONE; +// console.log("Limit setter is none"); - upperLimitChanged = true; - lowerLimitChanged = true; +// upperLimitChanged = true; +// lowerLimitChanged = true; - renderLowerLimit(); - renderUpperLimit(); -} +// renderLowerLimit(); +// renderUpperLimit(); +// } -function incrementLimit(){ - resetHighlightTimeout(); +// function incrementLimit(){ +// resetHighlightTimeout(); - if (limitSetter === Setter.UPPER) { - upperLimit++; - renderUpperLimit(); - console.log("Upper limit: " + upperLimit); - upperLimitChanged = true; - } else if(limitSetter === Setter.LOWER) { - lowerLimit++; - renderLowerLimit(); - console.log("Lower limit: " + lowerLimit); - lowerLimitChanged = true; - } -} +// if (limitSetter === Setter.UPPER) { +// upperLimit++; +// renderUpperLimit(); +// console.log("Upper limit: " + upperLimit); +// upperLimitChanged = true; +// } else if(limitSetter === Setter.LOWER) { +// lowerLimit++; +// renderLowerLimit(); +// console.log("Lower limit: " + lowerLimit); +// lowerLimitChanged = true; +// } +// } -function decrementLimit(){ - resetHighlightTimeout(); +// function decrementLimit(){ +// resetHighlightTimeout(); - if (limitSetter === Setter.UPPER) { - upperLimit--; - renderUpperLimit(); - console.log("Upper limit: " + upperLimit); - upperLimitChanged = true; - } else if(limitSetter === Setter.LOWER) { - lowerLimit--; - renderLowerLimit(); - console.log("Lower limit: " + lowerLimit); - lowerLimitChanged = true; - } -} +// if (limitSetter === Setter.UPPER) { +// upperLimit--; +// renderUpperLimit(); +// console.log("Upper limit: " + upperLimit); +// upperLimitChanged = true; +// } else if(limitSetter === Setter.LOWER) { +// lowerLimit--; +// renderLowerLimit(); +// console.log("Lower limit: " + lowerLimit); +// lowerLimitChanged = true; +// } +// } -function resetHighlightTimeout() { - if (setterHighlightTimeout) { - clearTimeout(setterHighlightTimeout); - } +// function resetHighlightTimeout() { +// if (setterHighlightTimeout) { +// clearTimeout(setterHighlightTimeout); +// } - setterHighlightTimeout = setTimeout(setLimitSetterToNone, 2000); -} +// setterHighlightTimeout = setTimeout(setLimitSetterToNone, 2000); +// } -// Show launcher when middle button pressed -function switchOffApp(){ - Bangle.setHRMPower(0); - Bangle.showLauncher(); -} +// // Show launcher when middle button pressed +// function switchOffApp(){ +// Bangle.setHRMPower(0); +// Bangle.showLauncher(); +// } -// special function to handle display switch on -Bangle.on('lcdPower', (on) => { - g.clear(); - if (on) { - Bangle.drawWidgets(); - // call your app function here - renderLowerLimitBackground(); - renderUpperLimitBackground(); - lowerLimitChanged = true; - upperLimitChanged = true; - drawTrainingHeartRate(); - } -}); +// // special function to handle display switch on +// Bangle.on('lcdPower', (on) => { +// g.clear(); +// if (on) { +// Bangle.drawWidgets(); +// // call your app function here +// renderLowerLimitBackground(); +// renderUpperLimitBackground(); +// lowerLimitChanged = true; +// upperLimitChanged = true; +// drawTrainingHeartRate(); +// } +// }); -Bangle.setHRMPower(1); -Bangle.on('HRM', onHrm); +// Bangle.setHRMPower(1); +// Bangle.on('HRM', onHrm); -setWatch(incrementLimit, BTN1, {edge:"rising", debounce:50, repeat:true}); +// setWatch(incrementLimit, BTN1, {edge:"rising", debounce:50, repeat:true}); setWatch(switchOffApp, BTN2, {repeat:false,edge:"falling"}); -setWatch(decrementLimit, BTN3, {edge:"rising", debounce:50, repeat:true}); -setWatch(setLimitSetterToLower, BTN4, {edge:"rising", debounce:50, repeat:true}); -setWatch(setLimitSetterToUpper, BTN5, { edge: "rising", debounce: 50, repeat: true }); -g.clear(); -Bangle.loadWidgets(); -Bangle.drawWidgets(); -//drawTrainingHeartRate(); +renderButtonIcons +// setWatch(decrementLimit, BTN3, {edge:"rising", debounce:50, repeat:true}); +// setWatch(setLimitSetterToLower, BTN4, {edge:"rising", debounce:50, repeat:true}); +// setWatch(setLimitSetterToUpper, BTN5, { edge: "rising", debounce: 50, repeat: true }); -// refesh every sec -renderLowerLimitBackground(); -renderUpperLimitBackground(); -setInterval(drawTrainingHeartRate, 1000); +// g.clear(); +// Bangle.loadWidgets(); +// Bangle.drawWidgets(); +// //drawTrainingHeartRate(); + +// // refesh every sec +// renderLowerLimitBackground(); +// renderUpperLimitBackground(); +// setInterval(drawTrainingHeartRate, 1000); From df3935e390ed8492723e3a33d7809469799c379c Mon Sep 17 00:00:00 2001 From: Markus Deibel Date: Sun, 29 Mar 2020 08:42:53 +0200 Subject: [PATCH 24/59] Icon file size reduced --- apps/wohrm/app-icon.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/wohrm/app-icon.js b/apps/wohrm/app-icon.js index 36663d0ed..1bf4c808b 100644 --- a/apps/wohrm/app-icon.js +++ b/apps/wohrm/app-icon.js @@ -1 +1 @@ -require("heatshrink").decompress(atob("MDCI/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+wsK7u8HC/v7+/v7+/v7+/v7+/v7Cwbu7wsL+/v7+/v7+/v7+/v7+/v7+/v7+ybu7u7u7u7u7u7vI/v7+/v7+/v7Iu7u7u7u7u7u7u8n+/v7+/v7+/v7+/v7+/v67u7u7u7u7u7u7u7u7u/7+/v7+/ru7u7u7u7u7u7u7u7u7/v7+/v7+/v7+/v7+/ru7u7u7u7u7u7u7u7u7u7v+/v7+u7u7u7u7u7u7u7u7u7u7u/7+/v7+/v7+/v7+u7u7u7u7u7u7u7u7u7u7u7u7/v67u7u7u7u7u7u7u7u7u7u7u7v+/v7+/v7+/v67u7u7u7u7u7u7wci7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7/v7+/v7+/sm7u7u7u7u7u7u7wsm7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7u7yf7+/v7+/ru7u7u7u7u7u7u7ydC7u7u7u7u7u7u7u7u7u7u7u8LQ19DCu7u7u7u7u/7+/v7+/ru7u7u7u7u7u7u70NfCu7u7u7u7u7u7u7u7u7u7u9DX19fQu7u7u7u7u/7+/v7+wru7u7u7u7u7u7vC19fJu7u7u7u7u7u7u7u7u7u7u9fX19fXu7u7u7u7u8L+/v7+wru7u7u7u7u7u7vJ19fJu7u7u7u7u7u7u7u7u7u7u9DX19fQu7u7u7u7u8L+/v7+u7u7u7u7u7u7u7vQ19fQu7u7u7u7u7u7u7u7u7u7u8nX19DCu7u7u7u7u7v+/v7+wbu7u7u7ybu7u7vX19DXwru7u7u7u7u7u7u7wcnQ19fX0Lu7u7u7u7u7u8H+/v7+wru7u7vC18K7u8LX0MnXybu7u7vCu7u7wc/Q19fX19fX18K7u7u7u7u7u8L+/v7+yLu7u7vJ18m7u8nXycnXybu7u7vJu7u7wtfX19DJydfX19C7u7u7u7u7u8j+/v7+/ru7u8HR19HBu9DXwsLX0Lu7u7vQu7u7wdfX0Lu70NfJ0NfJu7u7u7u7u/7+/v7+/ru7u8nX19fJwtfQu7vQ18K7u8LXu7u7u8HQ18LC19fBwtfXycm7u7u7u/7+/v7+/tDX19fXydfQydfJu7vJ18m7u8nXu7u7u7vBwrvQ18m7u9DX19e7u7u7yf7+/v7+/v7Q19fQu9DX0NfIu7vJ18m7u9DXu7u7u7u7u8HX18K7u8HJycm7u7u7/v7+/v7+/v7+u7u7u8nX19fBu7vC19C7wtfQu7u7u7u7u8nX0Lu7u7u7u7u7u7v+/v7+/v7+/v7+wru7u8HR19C7u7u70NfCz9fJu7u7wru7u9fX18nCu7u7u7u7u8L+/v7+/v7+/v7+/sG7u7vJ18m7u7u7ydfJ0dfBu8HC19C7yNfX19fX0MK7u7u7wf7+/v7+/v7+/v7+/v67u7vC18K7u7u7ydfQ19C7u7vB0NfQ0NfJws/X18G7u7u7/v7+/v7+/v7+/v7+/v7+u7u70Lu7u7u7wtfX18m7u7u7wdDX19e7u8LX18K7u7v+/v7+/v7+/v7+/v7+/v7+/ru7wbu7u7u7u9DX18G7u7u7u8HJ18m7wdDX0Lu7u/7+/v7+/v7+/v7+/v7+/v7+/v67u7u7u7u7u8nX0Lu7u7u7u7u7wcG70NfQu7u7/v7+/v7+/v7+/v7+/v7+/v7+/v7+wbu7u7u7u8nXyLu7u7u7u7u7u7vJ19fCu7v+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/sG7u7u7u8LXwbu7u7u7u7u7u8HX18K7wf7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7Cu7u7u7vJu7u7u7u7u7u7u7vCybvC/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+ybu7u7vBu7u7u7u7u7u7u7u7u8L+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v67u7u7u7u7u7u7u7u7u7u7/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+wru7u7u7u7u7u7u7u8L+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/sm7u7u7u7u7u7u7yf7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+wru7u7u7u8L+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v67u7u7yf7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+wsL+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/v7+/g==")) +var img=require("heatshrink").decompress(atob("mEwwhC/AH4AVgnd7tABJ4AClvMAAXUBIdNBIfSCw0NBgYAB6AJLAAfcBovMBIIIG5ouJ5oDC4EMC4wwFFwnSDYY4HGAkCBIlDCQ4AFkBrHmYqIn89JApUEBoJDH4f/+ZqDC4NMC4n/lgXG5///4FC4h2GEoM8F5h4CC53C/5fDC4oTB7/z/oGBBIXNkYuEC4vNCYNPmfyBgJpB6c/LoP/OAYXCAwPDEQM/mQmCGwNP/8zDII5CO4anB7//7k/7oXB5pODBIMzU4zXBEQM9B4Xc4n8YwXd//UGYLXEgZRBIoc/lnDC4PM6hTDYAUwC4MAQIPT+f05kvnnfC4RJBLoPTF4J2CMAa9BBoPfnlPXAc/Y4heCAAMEDwLVC4f9CQXdBIJpBC4VAC4bBCCQRYBSoPU+fSNgIYCIwiRD77EB4XzVISkC6YeBRoYwF4YjC/7xCCgP9A4PcFwwwC5r5Cn7nCAgKVBGwJ1EMIyJG5vdn89FxBhDAAMvMYIACWQPcLo4wG740DAoP0FxQwE4YWDJAMsFxYABLgJ7CAAfECxh6FF4YWOPQgACIpoADnoWD4QWQJIhFQDAvNmAXUglACygA/AH4AFA")) From de603515073b5cc3e3060f89ba0f84d5d24985aa Mon Sep 17 00:00:00 2001 From: Markus Deibel Date: Sun, 29 Mar 2020 08:44:53 +0200 Subject: [PATCH 25/59] Image icon code --- apps/wohrm/app-icon.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/wohrm/app-icon.js b/apps/wohrm/app-icon.js index 1bf4c808b..1b30302b4 100644 --- a/apps/wohrm/app-icon.js +++ b/apps/wohrm/app-icon.js @@ -1 +1 @@ -var img=require("heatshrink").decompress(atob("mEwwhC/AH4AVgnd7tABJ4AClvMAAXUBIdNBIfSCw0NBgYAB6AJLAAfcBovMBIIIG5ouJ5oDC4EMC4wwFFwnSDYY4HGAkCBIlDCQ4AFkBrHmYqIn89JApUEBoJDH4f/+ZqDC4NMC4n/lgXG5///4FC4h2GEoM8F5h4CC53C/5fDC4oTB7/z/oGBBIXNkYuEC4vNCYNPmfyBgJpB6c/LoP/OAYXCAwPDEQM/mQmCGwNP/8zDII5CO4anB7//7k/7oXB5pODBIMzU4zXBEQM9B4Xc4n8YwXd//UGYLXEgZRBIoc/lnDC4PM6hTDYAUwC4MAQIPT+f05kvnnfC4RJBLoPTF4J2CMAa9BBoPfnlPXAc/Y4heCAAMEDwLVC4f9CQXdBIJpBC4VAC4bBCCQRYBSoPU+fSNgIYCIwiRD77EB4XzVISkC6YeBRoYwF4YjC/7xCCgP9A4PcFwwwC5r5Cn7nCAgKVBGwJ1EMIyJG5vdn89FxBhDAAMvMYIACWQPcLo4wG740DAoP0FxQwE4YWDJAMsFxYABLgJ7CAAfECxh6FF4YWOPQgACIpoADnoWD4QWQJIhFQDAvNmAXUglACygA/AH4AFA")) +var img = require("heatshrink").decompress(atob("mEwwhC/AH4AVgnd7tABJ4AClvMAAXUBIdNBIfSCw0NBgYAB6AJLAAfcBovMBIIIG5ouJ5oDC4EMC4wwFFwnSDYY4HGAkCBIlDCQ4AFkBrHmYqIn89JApUEBoJDH4f/+ZqDC4NMC4n/lgXG5///4FC4h2GEoM8F5h4CC53C/5fDC4oTB7/z/oGBBIXNkYuEC4vNCYNPmfyBgJpB6c/LoP/OAYXCAwPDEQM/mQmCGwNP/8zDII5CO4anB7//7k/7oXB5pODBIMzU4zXBEQM9B4Xc4n8YwXd//UGYLXEgZRBIoc/lnDC4PM6hTDYAUwC4MAQIPT+f05kvnnfC4RJBLoPTF4J2CMAa9BBoPfnlPXAc/Y4heCAAMEDwLVC4f9CQXdBIJpBC4VAC4bBCCQRYBSoPU+fSNgIYCIwiRD77EB4XzVISkC6YeBRoYwF4YjC/7xCCgP9A4PcFwwwC5r5Cn7nCAgKVBGwJ1EMIyJG5vdn89FxBhDAAMvMYIACWQPcLo4wG740DAoP0FxQwE4YWDJAMsFxYABLgJ7CAAfECxh6FF4YWOPQgACIpoADnoWD4QWQJIhFQDAvNmAXUglACygA/AH4AFA")) From bcce90d36df407a1b7e2c57bfae288f63cd915ce Mon Sep 17 00:00:00 2001 From: Markus Deibel Date: Sun, 29 Mar 2020 08:47:14 +0200 Subject: [PATCH 26/59] icon --- apps/wohrm/app-icon.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/wohrm/app-icon.js b/apps/wohrm/app-icon.js index 1b30302b4..84799199d 100644 --- a/apps/wohrm/app-icon.js +++ b/apps/wohrm/app-icon.js @@ -1 +1 @@ -var img = require("heatshrink").decompress(atob("mEwwhC/AH4AVgnd7tABJ4AClvMAAXUBIdNBIfSCw0NBgYAB6AJLAAfcBovMBIIIG5ouJ5oDC4EMC4wwFFwnSDYY4HGAkCBIlDCQ4AFkBrHmYqIn89JApUEBoJDH4f/+ZqDC4NMC4n/lgXG5///4FC4h2GEoM8F5h4CC53C/5fDC4oTB7/z/oGBBIXNkYuEC4vNCYNPmfyBgJpB6c/LoP/OAYXCAwPDEQM/mQmCGwNP/8zDII5CO4anB7//7k/7oXB5pODBIMzU4zXBEQM9B4Xc4n8YwXd//UGYLXEgZRBIoc/lnDC4PM6hTDYAUwC4MAQIPT+f05kvnnfC4RJBLoPTF4J2CMAa9BBoPfnlPXAc/Y4heCAAMEDwLVC4f9CQXdBIJpBC4VAC4bBCCQRYBSoPU+fSNgIYCIwiRD77EB4XzVISkC6YeBRoYwF4YjC/7xCCgP9A4PcFwwwC5r5Cn7nCAgKVBGwJ1EMIyJG5vdn89FxBhDAAMvMYIACWQPcLo4wG740DAoP0FxQwE4YWDJAMsFxYABLgJ7CAAfECxh6FF4YWOPQgACIpoADnoWD4QWQJIhFQDAvNmAXUglACygA/AH4AFA")) +var img = E.toArrayBuffer(atob("MDCCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAqqAAAACqoAAAAAAqqqqAACqqqoAAAACqqqqgAKqqqqAAAAKqqqqoAqqqqqgAAAqqqqqqCqqqqqoAACqqqqqqqqqqqqqAAKqqquqqqqqqqqqgAKqqq+qqqqqr+qqgAKqqq+qqqqqv/qqgAqqqq+qqqqqv/qqoAqqqr/qqqqqv/qqoAqqqr/qqqqqr+qqoAqq6r/qqqqr/6qqoAqq6r/qqqv//6qqoAqr+v76rqv//+qqoAKr+vr6rqv6//qqgAKv/vr6rqr6+v+qgAP//vr6vqqr+v+qwAD/v+q+vqqr6r+qAAAqv+q+vqqv6qqoAAAqr+q+/qqv+qqoAAAKr+q/+q+v/6qgAAACq6qv+q//v6qAAAAAq6qv6qv+r6oAAAAAKqqv6qr+v6gAAAAACqqv6qqq/qAAAAAAAqqrqqqr+oAAAAAAAKqrqqqr6gAAAAAAACqrqqqqqAAAAAAAAA6qqqqqoAAAAAAAAACqqqqqAAAAAAAAAAAqqqqoAAAAAAAAAAAOqqqgAAAAAAAAAAAAqqoAAAAAAAAAAAAACqwAAAAAAAAAAAAAAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==")) From 5d98017fe7d1519a11ebfa68d2f3af031e6f87a3 Mon Sep 17 00:00:00 2001 From: Markus Deibel Date: Sun, 29 Mar 2020 08:50:15 +0200 Subject: [PATCH 27/59] Icon --- apps/wohrm/app-icon.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/wohrm/app-icon.js b/apps/wohrm/app-icon.js index 84799199d..a95a3d4e0 100644 --- a/apps/wohrm/app-icon.js +++ b/apps/wohrm/app-icon.js @@ -1 +1 @@ -var img = E.toArrayBuffer(atob("MDCCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAqqAAAACqoAAAAAAqqqqAACqqqoAAAACqqqqgAKqqqqAAAAKqqqqoAqqqqqgAAAqqqqqqCqqqqqoAACqqqqqqqqqqqqqAAKqqquqqqqqqqqqgAKqqq+qqqqqr+qqgAKqqq+qqqqqv/qqgAqqqq+qqqqqv/qqoAqqqr/qqqqqv/qqoAqqqr/qqqqqr+qqoAqq6r/qqqqr/6qqoAqq6r/qqqv//6qqoAqr+v76rqv//+qqoAKr+vr6rqv6//qqgAKv/vr6rqr6+v+qgAP//vr6vqqr+v+qwAD/v+q+vqqr6r+qAAAqv+q+vqqv6qqoAAAqr+q+/qqv+qqoAAAKr+q/+q+v/6qgAAACq6qv+q//v6qAAAAAq6qv6qv+r6oAAAAAKqqv6qr+v6gAAAAACqqv6qqq/qAAAAAAAqqrqqqr+oAAAAAAAKqrqqqr6gAAAAAAACqrqqqqqAAAAAAAAA6qqqqqoAAAAAAAAACqqqqqAAAAAAAAAAAqqqqoAAAAAAAAAAAOqqqgAAAAAAAAAAAAqqoAAAAAAAAAAAAACqwAAAAAAAAAAAAAAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==")) +require("heatshrink").decompress(atob("mEwwhC/AH4AVgnd7tABJ4AClvMAAXUBIdNBIfSCw0NBgYAB6AJLAAfcBovMBIIIG5ouJ5oDC4EMC4wwFFwnSDYY4HGAkCBIlDCQ4AFkBrHmYqIn89JApUEBoJDH4f/+ZqDC4NMC4n/lgXG5///4FC4h2GEoM8F5h4CC53C/5fDC4oTB7/z/oGBBIXNkYuEC4vNCYNPmfyBgJpB6c/LoP/OAYXCAwPDEQM/mQmCGwNP/8zDII5CO4anB7//7k/7oXB5pODBIMzU4zXBEQM9B4Xc4n8YwXd//UGYLXEgZRBIoc/lnDC4PM6hTDYAUwC4MAQIPT+f05kvnnfC4RJBLoPTF4J2CMAa9BBoPfnlPXAc/Y4heCAAMEDwLVC4f9CQXdBIJpBC4VAC4bBCCQRYBSoPU+fSNgIYCIwiRD77EB4XzVISkC6YeBRoYwF4YjC/7xCCgP9A4PcFwwwC5r5Cn7nCAgKVBGwJ1EMIyJG5vdn89FxBhDAAMvMYIACWQPcLo4wG740DAoP0FxQwE4YWDJAMsFxYABLgJ7CAAfECxh6FF4YWOPQgACIpoADnoWD4QWQJIhFQDAvNmAXUglACygA/AH4AFA")) \ No newline at end of file From 94f89db572c529f3e5f2d7e1904049085d6dd624 Mon Sep 17 00:00:00 2001 From: Markus Deibel Date: Sun, 29 Mar 2020 08:51:49 +0200 Subject: [PATCH 28/59] Icon --- apps/wohrm/app-icon.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/wohrm/app-icon.js b/apps/wohrm/app-icon.js index a95a3d4e0..5a57c6cb1 100644 --- a/apps/wohrm/app-icon.js +++ b/apps/wohrm/app-icon.js @@ -1 +1 @@ -require("heatshrink").decompress(atob("mEwwhC/AH4AVgnd7tABJ4AClvMAAXUBIdNBIfSCw0NBgYAB6AJLAAfcBovMBIIIG5ouJ5oDC4EMC4wwFFwnSDYY4HGAkCBIlDCQ4AFkBrHmYqIn89JApUEBoJDH4f/+ZqDC4NMC4n/lgXG5///4FC4h2GEoM8F5h4CC53C/5fDC4oTB7/z/oGBBIXNkYuEC4vNCYNPmfyBgJpB6c/LoP/OAYXCAwPDEQM/mQmCGwNP/8zDII5CO4anB7//7k/7oXB5pODBIMzU4zXBEQM9B4Xc4n8YwXd//UGYLXEgZRBIoc/lnDC4PM6hTDYAUwC4MAQIPT+f05kvnnfC4RJBLoPTF4J2CMAa9BBoPfnlPXAc/Y4heCAAMEDwLVC4f9CQXdBIJpBC4VAC4bBCCQRYBSoPU+fSNgIYCIwiRD77EB4XzVISkC6YeBRoYwF4YjC/7xCCgP9A4PcFwwwC5r5Cn7nCAgKVBGwJ1EMIyJG5vdn89FxBhDAAMvMYIACWQPcLo4wG740DAoP0FxQwE4YWDJAMsFxYABLgJ7CAAfECxh6FF4YWOPQgACIpoADnoWD4QWQJIhFQDAvNmAXUglACygA/AH4AFA")) \ No newline at end of file +require("heatshrink").decompress(atob("mEwwhC/AH4AVgnd7tABJ4AClvMAAXUBIdNBIfSCw0NBgYAB6AJLAAfcBovMBIIIG5ouJ5oDC4EMC4wwFFwnSDYY4HGAkCBIlDCQ4AFkBrHmYqIn89JApUEBoJDH4f/+ZqDC4NMC4n/lgXG5///4FC4h2GEoM8F5h4CC53C/5fDC4oTB7/z/oGBBIXNkYuEC4vNCYNPmfyBgJpB6c/LoP/OAYXCAwPDEQM/mQmCGwNP/8zDII5CO4anB7//7k/7oXB5pODBIMzU4zXBEQM9B4Xc4n8YwXd//UGYLXEgZRBIoc/lnDC4PM6hTDYAUwC4MAQIPT+f05kvnnfC4RJBLoPTF4J2CMAa9BBoPfnlPXAc/Y4heCAAMEDwLVC4f9CQXdBIJpBC4VAC4bBCCQRYBSoPU+fSNgIYCIwiRD77EB4XzVISkC6YeBRoYwF4YjC/7xCCgP9A4PcFwwwC5r5Cn7nCAgKVBGwJ1EMIyJG5vdn89FxBhDAAMvMYIACWQPcLo4wG740DAoP0FxQwE4YWDJAMsFxYABLgJ7CAAfECxh6FF4YWOPQgACIpoADnoWD4QWQJIhFQDAvNmAXUglACygA/AH4AFA")) From e23c1ad2e508bd97c0c71ebe315a78cdf4b1dca7 Mon Sep 17 00:00:00 2001 From: Markus Deibel Date: Sun, 29 Mar 2020 08:53:33 +0200 Subject: [PATCH 29/59] Icon --- apps/wohrm/app-icon.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/wohrm/app-icon.js b/apps/wohrm/app-icon.js index 5a57c6cb1..a7f67291e 100644 --- a/apps/wohrm/app-icon.js +++ b/apps/wohrm/app-icon.js @@ -1 +1 @@ -require("heatshrink").decompress(atob("mEwwhC/AH4AVgnd7tABJ4AClvMAAXUBIdNBIfSCw0NBgYAB6AJLAAfcBovMBIIIG5ouJ5oDC4EMC4wwFFwnSDYY4HGAkCBIlDCQ4AFkBrHmYqIn89JApUEBoJDH4f/+ZqDC4NMC4n/lgXG5///4FC4h2GEoM8F5h4CC53C/5fDC4oTB7/z/oGBBIXNkYuEC4vNCYNPmfyBgJpB6c/LoP/OAYXCAwPDEQM/mQmCGwNP/8zDII5CO4anB7//7k/7oXB5pODBIMzU4zXBEQM9B4Xc4n8YwXd//UGYLXEgZRBIoc/lnDC4PM6hTDYAUwC4MAQIPT+f05kvnnfC4RJBLoPTF4J2CMAa9BBoPfnlPXAc/Y4heCAAMEDwLVC4f9CQXdBIJpBC4VAC4bBCCQRYBSoPU+fSNgIYCIwiRD77EB4XzVISkC6YeBRoYwF4YjC/7xCCgP9A4PcFwwwC5r5Cn7nCAgKVBGwJ1EMIyJG5vdn89FxBhDAAMvMYIACWQPcLo4wG740DAoP0FxQwE4YWDJAMsFxYABLgJ7CAAfECxh6FF4YWOPQgACIpoADnoWD4QWQJIhFQDAvNmAXUglACygA/AH4AFA")) +require("heatshrink").decompress(atob("mEwwhC/AH4AWzIAByAHDhIICCpINDDAgIIFpAADBBQuKE4QIIFxgAKC7g9HABSbIBQQXWGxgXEKQxOMC5AhBC66WMC5AuBJ5h3ICoI3LeAwKBBAICBD4TmHC48ACgQCCfxC/HAgYXDL44vFA4YRDAoiOIHAgXFYRAXFBwwIIOw4OGIxKmIC5ylHGAoXIXpBIGLxxIIIx6IJFxwwNCxQwLFxYwLCxgwJFxowJCxwwHFx4wHCyAwFFyIwFCyQYDCygA/AH4AFA")) \ No newline at end of file From 01483303766627054448bb88f215e944aa44515e Mon Sep 17 00:00:00 2001 From: Markus Deibel Date: Sun, 29 Mar 2020 08:56:11 +0200 Subject: [PATCH 30/59] Uncomment app code again --- apps/wohrm/app.js | 468 +++++++++++++++++++++++----------------------- 1 file changed, 233 insertions(+), 235 deletions(-) diff --git a/apps/wohrm/app.js b/apps/wohrm/app.js index 8323779c9..cc5dbc286 100644 --- a/apps/wohrm/app.js +++ b/apps/wohrm/app.js @@ -1,315 +1,313 @@ -// /* eslint-disable no-undef */ -// const Setter = { -// NONE: "none", -// UPPER: 'upper', -// LOWER: 'lower' -// }; +/* eslint-disable no-undef */ +const Setter = { + NONE: "none", + UPPER: 'upper', + LOWER: 'lower' +}; -// const shortBuzzTimeInMs = 50; -// const longBuzzTimeInMs = 200; +const shortBuzzTimeInMs = 50; +const longBuzzTimeInMs = 200; -// let upperLimit = 90; -// let upperLimitChanged = true; +let upperLimit = 90; +let upperLimitChanged = true; -// let lowerLimit = 50; -// let lowerLimitChanged = true; +let lowerLimit = 50; +let lowerLimitChanged = true; -// let limitSetter = Setter.NONE; +let limitSetter = Setter.NONE; -// let currentHeartRate = 0; -// let hrConfidence = -1; -// let hrOrConfidenceChanged = true; +let currentHeartRate = 0; +let hrConfidence = -1; +let hrOrConfidenceChanged = true; -// let setterHighlightTimeout; +let setterHighlightTimeout; -// function renderUpperLimitBackground() { -// g.setColor(1,0,0); -// g.fillRect(125,40, 210, 70); -// g.fillRect(180,70, 210, 200); +function renderUpperLimitBackground() { + g.setColor(1,0,0); + g.fillRect(125,40, 210, 70); + g.fillRect(180,70, 210, 200); -// //Round top left corner -// g.fillEllipse(115,40,135,70); + //Round top left corner + g.fillEllipse(115,40,135,70); -// //Round top right corner -// g.setColor(0,0,0); -// g.fillRect(205,40, 210, 45); -// g.setColor(1,0,0); -// g.fillEllipse(190,40,210,50); + //Round top right corner + g.setColor(0,0,0); + g.fillRect(205,40, 210, 45); + g.setColor(1,0,0); + g.fillEllipse(190,40,210,50); -// //Round inner corner -// g.fillRect(174,71, 179, 76); -// g.setColor(0,0,0); -// g.fillEllipse(160,71,179,82); + //Round inner corner + g.fillRect(174,71, 179, 76); + g.setColor(0,0,0); + g.fillEllipse(160,71,179,82); -// //Round bottom -// g.setColor(1,0,0); -// g.fillEllipse(180,190, 210, 210); -// } + //Round bottom + g.setColor(1,0,0); + g.fillEllipse(180,190, 210, 210); +} -// function renderLowerLimitBackground() { -// g.setColor(0,0,1); -// g.fillRect(10, 180, 100, 210); -// g.fillRect(10, 50, 40, 180); +function renderLowerLimitBackground() { + g.setColor(0,0,1); + g.fillRect(10, 180, 100, 210); + g.fillRect(10, 50, 40, 180); -// //Rounded top -// g.setColor(0,0,1); -// g.fillEllipse(10,40, 40, 60); + //Rounded top + g.setColor(0,0,1); + g.fillEllipse(10,40, 40, 60); -// //Round bottom right corner -// g.setColor(0,0,1); -// g.fillEllipse(90,180,110,210); + //Round bottom right corner + g.setColor(0,0,1); + g.fillEllipse(90,180,110,210); -// //Round inner corner -// g.setColor(0,0,1); -// g.fillRect(40,175,45,180); -// g.setColor(0,0,0); -// g.fillEllipse(41,170,60,179); + //Round inner corner + g.setColor(0,0,1); + g.fillRect(40,175,45,180); + g.setColor(0,0,0); + g.fillEllipse(41,170,60,179); -// //Round bottom left corner -// g.setColor(0,0,0); -// g.fillRect(10,205, 15, 210); -// g.setColor(0,0,1); -// g.fillEllipse(10,200,30,210); -// } + //Round bottom left corner + g.setColor(0,0,0); + g.fillRect(10,205, 15, 210); + g.setColor(0,0,1); + g.fillEllipse(10,200,30,210); +} -// function drawTrainingHeartRate() { -// //Only redraw if the display is on -// if (Bangle.isLCDOn()) { -// renderButtonIcons(); +function drawTrainingHeartRate() { + //Only redraw if the display is on + if (Bangle.isLCDOn()) { + renderButtonIcons(); -// renderUpperLimit(); + renderUpperLimit(); -// renderCurrentHeartRate(); + renderCurrentHeartRate(); -// renderLowerLimit(); + renderLowerLimit(); -// renderConfidenceBars(); -// } + renderConfidenceBars(); + } -// //buzz(); -// } + //buzz(); +} -// function renderUpperLimit() { -// if(!upperLimitChanged) { return; } +function renderUpperLimit() { + if(!upperLimitChanged) { return; } -// g.setColor(1,0,0); -// g.fillRect(125,40, 210, 70); + g.setColor(1,0,0); + g.fillRect(125,40, 210, 70); -// if(limitSetter === Setter.UPPER){ -// g.setColor(255,255, 0); -// } else { -// g.setColor(255,255,255); -// } -// g.setFontVector(13); -// g.drawString("Upper : " + upperLimit, 130,50); + if(limitSetter === Setter.UPPER){ + g.setColor(255,255, 0); + } else { + g.setColor(255,255,255); + } + g.setFontVector(13); + g.drawString("Upper : " + upperLimit, 130,50); -// upperLimitChanged = false; -// } + upperLimitChanged = false; +} -// function renderCurrentHeartRate() { -// if(!hrOrConfidenceChanged) { return; } +function renderCurrentHeartRate() { + if(!hrOrConfidenceChanged) { return; } -// g.setColor(255,255,255); -// g.fillRect(45, 110, 165, 150); + g.setColor(255,255,255); + g.fillRect(45, 110, 165, 150); -// g.setColor(0,0,0); -// g.setFontVector(24); -// g.setFontAlign(1, -1, 0); -// g.drawString(currentHeartRate, 130, 117); + g.setColor(0,0,0); + g.setFontVector(24); + g.setFontAlign(1, -1, 0); + g.drawString(currentHeartRate, 130, 117); -// //Reset alignment to defaults -// g.setFontAlign(-1, -1, 0); -// } + //Reset alignment to defaults + g.setFontAlign(-1, -1, 0); +} -// function renderLowerLimit() { -// if(!lowerLimitChanged) { return; } +function renderLowerLimit() { + if(!lowerLimitChanged) { return; } -// g.setColor(0,0,1); -// g.fillRect(10, 180, 100, 210); + g.setColor(0,0,1); + g.fillRect(10, 180, 100, 210); -// if(limitSetter === Setter.LOWER){ -// g.setColor(255,255, 0); -// } else { -// g.setColor(255,255,255); -// } -// g.setFontVector(13); -// g.drawString("Lower : " + lowerLimit, 20,190); + if(limitSetter === Setter.LOWER){ + g.setColor(255,255, 0); + } else { + g.setColor(255,255,255); + } + g.setFontVector(13); + g.drawString("Lower : " + lowerLimit, 20,190); -// lowerLimitChanged = false; -// } + lowerLimitChanged = false; +} -// function renderConfidenceBars(){ -// if(!hrOrConfidenceChanged) { return; } +function renderConfidenceBars(){ + if(!hrOrConfidenceChanged) { return; } -// if(hrConfidence >= 85){ -// g.setColor(0, 255, 0); -// } else if (hrConfidence >= 50) { -// g.setColor(255, 255, 0); -// } else if(hrConfidence >= 0){ -// g.setColor(255, 0, 0); -// } else { -// g.setColor(255, 255, 255); -// } + if(hrConfidence >= 85){ + g.setColor(0, 255, 0); + } else if (hrConfidence >= 50) { + g.setColor(255, 255, 0); + } else if(hrConfidence >= 0){ + g.setColor(255, 0, 0); + } else { + g.setColor(255, 255, 255); + } -// g.fillRect(45, 110, 55, 150); -// g.fillRect(165, 110, 175, 150); -// } + g.fillRect(45, 110, 55, 150); + g.fillRect(165, 110, 175, 150); +} function renderButtonIcons() { g.setColor(255,255,255); g.setFontVector(14); - // + for Btn1 + //+ for Btn1 g.drawString("+", 222,50); - // Home for Btn2 + //Home for Btn2 g.drawLine(220, 118, 227, 110); g.drawLine(227, 110, 234, 118); g.drawPoly([222,117,222,125,232,125,232,117], false); g.drawRect(226,120,229,125); - // - for Btn3 + //- for Btn3 g.drawString("-", 222,165); } -// function buzz() -// { -// if(currentHeartRate > upperLimit) -// { -// Bangle.buzz(shortBuzzTimeInMs); -// setTimeout(() => { Bangle.buzz(shortBuzzTimeInMs); }, shortBuzzTimeInMs); -// setTimeout(() => { Bangle.buzz(shortBuzzTimeInMs); }, shortBuzzTimeInMs); -// } +function buzz() +{ + if(currentHeartRate > upperLimit) + { + Bangle.buzz(shortBuzzTimeInMs); + setTimeout(() => { Bangle.buzz(shortBuzzTimeInMs); }, shortBuzzTimeInMs); + setTimeout(() => { Bangle.buzz(shortBuzzTimeInMs); }, shortBuzzTimeInMs); + } -// if(currentHeartRate < lowerLimit) -// { -// Bangle.buzz(longBuzzTimeInMs); -// setTimeout(() => { Bangle.buzz(longBuzzTimeInMs); }, longBuzzTimeInMs); -// } -// } + if(currentHeartRate < lowerLimit) + { + Bangle.buzz(longBuzzTimeInMs); + setTimeout(() => { Bangle.buzz(longBuzzTimeInMs); }, longBuzzTimeInMs); + } +} -// function onHrm(hrm){ -// hrOrConfidenceChanged = (currentHeartRate !== hrm.bpm || hrConfidence !== hrm.confidence); -// currentHeartRate = hrm.bpm; -// hrConfidence = hrm.confidence; -// } +function onHrm(hrm){ + hrOrConfidenceChanged = (currentHeartRate !== hrm.bpm || hrConfidence !== hrm.confidence); + currentHeartRate = hrm.bpm; + hrConfidence = hrm.confidence; +} -// function setLimitSetterToLower() { -// resetHighlightTimeout(); +function setLimitSetterToLower() { + resetHighlightTimeout(); -// limitSetter = Setter.LOWER; -// console.log("Limit setter is lower"); + limitSetter = Setter.LOWER; + console.log("Limit setter is lower"); -// upperLimitChanged = true; -// lowerLimitChanged = true; + upperLimitChanged = true; + lowerLimitChanged = true; -// renderUpperLimit(); -// renderLowerLimit(); -// } + renderUpperLimit(); + renderLowerLimit(); +} -// function setLimitSetterToUpper() { -// resetHighlightTimeout(); +function setLimitSetterToUpper() { + resetHighlightTimeout(); -// limitSetter = Setter.UPPER; -// console.log("Limit setter is upper"); + limitSetter = Setter.UPPER; + console.log("Limit setter is upper"); -// upperLimitChanged = true; -// lowerLimitChanged = true; + upperLimitChanged = true; + lowerLimitChanged = true; -// renderLowerLimit(); -// renderUpperLimit(); -// } + renderLowerLimit(); + renderUpperLimit(); +} -// function setLimitSetterToNone() { -// limitSetter = Setter.NONE; -// console.log("Limit setter is none"); +function setLimitSetterToNone() { + limitSetter = Setter.NONE; + console.log("Limit setter is none"); -// upperLimitChanged = true; -// lowerLimitChanged = true; + upperLimitChanged = true; + lowerLimitChanged = true; -// renderLowerLimit(); -// renderUpperLimit(); -// } + renderLowerLimit(); + renderUpperLimit(); +} -// function incrementLimit(){ -// resetHighlightTimeout(); +function incrementLimit(){ + resetHighlightTimeout(); -// if (limitSetter === Setter.UPPER) { -// upperLimit++; -// renderUpperLimit(); -// console.log("Upper limit: " + upperLimit); -// upperLimitChanged = true; -// } else if(limitSetter === Setter.LOWER) { -// lowerLimit++; -// renderLowerLimit(); -// console.log("Lower limit: " + lowerLimit); -// lowerLimitChanged = true; -// } -// } + if (limitSetter === Setter.UPPER) { + upperLimit++; + renderUpperLimit(); + console.log("Upper limit: " + upperLimit); + upperLimitChanged = true; + } else if(limitSetter === Setter.LOWER) { + lowerLimit++; + renderLowerLimit(); + console.log("Lower limit: " + lowerLimit); + lowerLimitChanged = true; + } +} -// function decrementLimit(){ -// resetHighlightTimeout(); +function decrementLimit(){ + resetHighlightTimeout(); -// if (limitSetter === Setter.UPPER) { -// upperLimit--; -// renderUpperLimit(); -// console.log("Upper limit: " + upperLimit); -// upperLimitChanged = true; -// } else if(limitSetter === Setter.LOWER) { -// lowerLimit--; -// renderLowerLimit(); -// console.log("Lower limit: " + lowerLimit); -// lowerLimitChanged = true; -// } -// } + if (limitSetter === Setter.UPPER) { + upperLimit--; + renderUpperLimit(); + console.log("Upper limit: " + upperLimit); + upperLimitChanged = true; + } else if(limitSetter === Setter.LOWER) { + lowerLimit--; + renderLowerLimit(); + console.log("Lower limit: " + lowerLimit); + lowerLimitChanged = true; + } +} -// function resetHighlightTimeout() { -// if (setterHighlightTimeout) { -// clearTimeout(setterHighlightTimeout); -// } +function resetHighlightTimeout() { + if (setterHighlightTimeout) { + clearTimeout(setterHighlightTimeout); + } -// setterHighlightTimeout = setTimeout(setLimitSetterToNone, 2000); -// } + setterHighlightTimeout = setTimeout(setLimitSetterToNone, 2000); +} -// // Show launcher when middle button pressed -// function switchOffApp(){ -// Bangle.setHRMPower(0); -// Bangle.showLauncher(); -// } +// Show launcher when middle button pressed +function switchOffApp(){ + Bangle.setHRMPower(0); + Bangle.showLauncher(); +} -// // special function to handle display switch on -// Bangle.on('lcdPower', (on) => { -// g.clear(); -// if (on) { -// Bangle.drawWidgets(); -// // call your app function here -// renderLowerLimitBackground(); -// renderUpperLimitBackground(); -// lowerLimitChanged = true; -// upperLimitChanged = true; -// drawTrainingHeartRate(); -// } -// }); +// special function to handle display switch on +Bangle.on('lcdPower', (on) => { + g.clear(); + if (on) { + Bangle.drawWidgets(); + // call your app function here + renderLowerLimitBackground(); + renderUpperLimitBackground(); + lowerLimitChanged = true; + upperLimitChanged = true; + drawTrainingHeartRate(); + } +}); -// Bangle.setHRMPower(1); -// Bangle.on('HRM', onHrm); +Bangle.setHRMPower(1); +Bangle.on('HRM', onHrm); -// setWatch(incrementLimit, BTN1, {edge:"rising", debounce:50, repeat:true}); +setWatch(incrementLimit, BTN1, {edge:"rising", debounce:50, repeat:true}); setWatch(switchOffApp, BTN2, {repeat:false,edge:"falling"}); +setWatch(decrementLimit, BTN3, {edge:"rising", debounce:50, repeat:true}); +setWatch(setLimitSetterToLower, BTN4, {edge:"rising", debounce:50, repeat:true}); +setWatch(setLimitSetterToUpper, BTN5, { edge: "rising", debounce: 50, repeat: true }); -renderButtonIcons -// setWatch(decrementLimit, BTN3, {edge:"rising", debounce:50, repeat:true}); -// setWatch(setLimitSetterToLower, BTN4, {edge:"rising", debounce:50, repeat:true}); -// setWatch(setLimitSetterToUpper, BTN5, { edge: "rising", debounce: 50, repeat: true }); +g.clear(); +Bangle.loadWidgets(); +Bangle.drawWidgets(); +//drawTrainingHeartRate(); -// g.clear(); -// Bangle.loadWidgets(); -// Bangle.drawWidgets(); -// //drawTrainingHeartRate(); - -// // refesh every sec -// renderLowerLimitBackground(); -// renderUpperLimitBackground(); -// setInterval(drawTrainingHeartRate, 1000); +// refesh every sec +renderLowerLimitBackground(); +renderUpperLimitBackground(); +setInterval(drawTrainingHeartRate, 1000); From 21b1eaa4237d8a982f589e06373b8497023fb545 Mon Sep 17 00:00:00 2001 From: Markus Deibel Date: Sun, 29 Mar 2020 09:02:21 +0200 Subject: [PATCH 31/59] Fixes eventhandler for BTN2 --- apps/wohrm/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/wohrm/app.js b/apps/wohrm/app.js index cc5dbc286..f077a9feb 100644 --- a/apps/wohrm/app.js +++ b/apps/wohrm/app.js @@ -297,7 +297,7 @@ Bangle.setHRMPower(1); Bangle.on('HRM', onHrm); setWatch(incrementLimit, BTN1, {edge:"rising", debounce:50, repeat:true}); -setWatch(switchOffApp, BTN2, {repeat:false,edge:"falling"}); +setWatch(switchOffApp, BTN2, {edge:"rising", debounce:50, repeat:true,}); setWatch(decrementLimit, BTN3, {edge:"rising", debounce:50, repeat:true}); setWatch(setLimitSetterToLower, BTN4, {edge:"rising", debounce:50, repeat:true}); setWatch(setLimitSetterToUpper, BTN5, { edge: "rising", debounce: 50, repeat: true }); From 7774b095b974e72ba2c979fd45352f37012f167c Mon Sep 17 00:00:00 2001 From: Markus Deibel Date: Sun, 29 Mar 2020 09:05:23 +0200 Subject: [PATCH 32/59] BTN2 handler --- apps/wohrm/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/wohrm/app.js b/apps/wohrm/app.js index f077a9feb..ec048c8a1 100644 --- a/apps/wohrm/app.js +++ b/apps/wohrm/app.js @@ -297,7 +297,7 @@ Bangle.setHRMPower(1); Bangle.on('HRM', onHrm); setWatch(incrementLimit, BTN1, {edge:"rising", debounce:50, repeat:true}); -setWatch(switchOffApp, BTN2, {edge:"rising", debounce:50, repeat:true,}); +setWatch(switchOffApp, BTN2, {edge:"rising", debounce:50, repeat:true}); setWatch(decrementLimit, BTN3, {edge:"rising", debounce:50, repeat:true}); setWatch(setLimitSetterToLower, BTN4, {edge:"rising", debounce:50, repeat:true}); setWatch(setLimitSetterToUpper, BTN5, { edge: "rising", debounce: 50, repeat: true }); From 5507eb04be552a801699f388ff72a8b552e7acd0 Mon Sep 17 00:00:00 2001 From: Markus Deibel Date: Sun, 29 Mar 2020 09:20:26 +0200 Subject: [PATCH 33/59] Only buzz on high confidence --- apps.json | 2 +- apps/wohrm/ChangeLog | 1 + apps/wohrm/app.js | 44 ++++++++++++++++++++++++++++++++------------ 3 files changed, 34 insertions(+), 13 deletions(-) diff --git a/apps.json b/apps.json index e5b0ab15e..93fa75524 100644 --- a/apps.json +++ b/apps.json @@ -816,7 +816,7 @@ { "id": "wohrm", "name": "Workout HRM", "icon": "app.png", - "version":"0.03", + "version":"0.04", "description": "Workout heart rate monitor notifies you with a buzz if your heart rate goes above or below the set limits.", "tags": "hrm,workout", "type": "app", diff --git a/apps/wohrm/ChangeLog b/apps/wohrm/ChangeLog index 36c08b9fd..f836f6f71 100644 --- a/apps/wohrm/ChangeLog +++ b/apps/wohrm/ChangeLog @@ -1,3 +1,4 @@ +0.04: Only buzz on high confidence (>85%) 0.03: Optimized rendering for the background 0.02: Adapted to new App code layout 0.01: Only tested on the emulator. diff --git a/apps/wohrm/app.js b/apps/wohrm/app.js index ec048c8a1..2e147251c 100644 --- a/apps/wohrm/app.js +++ b/apps/wohrm/app.js @@ -4,6 +4,10 @@ const Setter = { UPPER: 'upper', LOWER: 'lower' }; + +const Confidence = { + NONE +} const shortBuzzTimeInMs = 50; const longBuzzTimeInMs = 200; @@ -18,8 +22,8 @@ let limitSetter = Setter.NONE; let currentHeartRate = 0; let hrConfidence = -1; -let hrOrConfidenceChanged = true; - +let hrChanged = true; +let confidenceChanged = true; let setterHighlightTimeout; @@ -76,7 +80,7 @@ function renderLowerLimitBackground() { function drawTrainingHeartRate() { //Only redraw if the display is on if (Bangle.isLCDOn()) { - renderButtonIcons(); + renderUpperLimit(); @@ -108,7 +112,7 @@ function renderUpperLimit() { } function renderCurrentHeartRate() { - if(!hrOrConfidenceChanged) { return; } + if(!hrChanged) { return; } g.setColor(255,255,255); g.fillRect(45, 110, 165, 150); @@ -120,6 +124,8 @@ function renderCurrentHeartRate() { //Reset alignment to defaults g.setFontAlign(-1, -1, 0); + + hrChanged = false; } function renderLowerLimit() { @@ -140,7 +146,7 @@ function renderLowerLimit() { } function renderConfidenceBars(){ - if(!hrOrConfidenceChanged) { return; } + if(!confidenceChanged) { return; } if(hrConfidence >= 85){ g.setColor(0, 255, 0); @@ -154,6 +160,8 @@ function renderConfidenceBars(){ g.fillRect(45, 110, 55, 150); g.fillRect(165, 110, 175, 150); + + confidenceChanged = false; } function renderButtonIcons() { @@ -176,24 +184,33 @@ function renderButtonIcons() { function buzz() { + // Do not buzz if not confident + if(hrConfidence < 85) { return; } + if(currentHeartRate > upperLimit) { Bangle.buzz(shortBuzzTimeInMs); - setTimeout(() => { Bangle.buzz(shortBuzzTimeInMs); }, shortBuzzTimeInMs); - setTimeout(() => { Bangle.buzz(shortBuzzTimeInMs); }, shortBuzzTimeInMs); + setTimeout(() => { Bangle.buzz(shortBuzzTimeInMs); }, shortBuzzTimeInMs+10); + setTimeout(() => { Bangle.buzz(shortBuzzTimeInMs); }, shortBuzzTimeInMs+10); } if(currentHeartRate < lowerLimit) { Bangle.buzz(longBuzzTimeInMs); - setTimeout(() => { Bangle.buzz(longBuzzTimeInMs); }, longBuzzTimeInMs); + setTimeout(() => { Bangle.buzz(longBuzzTimeInMs); }, longBuzzTimeInMs+10); } } function onHrm(hrm){ - hrOrConfidenceChanged = (currentHeartRate !== hrm.bpm || hrConfidence !== hrm.confidence); - currentHeartRate = hrm.bpm; - hrConfidence = hrm.confidence; + if(currentHeartRate !== hrm.bpm){ + currentHeartRate = hrm.bpm; + hrChanged = true; + } + + if(hrConfidence !== hrm.confidence) { + hrConfidence = hrm.confidence; + confidenceChanged = true; + } } function setLimitSetterToLower() { @@ -284,6 +301,7 @@ Bangle.on('lcdPower', (on) => { g.clear(); if (on) { Bangle.drawWidgets(); + renderButtonIcons(); // call your app function here renderLowerLimitBackground(); renderUpperLimitBackground(); @@ -307,7 +325,9 @@ Bangle.loadWidgets(); Bangle.drawWidgets(); //drawTrainingHeartRate(); -// refesh every sec +renderButtonIcons(); renderLowerLimitBackground(); renderUpperLimitBackground(); + +// refesh every sec setInterval(drawTrainingHeartRate, 1000); From 18abff1d2f68ad7b78a3d189ed4c4cf258063e8d Mon Sep 17 00:00:00 2001 From: Markus Deibel Date: Sun, 29 Mar 2020 09:22:36 +0200 Subject: [PATCH 34/59] Stupid coding error fixed --- apps/wohrm/app.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/apps/wohrm/app.js b/apps/wohrm/app.js index 2e147251c..979a50205 100644 --- a/apps/wohrm/app.js +++ b/apps/wohrm/app.js @@ -4,10 +4,6 @@ const Setter = { UPPER: 'upper', LOWER: 'lower' }; - -const Confidence = { - NONE -} const shortBuzzTimeInMs = 50; const longBuzzTimeInMs = 200; From d273d8860b35cacc4792bd0f64fe2e4f964cff09 Mon Sep 17 00:00:00 2001 From: Markus Deibel Date: Sun, 29 Mar 2020 09:33:52 +0200 Subject: [PATCH 35/59] Re-enable buzzing --- apps/wohrm/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/wohrm/app.js b/apps/wohrm/app.js index 979a50205..dff69d76b 100644 --- a/apps/wohrm/app.js +++ b/apps/wohrm/app.js @@ -87,7 +87,7 @@ function drawTrainingHeartRate() { renderConfidenceBars(); } - //buzz(); + buzz(); } function renderUpperLimit() { From 39621bfae0c659e354840b31ff092e51ab6dca26 Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Fri, 3 Apr 2020 01:18:21 +0200 Subject: [PATCH 36/59] Settings: Add support for app/widget settings Apps and widgets can add a `.settings.js` file which can be opened from the "App/widget settings" submenu. This file should define a single function to configure the app/widget. The function is passed a `back` argument, which can be used to return to the settings menu by calling `back()`. Example `.settings.js`: ``` function settings(back) { const mySettingsMenu = { '': { 'title': 'My Widget' }, '< Back': back, // go back to settings menu 'Sound': { value: false, format: s => s ? 'on' : 'off', onchange: s => {if(s) Bangle.beep()} // TODO: save new value }, }; E.showMenu(mySettingsMenu) } ``` --- apps.json | 2 +- apps/setting/ChangeLog | 1 + apps/setting/settings.js | 47 ++++++++++++++++++++++++++++++++++++++++ js/appinfo.js | 2 ++ 4 files changed, 51 insertions(+), 1 deletion(-) diff --git a/apps.json b/apps.json index 2bd8ef7bf..5b269e44f 100644 --- a/apps.json +++ b/apps.json @@ -117,7 +117,7 @@ { "id": "setting", "name": "Settings", "icon": "settings.png", - "version":"0.07", + "version":"0.08", "description": "A menu for setting up Bangle.js", "tags": "tool,system", "storage": [ diff --git a/apps/setting/ChangeLog b/apps/setting/ChangeLog index d29a312d0..0cfa04bf0 100644 --- a/apps/setting/ChangeLog +++ b/apps/setting/ChangeLog @@ -4,3 +4,4 @@ 0.05: Fix Settings json 0.06: Remove distance setting as there's a separate app for Locale now 0.07: Added vibrate as beep workaround +0.08: Add support for app/widget settings diff --git a/apps/setting/settings.js b/apps/setting/settings.js index 9d5fa2775..6f399428d 100644 --- a/apps/setting/settings.js +++ b/apps/setting/settings.js @@ -114,6 +114,7 @@ function showMainMenu() { } }, 'Set Time': showSetTimeMenu, + 'App/widget settings': showAppSettingsMenu, 'Reset Settings': showResetMenu, 'Turn Off': Bangle.off, '< Back': ()=> {load();} @@ -295,4 +296,50 @@ function showSetTimeMenu() { return E.showMenu(timemenu); } +function showAppSettingsMenu(){ + let appmenu = { + '': { + 'title': 'App Settings', + }, + '< Back': showMainMenu, + } + const apps = storage.list(/\.info$/). + map(app => storage.readJSON(app, 1)). + filter(app => app && app.settings). + sort((a, b) => a.sortorder - b.sortorder) + if (apps.length === 0) { + appmenu['No app has settings'] = () => {}; + } + apps.forEach(function (app) { + appmenu[app.name] = () => {showAppSettings(app)}; + }) + E.showMenu(appmenu) +} +function showAppSettings(app) { + const showError = msg => { + E.showMessage(`${app.name}:\n${msg}!\n\nBTN1 to go back`); + setWatch(showAppSettingsMenu, BTN1, { repeat: false }); + } + let appSettings = storage.read(app.settings); + if (!appSettings) { + return showError('Missing settings'); + } + try { + appSettings = eval(appSettings); + } catch (e) { + console.log(`${app.name} settings error:`, e) + return showError('Error in settings'); + } + if (typeof appSettings !== "function") { + return showError('Invalid settings'); + } + try { + // pass showAppSettingsMenu as "back" argument + appSettings(showAppSettingsMenu); + } catch (e) { + console.log(`${app.name} settings error:`, e) + return showError('Error in settings'); + } +} + showMainMenu(); diff --git a/js/appinfo.js b/js/appinfo.js index 613d15379..f4ab498b1 100644 --- a/js/appinfo.js +++ b/js/appinfo.js @@ -60,6 +60,8 @@ var AppInfo = { if (app.type && app.type!="app") json.type = app.type; if (fileContents.find(f=>f.name==app.id+".app.js")) json.src = app.id+".app.js"; + if (fileContents.find(f=>f.name==app.id+".settings.js")) + json.settings = app.id+".settings.js"; if (fileContents.find(f=>f.name==app.id+".img")) json.icon = app.id+".img"; if (app.sortorder) json.sortorder = app.sortorder; From bbc6cf35c15a5b0d7c217d5ddaccd2e265e28bc9 Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Fri, 3 Apr 2020 01:41:57 +0200 Subject: [PATCH 37/59] Battery Widget with percentage: add settings (percentage/color/charger) Depends on settings 0.08 --- apps.json | 7 +++- apps/widbatpc/ChangeLog | 1 + apps/widbatpc/settings.js | 58 +++++++++++++++++++++++++++++ apps/widbatpc/widget.js | 77 ++++++++++++++++++++++++++++++++++----- 4 files changed, 131 insertions(+), 12 deletions(-) create mode 100644 apps/widbatpc/settings.js diff --git a/apps.json b/apps.json index 5b269e44f..58448d6f7 100644 --- a/apps.json +++ b/apps.json @@ -336,13 +336,16 @@ }, { "id": "widbatpc", "name": "Battery Level Widget (with percentage)", + "shortName": "Battery Widget", "icon": "widget.png", - "version":"0.06", + "version": "0.07", "description": "Show the current battery level and charging status in the top right of the clock, with charge percentage", "tags": "widget,battery", "type":"widget", "storage": [ - {"name":"widbatpc.wid.js","url":"widget.js"} + {"name":"widbatpc.wid.js","url":"widget.js"}, + {"name":"widbatpc.settings.js","url":"settings.js"}, + {"name":"widbatpc.settings.json","content": "{}"} ] }, { "id": "widbt", diff --git a/apps/widbatpc/ChangeLog b/apps/widbatpc/ChangeLog index 3988729c3..245ec3af3 100644 --- a/apps/widbatpc/ChangeLog +++ b/apps/widbatpc/ChangeLog @@ -3,3 +3,4 @@ 0.04: Ensure redrawing works with variable size widget system 0.05: Change color depending on battery level, cloned from widbat 0.06: Show battery percentage as text +0.07: Add settings: percentage/color/charger icon diff --git a/apps/widbatpc/settings.js b/apps/widbatpc/settings.js new file mode 100644 index 000000000..9ea86ed39 --- /dev/null +++ b/apps/widbatpc/settings.js @@ -0,0 +1,58 @@ +// This file should contain exactly one function, which shows the app's settings +/** + * @param {function} back Use back() to return to settings menu + */ +function settings(back) { + const SETTINGS_FILE = 'widbatpc.settings.json' + const COLORS = ['By Level', 'Green', 'Monochrome'] + + // initialize with default settings... + let s = { + 'color': COLORS[0], + 'percentage': true, + 'charger': true, + } + // ...and overwrite them with any saved values + // This way saved values are preserved if a new version adds more settings + const storage = require('Storage') + const saved = storage.readJSON(SETTINGS_FILE, 1) || {} + for (const key in saved) { + s[key] = saved[key] + } + + // creates a function to safe a specific setting, e.g. save('color')(1) + function save(key) { + return function (value) { + s[key] = value + storage.write(SETTINGS_FILE, s) + WIDGETS["batpc"].reload() + } + } + + const onOffFormat = b => (b ? 'on' : 'off') + const menu = { + '': { 'title': 'Battery Widget' }, + '< Back': back, + 'Percentage': { + value: s.percentage, + format: onOffFormat, + onchange: save('percentage'), + }, + 'Charging Icon': { + value: s.charger, + format: onOffFormat, + onchange: save('charger'), + }, + 'Color': { + format: () => s.color, + onchange: function () { + // cycles through options + const oldIndex = COLORS.indexOf(s.color) + const newIndex = (oldIndex + 1) % COLORS.length + s.color = COLORS[newIndex] + save('color')(s.color) + }, + }, + } + E.showMenu(menu) +} diff --git a/apps/widbatpc/widget.js b/apps/widbatpc/widget.js index 7100dc111..a679f6721 100644 --- a/apps/widbatpc/widget.js +++ b/apps/widbatpc/widget.js @@ -1,20 +1,62 @@ (function(){ +const DEFAULTS = { + 'color': 'By Level', + 'percentage': true, + 'charger': true, +} +const COLORS = { + 'white': -1, + 'charging': 0x07E0, // "Green" + 'high': 0x05E0, // slightly darker green + 'ok': 0xFD20, // "Orange" + 'low':0xF800, // "Red" +} +const SETTINGS_FILE = 'widbatpc.settings.json' + +let settings +function loadSettings() { + settings = require('Storage').readJSON(SETTINGS_FILE, 1) || {} +} +function setting(key) { + if (!settings) { loadSettings() } + return (key in settings) ? settings[key] : DEFAULTS[key] +} + const levelColor = (l) => { - if (Bangle.isCharging()) return 0x07E0; // "Green" - if (l >= 50) return 0x05E0; // slightly darker green - if (l >= 15) return 0xFD20; // "Orange" - return 0xF800; // "Red" + // "charging" is very bright -> percentage is hard to read, "high" is ok(ish) + const green = setting('percentage') ? COLORS.high : COLORS.charging + switch (setting('color')) { + case 'Monochrome': return COLORS.white; // no chance of reading the percentage here :-( + case 'Green': return green; + case 'By Level': // fall through + default: + if (setting('charger')) { + // charger icon -> always make percentage readable + if (Bangle.isCharging() || l >= 50) return green; + } else { + // no icon -> brightest green to indicate charging, even when showing percentage + if (Bangle.isCharging()) return COLORS.charging; + if (l >= 50) return COLORS.high; + } + if (l >= 15) return COLORS.ok; + return COLORS.low; + } +} +const chargerColor = () => { + return (setting('color') === 'Monochrome') ? COLORS.white : COLORS.charging } function setWidth() { - WIDGETS["bat"].width = 40 + (Bangle.isCharging()?16:0); + WIDGETS["batpc"].width = 40; + if (Bangle.isCharging() && setting('charger')) { + WIDGETS["batpc"].width += 16; + } } function draw() { var s = 39; var x = this.x, y = this.y; - const l = E.getBattery(), c = levelColor(l); - if (Bangle.isCharging()) { - g.setColor(c).drawImage(atob( + if (Bangle.isCharging() && setting('charger')) { + g.setColor(chargerColor()).drawImage(atob( "DhgBHOBzgc4HOP////////////////////3/4HgB4AeAHgB4AeAHgB4AeAHg"),x,y); x+=16; } @@ -22,8 +64,13 @@ function draw() { g.fillRect(x,y+2,x+s-4,y+21); g.clearRect(x+2,y+4,x+s-6,y+19); g.fillRect(x+s-3,y+10,x+s,y+14); + const l = E.getBattery(), + c = levelColor(l); g.setColor(c).fillRect(x+4,y+6,x+4+l*(s-12)/100,y+17); g.setColor(-1); + if (!setting('percentage')) { + return; + } g.setFontAlign(-1,-1); if (l >= 100) { g.setFont('4x6', 2); @@ -34,6 +81,16 @@ function draw() { g.drawString(l, x + 6, y + 4); } } +// reload widget, e.g. when settings have changed +function reload() { + loadSettings() + // need to redraw all widgets, because changing the "charger" setting + // can affect the width and mess with the whole widget layout + setWidth() + g.clear(); + Bangle.drawWidgets(); +} + Bangle.on('charging',function(charging) { if(charging) Bangle.buzz(); setWidth(); @@ -43,7 +100,7 @@ Bangle.on('charging',function(charging) { var batteryInterval; Bangle.on('lcdPower', function(on) { if (on) { - WIDGETS["bat"].draw(); + WIDGETS["batpc"].draw(); // refresh once a minute if LCD on if (!batteryInterval) batteryInterval = setInterval(draw, 60000); @@ -54,6 +111,6 @@ Bangle.on('lcdPower', function(on) { } } }); -WIDGETS["bat"]={area:"tr",width:40,draw:draw}; +WIDGETS["batpc"]={area:"tr",width:40,draw:draw,reload:reload}; setWidth(); })() From c135c70f7eb08dd127e909fe943f2a8cd7c47c49 Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Fri, 3 Apr 2020 19:56:30 +0200 Subject: [PATCH 38/59] Settings: load app settings in their own scope --- apps/setting/settings.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/setting/settings.js b/apps/setting/settings.js index 6f399428d..f13ad961f 100644 --- a/apps/setting/settings.js +++ b/apps/setting/settings.js @@ -325,7 +325,7 @@ function showAppSettings(app) { return showError('Missing settings'); } try { - appSettings = eval(appSettings); + appSettings = eval('('+appSettings+')'); } catch (e) { console.log(`${app.name} settings error:`, e) return showError('Error in settings'); From fc7e61e2caed761458bb3d740cefdd125d800be6 Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Fri, 3 Apr 2020 19:59:15 +0200 Subject: [PATCH 39/59] Settings: minor reformat --- apps/setting/settings.js | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/apps/setting/settings.js b/apps/setting/settings.js index f13ad961f..38ce9f886 100644 --- a/apps/setting/settings.js +++ b/apps/setting/settings.js @@ -298,15 +298,13 @@ function showSetTimeMenu() { function showAppSettingsMenu(){ let appmenu = { - '': { - 'title': 'App Settings', - }, + '': {'title': 'App Settings'}, '< Back': showMainMenu, } - const apps = storage.list(/\.info$/). - map(app => storage.readJSON(app, 1)). - filter(app => app && app.settings). - sort((a, b) => a.sortorder - b.sortorder) + const apps = storage.list(/\.info$/) + .map(app => storage.readJSON(app, 1)) + .filter(app => app && app.settings) + .sort((a, b) => a.sortorder - b.sortorder) if (apps.length === 0) { appmenu['No app has settings'] = () => {}; } From 3b056d9e855c7cfaca021c2077a0c17d21a0e2a2 Mon Sep 17 00:00:00 2001 From: ArticNet Date: Sat, 4 Apr 2020 03:12:26 +0900 Subject: [PATCH 40/59] Added Dot Clock initial release --- apps.json | 13 +++ apps/dotclock/ChangeLog | 1 + apps/dotclock/clock-dot-icon.js | 1 + apps/dotclock/clock-dot.js | 162 ++++++++++++++++++++++++++++++++ apps/dotclock/clock-dot.png | Bin 0 -> 1844 bytes 5 files changed, 177 insertions(+) create mode 100644 apps/dotclock/ChangeLog create mode 100644 apps/dotclock/clock-dot-icon.js create mode 100644 apps/dotclock/clock-dot.js create mode 100644 apps/dotclock/clock-dot.png diff --git a/apps.json b/apps.json index 90194b1c3..5f072c11e 100644 --- a/apps.json +++ b/apps.json @@ -889,5 +889,18 @@ {"name":"barclock.app.js","url":"clock-bar.js"}, {"name":"barclock.img","url":"clock-bar-icon.js","evaluate":true} ] + }, + { "id": "dotclock", + "name": "Dot Clock", + "icon": "clock-dot.png", + "version":"0.01", + "description": "A Minimal Dot Analog Clock", + "tags": "clock", + "type":"clock", + "allow_emulator":true, + "storage": [ + {"name":"dotclock.app.js","url":"clock-dot.js"}, + {"name":"dotclock.img","url":"clock-dot-icon.js","evaluate":true} + ] } ] diff --git a/apps/dotclock/ChangeLog b/apps/dotclock/ChangeLog new file mode 100644 index 000000000..26f95bbde --- /dev/null +++ b/apps/dotclock/ChangeLog @@ -0,0 +1 @@ +0.01: Based on the Analog Clock app, minimal dot interface \ No newline at end of file diff --git a/apps/dotclock/clock-dot-icon.js b/apps/dotclock/clock-dot-icon.js new file mode 100644 index 000000000..62d1dea2a --- /dev/null +++ b/apps/dotclock/clock-dot-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("AH4A/AH4A/AH4AmgkEF/4A/KyxodDpHX66YtF5AA/AH4AobDYbTF94A/AH4A/AG/X64FIAgILEACcEggvIAIQCGAYgfPF+qPUF5QA/AH4AGyAuuAAJf/ABEEggbtF94A/AH4A/bCzqdF96Y/F/4A/AH4A/AGIA==")) \ No newline at end of file diff --git a/apps/dotclock/clock-dot.js b/apps/dotclock/clock-dot.js new file mode 100644 index 000000000..a4b3f260f --- /dev/null +++ b/apps/dotclock/clock-dot.js @@ -0,0 +1,162 @@ +let g; +let Bangle; + +const locale = require('locale'); +const p = Math.PI / 2; +const pRad = Math.PI / 180; +const faceWidth = 100; // watch face radius +let timer = null; +let currentDate = new Date(); +let hourRadius = 60; +let minRadius = 80; +const centerPx = g.getWidth() / 2; + +const seconds = (angle) => { + const a = angle * pRad; + const x = centerPx + Math.sin(a) * faceWidth; + const y = centerPx - Math.cos(a) * faceWidth; + + // if 15 degrees, make hour marker larger + const radius = (angle % 15) ? 2 : 4; + g.fillCircle(x, y, radius); +}; + +const hourDot = (angle,radius) => { + const a = angle * pRad; + const x = centerPx + Math.sin(a) * hourRadius; + const y = centerPx - Math.cos(a) * hourRadius; + g.fillCircle(x, y, radius); +}; + +const minDot = (angle,radius) => { + const a = angle * pRad; + const x = centerPx + Math.sin(a) * minRadius; + const y = centerPx - Math.cos(a) * minRadius; + g.fillCircle(x, y, radius); +}; + +const drawAll = () => { + g.clear(); + currentDate = new Date(); + // draw hands first + onMinute(); + // draw seconds + const currentSec = currentDate.getSeconds(); + // draw all secs + + for (let i = 0; i < 60; i++) { + if (i > currentSec) { + g.setColor(0, 0, 0.6); + } else { + g.setColor(0.3, 0.3, 1); + } + seconds((360 * i) / 60); + } + onSecond(); +}; + +const resetSeconds = () => { + g.setColor(0, 0, 0.6); + for (let i = 0; i < 60; i++) { + seconds((360 * i) / 60); + } +}; + +const drawMin = () => { + g.setColor(0.5, 0.5, 0.5); + for (let i = 0; i < 60; i++) { + minDot((360 * i) / 60,1); + } +}; + +const drawHour = () => { + g.setColor(0.5, 0.5, 0.5); + for (let i = 0; i < 12; i++) { + hourDot((360 * 5 * i) / 60,1); + } +}; + +const onSecond = () => { + g.setColor(0.3, 0.3, 1); + seconds((360 * currentDate.getSeconds()) / 60); + if (currentDate.getSeconds() === 59) { + resetSeconds(); + onMinute(); + } + g.setColor(1, 0.7, 0.2); + currentDate = new Date(); + seconds((360 * currentDate.getSeconds()) / 60); + g.setColor(1, 1, 1); +}; + +const drawDate = () => { + g.reset(); + g.setColor(1, 1, 1); + g.setFont('6x8', 2); + + const dayString = locale.dow(currentDate, true); + // pad left date + const dateString = ((currentDate.getDate() < 10) ? '0' : '') + currentDate.getDate().toString(); + const dateDisplay = `${dayString} ${dateString}`; + // console.log(`${dayString}|${dateString}`); + // center date + const l = (g.getWidth() - g.stringWidth(dateDisplay)) / 2; + const t = centerPx - 6 ; + g.drawString(dateDisplay, l, t); + // console.log(l, t); +}; +const onMinute = () => { + if (currentDate.getHours() === 0 && currentDate.getMinutes() === 0) { + g.clear(); + resetSeconds(); + } + // clear existing hands + g.setColor(0, 0, 0); + hourDot((360 * currentDate.getHours()) / 12,4); + minDot((360 * currentDate.getMinutes()) / 60,3); + + // Hour + drawHour(); + // Minute + drawMin(); + + // get new date, then draw new hands + currentDate = new Date(); + g.setColor(1, 0, 0); + // Hour + hourDot((360 * currentDate.getHours()) / 12,4); + g.setColor(1, 0.9, 0.9); + // Minute + minDot((360 * currentDate.getMinutes()) / 60,3); + if (currentDate.getHours() >= 0 && currentDate.getMinutes() === 0) { + Bangle.buzz(); + } + drawDate(); +}; + +const startTimers = () => { + timer = setInterval(onSecond, 1000); +}; + +Bangle.on('lcdPower', (on) => { + if (on) { + // g.clear(); + drawAll(); + startTimers(); + Bangle.drawWidgets(); + } else { + if (timer) { + clearInterval(timer); + } + } +}); + +g.clear(); +resetSeconds(); +startTimers(); +drawAll(); +Bangle.loadWidgets(); +Bangle.drawWidgets(); + +// Show launcher when middle button pressed +setWatch(Bangle.showLauncher, BTN2, { repeat: false, edge: "falling" }); diff --git a/apps/dotclock/clock-dot.png b/apps/dotclock/clock-dot.png new file mode 100644 index 0000000000000000000000000000000000000000..702ac90655f0a552c6567174ddba0330134694ef GIT binary patch literal 1844 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA1SD@HXQ2>tmIipR1RclAn~S zSCLx)lxJYDv9BmdOwLX%QAkQn&&;z`dcS+Wl0s&Rtx~wDuYqrYb81GWM^#a3aFt(3 za#eP+Wr~u$9hXgo70`g()RIJnirk#MVyg;UC9t_xKsHENUr7P1q$Jx`DZ)2E!8yMu zRl!uxRL?-kj!VI&C?(A*$i)q+8OXC$$|xx*u+rBrFE7_CH`dE9O4m2Ew6xSWFw!?N z(gmu}Ew0QfNvzP#D^>;>0WrfRwK%ybv!En1KTiQQ?NYIsRz8p8Cv zVyO3l0ih3)(KpmH&_`CDT9JuEIY!B| zRX}D%YEFbpW^QU;G0;@FD-e>AI3%6(bMlLVfyp}6R>=@-7d#%Uz;eF%DL^S>G$~JK z=YXR8w9Fi!Tyc=QlY*zKvzei#nVGJU9>f@6q*(#=W~NoTB$fbG85tNE=o**+QHX(& zm8pf5fr++(rIi81gJ9LbypWPul1NBBC`BvS0Co8KT6ts^m*f{!f`uT-JUF!w!h>*g zGQsIvK>-}gR*A`=P`6boD9TSMO-@Y#dkbhBM7B6Tt)x7$DAh3?7{Rtmj%jI`!1$?D z2mqyA1r6WCA_ZeZ1&~iPQ8kulqyi1a?L~d41NA`}59UG}eGEU?fE6I+RG>bH7_bBY z7A5-dvINM1mqw|1z#^y!Sk{ysSzpG$z}S=tj2(Z zSm^Xl&UEYUHp-l`WTsKfw)b@_bNAKmkM~@6s?@c!JD&X?)4EfUno6qb?CFmV{rXjt zyH)kKP3^q%uPg1(KfnCBMs9=aCNIDB-yQYxGad$9u$7N3u#Q`C+>g82BDrf_-?=kB zftT&xuiX4-?e$fmzwhk7HpSx=*A-K)evMUW9R3{sYb945wLbLLOKqBfo$$M>Pnr&u zPm|OCxccZzq59}Gu7{EnvPH|5ueOLg>g9Ht^YrPDPd2Ug`e}E~d)DNiJ0m+|AI*Ky z!YO#C=1oj48v|)d6 ztL5|RF0uQq-MTL-LXxB2gm3D;9i&-d-8xNU%iV_JjaN2*vQy_5xH)0{uC~3kFD8Co zw^UwzL;6YAzxrQ+wFYN_M`SSr1Gg{;GcwGYBLNhg>gnPb64CnhMj%&%0#8HYTfVtV zf7`dYzZ7`wIN`*m7-OS$wXd)(4`&ft((kXUd~L*&ehb4$yno}Jj)(J`ZC)5o1H z9|YT;zN_=$Qob-Nd`)NUq3U|G$+u2?o8^A$s?xjZWoOxU7l!_czp`-8cKLIAW{dEg zS)4ZYV)9JSn?Bx)WnaB~7r^=6`M~L_U)zq0{#(E(8_78NgXirnGoJB)DmzbCKbLh* G2~7Zz)0$-f literal 0 HcmV?d00001 From 9d5751405871766fed7cb5c5ee3ac31ae4031c1d Mon Sep 17 00:00:00 2001 From: MaBecker Date: Fri, 3 Apr 2020 20:34:38 +0200 Subject: [PATCH 41/59] add cs_CZ with support from Standa --- apps/locale/locales.js | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/apps/locale/locales.js b/apps/locale/locales.js index 7f6fbaef9..43e073cd1 100644 --- a/apps/locale/locales.js +++ b/apps/locale/locales.js @@ -1,4 +1,4 @@ - +/* jshint esversion: 6 */ const distanceUnits = { // how many meters per X? "m" : 1, "yd" : 0.9144, @@ -387,4 +387,21 @@ var locales = { abday: "Dom,Seg,Ter,Qua,Qui,Sex,Sab", day: "Domingo,Segunda-feira,Terça-feira,Quarta-feira,Quinta-feira,Sexta-feira,Sábado", trans: { yes: "sim", Yes: "Sim", no: "não", No: "Não", ok: "certo", on: "ligado", off: "desligado" }}, + "cs_CZ": { + lang: "cs_CZ", + decimal_point: ",", + thousands_sep: " ", + currency_symbol: "Kč", + int_curr_symbol: " CZK", + speed: 'kmh', + distance: { "0": "m", "1": "km" }, + temperature: '°C', + ampm: {0:"dop",1:"odp"}, + timePattern: { 0: "%HH:%MM:%SS ", 1: "%HH:%MM" }, + datePattern: { 0: "%d. %b %Y", 1: "%d.%m.%Y" }, // "30. led 2020" // "30.01.2020"(short) + abmonth: "led,úno,bře,dub,kvě,čvn,čvc,srp,zář,říj,lis,pro", + month: "leden,únor,březen,duben,květen,červen,červenec,srpen,září,říjen,listopad,prosinec", + abday: "ne,po,út,st,čt,pá,so", + day: "neděle,pondělí,úterý,středa,čtvrtek,pátek,sobota", + trans: { yes: "tak", Yes: "Tak", no: "nie", No: "Nie", ok: "ok", on: "na", off: "poza" }} }; From 3a70e315b8e5fec76a1ea84f7584cf9444ad0b6b Mon Sep 17 00:00:00 2001 From: MaBecker Date: Fri, 3 Apr 2020 20:41:33 +0200 Subject: [PATCH 42/59] update_app_miclock no commands before jshint --- apps.json | 2 +- apps/miclock/ChangeLog | 1 + apps/miclock/clock-mixed.js | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/apps.json b/apps.json index dcb27d1d1..3d4a6beee 100644 --- a/apps.json +++ b/apps.json @@ -662,7 +662,7 @@ { "id": "miclock", "name": "Mixed Clock", "icon": "clock-mixed.png", - "version":"0.03", + "version":"0.04", "description": "A mix of analog and digital Clock", "tags": "clock", "type":"clock", diff --git a/apps/miclock/ChangeLog b/apps/miclock/ChangeLog index 9c2cccf09..f2e354bc1 100644 --- a/apps/miclock/ChangeLog +++ b/apps/miclock/ChangeLog @@ -1,2 +1,3 @@ 0.02: Modified for use with new bootloader and firmware 0.03: Localization +0.04: move jshint to the top diff --git a/apps/miclock/clock-mixed.js b/apps/miclock/clock-mixed.js index cf6f4c196..bf6efb09e 100644 --- a/apps/miclock/clock-mixed.js +++ b/apps/miclock/clock-mixed.js @@ -1,5 +1,5 @@ -var locale = require("locale"); /* jshint esversion: 6 */ +var locale = require("locale"); const Radius = { "center": 8, "hour": 78, "min": 95, "dots": 102 }; const Center = { "x": 120, "y": 132 }; From 18e69603dd0e07e92916f57e2e1790a7767eb946 Mon Sep 17 00:00:00 2001 From: ArticNet Date: Sat, 4 Apr 2020 04:22:41 +0900 Subject: [PATCH 43/59] Fixed icon --- apps/dotclock/clock-dot-icon.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/dotclock/clock-dot-icon.js b/apps/dotclock/clock-dot-icon.js index 62d1dea2a..7098cb51f 100644 --- a/apps/dotclock/clock-dot-icon.js +++ b/apps/dotclock/clock-dot-icon.js @@ -1 +1 @@ -require("heatshrink").decompress(atob("AH4A/AH4A/AH4AmgkEF/4A/KyxodDpHX66YtF5AA/AH4AobDYbTF94A/AH4A/AG/X64FIAgILEACcEggvIAIQCGAYgfPF+qPUF5QA/AH4AGyAuuAAJf/ABEEggbtF94A/AH4A/bCzqdF96Y/F/4A/AH4A/AGIA==")) \ No newline at end of file +require("heatshrink").decompress(atob("mEwwkBIf4A/AGUJyAXtACeZBCAOJh/wC6IADC4gA/XEINJC64A/AHcP+ACD/4CBTB0Ph8A+ACBAIKoKC65HKC4gA/AAfACysM5gvjTBgNKC64A/AEWZBCAXdADa4XaH4A/AAgA==")) From 048a042ffa0f6a0254dfbed79ca5281704073496 Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Fri, 3 Apr 2020 21:32:05 +0200 Subject: [PATCH 44/59] Revert "Settings: load app settings in their own scope" > Actually eval('('+appSettings+')') is significantly worse I'm afraid. > > Basically, if you do Storage.read you get a pointer to external memory > Any functions have their code kept in that memory so it saves loads of > RAM. The second you append to the string it has to copy everything to > RAM - so now every function ends up in RAM, not Flash :( This reverts commit c135c70f --- apps/setting/settings.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/setting/settings.js b/apps/setting/settings.js index 38ce9f886..dbb03555c 100644 --- a/apps/setting/settings.js +++ b/apps/setting/settings.js @@ -323,7 +323,7 @@ function showAppSettings(app) { return showError('Missing settings'); } try { - appSettings = eval('('+appSettings+')'); + appSettings = eval(appSettings); } catch (e) { console.log(`${app.name} settings error:`, e) return showError('Error in settings'); From c269083382c4dd1ea2e53f6e04fd9c981b1849c7 Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Fri, 3 Apr 2020 21:36:48 +0200 Subject: [PATCH 45/59] widbatpc: put settings function in parentheses --- apps/widbatpc/settings.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/widbatpc/settings.js b/apps/widbatpc/settings.js index 9ea86ed39..5c0bdbcae 100644 --- a/apps/widbatpc/settings.js +++ b/apps/widbatpc/settings.js @@ -2,7 +2,7 @@ /** * @param {function} back Use back() to return to settings menu */ -function settings(back) { +(function(back) { const SETTINGS_FILE = 'widbatpc.settings.json' const COLORS = ['By Level', 'Green', 'Monochrome'] @@ -55,4 +55,4 @@ function settings(back) { }, } E.showMenu(menu) -} +}) From ee4295e5c581cc81f485ad4ab3a5cc3fb77a0255 Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Fri, 3 Apr 2020 22:31:08 +0200 Subject: [PATCH 46/59] widbatpc: whitespace fix in apps.json --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index 0cbcc7294..daf1fba68 100644 --- a/apps.json +++ b/apps.json @@ -338,7 +338,7 @@ "name": "Battery Level Widget (with percentage)", "shortName": "Battery Widget", "icon": "widget.png", - "version": "0.07", + "version":"0.07", "description": "Show the current battery level and charging status in the top right of the clock, with charge percentage", "tags": "widget,battery", "type":"widget", From 323b2dc3b41cf8b2ea52f936bf9971a74667fcba Mon Sep 17 00:00:00 2001 From: Dimitri Gigot Date: Fri, 3 Apr 2020 21:37:00 +0000 Subject: [PATCH 47/59] Improvement: Close launcher when lcd turn off --- apps.json | 2 +- apps/toucher/ChangeLog | 3 ++- apps/toucher/app.js | 4 ++++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/apps.json b/apps.json index f0bc4874a..d3ff86ab0 100644 --- a/apps.json +++ b/apps.json @@ -1013,7 +1013,7 @@ "name": "Touch Launcher", "shortName":"Menu", "icon": "app.png", - "version":"0.02", + "version":"0.03", "description": "Touch enable left to right launcher.", "tags": "tool,system,launcher", "type":"launch", diff --git a/apps/toucher/ChangeLog b/apps/toucher/ChangeLog index bd3d5d225..f21553c54 100644 --- a/apps/toucher/ChangeLog +++ b/apps/toucher/ChangeLog @@ -1,2 +1,3 @@ 0.01: New App! -0.02: Add swipe support and doucle tap to run application \ No newline at end of file +0.02: Add swipe support and doucle tap to run application +0.03: Close launcher when lcd turn off \ No newline at end of file diff --git a/apps/toucher/app.js b/apps/toucher/app.js index 2b80198c9..7a3f6ff97 100644 --- a/apps/toucher/app.js +++ b/apps/toucher/app.js @@ -127,4 +127,8 @@ Bangle.on('touch', function(button){ Bangle.on('swipe', dir => { if(dir == 1) prev(); else next(); +}); + +Bangle.on('lcdPower', function(on) { + if(!on) return load(); }); \ No newline at end of file From e38b7dfaa2e747a9712bd951b973d14d2e669881 Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Sat, 4 Apr 2020 00:00:14 +0200 Subject: [PATCH 48/59] Readme: app settings --- README.md | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/README.md b/README.md index 2d0b54a7d..f59fa54e0 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,7 @@ easily distinguish between file types, we use the following: * `stuff.img` is an image * `stuff.app.js` is JS code for applications * `stuff.wid.js` is JS code for widgets +* `stuff.settings.js` is JS code for the settings menu * `stuff.boot.js` is JS code that automatically gets run at boot time * `stuff.json` is used for JSON settings for an app @@ -314,6 +315,48 @@ the data you require from Bangle.js. See [apps/gpsrec/interface.html](the GPS Recorder) for a full example. +### Adding configuration to the "Settings" menu + +Apps (or widgets) can add their own settings to the "Settings" menu under "App/widget settings". +To do so, the app needs to include a `settings.js` file, containing a single function +that handles configuring the app. +When the app settings are opened, this function is called with one +argument, `back`: a callback to return to the settings menu. + +Example `settings.js` +```js +// make sure to enclose the function in parentheses +(function(back) { + let settings = require('Storage').readJSON('app.settings.json',1)||{}; + function save(key, value) { + settings[key] = value; + require('Storage').write('app.settings.json',settings); + } + const appMenu = { + '': {'title': 'App Settings'}, + '< Back': back, + 'Monkeys': { + value: settings.monkeys||12, + onchange: (m) => {save('monkeys', m)} + } + }; + E.showMenu(appMenu) +}) +``` +In this example the app needs to add both `app.settings.js` and +`app.settings.json` to `apps.json`: +```json + { "id": "app", + ... + "storage": [ + ... + {"name":"app.settings.js","url":"settings.js"}, + {"name":"app.settings.json","content":"{}"} + ] + }, +``` +That way removing the app also cleans up `app.settings.json`. + ## Coding hints - use `g.setFont(.., size)` to multiply the font size, eg ("6x8",3) : "18x24" From 7b669cd028b8f4d0e23c9706ff58b808a6055726 Mon Sep 17 00:00:00 2001 From: Richard de Boer Date: Sat, 4 Apr 2020 01:30:33 +0200 Subject: [PATCH 49/59] Move Welcome config into App/widget settings --- apps.json | 5 +++-- apps/setting/ChangeLog | 1 + apps/setting/settings.js | 8 -------- apps/welcome/ChangeLog | 1 + apps/welcome/settings.js | 16 ++++++++++++++++ 5 files changed, 21 insertions(+), 10 deletions(-) create mode 100644 apps/welcome/settings.js diff --git a/apps.json b/apps.json index f0bc4874a..28e2e20c6 100644 --- a/apps.json +++ b/apps.json @@ -78,13 +78,14 @@ { "id": "welcome", "name": "Welcome", "icon": "app.png", - "version":"0.04", + "version":"0.05", "description": "Appears at first boot and explains how to use Bangle.js", "tags": "start,welcome", "allow_emulator":true, "storage": [ {"name":"welcome.js","url":"welcome.js"}, {"name":"welcome.app.js","url":"app.js"}, + {"name":"welcome.settings.js","url":"settings.js"}, {"name":"welcome.img","url":"app-icon.js","evaluate":true} ] }, @@ -117,7 +118,7 @@ { "id": "setting", "name": "Settings", "icon": "settings.png", - "version":"0.08", + "version":"0.09", "description": "A menu for setting up Bangle.js", "tags": "tool,system", "storage": [ diff --git a/apps/setting/ChangeLog b/apps/setting/ChangeLog index 0cfa04bf0..db0ac834a 100644 --- a/apps/setting/ChangeLog +++ b/apps/setting/ChangeLog @@ -5,3 +5,4 @@ 0.06: Remove distance setting as there's a separate app for Locale now 0.07: Added vibrate as beep workaround 0.08: Add support for app/widget settings +0.09: Move Welcome into App/widget settings diff --git a/apps/setting/settings.js b/apps/setting/settings.js index dbb03555c..3d7586851 100644 --- a/apps/setting/settings.js +++ b/apps/setting/settings.js @@ -95,14 +95,6 @@ function showMainMenu() { } } }, - 'Welcome App': { - value: !settings.welcomed, - format: boolFormat, - onchange: v => { - settings.welcomed = v?undefined:true; - updateSettings(); - } - }, 'Locale': showLocaleMenu, 'Select Clock': showClockMenu, 'HID': { diff --git a/apps/welcome/ChangeLog b/apps/welcome/ChangeLog index d8d647138..34f6e3a82 100644 --- a/apps/welcome/ChangeLog +++ b/apps/welcome/ChangeLog @@ -2,3 +2,4 @@ 0.02: Animate balloon intro 0.03: BTN3 now won't restart when at the end 0.04: Fix regression after tweaks to Storage.readJSON +0.05: Move configuration into App/widget settings diff --git a/apps/welcome/settings.js b/apps/welcome/settings.js new file mode 100644 index 000000000..2fbd585c6 --- /dev/null +++ b/apps/welcome/settings.js @@ -0,0 +1,16 @@ +// The welcome app is special, and gets to use global settings +(function(back) { + let settings = require('Storage').readJSON('setting.json', 1) || {} + E.showMenu({ + '': { 'title': 'Welcome App' }, + 'Run again': { + value: !settings.welcomed, + format: v => v ? 'Yes' : 'No', + onchange: v => { + settings.welcomed = v ? undefined : true + require('Storage').write('setting.json', settings) + }, + }, + '< Back': back, + }) +}) From 8fa7fd0e431674662535aaa7c9c3787330a6ea67 Mon Sep 17 00:00:00 2001 From: msdeibel Date: Sat, 4 Apr 2020 08:50:55 +0200 Subject: [PATCH 50/59] Improved buzz timing and rendering --- apps/wohrm/ChangeLog | 1 + apps/wohrm/app.js | 654 +++++++++++++++++++++---------------------- 2 files changed, 326 insertions(+), 329 deletions(-) diff --git a/apps/wohrm/ChangeLog b/apps/wohrm/ChangeLog index f836f6f71..273b7b633 100644 --- a/apps/wohrm/ChangeLog +++ b/apps/wohrm/ChangeLog @@ -1,3 +1,4 @@ +0.05: Improved buzz timing and rendering 0.04: Only buzz on high confidence (>85%) 0.03: Optimized rendering for the background 0.02: Adapted to new App code layout diff --git a/apps/wohrm/app.js b/apps/wohrm/app.js index dff69d76b..ff57c0b62 100644 --- a/apps/wohrm/app.js +++ b/apps/wohrm/app.js @@ -1,329 +1,325 @@ -/* eslint-disable no-undef */ -const Setter = { - NONE: "none", - UPPER: 'upper', - LOWER: 'lower' -}; - -const shortBuzzTimeInMs = 50; -const longBuzzTimeInMs = 200; - -let upperLimit = 90; -let upperLimitChanged = true; - -let lowerLimit = 50; -let lowerLimitChanged = true; - -let limitSetter = Setter.NONE; - -let currentHeartRate = 0; -let hrConfidence = -1; -let hrChanged = true; -let confidenceChanged = true; - -let setterHighlightTimeout; - -function renderUpperLimitBackground() { - g.setColor(1,0,0); - g.fillRect(125,40, 210, 70); - g.fillRect(180,70, 210, 200); - - //Round top left corner - g.fillEllipse(115,40,135,70); - - //Round top right corner - g.setColor(0,0,0); - g.fillRect(205,40, 210, 45); - g.setColor(1,0,0); - g.fillEllipse(190,40,210,50); - - //Round inner corner - g.fillRect(174,71, 179, 76); - g.setColor(0,0,0); - g.fillEllipse(160,71,179,82); - - //Round bottom - g.setColor(1,0,0); - g.fillEllipse(180,190, 210, 210); -} - -function renderLowerLimitBackground() { - g.setColor(0,0,1); - g.fillRect(10, 180, 100, 210); - g.fillRect(10, 50, 40, 180); - - //Rounded top - g.setColor(0,0,1); - g.fillEllipse(10,40, 40, 60); - - //Round bottom right corner - g.setColor(0,0,1); - g.fillEllipse(90,180,110,210); - - //Round inner corner - g.setColor(0,0,1); - g.fillRect(40,175,45,180); - g.setColor(0,0,0); - g.fillEllipse(41,170,60,179); - - //Round bottom left corner - g.setColor(0,0,0); - g.fillRect(10,205, 15, 210); - g.setColor(0,0,1); - g.fillEllipse(10,200,30,210); -} - -function drawTrainingHeartRate() { - //Only redraw if the display is on - if (Bangle.isLCDOn()) { - - - renderUpperLimit(); - - renderCurrentHeartRate(); - - renderLowerLimit(); - - renderConfidenceBars(); - } - - buzz(); -} - -function renderUpperLimit() { - if(!upperLimitChanged) { return; } - - g.setColor(1,0,0); - g.fillRect(125,40, 210, 70); - - if(limitSetter === Setter.UPPER){ - g.setColor(255,255, 0); - } else { - g.setColor(255,255,255); - } - g.setFontVector(13); - g.drawString("Upper : " + upperLimit, 130,50); - - upperLimitChanged = false; -} - -function renderCurrentHeartRate() { - if(!hrChanged) { return; } - - g.setColor(255,255,255); - g.fillRect(45, 110, 165, 150); - - g.setColor(0,0,0); - g.setFontVector(24); - g.setFontAlign(1, -1, 0); - g.drawString(currentHeartRate, 130, 117); - - //Reset alignment to defaults - g.setFontAlign(-1, -1, 0); - - hrChanged = false; -} - -function renderLowerLimit() { - if(!lowerLimitChanged) { return; } - - g.setColor(0,0,1); - g.fillRect(10, 180, 100, 210); - - if(limitSetter === Setter.LOWER){ - g.setColor(255,255, 0); - } else { - g.setColor(255,255,255); - } - g.setFontVector(13); - g.drawString("Lower : " + lowerLimit, 20,190); - - lowerLimitChanged = false; -} - -function renderConfidenceBars(){ - if(!confidenceChanged) { return; } - - if(hrConfidence >= 85){ - g.setColor(0, 255, 0); - } else if (hrConfidence >= 50) { - g.setColor(255, 255, 0); - } else if(hrConfidence >= 0){ - g.setColor(255, 0, 0); - } else { - g.setColor(255, 255, 255); - } - - g.fillRect(45, 110, 55, 150); - g.fillRect(165, 110, 175, 150); - - confidenceChanged = false; -} - -function renderButtonIcons() { - g.setColor(255,255,255); - g.setFontVector(14); - - //+ for Btn1 - g.drawString("+", 222,50); - - //Home for Btn2 - g.drawLine(220, 118, 227, 110); - g.drawLine(227, 110, 234, 118); - - g.drawPoly([222,117,222,125,232,125,232,117], false); - g.drawRect(226,120,229,125); - - //- for Btn3 - g.drawString("-", 222,165); -} - -function buzz() -{ - // Do not buzz if not confident - if(hrConfidence < 85) { return; } - - if(currentHeartRate > upperLimit) - { - Bangle.buzz(shortBuzzTimeInMs); - setTimeout(() => { Bangle.buzz(shortBuzzTimeInMs); }, shortBuzzTimeInMs+10); - setTimeout(() => { Bangle.buzz(shortBuzzTimeInMs); }, shortBuzzTimeInMs+10); - } - - if(currentHeartRate < lowerLimit) - { - Bangle.buzz(longBuzzTimeInMs); - setTimeout(() => { Bangle.buzz(longBuzzTimeInMs); }, longBuzzTimeInMs+10); - } -} - -function onHrm(hrm){ - if(currentHeartRate !== hrm.bpm){ - currentHeartRate = hrm.bpm; - hrChanged = true; - } - - if(hrConfidence !== hrm.confidence) { - hrConfidence = hrm.confidence; - confidenceChanged = true; - } -} - -function setLimitSetterToLower() { - resetHighlightTimeout(); - - limitSetter = Setter.LOWER; - console.log("Limit setter is lower"); - - upperLimitChanged = true; - lowerLimitChanged = true; - - renderUpperLimit(); - renderLowerLimit(); -} - -function setLimitSetterToUpper() { - resetHighlightTimeout(); - - limitSetter = Setter.UPPER; - console.log("Limit setter is upper"); - - upperLimitChanged = true; - lowerLimitChanged = true; - - renderLowerLimit(); - renderUpperLimit(); -} - -function setLimitSetterToNone() { - limitSetter = Setter.NONE; - console.log("Limit setter is none"); - - upperLimitChanged = true; - lowerLimitChanged = true; - - renderLowerLimit(); - renderUpperLimit(); -} - -function incrementLimit(){ - resetHighlightTimeout(); - - if (limitSetter === Setter.UPPER) { - upperLimit++; - renderUpperLimit(); - console.log("Upper limit: " + upperLimit); - upperLimitChanged = true; - } else if(limitSetter === Setter.LOWER) { - lowerLimit++; - renderLowerLimit(); - console.log("Lower limit: " + lowerLimit); - lowerLimitChanged = true; - } -} - -function decrementLimit(){ - resetHighlightTimeout(); - - if (limitSetter === Setter.UPPER) { - upperLimit--; - renderUpperLimit(); - console.log("Upper limit: " + upperLimit); - upperLimitChanged = true; - } else if(limitSetter === Setter.LOWER) { - lowerLimit--; - renderLowerLimit(); - console.log("Lower limit: " + lowerLimit); - lowerLimitChanged = true; - } -} - -function resetHighlightTimeout() { - if (setterHighlightTimeout) { - clearTimeout(setterHighlightTimeout); - } - - setterHighlightTimeout = setTimeout(setLimitSetterToNone, 2000); -} - -// Show launcher when middle button pressed -function switchOffApp(){ - Bangle.setHRMPower(0); - Bangle.showLauncher(); -} - -// special function to handle display switch on -Bangle.on('lcdPower', (on) => { - g.clear(); - if (on) { - Bangle.drawWidgets(); - renderButtonIcons(); - // call your app function here - renderLowerLimitBackground(); - renderUpperLimitBackground(); - lowerLimitChanged = true; - upperLimitChanged = true; - drawTrainingHeartRate(); - } -}); - -Bangle.setHRMPower(1); -Bangle.on('HRM', onHrm); - -setWatch(incrementLimit, BTN1, {edge:"rising", debounce:50, repeat:true}); -setWatch(switchOffApp, BTN2, {edge:"rising", debounce:50, repeat:true}); -setWatch(decrementLimit, BTN3, {edge:"rising", debounce:50, repeat:true}); -setWatch(setLimitSetterToLower, BTN4, {edge:"rising", debounce:50, repeat:true}); -setWatch(setLimitSetterToUpper, BTN5, { edge: "rising", debounce: 50, repeat: true }); - -g.clear(); -Bangle.loadWidgets(); -Bangle.drawWidgets(); -//drawTrainingHeartRate(); - -renderButtonIcons(); -renderLowerLimitBackground(); -renderUpperLimitBackground(); - -// refesh every sec -setInterval(drawTrainingHeartRate, 1000); +/* eslint-disable no-undef */ +const Setter = { + NONE: "none", + UPPER: 'upper', + LOWER: 'lower' +}; + +const shortBuzzTimeInMs = 80; +const longBuzzTimeInMs = 400; + +let upperLimit = 130; +let upperLimitChanged = true; + +let lowerLimit = 100; +let lowerLimitChanged = true; + +let limitSetter = Setter.NONE; + +let currentHeartRate = 0; +let hrConfidence = -1; +let hrChanged = true; +let confidenceChanged = true; + +let setterHighlightTimeout; + +function renderUpperLimitBackground() { + g.setColor(1,0,0); + g.fillRect(125,40, 210, 70); + g.fillRect(180,70, 210, 200); + + //Round top left corner + g.fillEllipse(115,40,135,70); + + //Round top right corner + g.setColor(0,0,0); + g.fillRect(205,40, 210, 45); + g.setColor(1,0,0); + g.fillEllipse(190,40,210,50); + + //Round inner corner + g.fillRect(174,71, 179, 76); + g.setColor(0,0,0); + g.fillEllipse(160,71,179,82); + + //Round bottom + g.setColor(1,0,0); + g.fillEllipse(180,190, 210, 210); +} + +function renderLowerLimitBackground() { + g.setColor(0,0,1); + g.fillRect(10, 180, 100, 210); + g.fillRect(10, 50, 40, 180); + + //Rounded top + g.setColor(0,0,1); + g.fillEllipse(10,40, 40, 60); + + //Round bottom right corner + g.setColor(0,0,1); + g.fillEllipse(90,180,110,210); + + //Round inner corner + g.setColor(0,0,1); + g.fillRect(40,175,45,180); + g.setColor(0,0,0); + g.fillEllipse(41,170,60,179); + + //Round bottom left corner + g.setColor(0,0,0); + g.fillRect(10,205, 15, 210); + g.setColor(0,0,1); + g.fillEllipse(10,200,30,210); +} + +function drawTrainingHeartRate() { + //Only redraw if the display is on + if (Bangle.isLCDOn()) { + renderUpperLimit(); + + renderCurrentHeartRate(); + + renderLowerLimit(); + + renderConfidenceBars(); + } + + buzz(); +} + +function renderUpperLimit() { + if(!upperLimitChanged) { return; } + + g.setColor(1,0,0); + g.fillRect(125,40, 210, 70); + + if(limitSetter === Setter.UPPER){ + g.setColor(255,255, 0); + } else { + g.setColor(255,255,255); + } + g.setFontVector(13); + g.drawString("Upper : " + upperLimit, 130,50); + + upperLimitChanged = false; +} + +function renderCurrentHeartRate() { + if(!hrChanged) { return; } + + g.setColor(255,255,255); + g.fillRect(55, 110, 165, 150); + + g.setColor(0,0,0); + g.setFontVector(24); + g.setFontAlign(1, -1, 0); + g.drawString(currentHeartRate, 130, 117); + + //Reset alignment to defaults + g.setFontAlign(-1, -1, 0); + + hrChanged = false; +} + +function renderLowerLimit() { + if(!lowerLimitChanged) { return; } + + g.setColor(0,0,1); + g.fillRect(10, 180, 100, 210); + + if(limitSetter === Setter.LOWER){ + g.setColor(255,255, 0); + } else { + g.setColor(255,255,255); + } + g.setFontVector(13); + g.drawString("Lower : " + lowerLimit, 20,190); + + lowerLimitChanged = false; +} + +function renderConfidenceBars(){ + if(!confidenceChanged) { return; } + + if(hrConfidence >= 85){ + g.setColor(0, 255, 0); + } else if (hrConfidence >= 50) { + g.setColor(255, 255, 0); + } else if(hrConfidence >= 0){ + g.setColor(255, 0, 0); + } else { + g.setColor(255, 255, 255); + } + + g.fillRect(45, 110, 55, 150); + g.fillRect(165, 110, 175, 150); + + confidenceChanged = false; +} + +function renderButtonIcons() { + g.setColor(255,255,255); + g.setFontVector(14); + + //+ for Btn1 + g.drawString("+", 222,50); + + //Home for Btn2 + g.drawLine(220, 118, 227, 110); + g.drawLine(227, 110, 234, 118); + + g.drawPoly([222,117,222,125,232,125,232,117], false); + g.drawRect(226,120,229,125); + + //- for Btn3 + g.drawString("-", 222,165); +} + +function buzz() +{ + // Do not buzz if not confident + if(hrConfidence < 85) { return; } + + if(currentHeartRate > upperLimit) + { + Bangle.buzz(shortBuzzTimeInMs); + setTimeout(() => { Bangle.buzz(shortBuzzTimeInMs); }, shortBuzzTimeInMs * 2); + } + + if(currentHeartRate < lowerLimit) + { + Bangle.buzz(longBuzzTimeInMs); + } +} + +function onHrm(hrm){ + if(currentHeartRate !== hrm.bpm){ + currentHeartRate = hrm.bpm; + hrChanged = true; + } + + if(hrConfidence !== hrm.confidence) { + hrConfidence = hrm.confidence; + confidenceChanged = true; + } +} + +function setLimitSetterToLower() { + resetHighlightTimeout(); + + limitSetter = Setter.LOWER; + console.log("Limit setter is lower"); + + upperLimitChanged = true; + lowerLimitChanged = true; + + renderUpperLimit(); + renderLowerLimit(); +} + +function setLimitSetterToUpper() { + resetHighlightTimeout(); + + limitSetter = Setter.UPPER; + console.log("Limit setter is upper"); + + upperLimitChanged = true; + lowerLimitChanged = true; + + renderLowerLimit(); + renderUpperLimit(); +} + +function setLimitSetterToNone() { + limitSetter = Setter.NONE; + console.log("Limit setter is none"); + + upperLimitChanged = true; + lowerLimitChanged = true; + + renderLowerLimit(); + renderUpperLimit(); +} + +function incrementLimit(){ + resetHighlightTimeout(); + + if (limitSetter === Setter.UPPER) { + upperLimit++; + renderUpperLimit(); + console.log("Upper limit: " + upperLimit); + upperLimitChanged = true; + } else if(limitSetter === Setter.LOWER) { + lowerLimit++; + renderLowerLimit(); + console.log("Lower limit: " + lowerLimit); + lowerLimitChanged = true; + } +} + +function decrementLimit(){ + resetHighlightTimeout(); + + if (limitSetter === Setter.UPPER) { + upperLimit--; + renderUpperLimit(); + console.log("Upper limit: " + upperLimit); + upperLimitChanged = true; + } else if(limitSetter === Setter.LOWER) { + lowerLimit--; + renderLowerLimit(); + console.log("Lower limit: " + lowerLimit); + lowerLimitChanged = true; + } +} + +function resetHighlightTimeout() { + if (setterHighlightTimeout) { + clearTimeout(setterHighlightTimeout); + } + + setterHighlightTimeout = setTimeout(setLimitSetterToNone, 2000); +} + +// Show launcher when middle button pressed +function switchOffApp(){ + Bangle.setHRMPower(0); + Bangle.showLauncher(); +} + +// special function to handle display switch on +Bangle.on('lcdPower', (on) => { + g.clear(); + if (on) { + Bangle.drawWidgets(); + renderButtonIcons(); + // call your app function here + renderLowerLimitBackground(); + renderUpperLimitBackground(); + lowerLimitChanged = true; + upperLimitChanged = true; + drawTrainingHeartRate(); + } +}); + +Bangle.setHRMPower(1); +Bangle.on('HRM', onHrm); + +setWatch(incrementLimit, BTN1, {edge:"rising", debounce:50, repeat:true}); +setWatch(switchOffApp, BTN2, {edge:"rising", debounce:50, repeat:true}); +setWatch(decrementLimit, BTN3, {edge:"rising", debounce:50, repeat:true}); +setWatch(setLimitSetterToLower, BTN4, {edge:"rising", debounce:50, repeat:true}); +setWatch(setLimitSetterToUpper, BTN5, { edge: "rising", debounce: 50, repeat: true }); + +g.clear(); +Bangle.loadWidgets(); +Bangle.drawWidgets(); +//drawTrainingHeartRate(); + +renderButtonIcons(); +renderLowerLimitBackground(); +renderUpperLimitBackground(); + +// refesh every sec +setInterval(drawTrainingHeartRate, 1000); From ba5df106013a748e8370c4b6dcb2f1ecf832da5c Mon Sep 17 00:00:00 2001 From: msdeibel Date: Sat, 4 Apr 2020 08:55:13 +0200 Subject: [PATCH 51/59] JS for icon changed --- apps/wohrm/app-icon.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/wohrm/app-icon.js b/apps/wohrm/app-icon.js index a7f67291e..4a69b16bd 100644 --- a/apps/wohrm/app-icon.js +++ b/apps/wohrm/app-icon.js @@ -1 +1 @@ -require("heatshrink").decompress(atob("mEwwhC/AH4AWzIAByAHDhIICCpINDDAgIIFpAADBBQuKE4QIIFxgAKC7g9HABSbIBQQXWGxgXEKQxOMC5AhBC66WMC5AuBJ5h3ICoI3LeAwKBBAICBD4TmHC48ACgQCCfxC/HAgYXDL44vFA4YRDAoiOIHAgXFYRAXFBwwIIOw4OGIxKmIC5ylHGAoXIXpBIGLxxIIIx6IJFxwwNCxQwLFxYwLCxgwJFxowJCxwwHFx4wHCyAwFFyIwFCyQYDCygA/AH4AFA")) \ No newline at end of file +require("heatshrink").decompress(atob("mEwwhC/AH4AVgnd5tABI3c7oJGAAUs5gAC4gJDpgJD4QWGhoMDAAPQBJYADBgoABBJYAChgJD5oDC4AJEAAfAC4fcBIfUDYYJEEogWCgQJEoYSHAAsgIw3MmYqIn89JAoXFn5DH4f/+YXFWQnE/4GEAAXP///ZgooE4X/ngvMPAQXEBoIXHHIJfDC4ss5nf+f9OosjFwgXF5oTBp8z+gMBMQPTn5dBNIgXCAwPDEQM/mQmCJQNP/8zDIJRDO4SnB6fz7k/poXEJwIJBmanGhvMl//loxC7nE/jUCon/6gzBC4PQC4MDKIJFDn9M4YXB5nUKYbACmAXBgE/+YMBOoMvngXDJIKDB6YvBOwRgDaoINB788p5wDn7HELwQABghWCBoPD/s/YwNN5i+Bc4dAC4bBCC4fyPIPU+Z0BDAZGEJAffYgPC+ZxBG4KkB6f/C4JGEAAQsBcIX/+QEBCgP9A4IXBCwwwB5pxDPYJoDcgIuIGASJH5rvBAwIWIeYQABl5jBAAXDIwLrCABCcC76gDAoP0RgwAFYYJ7DJAcsFxYABaYJ7DAAXECxhJEAAgWOPQgACIpoADUwb1BCyBJERZgYKkAXUglACygA/AH4AFA==")) \ No newline at end of file From d4ab3c075ddbe65c6536e1f8fd033ae0f68c866a Mon Sep 17 00:00:00 2001 From: msdeibel Date: Sat, 4 Apr 2020 08:55:33 +0200 Subject: [PATCH 52/59] wohrm version changed --- apps.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps.json b/apps.json index a770d9a6c..cd9a27dc1 100644 --- a/apps.json +++ b/apps.json @@ -867,7 +867,7 @@ { "id": "wohrm", "name": "Workout HRM", "icon": "app.png", - "version":"0.04", + "version":"0.05", "description": "Workout heart rate monitor notifies you with a buzz if your heart rate goes above or below the set limits.", "tags": "hrm,workout", "type": "app", From 16ea9a8167b1e65b42a50701cec9a989d5e31d14 Mon Sep 17 00:00:00 2001 From: Paul Cockrell Date: Sat, 4 Apr 2020 11:03:34 +0100 Subject: [PATCH 53/59] Enhance Mario clock performance and graphics --- apps.json | 2 +- apps/marioclock/ChangeLog | 1 + apps/marioclock/marioclock-app.js | 303 ++++++++++++------------------ 3 files changed, 124 insertions(+), 182 deletions(-) diff --git a/apps.json b/apps.json index f0bc4874a..32682282c 100644 --- a/apps.json +++ b/apps.json @@ -893,7 +893,7 @@ { "id": "marioclock", "name": "Mario Clock", "icon": "marioclock.png", - "version":"0.05", + "version":"0.06", "description": "Animated Mario clock, jumps to change the time!", "tags": "clock,mario,retro", "type": "clock", diff --git a/apps/marioclock/ChangeLog b/apps/marioclock/ChangeLog index 74db9bc18..dfad2d26a 100644 --- a/apps/marioclock/ChangeLog +++ b/apps/marioclock/ChangeLog @@ -3,3 +3,4 @@ 0.03: use short date format from locale, take timeout from settings 0.04: modify date to display to be more at the original idea but still localized 0.05: use 12/24 hour clock from settings +0.06: Performance refactor, and enhanced graphics! diff --git a/apps/marioclock/marioclock-app.js b/apps/marioclock/marioclock-app.js index 2eeb21c97..ed1d51cde 100644 --- a/apps/marioclock/marioclock-app.js +++ b/apps/marioclock/marioclock-app.js @@ -3,6 +3,7 @@ + Based on Espruino Mario Clock V3 https://github.com/paulcockrell/espruino-mario-clock + Converting images to 1bit BMP: Image > Mode > Indexed and tick the "Use black and white (1-bit) palette", Then export as BMP. + Online Image convertor: https://www.espruino.com/Image+Converter + + Images must be converted 1Bit White/Black !!! Not Black/White **********************************/ const locale = require("locale"); @@ -16,110 +17,32 @@ let W, H; let intervalRef, displayTimeoutRef = null; -// Space to draw watch widgets (e.g battery, bluetooth status) -const WIDGETS_GUTTER = 10; - // Colours const LIGHTEST = "#effedd"; const LIGHT = "#add795"; const DARK = "#588d77"; const DARKEST = "#122d3e"; -// Mario Images -const marioRunningImage1 = { - width : 15, height : 20, bpp : 1, - transparent : 0, - buffer : E.toArrayBuffer(atob("B8AfwH+B/8f/z4M+KExcnAUSCw87w4L8CJQRNB/YH+AxgCEAPAA=")) -}; - -const marioRunningImage1Neg = { - width : 15, height : 20, bpp : 1, - transparent : 0, - buffer : E.toArrayBuffer(atob("AAAAAAAAAAAAAHwB0DOgY/jt8PDAPAEAB2gOyAAgAAAOAB4AAAA=")) -}; - -const marioRunningImage2 = { - width : 15, height : 20, bpp : 1, - transparent : 0, - buffer : E.toArrayBuffer(atob("B8AfwH+B/8f/z4M+KExcnAUSCw87w4J6BEsPnSfyT+S+OMAAAAA=")) -}; - -const marioRunningImage2Neg = { - width : 15, height : 20, bpp : 1, - transparent : 0, - buffer : E.toArrayBuffer(atob("AAAAAAAAAAAAAHwB0DOgY/jt8PDAPAGEA7QAYhgMMBhAAAAAAAA=")) -}; - -const pyramid = { - width : 20, height : 20, bpp : 1, - transparent : 0, - buffer : E.toArrayBuffer(atob("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABgAAkAAQgAIEAEAgCAEBAAggAEQAAoAAE=")) -}; - -const pipe = { - width : 9, height : 6, bpp : 1, - transparent : 0, - buffer : E.toArrayBuffer(atob("/8BxaCRSCA==")) -}; - -const floor = { - width : 8, height : 3, bpp : 1, - transparent : 0, - buffer : E.toArrayBuffer(atob("/6pE")) -}; - -const sky = { - width : 128, height : 30, bpp : 1, - transparent : 0, - buffer : E.toArrayBuffer(atob("VVVVVVVVVVVVVVVVVVVVVQAAAAAAAAAAAAAAAAAAAABVVVVVVVVVVVVVVVVVVVVVIiIiIiIiIiIiIiIiIiIiIlVVVVVVVVVVVVVVVVVVVVWIiIiIiIiIiIiIiIiIiIiIVVVVVVVVVVVVVVVVVVVVVSIiIiIiIiICIiIiIiIiIiJVVVVVVVVVAVVVVVVVVVVViIiIiIiIiACIiIiIiIiIiFVVVVVVVVQAVVVVVVVVVVUiIiIiIiIgACIiIiIiIiIiVVVVVVVVUAAVVVUBVVVVUKqqqqqqqggAKCqqAKqqqoBVUBVVVVQAABAVVABVVVUAIiACIiIgAAAgAiAAIiIiAFVABVVVUAAAUAVUABRVVQCqgAKCqqAAACAAAAAgCqoAVUABAVVAAAAAAAAAAAVQAKqAAACqoAAAAAAAAAACgABAAAAAUEAAAAAAAAAABQAAgAAAACAAAAAAAAAAAAIAAAAAAABQAAAAAAAAAAAEAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")) -}; - -const brick = { - width : 21, height : 15, bpp : 1, - transparent : 0, - buffer : E.toArrayBuffer(atob("f//0AABoAAsAABgAAMAABgAAMAABgAAMAABgAAMAABoAAsAABf//wA==")) -}; - -const flower = { - width : 7, height : 7, bpp : 1, - transparent : 0, - buffer : E.toArrayBuffer(atob("fY3wjW+OAA==")) -}; - -const pipePlant = { - width : 9, height : 15, bpp : 1, - transparent : 0, - buffer : E.toArrayBuffer(atob("FBsNhsHDWPn/gOLQSKQSKQQ=")) -}; - const marioSprite = { frameIdx: 0, - frames: [ - marioRunningImage1, - marioRunningImage2 - ], - negFrames: [ - marioRunningImage1Neg, - marioRunningImage2Neg - ], x: 35, y: 55, jumpCounter: 0, - jumpIncrement: Math.PI / 10, + jumpIncrement: Math.PI / 6, isJumping: false }; -const STATIC_TILES = { - "_": {img: floor, x: 16 * 8, y: 75}, - "X": {img: sky, x: 0, y: 10}, - "#": {img: brick, x: 0, y: 0}, +const coinSprite = { + frameIdx: 0, + x: 34, + y: 18, + isAnimating: false, + yDefault: 18, }; -const TILES = { - "T": {img: pipe, x: 16 * 8, y: 69}, - "^": {img: pyramid, x: 16 * 8, y: 55}, - "*": {img: flower, x: 16 * 8, y: 68}, - "V": {img: pipePlant, x: 16 * 8, y: 60} +const pyramidSprite = { + x: 90, + height: 34, }; const ONE_SECOND = 1000; @@ -136,95 +59,133 @@ function incrementTimer() { } } -function drawTile(sprite) { - g.drawImage(sprite.img, sprite.x, sprite.y); -} - function drawBackground() { + // Clear screen g.setColor(LIGHTEST); g.fillRect(0, 10, W, H); - // draw floor - g.setColor(DARK); - for (var x = 0; x < 16; x++) { - var floorSprite = Object.assign({}, STATIC_TILES._, {x: x * 8}); - drawTile(floorSprite); - } + // Date bar + g.setColor(DARKEST); + g.fillRect(0, 0, W, 9); // draw sky - var skySprite = STATIC_TILES.X; g.setColor(LIGHT); - drawTile(skySprite); + g.fillRect(0, 10, g.getWidth(), 15); + g.fillRect(0, 17, g.getWidth(), 17); + g.fillRect(0, 19, g.getWidth(), 19); + g.fillRect(0, 21, g.getWidth(), 21); } -function drawScenery() { - // new random sprite - const spriteKeys = Object.keys(TILES); - const key = spriteKeys[Math.floor(Math.random() * spriteKeys.length)]; - let newSprite = Object.assign({}, TILES[key]); +function drawFloor() { + const fImg = require("heatshrink").decompress(atob("ikDxH+rgATCoIBQAQYDP")); // Floor image + for (let x = 0; x < 4; x++) { + g.drawImage(fImg, x * 20, g.getHeight() - 5); + } +} + +function drawPyramid() { + const pPol = [pyramidSprite.x + 10, H - 6, pyramidSprite.x + 50, pyramidSprite.height, pyramidSprite.x + 90, H - 6]; // Pyramid poly + + g.setColor(LIGHT); + g.fillPoly(pPol); + + pyramidSprite.x -= 1; + // Reset and randomize pyramid if off-screen + if (pyramidSprite.x < - 100) { + pyramidSprite.x = 90; + pyramidSprite.height = Math.floor(Math.random() * (60 /* max */ - 25 /* min */ + 1) + 25 /* min */); + } +} + +function drawTreesFrame(x, y) { + const tImg = require("heatshrink").decompress(atob("h8GxH+AAMHAAIFCAxADEBYgDCAQYAFCwobOAZAEFBxo=")); // Tree image + + g.drawImage(tImg, x, y); + g.setColor(DARKEST); + g.drawLine(x + 6 /* Match stalk to palm tree */, y + 6 /* Match stalk to palm tree */, x + 6, H - 6); +} + +function drawTrees() { + let newSprite = {x: 90, y: Math.floor(Math.random() * (40 /* max */ - 5 /* min */ + 1) + 15 /* min */)}; // remove first sprite if offscreen let firstBackgroundSprite = backgroundArr[0]; if (firstBackgroundSprite) { - if (firstBackgroundSprite.x < -20) backgroundArr.splice(0, 1); + if (firstBackgroundSprite.x < -15) backgroundArr.splice(0, 1); } // set background sprite if array empty - var lastBackgroundSprite = backgroundArr[backgroundArr.length - 1]; + let lastBackgroundSprite = backgroundArr[backgroundArr.length - 1]; if (!lastBackgroundSprite) { lastBackgroundSprite = newSprite; backgroundArr.push(lastBackgroundSprite); } // add random sprites - if (backgroundArr.length < 6 && lastBackgroundSprite.x < (16 * 7)) { - var randIdx = Math.floor(Math.random() * 25); - if (randIdx < spriteKeys.length - 1) { + if (backgroundArr.length < 2 && lastBackgroundSprite.x < (16 * 7)) { + const randIdx = Math.floor(Math.random() * 25); + if (randIdx < 2) { backgroundArr.push(newSprite); } } for (x = 0; x < backgroundArr.length; x++) { let scenerySprite = backgroundArr[x]; - - // clear sprite at previous position - g.setColor(LIGHTEST); - drawTile(scenerySprite); - - // draw sprite in new position - g.setColor(LIGHT); scenerySprite.x -= 5; - drawTile(scenerySprite); + drawTreesFrame(scenerySprite.x, scenerySprite.y); } } -function drawMario() { - // clear old mario frame - g.setColor(LIGHTEST); - g.drawImage( - marioSprite.negFrames[marioSprite.frameIdx], - marioSprite.x, - marioSprite.y - ); - g.drawImage( - marioSprite.frames[marioSprite.frameIdx], - marioSprite.x, - marioSprite.y - ); +function drawCoinFrame(x, y) { + const cImg = require("heatshrink").decompress(atob("hkPxH+AAcHAAQIEBIXWAAQNEBIWHAAdcBgQLBA4IODBYQKEBAQMDBelcBaJUBM4QRBNYx1EBQILDR4QHBBISdIBIoA==")); // Coin image + g.drawImage(cImg, x, y); +} +function drawCoin() { + if (!coinSprite.isAnimating) return; + + coinSprite.y -= 8; + if (coinSprite.y < (0 - 15 /*Coin sprite height*/)) { + coinSprite.isAnimating = false; + coinSprite.y = coinSprite.yDefault; + return; + } + + drawCoinFrame(coinSprite.x, coinSprite.y); +} + +function drawMarioFrame(idx, x, y) { + const mFr1 = require("heatshrink").decompress(atob("h8UxH+AAkHAAYKFBolcAAIPIBgYPDBpgfGFIY7EA4YcEBIPWAAYdDC4gLDAII5ECoYOFDogODFgoJCBwYZCAQYOFBAhAFFwZKGHQpMDw52FSg2HAAIoDAgIOMB5AAFGQTtKeBLuNcQwOJFwgJFA=")); // Mario Frame 1 + const mFr2 = require("heatshrink").decompress(atob("h8UxH+AAkHAAYKFBolcAAIPIBgYPDBpgfGFIY7EA4YcEBIPWAAYdDC4gLDAII5ECoYOFDogODFgoJCBwYZCAQYOFBAhAFFwZKGHQpMDw+HCQYEBSowOBBQIdCCgTOIFgiVHFwYCBUhA9FBwz8HAo73GACQA=")); // Mario frame 2 + + switch(idx) { + case 0: + g.drawImage(mFr1, x, y); + break; + case 1: + g.drawImage(mFr2, x, y); + break; + default: + } +} + +function drawMario(date) { // calculate jumping - const t = new Date(), - seconds = t.getSeconds(), - milliseconds = t.getMilliseconds(); + const seconds = date.getSeconds(), + milliseconds = date.getMilliseconds(); if (seconds == 59 && milliseconds > 800 && !marioSprite.isJumping) { marioSprite.isJumping = true; } if (marioSprite.isJumping) { - marioSprite.y = (Math.sin(marioSprite.jumpCounter) * -10) + 50 /* Mario Y base value */; + marioSprite.y = (Math.sin(marioSprite.jumpCounter) * -12) + 50 /* Mario Y base value */; marioSprite.jumpCounter += marioSprite.jumpIncrement; + if (parseInt(marioSprite.jumpCounter) === 2 && !coinSprite.isAnimating) { + coinSprite.isAnimating = true; + } + if (marioSprite.jumpCounter.toFixed(1) >= 4) { marioSprite.jumpCounter = 0; marioSprite.isJumping = false; @@ -232,51 +193,28 @@ function drawMario() { } // calculate animation timing - if (timer % 100 === 0) { + if (timer % 50 === 0) { // shift to next frame marioSprite.frameIdx ^= 1; } - // colour in mario - g.setColor(LIGHT); - g.drawImage( - marioSprite.negFrames[marioSprite.frameIdx], - marioSprite.x, - marioSprite.y - ); - - // draw mario - g.setColor(DARKEST); - g.drawImage( - marioSprite.frames[marioSprite.frameIdx], - marioSprite.x, - marioSprite.y - ); + drawMarioFrame(marioSprite.frameIdx, marioSprite.x, marioSprite.y); } - -function drawBrick(x, y) { - const brickSprite = Object.assign({}, STATIC_TILES['#'], {x: x, y: y}); - - // draw brick background colour - g.setColor(LIGHT); - g.fillRect(x, y, x + 20, y+14); - - // draw brick sprite - g.setColor(DARK); - drawTile(brickSprite); +function drawBrickFrame(x, y) { + const brk = require("heatshrink").decompress(atob("ikQxH+/0HACASB6wAQCoPWw4AOrgT/Cf4T/Cb1cAB8H/wVBAB/+A")); + g.drawImage(brk, x, y); } -function drawTime() { +function drawTime(date) { // draw hour brick - drawBrick(20, 25); + drawBrickFrame(20, 25); // draw minute brick - drawBrick(42, 25); + drawBrickFrame(42, 25); - const t = new Date(); - const h = t.getHours(); + const h = date.getHours(); const hours = ("0" + ((is12Hour && h > 12) ? h - 12 : h)).substr(-2); - const mins = ("0" + t.getMinutes()).substr(-2); + const mins = ("0" + date.getMinutes()).substr(-2); g.setFont("6x8"); g.setColor(DARKEST); @@ -284,25 +222,30 @@ function drawTime() { g.drawString(mins, 47, 29); } -function drawDate() { +function drawDate(date) { g.setFont("6x8"); g.setColor(LIGHTEST); - let d = new Date(); - let dateStr = locale.date(d, true); - dateStr = dateStr.replace(d.getFullYear(), "").trim().replace(/\/$/i,""); - dateStr = locale.dow(d, true) + " " + dateStr; - g.drawString(dateStr, (W - g.stringWidth(dateStr))/2, 0, true); + let dateStr = locale.date(date, true); + dateStr = dateStr.replace(date.getFullYear(), "").trim().replace(/\/$/i,""); + dateStr = locale.dow(date, true) + " " + dateStr; + g.drawString(dateStr, (W - g.stringWidth(dateStr))/2, 0); } function redraw() { + const date = new Date(); + // Update timers incrementTimer(); // Draw frame - drawScenery(); - drawTime(); - drawDate(); - drawMario(); + drawBackground(); + drawFloor(); + drawPyramid(); + drawTrees(); + drawTime(date); + drawDate(date); + drawMario(date); + drawCoin(); // Render new frame g.flip(); @@ -335,7 +278,6 @@ function startTimers(){ resetDisplayTimeout(); - drawBackground(); redraw(); } @@ -345,7 +287,6 @@ function init() { // Initialise display Bangle.setLCDMode("80x80"); - g.clear(); // Store screen dimensions W = g.getWidth(); @@ -381,4 +322,4 @@ function init() { } // Initialise! -init(); +init(); \ No newline at end of file From 3f6e4b630ed4ff9f1274ff7bfd1aed6258fe5908 Mon Sep 17 00:00:00 2001 From: Paul Cockrell Date: Sat, 4 Apr 2020 11:05:51 +0100 Subject: [PATCH 54/59] Vertical align date string --- apps/marioclock/marioclock-app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/marioclock/marioclock-app.js b/apps/marioclock/marioclock-app.js index ed1d51cde..5622c10f2 100644 --- a/apps/marioclock/marioclock-app.js +++ b/apps/marioclock/marioclock-app.js @@ -228,7 +228,7 @@ function drawDate(date) { let dateStr = locale.date(date, true); dateStr = dateStr.replace(date.getFullYear(), "").trim().replace(/\/$/i,""); dateStr = locale.dow(date, true) + " " + dateStr; - g.drawString(dateStr, (W - g.stringWidth(dateStr))/2, 0); + g.drawString(dateStr, (W - g.stringWidth(dateStr))/2, 1); } function redraw() { From 32e1642555d656bcc88b0e84dc18076c6dd65d8c Mon Sep 17 00:00:00 2001 From: Stefano Baldan Date: Sat, 4 Apr 2020 14:14:01 +0200 Subject: [PATCH 55/59] Added minion themed clock --- apps.json | 13 +++++++ apps/minionclk/ChangeLog | 1 + apps/minionclk/app-icon.js | 1 + apps/minionclk/app.js | 65 +++++++++++++++++++++++++++++++++++ apps/minionclk/minionclk.png | Bin 0 -> 5654 bytes 5 files changed, 80 insertions(+) create mode 100755 apps/minionclk/ChangeLog create mode 100755 apps/minionclk/app-icon.js create mode 100755 apps/minionclk/app.js create mode 100755 apps/minionclk/minionclk.png diff --git a/apps.json b/apps.json index f0bc4874a..d5d321bbe 100644 --- a/apps.json +++ b/apps.json @@ -1059,5 +1059,18 @@ "storage": [ {"name":"widmp.wid.js","url":"widget.js"} ] + }, + { "id": "minionclk", + "name": "Minion clock", + "icon": "minionclk.png", + "version": "0.01", + "description": "Minion themed clock.", + "tags": "clock,minion", + "type": "clock", + "allow_emulator": true, + "storage": [ + {"name":"minionclk.app.js","url":"app.js"}, + {"name":"minionclk.img","url":"app-icon.js","evaluate":true} + ] } ] diff --git a/apps/minionclk/ChangeLog b/apps/minionclk/ChangeLog new file mode 100755 index 000000000..7b83706bf --- /dev/null +++ b/apps/minionclk/ChangeLog @@ -0,0 +1 @@ +0.01: First release diff --git a/apps/minionclk/app-icon.js b/apps/minionclk/app-icon.js new file mode 100755 index 000000000..f78fb9e35 --- /dev/null +++ b/apps/minionclk/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwhAaXlZEolVVvOj0mq1XOv9/qtWFb8rquj1XV5wBDAA2jvMqNLMqwAsCABBhBAIujqpbWvIsCLowBHMg0qFyVVFQJNDK4YoEAYxjFvIuQwHP6ur5+rDgfU5wBDMI2qCYOsC4XV0bFOwIWBAAeBAIOrMYYsF54sCCIWswQDB52AGBcrFIOtF4gAEMoJfDAAOrCYQuDAIowKFwQWIBIeA52pGQPWLYgAFA4YDBGA4uDEwQYFGQvPL4IuKC4wwHFglWAIQYIYoQuFCYwDGqrqFF4YYCYBKeHHwgRLlZhCLowMBKIIubWAtWF4PXBQRdEBAIBHGAoTRCIRfCDQQvBLofXB4NVBIQcDFweAOYdWp9WqwrDGA8ABoRJFAAOswFOqtUwBNFeQYVCwMqp4ABqwbDCowvCAgKOGf4N5aAIwKKIVPpwRBGQOBFw5fCIgZfGwFVlT/BqtVBQQwFUAVWFwMAlYvCL6mBqkqDgNUF4RLGAgVPFwMAklPwD0GX5gOCXoReBJgSvDIwWrAoN6py/Cp58DCYxQBVIYwHqyQBbgL6EX4qQDFwRdFLAifBaoQaEAJIuDCYWrEgoTIGAerWIJfHGRZdECZ5fD0bQBIwJgEIoynEGBJxIAAYPBwHNlUq6owBMIZ4OMKQPC0eiqsr53PX4guOwBhOComk0ejqpfB53OJZAeDU4lVvN5OQQXKBIeA0RfBvNV5wwBMI4uD1oLDFoN4AQJEMBYWl0fOL4NUL4QwCPw4BEwN4AAejvGACZaMBLoRfGAIWr1Z8HwGkFQRIBDgekwAVGFoOAB4QTDqgvBFwQDD1Wk1el1YsBv4oDAIoAB0d/GQOlAIV/CpF51ZfFAIgAEUoOiAJYmEAAoHDvOBFxWqAIWpFxwnDOJABBquJ1QwM5oDCMYYDDAIN/5+r6CABHRKOBmVewIwCYY4sC0bGB678B1ekZYIAB0ulwOlvWkIQLJCMY0yq2sr2sMJYABp96vQnB0tPz4FBBANzAAWj5pdI0dWq0zr2Ir2rMJKQCvNIp9PudIuYDBAIV0FwSMFL4d/LoMzL4WBwIwD6hhH5ujuZXBFAIDDAIOdFwPNL4hdCwBdCq15AgMrAQLDB52pRYYACBIWjvGdK4NJAQOdvIlB5oXB0QwBLoWjqsrAAaSCGANVGAJHBSQjBEAAINBewIDCLYIBCAAJfDv5dCLAIvBvIEDAAJoBwGqDQSUBY4htDBwIBBAoIwDL4WjvNdhAvCAAYFGhDGCY4IAB1QABFwQwDv4BB1V/0eA0mALINdP4IpGMYcAAIQABGAIxDAAIFBruCroAGq1eFALkDmdeD4IjDGQYCCBQYDBCgIqBAJAoBAQIDCmeBCoIDCGgIfBLooADL4YBCJAIiCAANdAIQoCAI4ABAYdWKQQDDMooEBlVPBwJfCGAwABFxABDSAZYGLo1OvFOIgQaBLYZhFAIsyFgYAEFAUqpxUBFYQ=")) \ No newline at end of file diff --git a/apps/minionclk/app.js b/apps/minionclk/app.js new file mode 100755 index 000000000..b613a5192 --- /dev/null +++ b/apps/minionclk/app.js @@ -0,0 +1,65 @@ +const bob = require("heatshrink").decompress(atob("nk8hAaXlYLWAEsqvN/0gBBql5lQ2tquj1XV5wBJ52j0hACPsdP1QsBAQQAGBIIBF51/P8OkN5R1GIxF5HLmAFgoDLPZfOpzmZ6vPFwomCPaA6DAYOjeq2A1YyCdI4HGQJQ8F1T2SJ4Oq1XW1es1mtAQOrPoPUAIh3J54ZHIAR5S62s64cBwIBGQIOqHQK4HKQYVDAAIFC1g+BHh9VHAQAFDwQDDHoJ5E54BB6AaBKQ5YGqo6MwJzGHQ4BDeIj/BR4JxDABY8BvI6OOYgaEHwZADHgQ6BZA42GAIusPJNW64eFqzJDlcrERA8BHQI2FqwaBDYYGBPI45GCoIgCLoVWQ5NWXA2rKhaiGLAwOGEAmADxJPDVA51ElQaMC4ouEWALdEHRg8Dc4woCDJo8EAIYxCHQQIFHiwaRegJ5EcYWsHgbrKbBA8GDSrNDO4wfRKgR3FDSh3CN4UrdwZbSHYZ5DHajMFHYQGCHalWO4jtQDQwABwAGCAAQfTKoK0EHahwCeARdFHakASIZWVZ4Q8CO4YgWO4QbCO6hWGEIKYZKzZ3DLog7UG4I6C1lWDSdWO4bpCO4bwUwKYEHajMDwOAlUkLojTUd4gaTZoRWC0YIB1eJLqo4EWiqRE0mjlcr1QkEeKFWOooBCHiB2CC4WA5wzB52rEQgfPHQwABAYJXOHQ2iO4XO6omFEJh1BEAgBGPJlWDIQbC0ej50qgHV1XPEwohKcwRbEvJ3EBQTrLFomkOwOjlR3C5w8GMAR8ClYuBLIgOCvN4HgIZFDQYbBlaOBR4YNCwA5B0XOpzvBHgWqTw4AFxB1EvQ6BAAI8GDZILEdgQBCqp3DPIRfIEQwABvJ1CvGkvGiwA6IAYoBCv6wCAAVOlQ6DAIWkL5ABEwN40Z1CAYJfCv7zEAJNWOYZ3KAIWq5yYHFYLOBLIrVCAIh7BOIzpECoYDDpw7BHAQDG1WqwGkAIN/CwIABLY4LDAAZ9BwAABvLCBC5IBBvOrO44BEAAmjAIPN0XOAJyHIAAgPEquBHBi4BAId+HwWiHxqJDRpYBDq2I1R3LIAQ6BAAOpPogABGgIDDOomk0nP5pIGd42Aq1ewI8CeZI6CHAJhCEAIDCdIo2B0er1esAQIZBC4Z9JlVW1leeKGp0es5+s6+s6ABB0oFBAIervWr0ulub7OqtWmdexJ4BGxB5G0V6pF6wItB0t6p9PvQABvINBudJudPzwXCHQwBDlY6BO4WIwPPPJbvDvA0BFgNzAAIDGugGCzrtHdYh1DAIOBrzxBPIgAIeIXNHgoBCGwYADzoVB0fNOpMyHQdW5+Bro7BHgQAB6jxJAAOjOYhxCAIukOoPN5ujdZFWqyyD0d6AwUrquBwAuB1I1FHgRJBMoQ9BWg1zzw0BDYI6B0R3DAAJ1BvMyp8rAAV4IQWBIodewAeCHAZ5IAAJoBAAXHHAJWDO4TtEdYQvEHgejAwIKClcqIQRdDXYbzFeoQBIGwIDDOot/VgQ6FAAIGBlgBCAAMzmZPBF4LzDACB1FAAOi1WjvFVr0zGYQ7GAAMAAYpPBwNeAIOIwOrfYOA1eA1WkAIWjAIekv4PBwCVBruBq5eBEYIABlcBF4wCEHw55CHwQABIQQBBABkzAILlCHQR1CFYavEPgsAAAIDEDQNdAwQAaHQNWEwQ0DHAh3KleBLoI7dHQKuFWQo0EAIsISoKdBHbyyHNgwADlVVpwEBDANWro7fd4Q6HO495vF5QgIYCd75eBHYUINAN5lQ3EA")); + +const locale = require("locale"); + +const black = 0x0000; +const white = 0xFFFF; + +let hour = ''; +let minute = ''; +let date = ''; + +function draw() { + const d = new Date(); + + const newHour = ('0' + d.getHours()).substr(-2); + const newMinute = ('0' + d.getMinutes()).substr(-2); + const newDate = locale.date(d).trim(); + + g.setFontAlign(0, 0, 0); + + if (newHour !== hour) { + g.setFontVector(48); + g.setColor(black); + g.drawString(hour, 64, 92); + g.setColor(white); + g.drawString(newHour, 64, 92); + hour = newHour; + } + + if (newMinute !== minute) { + g.setFontVector(48); + g.setColor(black); + g.drawString(minute, 172, 92); + g.setColor(white); + g.drawString(newMinute, 172, 92); + minute = newMinute; + } + + if (newDate !== date) { + g.setFontVector(12); + g.setColor(black); + g.drawString(date, 120, 228); + g.setColor(0xFFFF); + g.drawString(newDate, 120, 228); + date = newDate; + } +} + +function drawAll() { + g.drawImage(bob, 0, 0, { scale: 4 }); + draw(); +} + +Bangle.on('lcdPower', function(on) { + if (on) { + drawAll(); + } +}); + +Bangle.loadWidgets(); +Bangle.drawWidgets(); +setInterval(draw, 1000); +drawAll(); + +setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"}); diff --git a/apps/minionclk/minionclk.png b/apps/minionclk/minionclk.png new file mode 100755 index 0000000000000000000000000000000000000000..77cac31df144daa3092f595ab388d5459e39903f GIT binary patch literal 5654 zcmV+x7U}7UP)r1PMDMs^@2B000%WNklK#%ZcJhUS&(BVp*1Gnj%GtGn{?q&Rx&)E>Az4v7Dl4i?&8DFu1tDocBEI z|M@@vSMd}4?0)apRl*FVl@dfD0YxN6f#^k|5WL9BJO7pZq~59iUmo81)<06Mg)&VO zbWw)CWQ=+j;_pH@FCu4PlMk?SGEKMXPcXXE9i-My;3 z=Vw13f1(Z)SARpb?)a<#gtcEYRb}pn@F|FY3ndl;T8W1!h$xgOk*Ji25@~D^1SCQf z5kw@2NQ@#;Oz=@hFT@b9co+Y%#P~-iANdc1pNIpKtG}tbcYHRw*}}cGDOfopeB+Ov&sFt7l}U0#Sr$P+FsmL1~L&$P3dP~9Pf_P|l3lu45ffcjVK!{Va(J;De)w~9KmEcLfbC}}_6E z%d2+?z}hSS<<4%e{VTOspFFHq-Kc1p+IcOp!nvBNj<~9zV-H#CY;ml&Ny`q%(*hwu zX@jyk+O$FED5Z#^@Nt>pBw>HL%HFt3;WRPSNOV9#h>+_Ui`~I&F}c#l&7RKcOMmzD z2fpwMz-v!^Lf!ts-;@7k2_0;F|Ium5znE0nUBgLTO~?D0F`%_UDTVhAg&+dXM_jNZ zD$=vBbAI_H=JEqX<><77PFK;!5@O0>ahi?8vkb;1gM%IFdWJ|qqJYwfN|9$IN+xpfm-cXDgjGn)=j$}*Xb866HN%PFa~ zbbDRe-5yz*V~i$78tS1H!3VUq1n;R`RnGV4@^%`3>-``6=x6@B41D*yFP&aJwfdX4 z*4KY-dwah&My2cP*Lm&Q6*`?3t0zvfxVS`bu1CAw!di>c3Z>K$492FZeLyQqRTb2= z$7XX>#hBnrtg#G70|xusfUvZ@#C(6AcDqBK=UAJfv<4I+;De{ED(bqXDjm+%lto#u ztSsu;Z2AjT<-YXskAM779S(JHWO=&$}+R72v1#o_0?anH?H5v<`?FFYHMrPS!*^za@6*2`_L;AK^Bo_3{4r)lp+sOj9xy9roWK1X{eGXNr4<$zmua;-SRHx! z`!Dm&ulx!7gX^fI$GhMCI1fJbc2trQf@fhq$CwGTS%Ff5(VFNh2sQJ)9`o~yoIHJs z(ddBR{oT)T>*^1&S)04w`gVTiiN{%9UZyB2j4^~@2vO+G^-+38cUDjog&rP`U20?N zBaeM((VjbZ_C3xyLWnwqnqoR(e!fq))22Vaz+8WxR=Z7}C0xILl^4JDAG!R(m)Nf= z&YaG8>Z!|g+P})Z_dSSG8lw&Ec8fGksj3PQK|)QMSX%84E5}yQR`ca2|Abec{vt&& zqN+jNy2KyM4te6^pI~We1?K`v8FY*!X+rHB{rNtJhldnJp<;;1a57%jcbq@p8jVJP zP*o*WRWje7BhOoO=jO;;ZERwhO(tw_US+WNL+-ibG$uLE%a>A8Zt?AB|B&HuNS3A; zV@Rx}*Xv=7IT}uZG)7V{PO(SsyUo+Xb!A8jR7++yK%vLjl%k0J6MAp5=GxPN%aLVn)~1WxB19NKS8(KJ>vgOq$lGEAq2o+Y=-v%1=K!r`c0?##b5qq((`w-<2~a5 zZ+_PY_~b8rn%mEv!_^+E%~3`*S}Urm!nuH}YeXW%f;=3awPE+tHFNwvA|l4-^tye9 z!$az-#`~HOnm&-D<>Wo@`)M9}_?zcAGDarKAr44uAdq4l+H+~!MYLr%_d7C_M5kf;vj7`v{8E{2W(&@C>+uOr?hc=m746lNk ztlGDnziD0@9V1QK1m{RwZF=1vhod2jODp7g2Wy*1A^}m5w|lfzWAKk^zDc!EJI{DL zB1BJJ*Mtx#Yaz{BjE4i}dh?`NMv_|Eo!%Qg2C6|Ur7+r}wM8k7_nv7n#cIoBJV6As z*0k%(7%Qi=Hu3bly+W3Cnxn+Bv~q&+Xw1RjfU26|TutzSh#W1o3Z;JBuv%+G6w{(0 z2G8Jdgm(?a2q93GHH*t97z_qXr(>$x;a$W>!AFR(c^+-iCPixtD7^O^j)oXx7!HRF zheLdbcP^_zC8Bx#01k&$7o0R>7WXk}3}=;gg0_jZKQO#Q8u~P8qDdh>8`)B!no8ClyP}$JpH5W;h&DRwZ@qnlq(A zF6TVc>6D$lT_S?39k(_%n2bl1Wu!O#W4dO55T@F`kpP>SiapsFf@KwUfbH?Oky zoqtU>yGhdPp+=XeU;dZmZ}~fTdMKT6Fc_0(3EggoC_)HMuc4NTs4e2?5d%WHdgGV?uZNvJ$juErRLn$9p< zqmKrRQVGsEVm)N<#&?LX{U?_72);X{G_I$0`=O7rAz8iT&av zo-WQ?yh~6f#RtLo8jS-tqBy*P+kBc6)r+WQLlBD`P2x0#Br~MxKI-tFGEU#iwEYf9 zmI-w5riF`5FubcFlo$$pH6RRsz;T{sb#aR5oYmsp3c-6r zlD4?_jzh}H1{*tuNxi_d%Bj6=R0Tgls%=bhjpOzv_PD3=eS)u%&`2X%gEET5B$&iv ztYJ=`qprTi;rI+LJ5NYgDSZp?1RG|kdLL77uw-6irB|Vn4lcG(2wF7?;E(psgPA#} zp8Lvg#|Lj8sfeJI91WJHL1Spp!BC-m0lpx(0#_CIs>V6Nd!ecV&Xq)85`%*niK=;_ z0<Xo;m=l9T#3K?wd{fa%p;SN! z1Xts$indG z&tK&DN(UbTn#OaHMsaQit_GSvtqoBrBup7?M-FCvRxaGf+_^It1;Ke@IpNa97g#-a zC+SLu7{EIi@9(qu@*16m^JKk*>CKxgbzbAbJ9eqZDK>3XI$|VBBVUR{L=-_ZnRQ&e zX88KnThPfIwseuG&+^P`yL>piPH(P@a{;ZIOhow$T0ep)1;(I!AnPBeGq=X)fB$6` zz7;uh`#w6$K!j>E*MDLmI@3MFK3K?I+nvBE`IrWJiLJNuhNZb-6 zs-qxEBX*(5OwD(182;e^vr6iU-!P2R=RH*(&0<`VsWm)b>)ibt5$a2}LG zD^1iIr4^_S3#WSAb;l*1{QPxZlbn@)hE@jgLe}ZBaqF9ik6@Y&D@`nm?H+Ct=(IiW z`o&Y6ekftIcYsL}Bu0oH!6PDssEBA1neyC?CI0xv{mj%Hp{~hPz&>)@WxnveMNB>5 z>f92keJc-#i!Agriqeyq2+9D-(RYI^(HQU!+gs(sAJZ(&-{7S`3(WQw$Xh9SX3$2^ zx+y~m0#Okw!Bn2x-ln=PqHt^UPOSzhVjX6eTq`R!=i~q~AF%UkWW1H)XF1{xiB+`cU~UDL&S{n}BrLzVO?w5((G)^JnFNUy z5+fl*YOhhTV1MX&cI!UA{R&JbH^9#bD&_dH<-KQL$3Fe71D2MS$=Y46Tz;9&wd;sV z*m&!Ec<15M+h%9&qomb;06Ecna1QYv!~>BSD#X{6MZxy&l=WR<-QUOe#t-p>A8xYbw^`^f zaASR){kR>1l3a3wbfM>4fMIF zi6NpS!2x9*K|G0yln$aa>{23x81S*iv=UUD;I^(ZT)#v$9n(5>lGWp@{P4HmG*yfQX{2*SY%cI41f`gb$7FdMQ;rC;15A<bk~`$0L9vJ*VJUPjPm+An1gv)!nS#`5^hRQ;a7Cr*2!JtZIxgc<<4s z88SXbY8Ua&AC*iXhQE_l73V{?3-d~O+%7OhUR{%Ige z#CgYjt4nU1j70^N^He?}A>u=WNFg>iEuhdy^E(FW>6F3nfPlsrLkt15rY>icqX98r wpm)q*i*4@cZL)N{;@WP)en=ZG78`W?Z*>U&R3l4K!2kdN07*qoM6N<$f>uAdmH+?% literal 0 HcmV?d00001 From aa3f074ed4e08b98859ce77c24f66490f3fe523f Mon Sep 17 00:00:00 2001 From: Stefano Baldan Date: Sat, 4 Apr 2020 15:10:15 +0200 Subject: [PATCH 56/59] Fix drawing when lcd screen on --- apps/minionclk/app.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/apps/minionclk/app.js b/apps/minionclk/app.js index b613a5192..88fe446ae 100755 --- a/apps/minionclk/app.js +++ b/apps/minionclk/app.js @@ -5,9 +5,9 @@ const locale = require("locale"); const black = 0x0000; const white = 0xFFFF; -let hour = ''; -let minute = ''; -let date = ''; +let hour; +let minute; +let date; function draw() { const d = new Date(); @@ -47,6 +47,9 @@ function draw() { } function drawAll() { + hour = ''; + minute = ''; + date = ''; g.drawImage(bob, 0, 0, { scale: 4 }); draw(); } From a6231c0041ba87da0d1b95a4fb9671561a8f103c Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Sat, 4 Apr 2020 14:30:46 +0100 Subject: [PATCH 57/59] license notes --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index f59fa54e0..57999186b 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,9 @@ Bangle.js App Loader (and Apps) * Try the **release version** at [banglejs.com/apps](https://banglejs.com/apps) * Try the **development version** at [github.io](https://espruino.github.io/BangleApps/) +**All software (including apps) in this repository is MIT Licensed - see [LICENSE](LICENSE)** By +submitting code to this repository you confirm that you are happy with it being MIT licensed. + ## How does it work? * A list of apps is in `apps.json` From 62ef241369d7a9ab8c1659c2a11c1ee2eac947c7 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Sat, 4 Apr 2020 14:33:43 +0100 Subject: [PATCH 58/59] license notes --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 57999186b..877fe5e2c 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,8 @@ Bangle.js App Loader (and Apps) * Try the **development version** at [github.io](https://espruino.github.io/BangleApps/) **All software (including apps) in this repository is MIT Licensed - see [LICENSE](LICENSE)** By -submitting code to this repository you confirm that you are happy with it being MIT licensed. +submitting code to this repository you confirm that you are happy with it being MIT licensed, +and that it is not licensed in another way that would make this impossible. ## How does it work? From 25a59c87430961ef2176e72c3b72216a0c4ffb71 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Sat, 4 Apr 2020 14:37:09 +0100 Subject: [PATCH 59/59] flip changelog --- apps/wohrm/ChangeLog | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/wohrm/ChangeLog b/apps/wohrm/ChangeLog index 273b7b633..e16b50c5b 100644 --- a/apps/wohrm/ChangeLog +++ b/apps/wohrm/ChangeLog @@ -1,5 +1,5 @@ -0.05: Improved buzz timing and rendering -0.04: Only buzz on high confidence (>85%) -0.03: Optimized rendering for the background -0.02: Adapted to new App code layout 0.01: Only tested on the emulator. +0.02: Adapted to new App code layout +0.03: Optimized rendering for the background +0.04: Only buzz on high confidence (>85%) +0.05: Improved buzz timing and rendering