Merge pull request #2156 from halemmerich/unload

Fast switch for imageclock and iconlaunch
pull/2158/head
Gordon Williams 2022-09-30 10:10:04 +01:00 committed by GitHub
commit a456f4ff62
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 928 additions and 851 deletions

View File

@ -1,3 +1,4 @@
0.01: Initial release 0.01: Initial release
0.02: implemented "direct launch" and "one click exit" settings 0.02: implemented "direct launch" and "one click exit" settings
0.03: Use default Bangle formatter for booleans 0.03: Use default Bangle formatter for booleans
0.04: Support new fast app switching

View File

@ -1,15 +1,21 @@
const s = require("Storage"); {
const settings = s.readJSON("launch.json", true) || { showClocks: true, fullscreen: false,direct:false,oneClickExit:false }; const s = require("Storage");
const settings = s.readJSON("launch.json", true) || { showClocks: true, fullscreen: false,direct:false,oneClickExit:false };
if( settings.oneClickExit) function returnToClock() {
setWatch(_=> load(), BTN1); Bangle.setUI();
setTimeout(eval,0,s.read(".bootcde"));
}
if (!settings.fullscreen) { if( settings.oneClickExit)
Bangle.loadWidgets(); setWatch(returnToClock, BTN1);
if (!settings.fullscreen) {
if (!global.WIDGETS) Bangle.loadWidgets();
Bangle.drawWidgets(); Bangle.drawWidgets();
} }
var apps = s var apps = s
.list(/\.info$/) .list(/\.info$/)
.map((app) => { .map((app) => {
var a = s.readJSON(app, 1); var a = s.readJSON(app, 1);
@ -30,29 +36,29 @@ var apps = s
(app.type == "clock" && settings.showClocks) || (app.type == "clock" && settings.showClocks) ||
!app.type) !app.type)
); );
apps.sort((a, b) => { apps.sort((a, b) => {
var n = (0 | a.sortorder) - (0 | b.sortorder); var n = (0 | a.sortorder) - (0 | b.sortorder);
if (n) return n; // do sortorder first if (n) return n; // do sortorder first
if (a.name < b.name) return -1; if (a.name < b.name) return -1;
if (a.name > b.name) return 1; if (a.name > b.name) return 1;
return 0; return 0;
}); });
apps.forEach((app) => { apps.forEach((app) => {
if (app.icon) app.icon = s.read(app.icon); // should just be a link to a memory area if (app.icon) app.icon = s.read(app.icon); // should just be a link to a memory area
}); });
let scroll = 0; let scroll = 0;
let selectedItem = -1; let selectedItem = -1;
const R = Bangle.appRect; const R = Bangle.appRect;
const iconSize = 48; const iconSize = 48;
const appsN = Math.floor(R.w / iconSize); const appsN = Math.floor(R.w / iconSize);
const whitespace = (R.w - appsN * iconSize) / (appsN + 1); const whitespace = (R.w - appsN * iconSize) / (appsN + 1);
const itemSize = iconSize + whitespace; const itemSize = iconSize + whitespace;
function drawItem(itemI, r) { function drawItem(itemI, r) {
g.clearRect(r.x, r.y, r.x + r.w - 1, r.y + r.h - 1); g.clearRect(r.x, r.y, r.x + r.w - 1, r.y + r.h - 1);
let x = 0; let x = 0;
for (let i = itemI * appsN; i < appsN * (itemI + 1); i++) { for (let i = itemI * appsN; i < appsN * (itemI + 1); i++) {
@ -74,9 +80,9 @@ function drawItem(itemI, r) {
x += iconSize; x += iconSize;
} }
drawText(itemI); drawText(itemI);
} }
function drawItemAuto(i) { function drawItemAuto(i) {
var y = idxToY(i); var y = idxToY(i);
g.reset().setClipRect(R.x, y, R.x2, y + itemSize); g.reset().setClipRect(R.x, y, R.x2, y + itemSize);
drawItem(i, { drawItem(i, {
@ -86,11 +92,11 @@ function drawItemAuto(i) {
h: itemSize h: itemSize
}); });
g.setClipRect(0, 0, g.getWidth() - 1, g.getHeight() - 1); g.setClipRect(0, 0, g.getWidth() - 1, g.getHeight() - 1);
} }
let lastIsDown = false; let lastIsDown = false;
function drawText(i) { function drawText(i) {
const selectedApp = apps[selectedItem]; const selectedApp = apps[selectedItem];
const idy = (selectedItem - (selectedItem % 3)) / 3; const idy = (selectedItem - (selectedItem % 3)) / 3;
if (!selectedApp || i != idy) return; if (!selectedApp || i != idy) return;
@ -105,9 +111,9 @@ function drawText(i) {
appY + rect.height / 2 appY + rect.height / 2
); );
g.drawString(selectedApp.name, R.w / 2, appY); g.drawString(selectedApp.name, R.w / 2, appY);
} }
function selectItem(id, e) { function selectItem(id, e) {
const iconN = E.clip(Math.floor((e.x - R.x) / itemSize), 0, appsN - 1); const iconN = E.clip(Math.floor((e.x - R.x) / itemSize), 0, appsN - 1);
const appId = id * appsN + iconN; const appId = id * appsN + iconN;
if( settings.direct && apps[appId]) if( settings.direct && apps[appId])
@ -125,17 +131,17 @@ function selectItem(id, e) {
} }
selectedItem = appId; selectedItem = appId;
drawItems(); drawItems();
} }
function idxToY(i) { function idxToY(i) {
return i * itemSize + R.y - (scroll & ~1); return i * itemSize + R.y - (scroll & ~1);
} }
function YtoIdx(y) { function YtoIdx(y) {
return Math.floor((y + (scroll & ~1) - R.y) / itemSize); return Math.floor((y + (scroll & ~1) - R.y) / itemSize);
} }
function drawItems() { function drawItems() {
g.reset().clearRect(R.x, R.y, R.x2, R.y2); g.reset().clearRect(R.x, R.y, R.x2, R.y2);
g.setClipRect(R.x, R.y, R.x2, R.y2); g.setClipRect(R.x, R.y, R.x2, R.y2);
var a = YtoIdx(R.y); var a = YtoIdx(R.y);
@ -148,16 +154,14 @@ function drawItems() {
h: itemSize, h: itemSize,
}); });
g.setClipRect(0, 0, g.getWidth() - 1, g.getHeight() - 1); g.setClipRect(0, 0, g.getWidth() - 1, g.getHeight() - 1);
} }
drawItems(); drawItems();
g.flip(); g.flip();
const itemsN = Math.ceil(apps.length / appsN); const itemsN = Math.ceil(apps.length / appsN);
Bangle.setUI({ function onDrag(e){
mode: "custom",
drag: (e) => {
g.setColor(g.theme.fg); g.setColor(g.theme.fg);
g.setBgColor(g.theme.bg); g.setBgColor(g.theme.bg);
let dy = e.dy; let dy = e.dy;
@ -202,10 +206,15 @@ Bangle.setUI({
} }
} }
g.setClipRect(0, 0, g.getWidth() - 1, g.getHeight() - 1); g.setClipRect(0, 0, g.getWidth() - 1, g.getHeight() - 1);
}, }
Bangle.setUI({
mode: "custom",
drag: onDrag,
touch: (_, e) => { touch: (_, e) => {
if (e.y < R.y - 4) return; if (e.y < R.y - 4) return;
var i = YtoIdx(e.y); var i = YtoIdx(e.y);
selectItem(i, e); selectItem(i, e);
}, },
}); });
}

View File

@ -2,7 +2,7 @@
"id": "iconlaunch", "id": "iconlaunch",
"name": "Icon Launcher", "name": "Icon Launcher",
"shortName" : "Icon launcher", "shortName" : "Icon launcher",
"version": "0.03", "version": "0.04",
"icon": "app.png", "icon": "app.png",
"description": "A launcher inspired by smartphones, with an icon-only scrollable menu.", "description": "A launcher inspired by smartphones, with an icon-only scrollable menu.",
"tags": "tool,system,launcher", "tags": "tool,system,launcher",

View File

@ -8,3 +8,4 @@
0.07: Allow wrapping drawing in timeouts to get faster reactions 0.07: Allow wrapping drawing in timeouts to get faster reactions
Show/Hide widgets with swipe up or down Show/Hide widgets with swipe up or down
0.08: Use default Bangle formatter for booleans 0.08: Use default Bangle formatter for booleans
0.09: Support new fast app switching

View File

@ -1,58 +1,63 @@
var watchface = require("Storage").readJSON("imageclock.face.json"); let unlockedDrawInterval = [];
var watchfaceResources = require("Storage").readJSON("imageclock.resources.json"); let lockedDrawInterval = [];
var precompiledJs = eval(require("Storage").read("imageclock.draw.js")); let showWidgets = false;
var settings = require('Storage').readJSON("imageclock.json", true) || {};
var performanceLog = {}; {
let watchface = require("Storage").readJSON("imageclock.face.json");
let watchfaceResources = require("Storage").readJSON("imageclock.resources.json");
let precompiledJs = eval(require("Storage").read("imageclock.draw.js"));
let settings = require('Storage').readJSON("imageclock.json", true) || {};
var startPerfLog = () => {}; let performanceLog = {};
var endPerfLog = () => {};
var printPerfLog = () => print("Deactivated");
var resetPerfLog = () => {performanceLog = {};};
var colormap={ let startPerfLog = () => {};
"#000":0, let endPerfLog = () => {};
"#00f":1, let printPerfLog = () => print("Deactivated");
"#0f0":2, let resetPerfLog = () => {performanceLog = {};};
"#0ff":3,
"#f00":4,
"#f0f":5,
"#ff0":6,
"#fff":7
};
var palette = new Uint16Array([ let colormap={
0x0000, //black #000 "#000":0,
0x001f, //blue #00f "#00f":1,
0x07e0, //green #0f0 "#0f0":2,
0x07ff, //cyan #0ff "#0ff":3,
0xf800, //red #f00 "#f00":4,
0xf81f, //magenta #f0f "#f0f":5,
0xffe0, //yellow #ff0 "#ff0":6,
0xffff, //white #fff "#fff":7
0xffff, //white };
0xffff, //white
0xffff, //white
0xffff, //white
0xffff, //white
0xffff, //white
0xffff, //white
0xffff, //white
])
var p0 = g; let palette = new Uint16Array([
var p1; 0x0000, //black #000
0x001f, //blue #00f
0x07e0, //green #0f0
0x07ff, //cyan #0ff
0xf800, //red #f00
0xf81f, //magenta #f0f
0xffe0, //yellow #ff0
0xffff, //white #fff
0xffff, //white
0xffff, //white
0xffff, //white
0xffff, //white
0xffff, //white
0xffff, //white
0xffff, //white
0xffff, //white
]);
if (settings.perflog){ let p0 = g;
let p1;
if (settings.perflog){
startPerfLog = function(name){ startPerfLog = function(name){
var time = getTime(); let time = getTime();
if (!performanceLog.start) performanceLog.start={}; if (!performanceLog.start) performanceLog.start={};
performanceLog.start[name] = time; performanceLog.start[name] = time;
}; };
endPerfLog = function (name){ endPerfLog = function (name){
var time = getTime(); let time = getTime();
if (!performanceLog.last) performanceLog.last={}; if (!performanceLog.last) performanceLog.last={};
var duration = time - performanceLog.start[name]; let duration = time - performanceLog.start[name];
performanceLog.last[name] = duration; performanceLog.last[name] = duration;
if (!performanceLog.cum) performanceLog.cum={}; if (!performanceLog.cum) performanceLog.cum={};
if (!performanceLog.cum[name]) performanceLog.cum[name] = 0; if (!performanceLog.cum[name]) performanceLog.cum[name] = 0;
@ -63,25 +68,34 @@ if (settings.perflog){
}; };
printPerfLog = function(){ printPerfLog = function(){
var result = ""; let result = "";
var keys = []; let keys = [];
for (var c in performanceLog.cum){ for (let c in performanceLog.cum){
keys.push(c); keys.push(c);
} }
keys.sort(); keys.sort();
for (var k of keys){ for (let k of keys){
print(k, "last:", (performanceLog.last[k] * 1000).toFixed(0), "average:", (performanceLog.cum[k]/performanceLog.count[k]*1000).toFixed(0), "count:", performanceLog.count[k], "total:", (performanceLog.cum[k] * 1000).toFixed(0)); print(k, "last:", (performanceLog.last[k] * 1000).toFixed(0), "average:", (performanceLog.cum[k]/performanceLog.count[k]*1000).toFixed(0), "count:", performanceLog.count[k], "total:", (performanceLog.cum[k] * 1000).toFixed(0));
} }
}; };
} }
function delay(t) { let delayTimeouts = [];
function delay(t) {
return new Promise(function (resolve) { return new Promise(function (resolve) {
setTimeout(resolve, t); delayTimeouts.push(setTimeout(resolve, t));
}); });
} }
function prepareImg(resource){ function cleanupDelays(){
for (let t of delayTimeouts){
clearTimeout(t);
}
delayTimeouts = [];
}
function prepareImg(resource){
startPerfLog("prepareImg"); startPerfLog("prepareImg");
//print("prepareImg: ", resource); //print("prepareImg: ", resource);
@ -96,14 +110,14 @@ function prepareImg(resource){
} }
endPerfLog("prepareImg"); endPerfLog("prepareImg");
return resource; return resource;
} }
function getByPath(object, path, lastElem){ function getByPath(object, path, lastElem){
startPerfLog("getByPath"); startPerfLog("getByPath");
//print("getByPath", path,lastElem); //print("getByPath", path,lastElem);
var current = object; let current = object;
if (path.length) { if (path.length) {
for (var c of path){ for (let c of path){
if (!current[c]) return undefined; if (!current[c]) return undefined;
current = current[c]; current = current[c];
} }
@ -119,36 +133,36 @@ function getByPath(object, path, lastElem){
return undefined; return undefined;
} }
return current; return current;
} }
function splitNumberToDigits(num){ function splitNumberToDigits(num){
return String(num).split('').map(item => Number(item)); return String(num).split('').map(item => Number(item));
} }
function isChangedNumber(element){ function isChangedNumber(element){
return element.lastDrawnValue != getValue(element.Value); return element.lastDrawnValue != getValue(element.Value);
} }
function isChangedMultistate(element){ function isChangedMultistate(element){
return element.lastDrawnValue != getMultistate(element.Value); return element.lastDrawnValue != getMultistate(element.Value);
} }
function drawNumber(graphics, resources, element){ function drawNumber(graphics, resources, element){
startPerfLog("drawNumber"); startPerfLog("drawNumber");
var number = getValue(element.Value); let number = getValue(element.Value);
var spacing = element.Spacing ? element.Spacing : 0; let spacing = element.Spacing ? element.Spacing : 0;
var unit = element.Unit; let unit = element.Unit;
var imageIndexMinus = element.ImageIndexMinus; let imageIndexMinus = element.ImageIndexMinus;
var imageIndexUnit = element.ImageIndexUnit; let imageIndexUnit = element.ImageIndexUnit;
var numberOfDigits = element.Digits; let numberOfDigits = element.Digits;
//print("drawNumber: ", number, element); //print("drawNumber: ", number, element);
if (number) number = number.toFixed(0); if (number) number = number.toFixed(0);
var isNegative; let isNegative;
var digits; let digits;
if (number == undefined){ if (number == undefined){
isNegative = true; isNegative = true;
digits = []; digits = [];
@ -161,25 +175,25 @@ function drawNumber(graphics, resources, element){
//print("digits: ", digits); //print("digits: ", digits);
if (!numberOfDigits) numberOfDigits = digits.length; if (!numberOfDigits) numberOfDigits = digits.length;
var firstDigitX = element.X; let firstDigitX = element.X;
var firstDigitY = element.Y; let firstDigitY = element.Y;
var imageIndex = element.ImageIndex ? element.ImageIndex : 0; let imageIndex = element.ImageIndex ? element.ImageIndex : 0;
var firstImage; let firstImage;
if (imageIndex){ if (imageIndex){
firstImage = getByPath(resources, [], "" + (0 + imageIndex)); firstImage = getByPath(resources, [], "" + (0 + imageIndex));
} else { } else {
firstImage = getByPath(resources, element.ImagePath, 0); firstImage = getByPath(resources, element.ImagePath, 0);
} }
var minusImage; let minusImage;
if (imageIndexMinus){ if (imageIndexMinus){
minusImage = getByPath(resources, [], "" + (0 + imageIndexMinus)); minusImage = getByPath(resources, [], "" + (0 + imageIndexMinus));
} else { } else {
minusImage = getByPath(resources, element.ImagePath, "minus"); minusImage = getByPath(resources, element.ImagePath, "minus");
} }
var unitImage; let unitImage;
//print("Get image for unit", imageIndexUnit); //print("Get image for unit", imageIndexUnit);
if (imageIndexUnit !== undefined){ if (imageIndexUnit !== undefined){
unitImage = getByPath(resources, [], "" + (0 + imageIndexUnit)); unitImage = getByPath(resources, [], "" + (0 + imageIndexUnit));
@ -188,7 +202,7 @@ function drawNumber(graphics, resources, element){
unitImage = getByPath(resources, element.ImagePath, getMultistate(element.Unit, "unknown")); unitImage = getByPath(resources, element.ImagePath, getMultistate(element.Unit, "unknown"));
} }
var numberWidth = (numberOfDigits * firstImage.width) + (Math.max((numberOfDigits - 1),0) * spacing); let numberWidth = (numberOfDigits * firstImage.width) + (Math.max((numberOfDigits - 1),0) * spacing);
if (isNegative && minusImage){ if (isNegative && minusImage){
//print("Adding to width", minusImage); //print("Adding to width", minusImage);
numberWidth += minusImage.width + spacing; numberWidth += minusImage.width + spacing;
@ -213,7 +227,7 @@ function drawNumber(graphics, resources, element){
firstDigitY = element.Y - firstImage.height + 1; firstDigitY = element.Y - firstImage.height + 1;
} }
var currentX = firstDigitX; let currentX = firstDigitX;
if (isNegative && minusImage){ if (isNegative && minusImage){
//print("Draw minus at", currentX); //print("Draw minus at", currentX);
if (imageIndexMinus){ if (imageIndexMinus){
@ -223,9 +237,9 @@ function drawNumber(graphics, resources, element){
} }
currentX += minusImage.width + spacing; currentX += minusImage.width + spacing;
} }
for (var d = 0; d < numberOfDigits; d++){ for (let d = 0; d < numberOfDigits; d++){
var currentDigit; let currentDigit;
var difference = numberOfDigits - digits.length; let difference = numberOfDigits - digits.length;
if (d >= difference){ if (d >= difference){
currentDigit = digits[d-difference]; currentDigit = digits[d-difference];
} else { } else {
@ -244,14 +258,14 @@ function drawNumber(graphics, resources, element){
element.lastDrawnValue = number; element.lastDrawnValue = number;
endPerfLog("drawNumber"); endPerfLog("drawNumber");
} }
function drawElement(graphics, resources, pos, element, lastElem){ function drawElement(graphics, resources, pos, element, lastElem){
startPerfLog("drawElement"); startPerfLog("drawElement");
var cacheKey = "_"+(lastElem?lastElem:"nole"); let cacheKey = "_"+(lastElem?lastElem:"nole");
if (!element.cachedImage) element.cachedImage={}; if (!element.cachedImage) element.cachedImage={};
if (!element.cachedImage[cacheKey]){ if (!element.cachedImage[cacheKey]){
var resource = getByPath(resources, element.ImagePath, lastElem); let resource = getByPath(resources, element.ImagePath, lastElem);
if (resource){ if (resource){
prepareImg(resource); prepareImg(resource);
//print("lastElem", typeof resource) //print("lastElem", typeof resource)
@ -273,7 +287,7 @@ function drawElement(graphics, resources, pos, element, lastElem){
//print("drawElement ",pos, path, lastElem); //print("drawElement ",pos, path, lastElem);
//print("resource ", resource,pos, path, lastElem); //print("resource ", resource,pos, path, lastElem);
//print("drawImage from drawElement", image, pos); //print("drawImage from drawElement", image, pos);
var options={}; let options={};
if (element.RotationValue){ if (element.RotationValue){
options.rotate = radians(element); options.rotate = radians(element);
} }
@ -290,50 +304,50 @@ function drawElement(graphics, resources, pos, element, lastElem){
endPerfLog("drawElement_g.drawImage"); endPerfLog("drawElement_g.drawImage");
} }
endPerfLog("drawElement"); endPerfLog("drawElement");
} }
function getValue(value, defaultValue){ function getValue(value, defaultValue){
if (typeof value == "string"){ if (typeof value == "string"){
return numbers[value](); return numbers[value]();
} }
if (value == undefined) return defaultValue; if (value == undefined) return defaultValue;
return value; return value;
} }
function getMultistate(name, defaultValue){ function getMultistate(name, defaultValue){
if (typeof name == "string"){ if (typeof name == "string"){
return multistates[name](); return multistates[name]();
} else { } else {
if (name == undefined) return defaultValue; if (name == undefined) return defaultValue;
} }
return undefined; return undefined;
} }
function drawScale(graphics, resources, scale){ function drawScale(graphics, resources, scale){
startPerfLog("drawScale"); startPerfLog("drawScale");
//print("drawScale", scale); //print("drawScale", scale);
var segments = scale.Segments; let segments = scale.Segments;
var imageIndex = scale.ImageIndex !== undefined ? scale.ImageIndex : 0; let imageIndex = scale.ImageIndex !== undefined ? scale.ImageIndex : 0;
var value = scaledown(scale.Value, scale.MinValue, scale.MaxValue); let value = scaledown(scale.Value, scale.MinValue, scale.MaxValue);
//print("Value is ", value, "(", maxValue, ",", minValue, ")"); //print("Value is ", value, "(", maxValue, ",", minValue, ")");
var segmentsToDraw = Math.ceil(value * segments.length); let segmentsToDraw = Math.ceil(value * segments.length);
for (var i = 0; i < segmentsToDraw; i++){ for (let i = 0; i < segmentsToDraw; i++){
drawElement(graphics, resources, segments[i], scale, imageIndex + i); drawElement(graphics, resources, segments[i], scale, imageIndex + i);
} }
scale.lastDrawnValue = segmentsToDraw; scale.lastDrawnValue = segmentsToDraw;
endPerfLog("drawScale"); endPerfLog("drawScale");
} }
function drawImage(graphics, resources, image, name){ function drawImage(graphics, resources, image, name){
startPerfLog("drawImage"); startPerfLog("drawImage");
//print("drawImage", image.X, image.Y, name); //print("drawImage", image.X, image.Y, name);
if (image.Value && image.Steps){ if (image.Value && image.Steps){
var steps = Math.floor(scaledown(image.Value, image.MinValue, image.MaxValue) * (image.Steps - 1)); let steps = Math.floor(scaledown(image.Value, image.MinValue, image.MaxValue) * (image.Steps - 1));
//print("Step", steps, "of", image.Steps); //print("Step", steps, "of", image.Steps);
drawElement(graphics, resources, image, image, "" + steps); drawElement(graphics, resources, image, image, "" + steps);
} else if (image.ImageIndex !== undefined) { } else if (image.ImageIndex !== undefined) {
@ -343,16 +357,16 @@ function drawImage(graphics, resources, image, name){
} }
endPerfLog("drawImage"); endPerfLog("drawImage");
} }
function drawCodedImage(graphics, resources, image){ function drawCodedImage(graphics, resources, image){
startPerfLog("drawCodedImage"); startPerfLog("drawCodedImage");
var code = getValue(image.Value); let code = getValue(image.Value);
//print("drawCodedImage", image, code); //print("drawCodedImage", image, code);
if (image.ImagePath) { if (image.ImagePath) {
var factor = 1; let factor = 1;
var currentCode = code; let currentCode = code;
while (code / factor > 1){ while (code / factor > 1){
currentCode = Math.floor(currentCode/factor)*factor; currentCode = Math.floor(currentCode/factor)*factor;
//print("currentCode", currentCode); //print("currentCode", currentCode);
@ -372,28 +386,28 @@ function drawCodedImage(graphics, resources, image){
image.lastDrawnValue = code; image.lastDrawnValue = code;
startPerfLog("drawCodedImage"); startPerfLog("drawCodedImage");
} }
function getWeatherCode(){ function getWeatherCode(){
var jsonWeather = require("Storage").readJSON('weather.json'); let jsonWeather = require("Storage").readJSON('weather.json');
var weather = (jsonWeather && jsonWeather.weather) ? jsonWeather.weather : undefined; let weather = (jsonWeather && jsonWeather.weather) ? jsonWeather.weather : undefined;
if (weather && weather.code){ if (weather && weather.code){
return weather.code; return weather.code;
} }
return undefined; return undefined;
} }
function getWeatherTemperature(){ function getWeatherTemperature(){
var jsonWeather = require("Storage").readJSON('weather.json'); let jsonWeather = require("Storage").readJSON('weather.json');
var weather = (jsonWeather && jsonWeather.weather) ? jsonWeather.weather : undefined; let weather = (jsonWeather && jsonWeather.weather) ? jsonWeather.weather : undefined;
var result = { unit: "unknown"}; let result = { unit: "unknown"};
if (weather && weather.temp){ if (weather && weather.temp){
//print("Weather is", weather); //print("Weather is", weather);
var temp = require('locale').temp(weather.temp-273.15); let temp = require('locale').temp(weather.temp-273.15);
result.value = Number(temp.match(/[\d\-]*/)[0]); result.value = Number(temp.match(/[\d\-]*/)[0]);
var unit; let unit;
if (temp.includes("C")){ if (temp.includes("C")){
result.unit = "celsius"; result.unit = "celsius";
} else if (temp.includes("F")){ } else if (temp.includes("F")){
@ -401,34 +415,34 @@ function getWeatherTemperature(){
} }
} }
return result; return result;
} }
function scaledown(value, min, max){ function scaledown(value, min, max){
//print("scaledown", value, min, max); //print("scaledown", value, min, max);
var scaled = E.clip(getValue(value),getValue(min,0),getValue(max,1)); let scaled = E.clip(getValue(value),getValue(min,0),getValue(max,1));
scaled -= getValue(min,0); scaled -= getValue(min,0);
scaled /= getValue(max,1); scaled /= getValue(max,1);
return scaled; return scaled;
} }
function radians(rotation){ function radians(rotation){
var value = scaledown(rotation.RotationValue, rotation.MinRotationValue, rotation.MaxRotationValue); let value = scaledown(rotation.RotationValue, rotation.MinRotationValue, rotation.MaxRotationValue);
value -= rotation.RotationOffset ? rotation.RotationOffset : 0; value -= rotation.RotationOffset ? rotation.RotationOffset : 0;
value *= 360; value *= 360;
value *= Math.PI / 180; value *= Math.PI / 180;
return value; return value;
} }
function drawPoly(graphics, resources, element){ function drawPoly(graphics, resources, element){
startPerfLog("drawPoly"); startPerfLog("drawPoly");
var vertices = []; let vertices = [];
startPerfLog("drawPoly_transform"); startPerfLog("drawPoly_transform");
for (var c of element.Vertices){ for (let c of element.Vertices){
vertices.push(c.X); vertices.push(c.X);
vertices.push(c.Y); vertices.push(c.Y);
} }
var transform = { x: element.X ? element.X : 0, let transform = { x: element.X ? element.X : 0,
y: element.Y ? element.Y : 0 y: element.Y ? element.Y : 0
}; };
if (element.RotationValue){ if (element.RotationValue){
@ -449,11 +463,11 @@ function drawPoly(graphics, resources, element){
} }
endPerfLog("drawPoly"); endPerfLog("drawPoly");
} }
function drawRect(graphics, resources, element){ function drawRect(graphics, resources, element){
startPerfLog("drawRect"); startPerfLog("drawRect");
var vertices = []; let vertices = [];
if (element.Filled){ if (element.Filled){
startPerfLog("drawRect_g.fillRect"); startPerfLog("drawRect_g.fillRect");
@ -465,9 +479,9 @@ function drawRect(graphics, resources, element){
endPerfLog("drawRect_g.fillRect"); endPerfLog("drawRect_g.fillRect");
} }
endPerfLog("drawRect"); endPerfLog("drawRect");
} }
function drawCircle(graphics, resources, element){ function drawCircle(graphics, resources, element){
startPerfLog("drawCircle"); startPerfLog("drawCircle");
if (element.Filled){ if (element.Filled){
@ -480,83 +494,86 @@ function drawCircle(graphics, resources, element){
endPerfLog("drawCircle_g.drawCircle"); endPerfLog("drawCircle_g.drawCircle");
} }
endPerfLog("drawCircle"); endPerfLog("drawCircle");
} }
var numbers = {}; let numbers = {};
numbers.Hour = () => { return new Date().getHours(); }; numbers.Hour = () => { return new Date().getHours(); };
numbers.HourTens = () => { return Math.floor(new Date().getHours()/10); }; numbers.HourTens = () => { return Math.floor(new Date().getHours()/10); };
numbers.HourOnes = () => { return Math.floor(new Date().getHours()%10); }; numbers.HourOnes = () => { return Math.floor(new Date().getHours()%10); };
numbers.Hour12 = () => { return new Date().getHours()%12; }; numbers.Hour12 = () => { return new Date().getHours()%12; };
numbers.Hour12Analog = () => { var date = new Date(); return date.getHours()%12 + (date.getMinutes()/59); }; numbers.Hour12Analog = () => { let date = new Date(); return date.getHours()%12 + (date.getMinutes()/59); };
numbers.Hour12Tens = () => { return Math.floor((new Date().getHours()%12)/10); }; numbers.Hour12Tens = () => { return Math.floor((new Date().getHours()%12)/10); };
numbers.Hour12Ones = () => { return Math.floor((new Date().getHours()%12)%10); }; numbers.Hour12Ones = () => { return Math.floor((new Date().getHours()%12)%10); };
numbers.Minute = () => { return new Date().getMinutes(); }; numbers.Minute = () => { return new Date().getMinutes(); };
numbers.MinuteAnalog = () => { var date = new Date(); return date.getMinutes() + (date.getSeconds()/59); }; numbers.MinuteAnalog = () => { let date = new Date(); return date.getMinutes() + (date.getSeconds()/59); };
numbers.MinuteTens = () => { return Math.floor(new Date().getMinutes()/10); }; numbers.MinuteTens = () => { return Math.floor(new Date().getMinutes()/10); };
numbers.MinuteOnes = () => { return Math.floor(new Date().getMinutes()%10); }; numbers.MinuteOnes = () => { return Math.floor(new Date().getMinutes()%10); };
numbers.Second = () => { return new Date().getSeconds(); }; numbers.Second = () => { return new Date().getSeconds(); };
numbers.SecondAnalog = () => { var date = new Date(); return date.getSeconds() + (date.getMilliseconds()/999); }; numbers.SecondAnalog = () => { let date = new Date(); return date.getSeconds() + (date.getMilliseconds()/999); };
numbers.SecondTens = () => { return Math.floor(new Date().getSeconds()/10); }; numbers.SecondTens = () => { return Math.floor(new Date().getSeconds()/10); };
numbers.SecondOnes = () => { return Math.floor(new Date().getSeconds()%10); }; numbers.SecondOnes = () => { return Math.floor(new Date().getSeconds()%10); };
numbers.WeekDay = () => { return new Date().getDay(); }; numbers.WeekDay = () => { return new Date().getDay(); };
numbers.WeekDayMondayFirst = () => { var day = (new Date().getDay() - 1); if (day < 0) day = 7 + day; return day; }; numbers.WeekDayMondayFirst = () => { let day = (new Date().getDay() - 1); if (day < 0) day = 7 + day; return day; };
numbers.Day = () => { return new Date().getDate(); }; numbers.Day = () => { return new Date().getDate(); };
numbers.DayTens = () => { return Math.floor(new Date().getDate()/10); }; numbers.DayTens = () => { return Math.floor(new Date().getDate()/10); };
numbers.DayOnes = () => { return Math.floor(new Date().getDate()%10); }; numbers.DayOnes = () => { return Math.floor(new Date().getDate()%10); };
numbers.Month = () => { return new Date().getMonth() + 1; }; numbers.Month = () => { return new Date().getMonth() + 1; };
numbers.MonthTens = () => { return Math.floor((new Date().getMonth() + 1)/10); }; numbers.MonthTens = () => { return Math.floor((new Date().getMonth() + 1)/10); };
numbers.MonthOnes = () => { return Math.floor((new Date().getMonth() + 1)%10); }; numbers.MonthOnes = () => { return Math.floor((new Date().getMonth() + 1)%10); };
numbers.Pulse = () => { return pulse; }; numbers.Pulse = () => { return pulse; };
numbers.Steps = () => { return Bangle.getHealthStatus ? Bangle.getHealthStatus("day").steps : undefined; }; numbers.Steps = () => { return Bangle.getHealthStatus ? Bangle.getHealthStatus("day").steps : undefined; };
numbers.StepsGoal = () => { return settings.stepsgoal || 10000; }; numbers.StepsGoal = () => { return settings.stepsgoal || 10000; };
numbers.Temperature = () => { return temp; }; numbers.Temperature = () => { return temp; };
numbers.Pressure = () => { return press; }; numbers.Pressure = () => { return press; };
numbers.Altitude = () => { return alt; }; numbers.Altitude = () => { return alt; };
numbers.BatteryPercentage = E.getBattery; numbers.BatteryPercentage = E.getBattery;
numbers.BatteryVoltage = NRF.getBattery; numbers.BatteryVoltage = NRF.getBattery;
numbers.WeatherCode = getWeatherCode; numbers.WeatherCode = getWeatherCode;
numbers.WeatherTemperature = () => { return getWeatherTemperature().value; }; numbers.WeatherTemperature = () => { return getWeatherTemperature().value; };
var multistates = {}; let multistates = {};
multistates.Lock = () => { return Bangle.isLocked() ? "on" : "off"; }; multistates.Lock = () => { return Bangle.isLocked() ? "on" : "off"; };
multistates.Charge = () => { return Bangle.isCharging() ? "on" : "off"; }; multistates.Charge = () => { return Bangle.isCharging() ? "on" : "off"; };
multistates.Notifications = () => { return ((require("Storage").readJSON("setting.json", 1) || {}).quiet|0) ? "off" : "vibrate"; }; multistates.Notifications = () => { return ((require("Storage").readJSON("setting.json", 1) || {}).quiet|0) ? "off" : "vibrate"; };
multistates.Alarm = () => { return (require('Storage').readJSON('alarm.json',1)||[]).some(alarm=>alarm.on) ? "on" : "off"; }; multistates.Alarm = () => { return (require('Storage').readJSON('alarm.json',1)||[]).some(alarm=>alarm.on) ? "on" : "off"; };
multistates.Bluetooth = () => { return NRF.getSecurityStatus().connected ? "on" : "off"; }; multistates.Bluetooth = () => { return NRF.getSecurityStatus().connected ? "on" : "off"; };
//TODO: Implement peripheral connection status //TODO: Implement peripheral connection status
multistates.BluetoothPeripheral = () => { return NRF.getSecurityStatus().connected ? "on" : "off"; }; multistates.BluetoothPeripheral = () => { return NRF.getSecurityStatus().connected ? "on" : "off"; };
multistates.HRM = () => { return Bangle.isHRMOn ? "on" : "off"; }; multistates.HRM = () => { return Bangle.isHRMOn ? "on" : "off"; };
multistates.Barometer = () => { return Bangle.isBarometerOn() ? "on" : "off"; }; multistates.Barometer = () => { return Bangle.isBarometerOn() ? "on" : "off"; };
multistates.Compass = () => { return Bangle.isCompassOn() ? "on" : "off"; }; multistates.Compass = () => { return Bangle.isCompassOn() ? "on" : "off"; };
multistates.GPS = () => { return Bangle.isGPSOn() ? "on" : "off"; }; multistates.GPS = () => { return Bangle.isGPSOn() ? "on" : "off"; };
multistates.WeatherTemperatureNegative = () => { return getWeatherTemperature().value ? getWeatherTemperature().value : 0 < 0; }; multistates.WeatherTemperatureNegative = () => { return getWeatherTemperature().value ? getWeatherTemperature().value : 0 < 0; };
multistates.WeatherTemperatureUnit = () => { return getWeatherTemperature().unit; }; multistates.WeatherTemperatureUnit = () => { return getWeatherTemperature().unit; };
multistates.StepsGoal = () => { return (numbers.Steps() >= (settings.stepsgoal || 10000)) ? "on": "off"; }; multistates.StepsGoal = () => { return (numbers.Steps() >= (settings.stepsgoal || 10000)) ? "on": "off"; };
function drawMultiState(graphics, resources, element){ function drawMultiState(graphics, resources, element){
startPerfLog("drawMultiState"); startPerfLog("drawMultiState");
//print("drawMultiState", element); //print("drawMultiState", element);
var value = multistates[element.Value](); let value = multistates[element.Value]();
//print("drawImage from drawMultiState", element, value); //print("drawImage from drawMultiState", element, value);
drawImage(graphics, resources, element, value); drawImage(graphics, resources, element, value);
element.lastDrawnValue = value; element.lastDrawnValue = value;
endPerfLog("drawMultiState"); endPerfLog("drawMultiState");
} }
var pulse,alt,temp,press; let pulse,alt,temp,press;
var requestedDraws = 0; let requestedDraws = 0;
var isDrawing = false; let isDrawing = false;
var drawingTime; let drawingTime;
var start; let start;
function initialDraw(resources, face){ let deferredTimout;
function initialDraw(resources, face){
//print("Free memory", process.memory(false).free); //print("Free memory", process.memory(false).free);
requestedDraws++; requestedDraws++;
if (!isDrawing){ if (!isDrawing){
cleanupDelays();
//print(new Date().toISOString(), "Can draw,", requestedDraws, "draws requested so far"); //print(new Date().toISOString(), "Can draw,", requestedDraws, "draws requested so far");
isDrawing = true; isDrawing = true;
resetPerfLog(); resetPerfLog();
@ -566,12 +583,13 @@ function initialDraw(resources, face){
//start = Date.now(); //start = Date.now();
drawingTime = 0; drawingTime = 0;
//print("Precompiled"); //print("Precompiled");
var promise = precompiledJs(watchfaceResources, watchface); let promise = precompiledJs(watchfaceResources, watchface);
promise.then(()=>{ promise.then(()=>{
var currentDrawingTime = Date.now(); let currentDrawingTime = Date.now();
if (showWidgets){ if (showWidgets && global.WIDGETS){
//print("Draw widgets"); //print("Draw widgets");
restoreWidgetDraw();
Bangle.drawWidgets(); Bangle.drawWidgets();
g.setColor(g.theme.fg); g.setColor(g.theme.fg);
g.drawLine(0,24,g.getWidth(),24); g.drawLine(0,24,g.getWidth(),24);
@ -590,14 +608,14 @@ function initialDraw(resources, face){
if (requestedDraws > 0){ if (requestedDraws > 0){
//print(new Date().toISOString(), "Had deferred drawing left, drawing again"); //print(new Date().toISOString(), "Had deferred drawing left, drawing again");
requestedDraws = 0; requestedDraws = 0;
setTimeout(()=>{initialDraw(resources, face);}, 10); deferredTimout = setTimeout(()=>{initialDraw(resources, face);}, 10);
} }
} //else { } //else {
//print("queued draw"); //print("queued draw");
//} //}
} }
function handleHrm(e){ function handleHrm(e){
if (e.confidence > 70){ if (e.confidence > 70){
pulse = e.bpm; pulse = e.bpm;
if (!redrawEvents || redrawEvents.includes("HRM") && !Bangle.isLocked()){ if (!redrawEvents || redrawEvents.includes("HRM") && !Bangle.isLocked()){
@ -605,9 +623,9 @@ function handleHrm(e){
initialDraw(watchfaceResources, watchface); initialDraw(watchfaceResources, watchface);
} }
} }
} }
function handlePressure(e){ function handlePressure(e){
alt = e.altitude; alt = e.altitude;
temp = e.temperature; temp = e.temperature;
press = e.pressure; press = e.pressure;
@ -615,64 +633,73 @@ function handlePressure(e){
//print("Redrawing on pressure"); //print("Redrawing on pressure");
initialDraw(watchfaceResources, watchface); initialDraw(watchfaceResources, watchface);
} }
} }
function handleCharging(e){ function handleCharging(e){
if (!redrawEvents || redrawEvents.includes("charging") && !Bangle.isLocked()){ if (!redrawEvents || redrawEvents.includes("charging") && !Bangle.isLocked()){
//print("Redrawing on charging"); //print("Redrawing on charging");
initialDraw(watchfaceResources, watchface); initialDraw(watchfaceResources, watchface);
} }
} }
function getMatchedWaitingTime(time){ function getMatchedWaitingTime(time){
var result = time - (Date.now() % time); let result = time - (Date.now() % time);
//print("Matched timeout", time, result); //print("Matched timeout", time, result);
return result; return result;
} }
function setMatchedInterval(callable, time, intervalHandler, delay){
//print("Setting matched interval for", time, intervalHandler);
function setMatchedInterval(callable, time, intervalHandler, delay){ let matchedTime = getMatchedWaitingTime(time + delay);
//print("Setting matched interval for", time); return setTimeout(()=>{
var matchedTime = getMatchedWaitingTime(time + delay); let interval = setInterval(callable, time);
setTimeout(()=>{
var interval = setInterval(callable, time);
if (intervalHandler) intervalHandler(interval); if (intervalHandler) intervalHandler(interval);
callable(); callable();
}, matchedTime); }, matchedTime);
} }
var unlockedDrawInterval;
var lockedDrawInterval;
var lastDrawTime = 0; let lastDrawTime = 0;
var firstDraw = true; let firstDraw = true;
var lockedRedraw = getByPath(watchface, ["Properties","Redraw","Locked"]) || 60000; let lockedRedraw = getByPath(watchface, ["Properties","Redraw","Locked"]) || 60000;
var unlockedRedraw = getByPath(watchface, ["Properties","Redraw","Unlocked"]) || 1000; let unlockedRedraw = getByPath(watchface, ["Properties","Redraw","Unlocked"]) || 1000;
var defaultRedraw = getByPath(watchface, ["Properties","Redraw","Default"]) || "Always"; let defaultRedraw = getByPath(watchface, ["Properties","Redraw","Default"]) || "Always";
var redrawEvents = getByPath(watchface, ["Properties","Redraw","Events"]); let redrawEvents = getByPath(watchface, ["Properties","Redraw","Events"]);
var clearOnRedraw = getByPath(watchface, ["Properties","Redraw","Clear"]); let clearOnRedraw = getByPath(watchface, ["Properties","Redraw","Clear"]);
var events = getByPath(watchface, ["Properties","Events"]); let events = getByPath(watchface, ["Properties","Events"]);
//print("events", events); //print("events", events);
//print("redrawEvents", redrawEvents); //print("redrawEvents", redrawEvents);
function handleLock(isLocked, forceRedraw){ let initialDrawTimeoutUnlocked;
let initialDrawTimeoutLocked;
function handleLock(isLocked, forceRedraw){
//print("isLocked", Bangle.isLocked()); //print("isLocked", Bangle.isLocked());
if (lockedDrawInterval) clearInterval(lockedDrawInterval); for (let i of unlockedDrawInterval){
if (unlockedDrawInterval) clearInterval(unlockedDrawInterval); //print("Clearing unlocked", i);
clearInterval(i);
}
for (let i of lockedDrawInterval){
//print("Clearing locked", i);
clearInterval(i);
}
unlockedDrawInterval = [];
lockedDrawInterval = [];
if (!isLocked){ if (!isLocked){
if (forceRedraw || !redrawEvents || (redrawEvents.includes("unlock"))){ if (forceRedraw || !redrawEvents || (redrawEvents.includes("unlock"))){
//print("Redrawing on unlock", isLocked); //print("Redrawing on unlock", isLocked);
initialDraw(watchfaceResources, watchface); initialDraw(watchfaceResources, watchface);
} }
setMatchedInterval(()=>{ initialDrawTimeoutUnlocked = setMatchedInterval(()=>{
//print("Redrawing on unlocked interval"); //print("Redrawing on unlocked interval");
initialDraw(watchfaceResources, watchface); initialDraw(watchfaceResources, watchface);
},unlockedRedraw, (v)=>{ },unlockedRedraw, (v)=>{
unlockedDrawInterval = v; //print("New matched unlocked interval", v);
unlockedDrawInterval.push(v);
}, lastDrawTime); }, lastDrawTime);
if (!events || events.includes("HRM")) Bangle.setHRMPower(1, "imageclock"); if (!events || events.includes("HRM")) Bangle.setHRMPower(1, "imageclock");
if (!events || events.includes("pressure")) Bangle.setBarometerPower(1, 'imageclock'); if (!events || events.includes("pressure")) Bangle.setBarometerPower(1, 'imageclock');
@ -681,37 +708,41 @@ function handleLock(isLocked, forceRedraw){
//print("Redrawing on lock", isLocked); //print("Redrawing on lock", isLocked);
initialDraw(watchfaceResources, watchface); initialDraw(watchfaceResources, watchface);
} }
setMatchedInterval(()=>{ initialDrawTimeoutLocked = setMatchedInterval(()=>{
//print("Redrawing on locked interval"); //print("Redrawing on locked interval");
initialDraw(watchfaceResources, watchface); initialDraw(watchfaceResources, watchface);
},lockedRedraw, (v)=>{ },lockedRedraw, (v)=>{
lockedDrawInterval = v; //print("New matched locked interval", v);
lockedDrawInterval.push(v);
}, lastDrawTime); }, lastDrawTime);
Bangle.setHRMPower(0, "imageclock"); Bangle.setHRMPower(0, "imageclock");
Bangle.setBarometerPower(0, 'imageclock'); Bangle.setBarometerPower(0, 'imageclock');
} }
} }
var showWidgets = false; let showWidgetsChanged = false;
var showWidgetsChanged = false; let currentDragDistance = 0;
var currentDragDistance = 0;
Bangle.setUI("clock"); function restoreWidgetDraw(){
Bangle.on('drag', (e)=>{ if (global.WIDGETS) {
for (let w in global.WIDGETS) {
let wd = global.WIDGETS[w];
wd.draw = originalWidgetDraw[w];
wd.area = originalWidgetArea[w];
}
}
}
function handleDrag(e){
//print("handleDrag");
currentDragDistance += e.dy; currentDragDistance += e.dy;
if (Math.abs(currentDragDistance) < 10) return; if (Math.abs(currentDragDistance) < 10) return;
dragDown = currentDragDistance > 0; dragDown = currentDragDistance > 0;
currentDragDistance = 0; currentDragDistance = 0;
if (!showWidgets && dragDown){ if (!showWidgets && dragDown){
//print("Enable widgets"); //print("Enable widgets");
if (WIDGETS && typeof WIDGETS === "object") { restoreWidgetDraw();
for (let w in WIDGETS) {
var wd = WIDGETS[w];
wd.draw = originalWidgetDraw[w];
wd.area = originalWidgetArea[w];
}
}
showWidgetsChanged = true; showWidgetsChanged = true;
} }
if (showWidgets && !dragDown){ if (showWidgets && !dragDown){
@ -727,48 +758,83 @@ Bangle.on('drag', (e)=>{
initialDraw(); initialDraw();
} }
} }
);
if (!events || events.includes("pressure")){ Bangle.on('drag', handleDrag);
if (!events || events.includes("pressure")){
Bangle.on('pressure', handlePressure); Bangle.on('pressure', handlePressure);
try{ try{
Bangle.setBarometerPower(1, 'imageclock'); Bangle.setBarometerPower(1, 'imageclock');
} catch (e){ } catch (e){
print("Error during barometer power up", e); print("Error during barometer power up", e);
} }
} }
if (!events || events.includes("HRM")) { if (!events || events.includes("HRM")) {
Bangle.on('HRM', handleHrm); Bangle.on('HRM', handleHrm);
Bangle.setHRMPower(1, "imageclock"); Bangle.setHRMPower(1, "imageclock");
} }
if (!events || events.includes("lock")) { if (!events || events.includes("lock")) {
Bangle.on('lock', handleLock); Bangle.on('lock', handleLock);
} }
if (!events || events.includes("charging")) { if (!events || events.includes("charging")) {
Bangle.on('charging', handleCharging); Bangle.on('charging', handleCharging);
} }
var originalWidgetDraw = {}; let originalWidgetDraw = {};
var originalWidgetArea = {}; let originalWidgetArea = {};
function clearWidgetsDraw(){ function clearWidgetsDraw(){
//print("Clear widget draw calls"); //print("Clear widget draw calls");
if (WIDGETS && typeof WIDGETS === "object") { if (global.WIDGETS) {
originalWidgetDraw = {}; originalWidgetDraw = {};
originalWidgetArea = {}; originalWidgetArea = {};
for (let w in WIDGETS) { for (let w in global.WIDGETS) {
var wd = WIDGETS[w]; let wd = global.WIDGETS[w];
originalWidgetDraw[w] = wd.draw; originalWidgetDraw[w] = wd.draw;
originalWidgetArea[w] = wd.area; originalWidgetArea[w] = wd.area;
wd.draw = () => {}; wd.draw = () => {};
wd.area = ""; wd.area = "";
} }
} }
} }
setTimeout(()=>{ if (!global.WIDGETS) Bangle.loadWidgets();
Bangle.loadWidgets();
clearWidgetsDraw(); clearWidgetsDraw();
}, 0);
handleLock(Bangle.isLocked()); handleLock(Bangle.isLocked());
Bangle.setUI({
mode : "clock",
remove : function() {
//print("remove calls");
// Called to unload all of the clock app
Bangle.setHRMPower(0, "imageclock");
Bangle.setBarometerPower(0, 'imageclock');
Bangle.removeListener('drag', handleDrag);
Bangle.removeListener('lock', handleLock);
Bangle.removeListener('charging', handleCharging);
Bangle.removeListener('HRM', handleHrm);
Bangle.removeListener('pressure', handlePressure);
if (deferredTimout) clearTimeout(deferredTimout);
if (initialDrawTimeoutUnlocked) clearTimeout(initialDrawTimeoutUnlocked);
if (initialDrawTimeoutLocked) clearTimeout(initialDrawTimeoutLocked);
for (let i of unlockedDrawInterval){
//print("Clearing unlocked", i);
clearInterval(i);
}
delete unlockedDrawInterval;
for (let i of lockedDrawInterval){
//print("Clearing locked", i);
clearInterval(i);
}
delete lockedDrawInterval;
delete showWidgets;
cleanupDelays();
restoreWidgetDraw();
}
});
}

View File

@ -2,7 +2,7 @@
"id": "imageclock", "id": "imageclock",
"name": "Imageclock", "name": "Imageclock",
"shortName": "Imageclock", "shortName": "Imageclock",
"version": "0.08", "version": "0.09",
"type": "clock", "type": "clock",
"description": "BETA!!! File formats still subject to change --- This app is a highly customizable watchface. To use it, you need to select a watchface. You can build the watchfaces yourself without programming anything. All you need to do is write some json and create image files.", "description": "BETA!!! File formats still subject to change --- This app is a highly customizable watchface. To use it, you need to select a watchface. You can build the watchfaces yourself without programming anything. All you need to do is write some json and create image files.",
"icon": "app.png", "icon": "app.png",