From 8be9b27f8b83605e72083c9ac99f09a68351817b Mon Sep 17 00:00:00 2001 From: only-meeps <151784194+only-meeps@users.noreply.github.com> Date: Thu, 20 Jun 2024 09:15:12 -0700 Subject: [PATCH 001/110] Create app.js --- 8Ball/app.js | 1 + 1 file changed, 1 insertion(+) create mode 100644 8Ball/app.js diff --git a/8Ball/app.js b/8Ball/app.js new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/8Ball/app.js @@ -0,0 +1 @@ + From 61feaec8c72e7bc78829fe05e6155f1e30b16d90 Mon Sep 17 00:00:00 2001 From: only-meeps <151784194+only-meeps@users.noreply.github.com> Date: Thu, 20 Jun 2024 09:18:29 -0700 Subject: [PATCH 002/110] Update app.js added the app --- 8Ball/app.js | 129 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) diff --git a/8Ball/app.js b/8Ball/app.js index 8b1378917..86096434d 100644 --- a/8Ball/app.js +++ b/8Ball/app.js @@ -1 +1,130 @@ +try {keyboard = require(keyboard);} catch(e) {keyboard = null;}var keyboard = "textinput"; +var Name = ""; +var WaitTime = 0; +Bangle.setLCDTimeout(0); +var answers = new Array("no", "yes","WHAT????","What do you think", "That was a bad question", "YES!!!", "NOOOOO!!", "nope","100%","yup","why should I answer that?","think for yourself","ask again later, I'm busy", "what Was that horrible question","how dare you?","you wanted to hear yes? okay, yes", "Don't get angry when I say no","you are 100% wrong","totally, for sure","hmmm... I'll ponder it and get back to you later","I just asked the presedent and they say yes","wow, you really have a lot of questions", "NOPE","is the sky blue, hmmm...","I don't have time to answer","How many more questions before you change my name?","theres this thing called wikipedia","hmm... I don't seem to be able to reach the internet right now","if you phrase it like that, yes","Huh, never thought so hard in my life","The winds of time say no"); +var consonants = new Array("b","c","d","f","g","h","j","k","l","m","n","p","q","r","s","t","v","w","x","y","z"); +var vowels = new Array("a","e","i","o","u"); +try {keyboard = require(keyboard);} catch(e) {keyboard = null;} +function generateName() +{ + Name = ""; + var nameLength = Math.round(Math.random()*5); + for(var i = 0; i < nameLength; i++){ + var cosonant = consonants[Math.round(Math.random()*consonants.length/2)]; + var vowel = vowels[Math.round(Math.random()*vowels.length/2)]; + Name = Name + cosonant + vowel; + if(Name == "") + { + generateName(); + } + } +} +generateName(); +function menu() +{ + g.clear(); + E.showMenu(); + menuOpen = 1; + E.showMenu({ + "" : { title : /*LANG*/Name }, + "< Back" : () => menu(), + "Start" : () => { + E.showMenu(); + g.clear(); + menuOpen = 0; + Drawtext("ask " + Name + " a yes or no question"); + }, + "Show name" : () => { + E.showMenu(); + if(Name == null) + { + E.showAlert("No Name Data").then(result => {menu();}); + } + + else + { + E.showAlert(Name).then(result => {menu();}); + } + }, + + "regenerate name" : () => { + E.showMenu(); + generateName(); + E.showAlert("name regenerated as " + Name).then(result => {menu();}); + + + }, + "show answers" : () => { + var menu = new Array(); + for(var i = 0; i < answers.length; i++){ + menu.push({title : answers[i]}); + } + E.showMenu(menu); + + + }, + + "Add answer" : () => { + E.showMenu(); + var result = keyboard.input({}).then(result => {if(result != ""){answers.push(result);} menu();}); + }, + "Edit name" : () => { + E.showMenu(); + var result = keyboard.input({}).then(result => {Name = result, menu();}); + + }, + "Exit" : () => load(), + }); +} +menu(); + + var answer; +function Drawtext(text) +{ + g.clear(); + //g.setFontAlign(0,0); + g.setFont("Vector", 20); + g.drawString(g.wrapString(text, g.getWidth(), -20).join("\n")); + + +} +function DrawWidgets() +{ + Bangle.loadWidgets(); + Bangle.drawWidgets(); +} +function WriteAnswer() +{ + if (menuOpen == 0) + { + var randomnumber = Math.round(Math.random()*answers.length); + answer = answers[randomnumber]; + var i; + + Drawtext(answer); + setTimeout(function() { + Drawtext("ask " + Name + " a yes or no question"); +}, 3000); + + } + +} +//turns screen timeout off when menu closed +//needs attention +/*if(menuOpen == 1) +{ + Bangle.setLCDTimeout(10); +} +else +{ + Bangle.setLCDTimeout(undefined); +}*/ + +setWatch(function() { + menu(); + +}, (process.env.HWVERSION==2) ? BTN1 : BTN2, {repeat:true, edge:"falling"}); + + Bangle.on('touch', function(button, xy) { WriteAnswer(); }); From 2b7aac868693668fa38761e982bf62386e24ef26 Mon Sep 17 00:00:00 2001 From: only-meeps <151784194+only-meeps@users.noreply.github.com> Date: Thu, 20 Jun 2024 09:34:12 -0700 Subject: [PATCH 003/110] Create app-icon.js added appicon --- 8Ball/app-icon.js | 1 + 1 file changed, 1 insertion(+) create mode 100644 8Ball/app-icon.js diff --git a/8Ball/app-icon.js b/8Ball/app-icon.js new file mode 100644 index 000000000..18811535a --- /dev/null +++ b/8Ball/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwwIROj/wAod//wECgPgg+AAoIDBA4IFBhwCBuACBjgCBnACD4AICBwPACgVggfwgwFB4AiBgYuB4AHBgYsBGQQDBAooTBAAQTBgIFEBgYFBg4kBApARCwAdE4AFBAgMD8AFJCIRBDwJNHFwRZBCgIFCAQKMCg6gC///UQQFFsACBQYQFLFIoFKSpcBGgIABTYIFD4ArCGYQFFg4RDY4IXECAYAHA==")) From f73cdb7126caac0bc5e6c916bc871cffade6f306 Mon Sep 17 00:00:00 2001 From: only-meeps <151784194+only-meeps@users.noreply.github.com> Date: Thu, 20 Jun 2024 09:41:13 -0700 Subject: [PATCH 004/110] Create metadata.json --- 8Ball/metadata.json | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 8Ball/metadata.json diff --git a/8Ball/metadata.json b/8Ball/metadata.json new file mode 100644 index 000000000..9cbe91389 --- /dev/null +++ b/8Ball/metadata.json @@ -0,0 +1,15 @@ +{ "id": "8ball", + "name": "Magic 8 ball", + "shortName":"8ball", + "icon": "8ball.png", + "version":"0.01", + "description": "It tells your future! + + Ask the 8ball a question by clicking start and then clicking the screen! Then it will answer you question with a yes or no answer (hint : only ask it yes or no questions, its a little dumb).", + "tags": "Games", + "supports": ["BANGLEJS2"], + "storage": [ + {"name":"8ball.app.js","url":"app.js"}, + {"name":"8ball.img","url":"app-icon.js","evaluate":true} + ] +} From e83129cfa1e16a825a63fa588f0d41f0da221c40 Mon Sep 17 00:00:00 2001 From: only-meeps <151784194+only-meeps@users.noreply.github.com> Date: Thu, 20 Jun 2024 09:42:07 -0700 Subject: [PATCH 005/110] Add files via upload --- 8Ball/8ball.png | Bin 0 -> 983 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 8Ball/8ball.png diff --git a/8Ball/8ball.png b/8Ball/8ball.png new file mode 100644 index 0000000000000000000000000000000000000000..72344261a449d4945cc8c8e7e889bc8b1614e466 GIT binary patch literal 983 zcmV;|11S87P)6>g+VS4QY7+% ziE?@2!7brUZp8zUdBjLzghVdo{=iJR%(%^`>!(;ip{lsgQ#O8=MZchl=- zz*=cUj+wn>Ky}=J?f@G#yO|C)nYy+KxEp8p9#|6P6X~W`!8mUKP64AWbc{{0G>q1H zAd8S08uxxb1ttZcIT?5sw@z{iiQ&KpIWkY6lS{i{z=5E!66{s zgY9Q6*kq&w2j!yz=;33$e+XZba0$@TrQIlCx$M5^_uwQpEr1iUx#GcBv#gWgW1xcv zyE2E+dBcTW2Jk@ri||Qz&E8L7q(|H7z)lUM2H2qm>xMDFFTH-gBGWDnV4n|-8buec z9FlKy<5si*J^^(=wyg*-4H$1>*H=&eBhcE$@jT7IX;Mdt#xTdm_=t=bkvbM@42Nxu zV^JhgJT`UBQ6-_U=oy#wJz+vwJ@B@fJ_jUTNVvRLL^5mAHG?#`>kilQRCraW&wUkT zP8Dbn+>oDvUX1eMGH+8>I3y?&srnNR=j3B-P&bgKuzFH`R{BUb*}zR;ri(~q#^jnl zGP>1FpCZlt2<(|HKcU4xOrqKJd&Xqg zuX?nmtd5#2t&ML$7h93o7H=!jvrWGD`wB6 zR6chT0BsZOZ^LfSgZ%6m`%-XOg`JUlNWUoY45k0Hr+aywJ9!bQM6j75a-w$mC#z~+)g5*`4pw-*#hhzKQ*xA+J z&>Da>UiJZXI_jAfVF8z)pcU$9tIqAQR*vraK~N_oK540S(5Nrgu4 Date: Thu, 20 Jun 2024 09:57:31 -0700 Subject: [PATCH 006/110] Create app.js --- apps/8ball/app.js | 130 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 apps/8ball/app.js diff --git a/apps/8ball/app.js b/apps/8ball/app.js new file mode 100644 index 000000000..86096434d --- /dev/null +++ b/apps/8ball/app.js @@ -0,0 +1,130 @@ +try {keyboard = require(keyboard);} catch(e) {keyboard = null;}var keyboard = "textinput"; +var Name = ""; +var WaitTime = 0; +Bangle.setLCDTimeout(0); + +var answers = new Array("no", "yes","WHAT????","What do you think", "That was a bad question", "YES!!!", "NOOOOO!!", "nope","100%","yup","why should I answer that?","think for yourself","ask again later, I'm busy", "what Was that horrible question","how dare you?","you wanted to hear yes? okay, yes", "Don't get angry when I say no","you are 100% wrong","totally, for sure","hmmm... I'll ponder it and get back to you later","I just asked the presedent and they say yes","wow, you really have a lot of questions", "NOPE","is the sky blue, hmmm...","I don't have time to answer","How many more questions before you change my name?","theres this thing called wikipedia","hmm... I don't seem to be able to reach the internet right now","if you phrase it like that, yes","Huh, never thought so hard in my life","The winds of time say no"); +var consonants = new Array("b","c","d","f","g","h","j","k","l","m","n","p","q","r","s","t","v","w","x","y","z"); +var vowels = new Array("a","e","i","o","u"); +try {keyboard = require(keyboard);} catch(e) {keyboard = null;} +function generateName() +{ + Name = ""; + var nameLength = Math.round(Math.random()*5); + for(var i = 0; i < nameLength; i++){ + var cosonant = consonants[Math.round(Math.random()*consonants.length/2)]; + var vowel = vowels[Math.round(Math.random()*vowels.length/2)]; + Name = Name + cosonant + vowel; + if(Name == "") + { + generateName(); + } + } +} +generateName(); +function menu() +{ + g.clear(); + E.showMenu(); + menuOpen = 1; + E.showMenu({ + "" : { title : /*LANG*/Name }, + "< Back" : () => menu(), + "Start" : () => { + E.showMenu(); + g.clear(); + menuOpen = 0; + Drawtext("ask " + Name + " a yes or no question"); + }, + "Show name" : () => { + E.showMenu(); + if(Name == null) + { + E.showAlert("No Name Data").then(result => {menu();}); + } + + else + { + E.showAlert(Name).then(result => {menu();}); + } + }, + + "regenerate name" : () => { + E.showMenu(); + generateName(); + E.showAlert("name regenerated as " + Name).then(result => {menu();}); + + + }, + "show answers" : () => { + var menu = new Array(); + for(var i = 0; i < answers.length; i++){ + menu.push({title : answers[i]}); + } + E.showMenu(menu); + + + }, + + "Add answer" : () => { + E.showMenu(); + var result = keyboard.input({}).then(result => {if(result != ""){answers.push(result);} menu();}); + }, + "Edit name" : () => { + E.showMenu(); + var result = keyboard.input({}).then(result => {Name = result, menu();}); + + }, + "Exit" : () => load(), + }); +} +menu(); + + var answer; +function Drawtext(text) +{ + g.clear(); + //g.setFontAlign(0,0); + g.setFont("Vector", 20); + g.drawString(g.wrapString(text, g.getWidth(), -20).join("\n")); + + +} +function DrawWidgets() +{ + Bangle.loadWidgets(); + Bangle.drawWidgets(); +} +function WriteAnswer() +{ + if (menuOpen == 0) + { + var randomnumber = Math.round(Math.random()*answers.length); + answer = answers[randomnumber]; + var i; + + Drawtext(answer); + setTimeout(function() { + Drawtext("ask " + Name + " a yes or no question"); +}, 3000); + + } + +} +//turns screen timeout off when menu closed +//needs attention +/*if(menuOpen == 1) +{ + Bangle.setLCDTimeout(10); +} +else +{ + Bangle.setLCDTimeout(undefined); +}*/ + +setWatch(function() { + menu(); + +}, (process.env.HWVERSION==2) ? BTN1 : BTN2, {repeat:true, edge:"falling"}); + + Bangle.on('touch', function(button, xy) { WriteAnswer(); }); From 57cb0586419165b23f7196e0af3016b815914ba1 Mon Sep 17 00:00:00 2001 From: only-meeps <151784194+only-meeps@users.noreply.github.com> Date: Sat, 6 Jul 2024 13:41:38 -0700 Subject: [PATCH 007/110] Add files via upload --- apps/8ball/8ball.png | Bin 0 -> 983 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 apps/8ball/8ball.png diff --git a/apps/8ball/8ball.png b/apps/8ball/8ball.png new file mode 100644 index 0000000000000000000000000000000000000000..72344261a449d4945cc8c8e7e889bc8b1614e466 GIT binary patch literal 983 zcmV;|11S87P)6>g+VS4QY7+% ziE?@2!7brUZp8zUdBjLzghVdo{=iJR%(%^`>!(;ip{lsgQ#O8=MZchl=- zz*=cUj+wn>Ky}=J?f@G#yO|C)nYy+KxEp8p9#|6P6X~W`!8mUKP64AWbc{{0G>q1H zAd8S08uxxb1ttZcIT?5sw@z{iiQ&KpIWkY6lS{i{z=5E!66{s zgY9Q6*kq&w2j!yz=;33$e+XZba0$@TrQIlCx$M5^_uwQpEr1iUx#GcBv#gWgW1xcv zyE2E+dBcTW2Jk@ri||Qz&E8L7q(|H7z)lUM2H2qm>xMDFFTH-gBGWDnV4n|-8buec z9FlKy<5si*J^^(=wyg*-4H$1>*H=&eBhcE$@jT7IX;Mdt#xTdm_=t=bkvbM@42Nxu zV^JhgJT`UBQ6-_U=oy#wJz+vwJ@B@fJ_jUTNVvRLL^5mAHG?#`>kilQRCraW&wUkT zP8Dbn+>oDvUX1eMGH+8>I3y?&srnNR=j3B-P&bgKuzFH`R{BUb*}zR;ri(~q#^jnl zGP>1FpCZlt2<(|HKcU4xOrqKJd&Xqg zuX?nmtd5#2t&ML$7h93o7H=!jvrWGD`wB6 zR6chT0BsZOZ^LfSgZ%6m`%-XOg`JUlNWUoY45k0Hr+aywJ9!bQM6j75a-w$mC#z~+)g5*`4pw-*#hhzKQ*xA+J z&>Da>UiJZXI_jAfVF8z)pcU$9tIqAQR*vraK~N_oK540S(5Nrgu4 Date: Sat, 6 Jul 2024 13:45:52 -0700 Subject: [PATCH 009/110] Create app-icon.js --- apps/8ball/app-icon.js | 1 + 1 file changed, 1 insertion(+) create mode 100644 apps/8ball/app-icon.js diff --git a/apps/8ball/app-icon.js b/apps/8ball/app-icon.js new file mode 100644 index 000000000..399dbef21 --- /dev/null +++ b/apps/8ball/app-icon.js @@ -0,0 +1 @@ +atob("MDCBAAAAAAAAAAAAAAAAAAAAH/AAAAAAf/4AAAAB4AeAAAAHgAHgAAAOAABwAAAcAAA4AAA4AMAcAABwAMAOAABgA/AGAADAAeADAAHAAMADgAGAAAABgAGAAAABgAMAAAAAwAMBAAAAwAMDAAAAwAMHwAAAwAMHwAAAwAMDAACAwAMBAADAwAMAAAPgwAMAAAPgwAMAAADAwAGAAACBgAGAAAABgAHAAAADgADAAAADAADgAAAHAAB////+AAB////+AABgAAAGAABgAAAGAABgAAAGAADAAAADAADAAAADAADAAAADAAGAAAABgAGAAAABgAH/////gAP/////wAYAAAAAYAYAAAAAYAf/////4AP/////wAAAAAAAAAAAAAAAAA==") From d8db65b3e76d36c83f24ba21513b0a9e8938fe90 Mon Sep 17 00:00:00 2001 From: only-meeps <151784194+only-meeps@users.noreply.github.com> Date: Sat, 6 Jul 2024 13:46:19 -0700 Subject: [PATCH 010/110] Create metadata.json --- apps/8ball/metadata.json | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 apps/8ball/metadata.json diff --git a/apps/8ball/metadata.json b/apps/8ball/metadata.json new file mode 100644 index 000000000..9cbe91389 --- /dev/null +++ b/apps/8ball/metadata.json @@ -0,0 +1,15 @@ +{ "id": "8ball", + "name": "Magic 8 ball", + "shortName":"8ball", + "icon": "8ball.png", + "version":"0.01", + "description": "It tells your future! + + Ask the 8ball a question by clicking start and then clicking the screen! Then it will answer you question with a yes or no answer (hint : only ask it yes or no questions, its a little dumb).", + "tags": "Games", + "supports": ["BANGLEJS2"], + "storage": [ + {"name":"8ball.app.js","url":"app.js"}, + {"name":"8ball.img","url":"app-icon.js","evaluate":true} + ] +} From 8f4ea698e29862f4260dc2847d38c2f29d415a72 Mon Sep 17 00:00:00 2001 From: only-meeps <151784194+only-meeps@users.noreply.github.com> Date: Sat, 6 Jul 2024 13:46:52 -0700 Subject: [PATCH 011/110] Delete 8Ball directory --- 8Ball/8ball.png | Bin 983 -> 0 bytes 8Ball/app-icon.js | 1 - 8Ball/app.js | 130 -------------------------------------------- 8Ball/metadata.json | 15 ----- 4 files changed, 146 deletions(-) delete mode 100644 8Ball/8ball.png delete mode 100644 8Ball/app-icon.js delete mode 100644 8Ball/app.js delete mode 100644 8Ball/metadata.json diff --git a/8Ball/8ball.png b/8Ball/8ball.png deleted file mode 100644 index 72344261a449d4945cc8c8e7e889bc8b1614e466..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 983 zcmV;|11S87P)6>g+VS4QY7+% ziE?@2!7brUZp8zUdBjLzghVdo{=iJR%(%^`>!(;ip{lsgQ#O8=MZchl=- zz*=cUj+wn>Ky}=J?f@G#yO|C)nYy+KxEp8p9#|6P6X~W`!8mUKP64AWbc{{0G>q1H zAd8S08uxxb1ttZcIT?5sw@z{iiQ&KpIWkY6lS{i{z=5E!66{s zgY9Q6*kq&w2j!yz=;33$e+XZba0$@TrQIlCx$M5^_uwQpEr1iUx#GcBv#gWgW1xcv zyE2E+dBcTW2Jk@ri||Qz&E8L7q(|H7z)lUM2H2qm>xMDFFTH-gBGWDnV4n|-8buec z9FlKy<5si*J^^(=wyg*-4H$1>*H=&eBhcE$@jT7IX;Mdt#xTdm_=t=bkvbM@42Nxu zV^JhgJT`UBQ6-_U=oy#wJz+vwJ@B@fJ_jUTNVvRLL^5mAHG?#`>kilQRCraW&wUkT zP8Dbn+>oDvUX1eMGH+8>I3y?&srnNR=j3B-P&bgKuzFH`R{BUb*}zR;ri(~q#^jnl zGP>1FpCZlt2<(|HKcU4xOrqKJd&Xqg zuX?nmtd5#2t&ML$7h93o7H=!jvrWGD`wB6 zR6chT0BsZOZ^LfSgZ%6m`%-XOg`JUlNWUoY45k0Hr+aywJ9!bQM6j75a-w$mC#z~+)g5*`4pw-*#hhzKQ*xA+J z&>Da>UiJZXI_jAfVF8z)pcU$9tIqAQR*vraK~N_oK540S(5Nrgu4 menu(), - "Start" : () => { - E.showMenu(); - g.clear(); - menuOpen = 0; - Drawtext("ask " + Name + " a yes or no question"); - }, - "Show name" : () => { - E.showMenu(); - if(Name == null) - { - E.showAlert("No Name Data").then(result => {menu();}); - } - - else - { - E.showAlert(Name).then(result => {menu();}); - } - }, - - "regenerate name" : () => { - E.showMenu(); - generateName(); - E.showAlert("name regenerated as " + Name).then(result => {menu();}); - - - }, - "show answers" : () => { - var menu = new Array(); - for(var i = 0; i < answers.length; i++){ - menu.push({title : answers[i]}); - } - E.showMenu(menu); - - - }, - - "Add answer" : () => { - E.showMenu(); - var result = keyboard.input({}).then(result => {if(result != ""){answers.push(result);} menu();}); - }, - "Edit name" : () => { - E.showMenu(); - var result = keyboard.input({}).then(result => {Name = result, menu();}); - - }, - "Exit" : () => load(), - }); -} -menu(); - - var answer; -function Drawtext(text) -{ - g.clear(); - //g.setFontAlign(0,0); - g.setFont("Vector", 20); - g.drawString(g.wrapString(text, g.getWidth(), -20).join("\n")); - - -} -function DrawWidgets() -{ - Bangle.loadWidgets(); - Bangle.drawWidgets(); -} -function WriteAnswer() -{ - if (menuOpen == 0) - { - var randomnumber = Math.round(Math.random()*answers.length); - answer = answers[randomnumber]; - var i; - - Drawtext(answer); - setTimeout(function() { - Drawtext("ask " + Name + " a yes or no question"); -}, 3000); - - } - -} -//turns screen timeout off when menu closed -//needs attention -/*if(menuOpen == 1) -{ - Bangle.setLCDTimeout(10); -} -else -{ - Bangle.setLCDTimeout(undefined); -}*/ - -setWatch(function() { - menu(); - -}, (process.env.HWVERSION==2) ? BTN1 : BTN2, {repeat:true, edge:"falling"}); - - Bangle.on('touch', function(button, xy) { WriteAnswer(); }); diff --git a/8Ball/metadata.json b/8Ball/metadata.json deleted file mode 100644 index 9cbe91389..000000000 --- a/8Ball/metadata.json +++ /dev/null @@ -1,15 +0,0 @@ -{ "id": "8ball", - "name": "Magic 8 ball", - "shortName":"8ball", - "icon": "8ball.png", - "version":"0.01", - "description": "It tells your future! - - Ask the 8ball a question by clicking start and then clicking the screen! Then it will answer you question with a yes or no answer (hint : only ask it yes or no questions, its a little dumb).", - "tags": "Games", - "supports": ["BANGLEJS2"], - "storage": [ - {"name":"8ball.app.js","url":"app.js"}, - {"name":"8ball.img","url":"app-icon.js","evaluate":true} - ] -} From 47854f69507783ccb19531f4ea9a5abeae2d2336 Mon Sep 17 00:00:00 2001 From: only-meeps <151784194+only-meeps@users.noreply.github.com> Date: Tue, 9 Jul 2024 14:09:44 -0700 Subject: [PATCH 012/110] Update app.js added clockbackground app functionality --- apps/boxclk/app.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/apps/boxclk/app.js b/apps/boxclk/app.js index 12c69e789..34ffac1b6 100644 --- a/apps/boxclk/app.js +++ b/apps/boxclk/app.js @@ -4,7 +4,7 @@ * 1. Module dependencies and initial configurations * --------------------------------------------------------------- */ - + let background = require("clockbg"); let storage = require("Storage"); let locale = require("locale"); let widgets = require("widget_utils"); @@ -224,9 +224,7 @@ return function(boxes) { date = new Date(); g.clear(); - if (bgImage) { - g.drawImage(bgImage, 0, 0); - } + background.fillRect(Bangle.appRect); if (boxes.time) { boxes.time.string = modString(boxes.time, locale.time(date, isBool(boxes.time.short, true) ? 1 : 0)); updatePerMinute = isBool(boxes.time.short, true); @@ -412,4 +410,4 @@ widgets.swipeOn(); modSetColor(); setup(); -} \ No newline at end of file +} From bf7eba198f61001649687ae36e4bfa6968df46f2 Mon Sep 17 00:00:00 2001 From: only-meeps <151784194+only-meeps@users.noreply.github.com> Date: Tue, 9 Jul 2024 14:10:37 -0700 Subject: [PATCH 013/110] Update ChangeLog --- apps/boxclk/ChangeLog | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/boxclk/ChangeLog b/apps/boxclk/ChangeLog index cc73fbc08..b78eba44c 100644 --- a/apps/boxclk/ChangeLog +++ b/apps/boxclk/ChangeLog @@ -3,3 +3,4 @@ 0.03: Allows showing the month in short or long format by setting `"shortMonth"` to true or false 0.04: Improves touchscreen drag handling for background apps such as Pattern Launcher 0.05: Fixes step count not resetting after a new day starts +0.06 Added clockbackground app functionality From b9c528214a3d647d3f1512df497335bcc2547bad Mon Sep 17 00:00:00 2001 From: only-meeps <151784194+only-meeps@users.noreply.github.com> Date: Tue, 9 Jul 2024 14:12:39 -0700 Subject: [PATCH 014/110] Update metadata.json --- apps/8ball/metadata.json | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/apps/8ball/metadata.json b/apps/8ball/metadata.json index 9cbe91389..62c7eb468 100644 --- a/apps/8ball/metadata.json +++ b/apps/8ball/metadata.json @@ -3,9 +3,7 @@ "shortName":"8ball", "icon": "8ball.png", "version":"0.01", - "description": "It tells your future! - - Ask the 8ball a question by clicking start and then clicking the screen! Then it will answer you question with a yes or no answer (hint : only ask it yes or no questions, its a little dumb).", + "description": "It tells your future!", "tags": "Games", "supports": ["BANGLEJS2"], "storage": [ From 5fcb2a0e70a3d099f0898215a99f293ffeda8656 Mon Sep 17 00:00:00 2001 From: only-meeps <151784194+only-meeps@users.noreply.github.com> Date: Tue, 9 Jul 2024 14:17:48 -0700 Subject: [PATCH 015/110] Update metadata.json --- apps/8ball/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/8ball/metadata.json b/apps/8ball/metadata.json index 62c7eb468..beb3a07a9 100644 --- a/apps/8ball/metadata.json +++ b/apps/8ball/metadata.json @@ -4,7 +4,7 @@ "icon": "8ball.png", "version":"0.01", "description": "It tells your future!", - "tags": "Games", + "tags": "", "supports": ["BANGLEJS2"], "storage": [ {"name":"8ball.app.js","url":"app.js"}, From 6c84343cca30b41fc681d6da42697e71041210f1 Mon Sep 17 00:00:00 2001 From: only-meeps <151784194+only-meeps@users.noreply.github.com> Date: Tue, 9 Jul 2024 14:18:53 -0700 Subject: [PATCH 016/110] Update metadata.json --- apps/8ball/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/8ball/metadata.json b/apps/8ball/metadata.json index beb3a07a9..43f24f385 100644 --- a/apps/8ball/metadata.json +++ b/apps/8ball/metadata.json @@ -4,7 +4,7 @@ "icon": "8ball.png", "version":"0.01", "description": "It tells your future!", - "tags": "", + "tags": "games", "supports": ["BANGLEJS2"], "storage": [ {"name":"8ball.app.js","url":"app.js"}, From b0874f33b5318dde78c7776db35d59cc3801e8b7 Mon Sep 17 00:00:00 2001 From: only-meeps <151784194+only-meeps@users.noreply.github.com> Date: Tue, 9 Jul 2024 14:20:42 -0700 Subject: [PATCH 017/110] Update metadata.json --- apps/8ball/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/8ball/metadata.json b/apps/8ball/metadata.json index 43f24f385..029deebbb 100644 --- a/apps/8ball/metadata.json +++ b/apps/8ball/metadata.json @@ -4,7 +4,7 @@ "icon": "8ball.png", "version":"0.01", "description": "It tells your future!", - "tags": "games", + "tags": "game", "supports": ["BANGLEJS2"], "storage": [ {"name":"8ball.app.js","url":"app.js"}, From 424d199d60ded91cb48c52c0ca6ab33696425a7f Mon Sep 17 00:00:00 2001 From: only-meeps <151784194+only-meeps@users.noreply.github.com> Date: Tue, 9 Jul 2024 14:23:34 -0700 Subject: [PATCH 018/110] Update metadata.json --- apps/8ball/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/8ball/metadata.json b/apps/8ball/metadata.json index 029deebbb..e8417ecb0 100644 --- a/apps/8ball/metadata.json +++ b/apps/8ball/metadata.json @@ -4,7 +4,7 @@ "icon": "8ball.png", "version":"0.01", "description": "It tells your future!", - "tags": "game", + "tags": "'game'", "supports": ["BANGLEJS2"], "storage": [ {"name":"8ball.app.js","url":"app.js"}, From 95aa6aebe4421c364c69c0a0972cf88063c17d2f Mon Sep 17 00:00:00 2001 From: only-meeps <151784194+only-meeps@users.noreply.github.com> Date: Tue, 9 Jul 2024 14:26:05 -0700 Subject: [PATCH 019/110] Update metadata.json --- apps/8ball/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/8ball/metadata.json b/apps/8ball/metadata.json index e8417ecb0..029deebbb 100644 --- a/apps/8ball/metadata.json +++ b/apps/8ball/metadata.json @@ -4,7 +4,7 @@ "icon": "8ball.png", "version":"0.01", "description": "It tells your future!", - "tags": "'game'", + "tags": "game", "supports": ["BANGLEJS2"], "storage": [ {"name":"8ball.app.js","url":"app.js"}, From 7bf68cd8d10181ea627558df8eb0f6412a65c93e Mon Sep 17 00:00:00 2001 From: only-meeps <151784194+only-meeps@users.noreply.github.com> Date: Tue, 9 Jul 2024 14:29:28 -0700 Subject: [PATCH 021/110] Delete apps/boxclk/boxclk.space.img --- apps/boxclk/boxclk.space.img | Bin 30979 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 apps/boxclk/boxclk.space.img diff --git a/apps/boxclk/boxclk.space.img b/apps/boxclk/boxclk.space.img deleted file mode 100644 index 1708b5c24248a388661783f446bd86f5a2e4f715..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 30979 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 Date: Tue, 9 Jul 2024 14:33:15 -0700 Subject: [PATCH 022/110] Add files via upload --- apps/8ball/screenshot.png | Bin 0 -> 2794 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 apps/8ball/screenshot.png diff --git a/apps/8ball/screenshot.png b/apps/8ball/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..f1f888cf339e202c85206ca66034cfa298fe8fff GIT binary patch literal 2794 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 Date: Tue, 9 Jul 2024 14:33:51 -0700 Subject: [PATCH 023/110] Add files via upload --- apps/8ball/screenshot (1).png | Bin 0 -> 2071 bytes apps/8ball/screenshot (2).png | Bin 0 -> 2159 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 apps/8ball/screenshot (1).png create mode 100644 apps/8ball/screenshot (2).png diff --git a/apps/8ball/screenshot (1).png b/apps/8ball/screenshot (1).png new file mode 100644 index 0000000000000000000000000000000000000000..edf1a4695f9c92a40c3dcc7c32cbde94f2c10ce8 GIT binary patch literal 2071 zcmeH|>sQhT7{?K>(Zx#W;zToVQ_fauO%RJR7h0xP3YDRiI;_Yd1TpjS>!w!Xsm(Pb zR%e}MM-aS}qTr-rTACQGpMpu6Mv@9hDVGeG`yckQ7tiy3^?ma_-_P@uCnew)!#rUS z2xM_wY|Nf{t^aS_T;{i+Fy(K?A_QO&qt=+EK zsl;F-T}Hm&VvPN3BI?g0r(Gx;e3R~dvKfuW$=+iB>1_+dd!hEvv-(1V&9?h3Zuud% zZ`VHoUoCZTUIH{<^1UNjMBKa0366Fe^t>eTf#NnZ3$1fgTX|<<*;aA)Ced@bndM%N zvY-Y|bhm5cvp_0=}PZA%1R632zE~3v`-_+P_S^bxB zs?cJA1XY4{T#am^l?G4SYp%o1!nFkVJk-L+)G9&qH^}l9C-1l_;cG&Wj^eBviqA|B z*iK&9(5T7HM0-#=Cnx%+nU1;d)s^EFa&P8}1BL##wR!w_h0;c$pA?6&u+Bw8xHQg# zW8MrSh<_x?7UvznBjm|v9+Az=xAJO1;Na~>B^s9%jUFB@D(H@$weW! zE^?d}4*1nKe#bOw5N2igbhK3(fuB(auis^MRSPJNY3fF}IpwEO=T7P@s)2m)929rH zjnlF$Y2pfg}-5Z8-oSm;;;}Xu)!GfXiyn3#e0W zGn|dEsQm!9*FM(A%@BDsv-64eF*H8IVz%h!9;GW$8FehJIPXQTMtqo%MIWz@)Xil5 zK7lOj+Db1<-`rLP4v*&roD^QC|h+g@Wg2Q~) zqoBlABA+|xSlJoJs_D6j&iSw|tjzj?1y`8>tmMA!Sc;Ffu5zr-c)y8lj2~GdLIff^ z--W`WEFIZzTA_V`^`Z(*Y(&ATI&XhLT2L@KC>1yi=oJSz+TEgcqXJ$ns*B<8SGigT z5RE&Dt}W0>%0nT|{p=SruBd`xG!!$Yu7WZ;M|)mWFaqZDjcr)~LOomQHQ75&DVzo;=^c8Myf}p_PW%2hf@wcENa( z5<+XNv#g*TEV^YQQ`2u(yXG5T{MO!w8;kN)Z-U;aZ#ejfM ny&S%pz6SBN5&s(+KrtlIcR_q;+Xe6WPY;RvF(HN@edyf3g>8t> literal 0 HcmV?d00001 diff --git a/apps/8ball/screenshot (2).png b/apps/8ball/screenshot (2).png new file mode 100644 index 0000000000000000000000000000000000000000..c5c6070896ac96a610ce639c9272b8d667f05624 GIT binary patch literal 2159 zcmeHJYgZBm05yU%R`U_omKFz1E9kLi&U}DoVo0TBDy5*-N_He)I1~kCW~J_wOdHuT ztqj{b65x@PL{MfA^X+mdNFquT6Ga_IKoOn$6Z_PMd+&$)?Vfwjxg}@APi_V81l!oy zYz@PNM6PT7f3VxM&V1p=_;uNk8F@0;hS%r%$;QTRe^|)zC~Ev{wJuhPfdI#?&`N97 z>*vpVrvAcjNr_ylNZ(_Ms(9*nf7B!t3Yk7@7&Uscc+SDB(U@pzt2Ij`Vd%B-NXA?M zd#yE_q9Jmq;@}+`jviVgWvJ*{AB;y=pHpaG^xu(c$4W+00w@+iq=53@60QOkv@q}r zX6{ilVC)`Oib$(oTjHi_ha&gQzsi?T&>SAw|BJ7XIM!^m{uW!O?`>na7Q3cZ$heE< zLjl1q8{~dGiYn8rP%h`3>1Z2E&}8Yc6iXzB z{ZlB-u4fB}l3R|nc>8vTr`~jiG&C7pKCPOPt0l7$B&&c_qhxWoZ+dbc{)v`3FD+}c zVKJ#(2~s87_`X@{==-ic*UKO1spyoElXgX^%WhvWdVo-Yc2Q599Av(^xKf2O^;Ee4 zueBAbNOzJLMwB@@!U8Ash)b9qE9-fgCq9*kMUAcC7kr5MonTSK2IYeC_Za63Z}ayV zljF`wj%N{W;)WGUT?|c)MZpcSoKU^fX2O8CX|ffs<|yHg)S}m3ZyI;gW6$DRC75op zsGMn6H2@+Q>ZR@xee3~vy3B+iK2paC4P_Lk5`NP;e-)j(<;vENbp#2FGaS##m^2@J zbn|}BC1#oQO8{70_(W^|4gg+BnaUgA1%yy-(ftc4K!{m6U}^WaqvuzVJMLObgJiz3 zV+&JxJ8CJsG6lRl!jij~Hyx4%UKu=qzrX|>ma>a-LBG|$)k3IMihJ&%sVVM)xOT}v z7`$Lx#Xsb@Vp$#+VDhHt6rAkhCNUEjLoixQ>-piz0A*ky zi9EFUtHZQAng=;I=J=Y@Hr59}YD^EOUMuwyM5$GzULFbf4Pl34Aul_N(CVILjrZbJ$@HDf<{``W%S|hWc>c(6 z^aBgl0mNG)z5LPTxL=@gVT%#TfZLAH@Rg(A^~D&dikTB!ScMkcDk zcA6C!iERY^Fp46YbWuatUsVUKaNSZ(UF`7bThlG41^rNVI9;)QV&#xzB#w*qb@R^~ z`JFbXA>BpNS*#fjaVW^xgwt|?sQ70|@?O`#F4`1~*Qf|A3h4hOh|^%gKCyRm*X@+R znRYL}rM+p+_THN&p4NM}r(TIe`&x1mvB`rUx@O7eZ$K$KL8}vf&eX%{AXT>@-~phb z_|_%})oysX9>DjaQ{Sl;+7u%$or18Rw#|ckF8Y3r2`bol>WI_c$I>d+-2x!wSUto& l1Mu1UoW|#F{J(Qp-FSiqi918|(XKxTn=o{E2roGC`oBR3t?mE- literal 0 HcmV?d00001 From 3af47e000eff936d8074fa05c10781620304f48e Mon Sep 17 00:00:00 2001 From: only-meeps <151784194+only-meeps@users.noreply.github.com> Date: Tue, 9 Jul 2024 14:37:15 -0700 Subject: [PATCH 024/110] Rename screenshot (1).png to screenshot-1.png --- apps/8ball/{screenshot (1).png => screenshot-1.png} | Bin 1 file changed, 0 insertions(+), 0 deletions(-) rename apps/8ball/{screenshot (1).png => screenshot-1.png} (100%) diff --git a/apps/8ball/screenshot (1).png b/apps/8ball/screenshot-1.png similarity index 100% rename from apps/8ball/screenshot (1).png rename to apps/8ball/screenshot-1.png From afb2a522419f9fe99d9789046adca3125982ae8a Mon Sep 17 00:00:00 2001 From: only-meeps <151784194+only-meeps@users.noreply.github.com> Date: Tue, 9 Jul 2024 14:37:32 -0700 Subject: [PATCH 025/110] Rename screenshot (2).png to screenshot-2.png --- apps/8ball/{screenshot (2).png => screenshot-2.png} | Bin 1 file changed, 0 insertions(+), 0 deletions(-) rename apps/8ball/{screenshot (2).png => screenshot-2.png} (100%) diff --git a/apps/8ball/screenshot (2).png b/apps/8ball/screenshot-2.png similarity index 100% rename from apps/8ball/screenshot (2).png rename to apps/8ball/screenshot-2.png From 6676acc37fe55276f41e36c16c845c10a2db74c0 Mon Sep 17 00:00:00 2001 From: only-meeps <151784194+only-meeps@users.noreply.github.com> Date: Tue, 9 Jul 2024 14:38:35 -0700 Subject: [PATCH 026/110] Update metadata.json --- apps/8ball/metadata.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/apps/8ball/metadata.json b/apps/8ball/metadata.json index 029deebbb..2cdb11002 100644 --- a/apps/8ball/metadata.json +++ b/apps/8ball/metadata.json @@ -3,6 +3,11 @@ "shortName":"8ball", "icon": "8ball.png", "version":"0.01", + "screenshots": [ + {"url":"screenshot.png"}, + {"url":"screenshot-1.png"}, + {"url":"screenshot-2.png"} + ], "description": "It tells your future!", "tags": "game", "supports": ["BANGLEJS2"], From 408dbf76b1593e5f965b8d715285890843d844bd Mon Sep 17 00:00:00 2001 From: only-meeps <151784194+only-meeps@users.noreply.github.com> Date: Tue, 9 Jul 2024 14:41:13 -0700 Subject: [PATCH 027/110] Update metadata.json --- apps/8ball/metadata.json | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/8ball/metadata.json b/apps/8ball/metadata.json index 2cdb11002..6944bfa2a 100644 --- a/apps/8ball/metadata.json +++ b/apps/8ball/metadata.json @@ -8,6 +8,7 @@ {"url":"screenshot-1.png"}, {"url":"screenshot-2.png"} ], + "allow_emulator": true, "description": "It tells your future!", "tags": "game", "supports": ["BANGLEJS2"], From 1b714a03503473ff72160197d570ac517ccc5610 Mon Sep 17 00:00:00 2001 From: only-meeps <151784194+only-meeps@users.noreply.github.com> Date: Tue, 9 Jul 2024 14:46:18 -0700 Subject: [PATCH 028/110] Create ChangeLog --- apps/8ball/ChangeLog | 1 + 1 file changed, 1 insertion(+) create mode 100644 apps/8ball/ChangeLog diff --git a/apps/8ball/ChangeLog b/apps/8ball/ChangeLog new file mode 100644 index 000000000..3bcffb19b --- /dev/null +++ b/apps/8ball/ChangeLog @@ -0,0 +1 @@ +0.01: New App! From 39aeb9f55ae7fff5fd31dcde40f5086d97154b5a Mon Sep 17 00:00:00 2001 From: only-meeps <151784194+only-meeps@users.noreply.github.com> Date: Tue, 9 Jul 2024 14:55:19 -0700 Subject: [PATCH 029/110] Update metadata.json --- apps/8ball/metadata.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/8ball/metadata.json b/apps/8ball/metadata.json index 6944bfa2a..b36cd5afb 100644 --- a/apps/8ball/metadata.json +++ b/apps/8ball/metadata.json @@ -16,4 +16,7 @@ {"name":"8ball.app.js","url":"app.js"}, {"name":"8ball.img","url":"app-icon.js","evaluate":true} ] + "data": [ + {"name":"8ballAnswers.json","url":"8ballAnswers.json"} + ] } From 9c391a9afd79c0f8fa42c5347b9ee0cfe80f31ac Mon Sep 17 00:00:00 2001 From: only-meeps <151784194+only-meeps@users.noreply.github.com> Date: Wed, 10 Jul 2024 06:05:55 -0700 Subject: [PATCH 030/110] Update metadata.json --- apps/8ball/metadata.json | 4 ---- 1 file changed, 4 deletions(-) diff --git a/apps/8ball/metadata.json b/apps/8ball/metadata.json index b36cd5afb..71a05e014 100644 --- a/apps/8ball/metadata.json +++ b/apps/8ball/metadata.json @@ -15,8 +15,4 @@ "storage": [ {"name":"8ball.app.js","url":"app.js"}, {"name":"8ball.img","url":"app-icon.js","evaluate":true} - ] - "data": [ - {"name":"8ballAnswers.json","url":"8ballAnswers.json"} - ] } From 32060fb8f6183c678629fd0a78914f97aa1bd1dd Mon Sep 17 00:00:00 2001 From: only-meeps <151784194+only-meeps@users.noreply.github.com> Date: Wed, 10 Jul 2024 06:06:21 -0700 Subject: [PATCH 031/110] Update metadata.json --- apps/8ball/metadata.json | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/8ball/metadata.json b/apps/8ball/metadata.json index 71a05e014..6944bfa2a 100644 --- a/apps/8ball/metadata.json +++ b/apps/8ball/metadata.json @@ -15,4 +15,5 @@ "storage": [ {"name":"8ball.app.js","url":"app.js"}, {"name":"8ball.img","url":"app-icon.js","evaluate":true} + ] } From 898f997ecc8c9f22901a8b572322102cc04341bf Mon Sep 17 00:00:00 2001 From: only-meeps <151784194+only-meeps@users.noreply.github.com> Date: Wed, 10 Jul 2024 06:16:58 -0700 Subject: [PATCH 032/110] Update metadata.json --- apps/boxclk/metadata.json | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/boxclk/metadata.json b/apps/boxclk/metadata.json index dd81ac436..79b4c3019 100644 --- a/apps/boxclk/metadata.json +++ b/apps/boxclk/metadata.json @@ -4,6 +4,7 @@ "version": "0.05", "description": "A customizable clock with configurable text boxes that can be positioned to show your favorite background", "icon": "app.png", + "dependencies" : { "clockbg":"module" }, "screenshots": [ {"url":"screenshot.png"}, {"url":"screenshot-1.png"}, From 9956c09339c3b41b47f2820b4d15fd6d458d5f3a Mon Sep 17 00:00:00 2001 From: only-meeps <151784194+only-meeps@users.noreply.github.com> Date: Fri, 12 Jul 2024 06:56:19 -0700 Subject: [PATCH 033/110] Update app.js --- apps/8ball/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/8ball/app.js b/apps/8ball/app.js index 86096434d..581e3e7bc 100644 --- a/apps/8ball/app.js +++ b/apps/8ball/app.js @@ -3,7 +3,7 @@ var Name = ""; var WaitTime = 0; Bangle.setLCDTimeout(0); -var answers = new Array("no", "yes","WHAT????","What do you think", "That was a bad question", "YES!!!", "NOOOOO!!", "nope","100%","yup","why should I answer that?","think for yourself","ask again later, I'm busy", "what Was that horrible question","how dare you?","you wanted to hear yes? okay, yes", "Don't get angry when I say no","you are 100% wrong","totally, for sure","hmmm... I'll ponder it and get back to you later","I just asked the presedent and they say yes","wow, you really have a lot of questions", "NOPE","is the sky blue, hmmm...","I don't have time to answer","How many more questions before you change my name?","theres this thing called wikipedia","hmm... I don't seem to be able to reach the internet right now","if you phrase it like that, yes","Huh, never thought so hard in my life","The winds of time say no"); +var answers = new Array("no", "yes","WHAT????","What do you think", "That was a bad question", "YES!!!", "NOOOOO!!", "nope","100%","yup","why should I answer that?","think for yourself","ask again later, I'm busy", "what Was that horrible question","how dare you?","you wanted to hear yes? okay, yes", "Don't get angry when I say no","you are 100% wrong","totally, for sure","hmmm... I'll ponder it and get back to you later","wow, you really have a lot of questions", "NOPE","is the sky blue, hmmm...","I don't have time to answer","How many more questions before you change my name?","theres this thing called wikipedia","hmm... I don't seem to be able to reach the internet right now","if you phrase it like that, yes","Huh, never thought so hard in my life","The winds of time say no", "uh... can you ask that again? I kinda forgot", "I know I'm a computer, but even I can get bored"); var consonants = new Array("b","c","d","f","g","h","j","k","l","m","n","p","q","r","s","t","v","w","x","y","z"); var vowels = new Array("a","e","i","o","u"); try {keyboard = require(keyboard);} catch(e) {keyboard = null;} From 540c68f2c500dc5cd793cab6789ff73f10328952 Mon Sep 17 00:00:00 2001 From: only-meeps <151784194+only-meeps@users.noreply.github.com> Date: Fri, 12 Jul 2024 06:56:58 -0700 Subject: [PATCH 034/110] Update metadata.json --- apps/8ball/metadata.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/8ball/metadata.json b/apps/8ball/metadata.json index 6944bfa2a..da387d3d6 100644 --- a/apps/8ball/metadata.json +++ b/apps/8ball/metadata.json @@ -9,7 +9,7 @@ {"url":"screenshot-2.png"} ], "allow_emulator": true, - "description": "It tells your future!", + "description": "A very sarcastic magic 8ball", "tags": "game", "supports": ["BANGLEJS2"], "storage": [ From f38f183b1e02853237807423439cc39ec17892ff Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Wed, 19 Jun 2024 00:25:24 +0200 Subject: [PATCH 035/110] [] skyspy: start libgps --- apps/skyspy/skyspy.app.js | 53 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/apps/skyspy/skyspy.app.js b/apps/skyspy/skyspy.app.js index ff6e29712..3278c9710 100644 --- a/apps/skyspy/skyspy.app.js +++ b/apps/skyspy/skyspy.app.js @@ -3,6 +3,44 @@ 1 .. DD MM.mmm' 2 .. DD MM'ss" */ + +let libgps = { + state: {}, + on_gps: function(f) { + let fix = this.getGPSFix(); + f(fix); + + /* + "lat": number, // Latitude in degrees + "lon": number, // Longitude in degrees + "alt": number, // altitude in M + "speed": number, // Speed in kph + "course": number, // Course in degrees + "time": Date, // Current Time (or undefined if not known) + "satellites": 7, // Number of satellites + "fix": 1 // NMEA Fix state - 0 is no fix + "hdop": number, // Horizontal Dilution of Precision + */ + this.state.timeout = setTimeout(this.on_gps, 1000, f); + }, + off_gps: function() { + clearTimeout(gps_state.timeout); + }, + getGPSFix: function() { + let fix = {}; + fix.fix = 1; + fix.lat = 50; + fix.lon = 14; + fix.alt = 200; + fix.speed = 5; + fix.course = 30; + fix.time = Date(); + fix.satellites = 5; + fix.hdop = 12; + return fix; + } +}; + var mode = 1; var display = 0; @@ -69,7 +107,8 @@ function updateGps() { if (cancel_gps) return; - fix = Bangle.getGPSFix(); + //fix = Bangle.getGPSFix(); + fix = libgps.getGPSFix(); try { Bangle.getPressure().then((x) => { @@ -81,6 +120,7 @@ function updateGps() { speed = getTime() - gps_start; + print(fix); if (fix && fix.fix && fix.lat) { lat = "" + format(fix.lat); lon = "" + format(fix.lon); @@ -244,10 +284,20 @@ function markGps() { updateGps(); } +function drawBusy() { + g.reset().setFont("Vector", 20) + .setColor(1,1,1) + .fillRect(0, wi, 176, 176) + .setColor(0,0,0) + .drawString(".oO busy", 0, 30); + +} + function onSwipe(dir) { display = display + 1; if (display == 3) display = 0; + drawBusy(); } Bangle.setUI({ @@ -257,4 +307,5 @@ Bangle.setUI({ }); Bangle.loadWidgets(); Bangle.drawWidgets(); +drawBusy(); markGps(); From 4bf47626ffa024f59adf0755a92f0be25439074d Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Wed, 19 Jun 2024 23:31:36 +0200 Subject: [PATCH 036/110] [] skyspy: move lat/lon formatting to library. --- apps/skyspy/skyspy.app.js | 57 ++++++++++++++++++++------------------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/apps/skyspy/skyspy.app.js b/apps/skyspy/skyspy.app.js index 3278c9710..181d0ea51 100644 --- a/apps/skyspy/skyspy.app.js +++ b/apps/skyspy/skyspy.app.js @@ -1,11 +1,34 @@ /* Sky spy */ -/* 0 .. DD.ddddd - 1 .. DD MM.mmm' - 2 .. DD MM'ss" -*/ let libgps = { state: {}, + /* 0 .. DD.ddddd + 1 .. DD MM.mmm' + 2 .. DD MM'ss" + */ + mode: 1, + format: function(x) { + switch (this.mode) { + case 0: + return "" + x; + case 1: { + let d = Math.floor(x); + let m = x - d; + m = m*60; + return "" + d + " " + m.toFixed(3) + "'"; + } + case 2: { + let d = Math.floor(x); + let m = x - d; + m = m*60; + let mf = Math.floor(m); + let s = m - mf; + s = s*60; + return "" + d + " " + mf + "'" + s.toFixed(0) + '"'; + } + } + return "bad mode?"; + }, on_gps: function(f) { let fix = this.getGPSFix(); f(fix); @@ -27,6 +50,7 @@ let libgps = { clearTimeout(gps_state.timeout); }, getGPSFix: function() { + if (0) Bangle.getGPSFix(); let fix = {}; fix.fix = 1; fix.lat = 50; @@ -41,7 +65,6 @@ let libgps = { } }; -var mode = 1; var display = 0; var debug = 0; @@ -65,25 +88,6 @@ function radY(p, d) { return h/2 - Math.cos(a)*radD(d) + wi; } -function format(x) { - switch (mode) { - case 0: - return "" + x; - case 1: - d = Math.floor(x); - m = x - d; - m = m*60; - return "" + d + " " + m.toFixed(3) + "'"; - case 2: - d = Math.floor(x); - m = x - d; - m = m*60; - mf = Math.floor(m); - s = m - mf; - s = s*60; - return "" + d + " " + mf + "'" + s.toFixed(0) + '"'; - } -} var qalt = -1; function resetAlt() { min_dalt = 9999; max_dalt = -9999; step = 0; @@ -107,7 +111,6 @@ function updateGps() { if (cancel_gps) return; - //fix = Bangle.getGPSFix(); fix = libgps.getGPSFix(); try { @@ -122,8 +125,8 @@ function updateGps() { print(fix); if (fix && fix.fix && fix.lat) { - lat = "" + format(fix.lat); - lon = "" + format(fix.lon); + lat = "" + libgps.format(fix.lat); + lon = "" + libgps.format(fix.lon); alt = "" + fix.alt.toFixed(1); speed = "" + fix.speed.toFixed(1); hdop = "" + fix.hdop.toFixed(1); From ff46f86b2d72cdd73cba73302bafdee69cf7a00b Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Wed, 19 Jun 2024 23:51:41 +0200 Subject: [PATCH 037/110] [] skyspy: Implement time adjustment (untested). --- apps/skyspy/skyspy.app.js | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/apps/skyspy/skyspy.app.js b/apps/skyspy/skyspy.app.js index 181d0ea51..14e24ac1d 100644 --- a/apps/skyspy/skyspy.app.js +++ b/apps/skyspy/skyspy.app.js @@ -77,6 +77,8 @@ var h = 176-wi, w = 176; var fix; +var adj_time = 0; + function radA(p) { return p*(Math.PI*2); } function radD(d) { return d*(h/2); } function radX(p, d) { @@ -112,6 +114,11 @@ function updateGps() { if (cancel_gps) return; fix = libgps.getGPSFix(); + if (adj_time) { + print("Adjusting time"); + setTime(fix.time.getTime()/1000); + adj_time = 0; + } try { Bangle.getPressure().then((x) => { @@ -293,21 +300,39 @@ function drawBusy() { .fillRect(0, wi, 176, 176) .setColor(0,0,0) .drawString(".oO busy", 0, 30); +} + +function nextScreen() { + display = display + 1; + if (display == 3) + display = 0; + drawBusy(); } function onSwipe(dir) { - display = display + 1; - if (display == 3) - display = 0; - drawBusy(); + nextScreen(); } +function touchHandler(d) { + let x = Math.floor(d.x); + let y = Math.floor(d.y); + + if ((xh/2) && (y>w/2)) + nextScreen(); +} + + +Bangle.on("drag", touchHandler); Bangle.setUI({ mode : "custom", swipe : onSwipe, clock : 0 }); + Bangle.loadWidgets(); Bangle.drawWidgets(); drawBusy(); From 78a910544b2d0215ff180ac2a6da396b83826df4 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Thu, 20 Jun 2024 00:04:00 +0200 Subject: [PATCH 038/110] [] skyspy: only use fake data on emulator. --- apps/skyspy/skyspy.app.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/apps/skyspy/skyspy.app.js b/apps/skyspy/skyspy.app.js index 14e24ac1d..db7736ba0 100644 --- a/apps/skyspy/skyspy.app.js +++ b/apps/skyspy/skyspy.app.js @@ -1,6 +1,11 @@ -/* Sky spy */ + /* Sky spy */ let libgps = { + emulator: -1, + init: function(x) { + this.emulator = (process.env.BOARD=="EMSCRIPTEN" + || process.env.BOARD=="EMSCRIPTEN2")?1:0; + }, state: {}, /* 0 .. DD.ddddd 1 .. DD MM.mmm' @@ -50,7 +55,8 @@ let libgps = { clearTimeout(gps_state.timeout); }, getGPSFix: function() { - if (0) Bangle.getGPSFix(); + if (!this.emulator) + return Bangle.getGPSFix(); let fix = {}; fix.fix = 1; fix.lat = 50; @@ -130,7 +136,7 @@ function updateGps() { speed = getTime() - gps_start; - print(fix); + //print(fix); if (fix && fix.fix && fix.lat) { lat = "" + libgps.format(fix.lat); lon = "" + libgps.format(fix.lon); @@ -325,6 +331,7 @@ function touchHandler(d) { nextScreen(); } +libgps.init(); Bangle.on("drag", touchHandler); Bangle.setUI({ From ab0b4cbb45bd3a8c2d7bd18d7fb6e56516652449 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Thu, 20 Jun 2024 22:05:28 +0200 Subject: [PATCH 039/110] [] skyspy: display time error. --- apps/skyspy/skyspy.app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/skyspy/skyspy.app.js b/apps/skyspy/skyspy.app.js index db7736ba0..5dec5f148 100644 --- a/apps/skyspy/skyspy.app.js +++ b/apps/skyspy/skyspy.app.js @@ -152,7 +152,7 @@ function updateGps() { .setColor(1,1,1) .fillRect(0, wi, 176, 176) .setColor(0,0,0) - .drawString("Acquiring GPS", 0, 30) + .drawString("terr "+(getTime()-fix.time.getTime()/1000), 0, 30) .drawString(lat, 0, 50) .drawString(lon, 0, 70) .drawString("alt "+alt, 0, 90) From a64efa4d1fc0205a072dd10f10d7add23ddab8fc Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Thu, 20 Jun 2024 22:11:05 +0200 Subject: [PATCH 040/110] [] skyspy: fix button handling. --- apps/skyspy/skyspy.app.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/apps/skyspy/skyspy.app.js b/apps/skyspy/skyspy.app.js index 5dec5f148..fd651a6fc 100644 --- a/apps/skyspy/skyspy.app.js +++ b/apps/skyspy/skyspy.app.js @@ -320,9 +320,16 @@ function onSwipe(dir) { nextScreen(); } +var last_b = 0; function touchHandler(d) { let x = Math.floor(d.x); let y = Math.floor(d.y); + + if (d.b != 1 || last_b != 0) { + last_b = d.b; + return; + } + last_b = d.b; if ((x Date: Thu, 20 Jun 2024 22:36:06 +0200 Subject: [PATCH 041/110] [] skyspy: switch to bigger font. --- apps/skyspy/skyspy.app.js | 57 +++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 32 deletions(-) diff --git a/apps/skyspy/skyspy.app.js b/apps/skyspy/skyspy.app.js index fd651a6fc..24337c3c8 100644 --- a/apps/skyspy/skyspy.app.js +++ b/apps/skyspy/skyspy.app.js @@ -72,12 +72,9 @@ let libgps = { }; var display = 0; - var debug = 0; - var cancel_gps, gps_start; var cur_altitude; - var wi = 24; var h = 176-wi, w = 176; @@ -123,6 +120,7 @@ function updateGps() { if (adj_time) { print("Adjusting time"); setTime(fix.time.getTime()/1000); + drawMsg("Time\nadjusted"); adj_time = 0; } @@ -147,38 +145,31 @@ function updateGps() { } let ddalt = calcAlt(alt, cur_altitude); - if (display == 1) - g.reset().setFont("Vector", 20) - .setColor(1,1,1) - .fillRect(0, wi, 176, 176) - .setColor(0,0,0) - .drawString("terr "+(getTime()-fix.time.getTime()/1000), 0, 30) - .drawString(lat, 0, 50) - .drawString(lon, 0, 70) - .drawString("alt "+alt, 0, 90) - .drawString("speed "+speed, 0, 110) - .drawString("hdop "+hdop, 0, 130) - .drawString("balt" + cur_altitude, 0, 150); - + let msg = ""; + if (display == 1) { + msg = lat + "\n" + lon + "\n" + alt + "m" + speed + "km/h\n" + + "hdop "+hdop + "m\nbalt" + cur_altitude + "m"; + } if (display == 2) { - g.reset().setFont("Vector", 20) - .setColor(1,1,1) - .fillRect(0, wi, 176, 176) - .setColor(0,0,0) - .drawString("GPS status", 0, 30) - .drawString("speed "+speed, 0, 50) - .drawString("hdop "+hdop, 0, 70) - .drawString("dd "+qalt.toFixed(0) + " (" + ddalt.toFixed(0) + ")", 0, 90) - .drawString("alt "+alt, 0, 110) - .drawString("balt " + cur_altitude, 0, 130) - .drawString(step, 0, 150); + msg = speed + "km/h\n" + + "hdop "+hdop + + "\ndd "+qalt.toFixed(0) + " (" + ddalt.toFixed(0) + ")" + + "\nalt "+alt + + "\nbalt "+cur_altitude + + "/" + step; step++; if (step == 10) { qalt = max_dalt - min_dalt; resetAlt(); } } - + if (display > 0) { + g.reset().setFont("Vector", 31) + .setColor(1,1,1) + .fillRect(0, wi, 176, 176) + .setColor(0,0,0) + .drawString(msg, 3, 25) + } if (debug > 0) print(fix); setTimeout(updateGps, 1000); @@ -299,13 +290,15 @@ function markGps() { gps_start = getTime(); updateGps(); } - -function drawBusy() { - g.reset().setFont("Vector", 20) +function drawMsg(msg) { + g.reset().setFont("Vector", 35) .setColor(1,1,1) .fillRect(0, wi, 176, 176) .setColor(0,0,0) - .drawString(".oO busy", 0, 30); + .drawString(msg, 5, 30); +} +function drawBusy() { + drawMsg("\n.oO busy"); } function nextScreen() { From eebc99fa6c4d637c161493925f0e38a5d178b6e9 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Thu, 20 Jun 2024 23:05:46 +0200 Subject: [PATCH 042/110] [] skyspy: fit data into 5 lines. --- apps/skyspy/skyspy.app.js | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/apps/skyspy/skyspy.app.js b/apps/skyspy/skyspy.app.js index 24337c3c8..17824eae6 100644 --- a/apps/skyspy/skyspy.app.js +++ b/apps/skyspy/skyspy.app.js @@ -71,7 +71,7 @@ let libgps = { } }; -var display = 0; +var display = 1; var debug = 0; var cancel_gps, gps_start; var cur_altitude; @@ -111,8 +111,9 @@ function calcAlt(alt, cur_altitude) { return ddalt; } function updateGps() { - let /*have = false,*/ lat = "lat", lon = "lon", alt = "alt", - speed = "speed", hdop = "hdop"; // balt = "balt"; + let have = false, lat = "lat ", lon = "lon ", alt = "alt ", + speed = "speed ", hdop = "hdop ", adelta = "adelta ", + tdelta = "tdelta "; if (cancel_gps) return; @@ -129,7 +130,7 @@ function updateGps() { cur_altitude = x.altitude; }, print); } catch (e) { - print("Altimeter error", e); + //print("Altimeter error", e); } speed = getTime() - gps_start; @@ -138,17 +139,20 @@ function updateGps() { if (fix && fix.fix && fix.lat) { lat = "" + libgps.format(fix.lat); lon = "" + libgps.format(fix.lon); - alt = "" + fix.alt.toFixed(1); + alt = "" + fix.alt.toFixed(0); + adelta = "" + (cur_altitude - fix.alt).toFixed(0); + tdelta = "" + (getTime() - fix.time.getTime()/1000).toFixed(0); speed = "" + fix.speed.toFixed(1); - hdop = "" + fix.hdop.toFixed(1); - //have = true; + hdop = "" + fix.hdop.toFixed(0); + have = true; } let ddalt = calcAlt(alt, cur_altitude); let msg = ""; if (display == 1) { - msg = lat + "\n" + lon + "\n" + alt + "m" + speed + "km/h\n" - + "hdop "+hdop + "m\nbalt" + cur_altitude + "m"; + msg = lat + "\n" + lon + + "\ne" + hdop + "m "+tdelta+"s\n" + + speed + "km/h\n"+ alt + "m+" + adelta + "\nmsghere"; } if (display == 2) { msg = speed + "km/h\n" + @@ -168,7 +172,7 @@ function updateGps() { .setColor(1,1,1) .fillRect(0, wi, 176, 176) .setColor(0,0,0) - .drawString(msg, 3, 25) + .drawString(msg, 3, 25); } if (debug > 0) print(fix); From 7ec2dbb17bc955288843261d3e8469642b60500a Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Thu, 20 Jun 2024 23:13:05 +0200 Subject: [PATCH 043/110] [] skyspy: Provide some info with no fix. --- apps/skyspy/skyspy.app.js | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/apps/skyspy/skyspy.app.js b/apps/skyspy/skyspy.app.js index 17824eae6..5d0a2fdb8 100644 --- a/apps/skyspy/skyspy.app.js +++ b/apps/skyspy/skyspy.app.js @@ -111,8 +111,8 @@ function calcAlt(alt, cur_altitude) { return ddalt; } function updateGps() { - let have = false, lat = "lat ", lon = "lon ", alt = "alt ", - speed = "speed ", hdop = "hdop ", adelta = "adelta ", + let have = false, lat = "lat ", lon = "lon ", alt = "?", + speed = "speed ", hdop = "?", adelta = "adelta ", tdelta = "tdelta "; if (cancel_gps) @@ -133,18 +133,24 @@ function updateGps() { //print("Altimeter error", e); } - speed = getTime() - gps_start; //print(fix); + if (fix && fix.time) { + tdelta = "" + (getTime() - fix.time.getTime()/1000).toFixed(0); + } if (fix && fix.fix && fix.lat) { lat = "" + libgps.format(fix.lat); lon = "" + libgps.format(fix.lon); alt = "" + fix.alt.toFixed(0); adelta = "" + (cur_altitude - fix.alt).toFixed(0); - tdelta = "" + (getTime() - fix.time.getTime()/1000).toFixed(0); speed = "" + fix.speed.toFixed(1); hdop = "" + fix.hdop.toFixed(0); have = true; + } else { + lat = "NO FIX"; + lon = "" + (getTime() - gps_start).toFixed(0) + "s"; + if (cur_altitude) + adelta = "" + cur_altitude.toFixed(0); } let ddalt = calcAlt(alt, cur_altitude); From 2dc4537dc04d41d8b5082b24b740bb0ea15855ce Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Thu, 20 Jun 2024 23:45:01 +0200 Subject: [PATCH 044/110] [] skyspy: show sats used/total when no signal --- apps/skyspy/skyspy.app.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/apps/skyspy/skyspy.app.js b/apps/skyspy/skyspy.app.js index 5d0a2fdb8..857da2410 100644 --- a/apps/skyspy/skyspy.app.js +++ b/apps/skyspy/skyspy.app.js @@ -71,15 +71,13 @@ let libgps = { } }; -var display = 1; +var display = 0; var debug = 0; var cancel_gps, gps_start; var cur_altitude; var wi = 24; var h = 176-wi, w = 176; - var fix; - var adj_time = 0; function radA(p) { return p*(Math.PI*2); } @@ -147,8 +145,9 @@ function updateGps() { hdop = "" + fix.hdop.toFixed(0); have = true; } else { - lat = "NO FIX"; - lon = "" + (getTime() - gps_start).toFixed(0) + "s"; + lat = "NO FIX "; + lon = "" + (getTime() - gps_start).toFixed(0) + "s " + + sats_used + "/" + snum; if (cur_altitude) adelta = "" + cur_altitude.toFixed(0); } @@ -241,7 +240,7 @@ function drawSats(sats) { var sats = []; var snum = 0; -//var sats_receiving = 0; +var sats_used = 0; function parseRaw(msg, lost) { if (lost) @@ -256,6 +255,7 @@ function parseRaw(msg, lost) { if (s[2] == "1") { snum = 0; sats = []; + sats_used = 0; } let view = 1 * s[3]; @@ -274,6 +274,8 @@ function parseRaw(msg, lost) { sat.ele = 1*s[i++]; sat.azi = 1*s[i++]; sat.snr = s[i++]; + if (sat.snr != "") + sats_used++; if (debug > 0) print(" ", sat); sats[snum++] = sat; From 2e60c8b5ecf28c060a1252cc6a91eed2678cddde Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Fri, 21 Jun 2024 00:04:13 +0200 Subject: [PATCH 045/110] [] skyspy: better summary for 3rd screen, too. --- apps/skyspy/skyspy.app.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/apps/skyspy/skyspy.app.js b/apps/skyspy/skyspy.app.js index 857da2410..c9e22d580 100644 --- a/apps/skyspy/skyspy.app.js +++ b/apps/skyspy/skyspy.app.js @@ -161,11 +161,9 @@ function updateGps() { } if (display == 2) { msg = speed + "km/h\n" + - "hdop "+hdop + - "\ndd "+qalt.toFixed(0) + " (" + ddalt.toFixed(0) + ")" + - "\nalt "+alt + - "\nbalt "+cur_altitude + - "/" + step; + "e"+hdop + "m/"+step + +"\ndd "+qalt.toFixed(0) + "\n(" + ddalt.toFixed(0) + ")" + + "\n"+alt + "m+" + adelta; step++; if (step == 10) { qalt = max_dalt - min_dalt; From 22d6bdbcc6e46e9647064b736d2c0ad6afc356e5 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Fri, 21 Jun 2024 00:18:55 +0200 Subject: [PATCH 046/110] [] skyspy: better debug output, add documentation --- apps/skyspy/skyspy.app.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/apps/skyspy/skyspy.app.js b/apps/skyspy/skyspy.app.js index c9e22d580..2b0965148 100644 --- a/apps/skyspy/skyspy.app.js +++ b/apps/skyspy/skyspy.app.js @@ -160,9 +160,17 @@ function updateGps() { speed + "km/h\n"+ alt + "m+" + adelta + "\nmsghere"; } if (display == 2) { + /* FIXME: ddalt/qalt should be updated in all modes */ + /* qalt is altitude quality estimate -- over ten seconds, + computes differences between GPS and barometric altitude. + The lower the better. + + ddalt is just a debugging -- same estimate, but without + waiting 10 seconds, so will be always optimistic at start + of the cycle */ msg = speed + "km/h\n" + - "e"+hdop + "m/"+step - +"\ndd "+qalt.toFixed(0) + "\n(" + ddalt.toFixed(0) + ")" + + "e"+hdop + "m" + +"\ndd "+qalt.toFixed(0) + "\n(" + step + "/" + ddalt.toFixed(0) + ")" + "\n"+alt + "m+" + adelta; step++; if (step == 10) { From 6eaad6f13a5e9b65aae151f7dbf01d7a70ff79e2 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Fri, 21 Jun 2024 09:56:52 +0200 Subject: [PATCH 047/110] [] skyspy: Compute altitude quality all the time, fix "clock adjust" message --- apps/skyspy/skyspy.app.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/skyspy/skyspy.app.js b/apps/skyspy/skyspy.app.js index 2b0965148..964e66f6a 100644 --- a/apps/skyspy/skyspy.app.js +++ b/apps/skyspy/skyspy.app.js @@ -119,7 +119,6 @@ function updateGps() { if (adj_time) { print("Adjusting time"); setTime(fix.time.getTime()/1000); - drawMsg("Time\nadjusted"); adj_time = 0; } @@ -160,7 +159,6 @@ function updateGps() { speed + "km/h\n"+ alt + "m+" + adelta + "\nmsghere"; } if (display == 2) { - /* FIXME: ddalt/qalt should be updated in all modes */ /* qalt is altitude quality estimate -- over ten seconds, computes differences between GPS and barometric altitude. The lower the better. @@ -172,12 +170,12 @@ function updateGps() { "e"+hdop + "m" +"\ndd "+qalt.toFixed(0) + "\n(" + step + "/" + ddalt.toFixed(0) + ")" + "\n"+alt + "m+" + adelta; + } step++; if (step == 10) { qalt = max_dalt - min_dalt; resetAlt(); } - } if (display > 0) { g.reset().setFont("Vector", 31) .setColor(1,1,1) @@ -342,8 +340,10 @@ function touchHandler(d) { } last_b = d.b; - if ((xh/2) && (y>w/2)) nextScreen(); From 1fa0c219e30b1aad8f49b618e1cb5ab8b4e6ed84 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Sat, 22 Jun 2024 23:20:47 +0200 Subject: [PATCH 048/110] [] skyspy: Create formatting library, and use it where suitable. --- apps/skyspy/skyspy.app.js | 169 ++++++++++++++++++++++---------------- 1 file changed, 96 insertions(+), 73 deletions(-) diff --git a/apps/skyspy/skyspy.app.js b/apps/skyspy/skyspy.app.js index 964e66f6a..ae1109fe8 100644 --- a/apps/skyspy/skyspy.app.js +++ b/apps/skyspy/skyspy.app.js @@ -1,74 +1,97 @@ - /* Sky spy */ +/* Sky spy */ + +let fmt = { + icon_alt : "\0\x08\x1a\1\x00\x00\x00\x20\x30\x78\x7C\xFE\xFF\x00\xC3\xE7\xFF\xDB\xC3\xC3\xC3\xC3\x00\x00\x00\x00\x00\x00\x00\x00", + icon_m : "\0\x08\x1a\1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC3\xE7\xFF\xDB\xC3\xC3\xC3\xC3\x00\x00\x00\x00\x00\x00\x00\x00", + icon_km : "\0\x08\x1a\1\xC3\xC6\xCC\xD8\xF0\xD8\xCC\xC6\xC3\x00\xC3\xE7\xFF\xDB\xC3\xC3\xC3\xC3\x00\x00\x00\x00\x00\x00\x00\x00", + icon_kph : "\0\x08\x1a\1\xC3\xC6\xCC\xD8\xF0\xD8\xCC\xC6\xC3\x00\xC3\xE7\xFF\xDB\xC3\xC3\xC3\xC3\x00\xFF\x00\xC3\xC3\xFF\xC3\xC3", + icon_c : "\0\x08\x1a\1\x00\x00\x60\x90\x90\x60\x00\x7F\xFF\xC0\xC0\xC0\xC0\xC0\xFF\x7F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", -let libgps = { - emulator: -1, - init: function(x) { - this.emulator = (process.env.BOARD=="EMSCRIPTEN" - || process.env.BOARD=="EMSCRIPTEN2")?1:0; - }, - state: {}, /* 0 .. DD.ddddd 1 .. DD MM.mmm' 2 .. DD MM'ss" */ - mode: 1, - format: function(x) { - switch (this.mode) { - case 0: - return "" + x; - case 1: { - let d = Math.floor(x); - let m = x - d; - m = m*60; - return "" + d + " " + m.toFixed(3) + "'"; - } - case 2: { - let d = Math.floor(x); - let m = x - d; - m = m*60; - let mf = Math.floor(m); - let s = m - mf; - s = s*60; - return "" + d + " " + mf + "'" + s.toFixed(0) + '"'; - } - } - return "bad mode?"; - }, - on_gps: function(f) { - let fix = this.getGPSFix(); - f(fix); + geo_mode : 1, + + init: function() {}, + fmtDist: function(km) { return km.toFixed(1) + this.icon_km; }, + fmtSteps: function(n) { return fmtDist(0.001 * 0.719 * n); }, + fmtAlt: function(m) { return m.toFixed(0) + this.icon_alt; }, + fmtTimeDiff: function(d) { + if (d < 180) + return ""+d.toFixed(0); + d = d/60; + return ""+d.toFixed(0)+"m"; + }, + fmtAngle: function(x) { + switch (this.geo_mode) { + case 0: + return "" + x; + case 1: { + let d = Math.floor(x); + let m = x - d; + m = m*60; + return "" + d + " " + m.toFixed(3) + "'"; + } + case 2: { + let d = Math.floor(x); + let m = x - d; + m = m*60; + let mf = Math.floor(m); + let s = m - mf; + s = s*60; + return "" + d + " " + mf + "'" + s.toFixed(0) + '"'; + } + } + return "bad mode?"; + }, + fmtPos: function(pos) { + return this.fmtAngle(pos.lat) + "\n" + this.fmtAngle(pos.lon); + }, +}; - /* - "lat": number, // Latitude in degrees - "lon": number, // Longitude in degrees - "alt": number, // altitude in M - "speed": number, // Speed in kph - "course": number, // Course in degrees - "time": Date, // Current Time (or undefined if not known) - "satellites": 7, // Number of satellites - "fix": 1 // NMEA Fix state - 0 is no fix - "hdop": number, // Horizontal Dilution of Precision - */ - this.state.timeout = setTimeout(this.on_gps, 1000, f); - }, - off_gps: function() { - clearTimeout(gps_state.timeout); - }, - getGPSFix: function() { - if (!this.emulator) - return Bangle.getGPSFix(); - let fix = {}; - fix.fix = 1; - fix.lat = 50; - fix.lon = 14; - fix.alt = 200; - fix.speed = 5; - fix.course = 30; - fix.time = Date(); - fix.satellites = 5; - fix.hdop = 12; - return fix; - } +let gps = { + emulator: -1, + init: function(x) { + this.emulator = (process.env.BOARD=="EMSCRIPTEN" + || process.env.BOARD=="EMSCRIPTEN2")?1:0; + }, + state: {}, + on_gps: function(f) { + let fix = this.getGPSFix(); + f(fix); + + /* + "lat": number, // Latitude in degrees + "lon": number, // Longitude in degrees + "alt": number, // altitude in M + "speed": number, // Speed in kph + "course": number, // Course in degrees + "time": Date, // Current Time (or undefined if not known) + "satellites": 7, // Number of satellites + "fix": 1 // NMEA Fix state - 0 is no fix + "hdop": number, // Horizontal Dilution of Precision + */ + this.state.timeout = setTimeout(this.on_gps, 1000, f); + }, + off_gps: function() { + clearTimeout(gps_state.timeout); + }, + getGPSFix: function() { + if (!this.emulator) + return Bangle.getGPSFix(); + let fix = {}; + fix.fix = 1; + fix.lat = 50; + fix.lon = 14; + fix.alt = 200; + fix.speed = 5; + fix.course = 30; + fix.time = Date(); + fix.satellites = 5; + fix.hdop = 12; + return fix; + } }; var display = 0; @@ -109,13 +132,13 @@ function calcAlt(alt, cur_altitude) { return ddalt; } function updateGps() { - let have = false, lat = "lat ", lon = "lon ", alt = "?", + let have = false, lat = "lat ", alt = "?", speed = "speed ", hdop = "?", adelta = "adelta ", tdelta = "tdelta "; if (cancel_gps) return; - fix = libgps.getGPSFix(); + fix = gps.getGPSFix(); if (adj_time) { print("Adjusting time"); setTime(fix.time.getTime()/1000); @@ -136,16 +159,15 @@ function updateGps() { tdelta = "" + (getTime() - fix.time.getTime()/1000).toFixed(0); } if (fix && fix.fix && fix.lat) { - lat = "" + libgps.format(fix.lat); - lon = "" + libgps.format(fix.lon); + lat = "" + fmt.fmtPos(fix); alt = "" + fix.alt.toFixed(0); adelta = "" + (cur_altitude - fix.alt).toFixed(0); speed = "" + fix.speed.toFixed(1); hdop = "" + fix.hdop.toFixed(0); have = true; } else { - lat = "NO FIX "; - lon = "" + (getTime() - gps_start).toFixed(0) + "s " + lat = "NO FIX\n" + + "" + (getTime() - gps_start).toFixed(0) + "s " + sats_used + "/" + snum; if (cur_altitude) adelta = "" + cur_altitude.toFixed(0); @@ -154,7 +176,7 @@ function updateGps() { let ddalt = calcAlt(alt, cur_altitude); let msg = ""; if (display == 1) { - msg = lat + "\n" + lon + + msg = lat + "\ne" + hdop + "m "+tdelta+"s\n" + speed + "km/h\n"+ alt + "m+" + adelta + "\nmsghere"; } @@ -349,7 +371,8 @@ function touchHandler(d) { nextScreen(); } -libgps.init(); +gps.init(); +fmt.init(); Bangle.on("drag", touchHandler); Bangle.setUI({ From cd87342bd9c07dfc5da143cc927bbcdabcbb7705 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Sun, 23 Jun 2024 14:43:35 +0200 Subject: [PATCH 049/110] [] skyspy: display N/E for a fix, too. --- apps/skyspy/skyspy.app.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/apps/skyspy/skyspy.app.js b/apps/skyspy/skyspy.app.js index ae1109fe8..7cfa5145a 100644 --- a/apps/skyspy/skyspy.app.js +++ b/apps/skyspy/skyspy.app.js @@ -46,7 +46,19 @@ let fmt = { return "bad mode?"; }, fmtPos: function(pos) { - return this.fmtAngle(pos.lat) + "\n" + this.fmtAngle(pos.lon); + let x = pos.lat; + let c = "N"; + if (x<0) { + c = "S"; + x = -x; + } + let s = c+this.fmtAngle(pos.lat) + "\n"; + c = "E"; + if (x<0) { + c = "W"; + x = -x; + } + return s + c + this.fmtAngle(pos.lon); }, }; From c2692e179b432a30fc6586f740a5f4b48b7cee1f Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Sun, 23 Jun 2024 15:11:11 +0200 Subject: [PATCH 050/110] [] skyspy: add automatic altitude adjustment --- apps/skyspy/skyspy.app.js | 70 +++++++++++++++++++++++++++++---------- 1 file changed, 52 insertions(+), 18 deletions(-) diff --git a/apps/skyspy/skyspy.app.js b/apps/skyspy/skyspy.app.js index 7cfa5145a..9d74890ff 100644 --- a/apps/skyspy/skyspy.app.js +++ b/apps/skyspy/skyspy.app.js @@ -113,7 +113,7 @@ var cur_altitude; var wi = 24; var h = 176-wi, w = 176; var fix; -var adj_time = 0; +var adj_time = 0, adj_alt = 0; function radA(p) { return p*(Math.PI*2); } function radD(d) { return d*(h/2); } @@ -156,6 +156,26 @@ function updateGps() { setTime(fix.time.getTime()/1000); adj_time = 0; } + if (adj_alt) { + print("Adjust altitude"); + if (qalt < 5) { + let rest_altitude = fix.alt; + let alt_adjust = cur_altitude - rest_altitude; + let abs = Math.abs(alt_adjust); + print("adj", alt_adjust); + let o = Bangle.getOptions(); + if (abs > 10 && abs < 150) { + let a = 0.01; + // FIXME: draw is called often compared to alt reading + if (cur_altitude > rest_altitude) + a = -a; + o.seaLevelPressure = o.seaLevelPressure + a; + Bangle.setOptions(o); + } + msg = o.seaLevelPressure.toFixed(1) + "hPa"; + print(msg); + } + } try { Bangle.getPressure().then((x) => { @@ -351,36 +371,50 @@ function drawBusy() { drawMsg("\n.oO busy"); } +var numScreens = 3; + function nextScreen() { display = display + 1; - if (display == 3) - display = 0; - drawBusy(); + if (display == numScreens) + display = 0; + drawBusy(); +} +function prevScreen() { + display = display - 1; + if (display < 0) + display = numScreens - 1; + drawBusy(); } function onSwipe(dir) { - nextScreen(); + nextScreen(); } var last_b = 0; function touchHandler(d) { - let x = Math.floor(d.x); - let y = Math.floor(d.y); - - if (d.b != 1 || last_b != 0) { + let x = Math.floor(d.x); + let y = Math.floor(d.y); + + if (d.b != 1 || last_b != 0) { + last_b = d.b; + return; + } last_b = d.b; - return; - } - last_b = d.b; - if ((xh/2) && (yh/2) && (y>w/2)) - nextScreen(); + if ((xw/2)) + prevScreen(); + if ((x>h/2) && (y>w/2)) + nextScreen(); } gps.init(); From 0eab3bdcc804c609d0175dcee6eb84551b7a9846 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Mon, 24 Jun 2024 21:26:03 +0200 Subject: [PATCH 051/110] [] skyspy: mark library versions --- apps/skyspy/skyspy.app.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/skyspy/skyspy.app.js b/apps/skyspy/skyspy.app.js index 9d74890ff..29c0a1360 100644 --- a/apps/skyspy/skyspy.app.js +++ b/apps/skyspy/skyspy.app.js @@ -1,5 +1,6 @@ /* Sky spy */ +/* fmt library v0.1 */ let fmt = { icon_alt : "\0\x08\x1a\1\x00\x00\x00\x20\x30\x78\x7C\xFE\xFF\x00\xC3\xE7\xFF\xDB\xC3\xC3\xC3\xC3\x00\x00\x00\x00\x00\x00\x00\x00", icon_m : "\0\x08\x1a\1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC3\xE7\xFF\xDB\xC3\xC3\xC3\xC3\x00\x00\x00\x00\x00\x00\x00\x00", @@ -62,6 +63,7 @@ let fmt = { }, }; +/* gps library v0.1 */ let gps = { emulator: -1, init: function(x) { From 6014001307dd35b7dfd2d7411919cd0d87cd639f Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Sat, 13 Jul 2024 12:05:52 +0200 Subject: [PATCH 052/110] [] skyspy: increase version. --- apps/skyspy/ChangeLog | 1 + apps/skyspy/metadata.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/skyspy/ChangeLog b/apps/skyspy/ChangeLog index 79da4daf2..15a83ceeb 100644 --- a/apps/skyspy/ChangeLog +++ b/apps/skyspy/ChangeLog @@ -1,2 +1,3 @@ 0.01: attempt to import 0.02: Minor code improvements +0.03: big rewrite, adding time-adjust and altitude-adjust functionality diff --git a/apps/skyspy/metadata.json b/apps/skyspy/metadata.json index 07bc9280a..d8e9d1356 100644 --- a/apps/skyspy/metadata.json +++ b/apps/skyspy/metadata.json @@ -1,6 +1,6 @@ { "id": "skyspy", "name": "Sky Spy", - "version": "0.02", + "version": "0.03", "description": "Application for debugging GPS problems", "icon": "app.png", "readme": "README.md", From 3e7c1b6710695eb145c6f605d30291d3bebb00f9 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Sat, 13 Jul 2024 12:23:52 +0200 Subject: [PATCH 053/110] [] skyspy: attempt warning fixes. --- apps/skyspy/skyspy.app.js | 174 ++++++++++++++++++-------------------- 1 file changed, 83 insertions(+), 91 deletions(-) diff --git a/apps/skyspy/skyspy.app.js b/apps/skyspy/skyspy.app.js index 29c0a1360..0e6654c62 100644 --- a/apps/skyspy/skyspy.app.js +++ b/apps/skyspy/skyspy.app.js @@ -16,25 +16,25 @@ let fmt = { init: function() {}, fmtDist: function(km) { return km.toFixed(1) + this.icon_km; }, - fmtSteps: function(n) { return fmtDist(0.001 * 0.719 * n); }, + fmtSteps: function(n) { return this.fmtDist(0.001 * 0.719 * n); }, fmtAlt: function(m) { return m.toFixed(0) + this.icon_alt; }, fmtTimeDiff: function(d) { - if (d < 180) - return ""+d.toFixed(0); - d = d/60; - return ""+d.toFixed(0)+"m"; + if (d < 180) + return ""+d.toFixed(0); + d = d/60; + return ""+d.toFixed(0)+"m"; }, fmtAngle: function(x) { - switch (this.geo_mode) { - case 0: + switch (this.geo_mode) { + case 0: return "" + x; - case 1: { + case 1: { let d = Math.floor(x); let m = x - d; m = m*60; return "" + d + " " + m.toFixed(3) + "'"; - } - case 2: { + } + case 2: { let d = Math.floor(x); let m = x - d; m = m*60; @@ -42,24 +42,24 @@ let fmt = { let s = m - mf; s = s*60; return "" + d + " " + mf + "'" + s.toFixed(0) + '"'; - } - } - return "bad mode?"; + } + } + return "bad mode?"; }, fmtPos: function(pos) { - let x = pos.lat; - let c = "N"; - if (x<0) { - c = "S"; - x = -x; - } - let s = c+this.fmtAngle(pos.lat) + "\n"; - c = "E"; - if (x<0) { - c = "W"; - x = -x; - } - return s + c + this.fmtAngle(pos.lon); + let x = pos.lat; + let c = "N"; + if (x<0) { + c = "S"; + x = -x; + } + let s = c+this.fmtAngle(pos.lat) + "\n"; + c = "E"; + if (x<0) { + c = "W"; + x = -x; + } + return s + c + this.fmtAngle(pos.lon); }, }; @@ -67,50 +67,50 @@ let fmt = { let gps = { emulator: -1, init: function(x) { - this.emulator = (process.env.BOARD=="EMSCRIPTEN" - || process.env.BOARD=="EMSCRIPTEN2")?1:0; + this.emulator = (process.env.BOARD=="EMSCRIPTEN" + || process.env.BOARD=="EMSCRIPTEN2")?1:0; }, state: {}, on_gps: function(f) { - let fix = this.getGPSFix(); - f(fix); + let fix = this.getGPSFix(); + f(fix); - /* - "lat": number, // Latitude in degrees - "lon": number, // Longitude in degrees - "alt": number, // altitude in M - "speed": number, // Speed in kph - "course": number, // Course in degrees - "time": Date, // Current Time (or undefined if not known) - "satellites": 7, // Number of satellites - "fix": 1 // NMEA Fix state - 0 is no fix - "hdop": number, // Horizontal Dilution of Precision - */ - this.state.timeout = setTimeout(this.on_gps, 1000, f); + /* + "lat": number, // Latitude in degrees + "lon": number, // Longitude in degrees + "alt": number, // altitude in M + "speed": number, // Speed in kph + "course": number, // Course in degrees + "time": Date, // Current Time (or undefined if not known) + "satellites": 7, // Number of satellites + "fix": 1 // NMEA Fix state - 0 is no fix + "hdop": number, // Horizontal Dilution of Precision + */ + this.state.timeout = setTimeout(this.on_gps, 1000, f); }, off_gps: function() { - clearTimeout(gps_state.timeout); + clearTimeout(this.state.timeout); }, getGPSFix: function() { - if (!this.emulator) - return Bangle.getGPSFix(); - let fix = {}; - fix.fix = 1; - fix.lat = 50; - fix.lon = 14; - fix.alt = 200; - fix.speed = 5; - fix.course = 30; - fix.time = Date(); - fix.satellites = 5; - fix.hdop = 12; - return fix; + if (!this.emulator) + return Bangle.getGPSFix(); + let fix = {}; + fix.fix = 1; + fix.lat = 50; + fix.lon = 14; + fix.alt = 200; + fix.speed = 5; + fix.course = 30; + fix.time = Date(); + fix.satellites = 5; + fix.hdop = 12; + return fix; } }; var display = 0; var debug = 0; -var cancel_gps, gps_start; +var gps_start; var cur_altitude; var wi = 24; var h = 176-wi, w = 176; @@ -128,7 +128,7 @@ function radY(p, d) { return h/2 - Math.cos(a)*radD(d) + wi; } -var qalt = -1; +var qalt = -1, min_dalt, max_dalt, step; function resetAlt() { min_dalt = 9999; max_dalt = -9999; step = 0; } @@ -150,8 +150,6 @@ function updateGps() { speed = "speed ", hdop = "?", adelta = "adelta ", tdelta = "tdelta "; - if (cancel_gps) - return; fix = gps.getGPSFix(); if (adj_time) { print("Adjusting time"); @@ -161,21 +159,21 @@ function updateGps() { if (adj_alt) { print("Adjust altitude"); if (qalt < 5) { - let rest_altitude = fix.alt; - let alt_adjust = cur_altitude - rest_altitude; - let abs = Math.abs(alt_adjust); - print("adj", alt_adjust); - let o = Bangle.getOptions(); - if (abs > 10 && abs < 150) { - let a = 0.01; - // FIXME: draw is called often compared to alt reading - if (cur_altitude > rest_altitude) - a = -a; - o.seaLevelPressure = o.seaLevelPressure + a; - Bangle.setOptions(o); - } - msg = o.seaLevelPressure.toFixed(1) + "hPa"; - print(msg); + let rest_altitude = fix.alt; + let alt_adjust = cur_altitude - rest_altitude; + let abs = Math.abs(alt_adjust); + print("adj", alt_adjust); + let o = Bangle.getOptions(); + if (abs > 10 && abs < 150) { + let a = 0.01; + // FIXME: draw is called often compared to alt reading + if (cur_altitude > rest_altitude) + a = -a; + o.seaLevelPressure = o.seaLevelPressure + a; + Bangle.setOptions(o); + } + msg = o.seaLevelPressure.toFixed(1) + "hPa"; + print(msg); } } @@ -350,13 +348,7 @@ function parseRaw(msg, lost) { } } -function stopGps() { - cancel_gps=true; - Bangle.setGPSPower(0, "skyspy"); -} - function markGps() { - cancel_gps = false; Bangle.setGPSPower(1, "skyspy"); Bangle.on('GPS-raw', parseRaw); gps_start = getTime(); @@ -378,14 +370,14 @@ var numScreens = 3; function nextScreen() { display = display + 1; if (display == numScreens) - display = 0; + display = 0; drawBusy(); } function prevScreen() { display = display - 1; if (display < 0) - display = numScreens - 1; + display = numScreens - 1; drawBusy(); } @@ -399,24 +391,24 @@ function touchHandler(d) { let y = Math.floor(d.y); if (d.b != 1 || last_b != 0) { - last_b = d.b; - return; + last_b = d.b; + return; } last_b = d.b; if ((xh/2) && (yw/2)) - prevScreen(); + prevScreen(); if ((x>h/2) && (y>w/2)) - nextScreen(); + nextScreen(); } gps.init(); From 5160c2eedaf9b02e55b8601bedf51a5ae2e76e6c Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Sat, 13 Jul 2024 12:26:29 +0200 Subject: [PATCH 054/110] [] skyspy: fix remaining warning --- apps/skyspy/skyspy.app.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/skyspy/skyspy.app.js b/apps/skyspy/skyspy.app.js index 0e6654c62..a3a0d8776 100644 --- a/apps/skyspy/skyspy.app.js +++ b/apps/skyspy/skyspy.app.js @@ -146,7 +146,7 @@ function calcAlt(alt, cur_altitude) { return ddalt; } function updateGps() { - let have = false, lat = "lat ", alt = "?", + let lat = "lat ", alt = "?", speed = "speed ", hdop = "?", adelta = "adelta ", tdelta = "tdelta "; @@ -196,7 +196,6 @@ function updateGps() { adelta = "" + (cur_altitude - fix.alt).toFixed(0); speed = "" + fix.speed.toFixed(1); hdop = "" + fix.hdop.toFixed(0); - have = true; } else { lat = "NO FIX\n" + "" + (getTime() - gps_start).toFixed(0) + "s " From 42b3de082ea2542315ce7d828de2f232da23065e Mon Sep 17 00:00:00 2001 From: only-meeps <151784194+only-meeps@users.noreply.github.com> Date: Sat, 13 Jul 2024 04:39:01 -0700 Subject: [PATCH 055/110] Update app.js --- apps/8ball/app.js | 49 +++++------------------------------------------ 1 file changed, 5 insertions(+), 44 deletions(-) diff --git a/apps/8ball/app.js b/apps/8ball/app.js index 581e3e7bc..5a15e5bca 100644 --- a/apps/8ball/app.js +++ b/apps/8ball/app.js @@ -1,9 +1,8 @@ try {keyboard = require(keyboard);} catch(e) {keyboard = null;}var keyboard = "textinput"; var Name = ""; -var WaitTime = 0; Bangle.setLCDTimeout(0); - -var answers = new Array("no", "yes","WHAT????","What do you think", "That was a bad question", "YES!!!", "NOOOOO!!", "nope","100%","yup","why should I answer that?","think for yourself","ask again later, I'm busy", "what Was that horrible question","how dare you?","you wanted to hear yes? okay, yes", "Don't get angry when I say no","you are 100% wrong","totally, for sure","hmmm... I'll ponder it and get back to you later","wow, you really have a lot of questions", "NOPE","is the sky blue, hmmm...","I don't have time to answer","How many more questions before you change my name?","theres this thing called wikipedia","hmm... I don't seem to be able to reach the internet right now","if you phrase it like that, yes","Huh, never thought so hard in my life","The winds of time say no", "uh... can you ask that again? I kinda forgot", "I know I'm a computer, but even I can get bored"); +var menuOpen = 1; +var answers = new Array("no", "yes","WHAT????","What do you think", "That was a bad question", "YES!!!", "NOOOOO!!", "nope","100%","yup","why should I answer that?","think for yourself","ask again later, I'm busy", "what Was that horrible question","how dare you?","you wanted to hear yes? okay, yes", "Don't get angry when I say no","you are 100% wrong","totally, for sure","hmmm... I'll ponder it and get back to you later","wow, you really have a lot of questions", "NOPE","is the sky blue, hmmm...","I don't have time to answer","How many more questions before you change my name?","theres this thing called wikipedia","hmm... I don't seem to be able to reach the internet right now","if you phrase it like that, yes","Huh, never thought so hard in my life","The winds of time say no"); var consonants = new Array("b","c","d","f","g","h","j","k","l","m","n","p","q","r","s","t","v","w","x","y","z"); var vowels = new Array("a","e","i","o","u"); try {keyboard = require(keyboard);} catch(e) {keyboard = null;} @@ -36,28 +35,12 @@ function menu() menuOpen = 0; Drawtext("ask " + Name + " a yes or no question"); }, - "Show name" : () => { - E.showMenu(); - if(Name == null) - { - E.showAlert("No Name Data").then(result => {menu();}); - } - - else - { - E.showAlert(Name).then(result => {menu();}); - } - }, - "regenerate name" : () => { E.showMenu(); generateName(); - E.showAlert("name regenerated as " + Name).then(result => {menu();}); - - }, "show answers" : () => { - var menu = new Array(); + var menu = new Array([]); for(var i = 0; i < answers.length; i++){ menu.push({title : answers[i]}); } @@ -72,28 +55,18 @@ function menu() }, "Edit name" : () => { E.showMenu(); - var result = keyboard.input({}).then(result => {Name = result, menu();}); - + var result = keyboard.input({}).then(result => {menu(), Name = result;}); }, "Exit" : () => load(), }); } menu(); - - var answer; +var answer; function Drawtext(text) { g.clear(); - //g.setFontAlign(0,0); g.setFont("Vector", 20); g.drawString(g.wrapString(text, g.getWidth(), -20).join("\n")); - - -} -function DrawWidgets() -{ - Bangle.loadWidgets(); - Bangle.drawWidgets(); } function WriteAnswer() { @@ -101,8 +74,6 @@ function WriteAnswer() { var randomnumber = Math.round(Math.random()*answers.length); answer = answers[randomnumber]; - var i; - Drawtext(answer); setTimeout(function() { Drawtext("ask " + Name + " a yes or no question"); @@ -111,16 +82,6 @@ function WriteAnswer() } } -//turns screen timeout off when menu closed -//needs attention -/*if(menuOpen == 1) -{ - Bangle.setLCDTimeout(10); -} -else -{ - Bangle.setLCDTimeout(undefined); -}*/ setWatch(function() { menu(); From d789d37de5d3339f87140fcc7088c94e778ee0f1 Mon Sep 17 00:00:00 2001 From: only-meeps <151784194+only-meeps@users.noreply.github.com> Date: Sat, 13 Jul 2024 04:41:09 -0700 Subject: [PATCH 056/110] Update app.js --- apps/boxclk/app.js | 798 ++++++++++++++++++++++----------------------- 1 file changed, 397 insertions(+), 401 deletions(-) diff --git a/apps/boxclk/app.js b/apps/boxclk/app.js index 34ffac1b6..8c29aac14 100644 --- a/apps/boxclk/app.js +++ b/apps/boxclk/app.js @@ -1,413 +1,409 @@ +let background = require("clockbg"); +Modules.addCached("widget_utils", function() { + exports.hide = function() { + exports.cleanup(); + if (!global.WIDGETS) return; + g.reset(); + for (var w of global.WIDGETS) { + if (w._draw) return; + w._draw = w.draw; + w.draw = () => {}; + w._area = w.area; + w.area = ""; + if (w.x != undefined) g.clearRect(w.x, w.y, w.x + w.width - 1, w.y + 23); + } + }; + exports.show = function() { + exports.cleanup(); + if (!global.WIDGETS) return; + for (var w of global.WIDGETS) { + if (!w._draw) return; + w.draw = w._draw; + w.area = w._area; + delete w._draw; + delete w._area; + w.draw(w); + } + }; + exports.cleanup = function() { + delete exports.autohide; + delete Bangle.appRect; + if (exports.swipeHandler) { + Bangle.removeListener("swipe", exports.swipeHandler); + delete exports.swipeHandler; + } + if (exports.animInterval) { + clearInterval(exports.animInterval); + delete exports.animInterval; + } + if (exports.hideTimeout) { + clearTimeout(exports.hideTimeout); + delete exports.hideTimeout; + } + if (exports.origDraw) { + Bangle.drawWidgets = exports.origDraw; + delete exports.origDraw; + } + } + exports.swipeOn = function(autohide) { + if (process.env.HWVERSION !== 2) return exports.hide(); + exports.cleanup(); + if (!global.WIDGETS) return; + exports.autohide = autohide === undefined ? 2000 : autohide; + Bangle.appRect = { + x: 0, + y: 0, + w: g.getWidth(), + h: g.getHeight(), + x2: g.getWidth() - 1, + y2: g.getHeight() - 1 + }; + let og = Graphics.createArrayBuffer(g.getWidth(), 26, 16, { + msb: true + }); + og.theme = g.theme; + og._reset = og.reset; + og.reset = function() { + return this._reset().setColor(g.theme.fg).setBgColor(g.theme.bg); + }; + og.reset().clearRect(0, 0, og.getWidth(), 23).fillRect(0, 24, og.getWidth(), 25); + let _g = g; + let offset = -24; + + function queueDraw() { + Bangle.appRect.y = offset + 24; + Bangle.appRect.h = 1 + Bangle.appRect.y2 - Bangle.appRect.y; + if (offset > -24) Bangle.setLCDOverlay(og, 0, offset); + else Bangle.setLCDOverlay(); + } + for (var w of global.WIDGETS) { + if (w._draw) continue; + w._draw = w.draw; + w.draw = function() { + g = og; + this._draw(this); + g = _g; + if (offset > -24) queueDraw(); + }; + w._area = w.area; + if (w.area.startsWith("b")) w.area = "t" + w.area.substr(1); + } + exports.origDraw = Bangle.drawWidgets; + Bangle.drawWidgets = () => { + g = og; + exports.origDraw(); + g = _g; + }; + + function anim(dir, callback) { + if (exports.animInterval) clearInterval(exports.interval); + exports.animInterval = setInterval(function() { + offset += dir; + let stop = false; + if (dir > 0 && offset >= 0) { + stop = true; + offset = 0; + } else if (dir < 0 && offset < -23) { + stop = true; + offset = -24; + } + if (stop) { + clearInterval(exports.animInterval); + delete exports.animInterval; + if (callback) callback(); + } + queueDraw(); + }, 50); + } + exports.swipeHandler = function(lr, ud) { + if (exports.hideTimeout) { + clearTimeout(exports.hideTimeout); + delete exports.hideTimeout; + } + let cb; + if (exports.autohide > 0) cb = function() { + exports.hideTimeout = setTimeout(function() { + anim(-4); + }, exports.autohide); + } + if (ud > 0 && offset < 0) anim(4, cb); + if (ud < 0 && offset > -24) anim(-4); + }; + Bangle.on("swipe", exports.swipeHandler); + Bangle.drawWidgets(); + }; +}); { - /** - * --------------------------------------------------------------- - * 1. Module dependencies and initial configurations - * --------------------------------------------------------------- - */ - let background = require("clockbg"); - let storage = require("Storage"); - let locale = require("locale"); - let widgets = require("widget_utils"); - let date = new Date(); - let bgImage; - let configNumber = (storage.readJSON("boxclk.json", 1) || {}).selectedConfig || 0; - let fileName = 'boxclk' + (configNumber > 0 ? `-${configNumber}` : '') + '.json'; - // Add a condition to check if the file exists, if it does not, default to 'boxclk.json' - if (!storage.read(fileName)) { - fileName = 'boxclk.json'; - } - let boxesConfig = storage.readJSON(fileName, 1) || {}; - let boxes = {}; - let boxPos = {}; - let isDragging = {}; - let wasDragging = {}; - let doubleTapTimer = null; - let g_setColor; - - let saveIcon = require("heatshrink").decompress(atob("mEwwkEogA/AHdP/4AK+gWVDBQWNAAIuVGBAIB+UQdhMfGBAHBCxUAgIXHIwPyCxQwEJAgXB+MAl/zBwQGBn8ggQjBGAQXG+EA/4XI/8gBIQXTGAMPC6n/C6HzkREBC6YACC6QAFC57aHCYIXOOgLsEn4XPABIX/C6vykQAEl6/WgCQBC5imFAAT2BC5gCBI4oUCC5x0IC/4X/C4K8Bl4XJ+TCCC4wKBABkvC4tEEoMQCxcBB4IWEC4XyDBUBFwIXGJAIAOIwowDABoWGGB4uHDBwWJAH4AzA")); - - /** - * --------------------------------------------------------------- - * 2. Graphical and visual configurations - * --------------------------------------------------------------- - */ - - let w = g.getWidth(); - let h = g.getHeight(); - let totalWidth, totalHeight; - let drawTimeout; - - /** - * --------------------------------------------------------------- - * 3. Touchscreen Handlers - * --------------------------------------------------------------- - */ - - let touchHandler; - let dragHandler; - let movementDistance = 0; - - /** - * --------------------------------------------------------------- - * 4. Font loading function - * --------------------------------------------------------------- - */ - - let loadCustomFont = function() { - Graphics.prototype.setFontBrunoAce = function() { - // Actual height 23 (24 - 2) - return this.setFontCustom( - E.toString(require('heatshrink').decompress(atob('ABMHwADBh4DKg4bKgIPDAYUfAYV/AYX/AQMD/gmC+ADBn/AByE/GIU8AYUwLxcfAYX/8AnB//4JIP/FgMP4F+CQQBBjwJBFYRbBAd43DHoJpBh/g/xPEK4ZfDgEEORKDDAY8////wADLfZrTCgITBnhEBAYJMBAYMPw4DCM4QDjhwDCjwDBn0+AYMf/gDBh/4AYMH+ADBLpc4ToK/NGYZfnAYcfL4U/x5fBW4LvB/7vC+LvBgHAsBfIn76Cn4WBcYQDFEgJ+CQQYDyH4L/BAZbHLNYjjCAZc8ngDunycBZ4KkBa4KwBnEHY4UB+BfMgf/ZgMH/4XBc4cf4F/gE+ZgRjwAYcfj5jBM4U4M4RQBM4UA8BjIngDFEYJ8BAYUDAYQvCM4ZxBC4V+AYQvBnkBQ4M8gabBJQPAI4WAAYM/GYQaBAYJKCnqyCn5OCn4aBAYIaBAYJPCU4IABnBhIuDXCFAMD+Z/BY4IDBQwOPwEfv6TDAYUPAcwrDAYQ7BAYY/BI4cD8bLCK4RfEAA0BRYTeDcwIrFn0Pw43Bg4DugYDBjxBBU4SvDMYMH/5QBgP/LAQAP8EHN4UPwADHB4YAHA'))), - 46, - atob("CBEdChgYGhgaGBsaCQ=="), - 32|65536 - ); - }; - }; - - /** - * --------------------------------------------------------------- - * 5. Initial settings of boxes and their positions - * --------------------------------------------------------------- - */ - - for (let key in boxesConfig) { - if (key === 'bg' && boxesConfig[key].img) { - bgImage = storage.read(boxesConfig[key].img); - } else if (key !== 'selectedConfig') { - boxes[key] = Object.assign({}, boxesConfig[key]); + let storage = require("Storage"); + let locale = require("locale"); + let widgets = require("widget_utils"); + let date = new Date(); + let configNumber = (storage.readJSON("boxclk.json", 1) || {}).selectedConfig || 0; + let fileName = 'boxclk' + (configNumber > 0 ? `-${configNumber}` : '') + '.json'; + if (!storage.read(fileName)) { + fileName = 'boxclk.json'; } - } - - let boxKeys = Object.keys(boxes); - - boxKeys.forEach((key) => { - let boxConfig = boxes[key]; - boxPos[key] = { - x: w * boxConfig.boxPos.x, - y: h * boxConfig.boxPos.y + let boxesConfig = storage.readJSON(fileName, 1) || {}; + let boxes = {}; + let boxPos = {}; + let isDragging = {}; + let wasDragging = {}; + let doubleTapTimer = null; + let g_setColor; + let saveIcon = require("heatshrink").decompress(atob("mEwwkEogA/AHdP/4AK+gWVDBQWNAAIuVGBAIB+UQdhMfGBAHBCxUAgIXHIwPyCxQwEJAgXB+MAl/zBwQGBn8ggQjBGAQXG+EA/4XI/8gBIQXTGAMPC6n/C6HzkREBC6YACC6QAFC57aHCYIXOOgLsEn4XPABIX/C6vykQAEl6/WgCQBC5imFAAT2BC5gCBI4oUCC5x0IC/4X/C4K8Bl4XJ+TCCC4wKBABkvC4tEEoMQCxcBB4IWEC4XyDBUBFwIXGJAIAOIwowDABoWGGB4uHDBwWJAH4AzA")); + let w = g.getWidth(); + let h = g.getHeight(); + let totalWidth, totalHeight; + let drawTimeout; + let touchHandler; + let dragHandler; + let movementDistance = 0; + let loadCustomFont = function() { + Graphics.prototype.setFontBrunoAce = function() { + return this.setFontCustom(E.toString(require('heatshrink').decompress(atob('ABMHwADBh4DKg4bKgIPDAYUfAYV/AYX/AQMD/gmC+ADBn/AByE/GIU8AYUwLxcfAYX/8AnB//4JIP/FgMP4F+CQQBBjwJBFYRbBAd43DHoJpBh/g/xPEK4ZfDgEEORKDDAY8////wADLfZrTCgITBnhEBAYJMBAYMPw4DCM4QDjhwDCjwDBn0+AYMf/gDBh/4AYMH+ADBLpc4ToK/NGYZfnAYcfL4U/x5fBW4LvB/7vC+LvBgHAsBfIn76Cn4WBcYQDFEgJ+CQQYDyH4L/BAZbHLNYjjCAZc8ngDunycBZ4KkBa4KwBnEHY4UB+BfMgf/ZgMH/4XBc4cf4F/gE+ZgRjwAYcfj5jBM4U4M4RQBM4UA8BjIngDFEYJ8BAYUDAYQvCM4ZxBC4V+AYQvBnkBQ4M8gabBJQPAI4WAAYM/GYQaBAYJKCnqyCn5OCn4aBAYIaBAYJPCU4IABnBhIuDXCFAMD+Z/BY4IDBQwOPwEfv6TDAYUPAcwrDAYQ7BAYY/BI4cD8bLCK4RfEAA0BRYTeDcwIrFn0Pw43Bg4DugYDBjxBBU4SvDMYMH/5QBgP/LAQAP8EHN4UPwADHB4YAHA'))), 46, atob("CBEdChgYGhgaGBsaCQ=="), 32 | 65536); + }; }; - isDragging[key] = false; - wasDragging[key] = false; - }); - - /** - * --------------------------------------------------------------- - * 6. Text and drawing functions - * --------------------------------------------------------------- - */ - - // Overwrite the setColor function to allow the - // use of (x) in g.theme.x as a string - // in your JSON config ("fg", "bg", "fg2", "bg2", "fgH", "bgH") - let modSetColor = function() { - // Save the original setColor function - g_setColor = g.setColor; - // Overwrite setColor with the new function - g.setColor = function(color) { - if (typeof color === "string" && color in g.theme) { - g_setColor.call(g, g.theme[color]); - } else { - g_setColor.call(g, color); - } + for (let key in boxesConfig) { + if (key === 'bg' && boxesConfig[key].img) { + bgImage = storage.read(boxesConfig[key].img); + } else if (key !== 'selectedConfig') { + boxes[key] = Object.assign({}, boxesConfig[key]); + } + } + let boxKeys = Object.keys(boxes); + boxKeys.forEach((key) => { + let boxConfig = boxes[key]; + boxPos[key] = { + x: w * boxConfig.boxPos.x, + y: h * boxConfig.boxPos.y + }; + isDragging[key] = false; + wasDragging[key] = false; + }); + let modSetColor = function() { + g_setColor = g.setColor; + g.setColor = function(color) { + if (typeof color === "string" && color in g.theme) { + g_setColor.call(g, g.theme[color]); + } else { + g_setColor.call(g, color); + } + }; }; - }; - - let restoreSetColor = function() { - // Restore the original setColor function - if (g_setColor) { - g.setColor = g_setColor; - } - }; - - // Overwrite the drawString function - let g_drawString = g.drawString; - g.drawString = function(box, str, x, y) { - outlineText(box, str, x, y); - g.setColor(box.color); - g_drawString.call(g, str, x, y); - }; - - let outlineText = function(box, str, x, y) { - let px = box.outline; - let dx = [-px, 0, px, -px, px, -px, 0, px]; - let dy = [-px, -px, -px, 0, 0, px, px, px]; - g.setColor(box.outlineColor); - for (let i = 0; i < dx.length; i++) { - g_drawString.call(g, str, x + dx[i], y + dy[i]); - } - }; - - let calcBoxSize = function(boxItem) { - g.reset(); - g.setFontAlign(0,0); - g.setFont(boxItem.font, boxItem.fontSize); - let strWidth = g.stringWidth(boxItem.string) + 2 * boxItem.outline; - let fontHeight = g.getFontHeight() + 2 * boxItem.outline; - totalWidth = strWidth + 2 * boxItem.xPadding; - totalHeight = fontHeight + 2 * boxItem.yPadding; - }; - - let calcBoxPos = function(boxKey) { - return { - x1: boxPos[boxKey].x - totalWidth / 2, - y1: boxPos[boxKey].y - totalHeight / 2, - x2: boxPos[boxKey].x + totalWidth / 2, - y2: boxPos[boxKey].y + totalHeight / 2 + let restoreSetColor = function() { + if (g_setColor) { + g.setColor = g_setColor; + } }; - }; - - let displaySaveIcon = function() { - draw(boxes); - g.drawImage(saveIcon, w / 2 - 24, h / 2 - 24); - // Display save icon for 2 seconds - setTimeout(() => { - g.clearRect(w / 2 - 24, h / 2 - 24, w / 2 + 24, h / 2 + 24); - draw(boxes); - }, 2000); - }; - - /** - * --------------------------------------------------------------- - * 7. String forming helper functions - * --------------------------------------------------------------- - */ - - let isBool = function(val, defaultVal) { - return typeof val !== 'undefined' ? Boolean(val) : defaultVal; - }; - - let getDate = function(short, shortMonth, disableSuffix) { - const date = new Date(); - const dayOfMonth = date.getDate(); - const month = shortMonth ? locale.month(date, 1) : locale.month(date, 0); - const year = date.getFullYear(); - let suffix; - if ([1, 21, 31].includes(dayOfMonth)) { - suffix = "st"; - } else if ([2, 22].includes(dayOfMonth)) { - suffix = "nd"; - } else if ([3, 23].includes(dayOfMonth)) { - suffix = "rd"; - } else { - suffix = "th"; - } - let dayOfMonthStr = disableSuffix ? dayOfMonth : dayOfMonth + suffix; - return month + " " + dayOfMonthStr + (short ? '' : (", " + year)); // not including year for short version - }; - - let getDayOfWeek = function(date, short) { - return locale.dow(date, short ? 1 : 0); - }; - - locale.meridian = function(date, short) { - let hours = date.getHours(); - let meridian = hours >= 12 ? 'PM' : 'AM'; - return short ? meridian[0] : meridian; - }; - - let modString = function(boxItem, data) { - let prefix = boxItem.prefix || ''; - let suffix = boxItem.suffix || ''; - return prefix + data + suffix; - }; - - /** - * --------------------------------------------------------------- - * 8. Main draw function - * --------------------------------------------------------------- - */ - - let draw = (function() { - let updatePerMinute = true; // variable to track the state of time display - - return function(boxes) { - date = new Date(); - g.clear(); - background.fillRect(Bangle.appRect); - if (boxes.time) { - boxes.time.string = modString(boxes.time, locale.time(date, isBool(boxes.time.short, true) ? 1 : 0)); - updatePerMinute = isBool(boxes.time.short, true); - } - if (boxes.meridian) { - boxes.meridian.string = modString(boxes.meridian, locale.meridian(date, isBool(boxes.meridian.short, true))); - } - if (boxes.date) { - boxes.date.string = ( - modString(boxes.date, - getDate(isBool(boxes.date.short, true), - isBool(boxes.date.shortMonth, true), - isBool(boxes.date.disableSuffix, false) - ))); - } - if (boxes.dow) { - boxes.dow.string = modString(boxes.dow, getDayOfWeek(date, isBool(boxes.dow.short, true))); - } - if (boxes.batt) { - boxes.batt.string = modString(boxes.batt, E.getBattery()); - } - if (boxes.step) { - boxes.step.string = modString(boxes.step, Bangle.getHealthStatus("day").steps); - } - boxKeys.forEach((boxKey) => { - let boxItem = boxes[boxKey]; + let g_drawString = g.drawString; + g.drawString = function(box, str, x, y) { + outlineText(box, str, x, y); + g.setColor(box.color); + g_drawString.call(g, str, x, y); + }; + let outlineText = function(box, str, x, y) { + let px = box.outline; + let dx = [-px, 0, px, -px, px, -px, 0, px]; + let dy = [-px, -px, -px, 0, 0, px, px, px]; + g.setColor(box.outlineColor); + for (let i = 0; i < dx.length; i++) { + g_drawString.call(g, str, x + dx[i], y + dy[i]); + } + }; + let calcBoxSize = function(boxItem) { + g.reset(); + g.setFontAlign(0, 0); + g.setFont(boxItem.font, boxItem.fontSize); + let strWidth = g.stringWidth(boxItem.string) + 2 * boxItem.outline; + let fontHeight = g.getFontHeight() + 2 * boxItem.outline; + totalWidth = strWidth + 2 * boxItem.xPadding; + totalHeight = fontHeight + 2 * boxItem.yPadding; + }; + let calcBoxPos = function(boxKey) { + return { + x1: boxPos[boxKey].x - totalWidth / 2, + y1: boxPos[boxKey].y - totalHeight / 2, + x2: boxPos[boxKey].x + totalWidth / 2, + y2: boxPos[boxKey].y + totalHeight / 2 + }; + }; + let displaySaveIcon = function() { + draw(boxes); + g.drawImage(saveIcon, w / 2 - 24, h / 2 - 24); + setTimeout(() => { + g.clearRect(w / 2 - 24, h / 2 - 24, w / 2 + 24, h / 2 + 24); + draw(boxes); + }, 2000); + }; + let isBool = function(val, defaultVal) { + return typeof val !== 'undefined' ? Boolean(val) : defaultVal; + }; + let getDate = function(short, shortMonth, disableSuffix) { + const date = new Date(); + const dayOfMonth = date.getDate(); + const month = shortMonth ? locale.month(date, 1) : locale.month(date, 0); + const year = date.getFullYear(); + let suffix; + if ([1, 21, 31].includes(dayOfMonth)) { + suffix = "st"; + } else if ([2, 22].includes(dayOfMonth)) { + suffix = "nd"; + } else if ([3, 23].includes(dayOfMonth)) { + suffix = "rd"; + } else { + suffix = "th"; + } + let dayOfMonthStr = disableSuffix ? dayOfMonth : dayOfMonth + suffix; + return month + " " + dayOfMonthStr + (short ? '' : (", " + year)); + }; + let getDayOfWeek = function(date, short) { + return locale.dow(date, short ? 1 : 0); + }; + locale.meridian = function(date, short) { + let hours = date.getHours(); + let meridian = hours >= 12 ? 'PM' : 'AM'; + return short ? meridian[0] : meridian; + }; + let modString = function(boxItem, data) { + let prefix = boxItem.prefix || ''; + let suffix = boxItem.suffix || ''; + return prefix + data + suffix; + }; + let draw = (function() { + let updatePerMinute = true; + return function(boxes) { + date = new Date(); + g.clear(); + background.fillRect(Bangle.appRect); + if (boxes.time) { + boxes.time.string = modString(boxes.time, locale.time(date, isBool(boxes.time.short, true) ? 1 : 0)); + updatePerMinute = isBool(boxes.time.short, true); + } + if (boxes.meridian) { + boxes.meridian.string = modString(boxes.meridian, locale.meridian(date, isBool(boxes.meridian.short, true))); + } + if (boxes.date) { + boxes.date.string = (modString(boxes.date, getDate(isBool(boxes.date.short, true), isBool(boxes.date.shortMonth, true), isBool(boxes.date.disableSuffix, false)))); + } + if (boxes.dow) { + boxes.dow.string = modString(boxes.dow, getDayOfWeek(date, isBool(boxes.dow.short, true))); + } + if (boxes.batt) { + boxes.batt.string = modString(boxes.batt, E.getBattery()); + } + if (boxes.step) { + boxes.step.string = modString(boxes.step, Bangle.getHealthStatus("day").steps); + } + boxKeys.forEach((boxKey) => { + let boxItem = boxes[boxKey]; + calcBoxSize(boxItem); + const pos = calcBoxPos(boxKey); + if (isDragging[boxKey]) { + g.setColor(boxItem.border); + g.drawRect(pos.x1, pos.y1, pos.x2, pos.y2); + } + g.drawString(boxItem, boxItem.string, boxPos[boxKey].x + boxItem.xOffset, boxPos[boxKey].y + boxItem.yOffset); + }); + if (!Object.values(isDragging).some(Boolean)) { + if (drawTimeout) clearTimeout(drawTimeout); + let interval = updatePerMinute ? 60000 - (Date.now() % 60000) : 1000; + drawTimeout = setTimeout(() => draw(boxes), interval); + } + }; + })(); + let touchInText = function(e, boxItem, boxKey) { calcBoxSize(boxItem); const pos = calcBoxPos(boxKey); - if (isDragging[boxKey]) { - g.setColor(boxItem.border); - g.drawRect(pos.x1, pos.y1, pos.x2, pos.y2); - } - g.drawString( - boxItem, - boxItem.string, - boxPos[boxKey].x + boxItem.xOffset, - boxPos[boxKey].y + boxItem.yOffset - ); - }); - if (!Object.values(isDragging).some(Boolean)) { - if (drawTimeout) clearTimeout(drawTimeout); - let interval = updatePerMinute ? 60000 - (Date.now() % 60000) : 1000; - drawTimeout = setTimeout(() => draw(boxes), interval); - } + return e.x >= pos.x1 && e.x <= pos.x2 && e.y >= pos.y1 && e.y <= pos.y2; }; - })(); - - /** - * --------------------------------------------------------------- - * 9. Helper function for touch event - * --------------------------------------------------------------- - */ - - let touchInText = function(e, boxItem, boxKey) { - calcBoxSize(boxItem); - const pos = calcBoxPos(boxKey); - return e.x >= pos.x1 && - e.x <= pos.x2 && - e.y >= pos.y1 && - e.y <= pos.y2; - }; - - let deselectAllBoxes = function() { - Object.keys(isDragging).forEach((boxKey) => { - isDragging[boxKey] = false; - }); - restoreSetColor(); - widgets.show(); - widgets.swipeOn(); - modSetColor(); - }; - - /** - * --------------------------------------------------------------- - * 10. Setup function to configure event handlers - * --------------------------------------------------------------- - */ - - let setup = function() { - // ------------------------------------ - // Define the touchHandler function - // ------------------------------------ - touchHandler = function(zone, e) { - wasDragging = Object.assign({}, isDragging); - let boxTouched = false; - boxKeys.forEach((boxKey) => { - if (touchInText(e, boxes[boxKey], boxKey)) { - isDragging[boxKey] = true; - wasDragging[boxKey] = true; - boxTouched = true; - } - }); - if (!boxTouched) { - if (!Object.values(isDragging).some(Boolean)) { // check if no boxes are being dragged - deselectAllBoxes(); - if (doubleTapTimer) { - clearTimeout(doubleTapTimer); - doubleTapTimer = null; - // Save boxesConfig on double tap outside of any box and when no boxes are being dragged - Object.keys(boxPos).forEach((boxKey) => { - boxesConfig[boxKey].boxPos.x = (boxPos[boxKey].x / w).toFixed(3); - boxesConfig[boxKey].boxPos.y = (boxPos[boxKey].y / h).toFixed(3); - }); - storage.write(fileName, JSON.stringify(boxesConfig)); - displaySaveIcon(); - return; - } - } else { - // if any box is being dragged, just deselect all without saving - deselectAllBoxes(); - } - } - if (Object.values(wasDragging).some(Boolean) || !boxTouched) { - draw(boxes); - } - doubleTapTimer = setTimeout(() => { - doubleTapTimer = null; - }, 500); // Increase or decrease this value based on the desired double tap timing - movementDistance = 0; - }; - - // ------------------------------------ - // Define the dragHandler function - // ------------------------------------ - dragHandler = function(e) { - // Check if any box is being dragged - if (!Object.values(isDragging).some(Boolean)) return; - // Calculate the movement distance - movementDistance += Math.abs(e.dx) + Math.abs(e.dy); - // Check if the movement distance exceeds a threshold - if (movementDistance > 1) { - boxKeys.forEach((boxKey) => { - if (isDragging[boxKey]) { - widgets.hide(); - let boxItem = boxes[boxKey]; - calcBoxSize(boxItem); - let newX = boxPos[boxKey].x + e.dx; - let newY = boxPos[boxKey].y + e.dy; - if (newX - totalWidth / 2 >= 0 && - newX + totalWidth / 2 <= w && - newY - totalHeight / 2 >= 0 && - newY + totalHeight / 2 <= h ) { - boxPos[boxKey].x = newX; - boxPos[boxKey].y = newY; - } - const pos = calcBoxPos(boxKey); - g.clearRect(pos.x1, pos.y1, pos.x2, pos.y2); - } + let deselectAllBoxes = function() { + Object.keys(isDragging).forEach((boxKey) => { + isDragging[boxKey] = false; }); - draw(boxes); - } - }; - - Bangle.on('touch', touchHandler); - Bangle.on('drag', dragHandler); - - Bangle.setUI({ - mode : "clock", - remove : function() { - // Remove event handlers, stop draw timer, remove custom font if used - Bangle.removeListener('touch', touchHandler); - Bangle.removeListener('drag', dragHandler); - if (drawTimeout) clearTimeout(drawTimeout); - drawTimeout = undefined; - delete Graphics.prototype.setFontBrunoAce; - // Restore original drawString function (no outlines) - g.drawString = g_drawString; restoreSetColor(); widgets.show(); - } - }); - loadCustomFont(); - draw(boxes); - }; - - /** - * --------------------------------------------------------------- - * 11. Main execution part - * --------------------------------------------------------------- - */ - - Bangle.loadWidgets(); - widgets.swipeOn(); - modSetColor(); - setup(); + widgets.swipeOn(); + modSetColor(); + }; + let setup = function() { + touchHandler = function(zone, e) { + wasDragging = Object.assign({}, isDragging); + let boxTouched = false; + boxKeys.forEach((boxKey) => { + if (touchInText(e, boxes[boxKey], boxKey)) { + isDragging[boxKey] = true; + wasDragging[boxKey] = true; + boxTouched = true; + } + }); + if (!boxTouched) { + if (!Object.values(isDragging).some(Boolean)) { + deselectAllBoxes(); + if (doubleTapTimer) { + clearTimeout(doubleTapTimer); + doubleTapTimer = null; + Object.keys(boxPos).forEach((boxKey) => { + boxesConfig[boxKey].boxPos.x = (boxPos[boxKey].x / w).toFixed(3); + boxesConfig[boxKey].boxPos.y = (boxPos[boxKey].y / h).toFixed(3); + }); + storage.write(fileName, JSON.stringify(boxesConfig)); + displaySaveIcon(); + return; + } + } else { + deselectAllBoxes(); + } + } + if (Object.values(wasDragging).some(Boolean) || !boxTouched) { + draw(boxes); + } + doubleTapTimer = setTimeout(() => { + doubleTapTimer = null; + }, 500); + movementDistance = 0; + }; + dragHandler = function(e) { + if (!Object.values(isDragging).some(Boolean)) return; + movementDistance += Math.abs(e.dx) + Math.abs(e.dy); + if (movementDistance > 1) { + boxKeys.forEach((boxKey) => { + if (isDragging[boxKey]) { + widgets.hide(); + let boxItem = boxes[boxKey]; + calcBoxSize(boxItem); + let newX = boxPos[boxKey].x + e.dx; + let newY = boxPos[boxKey].y + e.dy; + if (newX - totalWidth / 2 >= 0 && newX + totalWidth / 2 <= w && newY - totalHeight / 2 >= 0 && newY + totalHeight / 2 <= h) { + boxPos[boxKey].x = newX; + boxPos[boxKey].y = newY; + } + const pos = calcBoxPos(boxKey); + g.clearRect(pos.x1, pos.y1, pos.x2, pos.y2); + } + }); + draw(boxes); + } + }; + Bangle.on('touch', touchHandler); + Bangle.on('drag', dragHandler); + Bangle.setUI({ + mode: "clock", + remove: function() { + Bangle.removeListener('touch', touchHandler); + Bangle.removeListener('drag', dragHandler); + if (drawTimeout) clearTimeout(drawTimeout); + drawTimeout = undefined; + delete Graphics.prototype.setFontBrunoAce; + g.drawString = g_drawString; + restoreSetColor(); + widgets.show(); + } + }); + loadCustomFont(); + draw(boxes); + }; + Bangle.loadWidgets(); + widgets.swipeOn(); + modSetColor(); + setup(); } From 1a7e4c8e70b9c3a27caff7c0af4d9be376dbbb77 Mon Sep 17 00:00:00 2001 From: only-meeps <151784194+only-meeps@users.noreply.github.com> Date: Sat, 13 Jul 2024 04:51:10 -0700 Subject: [PATCH 057/110] Update app.js --- apps/8ball/app.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/apps/8ball/app.js b/apps/8ball/app.js index 5a15e5bca..59f243f80 100644 --- a/apps/8ball/app.js +++ b/apps/8ball/app.js @@ -27,7 +27,7 @@ function menu() E.showMenu(); menuOpen = 1; E.showMenu({ - "" : { title : /*LANG*/Name }, + "" : { title : Name }, "< Back" : () => menu(), "Start" : () => { E.showMenu(); @@ -36,7 +36,7 @@ function menu() Drawtext("ask " + Name + " a yes or no question"); }, "regenerate name" : () => { - E.showMenu(); + menu(); generateName(); }, "show answers" : () => { @@ -51,17 +51,19 @@ function menu() "Add answer" : () => { E.showMenu(); - var result = keyboard.input({}).then(result => {if(result != ""){answers.push(result);} menu();}); + keyboard.input({}).then(result => {if(result != ""){answers.push(result);} menu();}); }, "Edit name" : () => { E.showMenu(); - var result = keyboard.input({}).then(result => {menu(), Name = result;}); + keyboard.input({}).then(result => {if(result != ""){Name = result;} menu();}); + }, "Exit" : () => load(), }); } menu(); -var answer; + + var answer; function Drawtext(text) { g.clear(); @@ -82,7 +84,6 @@ function WriteAnswer() } } - setWatch(function() { menu(); From d6503cfdd80185d8c7b2785ab91e3b674ff9d179 Mon Sep 17 00:00:00 2001 From: only-meeps <151784194+only-meeps@users.noreply.github.com> Date: Sat, 13 Jul 2024 04:51:49 -0700 Subject: [PATCH 058/110] Update app.js --- apps/boxclk/app.js | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/boxclk/app.js b/apps/boxclk/app.js index 8c29aac14..df3457a09 100644 --- a/apps/boxclk/app.js +++ b/apps/boxclk/app.js @@ -165,7 +165,6 @@ Modules.addCached("widget_utils", function() { }; for (let key in boxesConfig) { if (key === 'bg' && boxesConfig[key].img) { - bgImage = storage.read(boxesConfig[key].img); } else if (key !== 'selectedConfig') { boxes[key] = Object.assign({}, boxesConfig[key]); } From f5b91c1bdd0027912623ff334df65d07eb69bebf Mon Sep 17 00:00:00 2001 From: only-meeps <151784194+only-meeps@users.noreply.github.com> Date: Sat, 13 Jul 2024 04:59:48 -0700 Subject: [PATCH 059/110] Update app.js --- apps/boxclk/app.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/apps/boxclk/app.js b/apps/boxclk/app.js index df3457a09..ed8a62b65 100644 --- a/apps/boxclk/app.js +++ b/apps/boxclk/app.js @@ -163,12 +163,6 @@ Modules.addCached("widget_utils", function() { return this.setFontCustom(E.toString(require('heatshrink').decompress(atob('ABMHwADBh4DKg4bKgIPDAYUfAYV/AYX/AQMD/gmC+ADBn/AByE/GIU8AYUwLxcfAYX/8AnB//4JIP/FgMP4F+CQQBBjwJBFYRbBAd43DHoJpBh/g/xPEK4ZfDgEEORKDDAY8////wADLfZrTCgITBnhEBAYJMBAYMPw4DCM4QDjhwDCjwDBn0+AYMf/gDBh/4AYMH+ADBLpc4ToK/NGYZfnAYcfL4U/x5fBW4LvB/7vC+LvBgHAsBfIn76Cn4WBcYQDFEgJ+CQQYDyH4L/BAZbHLNYjjCAZc8ngDunycBZ4KkBa4KwBnEHY4UB+BfMgf/ZgMH/4XBc4cf4F/gE+ZgRjwAYcfj5jBM4U4M4RQBM4UA8BjIngDFEYJ8BAYUDAYQvCM4ZxBC4V+AYQvBnkBQ4M8gabBJQPAI4WAAYM/GYQaBAYJKCnqyCn5OCn4aBAYIaBAYJPCU4IABnBhIuDXCFAMD+Z/BY4IDBQwOPwEfv6TDAYUPAcwrDAYQ7BAYY/BI4cD8bLCK4RfEAA0BRYTeDcwIrFn0Pw43Bg4DugYDBjxBBU4SvDMYMH/5QBgP/LAQAP8EHN4UPwADHB4YAHA'))), 46, atob("CBEdChgYGhgaGBsaCQ=="), 32 | 65536); }; }; - for (let key in boxesConfig) { - if (key === 'bg' && boxesConfig[key].img) { - } else if (key !== 'selectedConfig') { - boxes[key] = Object.assign({}, boxesConfig[key]); - } - } let boxKeys = Object.keys(boxes); boxKeys.forEach((key) => { let boxConfig = boxes[key]; From 7ae71e95066d108b8acc829423ac3da9945d25da Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Fri, 19 Jul 2024 09:58:01 +0200 Subject: [PATCH 060/110] iconbits: introduce color support --- apps/iconbits/iconbits.app.js | 52 +++++++++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 8 deletions(-) diff --git a/apps/iconbits/iconbits.app.js b/apps/iconbits/iconbits.app.js index 625070dd5..d046bf1df 100644 --- a/apps/iconbits/iconbits.app.js +++ b/apps/iconbits/iconbits.app.js @@ -10,6 +10,7 @@ let kule = [0, 0, 0]; // R, G, B var font_height = 22, font_width = 8; var zoom_x = 64, zoom_y = 24, zoom_f = 6; + var color = true; let oldLock = false; let sg = null; @@ -17,7 +18,7 @@ sg.setColor(1,1,1).fillRect(0,0, font_width, font_height); } - function setup(m) { + function __setup(m) { mode = m; switch (m) { case 'font': @@ -37,10 +38,23 @@ zoom_f = 2; break; } + } + function setup(m) { + __setup(m); sg = Graphics.createArrayBuffer(font_width, font_height, 8, {}); clear(); } + function icon_big() { + zoom_x = 16; + zoom_y = 25; + zoom_f = 3; + } + + function icon_small() { + __setup("icon"); + } + function updateLock() { if (oldLock) { return; @@ -66,7 +80,11 @@ Bangle.on("lock", function() { kule[2] = Math.random(); } function selectColor (x) { - let c; + if (color) { + i = Math.floor((x - 25) / 4); + kule = toColor(i); + return; + } if (x < g.getWidth()/2) { c = 0; } else { @@ -117,6 +135,7 @@ Bangle.on("lock", function() { g.clear(); if (mode == "draw") return; + const w = g.getWidth; g.setColor(0, 0, 0.5); g.fillRect(0, 0, g.getWidth(), g.getHeight()); g.setColor(1, 1, 1); @@ -129,6 +148,16 @@ Bangle.on("lock", function() { update(); } + function toColor(i) { + let r = [0, 0, 0]; + r[0] = (i % 3) / 2; + i = Math.floor(i / 3); + r[1] = (i % 3) / 2; + i = Math.floor(i / 3); + r[2] = (i % 3) / 2; + return r; + } + function drawUtil () { if (Bangle.isLocked()) { updateLock(); @@ -136,6 +165,11 @@ Bangle.on("lock", function() { // titlebar g.setColor(kule[0], kule[1], kule[2]); g.fillRect(0, 0, g.getWidth(), 20); + for (let i = 0; i < 3*3*3; i++) { + r = toColor(i); + g.setColor(r[0], r[1], r[2]); + g.fillRect(25+4*i, 20, 25+4*i+3, 24); + } // clear button g.setColor('#000'); // black g.fillCircle(10, 10, 8, 8); @@ -173,7 +207,7 @@ Bangle.on("lock", function() { var XS = (to.x - from.x) / 32; var YS = (to.y - from.y) / 32; for (let i = 0; i < 32; i++) { - g.fillCircle(from.x + (i * XS), from.y + (i * YS), 4, 4); + g.fillCircle(from.x + (i * XS), from.y + (i * YS), 2, 2); } break; case 'square': @@ -182,7 +216,7 @@ Bangle.on("lock", function() { for (let i = 0; i < 32; i++) { const posX = from.x + (i * XS); const posY = from.y + (i * YS); - g.fillRect(posX - 10, posY - 10, posX + 10, posY + 10); + g.fillRect(posX - 4, posY - 4, posX + 4, posY + 4); } break; } @@ -190,7 +224,7 @@ Bangle.on("lock", function() { } function update() { - g.drawImage(sg, 0, 64, {}); + g.drawImage(sg, 4, 64, {}); g.drawImage(sg, zoom_x, zoom_y, { scale: zoom_f }); } @@ -226,8 +260,9 @@ Bangle.on("lock", function() { oldY = -1; }, 100); + let top_bar = 20; // tap and hold the clear button - if (tap.x < 32 && tap.y < 32) { + if (tap.x < 32 && tap.y < top_bar) { if (tap.b === 1) { if (tapTimer === null) { tapTimer = setTimeout(function () { @@ -244,7 +279,7 @@ Bangle.on("lock", function() { } return; } - if (tap.x > g.getWidth() - 32 && tap.y < 32) { + if (tap.x > g.getWidth() - 32 && tap.y < top_bar) { if (tap.b === 1) { if (tapTimer === null) { tapTimer = setTimeout(function () { @@ -264,7 +299,7 @@ Bangle.on("lock", function() { } drawUtil(); return; - } else if (tap.y < 32) { + } else if (tap.y < top_bar) { if (mode == "draw") nextColor(); else @@ -308,6 +343,7 @@ Bangle.on("lock", function() { //print("wh", im, typeof im, im[0], typeof im[0]); //print("Image:", im.length, s); print('fi("'+btoa(im)+'");'); + print(btoa(require('heatshrink').compress(im))); } From aedb898177876ff8bca37c5674c741c7b63f1dbd Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Fri, 19 Jul 2024 10:04:32 +0200 Subject: [PATCH 061/110] iconbits: cleanups. --- apps/iconbits/iconbits.app.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/apps/iconbits/iconbits.app.js b/apps/iconbits/iconbits.app.js index d046bf1df..d40cc0285 100644 --- a/apps/iconbits/iconbits.app.js +++ b/apps/iconbits/iconbits.app.js @@ -194,6 +194,9 @@ Bangle.on("lock", function() { } function __draw (g, from, to) { + let XS = (to.x - from.x) / 32; + let YS = (to.y - from.y) / 32; + switch (pen) { case 'pixel': g.drawLine(from.x, from.y, to.x, to.y); @@ -204,15 +207,11 @@ Bangle.on("lock", function() { g.drawLine(from.x + 2, from.y + 2, to.x, to.y + 2); break; case 'circle': - var XS = (to.x - from.x) / 32; - var YS = (to.y - from.y) / 32; for (let i = 0; i < 32; i++) { g.fillCircle(from.x + (i * XS), from.y + (i * YS), 2, 2); } break; case 'square': - var XS = (to.x - from.x) / 32; - var YS = (to.y - from.y) / 32; for (let i = 0; i < 32; i++) { const posX = from.x + (i * XS); const posY = from.y + (i * YS); @@ -220,7 +219,6 @@ Bangle.on("lock", function() { } break; } - } function update() { From 9697902e40bee4f32dc25a75fb387a4c1e99fb0e Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Fri, 19 Jul 2024 10:12:57 +0200 Subject: [PATCH 062/110] iconbits: cleanups, finish color selector --- apps/iconbits/iconbits.app.js | 37 ++++++++++++++++------------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/apps/iconbits/iconbits.app.js b/apps/iconbits/iconbits.app.js index d40cc0285..b5f26d4df 100644 --- a/apps/iconbits/iconbits.app.js +++ b/apps/iconbits/iconbits.app.js @@ -13,6 +13,7 @@ var color = true; let oldLock = false; let sg = null; + const top_bar = 20; function clear(m) { sg.setColor(1,1,1).fillRect(0,0, font_width, font_height); @@ -61,9 +62,9 @@ } g.setColor('#fff'); g.fillRect(0, 0, g.getWidth(), 20); - g.setFont('6x8', 2); + g.setFont('Vector', 22); g.setColor('#000'); - g.drawString('PLEASE UNLOCK', 10, 2); + g.drawString('PLEASE\nUNLOCK', 10, 2); oldLock = true; } Bangle.on("lock", function() { @@ -74,14 +75,14 @@ Bangle.on("lock", function() { drawUtil(); } }); - function nextColor () { + function nextColor() { kule[0] = Math.random(); kule[1] = Math.random(); kule[2] = Math.random(); } - function selectColor (x) { + function selectColor(x) { if (color) { - i = Math.floor((x - 25) / 4); + i = Math.floor((x - 32) / 4); kule = toColor(i); return; } @@ -131,7 +132,7 @@ Bangle.on("lock", function() { } } - function drawArea () { + function drawArea() { g.clear(); if (mode == "draw") return; @@ -158,17 +159,17 @@ Bangle.on("lock", function() { return r; } - function drawUtil () { + function drawUtil() { if (Bangle.isLocked()) { updateLock(); } // titlebar g.setColor(kule[0], kule[1], kule[2]); - g.fillRect(0, 0, g.getWidth(), 20); + g.fillRect(0, 0, g.getWidth(), top_bar); for (let i = 0; i < 3*3*3; i++) { r = toColor(i); g.setColor(r[0], r[1], r[2]); - g.fillRect(25+4*i, 20, 25+4*i+3, 24); + g.fillRect(32+4*i, 12, 32+4*i+3, top_bar); } // clear button g.setColor('#000'); // black @@ -183,7 +184,7 @@ Bangle.on("lock", function() { drawBrushIcon(); } - function transform (p) { + function transform(p) { if (p.x < zoom_x || p.y < zoom_y) return p; p.x = ((p.x - zoom_x) / zoom_f); @@ -193,7 +194,7 @@ Bangle.on("lock", function() { return p; } - function __draw (g, from, to) { + function __draw(g, from, to) { let XS = (to.x - from.x) / 32; let YS = (to.y - from.y) / 32; @@ -258,7 +259,6 @@ Bangle.on("lock", function() { oldY = -1; }, 100); - let top_bar = 20; // tap and hold the clear button if (tap.x < 32 && tap.y < top_bar) { if (tap.b === 1) { @@ -343,19 +343,16 @@ Bangle.on("lock", function() { print('fi("'+btoa(im)+'");'); print(btoa(require('heatshrink').compress(im))); } - - } - setup("icon"); - drawArea(); - Bangle.setUI({ +setup("icon"); +drawArea(); +Bangle.setUI({ "mode": "custom", "drag": on_drag, "btn": on_btn, - }); - drawUtil(); - +}); +drawUtil(); function ft(icon) { g.reset().clear(); From 5cc09c832d21147f4b203868a7189db88fa60675 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Fri, 19 Jul 2024 10:31:08 +0200 Subject: [PATCH 063/110] iconbits: cleanup preview functions --- apps/iconbits/iconbits.app.js | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/apps/iconbits/iconbits.app.js b/apps/iconbits/iconbits.app.js index b5f26d4df..bb99e7c34 100644 --- a/apps/iconbits/iconbits.app.js +++ b/apps/iconbits/iconbits.app.js @@ -330,18 +330,15 @@ Bangle.on("lock", function() { s += f(v); } print("Manual bitmap\n"); - print('ft("' + s + '");'); + print('show_font("' + s + '");'); if (1) { s = ""; var im = sg.asImage("string"); for (var v of im) { - //print("val", v, typeof v); s += f(v); } - //print("wh", im, typeof im, im[0], typeof im[0]); - //print("Image:", im.length, s); - print('fi("'+btoa(im)+'");'); - print(btoa(require('heatshrink').compress(im))); + //print('show_unc_icon("'+btoa(im)+'");'); + print('show_icon("'+btoa(require('heatshrink').compress(im))+'");'); } } @@ -354,14 +351,22 @@ Bangle.setUI({ }); drawUtil(); -function ft(icon) { +function show_font(icon) { g.reset().clear(); g.setFont("Vector", 26).drawString("Hellord" + icon, 0, 0); } -function fi(icon) { +function show_bin_icon(icon) { g.reset().clear(); - g.drawImage(atob(icon), 40, 40); + g.drawImage(icon, 40, 40); +} + +function show_unc_icon(icon) { + show_bin_icon(atob(icon)); +} + +function show_icon(icon) { + unc = require("heatshrink").decompress(atob(icon)); + show_bin_icon(unc); } -//ft(icon_10 + "23.1" + icon_hpa); From 24ebb8a583e70e0125e1e35a05fac3b9e612d006 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Fri, 19 Jul 2024 11:13:32 +0200 Subject: [PATCH 064/110] iconbits: update png icon --- apps/iconbits/app.png | Bin 2459 -> 2010 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/apps/iconbits/app.png b/apps/iconbits/app.png index 7a3ee2e90600531bd4df39ad517637ecdc854745..d4e822ac7d47958ae769d3f09024801c10b8dc62 100644 GIT binary patch literal 2010 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 MB_Pzll? Date: Fri, 19 Jul 2024 11:14:18 +0200 Subject: [PATCH 065/110] iconbits: add loading/preview functions --- apps/iconbits/iconbits.app.js | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/apps/iconbits/iconbits.app.js b/apps/iconbits/iconbits.app.js index bb99e7c34..2be08e3d4 100644 --- a/apps/iconbits/iconbits.app.js +++ b/apps/iconbits/iconbits.app.js @@ -223,7 +223,8 @@ Bangle.on("lock", function() { } function update() { - g.drawImage(sg, 4, 64, {}); + if (zoom_f < 3) + g.drawImage(sg, 4, 64, {}); g.drawImage(sg, zoom_x, zoom_y, { scale: zoom_f }); } @@ -370,3 +371,20 @@ function show_icon(icon) { show_bin_icon(unc); } +function load_bin_icon(i) { + sg.reset().clear(); + sg.drawImage(i, 0, 0); + drawArea(); +} + +function load_icon(icon) { + unc = require("heatshrink").decompress(atob(icon)); + load_bin_icon(unc); +} + +function for_screen() { + g.reset().clear(); + icon_big(); + update(); +} + From b51a85657628dfb19aaa6b59d7cd701760b78dc9 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Fri, 19 Jul 2024 11:48:02 +0200 Subject: [PATCH 066/110] iconbits: cleanups, implement line drawing. --- apps/iconbits/iconbits.app.js | 53 ++++++++++++++++++++++------------- 1 file changed, 33 insertions(+), 20 deletions(-) diff --git a/apps/iconbits/iconbits.app.js b/apps/iconbits/iconbits.app.js index 2be08e3d4..1777a8af3 100644 --- a/apps/iconbits/iconbits.app.js +++ b/apps/iconbits/iconbits.app.js @@ -98,8 +98,8 @@ Bangle.on("lock", function() { function nextPen () { switch (pen) { case 'circle': pen = 'pixel'; break; - case 'pixel': pen = 'crayon'; break; - case 'crayon': pen = 'square'; break; + case 'pixel': pen = 'line'; break; + case 'line': pen = 'square'; break; case 'square': pen = 'circle'; break; default: pen = 'pixel'; break; } @@ -108,8 +108,8 @@ Bangle.on("lock", function() { discard = setTimeout(function () { oldX = -1; oldY = -1; console.log('timeout'); discard = null; }, 500); } - var oldX = -1; - var oldY = -1; + var oldX = -1, oldY = -1; + var line_from = null; function drawBrushIcon () { const w = g.getWidth(); @@ -129,6 +129,9 @@ Bangle.on("lock", function() { g.drawLine(w - 14, 6, w - 10, 12); g.drawLine(w - 6, 6, w - 10, 12); break; + case 'line': + g.drawLine(w - 5, 5, w - 15, 15); + break; } } @@ -199,6 +202,7 @@ Bangle.on("lock", function() { let YS = (to.y - from.y) / 32; switch (pen) { + case 'line': case 'pixel': g.drawLine(from.x, from.y, to.x, to.y); break; @@ -219,6 +223,8 @@ Bangle.on("lock", function() { g.fillRect(posX - 4, posY - 4, posX + 4, posY + 4); } break; + default: + print("Unkown pen ", pen); } } @@ -229,9 +235,11 @@ Bangle.on("lock", function() { } function do_draw(from, to) { + print("do-draw", from, to); from = transform(from); to = transform(to); if (from && to) { + print("__draw", from, to); __draw(sg, from, to); } update(); @@ -306,20 +314,31 @@ Bangle.on("lock", function() { drawUtil(); return; } - oldX = to.x; - oldY = to.y; sg.setColor(kule[0], kule[1], kule[2]); g.setColor(kule[0], kule[1], kule[2]); + oldX = to.x; + oldY = to.y; - do_draw(from, to); + if (pen != "line") { + do_draw(from, to); + } else { + if (tap.b == 1) { + print(line_from); + if (!line_from) { + line_from = to; + } else { + print("draw -- ", line_from, to); + do_draw(line_from, to); + line_from = null; + } + } + } drawUtil(); } function on_btn(n) { function f(i) { return "\\x" + i.toString(16).padStart(2, '0'); } - print("on_btn", n); - print(g.getPixel(0, 0)); let s = f(0) + f(font_width) + f(font_height) + f(1); // 0..black, 65535..white for (let y = 0; y < font_height; y++) { @@ -330,17 +349,11 @@ Bangle.on("lock", function() { } s += f(v); } - print("Manual bitmap\n"); - print('show_font("' + s + '");'); - if (1) { - s = ""; - var im = sg.asImage("string"); - for (var v of im) { - s += f(v); - } - //print('show_unc_icon("'+btoa(im)+'");'); - print('show_icon("'+btoa(require('heatshrink').compress(im))+'");'); - } + if (mode == "font") + print('show_font("' + s + '");'); + var im = sg.asImage("string"); + //print('show_unc_icon("'+btoa(im)+'");'); + print('show_icon("'+btoa(require('heatshrink').compress(im))+'");'); } setup("icon"); From 62cb337105f4ec196d6c1b6b7f8678de3bdc0a19 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Fri, 19 Jul 2024 13:29:25 +0200 Subject: [PATCH 067/110] iconbits: cleanups, add documentation. --- apps/iconbits/README.md | 17 +++++++++++++++-- apps/iconbits/iconbits.app.js | 8 +++----- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/apps/iconbits/README.md b/apps/iconbits/README.md index c5c524ab0..90bc0f5a3 100644 --- a/apps/iconbits/README.md +++ b/apps/iconbits/README.md @@ -3,5 +3,18 @@ Bitmap editor suitable for creating icons and fonts for BangleJS2. You'll want to run a copy of this in simulator, and another one on -watch to view the results. Draw using the provided tools, then press -the button, and you'll get result on the console. +watch to view the results. + +Draw using the provided tools, then press the button, and you'll get +result on the console; you can also use "dump();" on command +line. show_icon() takes same parameter as is used in app-icon.js +files, you can just copy&paste it to get an icon. By using +"for_screen();" command, then taking a screenshot, you can easily +generate app.png file. + +It is also possible to load existing icon into editor, using +"load_icon("");" command. At the end of iconbits.app.js file there are +more utility functions. + + + diff --git a/apps/iconbits/iconbits.app.js b/apps/iconbits/iconbits.app.js index 1777a8af3..83eb8ee89 100644 --- a/apps/iconbits/iconbits.app.js +++ b/apps/iconbits/iconbits.app.js @@ -235,11 +235,9 @@ Bangle.on("lock", function() { } function do_draw(from, to) { - print("do-draw", from, to); from = transform(from); to = transform(to); if (from && to) { - print("__draw", from, to); __draw(sg, from, to); } update(); @@ -327,7 +325,6 @@ Bangle.on("lock", function() { if (!line_from) { line_from = to; } else { - print("draw -- ", line_from, to); do_draw(line_from, to); line_from = null; } @@ -335,7 +332,8 @@ Bangle.on("lock", function() { } drawUtil(); } - function on_btn(n) { + +function dump(n) { function f(i) { return "\\x" + i.toString(16).padStart(2, '0'); } @@ -361,7 +359,7 @@ drawArea(); Bangle.setUI({ "mode": "custom", "drag": on_drag, - "btn": on_btn, + "btn": dump, }); drawUtil(); From 4561572aad3de1aee941e6da990e4acacd9e9b48 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Fri, 19 Jul 2024 21:50:37 +0200 Subject: [PATCH 068/110] iconbits: mark this as version 0.02. --- apps/iconbits/ChangeLog | 1 + apps/iconbits/metadata.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/iconbits/ChangeLog b/apps/iconbits/ChangeLog index 263d4078d..10f5d311c 100644 --- a/apps/iconbits/ChangeLog +++ b/apps/iconbits/ChangeLog @@ -1 +1,2 @@ 0.01: attempt to import +0.02: implement colors and lines diff --git a/apps/iconbits/metadata.json b/apps/iconbits/metadata.json index b98a43953..edb4b4d6a 100644 --- a/apps/iconbits/metadata.json +++ b/apps/iconbits/metadata.json @@ -1,6 +1,6 @@ { "id": "iconbits", "name": "Icon bits", - "version": "0.01", + "version": "0.02", "description": "Bitmap editor suitable for creating icons", "icon": "app.png", "readme": "README.md", From 9ae99c5cf2529cec89642a4a8e49945fa5c29972 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Sat, 11 Nov 2023 12:28:57 +0100 Subject: [PATCH 069/110] [] settings: cleanups, go to full brightness. --- 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 c5149ab5a..94c8e26a7 100644 --- a/apps/setting/settings.js +++ b/apps/setting/settings.js @@ -651,11 +651,11 @@ function showUtilMenu() { E.showMessage(/*LANG*/'Flattening battery - this can take hours.\nLong-press button to cancel.'); Bangle.setLCDTimeout(0); Bangle.setLCDPower(1); + Bangle.setLCDBrightness(1); if (Bangle.setGPSPower) Bangle.setGPSPower(1,"flat"); if (Bangle.setHRMPower) Bangle.setHRMPower(1,"flat"); if (Bangle.setCompassPower) Bangle.setCompassPower(1,"flat"); if (Bangle.setBarometerPower) Bangle.setBarometerPower(1,"flat"); - if (Bangle.setHRMPower) Bangle.setGPSPower(1,"flat"); setInterval(function() { var i=1000;while (i--); }, 1); From 1c6928ae60b9d5f17fb2499205f272cef75e8309 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Fri, 19 Jul 2024 22:12:44 +0200 Subject: [PATCH 070/110] settings: fix whitespace --- 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 94c8e26a7..d9d77d052 100644 --- a/apps/setting/settings.js +++ b/apps/setting/settings.js @@ -651,7 +651,7 @@ function showUtilMenu() { E.showMessage(/*LANG*/'Flattening battery - this can take hours.\nLong-press button to cancel.'); Bangle.setLCDTimeout(0); Bangle.setLCDPower(1); - Bangle.setLCDBrightness(1); + Bangle.setLCDBrightness(1); if (Bangle.setGPSPower) Bangle.setGPSPower(1,"flat"); if (Bangle.setHRMPower) Bangle.setHRMPower(1,"flat"); if (Bangle.setCompassPower) Bangle.setCompassPower(1,"flat"); From d85ec84ae32d35405eaaf27e9dc781e9660c14b1 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Fri, 19 Jul 2024 22:01:24 +0200 Subject: [PATCH 071/110] iconbits: fix warnings. --- apps/iconbits/iconbits.app.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/apps/iconbits/iconbits.app.js b/apps/iconbits/iconbits.app.js index 83eb8ee89..5fc10423c 100644 --- a/apps/iconbits/iconbits.app.js +++ b/apps/iconbits/iconbits.app.js @@ -82,14 +82,13 @@ Bangle.on("lock", function() { } function selectColor(x) { if (color) { - i = Math.floor((x - 32) / 4); + let i = Math.floor((x - 32) / 4); kule = toColor(i); return; } + let c = 255; if (x < g.getWidth()/2) { c = 0; - } else { - c = 255; } kule[0] = c; kule[1] = c; @@ -170,7 +169,7 @@ Bangle.on("lock", function() { g.setColor(kule[0], kule[1], kule[2]); g.fillRect(0, 0, g.getWidth(), top_bar); for (let i = 0; i < 3*3*3; i++) { - r = toColor(i); + let r = toColor(i); g.setColor(r[0], r[1], r[2]); g.fillRect(32+4*i, 12, 32+4*i+3, top_bar); } @@ -378,7 +377,7 @@ function show_unc_icon(icon) { } function show_icon(icon) { - unc = require("heatshrink").decompress(atob(icon)); + let unc = require("heatshrink").decompress(atob(icon)); show_bin_icon(unc); } @@ -389,7 +388,7 @@ function load_bin_icon(i) { } function load_icon(icon) { - unc = require("heatshrink").decompress(atob(icon)); + let unc = require("heatshrink").decompress(atob(icon)); load_bin_icon(unc); } From f520a8ae7b0fc16c28fa1c8c0727168b46c0b5a2 Mon Sep 17 00:00:00 2001 From: Ian Ward Date: Sat, 20 Jul 2024 18:56:34 +0100 Subject: [PATCH 072/110] initial commit --- apps/quarterclock/app-icon.js | 1 + apps/quarterclock/app.js | 139 +++++++++++++++++++++++++++++++ apps/quarterclock/app.png | Bin 0 -> 252 bytes apps/quarterclock/metadata.json | 20 +++++ apps/quarterclock/screenshot.png | Bin 0 -> 1475 bytes apps/quarterclock/settings.js | 66 +++++++++++++++ 6 files changed, 226 insertions(+) create mode 100644 apps/quarterclock/app-icon.js create mode 100644 apps/quarterclock/app.js create mode 100644 apps/quarterclock/app.png create mode 100644 apps/quarterclock/metadata.json create mode 100644 apps/quarterclock/screenshot.png create mode 100644 apps/quarterclock/settings.js diff --git a/apps/quarterclock/app-icon.js b/apps/quarterclock/app-icon.js new file mode 100644 index 000000000..d6ed783ec --- /dev/null +++ b/apps/quarterclock/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEw4X/AwX48AFCqoAEC4oL/Bf4L/Bf4LTAH4A/ADGqAAIL/Bf4LD")) diff --git a/apps/quarterclock/app.js b/apps/quarterclock/app.js new file mode 100644 index 000000000..da7efed16 --- /dev/null +++ b/apps/quarterclock/app.js @@ -0,0 +1,139 @@ +{ + const minute_boxes = [ + {x:0.5, y:0}, + {x:0.5, y:0.5}, + {x:0, y:0.5}, + {x:0, y:0}, + ]; + + const hour_boxes = [ + {x:0.5, y:0}, + {x:0.75, y:0}, + {x:0.75, y:0.25}, + {x:0.75, y:0.5}, + {x:0.75, y:0.75}, + {x:0.5, y:0.75}, + {x:0.25, y:0.75}, + {x:0, y:0.75}, + {x:0, y:0.5}, + {x:0, y:0.25}, + {x:0, y:0}, + {x:0.25, y:0}, + ]; + + let drawTimeout; + + // schedule a draw for the next 15 minute period + let queueDraw = function queueDraw() { + if (drawTimeout) clearTimeout(drawTimeout); + drawTimeout = setTimeout(function() { + drawTimeout = undefined; + draw(); + }, (60000 * 15) - (Date.now() % (60000 * 15))); + }; + + // Main draw function + let draw = function draw() { + var d = new Date(); + var h = d.getHours(), m = d.getMinutes(); + + g.setBgColor(settings.backgroundColour); + g.clearRect(Bangle.appRect); + + if (settings.showBattery) { + drawBattery(); + } + + // Draw minute box + drawBox(Math.floor(m/15), minute_boxes, Bangle.appRect.h/2, settings.minuteColour); + + // Draw an hour box or write the number + if (settings.digital) { + g.setColor(settings.hourColour); + g.setFont("Vector:60"); + g.setFontAlign(0,0); + g.drawString(h, Bangle.appRect.x + Bangle.appRect.w/2, Bangle.appRect.y + Bangle.appRect.h/2); + } else { + drawBox(h % 12, hour_boxes, Bangle.appRect.h/4, settings.hourColour); + } + + queueDraw(); + }; + + // Draw battery box + let drawBattery = function drawBattery() { + // Round battery up to 10% interval + let battery = (Math.floor(E.getBattery()/10)+1)/10; + + // Maximum battery box + let batterySize = 30; + + // Draw outer box at full brightness + g.setColor(settings.batteryColour); + g.drawRect( + (Bangle.appRect.w / 2) - batterySize, + (Bangle.appRect.h / 2) - batterySize + Bangle.appRect.y, + (Bangle.appRect.w / 2) + batterySize, + (Bangle.appRect.h / 2) + batterySize + Bangle.appRect.y + ); + + // Fade battery colour and draw inner box + g.setColor(settings.batteryColour.split('').map((c) => { + return c=='f' ? Math.ceil(15 * battery).toString(16) : c; + }).join('')); + g.fillRect( + (Bangle.appRect.w / 2) - (batterySize * battery), + (Bangle.appRect.h / 2) - (batterySize * battery) + Bangle.appRect.y, + (Bangle.appRect.w / 2) + (batterySize * battery), + (Bangle.appRect.h / 2) + (batterySize * battery) + Bangle.appRect.y + ); + }; + + // Draw hour or minute boxes + let drawBox = function drawBox(current, boxes, size, colour) { + x1 = (boxes[current].x * Bangle.appRect.h) + (Bangle.appRect.y/2); + y1 = (boxes[current].y * Bangle.appRect.h) + Bangle.appRect.y; + x2 = x1 + size; + y2 = y1 + size; + g.setColor(colour); + g.fillRect(x1, y1, x2, y2); + }; + + let settings = Object.assign({ + // Default values + minuteColour: '#f00', + hourColour: '#ff0', + backgroundColour: 'theme', + showWidgets: true, + showBattery: true, + digital: false, + batteryColour: '#0f0' + }, require('Storage').readJSON('quarterclock.json', true) || {}); + + if (settings.backgroundColour == 'theme') { + settings.backgroundColour = g.theme.bg; + } + + // Set minuteColour to a darker shade if same as hourColour + if (settings.minuteColour == settings.hourColour) { + settings.minuteColour = settings.minuteColour.split('').map((c) => { + return c=='f' ? '7' : c; + }).join(''); + } + + // Show launcher when middle button pressed + // Remove handler to allow fast loading + Bangle.setUI({mode:"clock", remove:function() { + if (drawTimeout) clearTimeout(drawTimeout); + }}); + + // Load and display widgets + if (settings.showWidgets) { + Bangle.loadWidgets(); + Bangle.drawWidgets(); + } + + // draw initial boxes and queue subsequent redraws + draw(); +} + diff --git a/apps/quarterclock/app.png b/apps/quarterclock/app.png new file mode 100644 index 0000000000000000000000000000000000000000..e2a1c7fc0db4e32f7602bbb68af544cf5a7b665b GIT binary patch literal 252 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA1|-9oezpTC#^NA%Cx&(BWL^R}TRdGHLo%G- z&T!;vFyLXi{oj7qC4P&R6vu)+%h-%}OE3AorZnus&4c&0e=TEBSi{8P!7Zrh{KxNr zt_xowci^!*PA(lb*VafUF=cd|T+}v$W8(2yrOrMKyoQli1cVhoMQqON;7qVNqFtl! z!d&)RJm5>x>feoD_Av`AEQw{k)Ut9v7YgfdG1r_&{k_aS(JrjZI>UaibeMYMOQq-x owWzntnL?8;Kd)bYfZ1YM{L6~#HK{=NGkCiCxvXFWXG+iEl@n0-z_3Z#iizdjjafDd4i6Yp+)G$E?rb!zbZ9uhe4_6Khro{H>`x60 zjqDR-FA6FY9KZI2k&%gC!FrLh!-KxHCz+X8f?+~=;!N>H?{lAm%%koY32m1B0*|UBBl^hbBWPBSAxUWC|l=DpE zVore{FTU=yX|yabVPuluYd2lpfW1%6;lbkT&p)v|J8+SOqvp%6n0W_eEM^^e&GDxz zKe8(4`|SEX(+=owxWFGTe}9AihbqoLvD~f?^0(a-k6gi2Z=4^WyKw!tDqE)?ZML%* z8vEn!t52_==&r^j{3C;j#jdKB%O`_pLjc9`&ZhY`x%h%l`R4-Ce8W-rv8c{I80&j;%oV zqj7oA1ML-eD~^S_u6nxn*F5vMlcM3l57ITR3E3B`v+irU)tep@yKT33&DGa?KYGc7 zZD)K|JYwMBocTO6A5WSLT^Z3=KyRnae z7WRg}lKgS=>7CfP^9Ro70d`FNq7(`FoKKD+OPAlDt;C}5(KpDeng+2=vu+x*7s{ru~{1atiF ze9as7pl>5E5sFqE`Sy{2PXB}krt$*O9m%T?C~xDEX%2h9w*ev>)|h;O>kcDO`C6v_ z8(IZCzr6n?Ec@C{{34pso+?BU%-R)3;x-j4|$Ncp6kxW&6A6U$I^uK-60p>3( z?-Yc0B>&!e{y_8f(spGIn;T6` labels[v], + min: 0, + max: values.length - 1, + wrap: true, + step: 1, + onchange: v => { + setSetting(key,values[v]); + } + }; + } + + // Helper method which breaks string set settings down to local settings object + function stringInSettings(name, values, labels) { + return stringItems(name,settings[name], values, labels); + } + + // Show the menu + E.showMenu({ + '' : { 'title' : 'Quarter Clock' }, + '< Back' : () => back(), + 'Hour Colour': stringInSettings('hourColour', ['#f00', '#0f0', '#00f', '#ff0', '#0ff', '#f0f'], ['Red', 'Green', 'Blue', 'Yellow', 'Cyan', 'Magenta']), + 'Minute Colour': stringInSettings('minuteColour', ['#f00', '#0f0', '#00f', '#ff0', '#0ff', '#f0f'], ['Red', 'Green', 'Blue', 'Yellow', 'Cyan', 'Magenta']), + 'Background Colour': stringInSettings('backgroundColour', ['theme', '#000', '#fff'],['theme', 'Black', 'White']), + 'Digital': { + value: !!settings.digital, // !! converts undefined to false + onchange: v => { + setSetting('digital', v); + }, + }, + 'Show Widgets': { + value: !!settings.showWidgets, + onchange: v => { + setSetting('showWidgets', v); + }, + }, + 'Show Battery': { + value: !!settings.showBattery, + onchange: v => { + setSetting('showBattery', v); + }, + }, + 'Battery Colour': stringInSettings('batteryColour', ['#f00', '#0f0', '#00f', '#ff0', '#0ff', '#f0f'], ['Red', 'Green', 'Blue', 'Yellow', 'Cyan', 'Magenta']), + }); +}) From 2b6839bedbee413e577802b9581b7a0d02ea09f5 Mon Sep 17 00:00:00 2001 From: Ian Ward Date: Sat, 20 Jul 2024 19:52:36 +0100 Subject: [PATCH 073/110] define variables --- apps/quarterclock/app.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/quarterclock/app.js b/apps/quarterclock/app.js index da7efed16..837cac6b6 100644 --- a/apps/quarterclock/app.js +++ b/apps/quarterclock/app.js @@ -91,10 +91,10 @@ // Draw hour or minute boxes let drawBox = function drawBox(current, boxes, size, colour) { - x1 = (boxes[current].x * Bangle.appRect.h) + (Bangle.appRect.y/2); - y1 = (boxes[current].y * Bangle.appRect.h) + Bangle.appRect.y; - x2 = x1 + size; - y2 = y1 + size; + let x1 = (boxes[current].x * Bangle.appRect.h) + (Bangle.appRect.y/2); + let y1 = (boxes[current].y * Bangle.appRect.h) + Bangle.appRect.y; + let x2 = x1 + size; + let y2 = y1 + size; g.setColor(colour); g.fillRect(x1, y1, x2, y2); }; From ec9bc29295b7935bffbc8b18d8d88e135902ce8b Mon Sep 17 00:00:00 2001 From: Ian Ward Date: Sun, 21 Jul 2024 19:05:12 +0100 Subject: [PATCH 074/110] Correctly handle hiding/showing widgets --- apps/quarterclock/app.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/apps/quarterclock/app.js b/apps/quarterclock/app.js index 837cac6b6..7899ff2c7 100644 --- a/apps/quarterclock/app.js +++ b/apps/quarterclock/app.js @@ -125,12 +125,15 @@ // Remove handler to allow fast loading Bangle.setUI({mode:"clock", remove:function() { if (drawTimeout) clearTimeout(drawTimeout); + require("widget_utils").show(); }}); // Load and display widgets + Bangle.loadWidgets(); if (settings.showWidgets) { - Bangle.loadWidgets(); - Bangle.drawWidgets(); + require("widget_utils").show(); + } else { + require("widget_utils").hide(); } // draw initial boxes and queue subsequent redraws From 7e5c67a2b6041f5822cec42e901cf54ace762605 Mon Sep 17 00:00:00 2001 From: Ian Ward Date: Tue, 23 Jul 2024 09:16:11 +0100 Subject: [PATCH 075/110] fix bug with 100% battery --- apps/quarterclock/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/quarterclock/app.js b/apps/quarterclock/app.js index 7899ff2c7..a668860cd 100644 --- a/apps/quarterclock/app.js +++ b/apps/quarterclock/app.js @@ -63,7 +63,7 @@ // Draw battery box let drawBattery = function drawBattery() { // Round battery up to 10% interval - let battery = (Math.floor(E.getBattery()/10)+1)/10; + let battery = Math.min((Math.floor(E.getBattery()/10)+1)/10, 1); // Maximum battery box let batterySize = 30; From 3e10fff37325b29652e1bed507d741bb8885be93 Mon Sep 17 00:00:00 2001 From: Alexander Minges Date: Wed, 24 Jul 2024 13:54:47 +0200 Subject: [PATCH 076/110] use weather codes if language is not English --- apps/ffcniftyapp/app.js | 43 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/apps/ffcniftyapp/app.js b/apps/ffcniftyapp/app.js index 840dd72ff..517c0e2c5 100644 --- a/apps/ffcniftyapp/app.js +++ b/apps/ffcniftyapp/app.js @@ -1,5 +1,5 @@ const w = require("weather"); -//const locale = require("locale"); +const locale = require("locale"); // Weather icons from https://icons8.com/icon/set/weather/color function getSun() { @@ -67,6 +67,33 @@ function chooseIcon(condition) { return getPartSun; } else return getErr; } + +/* +* Choose weather icon to display based on weather conditition code +* https://openweathermap.org/weather-conditions#Weather-Condition-Codes-2 +*/ +function chooseIconByCode(code) { + const codeGroup = Math.round(code / 100); + switch (codeGroup) { + case 2: return getStorm; + case 3: return getRain; + case 5: + switch (code) { + case 511: return getSnow; + default: return getRain; + } + case 6: return getSnow; + case 7: return getPartSun; + case 8: + switch (code) { + case 800: return getSun; + case 804: return getCloud; + default: return getPartSun; + } + default: return getCloud; + } +} + /*function condenseWeather(condition) { condition = condition.toLowerCase(); if (condition.includes("thunderstorm") || @@ -143,8 +170,18 @@ const clock = new ClockFace({ //let cWea =(curr === "no data" ? "no data" : curr.txt); let cTemp= (curr === "no data" ? 273 : curr.temp); // const temp = locale.temp(curr.temp - 273.15).match(/^(\D*\d*)(.*)$/); - let w_icon = chooseIcon(curr.txt === undefined ? "no data" : curr.txt ); - //let w_icon = chooseIcon(curr.txt); + + if (locale == "en" || locale == "en_GB" || locale == "en_US") { + let w_icon = chooseIcon(curr.txt === undefined ? "no data" : curr.txt); + } else { + // cannot use condition string to determine icon of language is not English; use weather code instead + const code = curr.code || -1; + if (code > 0) { + let w_icon = chooseIconByCode(curr.code); + } else { + let w_icon = getErr(); + } + } g.setFontAlign(1, 0).setFont("Vector", 90 * this.scale); g.drawString(format(hour), this.centerTimeScaleX, this.center.y - 31 * this.scale); From 1a3c94579d38018c5c0811eb56dea3e8e6df69d0 Mon Sep 17 00:00:00 2001 From: Alexander Minges Date: Wed, 24 Jul 2024 14:15:32 +0200 Subject: [PATCH 077/110] fix setting icon based on weather code --- apps/ffcniftyapp/app.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/apps/ffcniftyapp/app.js b/apps/ffcniftyapp/app.js index 517c0e2c5..4a11caca6 100644 --- a/apps/ffcniftyapp/app.js +++ b/apps/ffcniftyapp/app.js @@ -171,15 +171,14 @@ const clock = new ClockFace({ let cTemp= (curr === "no data" ? 273 : curr.temp); // const temp = locale.temp(curr.temp - 273.15).match(/^(\D*\d*)(.*)$/); - if (locale == "en" || locale == "en_GB" || locale == "en_US") { - let w_icon = chooseIcon(curr.txt === undefined ? "no data" : curr.txt); + let w_icon = getErr; + if (locale.name === "en" || locale.name === "en_GB" || locale.name === "en_US") { + w_icon = chooseIcon(curr.txt === undefined ? "no data" : curr.txt); } else { - // cannot use condition string to determine icon of language is not English; use weather code instead + // cannot use condition string to determine icon of language is not English; use weather code instead const code = curr.code || -1; if (code > 0) { - let w_icon = chooseIconByCode(curr.code); - } else { - let w_icon = getErr(); + w_icon = chooseIconByCode(curr.code); } } From 883958dc50360c2d736e90df0b1e0bfeba871682 Mon Sep 17 00:00:00 2001 From: Alexander Minges Date: Wed, 24 Jul 2024 14:21:15 +0200 Subject: [PATCH 078/110] update metadata and changelog --- apps/ffcniftyapp/ChangeLog | 1 + apps/ffcniftyapp/metadata.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/ffcniftyapp/ChangeLog b/apps/ffcniftyapp/ChangeLog index 30dcec467..ef797827e 100644 --- a/apps/ffcniftyapp/ChangeLog +++ b/apps/ffcniftyapp/ChangeLog @@ -1,3 +1,4 @@ 0.01: New Clock Nifty A ++ >> adding more information on the right side of the clock +0.02: Fix weather icon for languages other than English diff --git a/apps/ffcniftyapp/metadata.json b/apps/ffcniftyapp/metadata.json index bbe8e7e69..6f368160b 100644 --- a/apps/ffcniftyapp/metadata.json +++ b/apps/ffcniftyapp/metadata.json @@ -1,7 +1,7 @@ { "id": "ffcniftyapp", "name": "Nifty-A Clock ++", - "version": "0.01", + "version": "0.02", "description": "A nifty clock with time and date and more", "dependencies": {"weather":"app"}, "icon": "app.png", From e9d2478e8117aee2eedc310d58ff7e21da8928f5 Mon Sep 17 00:00:00 2001 From: Alexander Minges Date: Wed, 24 Jul 2024 14:23:11 +0200 Subject: [PATCH 079/110] fix typo in comment --- apps/ffcniftyapp/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/ffcniftyapp/app.js b/apps/ffcniftyapp/app.js index 4a11caca6..5ca48c2f1 100644 --- a/apps/ffcniftyapp/app.js +++ b/apps/ffcniftyapp/app.js @@ -175,7 +175,7 @@ const clock = new ClockFace({ if (locale.name === "en" || locale.name === "en_GB" || locale.name === "en_US") { w_icon = chooseIcon(curr.txt === undefined ? "no data" : curr.txt); } else { - // cannot use condition string to determine icon of language is not English; use weather code instead + // cannot use condition string to determine icon if language is not English; use weather code instead const code = curr.code || -1; if (code > 0) { w_icon = chooseIconByCode(curr.code); From ac899251dfc7240efd8d3dc34afd5678e4ee3012 Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Wed, 24 Jul 2024 22:13:43 +0200 Subject: [PATCH 080/110] dedreckon: add ded reckoning application --- apps/dedreckon/ChangeLog | 1 + apps/dedreckon/README.md | 17 ++ apps/dedreckon/app-icon.js | 1 + apps/dedreckon/app.png | Bin 0 -> 1841 bytes apps/dedreckon/dedreckon.app.js | 442 ++++++++++++++++++++++++++++++++ apps/dedreckon/metadata.json | 13 + 6 files changed, 474 insertions(+) create mode 100644 apps/dedreckon/ChangeLog create mode 100644 apps/dedreckon/README.md create mode 100644 apps/dedreckon/app-icon.js create mode 100644 apps/dedreckon/app.png create mode 100644 apps/dedreckon/dedreckon.app.js create mode 100644 apps/dedreckon/metadata.json diff --git a/apps/dedreckon/ChangeLog b/apps/dedreckon/ChangeLog new file mode 100644 index 000000000..263d4078d --- /dev/null +++ b/apps/dedreckon/ChangeLog @@ -0,0 +1 @@ +0.01: attempt to import diff --git a/apps/dedreckon/README.md b/apps/dedreckon/README.md new file mode 100644 index 000000000..e46c6fd69 --- /dev/null +++ b/apps/dedreckon/README.md @@ -0,0 +1,17 @@ +# Ded Reckon + +Dead Reckoning using compass and step counter. + +This allows logging track using "dead reckoning" -- that's logging +angles from compass and distances from step counter. You need to mark +turns, and point watch to direction of the turn. Simultaneously, it +tries to log positions using GPS. You can use it to calibrate your +step length by comparing GPS and step counter data. It can also get +pretty accurate recording of track walked in right circumstances. + +Tap bottom part of the screen to select display (text or map for +now). Point watch to new direction, then tap top left part of screen +to indicate a turn. + +Map shows blue line for track from dead reckonging, and green line for +track from GPS. \ No newline at end of file diff --git a/apps/dedreckon/app-icon.js b/apps/dedreckon/app-icon.js new file mode 100644 index 000000000..39b72f00b --- /dev/null +++ b/apps/dedreckon/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwhHXAH4A/AH4A/AFsAFtoADF1wwqF4wwhEI5goGGIjFYN4wFF1KbHGUolIMc4lGSdIwJd9DstAH7FrBywwgad4veDwojJBIIvcFwIACGBYICGDYvEGBYvdFwqyLL8i+LF7oxFRxgveGAQ0EF5IwfMY4vpL5AFLAEYv/F8owoE44vrAY4vmAQIEEF85dGGE0AE4gvoFwpmHd0oINAH4A/AH4AvA")) diff --git a/apps/dedreckon/app.png b/apps/dedreckon/app.png new file mode 100644 index 0000000000000000000000000000000000000000..db3fcfb8897226665afffca643527bf49ac8b5fc GIT binary patch literal 1841 zcmdT_c~Dd57QeZE%4Ml01OzecSo#7{TG3LV6k;GmG|>PFF#%$0sVtQxhNc?9t3DO9 zra^EDLpm#XYEIy&D{}5yj@t>>jP9hXZ#%D7j!%bQ*VE`GE6NeB_iEP*l zL318*SP^lGq=B-BIn)Td*-vI>Hb&33S&r*9$^%g+?!a@muU!gWi7h4(l^WPV5{7n7%6(SCqjc%e}Yn=YUM~<9wVh-KlV4E zhlTkuhj~7Q10BahVc)};btw?g4qzON;0kDu=$4@lBiA8w;&cxsA;JI5dFbaug%}(S z=Ho~B^^~#x;Owcbkha5jxnBVB)^HZm77LO1Zkn1S)TQV`;mbiEe^Xd`3Gs*KR(fSYw?)X?q%*xO9r7JK zyH)Ql(?sC26pvmU^LKdQ6#&~#ygYO96!xb52o?#Ui9S_rOb8WMx83<~*1>kayk^En z%wVOt_0}F1{$5pAHudw8AlYUHLR<7tjKfcFrX=8@JsUzMzdISCd`?3t2_C;x6k^SD zgV5QE({W%q+G(;A?k%hTPsU+D9^}CV#oL{ZX2Hj}QZV1&flqNpO-y9T@zJ>ZwGrc+Pr%IXE#!i# zk{hCt0iG00pNj2%^upoicw5wcp40U+^6!7zTWV03@Pl@nGnZJ@>swMA__*%d4#m#Q zQF}yUiIj{|t?vtJm?=*ZWx>xq0$`a{?!^4n8umj^*I@~v_t_)68GEMgHnK--dWdW|4h5J;S2>?g^2^K>%)ABf_ zKqr}Xs1x4xxCo&|InHC@L4M2Z(fA#_VTuvz<8Z*@6j!xq+@bl^y}`4w`$w9F5y>hV znojc0Vsy;|hS~eETIF@^5054i<=5QDD&`;!M~$Y6m{6hX$dkn46?hD5tCjI5*@U^Vq+1bzX8m{Lc%7Tr9&|!rkSexo;Ni#pqTRbF@x2nDp%|(|`23*&8CPm($ z7b23#+_k^jbkNfTkHc~Lg?)X3D}uE(Hde4u&CrP%3G!{eE+F@|Bu=}ox^IHJ3hA#j z{Yy|Qz5A-Hgxt=Nt<~$KcZc@5O{OjcFDhp~9Zd7Ad6lfRi*bR)0R~2qqb@jape=uJ zH&*sCx!;vC>>qV?TXyH|K(M$)94k?;xvKx#MNfy*r`BC?wAOSM?`hmvh=pwGNlV=` z6F)sRkLjJ`7Q;4szh8z>j0dOpHEJdqa1&A%=uQID*Ndp_&+cAW$wpPHYi62Qe@upG z6z92kX8FEx+UgzPYuVS=uilLz4SNa-{vo+tUc32MEmgI_y2obyj|s^Dtymg`Z+Y$S zO3Wg|OYSHdPsOe!(Ro~{20t;S;p_WPnOFQBdyMM=+35Jmjd&Q*+50qUAh_Oq#El y=sZ6X*wn(45w5i0Y9_(ZkEI&y!=;-4E!Y(3ZMhIif5wm#XAj~;a#;qZbjR;cizRRX literal 0 HcmV?d00001 diff --git a/apps/dedreckon/dedreckon.app.js b/apps/dedreckon/dedreckon.app.js new file mode 100644 index 000000000..449bf9c1b --- /dev/null +++ b/apps/dedreckon/dedreckon.app.js @@ -0,0 +1,442 @@ +/* Ded Reckon */ +/* eslint-disable no-unused-vars */ + +/* fmt library v0.1.3 */ +let fmt = { + icon_alt : "\0\x08\x1a\1\x00\x00\x00\x20\x30\x78\x7C\xFE\xFF\x00\xC3\xE7\xFF\xDB\xC3\xC3\xC3\xC3\x00\x00\x00\x00\x00\x00\x00\x00", + icon_m : "\0\x08\x1a\1\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xC3\xE7\xFF\xDB\xC3\xC3\xC3\xC3\x00\x00\x00\x00\x00\x00\x00\x00", + icon_km : "\0\x08\x1a\1\xC3\xC6\xCC\xD8\xF0\xD8\xCC\xC6\xC3\x00\xC3\xE7\xFF\xDB\xC3\xC3\xC3\xC3\x00\x00\x00\x00\x00\x00\x00\x00", + icon_kph : "\0\x08\x1a\1\xC3\xC6\xCC\xD8\xF0\xD8\xCC\xC6\xC3\x00\xC3\xE7\xFF\xDB\xC3\xC3\xC3\xC3\x00\xFF\x00\xC3\xC3\xFF\xC3\xC3", + icon_c : "\0\x08\x1a\1\x00\x00\x60\x90\x90\x60\x00\x7F\xFF\xC0\xC0\xC0\xC0\xC0\xFF\x7F\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + + /* 0 .. DD.ddddd + 1 .. DD MM.mmm' + 2 .. DD MM'ss" + */ + geo_mode : 1, + + init: function() {}, + fmtDist: function(km) { + if (km >= 1.0) return km.toFixed(1) + this.icon_km; + return (km*1000).toFixed(0) + this.icon_m; + }, + fmtSteps: function(n) { return this.fmtDist(0.001 * 0.719 * n); }, + fmtAlt: function(m) { return m.toFixed(0) + this.icon_alt; }, + draw_dot : 1, + add0: function(i) { + if (i > 9) { + return ""+i; + } else { + return "0"+i; + } + }, + fmtTOD: function(now) { + this.draw_dot = !this.draw_dot; + let dot = ":"; + if (!this.draw_dot) + dot = "."; + return now.getHours() + dot + this.add0(now.getMinutes()); + }, + fmtNow: function() { return this.fmtTOD(new Date()); }, + fmtTimeDiff: function(d) { + if (d < 180) + return ""+d.toFixed(0); + d = d/60; + return ""+d.toFixed(0)+"m"; + }, + fmtAngle: function(x) { + switch (this.geo_mode) { + case 0: + return "" + x; + case 1: { + let d = Math.floor(x); + let m = x - d; + m = m*60; + return "" + d + " " + m.toFixed(3) + "'"; + } + case 2: { + let d = Math.floor(x); + let m = x - d; + m = m*60; + let mf = Math.floor(m); + let s = m - mf; + s = s*60; + return "" + d + " " + mf + "'" + s.toFixed(0) + '"'; + } + } + return "bad mode?"; + }, + fmtPos: function(pos) { + let x = pos.lat; + let c = "N"; + if (x<0) { + c = "S"; + x = -x; + } + let s = c+this.fmtAngle(x) + "\n"; + c = "E"; + if (x<0) { + c = "W"; + x = -x; + } + return s + c + this.fmtAngle(x); + }, + fmtFix: function(fix, t) { + if (fix && fix.fix && fix.lat) { + return this.fmtSpeed(fix.speed) + " " + + this.fmtAlt(fix.alt); + } else { + return "N/FIX " + this.fmtTimeDiff(t); + } + }, + fmtSpeed: function(kph) { + return kph.toFixed(1) + this.icon_kph; + }, +}; + +/* gps library v0.1.1 */ +let gps = { + emulator: -1, + init: function(x) { + this.emulator = (process.env.BOARD=="EMSCRIPTEN" + || process.env.BOARD=="EMSCRIPTEN2")?1:0; + }, + state: {}, + on_gps: function(f) { + let fix = this.getGPSFix(); + f(fix); + + /* + "lat": number, // Latitude in degrees + "lon": number, // Longitude in degrees + "alt": number, // altitude in M + "speed": number, // Speed in kph + "course": number, // Course in degrees + "time": Date, // Current Time (or undefined if not known) + "satellites": 7, // Number of satellites + "fix": 1 // NMEA Fix state - 0 is no fix + "hdop": number, // Horizontal Dilution of Precision + */ + this.state.timeout = setTimeout(this.on_gps, 1000, f); + }, + off_gps: function() { + clearTimeout(this.state.timeout); + }, + getGPSFix: function() { + if (!this.emulator) + return Bangle.getGPSFix(); + let fix = {}; + fix.fix = 1; + fix.lat = 50; + fix.lon = 14-(getTime()-this.gps_start) / 1000; /* Go West! */ + fix.alt = 200; + fix.speed = 5; + fix.course = 30; + fix.time = Date(); + fix.satellites = 5; + fix.hdop = 12; + return fix; + }, + gps_start : -1, + start_gps: function() { + Bangle.setGPSPower(1, "libgps"); + this.gps_start = getTime(); + }, + stop_gps: function() { + Bangle.setGPSPower(0, "libgps"); + }, +}; + +/* ui library 0.1 */ +let ui = { + display: 0, + numScreens: 2, + drawMsg: function(msg) { + g.reset().setFont("Vector", 35) + .setColor(1,1,1) + .fillRect(0, this.wi, 176, 176) + .setColor(0,0,0) + .drawString(msg, 5, 30); + }, + drawBusy: function() { + this.drawMsg("\n.oO busy"); + }, + nextScreen: function() { + print("nextS"); + this.display = this.display + 1; + if (this.display == this.numScreens) + this.display = 0; + this.drawBusy(); + }, + prevScreen: function() { + print("prevS"); + this.display = this.display - 1; + if (this.display < 0) + this.display = this.numScreens - 1; + this.drawBusy(); +}, + onSwipe: function(dir) { + this.nextScreen(); +}, + h: 176, + w: 176, + wi: 32, + last_b: 0, + touchHandler: function(d) { + let x = Math.floor(d.x); + let y = Math.floor(d.y); + + if (d.b != 1 || this.last_b != 0) { + this.last_b = d.b; + return; + } + + print("touch", x, y, this.h, this.w); + + /* + if ((xthis.h/2) && (ythis.w/2)) { + print("prev"); + this.prevScreen(); + } + if ((x>this.h/2) && (y>this.w/2)) { + print("next"); + this.nextScreen(); + } + }, + init: function() { + } +}; + +var last_steps = Bangle.getStepCount(), last_time = getTime(), speed = 0, step_phase = 0; + +var mpstep = 0.719 * 1.15; + +function updateSteps() { + if (step_phase ++ > 9) { + step_phase =0; + let steps = Bangle.getStepCount(); + let time = getTime(); + + speed = 3.6 * mpstep * ((steps-last_steps) / (time-last_time)); + last_steps = steps; + last_time = time; + } + return "" + fmt.fmtSpeed(speed) + " " + step_phase + "\n" + fmt.fmtDist(log_dist/1000) + " " + fmt.fmtDist(log_last/1000); +} + +/* compensated compass */ +var CALIBDATA = require("Storage").readJSON("magnav.json",1)||null; +const tiltfixread = require("magnav").tiltfixread; +var heading; + + +var cancel_gps = false; + +function drawStats() { + let fix = gps.getGPSFix(); + + let msg = fmt.fmtFix(fix, getTime() - gps.gps_start); + + msg += "\n" + fmt.fmtDist(gps_dist/1000) + " " + fmt.fmtDist(gps_last/1000) + "\n" + updateSteps(); + let c = Bangle.getCompass(); + if (c) msg += "\n" + c.heading.toFixed(0) + "/" + heading.toFixed(0) + "deg " + log.length + "\n"; + + g.reset().clear().setFont("Vector", 31) + .setColor(1,1,1) + .fillRect(0, 24, 176, 100) + .setColor(0,0,0) + .drawString(msg, 3, 25); +} + +function updateGps() { + if (cancel_gps) + return; + heading = tiltfixread(CALIBDATA.offset,CALIBDATA.scale); + if (ui.display == 0) { + setTimeout(updateGps, 1000); + drawLog(); + drawStats(); + } + if (ui.display == 1) { + setTimeout(updateGps, 1000); + drawLog(); + } +} + +function stopGps() { + cancel_gps=true; + gps.stop_gps(); +} + +var log = [], log_dist = 0, gps_dist = 0; +var log_last = 0, gps_last = 0; + +function logEntry() { + let e = {}; + e.time = getTime(); + e.fix = gps.getGPSFix(); + e.steps = Bangle.getStepCount(); + if (0) { + let c = Bangle.getCompass(); + if (c) + e.dir = c.heading; + else + e.dir = -1; + } else { + e.dir = heading; + } + return e; +} + +function onTurn() { + let e = logEntry(); + log.push(e); +} + +function radians(a) { return a*Math.PI/180; } +function degrees(a) { return a*180/Math.PI; } +// distance between 2 lat and lons, in meters, Mean Earth Radius = 6371km +// https://www.movable-type.co.uk/scripts/latlong.html +// (Equirectangular approximation) +function calcDistance(a,b) { + var x = radians(b.lon-a.lon) * Math.cos(radians((a.lat+b.lat)/2)); + var y = radians(b.lat-a.lat); + return Math.sqrt(x*x + y*y) * 6371000; +} + +var dn, de; +function initConv(fix) { + let n = { lat: fix.lat+1, lon: fix.lon }; + let e = { lat: fix.lat, lon: fix.lon+1 }; + + dn = calcDistance(fix, n); + de = calcDistance(fix, e); + print("conversion is ", dn, 108000, de, 50000); +} +function toM(start, fix) { + return { x: (fix.lon - start.lon) * de, y: (fix.lat - start.lat) * dn }; +} +var mpp = 4; +function toPix(q) { + let p = { x: q.x, y: q.y }; + p.x /= mpp; /* 10 m / pix */ + p.y /= -mpp; + p.x += 85; + p.y += 85; + return p; +} + +function drawLog() { + let here = logEntry(); + if (!here.fix.lat) { + here.fix.lat = 50; + here.fix.lon = 14; + } + initConv(here.fix); + log.push(here); + let l = log; + log_dist = 0; + log_last = -1; + gps_last = -1; + + g.reset().clear(); + g.setColor(0, 0, 1); + let last = { x: 0, y: 0 }; + for (let i = l.length - 2; i >= 0; i--) { + let next = {}; + let m = (l[i+1].steps - l[i].steps) * mpstep; + let dir = radians(180 + l[i].dir); + next.x = last.x + m * Math.sin(dir); + next.y = last.y + m * Math.cos(dir); + print(dir, m, last, next); + let lp = toPix(last); + let np = toPix(next); + g.drawLine(lp.x, lp.y, np.x, np.y); + g.drawCircle(np.x, np.y, 3); + last = next; + if (log_last == -1) + log_last = m; + log_dist += m; + } + g.setColor(0, 1, 0); + last = { x: 0, y: 0 }; + gps_dist = 0; + for (let i = l.length - 2; i >= 0; i--) { + let fix = l[i].fix; + if (fix.fix && fix.lat) { + let next = toM(here.fix, fix); + let lp = toPix(last); + let np = toPix(next); + let d = Math.sqrt((next.x-last.x)*(next.x-last.x)+(next.y-last.y)*(next.y-last.y)); + if (gps_last == -1) + gps_last = d; + gps_dist += d; + g.drawLine(lp.x, lp.y, np.x, np.y); + g.drawCircle(np.x, np.y, 3); + last = next; + } + } + log.pop(); +} + +function testPaint() { + let pos = gps.getGPSFix(); + log = []; + let e = { fix: pos, steps: 100, dir: 0 }; + log.push(e); + e = { fix: pos, steps: 200, dir: 90 }; + log.push(e); + e = { fix: pos, steps: 300, dir: 0 }; + log.push(e); + print(log, log.length, log[0], log[1]); + drawLog(); +} + +function touchHandler(d) { + let x = Math.floor(d.x); + let y = Math.floor(d.y); + + if (d.b != 1 || ui.last_b != 0) { + ui.last_b = d.b; + return; + } + + + if ((xui.h/2) && (y ui.onSwipe(s), + clock : 0 +}); + +if (0) + testPaint(); +if (1) { + g.reset(); + updateGps(); +} diff --git a/apps/dedreckon/metadata.json b/apps/dedreckon/metadata.json new file mode 100644 index 000000000..79bf8868e --- /dev/null +++ b/apps/dedreckon/metadata.json @@ -0,0 +1,13 @@ +{ "id": "dedreckon", + "name": "Ded Reckon", + "version": "0.01", + "description": "Dead Reckoning using compass and step counter", + "icon": "app.png", + "readme": "README.md", + "supports" : ["BANGLEJS2"], + "tags": "outdoors", + "storage": [ + {"name":"dedreckon.app.js","url":"dedreckon.app.js"}, + {"name":"dedreckon.img","url":"app-icon.js","evaluate":true} + ] +} From d6e189945e6467e87cb4e0d53bf1227bc793a5d2 Mon Sep 17 00:00:00 2001 From: Bernhard Date: Fri, 2 Aug 2024 13:11:12 +0200 Subject: [PATCH 081/110] fix(measuretime): make sure to draw correct time number on overlapping-day hours --- apps/measuretime/measuretime.app.js | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/apps/measuretime/measuretime.app.js b/apps/measuretime/measuretime.app.js index 97b56c710..49f5f2835 100644 --- a/apps/measuretime/measuretime.app.js +++ b/apps/measuretime/measuretime.app.js @@ -78,6 +78,19 @@ return lineEndFull - 5; }; + let drawHourString = function(hour, yLines) { + var hourForDrawing = 0; + if (hour < 0) { + // a negative hour => (+ and - = -) + hourForDrawing = 24 + hour; + } else if (hour >= 24) { + hourForDrawing = hour - 24; + } else { + hourForDrawing = hour; + } + g.drawString(hourForDrawing, hourStringXOffset(hourForDrawing), yLines, true); + }; + let drawTime = function () { g.clear(); var d = new Date(); @@ -101,12 +114,12 @@ switch (yTopLines - 88 + mins) { case -60: lineEnd = lineEndFull; - g.drawString(d.getHours()-1, hourStringXOffset(d.getHours()-1), yTopLines, true); + drawHourString(d.getHours() - 1, yTopLines); break; case 0: case 60: lineEnd = lineEndFull; - g.drawString(d.getHours(), hourStringXOffset(d.getHours()), yTopLines, true); + drawHourString(d.getHours(), yTopLines); break; case 45: case -45: @@ -136,11 +149,11 @@ case 0: case 60: lineEnd = lineEndFull; - g.drawString(d.getHours() + 1, hourStringXOffset(d.getHours()+1), yBottomLines, true); + drawHourString(d.getHours() + 1, yBottomLines);; break; case 120: lineEnd = lineEndFull; - g.drawString(d.getHours() + 2, hourStringXOffset(d.getHours()+2), yBottomLines, true); + drawHourString(d.getHours() + 2, yBottomLines); break; case 15: case 75: From 2b751ede2ffad170d71c6af2666d1b73ab22c4b1 Mon Sep 17 00:00:00 2001 From: Bernhard Date: Fri, 2 Aug 2024 13:15:55 +0200 Subject: [PATCH 082/110] fix(measuretime): remove double semicolon --- apps/measuretime/measuretime.app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/measuretime/measuretime.app.js b/apps/measuretime/measuretime.app.js index 49f5f2835..419916416 100644 --- a/apps/measuretime/measuretime.app.js +++ b/apps/measuretime/measuretime.app.js @@ -149,7 +149,7 @@ case 0: case 60: lineEnd = lineEndFull; - drawHourString(d.getHours() + 1, yBottomLines);; + drawHourString(d.getHours() + 1, yBottomLines); break; case 120: lineEnd = lineEndFull; From 5bb2dc87a8e2d728e994bb3cb42a86f81bf6c47d Mon Sep 17 00:00:00 2001 From: Bernhard Date: Fri, 2 Aug 2024 16:02:08 +0200 Subject: [PATCH 083/110] fix(measuretime): update changelog and metadata file --- apps/measuretime/ChangeLog | 1 + apps/measuretime/metadata.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/measuretime/ChangeLog b/apps/measuretime/ChangeLog index d0ac21aac..886e92f22 100644 --- a/apps/measuretime/ChangeLog +++ b/apps/measuretime/ChangeLog @@ -1,2 +1,3 @@ 0.1: Initial release 0.2: Draw line for 3d effect, fix number alignment +0.3: Fix day-end overflowing hour calculation diff --git a/apps/measuretime/metadata.json b/apps/measuretime/metadata.json index 6ba022dc0..e25fe1ef6 100644 --- a/apps/measuretime/metadata.json +++ b/apps/measuretime/metadata.json @@ -1,7 +1,7 @@ { "id": "measuretime", "name": "Measure Time", - "version": "0.2", + "version": "0.3", "description": "Measure Time in a fancy way.", "icon": "measuretime_icon.png", "screenshots": [ From 0918ece048d9510d14489ba2d160c4baf990e002 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Fri, 2 Aug 2024 15:47:42 +0100 Subject: [PATCH 084/110] clkinfostopw 0.10: Timer ClockInfo now uses +- icons, and changes timer from 'T-5 min' to just '5 min' to aid readability --- apps/clkinfostopw/ChangeLog | 1 + apps/clkinfostopw/clkinfo.js | 2 +- apps/clkinfostopw/clkinfo.ts | 2 +- apps/clkinfostopw/metadata.json | 2 +- 4 files changed, 4 insertions(+), 3 deletions(-) diff --git a/apps/clkinfostopw/ChangeLog b/apps/clkinfostopw/ChangeLog index 20742562f..bca387666 100644 --- a/apps/clkinfostopw/ChangeLog +++ b/apps/clkinfostopw/ChangeLog @@ -1,3 +1,4 @@ 0.01: New clkinfo! 0.02: Added format option, reduced battery usage 0.03: Hardcode colon-format, show milliseconds for the first minute +0.04: Change clockinfo name from timer->Timer, now uses same menu with smpltmr \ No newline at end of file diff --git a/apps/clkinfostopw/clkinfo.js b/apps/clkinfostopw/clkinfo.js index fbbe80a55..9ba4c4dc4 100644 --- a/apps/clkinfostopw/clkinfo.js +++ b/apps/clkinfostopw/clkinfo.js @@ -40,7 +40,7 @@ }; var img = function () { return atob("GBiBAAAAAAB+AAB+AAAAAAB+AAH/sAOB8AcA4A4YcAwYMBgYGBgYGBg8GBg8GBgYGBgAGAwAMA4AcAcA4AOBwAH/gAB+AAAAAAAAAA=="); }; return { - name: "timer", + name: "Timer", img: img(), items: [ { diff --git a/apps/clkinfostopw/clkinfo.ts b/apps/clkinfostopw/clkinfo.ts index f0c2a6ccb..2d14054c6 100644 --- a/apps/clkinfostopw/clkinfo.ts +++ b/apps/clkinfostopw/clkinfo.ts @@ -48,7 +48,7 @@ const img = () => atob("GBiBAAAAAAB+AAB+AAAAAAB+AAH/sAOB8AcA4A4YcAwYMBgYGBgYGBg8GBg8GBgYGBgAGAwAMA4AcAcA4AOBwAH/gAB+AAAAAAAAAA=="); return { - name: "timer", + name: "Timer", img: img(), items: [ { diff --git a/apps/clkinfostopw/metadata.json b/apps/clkinfostopw/metadata.json index f33f61dbb..b785f5c96 100644 --- a/apps/clkinfostopw/metadata.json +++ b/apps/clkinfostopw/metadata.json @@ -1,7 +1,7 @@ { "id": "clkinfostopw", "name": "Stop Watch Clockinfo", - "version":"0.03", + "version":"0.04", "description": "A simple stopwatch, shown via clockinfo", "icon": "app.png", "type": "clkinfo", From 3d1dfd3fb3d157fb861a7e0a6fc7bf964cc57afb Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Fri, 2 Aug 2024 15:47:49 +0100 Subject: [PATCH 085/110] update lint --- apps/lint_exemptions.js | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/apps/lint_exemptions.js b/apps/lint_exemptions.js index e5a2170bd..3b7da1a20 100644 --- a/apps/lint_exemptions.js +++ b/apps/lint_exemptions.js @@ -196,12 +196,6 @@ module.exports = { "no-undef" ] }, - "apps/sixths/sixths.app.js": { - "hash": "2a4676828bdf78df052df402de34e6f1abd1c847ebe0d193fc789cd6e9dd0e5c", - "rules": [ - "no-undef" - ] - }, "apps/scribble/app.js": { "hash": "6d13abd27bab8009a6bdabe1df2df394bc14aac20c68f67e8f8b085fa6b427cd", "rules": [ @@ -1249,12 +1243,6 @@ module.exports = { "no-undef" ] }, - "apps/accelrec/app.js": { - "hash": "b5369a60afc8f360f0b33f71080eb3f5d09a1bf3703acfcf07cd80dd19f1997d", - "rules": [ - "no-undef" - ] - }, "apps/BLEcontroller/app-joy.js": { "hash": "e4f34bb1bc11b52c3d7a1c537a140b0e23ccef82694dcd602cb517a8ba342898", "rules": [ From 8d602d26692bea035495c23061c16fc6319d2adf Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Fri, 2 Aug 2024 15:48:02 +0100 Subject: [PATCH 086/110] smpltmr 0.10: Timer ClockInfo now uses +- icons, and changes timer from 'T-5 min' to just '5 min' to aid readability --- apps/smpltmr/ChangeLog | 1 + apps/smpltmr/clkinfo.js | 4 ++-- apps/smpltmr/metadata.json | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/apps/smpltmr/ChangeLog b/apps/smpltmr/ChangeLog index 2c073ff43..c3f069428 100644 --- a/apps/smpltmr/ChangeLog +++ b/apps/smpltmr/ChangeLog @@ -7,3 +7,4 @@ 0.07: Update clock_info to avoid a redraw 0.08: Timer ClockInfo now updates once a minute 0.09: Timer ClockInfo resets to timer menu when blurred +0.10: Timer ClockInfo now uses +- icons, and changes timer from 'T-5 min' to just '5 min' to aid readability \ No newline at end of file diff --git a/apps/smpltmr/clkinfo.js b/apps/smpltmr/clkinfo.js index a7a6bf71b..6fc2cd265 100644 --- a/apps/smpltmr/clkinfo.js +++ b/apps/smpltmr/clkinfo.js @@ -28,7 +28,7 @@ var min = getAlarmMinutes(); if(min < 0) return "OFF"; - return "T-" + String(min)+ " min"; + return min + " min"; } function increaseAlarm(t){ @@ -80,7 +80,7 @@ offsets.forEach((o, i) => { smpltmrItems.items = smpltmrItems.items.concat({ name: null, - get: () => ({ text: (o > 0 ? "+" : "") + o + " min.", img: smpltmrItems.img }), + get: () => ({ text: (o > 0 ? "+" : "") + o + " min", img: (o>0)?atob("GBiBAAB+AAB+AAAYAAAYAAB+AA3/sA+B8A4AcAwAMBgYGBgYGDAYDDAYDDH/jDH/jDAYDDAYDBgYGBgYGAwAMA4AcAeB4AH/gAB+AA=="):atob("GBiBAAB+AAB+AAAYAAAYAAB+AA3/sA+B8A4AcAwAMBgAGBgAGDAADDAADDH/jDH/jDAADDAADBgAGBgAGAwAMA4AcAeB4AH/gAB+AA==") }), show: function() { }, hide: function() { }, blur: restoreMainItem, diff --git a/apps/smpltmr/metadata.json b/apps/smpltmr/metadata.json index 98affcfe6..2f33f07b9 100644 --- a/apps/smpltmr/metadata.json +++ b/apps/smpltmr/metadata.json @@ -2,7 +2,7 @@ "id": "smpltmr", "name": "Simple Timer", "shortName": "Simple Timer", - "version": "0.09", + "version": "0.10", "description": "A very simple app to start a timer.", "icon": "app.png", "tags": "tool,alarm,timer,clkinfo", From e069a3870cdd56e11d4faf9d824a0b29d737b625 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Fri, 2 Aug 2024 15:48:15 +0100 Subject: [PATCH 087/110] twotwoclock 0.02: Clockinfos now save under correct name, and wrap correctly to >1 line --- apps/twotwoclock/ChangeLog | 1 + apps/twotwoclock/app.js | 8 ++++---- apps/twotwoclock/metadata.json | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/apps/twotwoclock/ChangeLog b/apps/twotwoclock/ChangeLog index 09953593e..d3275c0e8 100644 --- a/apps/twotwoclock/ChangeLog +++ b/apps/twotwoclock/ChangeLog @@ -1 +1,2 @@ 0.01: New Clock! +0.02: Clockinfos now save under correct name, and wrap correctly to >1 line \ No newline at end of file diff --git a/apps/twotwoclock/app.js b/apps/twotwoclock/app.js index 57be691e1..b2d5ea9fb 100644 --- a/apps/twotwoclock/app.js +++ b/apps/twotwoclock/app.js @@ -134,8 +134,8 @@ for (var i=0;i<10;i++) if (g.stringWidth(txt) > options.w) // if too big, smaller font g.setFont("LECO1976Regular14"); if (g.stringWidth(txt) > options.w) {// if still too big, split to 2 lines - var l = g.wrapString(txt, options.w); - txt = l.slice(0,2).join("\n") + (l.length>2)?"...":""; + var l = g.wrapString(txt, options.w-4); + txt = l.slice(0,2).join("\n") + ((l.length>2)?"...":""); } var x = options.x+options.w/2, y = options.y+54; g.setColor(g.theme.bg).drawString(txt, x-2, y). // draw the text background @@ -147,12 +147,12 @@ for (var i=0;i<10;i++) }; clockInfoMenuA = require("clock_info").addInteractive(clockInfoItems, { - app:"pebblepp", + app:"twotwoclock", x : g.getWidth()-clockInfoW, y: 0, w: clockInfoW, h:clockInfoH, draw : clockInfoDraw }); clockInfoMenuB = require("clock_info").addInteractive(clockInfoItems, { - app:"pebblepp", + app:"twotwoclock", x : g.getWidth()-clockInfoW, y: clockInfoH, w: clockInfoW, h:clockInfoH, draw : clockInfoDraw }); diff --git a/apps/twotwoclock/metadata.json b/apps/twotwoclock/metadata.json index ebcba539c..ae3b958ef 100644 --- a/apps/twotwoclock/metadata.json +++ b/apps/twotwoclock/metadata.json @@ -1,7 +1,7 @@ { "id": "twotwoclock", "name": "TwoTwo Clock", "shortName":"22 Clock", - "version":"0.01", + "version":"0.02", "description": "A clock with the time split over two lines, with custom backgrounds and two ClockInfos", "icon": "icon.png", "type": "clock", From 8c5eceb7c31e98e41f750bc54bfdc3dbd677734b Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Fri, 2 Aug 2024 16:07:48 +0100 Subject: [PATCH 088/110] Revert "clkinfostopw renaming timer->Timer" This just gets in the way of simpltmr, but maybe we should consider renaming to "stopw" or similar - or maybe it doesn't need its own category at all This reverts commit 0918ece048d9510d14489ba2d160c4baf990e002. --- apps/clkinfostopw/ChangeLog | 1 - apps/clkinfostopw/clkinfo.js | 2 +- apps/clkinfostopw/clkinfo.ts | 2 +- apps/clkinfostopw/metadata.json | 2 +- 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/apps/clkinfostopw/ChangeLog b/apps/clkinfostopw/ChangeLog index bca387666..20742562f 100644 --- a/apps/clkinfostopw/ChangeLog +++ b/apps/clkinfostopw/ChangeLog @@ -1,4 +1,3 @@ 0.01: New clkinfo! 0.02: Added format option, reduced battery usage 0.03: Hardcode colon-format, show milliseconds for the first minute -0.04: Change clockinfo name from timer->Timer, now uses same menu with smpltmr \ No newline at end of file diff --git a/apps/clkinfostopw/clkinfo.js b/apps/clkinfostopw/clkinfo.js index 9ba4c4dc4..fbbe80a55 100644 --- a/apps/clkinfostopw/clkinfo.js +++ b/apps/clkinfostopw/clkinfo.js @@ -40,7 +40,7 @@ }; var img = function () { return atob("GBiBAAAAAAB+AAB+AAAAAAB+AAH/sAOB8AcA4A4YcAwYMBgYGBgYGBg8GBg8GBgYGBgAGAwAMA4AcAcA4AOBwAH/gAB+AAAAAAAAAA=="); }; return { - name: "Timer", + name: "timer", img: img(), items: [ { diff --git a/apps/clkinfostopw/clkinfo.ts b/apps/clkinfostopw/clkinfo.ts index 2d14054c6..f0c2a6ccb 100644 --- a/apps/clkinfostopw/clkinfo.ts +++ b/apps/clkinfostopw/clkinfo.ts @@ -48,7 +48,7 @@ const img = () => atob("GBiBAAAAAAB+AAB+AAAAAAB+AAH/sAOB8AcA4A4YcAwYMBgYGBgYGBg8GBg8GBgYGBgAGAwAMA4AcAcA4AOBwAH/gAB+AAAAAAAAAA=="); return { - name: "Timer", + name: "timer", img: img(), items: [ { diff --git a/apps/clkinfostopw/metadata.json b/apps/clkinfostopw/metadata.json index b785f5c96..f33f61dbb 100644 --- a/apps/clkinfostopw/metadata.json +++ b/apps/clkinfostopw/metadata.json @@ -1,7 +1,7 @@ { "id": "clkinfostopw", "name": "Stop Watch Clockinfo", - "version":"0.04", + "version":"0.03", "description": "A simple stopwatch, shown via clockinfo", "icon": "app.png", "type": "clkinfo", From a5e37ec55617a13a0beb9b889a0fa8389da4de5f Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Fri, 2 Aug 2024 20:12:44 +0200 Subject: [PATCH 089/110] dedreckon: add a note about magnav. --- apps/dedreckon/README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/dedreckon/README.md b/apps/dedreckon/README.md index e46c6fd69..706c7f191 100644 --- a/apps/dedreckon/README.md +++ b/apps/dedreckon/README.md @@ -14,4 +14,7 @@ now). Point watch to new direction, then tap top left part of screen to indicate a turn. Map shows blue line for track from dead reckonging, and green line for -track from GPS. \ No newline at end of file +track from GPS. + +You probably want magnav installed (and calibrated) for useful +results, as it provides library with better compass. \ No newline at end of file From df89c22a006fe875e00f90543afa1cc79381cd22 Mon Sep 17 00:00:00 2001 From: only-meeps <151784194+only-meeps@users.noreply.github.com> Date: Fri, 2 Aug 2024 14:14:39 -0700 Subject: [PATCH 091/110] Update app.js --- apps/boxclk/app.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/boxclk/app.js b/apps/boxclk/app.js index ed8a62b65..c47f700b0 100644 --- a/apps/boxclk/app.js +++ b/apps/boxclk/app.js @@ -167,8 +167,8 @@ Modules.addCached("widget_utils", function() { boxKeys.forEach((key) => { let boxConfig = boxes[key]; boxPos[key] = { - x: w * boxConfig.boxPos.x, - y: h * boxConfig.boxPos.y + let background = require("clockbg"); + Modules.addCached("widget_utils", function() { }; isDragging[key] = false; wasDragging[key] = false; From e06a8d73fbdb580e160d34fd4f21fc8b889501f6 Mon Sep 17 00:00:00 2001 From: only-meeps <151784194+only-meeps@users.noreply.github.com> Date: Fri, 2 Aug 2024 14:21:58 -0700 Subject: [PATCH 092/110] Update app.js --- apps/8ball/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/8ball/app.js b/apps/8ball/app.js index 59f243f80..8a3ee427e 100644 --- a/apps/8ball/app.js +++ b/apps/8ball/app.js @@ -1,4 +1,4 @@ -try {keyboard = require(keyboard);} catch(e) {keyboard = null;}var keyboard = "textinput"; +var keyboard = "textinput"; var Name = ""; Bangle.setLCDTimeout(0); var menuOpen = 1; From ccee0c647d2a7b39c8708afefbdaee7faebbb118 Mon Sep 17 00:00:00 2001 From: only-meeps <151784194+only-meeps@users.noreply.github.com> Date: Fri, 2 Aug 2024 14:27:01 -0700 Subject: [PATCH 093/110] Update app.js --- apps/boxclk/app.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/apps/boxclk/app.js b/apps/boxclk/app.js index c47f700b0..73f4113c0 100644 --- a/apps/boxclk/app.js +++ b/apps/boxclk/app.js @@ -167,8 +167,6 @@ Modules.addCached("widget_utils", function() { boxKeys.forEach((key) => { let boxConfig = boxes[key]; boxPos[key] = { - let background = require("clockbg"); - Modules.addCached("widget_utils", function() { }; isDragging[key] = false; wasDragging[key] = false; From bfa9a757ddd417554b599f8b8ce92e88a7089471 Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Wed, 31 Jul 2024 17:52:56 +0100 Subject: [PATCH 094/110] slopeclockpp: avoid reusing background colour for clkinfo --- apps/slopeclockpp/app.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/slopeclockpp/app.js b/apps/slopeclockpp/app.js index 5b1d898d1..359993bc3 100644 --- a/apps/slopeclockpp/app.js +++ b/apps/slopeclockpp/app.js @@ -128,9 +128,9 @@ let clockInfoDraw = (itm, info, options) => { let texty = options.y+41; // set a cliprect to stop us drawing outside our box g.reset().setClipRect(options.x, options.y, options.x+options.w-1, options.y+options.h-1); - g.setFont("6x15").setBgColor(options.bg).setColor(options.fg).clearRect(options.x, texty-15, options.x+options.w-2, texty); + g.setFont("6x15").setBgColor(options.bg).clearRect(options.x, texty-15, options.x+options.w-2, texty); - if (options.focus) g.setColor(options.hl); + g.setColor(options.focus ? options.hl : options.fg); if (options.x < g.getWidth()/2) { // left align let x = options.x+2; if (info.img) g.clearRect(x, options.y, x+23, options.y+23).drawImage(info.img, x, options.y); @@ -150,7 +150,7 @@ let clockInfoMenu = require("clock_info").addInteractive(clockInfoItems, { // t }); let clockInfoMenu2 = require("clock_info").addInteractive(clockInfoItems, { // bottom left app:"slopeclockpp",x:0, y:115, w:50, h:40, - draw : clockInfoDraw, bg : bgColor, fg : g.theme.bg, hl : (bgColor=="#000")?"#f00"/*red*/:g.theme.fg + draw : clockInfoDraw, bg : bgColor, fg : g.theme.bg, hl : (g.theme.fg===g.toColor(bgColor))?"#f00"/*red*/:g.theme.fg }); // Show launcher when middle button pressed @@ -175,4 +175,4 @@ Bangle.loadWidgets(); if (settings.hideWidgets) require("widget_utils").swipeOn(); else setTimeout(Bangle.drawWidgets,0); draw(); -} \ No newline at end of file +} From 08e9d3439274bb7eb113ed9b205465caf55a9ea9 Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Wed, 31 Jul 2024 17:54:12 +0100 Subject: [PATCH 095/110] slopeclockpp: fix lint --- apps/slopeclockpp/app.js | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/slopeclockpp/app.js b/apps/slopeclockpp/app.js index 359993bc3..df732c1db 100644 --- a/apps/slopeclockpp/app.js +++ b/apps/slopeclockpp/app.js @@ -86,6 +86,7 @@ let draw = function() { let isAnimIn = true; let animInterval; +let minuteX; // Draw *just* the minute image let drawMinute = function() { var yo = slopeBorder + offsy + y - 2*slope*minuteX/R.w; From a6e0991065e500efca80666be61699bee405c9b6 Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Wed, 31 Jul 2024 17:54:29 +0100 Subject: [PATCH 096/110] slopeclockpp: bump version --- apps/slopeclockpp/ChangeLog | 3 ++- apps/slopeclockpp/metadata.json | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/slopeclockpp/ChangeLog b/apps/slopeclockpp/ChangeLog index 39f837386..43b457d4e 100644 --- a/apps/slopeclockpp/ChangeLog +++ b/apps/slopeclockpp/ChangeLog @@ -10,4 +10,5 @@ 0.08: Stability improvements - ensure we continue even if a flat string can't be allocated Stop ClockInfo text drawing outside the allocated area 0.09: Use clock_info module as an app -0.10: Option to hide widgets, tweak top widget width to avoid overlap with hour text at 9am \ No newline at end of file +0.10: Option to hide widgets, tweak top widget width to avoid overlap with hour text at 9am +0.11: Avoid rendering clkinfo in the same colour as the background diff --git a/apps/slopeclockpp/metadata.json b/apps/slopeclockpp/metadata.json index 086b8148f..00e0b0a77 100644 --- a/apps/slopeclockpp/metadata.json +++ b/apps/slopeclockpp/metadata.json @@ -1,6 +1,6 @@ { "id": "slopeclockpp", "name": "Slope Clock ++", - "version":"0.10", + "version":"0.11", "description": "A clock where hours and minutes are divided by a sloping line. When the minute changes, the numbers slide off the screen. This is a clone of the original Slope Clock which shows extra information and allows the colors to be selected.", "icon": "app.png", "screenshots": [{"url":"screenshot.png"}], From 9984914a91d4d06fe194d2ff980d4783c7909128 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Mon, 5 Aug 2024 10:45:41 +0100 Subject: [PATCH 097/110] Fix widget_utils breakage which caused the widget bar used with swipeOn to literally never be hidden. Was introduced as part of https://github.com/espruino/BangleApps/issues/3417#issuecomment-2120204969 --- modules/widget_utils.js | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/modules/widget_utils.js b/modules/widget_utils.js index 4e2acd296..4f9b85835 100644 --- a/modules/widget_utils.js +++ b/modules/widget_utils.js @@ -90,19 +90,17 @@ exports.swipeOn = function(autohide) { function queueDraw() { const o = exports.offset; + Bangle.appRect.y = o+24; + Bangle.appRect.h = 1 + Bangle.appRect.y2 - Bangle.appRect.y; if (o>-24) { - Bangle.appRect.y = o+24; - Bangle.appRect.h = 1 + Bangle.appRect.y2 - Bangle.appRect.y; - if (o>-24) { - Bangle.setLCDOverlay(og, 0, o, { - id:"widget_utils", - remove:()=>{ - require("widget_utils").cleanupOverlay(); - } - }); - } else { - Bangle.setLCDOverlay(undefined, {id: "widget_utils"}); - } + Bangle.setLCDOverlay(og, 0, o, { + id:"widget_utils", + remove:()=>{ + require("widget_utils").cleanupOverlay(); + } + }); + } else { + Bangle.setLCDOverlay(undefined, {id: "widget_utils"}); } } From 8de98708504bd9d46e73cae65353e1e65b51841d Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Mon, 5 Aug 2024 19:59:24 +0100 Subject: [PATCH 098/110] Revert changes from IDE --- apps/boxclk/app.js | 786 +++++++++++++++++++++++---------------------- 1 file changed, 395 insertions(+), 391 deletions(-) diff --git a/apps/boxclk/app.js b/apps/boxclk/app.js index 73f4113c0..83716fd90 100644 --- a/apps/boxclk/app.js +++ b/apps/boxclk/app.js @@ -1,400 +1,404 @@ -let background = require("clockbg"); -Modules.addCached("widget_utils", function() { - exports.hide = function() { - exports.cleanup(); - if (!global.WIDGETS) return; - g.reset(); - for (var w of global.WIDGETS) { - if (w._draw) return; - w._draw = w.draw; - w.draw = () => {}; - w._area = w.area; - w.area = ""; - if (w.x != undefined) g.clearRect(w.x, w.y, w.x + w.width - 1, w.y + 23); - } - }; - exports.show = function() { - exports.cleanup(); - if (!global.WIDGETS) return; - for (var w of global.WIDGETS) { - if (!w._draw) return; - w.draw = w._draw; - w.area = w._area; - delete w._draw; - delete w._area; - w.draw(w); - } - }; - exports.cleanup = function() { - delete exports.autohide; - delete Bangle.appRect; - if (exports.swipeHandler) { - Bangle.removeListener("swipe", exports.swipeHandler); - delete exports.swipeHandler; - } - if (exports.animInterval) { - clearInterval(exports.animInterval); - delete exports.animInterval; - } - if (exports.hideTimeout) { - clearTimeout(exports.hideTimeout); - delete exports.hideTimeout; - } - if (exports.origDraw) { - Bangle.drawWidgets = exports.origDraw; - delete exports.origDraw; - } - } - exports.swipeOn = function(autohide) { - if (process.env.HWVERSION !== 2) return exports.hide(); - exports.cleanup(); - if (!global.WIDGETS) return; - exports.autohide = autohide === undefined ? 2000 : autohide; - Bangle.appRect = { - x: 0, - y: 0, - w: g.getWidth(), - h: g.getHeight(), - x2: g.getWidth() - 1, - y2: g.getHeight() - 1 - }; - let og = Graphics.createArrayBuffer(g.getWidth(), 26, 16, { - msb: true - }); - og.theme = g.theme; - og._reset = og.reset; - og.reset = function() { - return this._reset().setColor(g.theme.fg).setBgColor(g.theme.bg); - }; - og.reset().clearRect(0, 0, og.getWidth(), 23).fillRect(0, 24, og.getWidth(), 25); - let _g = g; - let offset = -24; - - function queueDraw() { - Bangle.appRect.y = offset + 24; - Bangle.appRect.h = 1 + Bangle.appRect.y2 - Bangle.appRect.y; - if (offset > -24) Bangle.setLCDOverlay(og, 0, offset); - else Bangle.setLCDOverlay(); - } - for (var w of global.WIDGETS) { - if (w._draw) continue; - w._draw = w.draw; - w.draw = function() { - g = og; - this._draw(this); - g = _g; - if (offset > -24) queueDraw(); - }; - w._area = w.area; - if (w.area.startsWith("b")) w.area = "t" + w.area.substr(1); - } - exports.origDraw = Bangle.drawWidgets; - Bangle.drawWidgets = () => { - g = og; - exports.origDraw(); - g = _g; - }; - - function anim(dir, callback) { - if (exports.animInterval) clearInterval(exports.interval); - exports.animInterval = setInterval(function() { - offset += dir; - let stop = false; - if (dir > 0 && offset >= 0) { - stop = true; - offset = 0; - } else if (dir < 0 && offset < -23) { - stop = true; - offset = -24; - } - if (stop) { - clearInterval(exports.animInterval); - delete exports.animInterval; - if (callback) callback(); - } - queueDraw(); - }, 50); - } - exports.swipeHandler = function(lr, ud) { - if (exports.hideTimeout) { - clearTimeout(exports.hideTimeout); - delete exports.hideTimeout; - } - let cb; - if (exports.autohide > 0) cb = function() { - exports.hideTimeout = setTimeout(function() { - anim(-4); - }, exports.autohide); - } - if (ud > 0 && offset < 0) anim(4, cb); - if (ud < 0 && offset > -24) anim(-4); - }; - Bangle.on("swipe", exports.swipeHandler); - Bangle.drawWidgets(); - }; -}); { - let storage = require("Storage"); - let locale = require("locale"); - let widgets = require("widget_utils"); - let date = new Date(); - let configNumber = (storage.readJSON("boxclk.json", 1) || {}).selectedConfig || 0; - let fileName = 'boxclk' + (configNumber > 0 ? `-${configNumber}` : '') + '.json'; - if (!storage.read(fileName)) { - fileName = 'boxclk.json'; + /** + * --------------------------------------------------------------- + * 1. Module dependencies and initial configurations + * --------------------------------------------------------------- + */ + + let storage = require("Storage"); + let locale = require("locale"); + let widgets = require("widget_utils"); + let date = new Date(); + let configNumber = (storage.readJSON("boxclk.json", 1) || {}).selectedConfig || 0; + let fileName = 'boxclk' + (configNumber > 0 ? `-${configNumber}` : '') + '.json'; + // Add a condition to check if the file exists, if it does not, default to 'boxclk.json' + if (!storage.read(fileName)) { + fileName = 'boxclk.json'; + } + let boxesConfig = storage.readJSON(fileName, 1) || {}; + let boxes = {}; + let boxPos = {}; + let isDragging = {}; + let wasDragging = {}; + let doubleTapTimer = null; + let g_setColor; + + let saveIcon = require("heatshrink").decompress(atob("mEwwkEogA/AHdP/4AK+gWVDBQWNAAIuVGBAIB+UQdhMfGBAHBCxUAgIXHIwPyCxQwEJAgXB+MAl/zBwQGBn8ggQjBGAQXG+EA/4XI/8gBIQXTGAMPC6n/C6HzkREBC6YACC6QAFC57aHCYIXOOgLsEn4XPABIX/C6vykQAEl6/WgCQBC5imFAAT2BC5gCBI4oUCC5x0IC/4X/C4K8Bl4XJ+TCCC4wKBABkvC4tEEoMQCxcBB4IWEC4XyDBUBFwIXGJAIAOIwowDABoWGGB4uHDBwWJAH4AzA")); + + /** + * --------------------------------------------------------------- + * 2. Graphical and visual configurations + * --------------------------------------------------------------- + */ + + let w = g.getWidth(); + let h = g.getHeight(); + let totalWidth, totalHeight; + let drawTimeout; + + /** + * --------------------------------------------------------------- + * 3. Touchscreen Handlers + * --------------------------------------------------------------- + */ + + let touchHandler; + let dragHandler; + let movementDistance = 0; + + /** + * --------------------------------------------------------------- + * 4. Font loading function + * --------------------------------------------------------------- + */ + + let loadCustomFont = function() { + Graphics.prototype.setFontBrunoAce = function() { + // Actual height 23 (24 - 2) + return this.setFontCustom( + E.toString(require('heatshrink').decompress(atob('ABMHwADBh4DKg4bKgIPDAYUfAYV/AYX/AQMD/gmC+ADBn/AByE/GIU8AYUwLxcfAYX/8AnB//4JIP/FgMP4F+CQQBBjwJBFYRbBAd43DHoJpBh/g/xPEK4ZfDgEEORKDDAY8////wADLfZrTCgITBnhEBAYJMBAYMPw4DCM4QDjhwDCjwDBn0+AYMf/gDBh/4AYMH+ADBLpc4ToK/NGYZfnAYcfL4U/x5fBW4LvB/7vC+LvBgHAsBfIn76Cn4WBcYQDFEgJ+CQQYDyH4L/BAZbHLNYjjCAZc8ngDunycBZ4KkBa4KwBnEHY4UB+BfMgf/ZgMH/4XBc4cf4F/gE+ZgRjwAYcfj5jBM4U4M4RQBM4UA8BjIngDFEYJ8BAYUDAYQvCM4ZxBC4V+AYQvBnkBQ4M8gabBJQPAI4WAAYM/GYQaBAYJKCnqyCn5OCn4aBAYIaBAYJPCU4IABnBhIuDXCFAMD+Z/BY4IDBQwOPwEfv6TDAYUPAcwrDAYQ7BAYY/BI4cD8bLCK4RfEAA0BRYTeDcwIrFn0Pw43Bg4DugYDBjxBBU4SvDMYMH/5QBgP/LAQAP8EHN4UPwADHB4YAHA'))), + 46, + atob("CBEdChgYGhgaGBsaCQ=="), + 32|65536 + ); + }; + }; + + /** + * --------------------------------------------------------------- + * 5. Initial settings of boxes and their positions + * --------------------------------------------------------------- + */ + + let boxKeys = Object.keys(boxes); + + boxKeys.forEach((key) => { + let boxConfig = boxes[key]; + boxPos[key] = { + }; + isDragging[key] = false; + wasDragging[key] = false; + }); + + /** + * --------------------------------------------------------------- + * 6. Text and drawing functions + * --------------------------------------------------------------- + */ + + // Overwrite the setColor function to allow the + // use of (x) in g.theme.x as a string + // in your JSON config ("fg", "bg", "fg2", "bg2", "fgH", "bgH") + let modSetColor = function() { + // Save the original setColor function + g_setColor = g.setColor; + // Overwrite setColor with the new function + g.setColor = function(color) { + if (typeof color === "string" && color in g.theme) { + g_setColor.call(g, g.theme[color]); + } else { + g_setColor.call(g, color); + } + }; + }; + + let restoreSetColor = function() { + // Restore the original setColor function + if (g_setColor) { + g.setColor = g_setColor; } - let boxesConfig = storage.readJSON(fileName, 1) || {}; - let boxes = {}; - let boxPos = {}; - let isDragging = {}; - let wasDragging = {}; - let doubleTapTimer = null; - let g_setColor; - let saveIcon = require("heatshrink").decompress(atob("mEwwkEogA/AHdP/4AK+gWVDBQWNAAIuVGBAIB+UQdhMfGBAHBCxUAgIXHIwPyCxQwEJAgXB+MAl/zBwQGBn8ggQjBGAQXG+EA/4XI/8gBIQXTGAMPC6n/C6HzkREBC6YACC6QAFC57aHCYIXOOgLsEn4XPABIX/C6vykQAEl6/WgCQBC5imFAAT2BC5gCBI4oUCC5x0IC/4X/C4K8Bl4XJ+TCCC4wKBABkvC4tEEoMQCxcBB4IWEC4XyDBUBFwIXGJAIAOIwowDABoWGGB4uHDBwWJAH4AzA")); - let w = g.getWidth(); - let h = g.getHeight(); - let totalWidth, totalHeight; - let drawTimeout; - let touchHandler; - let dragHandler; - let movementDistance = 0; - let loadCustomFont = function() { - Graphics.prototype.setFontBrunoAce = function() { - return this.setFontCustom(E.toString(require('heatshrink').decompress(atob('ABMHwADBh4DKg4bKgIPDAYUfAYV/AYX/AQMD/gmC+ADBn/AByE/GIU8AYUwLxcfAYX/8AnB//4JIP/FgMP4F+CQQBBjwJBFYRbBAd43DHoJpBh/g/xPEK4ZfDgEEORKDDAY8////wADLfZrTCgITBnhEBAYJMBAYMPw4DCM4QDjhwDCjwDBn0+AYMf/gDBh/4AYMH+ADBLpc4ToK/NGYZfnAYcfL4U/x5fBW4LvB/7vC+LvBgHAsBfIn76Cn4WBcYQDFEgJ+CQQYDyH4L/BAZbHLNYjjCAZc8ngDunycBZ4KkBa4KwBnEHY4UB+BfMgf/ZgMH/4XBc4cf4F/gE+ZgRjwAYcfj5jBM4U4M4RQBM4UA8BjIngDFEYJ8BAYUDAYQvCM4ZxBC4V+AYQvBnkBQ4M8gabBJQPAI4WAAYM/GYQaBAYJKCnqyCn5OCn4aBAYIaBAYJPCU4IABnBhIuDXCFAMD+Z/BY4IDBQwOPwEfv6TDAYUPAcwrDAYQ7BAYY/BI4cD8bLCK4RfEAA0BRYTeDcwIrFn0Pw43Bg4DugYDBjxBBU4SvDMYMH/5QBgP/LAQAP8EHN4UPwADHB4YAHA'))), 46, atob("CBEdChgYGhgaGBsaCQ=="), 32 | 65536); - }; + }; + + // Overwrite the drawString function + let g_drawString = g.drawString; + g.drawString = function(box, str, x, y) { + outlineText(box, str, x, y); + g.setColor(box.color); + g_drawString.call(g, str, x, y); + }; + + let outlineText = function(box, str, x, y) { + let px = box.outline; + let dx = [-px, 0, px, -px, px, -px, 0, px]; + let dy = [-px, -px, -px, 0, 0, px, px, px]; + g.setColor(box.outlineColor); + for (let i = 0; i < dx.length; i++) { + g_drawString.call(g, str, x + dx[i], y + dy[i]); + } + }; + + let calcBoxSize = function(boxItem) { + g.reset(); + g.setFontAlign(0,0); + g.setFont(boxItem.font, boxItem.fontSize); + let strWidth = g.stringWidth(boxItem.string) + 2 * boxItem.outline; + let fontHeight = g.getFontHeight() + 2 * boxItem.outline; + totalWidth = strWidth + 2 * boxItem.xPadding; + totalHeight = fontHeight + 2 * boxItem.yPadding; + }; + + let calcBoxPos = function(boxKey) { + return { + x1: boxPos[boxKey].x - totalWidth / 2, + y1: boxPos[boxKey].y - totalHeight / 2, + x2: boxPos[boxKey].x + totalWidth / 2, + y2: boxPos[boxKey].y + totalHeight / 2 }; - let boxKeys = Object.keys(boxes); - boxKeys.forEach((key) => { - let boxConfig = boxes[key]; - boxPos[key] = { - }; - isDragging[key] = false; - wasDragging[key] = false; - }); - let modSetColor = function() { - g_setColor = g.setColor; - g.setColor = function(color) { - if (typeof color === "string" && color in g.theme) { - g_setColor.call(g, g.theme[color]); - } else { - g_setColor.call(g, color); - } - }; - }; - let restoreSetColor = function() { - if (g_setColor) { - g.setColor = g_setColor; - } - }; - let g_drawString = g.drawString; - g.drawString = function(box, str, x, y) { - outlineText(box, str, x, y); - g.setColor(box.color); - g_drawString.call(g, str, x, y); - }; - let outlineText = function(box, str, x, y) { - let px = box.outline; - let dx = [-px, 0, px, -px, px, -px, 0, px]; - let dy = [-px, -px, -px, 0, 0, px, px, px]; - g.setColor(box.outlineColor); - for (let i = 0; i < dx.length; i++) { - g_drawString.call(g, str, x + dx[i], y + dy[i]); - } - }; - let calcBoxSize = function(boxItem) { - g.reset(); - g.setFontAlign(0, 0); - g.setFont(boxItem.font, boxItem.fontSize); - let strWidth = g.stringWidth(boxItem.string) + 2 * boxItem.outline; - let fontHeight = g.getFontHeight() + 2 * boxItem.outline; - totalWidth = strWidth + 2 * boxItem.xPadding; - totalHeight = fontHeight + 2 * boxItem.yPadding; - }; - let calcBoxPos = function(boxKey) { - return { - x1: boxPos[boxKey].x - totalWidth / 2, - y1: boxPos[boxKey].y - totalHeight / 2, - x2: boxPos[boxKey].x + totalWidth / 2, - y2: boxPos[boxKey].y + totalHeight / 2 - }; - }; - let displaySaveIcon = function() { - draw(boxes); - g.drawImage(saveIcon, w / 2 - 24, h / 2 - 24); - setTimeout(() => { - g.clearRect(w / 2 - 24, h / 2 - 24, w / 2 + 24, h / 2 + 24); - draw(boxes); - }, 2000); - }; - let isBool = function(val, defaultVal) { - return typeof val !== 'undefined' ? Boolean(val) : defaultVal; - }; - let getDate = function(short, shortMonth, disableSuffix) { - const date = new Date(); - const dayOfMonth = date.getDate(); - const month = shortMonth ? locale.month(date, 1) : locale.month(date, 0); - const year = date.getFullYear(); - let suffix; - if ([1, 21, 31].includes(dayOfMonth)) { - suffix = "st"; - } else if ([2, 22].includes(dayOfMonth)) { - suffix = "nd"; - } else if ([3, 23].includes(dayOfMonth)) { - suffix = "rd"; - } else { - suffix = "th"; - } - let dayOfMonthStr = disableSuffix ? dayOfMonth : dayOfMonth + suffix; - return month + " " + dayOfMonthStr + (short ? '' : (", " + year)); - }; - let getDayOfWeek = function(date, short) { - return locale.dow(date, short ? 1 : 0); - }; - locale.meridian = function(date, short) { - let hours = date.getHours(); - let meridian = hours >= 12 ? 'PM' : 'AM'; - return short ? meridian[0] : meridian; - }; - let modString = function(boxItem, data) { - let prefix = boxItem.prefix || ''; - let suffix = boxItem.suffix || ''; - return prefix + data + suffix; - }; - let draw = (function() { - let updatePerMinute = true; - return function(boxes) { - date = new Date(); - g.clear(); - background.fillRect(Bangle.appRect); - if (boxes.time) { - boxes.time.string = modString(boxes.time, locale.time(date, isBool(boxes.time.short, true) ? 1 : 0)); - updatePerMinute = isBool(boxes.time.short, true); - } - if (boxes.meridian) { - boxes.meridian.string = modString(boxes.meridian, locale.meridian(date, isBool(boxes.meridian.short, true))); - } - if (boxes.date) { - boxes.date.string = (modString(boxes.date, getDate(isBool(boxes.date.short, true), isBool(boxes.date.shortMonth, true), isBool(boxes.date.disableSuffix, false)))); - } - if (boxes.dow) { - boxes.dow.string = modString(boxes.dow, getDayOfWeek(date, isBool(boxes.dow.short, true))); - } - if (boxes.batt) { - boxes.batt.string = modString(boxes.batt, E.getBattery()); - } - if (boxes.step) { - boxes.step.string = modString(boxes.step, Bangle.getHealthStatus("day").steps); - } - boxKeys.forEach((boxKey) => { - let boxItem = boxes[boxKey]; - calcBoxSize(boxItem); - const pos = calcBoxPos(boxKey); - if (isDragging[boxKey]) { - g.setColor(boxItem.border); - g.drawRect(pos.x1, pos.y1, pos.x2, pos.y2); - } - g.drawString(boxItem, boxItem.string, boxPos[boxKey].x + boxItem.xOffset, boxPos[boxKey].y + boxItem.yOffset); - }); - if (!Object.values(isDragging).some(Boolean)) { - if (drawTimeout) clearTimeout(drawTimeout); - let interval = updatePerMinute ? 60000 - (Date.now() % 60000) : 1000; - drawTimeout = setTimeout(() => draw(boxes), interval); - } - }; - })(); - let touchInText = function(e, boxItem, boxKey) { + }; + + let displaySaveIcon = function() { + draw(boxes); + g.drawImage(saveIcon, w / 2 - 24, h / 2 - 24); + // Display save icon for 2 seconds + setTimeout(() => { + g.clearRect(w / 2 - 24, h / 2 - 24, w / 2 + 24, h / 2 + 24); + draw(boxes); + }, 2000); + }; + + /** + * --------------------------------------------------------------- + * 7. String forming helper functions + * --------------------------------------------------------------- + */ + + let isBool = function(val, defaultVal) { + return typeof val !== 'undefined' ? Boolean(val) : defaultVal; + }; + + let getDate = function(short, shortMonth, disableSuffix) { + const date = new Date(); + const dayOfMonth = date.getDate(); + const month = shortMonth ? locale.month(date, 1) : locale.month(date, 0); + const year = date.getFullYear(); + let suffix; + if ([1, 21, 31].includes(dayOfMonth)) { + suffix = "st"; + } else if ([2, 22].includes(dayOfMonth)) { + suffix = "nd"; + } else if ([3, 23].includes(dayOfMonth)) { + suffix = "rd"; + } else { + suffix = "th"; + } + let dayOfMonthStr = disableSuffix ? dayOfMonth : dayOfMonth + suffix; + return month + " " + dayOfMonthStr + (short ? '' : (", " + year)); // not including year for short version + }; + + let getDayOfWeek = function(date, short) { + return locale.dow(date, short ? 1 : 0); + }; + + locale.meridian = function(date, short) { + let hours = date.getHours(); + let meridian = hours >= 12 ? 'PM' : 'AM'; + return short ? meridian[0] : meridian; + }; + + let modString = function(boxItem, data) { + let prefix = boxItem.prefix || ''; + let suffix = boxItem.suffix || ''; + return prefix + data + suffix; + }; + + /** + * --------------------------------------------------------------- + * 8. Main draw function + * --------------------------------------------------------------- + */ + + let draw = (function() { + let updatePerMinute = true; // variable to track the state of time display + + return function(boxes) { + date = new Date(); + g.clear(); + if (bgImage) { + g.drawImage(bgImage, 0, 0); + } + if (boxes.time) { + boxes.time.string = modString(boxes.time, locale.time(date, isBool(boxes.time.short, true) ? 1 : 0)); + updatePerMinute = isBool(boxes.time.short, true); + } + if (boxes.meridian) { + boxes.meridian.string = modString(boxes.meridian, locale.meridian(date, isBool(boxes.meridian.short, true))); + } + if (boxes.date) { + boxes.date.string = ( + modString(boxes.date, + getDate(isBool(boxes.date.short, true), + isBool(boxes.date.shortMonth, true), + isBool(boxes.date.disableSuffix, false) + ))); + } + if (boxes.dow) { + boxes.dow.string = modString(boxes.dow, getDayOfWeek(date, isBool(boxes.dow.short, true))); + } + if (boxes.batt) { + boxes.batt.string = modString(boxes.batt, E.getBattery()); + } + if (boxes.step) { + boxes.step.string = modString(boxes.step, Bangle.getHealthStatus("day").steps); + } + boxKeys.forEach((boxKey) => { + let boxItem = boxes[boxKey]; calcBoxSize(boxItem); const pos = calcBoxPos(boxKey); - return e.x >= pos.x1 && e.x <= pos.x2 && e.y >= pos.y1 && e.y <= pos.y2; + if (isDragging[boxKey]) { + g.setColor(boxItem.border); + g.drawRect(pos.x1, pos.y1, pos.x2, pos.y2); + } + g.drawString( + boxItem, + boxItem.string, + boxPos[boxKey].x + boxItem.xOffset, + boxPos[boxKey].y + boxItem.yOffset + ); + }); + if (!Object.values(isDragging).some(Boolean)) { + if (drawTimeout) clearTimeout(drawTimeout); + let interval = updatePerMinute ? 60000 - (Date.now() % 60000) : 1000; + drawTimeout = setTimeout(() => draw(boxes), interval); + } }; - let deselectAllBoxes = function() { - Object.keys(isDragging).forEach((boxKey) => { - isDragging[boxKey] = false; - }); - restoreSetColor(); - widgets.show(); - widgets.swipeOn(); - modSetColor(); - }; - let setup = function() { - touchHandler = function(zone, e) { - wasDragging = Object.assign({}, isDragging); - let boxTouched = false; - boxKeys.forEach((boxKey) => { - if (touchInText(e, boxes[boxKey], boxKey)) { - isDragging[boxKey] = true; - wasDragging[boxKey] = true; - boxTouched = true; - } - }); - if (!boxTouched) { - if (!Object.values(isDragging).some(Boolean)) { - deselectAllBoxes(); - if (doubleTapTimer) { - clearTimeout(doubleTapTimer); - doubleTapTimer = null; - Object.keys(boxPos).forEach((boxKey) => { - boxesConfig[boxKey].boxPos.x = (boxPos[boxKey].x / w).toFixed(3); - boxesConfig[boxKey].boxPos.y = (boxPos[boxKey].y / h).toFixed(3); - }); - storage.write(fileName, JSON.stringify(boxesConfig)); - displaySaveIcon(); - return; - } - } else { - deselectAllBoxes(); - } - } - if (Object.values(wasDragging).some(Boolean) || !boxTouched) { - draw(boxes); - } - doubleTapTimer = setTimeout(() => { - doubleTapTimer = null; - }, 500); - movementDistance = 0; - }; - dragHandler = function(e) { - if (!Object.values(isDragging).some(Boolean)) return; - movementDistance += Math.abs(e.dx) + Math.abs(e.dy); - if (movementDistance > 1) { - boxKeys.forEach((boxKey) => { - if (isDragging[boxKey]) { - widgets.hide(); - let boxItem = boxes[boxKey]; - calcBoxSize(boxItem); - let newX = boxPos[boxKey].x + e.dx; - let newY = boxPos[boxKey].y + e.dy; - if (newX - totalWidth / 2 >= 0 && newX + totalWidth / 2 <= w && newY - totalHeight / 2 >= 0 && newY + totalHeight / 2 <= h) { - boxPos[boxKey].x = newX; - boxPos[boxKey].y = newY; - } - const pos = calcBoxPos(boxKey); - g.clearRect(pos.x1, pos.y1, pos.x2, pos.y2); - } - }); - draw(boxes); - } - }; - Bangle.on('touch', touchHandler); - Bangle.on('drag', dragHandler); - Bangle.setUI({ - mode: "clock", - remove: function() { - Bangle.removeListener('touch', touchHandler); - Bangle.removeListener('drag', dragHandler); - if (drawTimeout) clearTimeout(drawTimeout); - drawTimeout = undefined; - delete Graphics.prototype.setFontBrunoAce; - g.drawString = g_drawString; - restoreSetColor(); - widgets.show(); - } - }); - loadCustomFont(); - draw(boxes); - }; - Bangle.loadWidgets(); + })(); + + /** + * --------------------------------------------------------------- + * 9. Helper function for touch event + * --------------------------------------------------------------- + */ + + let touchInText = function(e, boxItem, boxKey) { + calcBoxSize(boxItem); + const pos = calcBoxPos(boxKey); + return e.x >= pos.x1 && + e.x <= pos.x2 && + e.y >= pos.y1 && + e.y <= pos.y2; + }; + + let deselectAllBoxes = function() { + Object.keys(isDragging).forEach((boxKey) => { + isDragging[boxKey] = false; + }); + restoreSetColor(); + widgets.show(); widgets.swipeOn(); modSetColor(); - setup(); + }; + + /** + * --------------------------------------------------------------- + * 10. Setup function to configure event handlers + * --------------------------------------------------------------- + */ + + let setup = function() { + // ------------------------------------ + // Define the touchHandler function + // ------------------------------------ + touchHandler = function(zone, e) { + wasDragging = Object.assign({}, isDragging); + let boxTouched = false; + boxKeys.forEach((boxKey) => { + if (touchInText(e, boxes[boxKey], boxKey)) { + isDragging[boxKey] = true; + wasDragging[boxKey] = true; + boxTouched = true; + } + }); + if (!boxTouched) { + if (!Object.values(isDragging).some(Boolean)) { // check if no boxes are being dragged + deselectAllBoxes(); + if (doubleTapTimer) { + clearTimeout(doubleTapTimer); + doubleTapTimer = null; + // Save boxesConfig on double tap outside of any box and when no boxes are being dragged + Object.keys(boxPos).forEach((boxKey) => { + boxesConfig[boxKey].boxPos.x = (boxPos[boxKey].x / w).toFixed(3); + boxesConfig[boxKey].boxPos.y = (boxPos[boxKey].y / h).toFixed(3); + }); + storage.write(fileName, JSON.stringify(boxesConfig)); + displaySaveIcon(); + return; + } + } else { + // if any box is being dragged, just deselect all without saving + deselectAllBoxes(); + } + } + if (Object.values(wasDragging).some(Boolean) || !boxTouched) { + draw(boxes); + } + doubleTapTimer = setTimeout(() => { + doubleTapTimer = null; + }, 500); // Increase or decrease this value based on the desired double tap timing + movementDistance = 0; + }; + + // ------------------------------------ + // Define the dragHandler function + // ------------------------------------ + dragHandler = function(e) { + // Check if any box is being dragged + if (!Object.values(isDragging).some(Boolean)) return; + // Calculate the movement distance + movementDistance += Math.abs(e.dx) + Math.abs(e.dy); + // Check if the movement distance exceeds a threshold + if (movementDistance > 1) { + boxKeys.forEach((boxKey) => { + if (isDragging[boxKey]) { + widgets.hide(); + let boxItem = boxes[boxKey]; + calcBoxSize(boxItem); + let newX = boxPos[boxKey].x + e.dx; + let newY = boxPos[boxKey].y + e.dy; + if (newX - totalWidth / 2 >= 0 && + newX + totalWidth / 2 <= w && + newY - totalHeight / 2 >= 0 && + newY + totalHeight / 2 <= h ) { + boxPos[boxKey].x = newX; + boxPos[boxKey].y = newY; + } + const pos = calcBoxPos(boxKey); + g.clearRect(pos.x1, pos.y1, pos.x2, pos.y2); + } + }); + draw(boxes); + } + }; + + Bangle.on('touch', touchHandler); + Bangle.on('drag', dragHandler); + + Bangle.setUI({ + mode : "clock", + remove : function() { + // Remove event handlers, stop draw timer, remove custom font if used + Bangle.removeListener('touch', touchHandler); + Bangle.removeListener('drag', dragHandler); + if (drawTimeout) clearTimeout(drawTimeout); + drawTimeout = undefined; + delete Graphics.prototype.setFontBrunoAce; + // Restore original drawString function (no outlines) + g.drawString = g_drawString; + restoreSetColor(); + widgets.show(); + } + }); + loadCustomFont(); + draw(boxes); + }; + + /** + * --------------------------------------------------------------- + * 11. Main execution part + * --------------------------------------------------------------- + */ + + Bangle.loadWidgets(); + widgets.swipeOn(); + modSetColor(); + setup(); } From 438c3b83c8414a23fc2abbdaf9e6a3141347b613 Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Mon, 5 Aug 2024 19:59:44 +0100 Subject: [PATCH 099/110] Revert dropped code --- apps/boxclk/app.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/boxclk/app.js b/apps/boxclk/app.js index 83716fd90..cf2e46df3 100644 --- a/apps/boxclk/app.js +++ b/apps/boxclk/app.js @@ -75,6 +75,8 @@ boxKeys.forEach((key) => { let boxConfig = boxes[key]; boxPos[key] = { + x: w * boxConfig.boxPos.x, + y: h * boxConfig.boxPos.y }; isDragging[key] = false; wasDragging[key] = false; From 2c4e52d720051eb958d101fd9d219e8182532a69 Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Mon, 5 Aug 2024 19:59:57 +0100 Subject: [PATCH 100/110] Apply background/clockbg --- apps/boxclk/app.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/apps/boxclk/app.js b/apps/boxclk/app.js index cf2e46df3..548062349 100644 --- a/apps/boxclk/app.js +++ b/apps/boxclk/app.js @@ -5,6 +5,7 @@ * --------------------------------------------------------------- */ + let background = require("clockbg"); let storage = require("Storage"); let locale = require("locale"); let widgets = require("widget_utils"); @@ -215,9 +216,7 @@ return function(boxes) { date = new Date(); g.clear(); - if (bgImage) { - g.drawImage(bgImage, 0, 0); - } + background.fillRect(Bangle.appRect); if (boxes.time) { boxes.time.string = modString(boxes.time, locale.time(date, isBool(boxes.time.short, true) ? 1 : 0)); updatePerMinute = isBool(boxes.time.short, true); From 93f6dbae7429002130363a4413e7357f3dd01385 Mon Sep 17 00:00:00 2001 From: Septolum Date: Tue, 6 Aug 2024 13:32:15 +0100 Subject: [PATCH 101/110] Add date display --- apps/lato/app.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/apps/lato/app.js b/apps/lato/app.js index 88e723a78..cabddd3ef 100644 --- a/apps/lato/app.js +++ b/apps/lato/app.js @@ -38,9 +38,12 @@ Graphics.prototype.setFontLatoSmall = function(scale) { // must be inside our own scope here so that when we are unloaded everything disappears // we also define functions using 'let fn = function() {..}' for the same reason. function decls are global - let draw = function() { + let draw = function() { + //require('DateExt') var date = new Date(); var timeStr = require("locale").time(date,1); + var dateStr = require("locale").dow(date,1) + ', ' + date.getDate() + ' ' + require("locale").month(date,1); + //var dateStr = date.as("T, D C").str; var h = g.getHeight(); var w = g.getWidth(); @@ -53,6 +56,10 @@ Graphics.prototype.setFontLatoSmall = function(scale) { g.setFontAlign(0, 0); g.setColor(g.theme.fg); g.drawString(timeStr, w/2, h/2); + + g.setFontVector(16); + g.drawString(dateStr, w/2, h/4 -4); + clockInfoMenu.redraw(); // clock_info_support // schedule a draw for the next minute From 734e64ec535219abd608d455c8ab18b21f23c9f9 Mon Sep 17 00:00:00 2001 From: Septolum Date: Tue, 6 Aug 2024 13:34:55 +0100 Subject: [PATCH 102/110] Remove commented out alt method (slower code) --- apps/lato/app.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/apps/lato/app.js b/apps/lato/app.js index cabddd3ef..87ff9a5d8 100644 --- a/apps/lato/app.js +++ b/apps/lato/app.js @@ -38,12 +38,10 @@ Graphics.prototype.setFontLatoSmall = function(scale) { // must be inside our own scope here so that when we are unloaded everything disappears // we also define functions using 'let fn = function() {..}' for the same reason. function decls are global - let draw = function() { - //require('DateExt') + let draw = function() { var date = new Date(); var timeStr = require("locale").time(date,1); var dateStr = require("locale").dow(date,1) + ', ' + date.getDate() + ' ' + require("locale").month(date,1); - //var dateStr = date.as("T, D C").str; var h = g.getHeight(); var w = g.getWidth(); From 77fded87dc5936f6d23e9277942536c9de45bbe5 Mon Sep 17 00:00:00 2001 From: Septolum Date: Tue, 6 Aug 2024 18:42:53 +0100 Subject: [PATCH 103/110] Add date settings, update readme --- apps/lato/README.md | 5 +++++ apps/lato/app.js | 25 ++++++++++++++++++++++--- apps/lato/metadata.json | 8 ++++++-- apps/lato/screenshot4.png | Bin 0 -> 1542 bytes apps/lato/settings.js | 24 ++++++++++++++++++++++++ 5 files changed, 57 insertions(+), 5 deletions(-) create mode 100644 apps/lato/screenshot4.png create mode 100644 apps/lato/settings.js diff --git a/apps/lato/README.md b/apps/lato/README.md index 556ee6fbc..1dc571509 100644 --- a/apps/lato/README.md +++ b/apps/lato/README.md @@ -5,6 +5,7 @@ A simple clock with the Lato font, with fast load and clock_info ![](screenshot1.png) ![](screenshot2.png) ![](screenshot3.png) +![](screenshot4.png) This clock is a Lato version of Simplest++. Simplest++ provided the smallest example of a clock that supports 'fast load' and 'clock @@ -25,6 +26,8 @@ Pastel Clock. * Settings are saved automatically and reloaded along with the clock. +* Date display can be enabled and disabled, along with format choice in the app settings + ## About Clock Info's * The clock info modules enable all clocks to add the display of information to the clock face. @@ -52,3 +55,5 @@ Pastel Clock. Written by: [Hugh Barney](https://github.com/hughbarney) For support and discussion please post in the [Bangle JS Forum](http://forum.espruino.com/microcosms/1424/) + +Date functionality added by [Septolum](https://github.com/Septolum) diff --git a/apps/lato/app.js b/apps/lato/app.js index 87ff9a5d8..369cba17f 100644 --- a/apps/lato/app.js +++ b/apps/lato/app.js @@ -38,10 +38,14 @@ Graphics.prototype.setFontLatoSmall = function(scale) { // must be inside our own scope here so that when we are unloaded everything disappears // we also define functions using 'let fn = function() {..}' for the same reason. function decls are global + let settings = Object.assign({ + dateDisplay: false, + dateFormat: 0, + }, require("Storage").readJSON("lato.json", true) || {}); + let draw = function() { var date = new Date(); var timeStr = require("locale").time(date,1); - var dateStr = require("locale").dow(date,1) + ', ' + date.getDate() + ' ' + require("locale").month(date,1); var h = g.getHeight(); var w = g.getWidth(); @@ -55,8 +59,23 @@ Graphics.prototype.setFontLatoSmall = function(scale) { g.setColor(g.theme.fg); g.drawString(timeStr, w/2, h/2); - g.setFontVector(16); - g.drawString(dateStr, w/2, h/4 -4); + if (settings.dateDisplay) { + switch (settings.dateFormat) { + case 1: + var dateStr = require("locale").date(date,1); + break; + + case 2: + var dateStr = require("locale").date(date); + break; + + default: + var dateStr = require("locale").dow(date,1) + ', ' + date.getDate() + ' ' + require("locale").month(date,1); + break; + } + g.setFontVector(16); + g.drawString(dateStr, w/2, h/4 -4); + } clockInfoMenu.redraw(); // clock_info_support diff --git a/apps/lato/metadata.json b/apps/lato/metadata.json index 406413790..baeb5d3ea 100644 --- a/apps/lato/metadata.json +++ b/apps/lato/metadata.json @@ -1,7 +1,7 @@ { "id": "lato", "name": "Lato", - "version": "0.03", + "version": "0.04", "description": "A Lato Font clock with fast load and clock_info", "readme": "README.md", "icon": "app.png", @@ -12,6 +12,10 @@ "dependencies" : { "clock_info":"module" }, "storage": [ {"name":"lato.app.js","url":"app.js"}, - {"name":"lato.img","url":"icon.js","evaluate":true} + {"name":"lato.img","url":"icon.js","evaluate":true}, + {"name":"lato.settings.js","url":"settings.js"} + ], + "data": [ + {"name":"lato.json"} ] } diff --git a/apps/lato/screenshot4.png b/apps/lato/screenshot4.png new file mode 100644 index 0000000000000000000000000000000000000000..5fc70fb1824acf78ae65bca8f5d95398773905c5 GIT binary patch literal 1542 zcmY+EdpOg39LLvOms{aPb5NLTgpTBKt!6V~Az_&1pu*hC-TI|EsYn=ELl-CHnqj$2 zQ}m?mRI*$)+qAP>j)!TbB?o67r{_H9^E{vT`}2JM{CvN!cm8o7q{?>ab`S`pg7Sd- zNxgNm73HPcLKR}ACLiI2giBpoD@S_>QiCLV1gC&NN*bHJ4MZYqOP30%C~tR#Sw;Ds zd(<2i#*9HAxe^ro@QHNx0ym_%;gF`>@WKASYmX5EF16%Q3wahB-SIlIMtAZ+a}+%1 ztNvTF>tP_U3^8Z{3}0HwZnN5`dq3_H<(fpqe`;ubt#+x3S^Z`vK*bxUiROm~^Iy#ytGV4BKj;M0&?TS9&1JA9oj$C z4YxTL9Q8VI8BbkRZM#l$3jSQ~>H&tH;duRS~@tgm! zsL?S>r}~RkD4v47is(vl^Hja8+131jca_B12RQnyVyUn|{U^}dz3#DMJt`XPXw&23 z09zWkQ55zaIE=eM2mPztzX!D&7i4}Tk=@sTPv;c=K2z!H zuajk5-a8>@ygxa7+pdVB+LLbZMnXj})+BgiHLWt>Y6ZG&mwZxw%yUm{`9>9|Z^y-6 z+I!kPaC!F$A+HOeHH+p&0z=o?fr6;>8Ia+$2?}$MsLuZAfpXP*_DM}jHhyz&N7gNe zdFO<>4U4)@nbK!vKc^?!r8T1I`4h>E~jjXAw&%*uCzHp`K0joPuj)51Q?ixLa?KurNdS)s0` z_w+n;ZM7SU#~{n8C)qQL2uBQ$o3FxeuN^R&MRPg|trD78UST2*pI>eBPUH_|f z{9Z~)@=vj+!uK04q>5iK%6g7@IY-Z%il^BVp2SX@UUQPA{-UfpuovLg0Q9O^E~BnX$lQSg^gH3u`(-I2gW?tQJ|>h6SVdNrEFD zhCUP3Bor>IKRF_x(S*qDxvWCbQ$B6db>bmwSv}~c`>3V@aL30$>~fm4lkK%ViG`Q6 z2Y&FjBzI#W`zpeTCce%Z6z7+_t$>zkTSmrl!kDfdbx>q0$%Gn=a-yb~hX&mi%!1y? zI%77tws!|QQB$7x%bYGCixJG?jIU>$GHEeWfPd$*-p$>f5c?!Km^oL&HhIpvm!6=C zdA&0Ex@_%>C8ZR}kk#{8A}dH1K4ys?f92SZN8@zE-ZjW@Unze|>v?9tE6{!fA1T;H zX!W=HU?zC|&6FL {save('dateDisplay', v)} + }, + "Date Format": { + value: settings.dateFormat, + min: 0, max: 2, + format: v => ["DoW, dd MMM","Locale Short","Locale Long"][v], + onchange: (v) => {save('dateFormat', v)} + } + }; + E.showMenu(appMenu) + }) \ No newline at end of file From 2d26028e24046af42abe4b5b00c9a6d5cd649e3a Mon Sep 17 00:00:00 2001 From: Septolum Date: Tue, 6 Aug 2024 21:52:42 +0100 Subject: [PATCH 104/110] Update changelog --- apps/lato/ChangeLog | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/lato/ChangeLog b/apps/lato/ChangeLog index 686f3b707..814b06b31 100644 --- a/apps/lato/ChangeLog +++ b/apps/lato/ChangeLog @@ -1,3 +1,4 @@ 0.01: first release 0.02: Use clock_info module as an app -0.03: clock_info now uses app name to maintain settings specifically for this clock face \ No newline at end of file +0.03: clock_info now uses app name to maintain settings specifically for this clock face +0.04: add optional date display, and a settings page to configure it \ No newline at end of file From 477165153a30a62d442f7b6ed6736cde3a94e229 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Wed, 7 Aug 2024 08:52:35 +0100 Subject: [PATCH 105/110] 2v24 crc --- apps/fwupdate/custom.html | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/fwupdate/custom.html b/apps/fwupdate/custom.html index 6c47cf3f2..606e59d89 100644 --- a/apps/fwupdate/custom.html +++ b/apps/fwupdate/custom.html @@ -106,6 +106,7 @@ function onInit(device) { else if (crcs[0] == 3816337552) version = "2v21"; else if (crcs[0] == 3329616485) version = "2v22"; else if (crcs[0] == 1569433504) version = "2v23"; + else if (crcs[0] == 680675961) version = "2v24"; else { // for other versions all 7 pages are used, check those var crc = crcs[1]; if (crc==1339551013) { version = "2v10.219"; ok = false; } From 3a18309f9a4ea5df9c02f4d346bc89fd6b086292 Mon Sep 17 00:00:00 2001 From: Gordon Williams Date: Wed, 7 Aug 2024 08:56:54 +0100 Subject: [PATCH 106/110] 2v24 latest version --- loader.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/loader.js b/loader.js index d63610ade..1f3350656 100644 --- a/loader.js +++ b/loader.js @@ -16,7 +16,7 @@ if (window.location.host=="banglejs.com") { 'This is not the official Bangle.js App Loader - you can try the Official Version here.'; } -var RECOMMENDED_VERSION = "2v23"; +var RECOMMENDED_VERSION = "2v24"; // could check http://www.espruino.com/json/BANGLEJS.json for this // We're only interested in Bangles From 5dac7b26240b79fb210db75532ae86c0c77ab81f Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Sat, 10 Aug 2024 15:54:12 +0100 Subject: [PATCH 107/110] promenu: return a scroller (fixes alarms app) --- apps/promenu/bootb2.js | 5 +++++ apps/promenu/bootb2.ts | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/apps/promenu/bootb2.js b/apps/promenu/bootb2.js index 9909d2af3..faf989597 100644 --- a/apps/promenu/bootb2.js +++ b/apps/promenu/bootb2.js @@ -28,6 +28,9 @@ E.showMenu = function (items) { y += 22; var lastIdx = 0; var selectEdit = undefined; + var scroller = { + scroll: selected, + }; var l = { draw: function (rowmin, rowmax) { var rows = 0 | Math.min((y2 - y) / fontHeight, menuItems.length); @@ -138,9 +141,11 @@ E.showMenu = function (items) { else { var lastSelected = selected; selected = (selected + dir + menuItems.length) % menuItems.length; + scroller.scroll = selected; l.draw(Math.min(lastSelected, selected), Math.max(lastSelected, selected)); } }, + scroller: scroller, }; l.draw(); var back = options.back; diff --git a/apps/promenu/bootb2.ts b/apps/promenu/bootb2.ts index 9342d2ec9..ac89f7033 100644 --- a/apps/promenu/bootb2.ts +++ b/apps/promenu/bootb2.ts @@ -35,6 +35,10 @@ E.showMenu = (items?: Menu): MenuInstance => { let lastIdx = 0; let selectEdit: undefined | ActualMenuItem = undefined; + const scroller = { + scroll: selected, + }; + const l = { draw: (rowmin?: number, rowmax?: number) => { let rows = 0|Math.min((y2 - y) / fontHeight, menuItems.length); @@ -156,9 +160,11 @@ E.showMenu = (items?: Menu): MenuInstance => { } else { const lastSelected = selected; selected = (selected + dir + /*keep +ve*/menuItems.length) % menuItems.length; + scroller.scroll = selected; l.draw(Math.min(lastSelected, selected), Math.max(lastSelected, selected)); } }, + scroller, }; l.draw(); From c6d4713f5bd673f2ebc9eb582f27545a102593d7 Mon Sep 17 00:00:00 2001 From: Rob Pilling Date: Sat, 10 Aug 2024 16:19:30 +0100 Subject: [PATCH 108/110] promenu: only calculate offsets for plain (non-image) strings This fixes the alarm app, for example, which shows images within the strings --- apps/promenu/bootb2.js | 5 +++-- apps/promenu/bootb2.ts | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/apps/promenu/bootb2.js b/apps/promenu/bootb2.js index faf989597..434f0c07f 100644 --- a/apps/promenu/bootb2.js +++ b/apps/promenu/bootb2.js @@ -79,10 +79,11 @@ E.showMenu = function (items) { v = ""; } { - if (name.length >= 17 - v.length && typeof item === "object") { + var vplain = v.indexOf("\0") < 0; + if (vplain && name.length >= 17 - v.length && typeof item === "object") { g.drawString(name.substring(0, 12 - v.length) + "...", x + 3.7, iy + 2.7); } - else if (name.length >= 15) { + else if (vplain && name.length >= 15) { g.drawString(name.substring(0, 15) + "...", x + 3.7, iy + 2.7); } else { diff --git a/apps/promenu/bootb2.ts b/apps/promenu/bootb2.ts index ac89f7033..11ae56e1b 100644 --- a/apps/promenu/bootb2.ts +++ b/apps/promenu/bootb2.ts @@ -87,9 +87,10 @@ E.showMenu = (items?: Menu): MenuInstance => { } /*???*/{ - if(name.length >= 17 - v.length && typeof item === "object"){ + const vplain = v.indexOf("\0") < 0; + if(vplain && name.length >= 17 - v.length && typeof item === "object"){ g.drawString(name.substring(0, 12 - v.length) + "...", x + 3.7, iy + 2.7); - }else if(name.length >= 15){ + }else if(vplain && name.length >= 15){ g.drawString(name.substring(0, 15) + "...", x + 3.7, iy + 2.7); }else{ g.drawString(name, x + 3.7, iy + 2.7); From cd6b31f1efbd2bc59643ac2729ad18bf6b9120c8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Aug 2024 00:57:09 +0000 Subject: [PATCH 109/110] build(deps): bump core from `1cdcb34` to `294690a` Bumps [core](https://github.com/espruino/EspruinoAppLoaderCore) from `1cdcb34` to `294690a`. - [Commits](https://github.com/espruino/EspruinoAppLoaderCore/compare/1cdcb3405f78ef35f231b9c3df501721bda75525...294690a4f0257cfb2221770b2e48eb20404e6a68) --- updated-dependencies: - dependency-name: core dependency-type: direct:production ... Signed-off-by: dependabot[bot] --- core | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core b/core index 1cdcb3405..294690a4f 160000 --- a/core +++ b/core @@ -1 +1 @@ -Subproject commit 1cdcb3405f78ef35f231b9c3df501721bda75525 +Subproject commit 294690a4f0257cfb2221770b2e48eb20404e6a68 From d40a0100b8ee70d708eee0f2bfba35f7b61bf6fc Mon Sep 17 00:00:00 2001 From: Anton Date: Thu, 15 Aug 2024 12:21:58 +0200 Subject: [PATCH 110/110] gipy: Fix lint issues --- apps/gipy/app.js | 6 +++--- apps/lint_exemptions.js | 6 ------ 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/apps/gipy/app.js b/apps/gipy/app.js index 4bd1adbeb..cbc2c1bcd 100644 --- a/apps/gipy/app.js +++ b/apps/gipy/app.js @@ -660,11 +660,11 @@ class Status { towards = next_point; } let diff = towards.minus(this.projected_point); - direction = Math.atan2(diff.lat, diff.lon); + const direction = Math.atan2(diff.lat, diff.lon); let full_angle = direction - this.angle; - c = this.projected_point.coordinates( + const c = this.projected_point.coordinates( this.displayed_position, this.adjusted_cos_direction, this.adjusted_sin_direction, @@ -1394,7 +1394,7 @@ function ask_options(fn) { g.flip(); function options_select(b, xy) { - end = false; + let end = false; if (xy.y < height / 2 - 10) { g.setColor(0, 0, 0).fillRect(10, 10, width - 10, height / 2 - 10); g.setColor(1, 1, 1).setFont("Vector:30").setFontAlign(0,0).drawString("Forward", width/2, height/4); diff --git a/apps/lint_exemptions.js b/apps/lint_exemptions.js index 3b7da1a20..b3503de72 100644 --- a/apps/lint_exemptions.js +++ b/apps/lint_exemptions.js @@ -1015,12 +1015,6 @@ module.exports = { "no-undef" ] }, - "apps/gipy/app.js": { - "hash": "41f342e8ef6f2a87b3aea19b75ee45cfdfeff723b94281049e3ae0ec89cddba5", - "rules": [ - "no-undef" - ] - }, "apps/geissclk/precompute.js": { "hash": "2317812a9e348e7883e93a4be9e294ad7accd4dc3f0e31ee00343e2412030f98", "rules": [