Merge pull request #1347 from myxor/circlesclock_v0.08

Circlesclock v0.08
pull/1351/head
Gordon Williams 2022-01-26 13:24:14 +00:00 committed by GitHub
commit e1dba617ed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 76 additions and 39 deletions

View File

@ -12,3 +12,4 @@
Support to show time and progress until next sunrise or sunset Support to show time and progress until next sunrise or sunset
Load daily steps from Bangle health if available Load daily steps from Bangle health if available
0.07: Allow configuration of minimal heart rate confidence 0.07: Allow configuration of minimal heart rate confidence
0.08: Allow configuration of up to 4 circles in a row

View File

@ -1,6 +1,6 @@
# Circles clock # Circles clock
A clock with circles for different data at the bottom in a probably familiar style A clock with three or four circles for different data at the bottom in a probably familiar style
By default the time, date and day of week is shown. By default the time, date and day of week is shown.
@ -18,6 +18,8 @@ It can show the following information (this can be configured):
## Screenshots ## Screenshots
![Screenshot dark theme](screenshot-dark.png) ![Screenshot dark theme](screenshot-dark.png)
![Screenshot light theme](screenshot-light.png) ![Screenshot light theme](screenshot-light.png)
![Screenshot dark theme with four circles](screenshot-dark-4.png)
![Screenshot light theme with four circles](screenshot-light-4.png)
## Creator ## Creator
Marco ([myxor](https://github.com/myxor)) Marco ([myxor](https://github.com/myxor))

View File

@ -23,31 +23,27 @@ const weatherStormy = heatshrink.decompress(atob("iEQwYLIg/gAgUB///wAFBh/AgfwgED
const sunSetDown = heatshrink.decompress(atob("iEQwIHEgOAAocT5EGtEEkF//wLDg1ggfACoo")); const sunSetDown = heatshrink.decompress(atob("iEQwIHEgOAAocT5EGtEEkF//wLDg1ggfACoo"));
const sunSetUp = heatshrink.decompress(atob("iEQwIHEgOAAocT5EGtEEkF//wRFgfAg1gBIY")); const sunSetUp = heatshrink.decompress(atob("iEQwIHEgOAAocT5EGtEEkF//wRFgfAg1gBIY"));
let settings; let settings = storage.readJSON("circlesclock.json", 1) || {
'minHR': 40,
function loadSettings() { 'maxHR': 200,
settings = storage.readJSON("circlesclock.json", 1) || { 'confidence': 0,
'minHR': 40, 'stepGoal': 10000,
'maxHR': 200, 'stepDistanceGoal': 8000,
'confidence': 0, 'stepLength': 0.8,
'stepGoal': 10000, 'batteryWarn': 30,
'stepDistanceGoal': 8000, 'showWidgets': false,
'stepLength': 0.8, 'weatherCircleData': 'humidity',
'batteryWarn': 30, 'circleCount': 3,
'showWidgets': false, 'circle1': 'hr',
'weatherCircleData': 'humidity', 'circle2': 'steps',
'circle1': 'hr', 'circle3': 'battery',
'circle2': 'steps', 'circle4': 'weather'
'circle3': 'battery' };
}; // Load step goal from pedometer widget as fallback
// Load step goal from pedometer widget as fallback if (settings.stepGoal == undefined) {
if (settings.stepGoal == undefined) { const d = require('Storage').readJSON("wpedom.json", 1) || {};
const d = require('Storage').readJSON("wpedom.json", 1) || {}; settings.stepGoal = d != undefined && d.settings != undefined ? d.settings.goal : 10000;
settings.stepGoal = d != undefined && d.settings != undefined ? d.settings.goal : 10000;
}
} }
loadSettings();
/* /*
* Read location from myLocation app * Read location from myLocation app
@ -58,6 +54,7 @@ function getLocation() {
let location = getLocation(); let location = getLocation();
const showWidgets = settings.showWidgets || false; const showWidgets = settings.showWidgets || false;
const circleCount = settings.circleCount || 3;
let hrtValue; let hrtValue;
let now = Math.round(new Date().getTime() / 1000); let now = Math.round(new Date().getTime() / 1000);
@ -78,11 +75,33 @@ const hOffset = 30 - widgetOffset;
const h1 = Math.round(1 * h / 5 - hOffset); const h1 = Math.round(1 * h / 5 - hOffset);
const h2 = Math.round(3 * h / 5 - hOffset); const h2 = Math.round(3 * h / 5 - hOffset);
const h3 = Math.round(8 * h / 8 - hOffset - 3); // circle y position const h3 = Math.round(8 * h / 8 - hOffset - 3); // circle y position
const circlePosX = [Math.round(w / 6), Math.round(3 * w / 6), Math.round(5 * w / 6)]; // cirle x positions
const radiusOuter = 25; /*
const radiusInner = 20; * circle x positions
const circleFont = "Vector:15"; * depending on circleCount
const circleFontBig = "Vector:16"; *
* | 1 2 3 4 5 6 |
* | (1) (2) (3) |
* => circles start at 1,3,5 / 6
*
* | 1 2 3 4 5 6 7 8 |
* | (1) (2) (3) (4) |
* => circles start at 1,3,5,7 / 8
*/
const parts = circleCount * 2;
const circlePosX = [
Math.round(1 * w / parts), // circle1
Math.round(3 * w / parts), // circle2
Math.round(5 * w / parts), // circle3
Math.round(7 * w / parts), // circle4
];
const radiusOuter = circleCount == 3 ? 25 : 20;
const radiusInner = circleCount == 3 ? 20 : 15;
const circleFont = circleCount == 3 ? "Vector:15" : "Vector:12";
const circleFontBig = circleCount == 3 ? "Vector:16" : "Vector:13";
const defaultCircleTypes = ["steps", "hr", "battery", "weather"];
function draw() { function draw() {
g.clear(true); g.clear(true);
@ -122,10 +141,9 @@ function draw() {
drawCircle(1); drawCircle(1);
drawCircle(2); drawCircle(2);
drawCircle(3); drawCircle(3);
if (circleCount >= 4) drawCircle(4);
} }
const defaultCircleTypes = ["steps", "hr", "battery"];
function drawCircle(index) { function drawCircle(index) {
let type = settings['circle' + index]; let type = settings['circle' + index];
if (!type) type = defaultCircleTypes[index - 1]; if (!type) type = defaultCircleTypes[index - 1];
@ -147,6 +165,7 @@ function drawCircle(index) {
drawWeather(w); drawWeather(w);
break; break;
case "sunprogress": case "sunprogress":
case "sunProgress":
drawSunProgress(w); drawSunProgress(w);
break; break;
case "empty": case "empty":
@ -169,7 +188,7 @@ function getCirclePosition(type) {
if (circlePositionsCache[type] >= 0) { if (circlePositionsCache[type] >= 0) {
return circlePosX[circlePositionsCache[type]]; return circlePosX[circlePositionsCache[type]];
} }
for (let i = 1; i <= 3; i++) { for (let i = 1; i <= circleCount; i++) {
const setting = settings['circle' + i]; const setting = settings['circle' + i];
if (setting == type) { if (setting == type) {
circlePositionsCache[type] = i - 1; circlePositionsCache[type] = i - 1;
@ -319,6 +338,8 @@ function drawWeather(w) {
if (code > 0) { if (code > 0) {
const icon = getWeatherIconByCode(code); const icon = getWeatherIconByCode(code);
if (icon) g.drawImage(icon, w - 6, h3 + radiusOuter - 10); if (icon) g.drawImage(icon, w - 6, h3 + radiusOuter - 10);
} else {
g.drawString("?", w, h3 + radiusOuter);
} }
} }

View File

@ -1,10 +1,10 @@
{ "id": "circlesclock", { "id": "circlesclock",
"name": "Circles clock", "name": "Circles clock",
"shortName":"Circles clock", "shortName":"Circles clock",
"version":"0.07", "version":"0.08",
"description": "A clock with circles for different data at the bottom in a probably familiar style", "description": "A clock with three or four circles for different data at the bottom in a probably familiar style",
"icon": "app.png", "icon": "app.png",
"screenshots": [{"url":"screenshot-dark.png"}, {"url":"screenshot-light.png"}], "screenshots": [{"url":"screenshot-dark.png"}, {"url":"screenshot-light.png"}, {"url":"screenshot-dark-4.png"}, {"url":"screenshot-light-4.png"}],
"type": "clock", "type": "clock",
"tags": "clock", "tags": "clock",
"supports" : ["BANGLEJS2"], "supports" : ["BANGLEJS2"],

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

View File

@ -96,23 +96,36 @@
format: v => weatherData[v], format: v => weatherData[v],
onchange: x => save('weatherCircleData', weatherData[x]), onchange: x => save('weatherCircleData', weatherData[x]),
}, },
'left': { 'circle count': {
value: "circleCount" in settings ? settings.circleCount : 3,
min: 3,
max : 4,
step: 1,
onchange: x => save('circleCount', x),
},
'circle1': {
value: settings.circle1 ? valuesCircleTypes.indexOf(settings.circle1) : 0, value: settings.circle1 ? valuesCircleTypes.indexOf(settings.circle1) : 0,
min: 0, max: 6, min: 0, max: 6,
format: v => namesCircleTypes[v], format: v => namesCircleTypes[v],
onchange: x => save('circle1', valuesCircleTypes[x]), onchange: x => save('circle1', valuesCircleTypes[x]),
}, },
'middle': { 'circle2': {
value: settings.circle2 ? valuesCircleTypes.indexOf(settings.circle2) : 2, value: settings.circle2 ? valuesCircleTypes.indexOf(settings.circle2) : 2,
min: 0, max: 6, min: 0, max: 6,
format: v => namesCircleTypes[v], format: v => namesCircleTypes[v],
onchange: x => save('circle2', valuesCircleTypes[x]), onchange: x => save('circle2', valuesCircleTypes[x]),
}, },
'right': { 'circle3': {
value: settings.circle3 ? valuesCircleTypes.indexOf(settings.circle3) : 3, value: settings.circle3 ? valuesCircleTypes.indexOf(settings.circle3) : 3,
min: 0, max: 6, min: 0, max: 6,
format: v => namesCircleTypes[v], format: v => namesCircleTypes[v],
onchange: x => save('circle3', valuesCircleTypes[x]), onchange: x => save('circle3', valuesCircleTypes[x]),
},
'circle4': {
value: settings.circle4 ? valuesCircleTypes.indexOf(settings.circle4) : 4,
min: 0, max: 6,
format: v => namesCircleTypes[v],
onchange: x => save('circle4', valuesCircleTypes[x]),
} }
}); });
}); });