diff --git a/apps/7x7dotsclock/7x7dotsclock.app.js b/apps/7x7dotsclock/7x7dotsclock.app.js new file mode 100644 index 000000000..3f2e9b9b1 --- /dev/null +++ b/apps/7x7dotsclock/7x7dotsclock.app.js @@ -0,0 +1,356 @@ +/* +7x7DotsClock + +by Peter Kuppelwieser + +*/ + +let settings = Object.assign({ swupApp: "",swdownApp: "", swleftApp: "", swrightApp: ""}, require("Storage").readJSON("7x7dotsclock.json", true) || {}); + +// position on screen +var Xs = 0, Ys = 30,Xe = 175, Ye=175; +//const Xs = 0, Ys = 0,Xe = 175, Ye=175; +var SegH = (Ye-Ys)/2,SegW = (Xe-Xs)/2; +var Dx = SegW/14, Dy = SegH/16; + +const hColor = [1,1,1]; +const mColor = [0.3,0.3,1]; +const bColor = [0.2,0.2,0.2]; + +const Font = [ + [ + [1,1,1,1,1,1,1], + [1,1,1,1,1,1,1], + [1,1,0,0,0,1,1], + [1,1,0,0,0,1,1], + [1,1,0,0,0,1,1], + [1,1,1,1,1,1,1], + [1,1,1,1,1,1,1] + ], + [ + [0,0,0,1,1,0,0], + [0,0,0,1,1,0,0], + [0,0,0,1,1,0,0], + [0,0,0,1,1,0,0], + [0,0,0,1,1,0,0], + [0,0,0,1,1,0,0], + [0,0,0,1,1,0,0], + ], + [ + [1,1,1,1,1,1,1], + [1,1,1,1,1,1,1], + [0,0,0,0,0,1,1], + [1,1,1,1,1,1,1], + [1,1,0,0,0,0,0], + [1,1,1,1,1,1,1], + [1,1,1,1,1,1,1] + ], + [ + [1,1,1,1,1,1,1], + [1,1,1,1,1,1,1], + [0,0,0,0,0,1,1], + [0,0,0,1,1,1,1], + [0,0,0,0,0,1,1], + [1,1,1,1,1,1,1], + [1,1,1,1,1,1,1] + ], + [ + [1,1,0,0,0,0,0], + [1,1,0,0,0,0,0], + [1,1,0,1,1,0,0], + [1,1,1,1,1,1,1], + [1,1,1,1,1,1,1], + [0,0,0,1,1,0,0], + [0,0,0,1,1,0,0] + ], + [ + [1,1,1,1,1,1,1], + [1,1,1,1,1,1,1], + [1,1,0,0,0,0,0], + [1,1,1,1,1,1,1], + [0,0,0,0,0,1,1], + [1,1,1,1,1,1,1], + [1,1,1,1,1,1,1] + ], + [ + [1,1,0,0,0,0,0], + [1,1,0,0,0,0,0], + [1,1,0,0,0,0,0], + [1,1,1,1,1,1,1], + [1,1,0,0,0,1,1], + [1,1,1,1,1,1,1], + [1,1,1,1,1,1,1] + ], + [ + [1,1,1,1,1,1,1], + [1,1,1,1,1,1,1], + [0,0,0,0,0,1,1], + [0,0,0,0,0,1,1], + [0,0,0,0,0,1,1], + [0,0,0,0,0,1,1], + [0,0,0,0,0,1,1] + ], + [ + [1,1,1,1,1,1,1], + [1,1,1,1,1,1,1], + [1,1,0,0,0,1,1], + [1,1,1,1,1,1,1], + [1,1,0,0,0,1,1], + [1,1,1,1,1,1,1], + [1,1,1,1,1,1,1] + ], + [ + [1,1,1,1,1,1,1], + [1,1,1,1,1,1,1], + [1,1,0,0,0,1,1], + [1,1,1,1,1,1,1], + [1,1,1,1,1,1,1], + [0,0,0,0,0,1,1], + [0,0,0,0,0,1,1] + ], + ]; + +// Global Vars +var dho = -1, eho = -1, dmo = -1, emo = -1; + + +function drawHSeg(x1,y1,x2,y2,Num,dColor,Size) { + g.setColor(0,0,0); + g.fillRect(x1, y1, x2, y2); + for (let i = 1; i < 8; i++) { + for (let j = 1; j < 8; j++) { + if (Font[Num][j-1][i-1] == 1) { + g.setColor(dColor[0],dColor[1],dColor[2]); + g.fillCircle(x1+Dx+(i-1)*(x2-x1)/7,y1+Dy+(j-1)*(y2-y1)/7,Size); + } else { + g.setColor(bColor[0],bColor[1],bColor[2]); + g.fillCircle(x1+Dx+(i-1)*(x2-x1)/7,y1+Dy+(j-1)*(y2-y1)/7,1); + } + } + } +} + + +function drawSSeg(x1,y1,x2,y2,Num,dColor,Size) { + for (let i = 1; i < 8; i++) { + for (let j = 1; j < 8; j++) { + if (Font[Num][j-1][i-1] == 1) { + g.setColor(dColor[0],dColor[1],dColor[2]); + g.fillCircle(x1+(i-1)*(x2-x1)/7,y1+(j-1)*(y2-y1)/7,Size); + } + } + } +} + + +function ShowSecons() { + g.setColor(1,1,1); + g.fillRect((Xe-Xs) / 2 - 14 + Xs -3, + (Ye-Ys) / 2 - 7 + Ys -3, + (Xe-Xs) / 2 + 14 + Xs +1, + (Ye-Ys) / 2 + 7 + Ys +1); + + + drawSSeg( (Xe-Xs) / 2 - 14 + Xs -1, + (Ye-Ys) / 2 - 7 + Ys , + (Xe-Xs) / 2 + Xs -1, + (Ye-Ys) / 2 + 7 + Ys, + ds,mColor,1); + + drawSSeg( (Xe-Xs) / 2 + Xs +1, + (Ye-Ys) / 2 - 7 + Ys, + (Xe-Xs) / 2 + 14 + Xs +1, + (Ye-Ys) / 2 + 7 + Ys, + es,mColor,1); + +} + +function draw() { + // work out how to display the current time + var d = new Date(); + var h = d.getHours(), m = d.getMinutes(), s = d.getSeconds(); + + + dh = Math.floor(h/10); + eh = h - dh * 10; + + dm = Math.floor(m/10); + em = m - dm * 10; + + ds = Math.floor(s/10); + es = s - ds * 10; + + + // Reset the state of the graphics library + g.reset(); + if (dh != dho) { + g.setColor(1,1,1); + drawHSeg(Xs, Ys, Xs+SegW, Ys+SegH,dh,hColor,4); + dho = dh; + } + + if (eh != eho) { + g.setColor(1,1,1); + drawHSeg(Xs+SegW+Dx, Ys, Xs+SegW*2, Ys+SegH,eh,hColor,4); + eho = eh; + } + + if (dm != dmo) { + g.setColor(0.3,0.3,1); + drawHSeg(Xs, Ys+SegH+Dy, Xs+SegW, Ys+SegH*2,dm,mColor,4); + dmo = dm; + } + + if (em != emo) { + g.setColor(0.3,0.3,1); + drawHSeg(Xs+SegW+Dx, Ys+SegH+Dy, Xs+SegW*2, Ys+SegH*2,em,mColor,4); + emo = em; + } + + if (!Bangle.isLocked()) ShowSecons(); + +} + + +function actions(v){ + if(BTN1.read() === true) { + print("BTN pressed"); + Bangle.showLauncher(); + } + + if(v==-1){ + print("up swipe event"); + if(settings.swupApp != "") load(settings.swupApp); + print(settings.swupApp); + } else if(v==1) { + print("down swipe event"); + if(settings.swdownApp != "") load(settings.swdownApp); + print(settings.swdownApp); + } else { + print("touch event"); + } +} + +// Get Messages status +var messages = require("Storage").readJSON("messages.json",1)||[]; + +//var BTconnected = NRF.getSecurityStatus().connected; +//NRF.on('connect',BTconnected = NRF.getSecurityStatus().connected); +//NRF.on('disconnect',BTconnected = NRF.getSecurityStatus().connected); + + +function drawWidgeds() { + + //Bluetooth + //print(BluetoothDevice.connected); + var x1Bt = 160; + var y1Bt = 0; + var x2Bt = x1Bt + 30; + var y2Bt = y2Bt; + + if (NRF.getSecurityStatus().connected) + g.setColor((g.getBPP()>8) ? "#07f" : (g.theme.dark ? "#0ff" : "#00f")); + else + g.setColor(g.theme.dark ? "#666" : "#999"); + g.drawImage(atob("CxQBBgDgFgJgR4jZMawfAcA4D4NYybEYIwTAsBwDAA=="),x1Bt,y1Bt); + + + //Battery + //print(E.getBattery()); + //print(Bangle.isCharging()); + + var x1B = 130; + var y1B = 2; + var x2B = x1B + 20; + var y2B = y1B + 15; + + g.setColor(g.theme.bg); + g.clearRect(x1B,y1B,x2B,y2B); + + g.setColor(g.theme.fg); + g.drawRect(x1B,y1B,x2B,y2B); + g.fillRect(x1B,y1B,x1B+(E.getBattery()*(x2B-x1B)/100),y2B); + g.fillRect(x2B,y1B+(y2B-y1B)/2-3,x2B+4,y1B+(y2B-y1B)/2+3); + + + + //Messages + + var x1M = 100; + var y1M = y1B; + var x2M = x1M + 30; + var y2M = y2B; + + if (messages.some(m=>m.new)) { + g.setColor(g.theme.fg); + g.fillRect(x1M,y1M,x2M,y2M); + g.setColor(g.theme.bg); + g.drawLine(x1M,y1M,x1M+(x2M-x1M)/2,y1M+(y2M-y1M)/2); + g.drawLine(x1M+(x2M-x1M)/2,y1M+(y2M-y1M)/2,x2M,y1M); + } + + var strDow = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat']; + var d = new Date(); + var dow = d.getDay(),day = d.getDate(), month = d.getMonth() + 1, year = d.getFullYear(); + + print(strDow[dow] + ' ' + day + '.' + month + ' ' + year); + + g.setFontAlign(-1, -1,0); + g.setFont("Vector", 20); + g.drawString(strDow[dow] + ' ' + day, 0, 0, true); + +} + + + + +function SetFull(on) { + dho = -1; eho = -1; dmo = -1; emo = -1; + g.clear(); + + if (on === true) { + Ys = 0; + Bangle.setUI("clock"); + Bangle.on('swipe', function(direction) { }); + + } else { + Ys = 30; + Bangle.setUI("updown",actions); + Bangle.on('swipe', function(direction) { + switch (direction) { + case 1: + print("swipe left event"); + if(settings.swleftApp != "") load(settings.swleftApp); + print(settings.swleftApp); + break; + case -1: + print("swipe right event"); + if(settings.swrightApp != "") load(settings.swrightApp); + print(settings.swrightApp); + break; + default: + print("swipe undefined event"); + } + }); + } + + SegH = (Ye-Ys)/2; + Dy = SegH/16; + + draw(); + + if (on != true) { + //Bangle.loadWidgets(); + //Bangle.drawWidgets(); + drawWidgeds(); + } +} + +Bangle.on('lock', function(on) { + SetFull(on); +}); + + +SetFull(Bangle.isLocked()); + +var secondInterval = setInterval(draw, 1000); diff --git a/apps/7x7dotsclock/7x7dotsclock.img.js b/apps/7x7dotsclock/7x7dotsclock.img.js new file mode 100644 index 000000000..b1f91c0bb --- /dev/null +++ b/apps/7x7dotsclock/7x7dotsclock.img.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwwkEBAkTmEzkAHDmcjmQBBmcTmICCgMAiMAkE/+P/mEQgMQgH/n/zAIP/l/yA4QvXC4kDkEjFgIACkcSmMTkMyBoQHBI4kvI6wXBn8wA4c/mfzl8y+cfEoIaBVa5HBAAMQF4UgIoIBBBgJNBAwQ3BkfygSnJSQIUBkECiBoCL48DmCPFAA6PCX40jX4hYEU4LNBX4JHIkBHCBgJHBianKj8wO4IvHgSnBmJ3CHYqGCABcRcYTXLAA5KCFAJfCC4KnDX4anNgUgiSnMkQQBO5hvCl8yO4pHEd4oyBH4QBBU5TXHkcimUTkLXFL44HEiTbBO4MhBoQHBI4KECR45HGBoIFBU4y/BC4c/mYXGMQJHFiBHLEAIHCf5gAKhWg1UB0IEBjUA0MB0EAjQKCiANCCQOg0cxmcSmWjU4MqmcDmSnDBASkBmejCQIXFmYXEmYXHicyhRLC0AEBAIJFBAIIFCBAYHDF65fXR66vImUCnS8IkeinUBgERgEgcIMBgRHDBgLvCBYMQmcjBYIAHfwL7JiQLBichkcSnUSO4MhI4MxI5MSmMjPgMinCnCkRHGIgJHFiUgkUalUCAgMRkUCkIvIkUSkMC0EiBxAAI0UKkBHCkCPDgA+CI5Z3BmYPBAB53CV4MSEgcSiCnOR4cyR5JQEgBHCC4I0BC4UjC4MCxQXGF4IlBxRHB0UAlUK0BMBkIEBI5ILB0ZHBF4czlTXHI4mjCQIXOH4KnDC4MKgGqgGgAgIBBIoJHJBoQ=")) diff --git a/apps/7x7dotsclock/7x7dotsclock.settings.js b/apps/7x7dotsclock/7x7dotsclock.settings.js new file mode 100644 index 000000000..42473ec17 --- /dev/null +++ b/apps/7x7dotsclock/7x7dotsclock.settings.js @@ -0,0 +1,65 @@ +(function(back) { + +let settings = Object.assign({ swupApp: "",swdownApp: "", swleftApp: "", swrightApp: ""}, require("Storage").readJSON("7x7dotsclock.json", true) || {}); + + +function showMainMenu() { + const mainMenu = { + "": {"title": "7x7 Dots Clock Settings"}, + "< Back": ()=>load(), + "sw-up": ()=>showSelAppMenu("swupApp"), + "sw-down": ()=>showSelAppMenu("swdownApp"), + "sw-left": ()=>showSelAppMenu("swleftApp"), + "sw-right": ()=>showSelAppMenu("swrightApp") + + }; + + E.showMenu(mainMenu); +} + +function setSetting(key,value) { + print("call " + key + " = " + value); + settings[key] = value; + + print("storing settings 7x7dotsclock.json"); + storage.write('7x7dotsclock.json', settings); +} + + +function showSelAppMenu(key) { + var Apps = require("Storage").list(/\.info$/) + .map(app => {var a=storage.readJSON(app, 1);return ( + a&&a.name != "Launcher" + && a&&a.name != "Bootloader" + && a&&a.type != "clock" + && a&&a.type !="widget" + )?a:undefined}) + .filter(app => app) // filter out any undefined apps + .sort((a, b) => a.sortorder - b.sortorder); + const SelAppMenu = { + '': { + 'title': /*LANG*/'Select App', + }, + '< Back': ()=>showMainMenu(), + }; + Apps.forEach((app, index) => { + var label = app.name; + if (settings[key] === app.src) { + label = "* " + label; + } + SelAppMenu[label] = () => { + if (settings[key] !== app.src) { + setSetting(key,app.src); + showMainMenu(); + } + }; + }); + if (Apps.length === 0) { + SelAppMenu[/*LANG*/"No Apps Found"] = () => { }; + } + return E.showMenu(SelAppMenu); +} + +showMainMenu(); + +}) diff --git a/apps/7x7dotsclock/ChangeLog b/apps/7x7dotsclock/ChangeLog new file mode 100644 index 000000000..50c5eca4a --- /dev/null +++ b/apps/7x7dotsclock/ChangeLog @@ -0,0 +1 @@ +0.01: Initial version for upload diff --git a/apps/7x7dotsclock/README.md b/apps/7x7dotsclock/README.md new file mode 100644 index 000000000..7f899ff0f --- /dev/null +++ b/apps/7x7dotsclock/README.md @@ -0,0 +1,17 @@ +# 7x7 dots clock + +![](dotsfontclock.png) + +looks best with dark theme so far + +* A Clock with big numbers made of 7x7 dots +* system widgeds ar not (yet) supported +* when screen is locked it shows hours and minutes in full screen mode + +![](dotsfontclock-scr1.png) + +* when screen is unlocked it shows additional info: bluetooth, battery, new message, date and seconds +* you can configure a app per swipe direction +* when swiping the configured apps are launced +* button press opens launcher + diff --git a/apps/7x7dotsclock/dotsfontclock-scr1.png b/apps/7x7dotsclock/dotsfontclock-scr1.png new file mode 100644 index 000000000..dc86396c0 Binary files /dev/null and b/apps/7x7dotsclock/dotsfontclock-scr1.png differ diff --git a/apps/7x7dotsclock/dotsfontclock.png b/apps/7x7dotsclock/dotsfontclock.png new file mode 100644 index 000000000..af8fa61ba Binary files /dev/null and b/apps/7x7dotsclock/dotsfontclock.png differ diff --git a/apps/7x7dotsclock/metadata.json b/apps/7x7dotsclock/metadata.json new file mode 100644 index 000000000..7b2c52512 --- /dev/null +++ b/apps/7x7dotsclock/metadata.json @@ -0,0 +1,17 @@ +{ "id": "7x7dotsclock", + "name": "7x7 Dots Clock", + "shortName":"7x7 Dots Clock", + "version":"0.01", + "description": "A clock with a big 7x7 dots Font", + "icon": "dotsfontclock.png", + "tags": "clock", + "type": "clock", + "supports" : ["BANGLEJS2"], + "readme": "README.md", + "storage": [ + {"name":"7x7dotsclock.app.js","url":"7x7dotsclock.app.js"}, + {"name":"7x7dotsclock.settings.js","url":"7x7dotsclock.settings.js"}, + {"name":"7x7dotsclock.img","url":"7x7dotsclock.img.js","evaluate":true} + ], + "data": [{"name":"7x7dotsclock.json"}] +} diff --git a/apps/antonclk/ChangeLog b/apps/antonclk/ChangeLog index 4dca8053e..ac49dcbd7 100644 --- a/apps/antonclk/ChangeLog +++ b/apps/antonclk/ChangeLog @@ -7,4 +7,5 @@ when weekday name "On": weekday name is cut at 6th position and .# is added 0.06: fixes #1271 - wrong settings name when weekday name and calendar weeknumber are on then display is # - week is buffered until date or timezone changes \ No newline at end of file + week is buffered until date or timezone changes +0.07: align default settings with app.js (otherwise the initial displayed settings will be confusing to users) \ No newline at end of file diff --git a/apps/antonclk/metadata.json b/apps/antonclk/metadata.json index def5d3b48..4d26dd0c7 100644 --- a/apps/antonclk/metadata.json +++ b/apps/antonclk/metadata.json @@ -1,7 +1,7 @@ { "id": "antonclk", "name": "Anton Clock", - "version": "0.06", + "version": "0.07", "description": "A clock using the bold Anton font, optionally showing seconds and date in ISO-8601 format.", "readme":"README.md", "icon": "app.png", diff --git a/apps/antonclk/settings.js b/apps/antonclk/settings.js index e452b02c7..6882cbd0f 100644 --- a/apps/antonclk/settings.js +++ b/apps/antonclk/settings.js @@ -38,7 +38,7 @@ }, "< Back": () => back(), "Seconds...": () => E.showMenu(secmenu), - "Date": stringInSettings("dateOnMain", ["Short", "Long", "ISO8601"]), + "Date": stringInSettings("dateOnMain", ["Long", "Short", "ISO8601"]), "Show Weekday": { value: (settings.weekDay !== undefined ? settings.weekDay : true), format: v => v ? "On" : "Off", @@ -56,7 +56,7 @@ } }, "Uppercase": { - value: (settings.upperCase !== undefined ? settings.upperCase : false), + value: (settings.upperCase !== undefined ? settings.upperCase : true), format: v => v ? "On" : "Off", onchange: v => { settings.upperCase = v; @@ -81,7 +81,7 @@ "< Back": () => E.showMenu(mainmenu), "Show": stringInSettings("secondsMode", ["Never", "Unlocked", "Always"]), "With \":\"": { - value: (settings.secondsWithColon !== undefined ? settings.secondsWithColon : false), + value: (settings.secondsWithColon !== undefined ? settings.secondsWithColon : true), format: v => v ? "On" : "Off", onchange: v => { settings.secondsWithColon = v; @@ -89,14 +89,14 @@ } }, "Color": { - value: (settings.secondsColoured !== undefined ? settings.secondsColoured : false), + value: (settings.secondsColoured !== undefined ? settings.secondsColoured : true), format: v => v ? "On" : "Off", onchange: v => { settings.secondsColoured = v; writeSettings(); } }, - "Date": stringInSettings("dateOnSecs", ["No", "Year", "Weekday"]) + "Date": stringInSettings("dateOnSecs", ["Year", "Weekday", "No"]) }; // Actually display the menu diff --git a/apps/blackjack/ChangeLog b/apps/blackjack/ChangeLog index 25b5f9195..8e468e9ad 100644 --- a/apps/blackjack/ChangeLog +++ b/apps/blackjack/ChangeLog @@ -1,2 +1,3 @@ 0.01: New game! BTN4- Hit card, BTN5- Stand -0.02: ignore buttons on pauses \ No newline at end of file +0.02: Ignore buttons on pauses +0.03: Support Bangle.js 2 diff --git a/apps/blackjack/appb2.js b/apps/blackjack/appb2.js new file mode 100644 index 000000000..c9907487d --- /dev/null +++ b/apps/blackjack/appb2.js @@ -0,0 +1,207 @@ +var Clubs = require("heatshrink").decompress(atob("j0ewcBkmSpICipEAiQLHwA3BBY8gBQMEEA1AJwQgGyAKChILGBQUCFgxwDJpEAO5AVCII44CAQI1GAAg1GAAZQCWxCDEAAqJBQYQAFRIJWCAApcCR4YADPoRWCgQdBPopfCwAdBTw47BcBAvBU44vDfBDUIRIbUHATuQ")); + +var Spades = require("heatshrink").decompress(atob("j0ewcBkmSpICuoALJIQILHpAKBJQ+QLIUJBYsgMoY1GBQcCBYmAPgkSEBEAgggIKApBDIg4KFHAZiCAAgsDBQw4DFitJFhQ4FTwplBgRoCSQoRBBYJ6EF4jgUwDUHAVOQA==")); + +var Hearts = require("heatshrink").decompress(atob("j0ewY96gMkyAEByVIBQcSpILBhMkBYkEyQLBAQYKCCIQLEEwQgCBYuAEBFJkBBCBYw4CEA44CgQLHIYQsHLJsAEBJEHSQhxENwQADMQoAEKAdAWowLCYJESXggAFGowA/AAQ")); + +var Diamonds = require("heatshrink").decompress(atob("j0ewY1ykgKJhIKJiVIEBOSoAKHpILBBQ+SBYOQBIsBCgILBwAKEgQgCAQIKEggICAQMgKwgUDAQI1GBY4IFLgoLGJpGSPoo4EMoxNIMoqSHiR6HLgizIPoLgfAFA")); + +var deck = []; +var player = {Hand:[]}; +var computer = {Hand:[]}; +var ctx = {ready:true}; + +function createDeck() { + var suits = ["Spades", "Hearts", "Diamonds", "Clubs"]; + var values = ["2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"]; + + var dck = []; + for (var i = 0 ; i < values.length; i++) { + for(var x = 0; x < suits.length; x++) { + dck.push({ Value: values[i], Suit: suits[x] }); + } + } + return dck; +} + +function shuffle(a) { + var j, x, i; + for (i = a.length - 1; i > 0; i--) { + j = Math.floor(Math.random() * (i + 1)); + x = a[i]; + a[i] = a[j]; + a[j] = x; + } + return a; +} + +function EndGameMessdage(msg){ + ctx.ready = false; + g.clearRect(0,160,176,176); + g.setColor(255,255,255); + g.fillRect(0,160,176,176); + g.setColor(0,0,0); + g.drawString(msg, 12, 155); + setTimeout(function(){ + startGame(); + }, 2500); + +} + +function hitMe() { + if (!ctx.ready) return; + player.Hand.push(deck.pop()); + renderOnScreen(1); + var playerWeight = calcWeight(player.Hand, 0); + + if(playerWeight == 21) + EndGameMessdage('WINNER'); + else if(playerWeight > 21) + EndGameMessdage('LOSER'); +} + +function calcWeight(hand, hideCard) { + if(hideCard === 1) { + if (hand[0].Value == "J" || hand[0].Value == "Q" || hand[0].Value == "K") + return "10 +"; + else if (hand[0].Value == "A") + return "11 +"; + else + return parseInt(hand[0].Value) +" +"; + } + else { + var weight = 0; + for(i=0; i 21 || bangleWeight < playerWeight) + EndGameMessdage('WINNER'); + else if(bangleWeight > playerWeight) + EndGameMessdage('LOOSER'); +} + +function renderOnScreen(HideCard) { + const fontName = "6x8"; + + g.clear(); // clear screen + g.reset(); // default draw styles + g.setFont(fontName, 1); + + g.setColor(255,255,255); + g.fillRect(Bangle.appRect); + g.setColor(0,0,0); + + g.drawString('Hit', 176/4-10, 160); + g.drawString('Stand', 176/4+176/2-10, 160); + + g.setFont(fontName, 3); + for(i=0; i right; + + if(is_left){ + hitMe(); + + } else if(is_right){ + stand(); + } +}); +setWatch(startGame, BTN1, {repeat:true, edge:"falling"}); + +startGame(); diff --git a/apps/blackjack/metadata.json b/apps/blackjack/metadata.json index 331c64040..837b891bd 100644 --- a/apps/blackjack/metadata.json +++ b/apps/blackjack/metadata.json @@ -2,15 +2,16 @@ "id": "blackjack", "name": "Black Jack game", "shortName": "Black Jack game", - "version": "0.02", + "version": "0.03", "description": "Simple implementation of card game Black Jack", "icon": "blackjack.png", "tags": "game", - "supports": ["BANGLEJS"], + "supports": ["BANGLEJS","BANGLEJS2"], "screenshots": [{"url":"bangle1-black-jack-game-screenshot.png"}], "allow_emulator": true, "storage": [ - {"name":"blackjack.app.js","url":"blackjack.app.js"}, + {"name":"blackjack.app.js","url":"blackjack.app.js","supports": ["BANGLEJS"]}, + {"name":"blackjack.app.js","url":"appb2.js","supports": ["BANGLEJS2"]}, {"name":"blackjack.img","url":"blackjack-icon.js","evaluate":true} ] } diff --git a/apps/boldclk/ChangeLog b/apps/boldclk/ChangeLog index c7a4ba7b4..30ac31c61 100644 --- a/apps/boldclk/ChangeLog +++ b/apps/boldclk/ChangeLog @@ -2,3 +2,4 @@ 0.03: Tweak for more efficient rendering, and firmware 2v06 0.04: Work with themes, smaller screens 0.05: Adjust hand lengths to be within 'tick' points +0.06: Removed "wake LCD on face-up"-feature: A watch-face should not set things like "wake LCD on face-up". diff --git a/apps/boldclk/bold_clock.js b/apps/boldclk/bold_clock.js index 4358b2e29..9d3ea0756 100644 --- a/apps/boldclk/bold_clock.js +++ b/apps/boldclk/bold_clock.js @@ -129,14 +129,6 @@ Bangle.on('lcdPower', (on) => { clearTimers(); } }); -Bangle.on('faceUp',function(up){ - //console.log("faceUp: " + up + " LCD: " + Bangle.isLCDOn()); - if (up && !Bangle.isLCDOn()) { - //console.log("faceUp and LCD off"); - clearTimers(); - Bangle.setLCDPower(true); - } -}); g.clear(); Bangle.loadWidgets(); diff --git a/apps/boldclk/metadata.json b/apps/boldclk/metadata.json index 7e3941cb3..cf961347d 100644 --- a/apps/boldclk/metadata.json +++ b/apps/boldclk/metadata.json @@ -1,7 +1,7 @@ { "id": "boldclk", "name": "Bold Clock", - "version": "0.05", + "version": "0.06", "description": "Simple, readable and practical clock", "icon": "bold_clock.png", "screenshots": [{"url":"screenshot_bold.png"}], diff --git a/apps/contourclock/ChangeLog b/apps/contourclock/ChangeLog index 0b6709d24..9c62e637b 100644 --- a/apps/contourclock/ChangeLog +++ b/apps/contourclock/ChangeLog @@ -4,3 +4,4 @@ 0.22: Changed timing code, original "Nunito" Font is back! 0.23: Customizer! Unused fonts no longer take up precious memory. 0.24: Added previews to the customizer. +0.25: Fixed a bug that would let widgets change the color of the clock. diff --git a/apps/contourclock/app.js b/apps/contourclock/app.js index a5440845d..cdfadd217 100644 --- a/apps/contourclock/app.js +++ b/apps/contourclock/app.js @@ -10,6 +10,7 @@ if (settings.fontIndex==undefined) { function draw() { var date = new Date(); // Draw day of the week + g.reset(); g.setFont("Teletext10x18Ascii"); g.clearRect(0,138,g.getWidth()-1,176); g.setFontAlign(0,1).drawString(require("locale").dow(date).toUpperCase(),g.getWidth()/2,g.getHeight()-18); diff --git a/apps/contourclock/metadata.json b/apps/contourclock/metadata.json index a5d764f2d..54d799127 100644 --- a/apps/contourclock/metadata.json +++ b/apps/contourclock/metadata.json @@ -1,7 +1,7 @@ { "id": "contourclock", "name": "Contour Clock", "shortName" : "Contour Clock", - "version":"0.24", + "version":"0.25", "icon": "app.png", "description": "A Minimalist clockface with large Digits. Now with more fonts!", "screenshots" : [{"url":"cc-screenshot-1.png"},{"url":"cc-screenshot-2.png"}], diff --git a/apps/gbmusic/ChangeLog b/apps/gbmusic/ChangeLog index 8b1a3e4aa..e2ee53ede 100644 --- a/apps/gbmusic/ChangeLog +++ b/apps/gbmusic/ChangeLog @@ -7,3 +7,5 @@ 0.07: Fix "previous" button image 0.08: Fix scrolling title background color 0.09: Move event listener from widget to boot code, stops music from showing up in messages +0.10: Simplify touch events + Remove date+time diff --git a/apps/gbmusic/README.md b/apps/gbmusic/README.md index 5d06164c2..f1f9c4378 100644 --- a/apps/gbmusic/README.md +++ b/apps/gbmusic/README.md @@ -3,9 +3,10 @@ If you have an Android phone with Gadgetbridge, this app allows you to view and control music playback. -| Bangle.js 1 | Bangle.js 2 | -|:-------------------------------------------|:-------------------------------------------| -| ![Screenshot: Bangle 1](screenshot_v1.png) | ![Screenshot: Bangle 2](screenshot_v2.png) | +| Bangle.js 1 | Bangle.js 2 | +|:---------------------------------------------------------|:---------------------------------------------------------| +| ![Screenshot: Bangle 1 Dark theme](screenshot_v1_d.png) | ![Screenshot: Bangle 2 Darm theme](screenshot_v2_d.png) | +| ![Screenshot: Bangle 1 Light theme](screenshot_v1_l.png) | ![Screenshot: Bangle 2 Light theme](screenshot_v2_l.png) | Download the [latest Gadgetbridge for Android here](https://f-droid.org/packages/nodomain.freeyourgadget.gadgetbridge/). @@ -14,7 +15,6 @@ Download the [latest Gadgetbridge for Android here](https://f-droid.org/packages * Dynamic colors based on Track/Artist/Album name * Scrolling display for long titles * Automatic start when music plays -* Time and date display ## Settings @@ -40,9 +40,7 @@ Disable double/triple pressing Middle Button: always simply toggle play/pause. * Button 3 (*Bangle.js 1*): Volume down ### Touch -* Left: Pause/previous song -* Right: Next song/resume -* Center: Toggle play/pause +* Touch: Toggle play/pause * Swipe left/right: Next/previous song * Swipe up/down (*Bangle.js 2*): Volume up/down diff --git a/apps/gbmusic/app.js b/apps/gbmusic/app.js index c8395f745..5252ac0ac 100644 --- a/apps/gbmusic/app.js +++ b/apps/gbmusic/app.js @@ -10,15 +10,15 @@ const BANGLE2 = process.env.HWVERSION===2; /** * @param {string} text - * @return {number} Maximum font size to make text fit on screen + * @param {number} w Width to fit text in + * @return {number} Maximum font size to make text fit */ -function fitText(text) { +function fitText(text, w) { if (!text.length) { return Infinity; } // make a guess, then shrink/grow until it fits - const w = Bangle.appRect.w, - test = (s) => g.setFont("Vector", s).stringWidth(text); + const test = (s) => g.setFont("Vector", s).stringWidth(text); let best = Math.floor(100*w/test(100)); if (test(best)===w) { // good guess! return best; @@ -106,7 +106,7 @@ function rTitle(l) { rScroller(l); // already scrolling return; } - let size = fitText(l.label); + let size = fitText(l.label, l.w); if (sizel.h) { size = l.h; } @@ -182,23 +182,17 @@ function makeUI() { type: "v", c: [ { type: "h", fillx: 1, c: [ - {id: "time", type: "txt", label: "88:88", valign: -1, halign: -1, font: "8%", bgCol: g.theme.bg}, {fillx: 1}, - {id: "num", type: "txt", label: "88:88", valign: -1, halign: 1, font: "12%", bgCol: g.theme.bg}, - BANGLE2 ? {} : {id: "up", type: "txt", label: " +", font: "6x8:2"}, + {id: "num", type: "txt", label: "", valign: -1, halign: -1, font: "12%", bgCol: g.theme.bg}, + BANGLE2 ? {} : {id: "up", type: "txt", label: " +", halign: 1, font: "6x8:2"}, ], }, {id: "title", type: "custom", label: "", fillx: 1, filly: 2, offset: null, font: "Vector:20%", render: rTitle, bgCol: g.theme.bg}, {id: "artist", type: "custom", label: "", fillx: 1, filly: 1, size: 30, render: rInfo, bgCol: g.theme.bg}, - {id: "album", type: "custom", label: "", fillx: 1, filly: 1, size: 20, render: rInfo, bgCol: g.theme.bg}, - {height: 10}, { type: "h", c: [ - {width: 3}, - {id: "prev", type: "custom", height: 15, width: 15, icon: "previous", render: rIcon, bgCol: g.theme.bg}, - {id: "date", type: "txt", halign: 0, valign: 1, label: "", font: "8%", fillx: 1, bgCol: g.theme.bg}, - {id: "next", type: "custom", height: 15, width: 15, icon: "next", render: rIcon, bgCol: g.theme.bg}, - BANGLE2 ? {width: 3} : {id: "down", type: "txt", label: " -", font: "6x8:2"}, + {id: "album", type: "custom", label: "", fillx: 1, filly: 1, size: 20, render: rInfo, bgCol: g.theme.bg}, + BANGLE2 ? {} : {id: "down", type: "txt", label: " -", font: "6x8:2"}, ], }, {height: 10}, @@ -211,20 +205,6 @@ function makeUI() { // Self-repeating timeouts /////////////////////// -// Clock -let tock = -1; -function tick() { - if (!BANGLE2 && !Bangle.isLCDOn()) { - return; - } - const now = new Date(); - if (now.getHours()*60+now.getMinutes()!==tock) { - drawDateTime(); - tock = now.getHours()*60+now.getMinutes(); - } - setTimeout(tick, 1000); // we only show minute precision anyway -} - // Fade out while paused and auto closing let fade = null; function fadeOut() { @@ -271,40 +251,12 @@ function scrollStop() { //////////////////// // Drawing functions //////////////////// -/** - * Draw date and time - */ -function drawDateTime() { - const now = new Date(); - const l = require("locale"); - const is12 = (require("Storage").readJSON("setting.json", 1) || {})["12hour"]; - if (is12) { - const d12 = new Date(now.getTime()); - const hour = d12.getHours(); - if (hour===0) { - d12.setHours(12); - } else if (hour>12) { - d12.setHours(hour-12); - } - layout.time.label = l.time(d12, true)+l.meridian(now); - } else { - layout.time.label = l.time(now, true); - } - layout.date.label = require("locale").date(now, true); - layout.render(); -} function drawControls() { - let l = layout; + if (BANGLE2) return; const cc = a => (a ? "#f00" : "#0f0"); // control color: red for active, green for inactive - if (!BANGLE2) { - l.up.col = cc("volumeup" in tCommand); - l.down.col = cc("volumedown" in tCommand); - } - l.prev.icon = (stat==="play") ? "pause" : "previous"; - l.prev.col = cc("prev" in tCommand || "pause" in tCommand); - l.next.icon = (stat==="play") ? "next" : "play"; - l.next.col = cc("next" in tCommand || "play" in tCommand); + layout.up.col = cc("volumeup" in tCommand); + layout.down.col = cc("volumedown" in tCommand); layout.render(); } @@ -339,6 +291,7 @@ function info(info) { layout.album.col = infoColor("album"); layout.artist.col = infoColor("artist"); layout.num.label = formatNum(info); + layout.update(); layout.render(); rTitle(layout.title); // force redraw of title, or scroller might break // reset auto exit interval @@ -473,37 +426,16 @@ function sendCommand(command) { drawControls(); } -// touch/swipe: navigation function togglePlay() { sendCommand(stat==="play" ? "pause" : "play"); } -function pausePrev() { - sendCommand(stat==="play" ? "pause" : "previous"); -} -function nextPlay() { - sendCommand(stat==="play" ? "next" : "play"); -} /** * Setup touch+swipe for Bangle.js 1 */ function touch1() { - Bangle.on("touch", side => { - if (!Bangle.isLCDOn()) {return;} // for <2v10 firmware - switch(side) { - case 1: - pausePrev(); - break; - case 2: - nextPlay(); - break; - default: - togglePlay(); - break; - } - }); + Bangle.on("touch", togglePlay); Bangle.on("swipe", dir => { - if (!Bangle.isLCDOn()) {return;} // for <2v10 firmware sendCommand(dir===1 ? "previous" : "next"); }); } @@ -511,16 +443,7 @@ function touch1() { * Setup touch+swipe for Bangle.js 2 */ function touch2() { - Bangle.on("touch", (side, xy) => { - const ar = Bangle.appRect; - if (xy.xar.x+ar.w*2/3) { - nextPlay(); - } else { - togglePlay(); - } - }); + Bangle.on("touch", togglePlay); // swiping let drag; Bangle.on("drag", e => { @@ -595,7 +518,6 @@ function startWatches() { function start() { makeUI(); startWatches(); - tick(); startEmulator(); } diff --git a/apps/gbmusic/metadata.json b/apps/gbmusic/metadata.json index f578f1f48..0ded80452 100644 --- a/apps/gbmusic/metadata.json +++ b/apps/gbmusic/metadata.json @@ -2,10 +2,11 @@ "id": "gbmusic", "name": "Gadgetbridge Music Controls", "shortName": "Music Controls", - "version": "0.09", + "version": "0.10", "description": "Control the music on your Gadgetbridge-connected phone", "icon": "icon.png", - "screenshots": [{"url":"screenshot_v1.png"},{"url":"screenshot_v2.png"}], + "screenshots": [{"url":"screenshot_v1_d.png"},{"url":"screenshot_v1_l.png"}, + {"url":"screenshot_v2_d.png"},{"url":"screenshot_v2_l.png"}], "type": "app", "tags": "tools,bluetooth,gadgetbridge,music", "supports": ["BANGLEJS","BANGLEJS2"], diff --git a/apps/gbmusic/screenshot_v1.png b/apps/gbmusic/screenshot_v1.png deleted file mode 100644 index 3b290e459..000000000 Binary files a/apps/gbmusic/screenshot_v1.png and /dev/null differ diff --git a/apps/gbmusic/screenshot_v1_d.png b/apps/gbmusic/screenshot_v1_d.png new file mode 100644 index 000000000..3a6d84cff Binary files /dev/null and b/apps/gbmusic/screenshot_v1_d.png differ diff --git a/apps/gbmusic/screenshot_v1_l.png b/apps/gbmusic/screenshot_v1_l.png new file mode 100644 index 000000000..1b6b57809 Binary files /dev/null and b/apps/gbmusic/screenshot_v1_l.png differ diff --git a/apps/gbmusic/screenshot_v2.png b/apps/gbmusic/screenshot_v2.png deleted file mode 100644 index b89b5022e..000000000 Binary files a/apps/gbmusic/screenshot_v2.png and /dev/null differ diff --git a/apps/gbmusic/screenshot_v2_d.png b/apps/gbmusic/screenshot_v2_d.png new file mode 100644 index 000000000..761e1d14a Binary files /dev/null and b/apps/gbmusic/screenshot_v2_d.png differ diff --git a/apps/gbmusic/screenshot_v2_l.png b/apps/gbmusic/screenshot_v2_l.png new file mode 100644 index 000000000..5cf05c7cb Binary files /dev/null and b/apps/gbmusic/screenshot_v2_l.png differ diff --git a/apps/messages/ChangeLog b/apps/messages/ChangeLog index 4811cd19b..4ad3264b7 100644 --- a/apps/messages/ChangeLog +++ b/apps/messages/ChangeLog @@ -15,7 +15,7 @@ 0.10: Respect the 'new' attribute if it was set from iOS integrations 0.11: Open app when touching the widget (Bangle.js 2 only) 0.12: Extra app-specific notification icons - New animated notifcationicon (instead of large blinking 'MESSAGES') + New animated notification icon (instead of large blinking 'MESSAGES') Added screenshots 0.13: Add /*LANG*/ comments for internationalisation Add 'Delete All' option to message options @@ -31,3 +31,6 @@ 0.19: Use a larger font for message text if it'll fit 0.20: Allow tapping on the body to show a scrollable view of the message and title in a bigger font (fix #1405, #1031) 0.21: Improve list readability on dark theme +0.22: Allow repeat to be switched Off, so there is no buzzing repetition. + Also gave the widget a pixel more room to the right + diff --git a/apps/messages/app.js b/apps/messages/app.js index 67738bc70..8980cf11a 100644 --- a/apps/messages/app.js +++ b/apps/messages/app.js @@ -123,7 +123,7 @@ function getMessageImageCol(msg,def) { "telegram": "#0088cc", "twitter": "#1da1f2", "whatsapp": "#4fce5d", - "wordfeud": "#dcc8bd", + "wordfeud": "#e7d3c7", }[(msg.src||"").toLowerCase()]||(def !== undefined?def:g.theme.fg); } diff --git a/apps/messages/metadata.json b/apps/messages/metadata.json index e84d9f0d9..fd653ad57 100644 --- a/apps/messages/metadata.json +++ b/apps/messages/metadata.json @@ -1,8 +1,8 @@ { "id": "messages", "name": "Messages", - "version": "0.22", - "description": "App to display notifications from iOS and Gadgetbridge", + "version": "0.44", + "description": "App to display notifications from iOS and Gadgetbridge/Android", "icon": "app.png", "type": "app", "tags": "tool,system", diff --git a/apps/messages/settings.js b/apps/messages/settings.js index c865a37fb..39abfc131 100644 --- a/apps/messages/settings.js +++ b/apps/messages/settings.js @@ -4,6 +4,7 @@ if (settings.vibrate===undefined) settings.vibrate="."; if (settings.repeat===undefined) settings.repeat=4; if (settings.unreadTimeout===undefined) settings.unreadTimeout=60; + settings.maxUnreadTimeout=240; return settings; } function updateSetting(setting, value) { @@ -13,7 +14,6 @@ } var vibPatterns = [/*LANG*/"Off", ".", "-", "--", "-.-", "---"]; - var currentVib = settings().vibrate; var mainmenu = { "" : { "title" : /*LANG*/"Messages" }, "< Back" : back, @@ -27,13 +27,13 @@ }, /*LANG*/'Repeat': { value: settings().repeat, - min: 2, max: 10, - format: v => v+"s", + min: 0, max: 10, + format: v => v?v+"s":/*LANG*/"Off", onchange: v => updateSetting("repeat", v) }, /*LANG*/'Unread timer': { value: settings().unreadTimeout, - min: 0, max: 240, step : 10, + min: 0, max: settings().maxUnreadTimeout, step : 10, format: v => v?v+"s":/*LANG*/"Off", onchange: v => updateSetting("unreadTimeout", v) }, diff --git a/apps/messages/widget.js b/apps/messages/widget.js index 1239ef262..4a247b917 100644 --- a/apps/messages/widget.js +++ b/apps/messages/widget.js @@ -1,12 +1,12 @@ -WIDGETS["messages"]={area:"tl", width:0, iconwidth:23, +WIDGETS["messages"]={area:"tl", width:0, iconwidth:24, draw:function() { Bangle.removeListener('touch', this.touch); if (!this.width) return; var c = (Date.now()-this.t)/1000; g.reset().clearRect(this.x, this.y, this.x+this.width, this.y+this.iconwidth); g.drawImage((c&1) ? atob("GBiBAAAAAAAAAAAAAAAAAAAAAB//+DAADDAADDAADDwAPD8A/DOBzDDn/DA//DAHvDAPvjAPvjAPvjAPvh///gf/vAAD+AAB8AAAAA==") : atob("GBiBAAAAAAAAAAAAAAAAAAAAAB//+D///D///A//8CP/xDj/HD48DD+B8D/D+D/3vD/vvj/vvj/vvj/vvh/v/gfnvAAD+AAB8AAAAA=="), this.x, this.y); - //if (c<60) Bangle.setLCDPower(1); // keep LCD on for 1 minute let settings = require('Storage').readJSON("messages.settings.json", true) || {}; + console.log("dingen ", typeof(settings.repeat), settings.repeat) if (settings.repeat===undefined) settings.repeat = 4; if (c<120 && (Date.now()-this.l)>settings.repeat*1000) { this.l = Date.now(); diff --git a/apps/neonx/ChangeLog b/apps/neonx/ChangeLog index 7ac033fe8..968d6d629 100644 --- a/apps/neonx/ChangeLog +++ b/apps/neonx/ChangeLog @@ -1,2 +1,3 @@ 0.01: Initial release -0.02: Optional fullscreen mode \ No newline at end of file +0.02: Optional fullscreen mode +0.03: Optional show lock status via color \ No newline at end of file diff --git a/apps/neonx/README.md b/apps/neonx/README.md index f205b702f..ffb3c3f2c 100644 --- a/apps/neonx/README.md +++ b/apps/neonx/README.md @@ -21,4 +21,7 @@ Shows the current date as DD MM on touch and reverts back to time after 5 second ### Fullscreen Shows the watchface in fullscreen mode. -Note: In fullscreen mode, widgets are hidden, but still loaded. \ No newline at end of file +Note: In fullscreen mode, widgets are hidden, but still loaded. + +### Show lock status +If enabled, color changes when unlocked to detect the lock state easily. \ No newline at end of file diff --git a/apps/neonx/metadata.json b/apps/neonx/metadata.json index ffa4d1b8e..4ac7c4cea 100644 --- a/apps/neonx/metadata.json +++ b/apps/neonx/metadata.json @@ -2,7 +2,7 @@ "id": "neonx", "name": "Neon X & IO X Clock", "shortName": "Neon X Clock", - "version": "0.02", + "version": "0.03", "description": "Pebble Neon X & Neon IO X for Bangle.js", "icon": "neonx.png", "type": "clock", diff --git a/apps/neonx/neonx.app.js b/apps/neonx/neonx.app.js index 4ef0986fe..6a8b933e5 100644 --- a/apps/neonx/neonx.app.js +++ b/apps/neonx/neonx.app.js @@ -8,6 +8,19 @@ * Created: February 2022 */ +let settings = { + thickness: 4, + io: 0, + showDate: 1, + fullscreen: false, + showLock: false, +}; +let saved_settings = require('Storage').readJSON('neonx.json', 1) || settings; +for (const key in saved_settings) { + settings[key] = saved_settings[key] +} + + const digits = { 0:[[15,15,85,15,85,85,15,85,15,15]], 1:[[85,15,85,85]], @@ -21,6 +34,7 @@ const digits = { 9:[[15,50,15,15,85,15,85,85,15,85]], }; + const colors = { x: [ ["#FF00FF", "#00FFFF"], @@ -31,17 +45,14 @@ const colors = { ["#00FF00", "#00FFFF"] ] }; - const is12hour = (require("Storage").readJSON("setting.json",1)||{})["12hour"]||false; const screenWidth = g.getWidth(); const screenHeight = g.getHeight(); const halfWidth = screenWidth / 2; const scale = screenWidth / 240; -const REFRESH_RATE = 10E3; - -let interval = 0; let showingDate = false; + function drawLine(poly, thickness){ for (let i = 0; i < poly.length; i = i + 2){ if (poly[i + 2] === undefined) { @@ -59,18 +70,6 @@ function drawLine(poly, thickness){ } } -let settings = { - thickness: 4, - io: 0, - showDate: 1, - fullscreen: false, -}; -let saved_settings = require('Storage').readJSON('neonx.json', 1) || settings; -for (const key in saved_settings) { - settings[key] = saved_settings[key] -} - - function drawClock(num){ let tx, ty; @@ -80,10 +79,12 @@ function drawClock(num){ const current = ((y + 1) * 2 + x - 1); let newScale = scale; - g.setColor(colors[settings.io ? 'io' : 'x'][y][x]); + let xc = settings.showLock && !Bangle.isLocked() ? Math.abs(x-1) : x; + let c = colors[settings.io ? 'io' : 'x'][y][xc]; + g.setColor(c); if (!settings.io) { - newScale *= settings.fullscreen ? 1.18 : 1.0; + newScale *= settings.fullscreen ? 1.20 : 1.0; let dx = settings.fullscreen ? 0 : 18 tx = (x * 100 + dx) * newScale; ty = (y * 100 + dx*2) * newScale; @@ -101,21 +102,24 @@ function drawClock(num){ } } + function draw(date){ + queueDraw(); + let d = new Date(); let l1, l2; showingDate = date; if (date) { - setUpdateInt(0); - l1 = ('0' + (new Date()).getDate()).substr(-2); l2 = ('0' + ((new Date()).getMonth() + 1)).substr(-2); + if (drawTimeout) clearTimeout(drawTimeout); + drawTimeout = undefined; + setTimeout(_ => { draw(); - setUpdateInt(1); }, 5000); } else { l1 = ('0' + (d.getHours() % (is12hour ? 12 : 24))).substr(-2); @@ -131,34 +135,48 @@ function draw(date){ drawClock([l1, l2]); } -function setUpdateInt(set){ - if (interval) { - clearInterval(interval); - } - if (set) { - interval = setInterval(draw, REFRESH_RATE); - } +/* + * Draw watch face + */ +var drawTimeout; +function queueDraw() { + if (drawTimeout) clearTimeout(drawTimeout); + drawTimeout = setTimeout(function() { + drawTimeout = undefined; + draw(); + }, 60000 - (Date.now() % 60000)); } -g.clear(1); - -Bangle.setUI("clock"); - -setUpdateInt(1); -draw(); +/* + * Event handlers + */ if (settings.showDate) { Bangle.on('touch', () => draw(!showingDate)); } Bangle.on('lcdPower', function(on){ - if (on){ + if (drawTimeout) clearTimeout(drawTimeout); + drawTimeout = undefined; + + if (on) { draw(); - setUpdateInt(1); - } else setUpdateInt(0); + } }); +Bangle.on('lock', function(isLocked) { + draw(); +}); + + +/* + * Draw first time + */ +g.clear(1); +Bangle.setUI("clock"); +draw(); + Bangle.loadWidgets(); if(settings.fullscreen){ diff --git a/apps/neonx/neonx.settings.js b/apps/neonx/neonx.settings.js index 3af2e0fa5..e01ceb4d3 100644 --- a/apps/neonx/neonx.settings.js +++ b/apps/neonx/neonx.settings.js @@ -9,6 +9,7 @@ io: 0, showDate: 1, fullscreen: false, + showLock: false, }; updateSettings(); @@ -58,6 +59,14 @@ updateSettings(); }, }, + 'Show lock': { + value: false | neonXSettings.showLock, + format: () => (neonXSettings.showLock ? 'Yes' : 'No'), + onchange: () => { + neonXSettings.showLock = !neonXSettings.showLock; + updateSettings(); + }, + }, }; E.showMenu(menu); }) diff --git a/apps/pie/app-icon.js b/apps/pie/app-icon.js new file mode 100644 index 000000000..34a58225c --- /dev/null +++ b/apps/pie/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwwhC/AH4A/ABl3ABQVJg4WLC/QWMC/4X/U7NVqIXTgtVC4MXC6QWBAAQYLCxQAGqByJIoQAKC8IWMJBIuNGBIXvCxxgIC/4XH1QAO0AX/C/4X/C/4X/C6Q")) diff --git a/apps/pie/app.js b/apps/pie/app.js new file mode 100644 index 000000000..69b67d3bd --- /dev/null +++ b/apps/pie/app.js @@ -0,0 +1,56 @@ +function end(){ + clearInterval(m); + clearWatch(w); + gfx.clear(); + gfx.setColor(1,0,0); + gfx.setFont("Vector30"); + gfx.drawString('Game over!\n Score: '+score+'\nPress BTN1', gfx.getWidth()*0.15,gfx.getHeight()*0.4); + setWatch(function(){init();}, BTN1); +} +function scrollX(){ + gfx.clearRect(0,gfx.getHeight()*(1/4),gfx.getWidth(),0); + gfx.scroll(0,gfx.getHeight()/4); + score++; + if(typeof(m) != undefined && score>0){ + clearInterval(m); + m = setInterval(scrollY,Math.abs(100/score+15-0.1*score));} + gfx.setColor(1,1,1); + gfx.drawString(score,gfx.getWidth()*(4.2/5),gfx.getHeight()*(0.5/5)); + gfx.setColor(Math.random(),Math.random(),Math.random()); + gfx.setColor(col[0],col[1],col[2]); + gfx.fillRect(colm[0],colm[1],colm[2],colm[3]); + col = [Math.random(),Math.random(),Math.random()]; + gfx.setColor(col[0],col[1],col[2]); + block[0] = gfx.getWidth(); +} +function scrollY(){ + block[0] -= 2; + block[2] = block[0]+colm[2]-colm[0]; + gfx.clearRect(block[2], block[1], gfx.getWidth(), block[3]); + gfx.fillRect(block[0],block[1],block[2],block[3]); + if(block[2]block[2] && colm[0]layout[e.id].label = e.getString()); - sb.on('changed', e=>layout[e.id].label = e.getString()); + if (sa) sa.on('changed', e=>layout[e.id].label = e.getString()); + if (sb) sb.on('changed', e=>layout[e.id].label = e.getString()); } // At the bottom put time/GPS state/etc lc.push({ type:"h", filly:1, c:[ diff --git a/apps/run/metadata.json b/apps/run/metadata.json index ea68f4734..7aabf8b53 100644 --- a/apps/run/metadata.json +++ b/apps/run/metadata.json @@ -1,6 +1,6 @@ { "id": "run", "name": "Run", - "version":"0.06", + "version":"0.07", "description": "Displays distance, time, steps, cadence, pace and more for runners.", "icon": "app.png", "tags": "run,running,fitness,outdoors,gps", diff --git a/apps/stopwatch/ChangeLog b/apps/stopwatch/ChangeLog index 9db0e26c5..104fce19d 100644 --- a/apps/stopwatch/ChangeLog +++ b/apps/stopwatch/ChangeLog @@ -1 +1,2 @@ 0.01: first release +0.02: Adjust for touch events outside of screen g dimensions diff --git a/apps/stopwatch/metadata.json b/apps/stopwatch/metadata.json index e72d85af1..cc13ec92f 100644 --- a/apps/stopwatch/metadata.json +++ b/apps/stopwatch/metadata.json @@ -1,7 +1,7 @@ { "id": "stopwatch", "name": "Stopwatch Touch", - "version": "0.01", + "version": "0.02", "description": "A touch based stop watch for Bangle JS 2", "icon": "stopwatch.png", "screenshots": [{"url":"screenshot1.png"},{"url":"screenshot2.png"},{"url":"screenshot3.png"}], diff --git a/apps/stopwatch/stopwatch.app.js b/apps/stopwatch/stopwatch.app.js index 48d4f26ea..e2be95451 100644 --- a/apps/stopwatch/stopwatch.app.js +++ b/apps/stopwatch/stopwatch.app.js @@ -185,17 +185,27 @@ resetBtn.setImage(pause_img); Bangle.on('touch', function(button, xy) { + var x = xy.x; + var y = xy.y; + + // adjust for outside the dimension of the screen + // http://forum.espruino.com/conversations/371867/#comment16406025 + if (y > h) y = h; + if (y < 0) y = 0; + if (x > w) x = w; + if (x < 0) x = 0; + // not running, and reset - if (!running && tCurrent == tTotal && bigPlayPauseBtn.check(xy.x, xy.y)) return; + if (!running && tCurrent == tTotal && bigPlayPauseBtn.check(x, y)) return; // paused and hit play - if (!running && tCurrent != tTotal && smallPlayPauseBtn.check(xy.x, xy.y)) return; + if (!running && tCurrent != tTotal && smallPlayPauseBtn.check(x, y)) return; // paused and press reset - if (!running && tCurrent != tTotal && resetBtn.check(xy.x, xy.y)) return; + if (!running && tCurrent != tTotal && resetBtn.check(x, y)) return; // must be running - if (running && bigPlayPauseBtn.check(xy.x, xy.y)) return; + if (running && bigPlayPauseBtn.check(x, y)) return; }); // Stop updates when LCD is off, restart when on diff --git a/apps/terminalclock/ChangeLog b/apps/terminalclock/ChangeLog new file mode 100644 index 000000000..5560f00bc --- /dev/null +++ b/apps/terminalclock/ChangeLog @@ -0,0 +1 @@ +0.01: New App! diff --git a/apps/terminalclock/README.md b/apps/terminalclock/README.md new file mode 100644 index 000000000..2a2bc1204 --- /dev/null +++ b/apps/terminalclock/README.md @@ -0,0 +1,9 @@ +# Terminal clock + +A clock displayed as a terminal cli. +It can display : +- time +- date +- hrm +- activity +- steps diff --git a/apps/terminalclock/app-icon.js b/apps/terminalclock/app-icon.js new file mode 100644 index 000000000..5e57a4b7c --- /dev/null +++ b/apps/terminalclock/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwghC/AHsHu93uAX/C+wACsAaTC/4Xiu1mswXRCYNnDQQxTgwX/C8QABuAaTg4X/C7Z3Xa/4Xds1ms4XUCgV2DYIXUsBdTC/4AEg4VCC61wIiYX/C74A/AGIA==")) diff --git a/apps/terminalclock/app.js b/apps/terminalclock/app.js new file mode 100644 index 000000000..fb7bd16cc --- /dev/null +++ b/apps/terminalclock/app.js @@ -0,0 +1,138 @@ +var locale = require("locale"); +var fontColor = g.theme.dark ? "#0f0" : "#000"; +var startY = 24; +var paddingY = 2; +var font6x8At4Size = 32; +var font6x8At2Size = 18; +var heartRate = 0; + + +function setFontSize(pos){ + if(pos == 1) + g.setFont("6x8", 4); + else + g.setFont("6x8", 2); +} + +function clearField(pos){ + var yStartPos = startY + + paddingY * (pos - 1) + + font6x8At4Size * Math.min(1, pos-1) + + font6x8At2Size * Math.max(0, pos-2); + var yEndPos = startY + + paddingY * (pos - 1) + + font6x8At4Size * Math.min(1, pos) + + font6x8At2Size * Math.max(0, pos-1); + g.clearRect(0, yStartPos, 240, yEndPos); +} + +function clearWatchIfNeeded(now){ + if(now.getMinutes() % 10 == 0) + g.clearRect(0, startY, 240, 240); +} + +function drawLine(line, pos){ + setFontSize(pos); + var yPos = startY + + paddingY * (pos - 1) + + font6x8At4Size * Math.min(1, pos-1) + + font6x8At2Size * Math.max(0, pos-2); + g.drawString(line, 5, yPos, true); +} + +function drawTime(now, pos){ + var h = now.getHours(); + var m = now.getMinutes(); + var time = ">" + (""+h).substr(-2) + ":" + ("0"+m).substr(-2); + drawLine(time, pos); +} + +function drawDate(now, pos){ + var dow = locale.dow(now, 1); + var date = locale.date(now, 1).substr(0,6) + locale.date(now, 1).substr(-2); + var locale_date = ">" + dow + " " + date; + drawLine(locale_date, pos); +} + +function drawInput(now, pos){ + clearField(pos); + drawLine(">", pos); +} + +function drawStepCount(pos){ + var health = Bangle.getHealthStatus("day"); + var steps_formated = ">Steps: " + health.steps; + drawLine(steps_formated, pos); +} + +function drawHRM(pos){ + clearField(pos); + if(heartRate != 0) + drawLine(">HR: " + parseInt(heartRate), pos); + else + drawLine(">HR: unknown", pos); +} + +function drawActivity(pos){ + clearField(pos); + var health = Bangle.getHealthStatus('last'); + var steps_formated = ">Activity: " + parseInt(health.movement/10); + drawLine(steps_formated, pos); +} + + +function draw(){ + var curPos = 1; + g.reset(); + g.setFontAlign(-1, -1); + g.setColor(fontColor); + var now = new Date(); + clearWatchIfNeeded(now); // mostly to not have issues when changing days + drawTime(now, curPos); + curPos++; + if(settings.showDate){ + drawDate(now, curPos); + curPos++; + } + if(settings.showHRM){ + drawHRM(curPos); + curPos++; + } + if(settings.showActivity){ + drawActivity(curPos); + curPos++; + } + if(settings.showStepCount){ + drawStepCount(curPos); + curPos++; + } + drawInput(now, curPos); +} + + +Bangle.on('HRM',function(hrmInfo) { + if(hrmInfo.confidence >= settings.HRMinConfidence) + heartRate = hrmInfo.bpm; +}); + + +// Clear the screen once, at startup +g.clear(); +// load the settings +var settings = Object.assign({ + // default values + HRMinConfidence: 50, + showDate: true, + showHRM: true, + showActivity: true, + showStepCount: true, +}, require('Storage').readJSON("terminalclock.json", true) || {}); +// draw immediately at first +draw(); +// Show launcher when middle button pressed +Bangle.setUI("clock"); +// Load widgets +Bangle.loadWidgets(); +Bangle.drawWidgets(); + +var secondInterval = setInterval(draw, 10000); diff --git a/apps/terminalclock/app.png b/apps/terminalclock/app.png new file mode 100644 index 000000000..5d4507ead Binary files /dev/null and b/apps/terminalclock/app.png differ diff --git a/apps/terminalclock/metadata.json b/apps/terminalclock/metadata.json new file mode 100644 index 000000000..6907da84d --- /dev/null +++ b/apps/terminalclock/metadata.json @@ -0,0 +1,24 @@ +{ + "id": "terminalclock", + "name": "Terminal Clock", + "shortName":"Terminal Clock", + "description": "A terminal cli like clock displaying multiple sensor data", + "version":"0.01", + "icon": "app.png", + "type": "clock", + "tags": "clock", + "supports": ["BANGLEJS2"], + "readme": "README.md", + "storage": [ + {"name": "terminalclock.app.js","url": "app.js"}, + {"name": "terminalclock.settings.js","url": "settings.js"}, + {"name": "terminalclock.img","url": "app-icon.js","evaluate": true} + ], + "data": [ + {"name": "terminalclock.json"} + ], + "screenshots": [ + {"url": "screenshot1.png"}, + {"url": "screenshot2.png"} + ] +} diff --git a/apps/terminalclock/screenshot1.png b/apps/terminalclock/screenshot1.png new file mode 100644 index 000000000..a0d41f495 Binary files /dev/null and b/apps/terminalclock/screenshot1.png differ diff --git a/apps/terminalclock/screenshot2.png b/apps/terminalclock/screenshot2.png new file mode 100644 index 000000000..21d7aadbf Binary files /dev/null and b/apps/terminalclock/screenshot2.png differ diff --git a/apps/terminalclock/settings.js b/apps/terminalclock/settings.js new file mode 100644 index 000000000..77df69b12 --- /dev/null +++ b/apps/terminalclock/settings.js @@ -0,0 +1,61 @@ +(function(back) { + var FILE = "terminalclock.json"; + // Load settings + var settings = Object.assign({ + HRMinConfidence: 50, + showDate: true, + showHRM: true, + showActivity: true, + showStepCount: true, + }, require('Storage').readJSON(FILE, true) || {}); + + function writeSettings() { + require('Storage').writeJSON(FILE, settings); + } + + // Show the menu + E.showMenu({ + "" : { "title" : "Terminal Clock" }, + "< Back" : () => back(), + 'HR confidence': { + value: 50|settings.HRMinConfidence, // 0| converts undefined to 0 + min: 0, max: 100, + onchange: v => { + settings.HRMinConfidence = v; + writeSettings(); + } + }, + 'Show date': { + value: !!settings.showDate, + format: v => v?"Yes":"No", + onchange: v => { + settings.showDate = v; + writeSettings(); + } + }, + 'Show HRM': { + value: !!settings.showHRM, + format: v => v?"Yes":"No", + onchange: v => { + settings.showHRM = v; + writeSettings(); + } + }, + 'Show Activity': { + value: !!settings.showActivity, + format: v => v?"Yes":"No", + onchange: v => { + settings.showActivity = v; + writeSettings(); + } + }, + 'Show Steps': { + value: !!settings.showStepCount, + format: v => v?"Yes":"No", + onchange: v => { + settings.showStepCount = v; + writeSettings(); + } + } + }); +}) diff --git a/apps/timecal/ChangeLog b/apps/timecal/ChangeLog index 43bff461d..e48145b4b 100644 --- a/apps/timecal/ChangeLog +++ b/apps/timecal/ChangeLog @@ -6,4 +6,5 @@ -> locale: weekday name (first two characters) from locale -> added settings to render cal view begin day (-1: today, 0:sunday, 1:monday [default]) 0.03: a lot of more settings for outline, colors and highlights -0.04: finalized README, fixed settings cancel, fixed border-setting \ No newline at end of file +0.04: finalized README, fixed settings cancel, fixed border-setting +0.05: bugfix: default settings \ No newline at end of file diff --git a/apps/timecal/metadata.json b/apps/timecal/metadata.json index 4dd8a8ca0..f439f4e9c 100644 --- a/apps/timecal/metadata.json +++ b/apps/timecal/metadata.json @@ -1,7 +1,7 @@ { "id": "timecal", "name": "TimeCal", "shortName":"TimeCal", - "version":"0.04", + "version":"0.05", "description": "TimeCal shows the date/time along with a 3 week calendar", "icon": "icon.png", "type": "clock", diff --git a/apps/timecal/testing/timecal.app.test.js b/apps/timecal/testing/timecal.app.test._js similarity index 100% rename from apps/timecal/testing/timecal.app.test.js rename to apps/timecal/testing/timecal.app.test._js diff --git a/apps/timecal/timecal.settings.js b/apps/timecal/timecal.settings.js index f3b46384d..e86f3d8b8 100644 --- a/apps/timecal/timecal.settings.js +++ b/apps/timecal/timecal.settings.js @@ -2,7 +2,7 @@ (function(exit) { ABR_DAY = require("locale") && require("locale").abday ? require("locale").abday : ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; - var FILE = "timecal.validSttngs.json"; + var FILE = "timecal.settings.json"; const DEFAULTS = { shwDate:1, //0:none, 1:locale, 2:month, 3:monthshort.year #week @@ -19,14 +19,14 @@ calBrdr:false }; - validSttngs = require("Storage").readJSON("timecal.validSttngs.json", 1) || {}; + validSttngs = require("Storage").readJSON(FILE, 1) || {}; for (const k in validSttngs) if (!DEFAULTS.hasOwnProperty(k)) delete this.validSttngs[k]; //remove invalid settings - for (const k in DEFAULTS) if(!validSttngs.hasOwnProperty(k)) validSttngs[k] = DEFAULTS[k]; //assign missing defaults + for (const k in DEFAULTS) if(!validSttngs.hasOwnProperty(k)) validSttngs[k] = DEFAULTS[k]; //assign missing defaults fixed - var changedSttngs = Object.assign({}, validSttngs); + var chngdSttngs = Object.assign({}, validSttngs); var saveExitSettings = () => { - require('Storage').writeJSON(FILE, changedSttngs); + require('Storage').writeJSON(FILE, chngdSttngs); exit(); }; @@ -42,27 +42,27 @@ }, /*LANG*/"< Save": () => saveExitSettings(), /*LANG*/"Show date": { - value: validSttngs.shwDate, + value: chngdSttngs.shwDate, min: 0, max: 3, format: v => [/*LANG*/"none", /*LANG*/"locale", /*LANG*/"M", /*LANG*/"m.Y #W"][v], - onchange: v => validSttngs.shwDate = v + onchange: v => chngdSttngs.shwDate = v }, /*LANG*/"Start wday": { - value: validSttngs.wdStrt, + value: chngdSttngs.wdStrt, min: -1, max: 6, format: v => v>=0 ? ABR_DAY[v] : /*LANG*/"today", - onchange: v => validSttngs.wdStrt = v + onchange: v => chngdSttngs.wdStrt = v }, /*LANG*/"Su color": { - value: validSttngs.suClr, + value: chngdSttngs.suClr, min: 0, max: 3, format: v => [/*LANG*/"none", /*LANG*/"red", /*LANG*/"green", /*LANG*/"blue"][v], - onchange: v => validSttngs.suClr = v + onchange: v => chngdSttngs.suClr = v }, /*LANG*/"Border": { - value: validSttngs.calBrdr, + value: chngdSttngs.calBrdr, format: v => v ? /*LANG*/"show" : /*LANG*/"none", - onchange: v => validSttngs.calBrdr = v + onchange: v => chngdSttngs.calBrdr = v }, /*LANG*/"Today settings": () => { showTodayMenu(); @@ -78,28 +78,28 @@ }, "< Back": () => showMainMenu(), /*LANG*/"Color": { - value: validSttngs.tdyNumClr, + value: chngdSttngs.tdyNumClr, min: 0, max: 3, format: v => [/*LANG*/"none", /*LANG*/"red", /*LANG*/"green", /*LANG*/"blue"][v], - onchange: v => validSttngs.tdyNumClr = v + onchange: v => chngdSttngs.tdyNumClr = v }, /*LANG*/"Marker": { - value: validSttngs.tdyMrkr, + value: chngdSttngs.tdyMrkr, min: 0, max: 3, format: v => [/*LANG*/"none", /*LANG*/"circle", /*LANG*/"rectangle", /*LANG*/"filled"][v], - onchange: v => validSttngs.tdyMrkr = v + onchange: v => chngdSttngs.tdyMrkr = v }, /*LANG*/"Mrk.Color": { - value: validSttngs.tdyMrkClr, + value: chngdSttngs.tdyMrkClr, min: 0, max: 2, format: v => [/*LANG*/"red", /*LANG*/"green", /*LANG*/"blue"][v], - onchange: v => validSttngs.tdyMrkClr = v + onchange: v => chngdSttngs.tdyMrkClr = v }, /*LANG*/"Mrk.Size": { - value: validSttngs.tdyMrkPxl, + value: chngdSttngs.tdyMrkPxl, min: 1, max: 10, format: v => v+"px", - onchange: v => validSttngs.tdyMrkPxl = v + onchange: v => chngdSttngs.tdyMrkPxl = v }, /*LANG*/"< Cancel": () => cancelExitSettings() }); diff --git a/modules/Layout.js b/modules/Layout.js index 134cc8103..1b0bbd47f 100644 --- a/modules/Layout.js +++ b/modules/Layout.js @@ -232,7 +232,7 @@ Layout.prototype.render = function (l) { function render(l) {"ram" g.reset(); - if (l.col) g.setColor(l.col); + if (l.col!==undefined) g.setColor(l.col); if (l.bgCol!==undefined) g.setBgColor(l.bgCol).clearRect(l.x,l.y,l.x+l.w-1,l.y+l.h-1); cb[l.type](l); } @@ -264,7 +264,7 @@ Layout.prototype.render = function (l) { x,y+4 ], bg = l.selected?g.theme.bgH:g.theme.bg2; g.setColor(bg).fillPoly(poly).setColor(l.selected ? g.theme.fgH : g.theme.fg2).drawPoly(poly); - if (l.col) g.setColor(l.col); + if (l.col!==undefined) g.setColor(l.col); if (l.src) g.setBgColor(bg).drawImage("function"==typeof l.src?l.src():l.src, l.x + 10 + (0|l.pad), l.y + 8 + (0|l.pad)); else g.setFont("6x8",2).setFontAlign(0,0,l.r).drawString(l.label,l.x+l.w/2,l.y+l.h/2); }, "img":function(l){ diff --git a/modules/exstats.js b/modules/exstats.js index 8890ae9db..8a726a5de 100644 --- a/modules/exstats.js +++ b/modules/exstats.js @@ -207,7 +207,6 @@ exports.getStats = function(statIDs, options) { }; } if (statIDs.includes("caden")) { - needGPS = true; stats["caden"]={ title : "Cadence", getValue : function() { return state.stepsPerMin; },