diff --git a/apps.json b/apps.json index 2f31a59f2..052feff77 100644 --- a/apps.json +++ b/apps.json @@ -94,7 +94,7 @@ "name": "Notifications (default)", "shortName":"Notifications", "icon": "notify.png", - "version":"0.09", + "version":"0.10", "description": "A handler for displaying notifications that displays them in a bar at the top of the screen", "tags": "widget", "type": "notify", @@ -107,9 +107,9 @@ "name": "Fullscreen Notifications", "shortName":"Notifications", "icon": "notify.png", - "version":"0.10", + "version":"0.11", "description": "A handler for displaying notifications that displays them fullscreen. This may not fully restore the screen after on some apps. See `Notifications (default)` for more information about the notifications library.", - "tags": "widget", + "tags": "widget,b2", "type": "notify", "storage": [ {"name":"notify","url":"notify.js"} @@ -155,7 +155,7 @@ "icon": "app.png", "version":"0.24", "description": "The default notification handler for Gadgetbridge notifications from Android", - "tags": "tool,system,android,widget", + "tags": "tool,system,android,widget,b2", "readme": "README.md", "type":"widget", "dependencies": { "notify":"type" }, @@ -202,7 +202,7 @@ "name": "Default Alarm", "shortName":"Alarms", "icon": "app.png", - "version":"0.11", + "version":"0.12", "description": "Set and respond to alarms", "tags": "tool,alarm,widget,b2", "storage": [ @@ -571,7 +571,7 @@ { "id": "weather", "name": "Weather", "icon": "icon.png", - "version":"0.07", + "version":"0.08", "description": "Show Gadgetbridge weather report", "readme": "readme.md", "tags": "widget,outdoors", @@ -1184,7 +1184,7 @@ { "id": "widpedom", "name": "Pedometer widget", "icon": "widget.png", - "version":"0.17", + "version":"0.19", "description": "Daily pedometer widget", "tags": "widget,b2", "type":"widget", diff --git a/apps/accellog/app.js b/apps/accellog/app.js index 5408264f1..0da56b6ea 100644 --- a/apps/accellog/app.js +++ b/apps/accellog/app.js @@ -97,7 +97,7 @@ function startRecord(force) { {type:"txt", id:"samples", font:"6x8:2", label:" - ", pad:5}, {type:"txt", font:"6x8", label:"Time", pad:2}, {type:"txt", id:"time", font:"6x8:2", label:" - ", pad:5}, - {type:"txt", font:"6x8:2", label:"RECORDING", bgCol:"#f00", pad:5, fillx:true}, + {type:"txt", font:"6x8:2", label:"RECORDING", bgCol:"#f00", pad:5, fillx:1}, ] },[ // Buttons... {label:"STOP", cb:()=>{ diff --git a/apps/alarm/ChangeLog b/apps/alarm/ChangeLog index 96e1490ab..4084a7d3f 100644 --- a/apps/alarm/ChangeLog +++ b/apps/alarm/ChangeLog @@ -9,3 +9,4 @@ 0.09: Add per alarm auto-snooze option 0.10: Fix auto-snooze option (this stopped new alarms being added) (fix #506) 0.11: Respect Quiet Mode +0.12: Fix widget for bangle 2, now uses theme diff --git a/apps/alarm/widget.js b/apps/alarm/widget.js index dbe91b3dd..7b9a88bb9 100644 --- a/apps/alarm/widget.js +++ b/apps/alarm/widget.js @@ -5,7 +5,7 @@ delete alarms; // add the widget WIDGETS["alarm"]={area:"tl",width:24,draw:function() { - g.setColor(-1); + g.setColor(g.theme.fg); g.drawImage(atob("GBgBAAAAAAAAABgADhhwDDwwGP8YGf+YMf+MM//MM//MA//AA//AA//AA//AA//AA//AB//gD//wD//wAAAAADwAABgAAAAAAAAA"),this.x,this.y); }}; })() diff --git a/apps/notify/ChangeLog b/apps/notify/ChangeLog index 291f32a5a..d1826f57e 100644 --- a/apps/notify/ChangeLog +++ b/apps/notify/ChangeLog @@ -6,3 +6,4 @@ 0.07: Auto-calculate height, and pad text down even when there's no title (so it stays on-screen) 0.08: Don't turn on screen during Quiet Mode 0.09: Add onHide callback +0.10: Improvements to help notifications work with themes diff --git a/apps/notify/README.md b/apps/notify/README.md index 11c493102..f186aaab2 100644 --- a/apps/notify/README.md +++ b/apps/notify/README.md @@ -5,6 +5,10 @@ A handler for displaying notifications that displays them in a bar at the top of This is not an app, but instead it is a library that can be used by other applications or widgets to display messages. +**Note:** There are other implementations of this library available such +as `notifyfs` (Fullscreen Notifications). These can be used in the exact +same way from code, but they look different to the user. + ## Usage ```JS diff --git a/apps/notify/notify.js b/apps/notify/notify.js index 68bc1a954..4448de73b 100644 --- a/apps/notify/notify.js +++ b/apps/notify/notify.js @@ -96,15 +96,17 @@ exports.show = function(options) { b = y+h-1, r = x+w-1; // bottom,right g.setClipRect(x,y, r,b); // clear area - g.setColor(options.bgColor||0).fillRect(x,y, r,b); + g.reset(); + if (options.bgColor!==undefined) g.setColor(options.bgColor); + g.clearRect(x,y, r,b); // bottom border - g.setColor(0x39C7).fillRect(0,b-1, r,b); + g.setColor("#333").fillRect(0,b-1, r,b); b -= 2;h -= 2; // title bar if (options.title || options.src) { g.setColor(options.titleBgColor||0x39C7).fillRect(x,y, r,y+20); const title = options.title||options.src; - g.setColor(-1).setFontAlign(-1, -1, 0).setFont("6x8", 2); + g.setColor(g.theme.fg).setFontAlign(-1, -1, 0).setFont("6x8", 2); g.drawString(title.trim().substring(0, 13), x+25,y+3); if (options.title && options.src) { g.setFont("6x8", 1).setFontAlign(1, 1, 0); @@ -122,7 +124,7 @@ exports.show = function(options) { } // body text if (options.body) { - g.setColor(-1).setFont("6x8", 1).setFontAlign(-1, -1, 0).drawString(text, x+6,y+4); + g.setColor(g.theme.fg).setFont("6x8", 1).setFontAlign(-1, -1, 0).drawString(text, x+6,y+4); } if (options.render) { diff --git a/apps/notifyfs/ChangeLog b/apps/notifyfs/ChangeLog index ace651a0d..1c39bcbd5 100644 --- a/apps/notifyfs/ChangeLog +++ b/apps/notifyfs/ChangeLog @@ -8,3 +8,4 @@ 0.08: Don't turn on screen during Quiet Mode 0.09: Add onHide callback 0.10: Ensure dismissing a notification dismissal doesn't enter launcher if in clock mode +0.11: Improvements to help notifications work with themes, Bangle.js 2 support diff --git a/apps/notifyfs/notify.js b/apps/notifyfs/notify.js index cd8d108d5..a45d889f0 100644 --- a/apps/notifyfs/notify.js +++ b/apps/notifyfs/notify.js @@ -50,22 +50,24 @@ exports.show = function(options) { if (options.on===undefined) options.on=true; id = ("id" in options)?options.id:null; let size = options.size||120; - if (size>120) {size=120} - Bangle.setLCDMode("direct"); + if (size>120) size=120; + try { Bangle.setLCDMode("direct"); } catch(e) {} // not supported/needed on Bangle.js 2 let x = 0, y = 40, - w = 240, + w = g.getWidth(), h = size; // clear screen - g.setColor(options.bgColor||0).fillRect(0,0,g.getWidth(),g.getHeight()); + g.reset(); + if (options.bgColor!==undefined) g.setColor(options.bgColor); + g.clearRect(0,0,g.getWidth(),g.getHeight()); // top bar if (options.title||options.src) { - const title = options.title || options.src - g.setColor(options.titleBgColor||0x39C7).fillRect(x, y, x+w-1, y+30); - g.setColor(-1).setFontAlign(-1, -1, 0).setFont("6x8", 3); + const title = options.title || options.src; + g.setColor(options.titleBgColor||"#333").fillRect(x, y, x+w-1, y+30); + g.setColor(g.theme.fg).setFontAlign(-1, -1, 0).setFont("6x8", 3); g.drawString(title.trim().substring(0, 13), x+5, y+3); if (options.title && options.src) { - g.setColor(-1).setFontAlign(1, 1, 0).setFont("6x8", 2); + g.setColor(g.theme.fg).setFontAlign(1, 1, 0).setFont("6x8", 2); // above drawing area, but we are fullscreen g.drawString(options.src.substring(0, 10), w-16, y-4); } @@ -73,8 +75,8 @@ exports.show = function(options) { } if (options.icon) { let i = options.icon, iw,ih; - if ("string"==typeof i) {iw=i.charCodeAt(0); ih=i.charCodeAt(1)} - else {iw=i[0]; ih=i[1]} + if ("string"==typeof i) {iw=i.charCodeAt(0); ih=i.charCodeAt(1);} + else {iw=i[0]; ih=i[1];} const iy=y ? (y+4) : (h-ih)/2; // show below title bar if present, otherwise center vertically g.drawImage(i, x+4,iy); x += iw+4;w -= iw+4; @@ -84,16 +86,13 @@ exports.show = function(options) { const maxRows = Math.floor((h-4)/16), // font=2*(6x8) maxChars = Math.floor((w-4)/12), text=fitWords(options.body, maxRows, maxChars); - g.setColor(-1).setFont("6x8", 2).setFontAlign(-1, -1, 0).drawString(text, x+4, y+4); + g.setColor(g.theme.fg).setFont("6x8", 2).setFontAlign(-1, -1, 0).drawString(text, x+4, y+4); } - if (options.render) { - const area={x:x, y:y, w:w, h:h} - options.render(area); - } - if (options.on && !(require('Storage').readJSON('setting.json',1)||{}).quiet) { + if (options.render) + options.render({x:x, y:y, w:w, h:h}); + if (options.on && !(require('Storage').readJSON('setting.json',1)||{}).quiet) Bangle.setLCDPower(1); // light up - } Bangle.on("touch", exports.hide); if (options.onHide) hideCallback = options.onHide; diff --git a/apps/weather/ChangeLog b/apps/weather/ChangeLog index 8e99f8faf..fd5d4d146 100644 --- a/apps/weather/ChangeLog +++ b/apps/weather/ChangeLog @@ -3,4 +3,5 @@ 0.04: Adjust "weather unknown" message according to Bluetooth connection. 0.05: Add wind direction. 0.06: Use setUI for launcher. -0.07: Add theme support and unknown icon. \ No newline at end of file +0.07: Add theme support and unknown icon. +0.08: Refactor and reduce widget ram usage. \ No newline at end of file diff --git a/apps/weather/app.js b/apps/weather/app.js index f5200c8ae..9d64583e9 100644 --- a/apps/weather/app.js +++ b/apps/weather/app.js @@ -1,5 +1,6 @@ (() => { const weather = require('weather'); + let current = weather.get(); function formatDuration(millis) { let pluralize = (n, w) => n + " " + w + (n == 1 ? "" : "s"); @@ -10,16 +11,15 @@ } function draw() { - let w = weather.current; g.reset(); g.clearRect(0, 24, 239, 239); - weather.drawIcon(w.txt, 65, 90, 55); + weather.drawIcon(current.txt, 65, 90, 55); const locale = require("locale"); g.reset(); - const temp = locale.temp(w.temp-273.15).match(/^(\D*\d*)(.*)$/); + const temp = locale.temp(current.temp-273.15).match(/^(\D*\d*)(.*)$/); let width = g.setFont("Vector", 40).stringWidth(temp[1]); width += g.setFont("Vector", 20).stringWidth(temp[2]); g.setFont("Vector", 40).setFontAlign(-1, -1, 0); @@ -31,19 +31,19 @@ g.setFontAlign(-1, 0, 0); g.drawString("Humidity", 135, 130); g.setFontAlign(1, 0, 0); - g.drawString(w.hum+"%", 225, 130); - if ('wind' in w) { + g.drawString(current.hum+"%", 225, 130); + if ('wind' in current) { g.setFontAlign(-1, 0, 0); g.drawString("Wind", 135, 142); g.setFontAlign(1, 0, 0); - g.drawString(locale.speed(w.wind)+' '+w.wrose.toUpperCase(), 225, 142); + g.drawString(locale.speed(current.wind)+' '+current.wrose.toUpperCase(), 225, 142); } g.setFont("6x8", 2).setFontAlign(0, 0, 0); - g.drawString(w.loc, 120, 170); + g.drawString(current.loc, 120, 170); g.setFont("6x8", 1).setFontAlign(0, 0, 0); - g.drawString(w.txt.charAt(0).toUpperCase()+w.txt.slice(1), 120, 190); + g.drawString(current.txt.charAt(0).toUpperCase()+current.txt.slice(1), 120, 190); drawUpdateTime(); @@ -51,8 +51,8 @@ } function drawUpdateTime() { - if (!weather.current || !weather.current.time) return; - let text = `Last update received ${formatDuration(Date.now() - weather.current.time)} ago`; + if (!current || !current.time) return; + let text = `Last update received ${formatDuration(Date.now() - current.time)} ago`; g.reset(); g.clearRect(0, 202, 239, 210); g.setFont("6x8", 1).setFontAlign(0, 0, 0); @@ -60,8 +60,9 @@ } function update() { + current = weather.get(); NRF.removeListener("connect", update); - if (weather.current) { + if (current) { draw(); } else if (NRF.getSecurityStatus().connected) { E.showMessage("Weather unknown\n\nIs Gadgetbridge\nweather reporting\nset up on your\nphone?"); diff --git a/apps/weather/lib.js b/apps/weather/lib.js index 6a57e1f00..f08df4a4a 100644 --- a/apps/weather/lib.js +++ b/apps/weather/lib.js @@ -1,6 +1,6 @@ const storage = require('Storage'); -let expiryTimeout = undefined; +let expiryTimeout; function scheduleExpiry(json) { if (expiryTimeout) { clearTimeout(expiryTimeout); @@ -9,53 +9,35 @@ function scheduleExpiry(json) { let expiry = "expiry" in json ? json.expiry : 2*3600000; if (json.weather && json.weather.time && expiry) { let t = json.weather.time + expiry - Date.now(); - expiryTimeout = setTimeout(() => { - expiryTimeout = undefined; - - let json = storage.readJSON('weather.json')||{}; - delete json.weather; - storage.write('weather.json', json); - - exports.current = undefined; - exports.emit("update"); - }, t); + expiryTimeout = setTimeout(update, t); } } -/** - * Convert numeric direction into human-readable label - * - * @param {number} deg - Direction in degrees - * @return {string|null} - Nearest compass point - */ -function compassRose(deg) { - if (typeof deg === 'undefined') return null; - while (deg<0 || deg>360) { - deg = (deg+360)%360; - } - return ['n','ne','e','se','s','sw','w','nw','n'][Math.floor((deg+22.5)/45)]; -} - -function setCurrentWeather(json) { - scheduleExpiry(json); - exports.current = json.weather; -} - function update(weatherEvent) { - let weather = Object.assign({}, weatherEvent); - weather.time = Date.now(); - if ('wdir' in weather) { - weather.wrose = compassRose(weather.wdir); - } - delete weather.t; - let json = storage.readJSON('weather.json')||{}; - json.weather = weather; + + if (weatherEvent) { + let weather = weatherEvent.clone(); + delete weather.t; + weather.time = Date.now(); + if (weather.wdir != null) { + // Convert numeric direction into human-readable label + let deg = weather.wdir; + while (deg<0 || deg>360) { + deg = (deg+360)%360; + } + weather.wrose = ['n','ne','e','se','s','sw','w','nw','n'][Math.floor((deg+22.5)/45)]; + } + + json.weather = weather; + } + else { + delete json.weather; + } + storage.write('weather.json', json); - - setCurrentWeather(json); - - exports.emit("update"); + scheduleExpiry(json); + exports.emit("update", json.weather); } const _GB = global.GB; @@ -64,7 +46,11 @@ global.GB = (event) => { if (_GB) setTimeout(_GB, 0, event); }; -setCurrentWeather(storage.readJSON('weather.json')||{}); +exports.get = function() { + return storage.readJSON('weather.json').weather; +} + +scheduleExpiry(storage.readJSON('weather.json')||{}); exports.drawIcon = function(cond, x, y, r) { function drawSun(x, y, r) { diff --git a/apps/weather/widget.js b/apps/weather/widget.js index ba0c8604d..4871ceda4 100644 --- a/apps/weather/widget.js +++ b/apps/weather/widget.js @@ -1,45 +1,23 @@ (() => { const weather = require('weather'); - function draw() { - const w = weather.current; - if (!w) return; - g.reset(); - g.clearRect(this.x, this.y, this.x+this.width-1, this.y+23); - if (w.txt) { - weather.drawIcon(w.txt, this.x+10, this.y+8, 7.5); - } - if (w.temp) { - let t = require('locale').temp(w.temp-273.15); // applies conversion - t = t.match(/[\d\-]*/)[0]; // but we have no room for units - g.reset(); - g.setFontAlign(0, 1); // center horizontally at bottom of widget - g.setFont('6x8', 1); - g.drawString(t, this.x+10, this.y+24); - } - } - var dirty = false; - function update() { - if (!WIDGETS["weather"].width) { - WIDGETS["weather"].width = 20; - Bangle.drawWidgets(); - } else if (Bangle.isLCDOn()) { - WIDGETS["weather"].draw(); - } else { - dirty = true; + weather.on("update", w => { + if (w) { + if (!WIDGETS["weather"].width) { + WIDGETS["weather"].width = 20; + Bangle.drawWidgets(); + } else if (Bangle.isLCDOn()) { + WIDGETS["weather"].draw(); + } else { + dirty = true; + } + } + else { + WIDGETS["weather"].width = 0; + Bangle.drawWidgets(); } - } - - function hide() { - WIDGETS["weather"].width = 0; - Bangle.drawWidgets(); - } - - weather.on("update", () => { - if (weather.current) update(); - else hide(); }); Bangle.on('lcdPower', on => { @@ -51,7 +29,23 @@ WIDGETS["weather"] = { area: "tl", - width: weather.current ? 20 : 0, - draw: draw, + width: weather.get() ? 20 : 0, + draw: function() { + const w = weather.get(); + if (!w) return; + g.reset(); + g.clearRect(this.x, this.y, this.x+this.width-1, this.y+23); + if (w.txt) { + weather.drawIcon(w.txt, this.x+10, this.y+8, 7.5); + } + if (w.temp) { + let t = require('locale').temp(w.temp-273.15); // applies conversion + t = t.match(/[\d\-]*/)[0]; // but we have no room for units + g.reset(); + g.setFontAlign(0, 1); // center horizontally at bottom of widget + g.setFont('6x8', 1); + g.drawString(t, this.x+10, this.y+24); + } + }, }; })(); diff --git a/apps/widpedom/ChangeLog b/apps/widpedom/ChangeLog index a5ed0eeb2..2f36c7647 100644 --- a/apps/widpedom/ChangeLog +++ b/apps/widpedom/ChangeLog @@ -14,3 +14,8 @@ 0.15: Settings option to hide the widget icon 0.16: Settings option to show large digits in widget area 0.17: Cope with 2v10+ firmware sometimes reporting >1 step +0.18: Adjust widget width when displaying large text +0.19: Allow goal in large font mode + Stop goal drawing outside widget area + Fix issue with widget overwrite in large font mode + Memory usage enhancements diff --git a/apps/widpedom/settings.js b/apps/widpedom/settings.js index 754b636c9..4455ce7d7 100644 --- a/apps/widpedom/settings.js +++ b/apps/widpedom/settings.js @@ -32,7 +32,7 @@ onchange: (g) => { s.goal = g s.progress = !!g - save() + save(); }, }, 'Show Progress': { @@ -40,7 +40,7 @@ format: () => (s.progress ? 'Yes' : 'No'), onchange: () => { s.progress = !s.progress - save() + save(); }, }, 'Large Digits': { @@ -48,7 +48,7 @@ format: () => (s.large ? 'Yes' : 'No'), onchange: () => { s.large = !s.large - save() + save(); }, }, 'Hide Widget': { @@ -56,7 +56,7 @@ format: () => (s.hide ? 'Yes' : 'No'), onchange: () => { s.hide = !s.hide - save() + save(); }, }, '< Back': back, diff --git a/apps/widpedom/widget.js b/apps/widpedom/widget.js index 975112e02..3c861cf54 100644 --- a/apps/widpedom/widget.js +++ b/apps/widpedom/widget.js @@ -23,78 +23,6 @@ return (key in settings) ? settings[key] : DEFAULTS[key]; } - function drawProgress(stps) { - if (setting('hide')) return; - const width = 24, half = width/2; - const goal = setting('goal'), left = Math.max(goal-stps,0); - const c = left ? "#00f" : "#090"; // blue or dark green - g.setColor(c).fillCircle(this.x + half, this.y + half, half); - const TAU = Math.PI*2; - if (left) { - const f = left/goal; // fraction to blank out - let p = []; - p.push(half,half); - p.push(half,0); - if(f>1/8) p.push(0,0); - if(f>2/8) p.push(0,half); - if(f>3/8) p.push(0,width); - if(f>4/8) p.push(half,width); - if(f>5/8) p.push(width,width); - if(f>6/8) p.push(width,half); - if(f>7/8) p.push(width,0); - p.push(half - Math.sin(f * TAU) * half); - p.push(half - Math.cos(f * TAU) * half); - for (let i = p.length; i; i -= 2) { - p[i - 2] += this.x; - p[i - 1] += this.y; - } - g.setColor(g.theme.bg).fillPoly(p); - } - } - - // show the step count in the widget area in a readable sized font - function draw_large(st) { - var width = 12 * st.length; - g.reset(); - g.clearRect(this.x, this.y, this.x + width, this.y + 16); // erase background - g.setColor(g.theme.fg); - g.setFont("6x8",2); - g.setFontAlign(-1, -1); - g.drawString(st, this.x + 4, this.y + 2); - } - - // draw your widget - function draw() { - if (setting('hide')) return; - var width = 24; - if (stp_today > 99999){ - stp_today = stp_today % 100000; // cap to five digits + comma = 6 characters - } - let stps = stp_today.toString(); - if (setting('large')) { - draw_large.call(this, stps); - return; - } - g.reset().clearRect(this.x, this.y, this.x + width, this.y + 23); // erase background - if (setting('progress')){ drawProgress.call(this, stps); } - g.setColor(g.theme.fg); - if (stps.length > 3){ - stps = stps.slice(0,-3) + "," + stps.slice(-3); - g.setFont("4x6", 1); // if big, shrink text to fix - } else { - g.setFont("6x8", 1); - } - g.setFontAlign(0, 0); // align to x: center, y: center - g.drawString(stps, this.x+width/2, this.y+19); - // on low bpp screens, draw 1 bit. Currently there is no getBPP so we just do it based on resolution - g.drawImage(atob("CgoCLguH9f2/7+v6/79f56CtAAAD9fw/n8Hx9A=="),this.x+(width-10)/2,this.y+2); - } - - function reload() { - loadSettings() - draw() - } - Bangle.on('step', stepCount => { var steps = stepCount-lastStepCount; if (lastStepCount===undefined || steps<0) steps=1; @@ -115,11 +43,11 @@ } lastUpdate = date //console.log("up: " + up + " stp: " + stp_today + " " + date.toString()); - if (Bangle.isLCDOn()) WIDGETS["wpedom"].draw(); + WIDGETS["wpedom"].redraw(); }); // redraw when the LCD turns on Bangle.on('lcdPower', function(on) { - if (on) WIDGETS["wpedom"].draw(); + if (on) WIDGETS["wpedom"].redraw(); }); // When unloading, save state E.on('kill', () => { @@ -134,10 +62,80 @@ // add your widget WIDGETS["wpedom"]={area:"tl",width:26, - draw:draw, - reload:reload, - getSteps:()=>stp_today - }; + redraw:function() { // work out the width, and queue a full redraw if needed + let stps = stp_today.toString(); + let newWidth = 24; + if (setting('hide')) + newWidth = 0; + else { + if (setting('large')) { + newWidth = 12 * stps.length + 3; + if (setting('progress')) + newWidth += 24; + } + } + if (newWidth!=this.width) { + // width has changed, re-layout all widgets + this.width = newWidth; + Bangle.drawWidgets(); + } else { + // width not changed - just redraw + WIDGETS["wpedom"].draw(); + } + }, + draw:function() { + if (setting('hide')) return; + if (stp_today > 99999) + stp_today = stp_today % 100000; // cap to five digits + comma = 6 characters + let stps = stp_today.toString(); + g.reset().clearRect(this.x, this.y, this.x + this.width, this.y + 23); // erase background + if (setting('progress')) { + const width = 23, half = 11; + const goal = setting('goal'), left = Math.max(goal-stps,0); + // blue or dark green + g.setColor(left ? "#08f" : "#080").fillCircle(this.x + half, this.y + half, half); + if (left) { + const TAU = Math.PI*2; + const f = left/goal; // fraction to blank out + let p = []; + p.push(half,half); + p.push(half,0); + if(f>1/8) p.push(0,0); + if(f>2/8) p.push(0,half); + if(f>3/8) p.push(0,width); + if(f>4/8) p.push(half,width); + if(f>5/8) p.push(width,width); + if(f>6/8) p.push(width,half); + if(f>7/8) p.push(width,0); + p.push(half - Math.sin(f * TAU) * half); + p.push(half - Math.cos(f * TAU) * half); + g.setColor(g.theme.bg).fillPoly(g.transformVertices(p,{x:this.x,y:this.y})); + } + g.reset(); + } + if (setting('large')) { + g.setFont("6x8",2); + g.setFontAlign(-1, 0); + g.drawString(stps, this.x + (setting('progress')?28:4), this.y + 12); + } else { + let w = 24; + if (stps.length > 3){ + stps = stps.slice(0,-3) + "," + stps.slice(-3); + g.setFont("4x6", 1); // if big, shrink text to fix + } else { + g.setFont("6x8", 1); + } + g.setFontAlign(0, 0); // align to x: center, y: center + g.drawString(stps, this.x+w/2, this.y+19); + g.drawImage(atob("CgoCLguH9f2/7+v6/79f56CtAAAD9fw/n8Hx9A=="),this.x+(w-10)/2,this.y+2); + } + }, + reload:function() { + loadSettings(); + WIDGETS["wpedom"].redraw(); + }, + getSteps:()=>stp_today + }; // Load data at startup let pedomData = require("Storage").readJSON(PEDOMFILE,1); if (pedomData) { diff --git a/core b/core index 2aac601e3..0fd608f08 160000 --- a/core +++ b/core @@ -1 +1 @@ -Subproject commit 2aac601e38d659876eb7db5aebc7a12dd3c39da7 +Subproject commit 0fd608f085deff9b39f2db3559ecc88edb232aba