mirror of https://github.com/espruino/BangleApps
widpedom: Add goal setting
Draws progress as part of a circle (default goal: 10.000 seems to be common-ish?)pull/260/head
parent
fe3229c262
commit
8b2ea9f0c3
|
@ -786,12 +786,13 @@
|
|||
{ "id": "widpedom",
|
||||
"name": "Pedometer widget",
|
||||
"icon": "widget.png",
|
||||
"version":"0.08",
|
||||
"version":"0.09",
|
||||
"description": "Daily pedometer widget",
|
||||
"tags": "widget",
|
||||
"type":"widget",
|
||||
"storage": [
|
||||
{"name":"widpedom.wid.js","url":"widget.js"}
|
||||
{"name":"widpedom.wid.js","url":"widget.js"},
|
||||
{"name":"widpedom.settings.js","url":"settings.js"}
|
||||
]
|
||||
},
|
||||
{ "id": "berlinc",
|
||||
|
|
|
@ -5,3 +5,4 @@
|
|||
0.06: Fix widget position increment
|
||||
0.07: Tweaks for variable size widget system
|
||||
0.08: Ensure redrawing works with variable size widget system
|
||||
0.09: Add daily goal
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
(function(back) {
|
||||
const SETTINGS_FILE = 'widpedom.settings.json'
|
||||
|
||||
// initialize with default settings...
|
||||
let s = {
|
||||
'goal': 10000,
|
||||
'progress': false,
|
||||
}
|
||||
// ...and overwrite them with any saved values
|
||||
// This way saved values are preserved if a new version adds more settings
|
||||
const storage = require('Storage')
|
||||
const saved = storage.readJSON(SETTINGS_FILE, 1) || {}
|
||||
for (const key in saved) {
|
||||
s[key] = saved[key]
|
||||
}
|
||||
|
||||
function save() {
|
||||
storage.write(SETTINGS_FILE, s)
|
||||
WIDGETS['wpedom'].reload()
|
||||
}
|
||||
|
||||
E.showMenu({
|
||||
'': { 'title': 'Pedometer widget' },
|
||||
'Daily Goal': {
|
||||
value: s.goal,
|
||||
min: 0, step: 1000,
|
||||
format: s => (s ? s / 1000 + ',000' : '0'),
|
||||
onchange: (g) => {
|
||||
s.goal = g
|
||||
s.progress = !!g
|
||||
save()
|
||||
},
|
||||
},
|
||||
'Show Progress': {
|
||||
value: s.progress,
|
||||
format: () => (s.progress ? 'Yes' : 'No'),
|
||||
onchange: () => {
|
||||
s.progress = !s.progress
|
||||
save()
|
||||
},
|
||||
},
|
||||
'< Back': back,
|
||||
})
|
||||
})
|
|
@ -1,7 +1,57 @@
|
|||
(() => {
|
||||
const PEDOMFILE = "wpedom.json";
|
||||
const PEDOMFILE = "wpedom.json"
|
||||
const SETTINGS_FILE = "widpedom.settings.json"
|
||||
const DEFAULTS = {
|
||||
'goal': 10000,
|
||||
'progress': false,
|
||||
}
|
||||
const COLORS = {
|
||||
'white': -1,
|
||||
'progress': 0x001F, // Blue
|
||||
'done': 0x03E0, // DarkGreen
|
||||
}
|
||||
const TAU = Math.PI*2;
|
||||
let lastUpdate = new Date();
|
||||
let stp_today = 0;
|
||||
let settings;
|
||||
|
||||
function loadSettings() {
|
||||
settings = require('Storage').readJSON(SETTINGS_FILE, 1) || {};
|
||||
}
|
||||
|
||||
function setting(key) {
|
||||
if (!settings) { loadSettings() }
|
||||
return (key in settings) ? settings[key] : DEFAULTS[key];
|
||||
}
|
||||
|
||||
function drawProgress(stps) {
|
||||
if (setting('progress')) {
|
||||
const width = 24, half = width/2;
|
||||
const goal = setting('goal'), left = Math.max(goal-stps,0);
|
||||
const c = left ? COLORS.progress : COLORS.done;
|
||||
g.setColor(c).fillCircle(this.x + half, this.y + half, half);
|
||||
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(0).fillPoly(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// draw your widget
|
||||
function draw() {
|
||||
|
@ -11,6 +61,9 @@
|
|||
}
|
||||
let stps = stp_today.toString();
|
||||
g.reset();
|
||||
g.clearRect(this.x, this.y, this.x + width, this.y + 23); // erase background
|
||||
drawProgress(stps);
|
||||
g.setColor(COLORS.white);
|
||||
if (stps.length > 3){
|
||||
stps = stps.slice(0,-3) + "," + stps.slice(-3);
|
||||
g.setFont("4x6", 1); // if big, shrink text to fix
|
||||
|
@ -18,11 +71,15 @@
|
|||
g.setFont("6x8", 1);
|
||||
}
|
||||
g.setFontAlign(0, 0); // align to x: center, y: center
|
||||
g.clearRect(this.x,this.y+15,this.x+width,this.y+23); // erase background
|
||||
g.drawString(stps, this.x+width/2, this.y+19);
|
||||
g.drawImage(atob("CgoCLguH9f2/7+v6/79f56CtAAAD9fw/n8Hx9A=="),this.x+(width-10)/2,this.y+2);
|
||||
}
|
||||
|
||||
function reload() {
|
||||
loadSettings()
|
||||
draw()
|
||||
}
|
||||
|
||||
Bangle.on('step', (up) => {
|
||||
let date = new Date();
|
||||
if (lastUpdate.getDate() == date.getDate()){
|
||||
|
@ -31,7 +88,13 @@
|
|||
// TODO: could save this to PEDOMFILE for lastUpdate's day?
|
||||
stp_today = 1;
|
||||
}
|
||||
lastUpdate = date;
|
||||
if (stp_today === setting('goal')) {
|
||||
let b = 3, buzz = () => {
|
||||
if (b--) Bangle.buzz().then(() => setTimeout(buzz, 100))
|
||||
}
|
||||
buzz()
|
||||
}
|
||||
lastUpdate = date
|
||||
//console.log("up: " + up + " stp: " + stp_today + " " + date.toString());
|
||||
if (Bangle.isLCDOn()) WIDGETS["wpedom"].draw();
|
||||
});
|
||||
|
@ -49,7 +112,7 @@
|
|||
});
|
||||
|
||||
// add your widget
|
||||
WIDGETS["wpedom"]={area:"tl",width:26,draw:draw};
|
||||
WIDGETS["wpedom"]={area:"tl",width:26,draw:draw,reload:Reload};
|
||||
// Load data at startup
|
||||
let pedomData = require("Storage").readJSON(PEDOMFILE,1);
|
||||
if (pedomData) {
|
||||
|
|
Loading…
Reference in New Issue