2022-09-27 18:44:32 +00:00
|
|
|
let unlockedDrawInterval = [];
|
|
|
|
let lockedDrawInterval = [];
|
2022-09-29 21:34:53 +00:00
|
|
|
let showWidgets = false;
|
2022-09-30 16:05:53 +00:00
|
|
|
let firstDraw = true;
|
2022-09-27 18:44:32 +00:00
|
|
|
|
|
|
|
{
|
2022-10-03 18:00:14 +00:00
|
|
|
let x = g.getWidth()/2;
|
|
|
|
let y = g.getHeight()/2;
|
|
|
|
g.setColor(g.theme.bg);
|
|
|
|
g.fillRect(x-49, y-19, x+49, y+19);
|
|
|
|
g.setColor(g.theme.fg);
|
|
|
|
g.drawRect(x-50, y-20, x+50, y+20);
|
|
|
|
y -= 4;
|
|
|
|
x -= 4*6;
|
|
|
|
g.setFont("6x8");
|
|
|
|
g.setFontAlign(-1,-1);
|
|
|
|
g.drawString("Loading...", x, y);
|
|
|
|
|
2022-09-27 18:44:32 +00:00
|
|
|
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) || {};
|
|
|
|
|
|
|
|
let performanceLog = {};
|
|
|
|
|
|
|
|
let startPerfLog = () => {};
|
|
|
|
let endPerfLog = () => {};
|
2022-10-04 20:16:01 +00:00
|
|
|
Bangle.printPerfLog = () => {print("Deactivated");};
|
|
|
|
Bangle.resetPerfLog = () => {performanceLog = {};};
|
2022-09-27 18:44:32 +00:00
|
|
|
|
|
|
|
let colormap={
|
2022-10-05 17:17:24 +00:00
|
|
|
"#000":0,
|
|
|
|
"#00f":1,
|
|
|
|
"#0f0":2,
|
|
|
|
"#0ff":3,
|
|
|
|
"#f00":4,
|
|
|
|
"#f0f":5,
|
|
|
|
"#ff0":6,
|
|
|
|
"#fff":7
|
2022-02-28 19:14:19 +00:00
|
|
|
};
|
|
|
|
|
2022-09-27 18:44:32 +00:00
|
|
|
let palette = new Uint16Array([
|
2022-10-05 17:17:24 +00:00
|
|
|
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
|
2022-09-27 18:44:32 +00:00
|
|
|
]);
|
|
|
|
|
|
|
|
let p0 = g;
|
|
|
|
let p1;
|
|
|
|
|
|
|
|
if (settings.perflog){
|
2022-10-04 20:16:01 +00:00
|
|
|
startPerfLog = function(name){
|
2022-09-27 18:44:32 +00:00
|
|
|
let time = getTime();
|
|
|
|
if (!performanceLog.start) performanceLog.start={};
|
|
|
|
performanceLog.start[name] = time;
|
|
|
|
};
|
2022-10-04 20:16:01 +00:00
|
|
|
endPerfLog = function (name){
|
2022-09-27 18:44:32 +00:00
|
|
|
let time = getTime();
|
|
|
|
if (!performanceLog.last) performanceLog.last={};
|
|
|
|
let duration = time - performanceLog.start[name];
|
|
|
|
performanceLog.last[name] = duration;
|
|
|
|
if (!performanceLog.cum) performanceLog.cum={};
|
|
|
|
if (!performanceLog.cum[name]) performanceLog.cum[name] = 0;
|
|
|
|
performanceLog.cum[name] += duration;
|
|
|
|
if (!performanceLog.count) performanceLog.count={};
|
|
|
|
if (!performanceLog.count[name]) performanceLog.count[name] = 0;
|
|
|
|
performanceLog.count[name]++;
|
|
|
|
};
|
2022-02-28 19:14:19 +00:00
|
|
|
|
2022-10-03 18:01:14 +00:00
|
|
|
Bangle.printPerfLog = function(){
|
2022-09-27 18:44:32 +00:00
|
|
|
let result = "";
|
|
|
|
let keys = [];
|
|
|
|
for (let c in performanceLog.cum){
|
|
|
|
keys.push(c);
|
|
|
|
}
|
|
|
|
keys.sort();
|
|
|
|
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));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
2022-10-05 17:22:30 +00:00
|
|
|
|
|
|
|
let delayTimeouts = {};
|
|
|
|
let timeoutCount = 0;
|
2022-03-06 17:35:32 +00:00
|
|
|
|
2022-10-03 16:30:22 +00:00
|
|
|
let delay = function(t) {
|
2022-09-27 18:44:32 +00:00
|
|
|
return new Promise(function (resolve) {
|
2022-10-05 17:22:30 +00:00
|
|
|
const i = timeoutCount++;
|
|
|
|
let timeout = setTimeout(()=>{
|
|
|
|
resolve();
|
|
|
|
delete delayTimeouts[i];
|
|
|
|
}, t);
|
|
|
|
delayTimeouts[i] = timeout;
|
|
|
|
//print("Add delay timeout", delayTimeouts);
|
2022-09-27 18:44:32 +00:00
|
|
|
});
|
2022-10-03 16:30:22 +00:00
|
|
|
};
|
2022-02-21 16:58:33 +00:00
|
|
|
|
2022-10-03 16:30:22 +00:00
|
|
|
let cleanupDelays = function(){
|
2022-10-05 17:17:24 +00:00
|
|
|
//print("Cleanup delays", delayTimeouts);
|
2022-09-27 18:44:32 +00:00
|
|
|
for (let t of delayTimeouts){
|
|
|
|
clearTimeout(t);
|
2022-03-03 17:44:50 +00:00
|
|
|
}
|
2022-10-05 17:22:30 +00:00
|
|
|
delayTimeouts = {};
|
2022-10-03 16:30:22 +00:00
|
|
|
};
|
2022-09-27 18:44:32 +00:00
|
|
|
|
2022-10-03 16:30:22 +00:00
|
|
|
let prepareImg = function(resource){
|
2022-09-27 18:44:32 +00:00
|
|
|
startPerfLog("prepareImg");
|
|
|
|
//print("prepareImg: ", resource);
|
|
|
|
|
|
|
|
if (resource.dataOffset !== undefined){
|
|
|
|
resource.buffer = E.toArrayBuffer(require("Storage").read("imageclock.resources.data", resource.dataOffset, resource.dataLength));
|
|
|
|
delete resource.dataOffset;
|
|
|
|
delete resource.dataLength;
|
|
|
|
if (resource.paletteData){
|
2022-10-04 20:08:13 +00:00
|
|
|
resource.palette = new Uint16Array(resource.paletteData);
|
2022-09-27 18:44:32 +00:00
|
|
|
delete resource.paletteData;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
endPerfLog("prepareImg");
|
|
|
|
return resource;
|
2022-10-03 16:30:22 +00:00
|
|
|
};
|
2022-02-19 01:34:37 +00:00
|
|
|
|
2022-10-03 16:30:22 +00:00
|
|
|
let getByPath = function(object, path, lastElem){
|
2022-09-27 18:44:32 +00:00
|
|
|
startPerfLog("getByPath");
|
|
|
|
//print("getByPath", path,lastElem);
|
|
|
|
let current = object;
|
|
|
|
if (path.length) {
|
|
|
|
for (let c of path){
|
|
|
|
if (!current[c]) return undefined;
|
|
|
|
current = current[c];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (lastElem!==undefined){
|
|
|
|
if (!current["" + lastElem]) return undefined;
|
|
|
|
//print("Found by lastElem", lastElem);
|
|
|
|
current = current["" + lastElem];
|
2022-02-24 22:15:58 +00:00
|
|
|
}
|
2022-09-27 18:44:32 +00:00
|
|
|
endPerfLog("getByPath");
|
|
|
|
if (typeof current == "function"){
|
|
|
|
//print("current was function");
|
|
|
|
return undefined;
|
|
|
|
}
|
|
|
|
return current;
|
2022-10-03 16:30:22 +00:00
|
|
|
};
|
2022-09-27 18:44:32 +00:00
|
|
|
|
2022-10-03 16:30:22 +00:00
|
|
|
let splitNumberToDigits = function(num){
|
2022-09-27 18:44:32 +00:00
|
|
|
return String(num).split('').map(item => Number(item));
|
2022-10-03 16:30:22 +00:00
|
|
|
};
|
2022-09-27 18:44:32 +00:00
|
|
|
|
2022-10-03 16:30:22 +00:00
|
|
|
let isChangedNumber = function(element){
|
2022-09-27 18:44:32 +00:00
|
|
|
return element.lastDrawnValue != getValue(element.Value);
|
2022-10-03 16:30:22 +00:00
|
|
|
};
|
2022-09-27 18:44:32 +00:00
|
|
|
|
2022-10-03 16:30:22 +00:00
|
|
|
let isChangedMultistate = function(element){
|
2022-09-27 18:44:32 +00:00
|
|
|
return element.lastDrawnValue != getMultistate(element.Value);
|
2022-10-03 16:30:22 +00:00
|
|
|
};
|
2022-02-19 01:34:37 +00:00
|
|
|
|
2022-10-03 16:30:22 +00:00
|
|
|
let drawNumber = function(graphics, resources, element){
|
2022-09-27 18:44:32 +00:00
|
|
|
startPerfLog("drawNumber");
|
|
|
|
let number = getValue(element.Value);
|
2022-10-05 17:17:24 +00:00
|
|
|
//print("drawNumber: ", number, element);
|
2022-09-27 18:44:32 +00:00
|
|
|
let spacing = element.Spacing ? element.Spacing : 0;
|
|
|
|
let unit = element.Unit;
|
2022-02-19 01:34:37 +00:00
|
|
|
|
2022-09-27 18:44:32 +00:00
|
|
|
let imageIndexMinus = element.ImageIndexMinus;
|
|
|
|
let imageIndexUnit = element.ImageIndexUnit;
|
|
|
|
let numberOfDigits = element.Digits;
|
2022-03-06 15:19:46 +00:00
|
|
|
|
|
|
|
|
2022-09-27 18:44:32 +00:00
|
|
|
if (number) number = number.toFixed(0);
|
|
|
|
|
|
|
|
let isNegative;
|
|
|
|
let digits;
|
|
|
|
if (number == undefined){
|
|
|
|
isNegative = true;
|
|
|
|
digits = [];
|
|
|
|
numberOfDigits = 0;
|
2022-03-01 20:37:33 +00:00
|
|
|
} else {
|
2022-09-27 18:44:32 +00:00
|
|
|
isNegative = number < 0;
|
|
|
|
if (isNegative) number *= -1;
|
|
|
|
digits = splitNumberToDigits(number);
|
2022-02-24 22:15:58 +00:00
|
|
|
}
|
2022-09-27 18:44:32 +00:00
|
|
|
|
|
|
|
//print("digits: ", digits);
|
|
|
|
if (!numberOfDigits) numberOfDigits = digits.length;
|
|
|
|
let firstDigitX = element.X;
|
|
|
|
let firstDigitY = element.Y;
|
|
|
|
let imageIndex = element.ImageIndex ? element.ImageIndex : 0;
|
|
|
|
|
|
|
|
let firstImage;
|
|
|
|
if (imageIndex){
|
|
|
|
firstImage = getByPath(resources, [], "" + (0 + imageIndex));
|
2022-03-01 20:37:33 +00:00
|
|
|
} else {
|
2022-09-27 18:44:32 +00:00
|
|
|
firstImage = getByPath(resources, element.ImagePath, 0);
|
2022-02-19 01:34:37 +00:00
|
|
|
}
|
2022-03-01 20:37:33 +00:00
|
|
|
|
2022-09-27 18:44:32 +00:00
|
|
|
let minusImage;
|
|
|
|
if (imageIndexMinus){
|
|
|
|
minusImage = getByPath(resources, [], "" + (0 + imageIndexMinus));
|
|
|
|
} else {
|
|
|
|
minusImage = getByPath(resources, element.ImagePath, "minus");
|
|
|
|
}
|
2022-02-19 01:34:37 +00:00
|
|
|
|
2022-09-27 18:44:32 +00:00
|
|
|
let unitImage;
|
|
|
|
//print("Get image for unit", imageIndexUnit);
|
|
|
|
if (imageIndexUnit !== undefined){
|
|
|
|
unitImage = getByPath(resources, [], "" + (0 + imageIndexUnit));
|
|
|
|
//print("Unit image is", unitImage);
|
|
|
|
} else if (element.Unit){
|
|
|
|
unitImage = getByPath(resources, element.ImagePath, getMultistate(element.Unit, "unknown"));
|
|
|
|
}
|
|
|
|
|
|
|
|
let numberWidth = (numberOfDigits * firstImage.width) + (Math.max((numberOfDigits - 1),0) * spacing);
|
|
|
|
if (isNegative && minusImage){
|
|
|
|
//print("Adding to width", minusImage);
|
|
|
|
numberWidth += minusImage.width + spacing;
|
|
|
|
}
|
|
|
|
if (unitImage){
|
|
|
|
//print("Adding to width", unitImage);
|
|
|
|
numberWidth += unitImage.width + spacing;
|
|
|
|
}
|
|
|
|
//print("numberWidth:", numberWidth);
|
|
|
|
|
|
|
|
if (element.Alignment == "Center") {
|
|
|
|
firstDigitX = Math.round(element.X - (numberWidth/2)) + 1;
|
|
|
|
firstDigitY = Math.round(element.Y - (firstImage.height/2)) + 1;
|
|
|
|
} else if (element.Alignment == "BottomRight"){
|
|
|
|
firstDigitX = element.X - numberWidth + 1;
|
|
|
|
firstDigitY = element.Y - firstImage.height + 1;
|
|
|
|
} else if (element.Alignment == "TopRight") {
|
|
|
|
firstDigitX = element.X - numberWidth + 1;
|
|
|
|
firstDigitY = element.Y;
|
|
|
|
} else if (element.Alignment == "BottomLeft") {
|
|
|
|
firstDigitX = element.X;
|
|
|
|
firstDigitY = element.Y - firstImage.height + 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
let currentX = firstDigitX;
|
|
|
|
if (isNegative && minusImage){
|
|
|
|
//print("Draw minus at", currentX);
|
|
|
|
if (imageIndexMinus){
|
|
|
|
drawElement(graphics, resources, {X:currentX,Y:firstDigitY}, element, "" + (0 + imageIndexMinus));
|
2022-03-07 20:23:41 +00:00
|
|
|
} else {
|
2022-09-27 18:44:32 +00:00
|
|
|
drawElement(graphics, resources, {X:currentX,Y:firstDigitY}, element, "minus");
|
2022-02-20 13:59:49 +00:00
|
|
|
}
|
2022-09-27 18:44:32 +00:00
|
|
|
currentX += minusImage.width + spacing;
|
2022-02-19 18:22:44 +00:00
|
|
|
}
|
2022-09-27 18:44:32 +00:00
|
|
|
for (let d = 0; d < numberOfDigits; d++){
|
|
|
|
let currentDigit;
|
|
|
|
let difference = numberOfDigits - digits.length;
|
|
|
|
if (d >= difference){
|
|
|
|
currentDigit = digits[d-difference];
|
|
|
|
} else {
|
|
|
|
currentDigit = 0;
|
|
|
|
}
|
2022-10-05 17:17:24 +00:00
|
|
|
//print("Digit", currentDigit, currentX);
|
2022-09-27 18:44:32 +00:00
|
|
|
drawElement(graphics, resources, {X:currentX,Y:firstDigitY}, element, currentDigit + imageIndex);
|
|
|
|
currentX += firstImage.width + spacing;
|
|
|
|
}
|
|
|
|
if (imageIndexUnit){
|
|
|
|
//print("Draw unit at", currentX);
|
|
|
|
drawElement(graphics, resources, {X:currentX,Y:firstDigitY}, element, "" + (0 + imageIndexUnit));
|
|
|
|
} else if (element.Unit){
|
|
|
|
drawElement(graphics, resources, {X:currentX,Y:firstDigitY}, element, getMultistate(element.Unit,"unknown"));
|
|
|
|
}
|
|
|
|
element.lastDrawnValue = number;
|
|
|
|
|
|
|
|
endPerfLog("drawNumber");
|
2022-10-03 16:30:22 +00:00
|
|
|
};
|
2022-09-27 18:44:32 +00:00
|
|
|
|
2022-10-03 16:30:22 +00:00
|
|
|
let drawElement = function(graphics, resources, pos, element, lastElem){
|
2022-09-27 18:44:32 +00:00
|
|
|
startPerfLog("drawElement");
|
|
|
|
let cacheKey = "_"+(lastElem?lastElem:"nole");
|
|
|
|
if (!element.cachedImage) element.cachedImage={};
|
|
|
|
if (!element.cachedImage[cacheKey]){
|
|
|
|
let resource = getByPath(resources, element.ImagePath, lastElem);
|
|
|
|
if (resource){
|
|
|
|
prepareImg(resource);
|
|
|
|
//print("lastElem", typeof resource)
|
|
|
|
if (resource) {
|
|
|
|
element.cachedImage[cacheKey] = resource;
|
|
|
|
//print("cache res ",typeof element.cachedImage[cacheKey]);
|
|
|
|
} else {
|
|
|
|
element.cachedImage[cacheKey] = null;
|
|
|
|
//print("cache null",typeof element.cachedImage[cacheKey]);
|
|
|
|
//print("Could not create image from", resource);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
//print("Could not get resource from", element, lastElem);
|
|
|
|
}
|
2022-03-07 20:23:41 +00:00
|
|
|
}
|
2022-09-27 18:44:32 +00:00
|
|
|
|
2022-10-05 17:17:24 +00:00
|
|
|
//print("cache ", typeof element.cachedImage[cacheKey], element.ImagePath, lastElem);
|
2022-09-27 18:44:32 +00:00
|
|
|
if(element.cachedImage[cacheKey]){
|
2022-10-05 17:17:24 +00:00
|
|
|
//print("drawElement ", pos, element, lastElem);
|
2022-09-27 18:44:32 +00:00
|
|
|
let options={};
|
|
|
|
if (element.RotationValue){
|
|
|
|
options.rotate = radians(element);
|
|
|
|
}
|
|
|
|
if (element.Scale){
|
|
|
|
options.scale = element.ScaleValue;
|
|
|
|
}
|
|
|
|
//print("options", options);
|
|
|
|
//print("Memory before drawing", process.memory(false));
|
|
|
|
startPerfLog("drawElement_g.drawImage");
|
|
|
|
try{
|
|
|
|
graphics.drawImage(element.cachedImage[cacheKey] ,(pos.X ? pos.X : 0), (pos.Y ? pos.Y : 0), options);} catch (e) {
|
|
|
|
//print("Error", e, element.cachedImage[cacheKey]);
|
|
|
|
}
|
|
|
|
endPerfLog("drawElement_g.drawImage");
|
|
|
|
}
|
|
|
|
endPerfLog("drawElement");
|
2022-10-03 16:30:22 +00:00
|
|
|
};
|
2022-02-19 01:34:37 +00:00
|
|
|
|
2022-10-03 16:30:22 +00:00
|
|
|
let getValue = function(value, defaultValue){
|
2022-09-27 18:44:32 +00:00
|
|
|
if (typeof value == "string"){
|
|
|
|
return numbers[value]();
|
|
|
|
}
|
|
|
|
if (value == undefined) return defaultValue;
|
|
|
|
return value;
|
2022-10-03 16:30:22 +00:00
|
|
|
};
|
2022-02-24 22:15:58 +00:00
|
|
|
|
2022-10-03 16:30:22 +00:00
|
|
|
let getMultistate = function(name, defaultValue){
|
2022-09-27 18:44:32 +00:00
|
|
|
if (typeof name == "string"){
|
|
|
|
return multistates[name]();
|
|
|
|
} else {
|
|
|
|
if (name == undefined) return defaultValue;
|
|
|
|
}
|
|
|
|
return undefined;
|
2022-10-03 16:30:22 +00:00
|
|
|
};
|
2022-02-24 22:15:58 +00:00
|
|
|
|
2022-10-03 16:30:22 +00:00
|
|
|
let drawScale = function(graphics, resources, scale){
|
2022-09-27 18:44:32 +00:00
|
|
|
startPerfLog("drawScale");
|
|
|
|
//print("drawScale", scale);
|
|
|
|
let segments = scale.Segments;
|
|
|
|
let imageIndex = scale.ImageIndex !== undefined ? scale.ImageIndex : 0;
|
2022-02-19 18:22:44 +00:00
|
|
|
|
2022-09-27 18:44:32 +00:00
|
|
|
let value = scaledown(scale.Value, scale.MinValue, scale.MaxValue);
|
|
|
|
let segmentsToDraw = Math.ceil(value * segments.length);
|
2022-02-19 18:22:44 +00:00
|
|
|
|
2022-09-27 18:44:32 +00:00
|
|
|
for (let i = 0; i < segmentsToDraw; i++){
|
|
|
|
drawElement(graphics, resources, segments[i], scale, imageIndex + i);
|
|
|
|
}
|
|
|
|
scale.lastDrawnValue = segmentsToDraw;
|
|
|
|
|
|
|
|
endPerfLog("drawScale");
|
2022-10-03 16:30:22 +00:00
|
|
|
};
|
2022-03-01 20:37:33 +00:00
|
|
|
|
2022-10-03 16:30:22 +00:00
|
|
|
let drawImage = function(graphics, resources, image, name){
|
2022-09-27 18:44:32 +00:00
|
|
|
startPerfLog("drawImage");
|
|
|
|
//print("drawImage", image.X, image.Y, name);
|
|
|
|
if (image.Value && image.Steps){
|
|
|
|
let steps = Math.floor(scaledown(image.Value, image.MinValue, image.MaxValue) * (image.Steps - 1));
|
|
|
|
//print("Step", steps, "of", image.Steps);
|
|
|
|
drawElement(graphics, resources, image, image, "" + steps);
|
|
|
|
} else if (image.ImageIndex !== undefined) {
|
|
|
|
drawElement(graphics, resources, image, image, image.ImageIndex);
|
|
|
|
} else {
|
|
|
|
drawElement(graphics, resources, image, image, name ? "" + name: undefined);
|
|
|
|
}
|
2022-02-19 01:34:37 +00:00
|
|
|
|
2022-09-27 18:44:32 +00:00
|
|
|
endPerfLog("drawImage");
|
2022-10-03 16:30:22 +00:00
|
|
|
};
|
2022-02-19 01:34:37 +00:00
|
|
|
|
2022-10-03 16:30:22 +00:00
|
|
|
let drawCodedImage = function(graphics, resources, image){
|
2022-09-27 18:44:32 +00:00
|
|
|
startPerfLog("drawCodedImage");
|
|
|
|
let code = getValue(image.Value);
|
|
|
|
//print("drawCodedImage", image, code);
|
|
|
|
|
|
|
|
if (image.ImagePath) {
|
|
|
|
let factor = 1;
|
|
|
|
let currentCode = code;
|
|
|
|
while (code / factor > 1){
|
|
|
|
currentCode = Math.floor(currentCode/factor)*factor;
|
|
|
|
//print("currentCode", currentCode);
|
|
|
|
if (getByPath(resources, image.ImagePath, currentCode)){
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
factor *= 10;
|
|
|
|
}
|
|
|
|
if (code / factor > 1){
|
|
|
|
//print("found match");
|
|
|
|
drawImage(graphics, resources, image, currentCode);
|
|
|
|
} else {
|
|
|
|
//print("fallback");
|
|
|
|
drawImage(graphics, resources, image, "fallback");
|
2022-02-19 18:22:44 +00:00
|
|
|
}
|
2022-02-19 01:34:37 +00:00
|
|
|
}
|
2022-09-27 18:44:32 +00:00
|
|
|
image.lastDrawnValue = code;
|
|
|
|
|
|
|
|
startPerfLog("drawCodedImage");
|
2022-10-03 16:30:22 +00:00
|
|
|
};
|
2022-03-01 20:37:33 +00:00
|
|
|
|
2022-10-03 16:30:22 +00:00
|
|
|
let getWeatherCode = function(){
|
2022-09-27 18:44:32 +00:00
|
|
|
let jsonWeather = require("Storage").readJSON('weather.json');
|
|
|
|
let weather = (jsonWeather && jsonWeather.weather) ? jsonWeather.weather : undefined;
|
2022-02-19 01:34:37 +00:00
|
|
|
|
2022-09-27 18:44:32 +00:00
|
|
|
if (weather && weather.code){
|
|
|
|
return weather.code;
|
|
|
|
}
|
|
|
|
return undefined;
|
2022-10-03 16:30:22 +00:00
|
|
|
};
|
2022-02-19 18:22:44 +00:00
|
|
|
|
2022-10-03 16:30:22 +00:00
|
|
|
let getWeatherTemperature = function(){
|
2022-09-27 18:44:32 +00:00
|
|
|
let jsonWeather = require("Storage").readJSON('weather.json');
|
|
|
|
let weather = (jsonWeather && jsonWeather.weather) ? jsonWeather.weather : undefined;
|
|
|
|
|
|
|
|
let result = { unit: "unknown"};
|
|
|
|
if (weather && weather.temp){
|
|
|
|
//print("Weather is", weather);
|
|
|
|
let temp = require('locale').temp(weather.temp-273.15);
|
|
|
|
result.value = Number(temp.match(/[\d\-]*/)[0]);
|
|
|
|
let unit;
|
|
|
|
if (temp.includes("C")){
|
|
|
|
result.unit = "celsius";
|
|
|
|
} else if (temp.includes("F")){
|
|
|
|
result.unit = "fahrenheit";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
2022-10-03 16:30:22 +00:00
|
|
|
};
|
2022-02-19 18:22:44 +00:00
|
|
|
|
2022-10-03 16:30:22 +00:00
|
|
|
let scaledown = function(value, min, max){
|
2022-09-27 18:44:32 +00:00
|
|
|
//print("scaledown", value, min, max);
|
|
|
|
let scaled = E.clip(getValue(value),getValue(min,0),getValue(max,1));
|
|
|
|
scaled -= getValue(min,0);
|
|
|
|
scaled /= getValue(max,1);
|
|
|
|
return scaled;
|
2022-10-03 16:30:22 +00:00
|
|
|
};
|
2022-02-19 01:34:37 +00:00
|
|
|
|
2022-10-03 16:30:22 +00:00
|
|
|
let radians = function(rotation){
|
2022-09-27 18:44:32 +00:00
|
|
|
let value = scaledown(rotation.RotationValue, rotation.MinRotationValue, rotation.MaxRotationValue);
|
|
|
|
value -= rotation.RotationOffset ? rotation.RotationOffset : 0;
|
|
|
|
value *= 360;
|
|
|
|
value *= Math.PI / 180;
|
|
|
|
return value;
|
2022-10-03 16:30:22 +00:00
|
|
|
};
|
2022-02-19 01:34:37 +00:00
|
|
|
|
2022-10-03 16:30:22 +00:00
|
|
|
let drawPoly = function(graphics, resources, element){
|
2022-09-27 18:44:32 +00:00
|
|
|
startPerfLog("drawPoly");
|
|
|
|
let vertices = [];
|
2022-02-23 20:53:44 +00:00
|
|
|
|
2022-09-27 18:44:32 +00:00
|
|
|
startPerfLog("drawPoly_transform");
|
|
|
|
for (let c of element.Vertices){
|
|
|
|
vertices.push(c.X);
|
|
|
|
vertices.push(c.Y);
|
|
|
|
}
|
|
|
|
let transform = { x: element.X ? element.X : 0,
|
|
|
|
y: element.Y ? element.Y : 0
|
|
|
|
};
|
|
|
|
if (element.RotationValue){
|
|
|
|
transform.rotate = radians(element);
|
|
|
|
}
|
|
|
|
vertices = graphics.transformVertices(vertices, transform);
|
2022-02-23 22:09:53 +00:00
|
|
|
|
2022-09-27 18:44:32 +00:00
|
|
|
endPerfLog("drawPoly_transform");
|
2022-02-23 22:09:53 +00:00
|
|
|
|
2022-09-27 18:44:32 +00:00
|
|
|
if (element.Filled){
|
|
|
|
startPerfLog("drawPoly_g.fillPoly");
|
|
|
|
graphics.fillPoly(vertices,true);
|
|
|
|
endPerfLog("drawPoly_g.fillPoly");
|
|
|
|
} else {
|
|
|
|
startPerfLog("drawPoly_g.drawPoly");
|
|
|
|
graphics.drawPoly(vertices,true);
|
|
|
|
endPerfLog("drawPoly_g.drawPoly");
|
|
|
|
}
|
2022-02-28 19:20:37 +00:00
|
|
|
|
2022-09-27 18:44:32 +00:00
|
|
|
endPerfLog("drawPoly");
|
2022-10-03 16:30:22 +00:00
|
|
|
};
|
2022-02-23 22:09:53 +00:00
|
|
|
|
2022-10-03 16:30:22 +00:00
|
|
|
let drawRect = function(graphics, resources, element){
|
2022-09-27 18:44:32 +00:00
|
|
|
startPerfLog("drawRect");
|
|
|
|
let vertices = [];
|
2022-02-23 22:09:53 +00:00
|
|
|
|
2022-09-27 18:44:32 +00:00
|
|
|
if (element.Filled){
|
|
|
|
startPerfLog("drawRect_g.fillRect");
|
|
|
|
graphics.fillRect(element.X, element.Y, element.X + element.Width, element.Y + element.Height);
|
|
|
|
endPerfLog("drawRect_g.fillRect");
|
|
|
|
} else {
|
|
|
|
startPerfLog("drawRect_g.fillRect");
|
|
|
|
graphics.drawRect(element.X, element.Y, element.X + element.Width, element.Y + element.Height);
|
|
|
|
endPerfLog("drawRect_g.fillRect");
|
|
|
|
}
|
|
|
|
endPerfLog("drawRect");
|
2022-10-03 16:30:22 +00:00
|
|
|
};
|
2022-02-23 22:09:53 +00:00
|
|
|
|
2022-10-03 16:30:22 +00:00
|
|
|
let drawCircle = function(graphics, resources, element){
|
2022-09-27 18:44:32 +00:00
|
|
|
startPerfLog("drawCircle");
|
2022-03-06 12:18:46 +00:00
|
|
|
|
2022-09-27 18:44:32 +00:00
|
|
|
if (element.Filled){
|
|
|
|
startPerfLog("drawCircle_g.fillCircle");
|
|
|
|
graphics.fillCircle(element.X, element.Y, element.Radius);
|
|
|
|
endPerfLog("drawCircle_g.fillCircle");
|
|
|
|
} else {
|
|
|
|
startPerfLog("drawCircle_g.drawCircle");
|
|
|
|
graphics.drawCircle(element.X, element.Y, element.Radius);
|
|
|
|
endPerfLog("drawCircle_g.drawCircle");
|
|
|
|
}
|
|
|
|
endPerfLog("drawCircle");
|
2022-10-03 16:30:22 +00:00
|
|
|
};
|
2022-03-06 12:18:46 +00:00
|
|
|
|
2022-09-27 18:44:32 +00:00
|
|
|
let numbers = {};
|
|
|
|
numbers.Hour = () => { return new Date().getHours(); };
|
|
|
|
numbers.HourTens = () => { return Math.floor(new Date().getHours()/10); };
|
|
|
|
numbers.HourOnes = () => { return Math.floor(new Date().getHours()%10); };
|
|
|
|
numbers.Hour12 = () => { return new Date().getHours()%12; };
|
|
|
|
numbers.Hour12Analog = () => { let date = new Date(); return date.getHours()%12 + (date.getMinutes()/59); };
|
|
|
|
numbers.Hour12Tens = () => { 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.MinuteAnalog = () => { let date = new Date(); return date.getMinutes() + (date.getSeconds()/59); };
|
|
|
|
numbers.MinuteTens = () => { return Math.floor(new Date().getMinutes()/10); };
|
|
|
|
numbers.MinuteOnes = () => { return Math.floor(new Date().getMinutes()%10); };
|
|
|
|
numbers.Second = () => { return new Date().getSeconds(); };
|
|
|
|
numbers.SecondAnalog = () => { let date = new Date(); return date.getSeconds() + (date.getMilliseconds()/999); };
|
|
|
|
numbers.SecondTens = () => { return Math.floor(new Date().getSeconds()/10); };
|
|
|
|
numbers.SecondOnes = () => { return Math.floor(new Date().getSeconds()%10); };
|
|
|
|
numbers.WeekDay = () => { return new Date().getDay(); };
|
|
|
|
numbers.WeekDayMondayFirst = () => { let day = (new Date().getDay() - 1); if (day < 0) day = 7 + day; return day; };
|
|
|
|
numbers.Day = () => { return new Date().getDate(); };
|
|
|
|
numbers.DayTens = () => { return Math.floor(new Date().getDate()/10); };
|
|
|
|
numbers.DayOnes = () => { return Math.floor(new Date().getDate()%10); };
|
|
|
|
numbers.Month = () => { return new Date().getMonth() + 1; };
|
|
|
|
numbers.MonthTens = () => { return Math.floor((new Date().getMonth() + 1)/10); };
|
|
|
|
numbers.MonthOnes = () => { return Math.floor((new Date().getMonth() + 1)%10); };
|
|
|
|
numbers.Pulse = () => { return pulse; };
|
|
|
|
numbers.Steps = () => { return Bangle.getHealthStatus ? Bangle.getHealthStatus("day").steps : undefined; };
|
|
|
|
numbers.StepsGoal = () => { return settings.stepsgoal || 10000; };
|
|
|
|
numbers.Temperature = () => { return temp; };
|
|
|
|
numbers.Pressure = () => { return press; };
|
|
|
|
numbers.Altitude = () => { return alt; };
|
|
|
|
numbers.BatteryPercentage = E.getBattery;
|
|
|
|
numbers.BatteryVoltage = NRF.getBattery;
|
|
|
|
numbers.WeatherCode = getWeatherCode;
|
|
|
|
numbers.WeatherTemperature = () => { return getWeatherTemperature().value; };
|
|
|
|
|
|
|
|
let multistates = {};
|
|
|
|
multistates.Lock = () => { return Bangle.isLocked() ? "on" : "off"; };
|
|
|
|
multistates.Charge = () => { return Bangle.isCharging() ? "on" : "off"; };
|
|
|
|
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.Bluetooth = () => { return NRF.getSecurityStatus().connected ? "on" : "off"; };
|
|
|
|
//TODO: Implement peripheral connection status
|
|
|
|
multistates.BluetoothPeripheral = () => { return NRF.getSecurityStatus().connected ? "on" : "off"; };
|
|
|
|
multistates.HRM = () => { return Bangle.isHRMOn ? "on" : "off"; };
|
|
|
|
multistates.Barometer = () => { return Bangle.isBarometerOn() ? "on" : "off"; };
|
|
|
|
multistates.Compass = () => { return Bangle.isCompassOn() ? "on" : "off"; };
|
|
|
|
multistates.GPS = () => { return Bangle.isGPSOn() ? "on" : "off"; };
|
|
|
|
multistates.WeatherTemperatureNegative = () => { return getWeatherTemperature().value ? getWeatherTemperature().value : 0 < 0; };
|
|
|
|
multistates.WeatherTemperatureUnit = () => { return getWeatherTemperature().unit; };
|
|
|
|
multistates.StepsGoal = () => { return (numbers.Steps() >= (settings.stepsgoal || 10000)) ? "on": "off"; };
|
|
|
|
|
2022-10-03 16:30:22 +00:00
|
|
|
let drawMultiState = function(graphics, resources, element){
|
2022-09-27 18:44:32 +00:00
|
|
|
startPerfLog("drawMultiState");
|
|
|
|
//print("drawMultiState", element);
|
|
|
|
let value = multistates[element.Value]();
|
|
|
|
//print("drawImage from drawMultiState", element, value);
|
|
|
|
drawImage(graphics, resources, element, value);
|
|
|
|
element.lastDrawnValue = value;
|
|
|
|
endPerfLog("drawMultiState");
|
2022-10-03 16:30:22 +00:00
|
|
|
};
|
2022-03-14 21:29:26 +00:00
|
|
|
|
2022-09-27 18:44:32 +00:00
|
|
|
let pulse,alt,temp,press;
|
2022-03-14 21:29:26 +00:00
|
|
|
|
2022-02-19 01:34:37 +00:00
|
|
|
|
2022-09-27 18:44:32 +00:00
|
|
|
let requestedDraws = 0;
|
|
|
|
let isDrawing = false;
|
|
|
|
|
|
|
|
let start;
|
2022-10-03 16:30:22 +00:00
|
|
|
|
2022-09-27 18:44:32 +00:00
|
|
|
let deferredTimout;
|
|
|
|
|
2022-10-03 16:30:22 +00:00
|
|
|
let initialDraw = function(resources, face){
|
2022-09-27 18:44:32 +00:00
|
|
|
//print("Free memory", process.memory(false).free);
|
|
|
|
requestedDraws++;
|
|
|
|
if (!isDrawing){
|
|
|
|
cleanupDelays();
|
|
|
|
//print(new Date().toISOString(), "Can draw,", requestedDraws, "draws requested so far");
|
|
|
|
isDrawing = true;
|
|
|
|
resetPerfLog();
|
2022-02-20 20:00:09 +00:00
|
|
|
requestedDraws = 0;
|
2022-09-27 18:44:32 +00:00
|
|
|
//print(new Date().toISOString(), "Drawing start");
|
|
|
|
startPerfLog("initialDraw");
|
|
|
|
//print("Precompiled");
|
|
|
|
let promise = precompiledJs(watchfaceResources, watchface);
|
|
|
|
|
|
|
|
promise.then(()=>{
|
|
|
|
let currentDrawingTime = Date.now();
|
|
|
|
if (showWidgets && global.WIDGETS){
|
|
|
|
//print("Draw widgets");
|
2022-09-27 20:16:42 +00:00
|
|
|
restoreWidgetDraw();
|
2022-09-27 18:44:32 +00:00
|
|
|
Bangle.drawWidgets();
|
|
|
|
g.setColor(g.theme.fg);
|
|
|
|
g.drawLine(0,24,g.getWidth(),24);
|
|
|
|
}
|
|
|
|
lastDrawTime = Date.now() - start;
|
|
|
|
isDrawing=false;
|
|
|
|
firstDraw=false;
|
|
|
|
requestRefresh = false;
|
|
|
|
endPerfLog("initialDraw");
|
|
|
|
}).catch((e)=>{
|
|
|
|
print("Error during drawing", e);
|
|
|
|
});
|
|
|
|
|
|
|
|
if (requestedDraws > 0){
|
|
|
|
//print(new Date().toISOString(), "Had deferred drawing left, drawing again");
|
|
|
|
requestedDraws = 0;
|
|
|
|
deferredTimout = setTimeout(()=>{initialDraw(resources, face);}, 10);
|
|
|
|
}
|
|
|
|
} //else {
|
|
|
|
//print("queued draw");
|
|
|
|
//}
|
2022-10-03 16:30:22 +00:00
|
|
|
};
|
2022-09-27 18:44:32 +00:00
|
|
|
|
2022-10-03 16:30:22 +00:00
|
|
|
let handleHrm = function(e){
|
2022-09-27 18:44:32 +00:00
|
|
|
if (e.confidence > 70){
|
|
|
|
pulse = e.bpm;
|
|
|
|
if (!redrawEvents || redrawEvents.includes("HRM") && !Bangle.isLocked()){
|
2022-09-30 08:37:49 +00:00
|
|
|
//print("Redrawing on HRM");
|
2022-09-27 18:44:32 +00:00
|
|
|
initialDraw(watchfaceResources, watchface);
|
|
|
|
}
|
2022-02-20 20:00:09 +00:00
|
|
|
}
|
2022-10-03 16:30:22 +00:00
|
|
|
};
|
2022-02-19 18:22:44 +00:00
|
|
|
|
2022-10-03 16:30:22 +00:00
|
|
|
let handlePressure = function(e){
|
2022-09-27 18:44:32 +00:00
|
|
|
alt = e.altitude;
|
|
|
|
temp = e.temperature;
|
|
|
|
press = e.pressure;
|
|
|
|
if (!redrawEvents || redrawEvents.includes("pressure") && !Bangle.isLocked()){
|
|
|
|
//print("Redrawing on pressure");
|
2022-03-02 20:39:10 +00:00
|
|
|
initialDraw(watchfaceResources, watchface);
|
2022-02-20 20:54:42 +00:00
|
|
|
}
|
2022-10-03 16:30:22 +00:00
|
|
|
};
|
2022-02-19 01:34:37 +00:00
|
|
|
|
2022-10-03 16:30:22 +00:00
|
|
|
let handleCharging = function(e){
|
2022-09-27 18:44:32 +00:00
|
|
|
if (!redrawEvents || redrawEvents.includes("charging") && !Bangle.isLocked()){
|
|
|
|
//print("Redrawing on charging");
|
|
|
|
initialDraw(watchfaceResources, watchface);
|
|
|
|
}
|
2022-10-03 16:30:22 +00:00
|
|
|
};
|
2022-02-19 01:34:37 +00:00
|
|
|
|
2022-09-27 18:44:32 +00:00
|
|
|
|
2022-10-03 16:30:22 +00:00
|
|
|
let getMatchedWaitingTime = function(time){
|
2022-09-27 18:44:32 +00:00
|
|
|
let result = time - (Date.now() % time);
|
2022-10-05 17:17:24 +00:00
|
|
|
//print("Matched wating time", time, result);
|
2022-09-27 18:44:32 +00:00
|
|
|
return result;
|
2022-10-03 16:30:22 +00:00
|
|
|
};
|
2022-02-22 17:47:55 +00:00
|
|
|
|
2022-10-03 16:30:22 +00:00
|
|
|
let setMatchedInterval = function(callable, time, intervalHandler, delay){
|
2022-09-27 18:44:32 +00:00
|
|
|
//print("Setting matched interval for", time, intervalHandler);
|
|
|
|
let matchedTime = getMatchedWaitingTime(time + delay);
|
|
|
|
return setTimeout(()=>{
|
|
|
|
let interval = setInterval(callable, time);
|
2022-10-05 17:17:24 +00:00
|
|
|
//print("setMatchedInterval", interval);
|
2022-09-27 18:44:32 +00:00
|
|
|
if (intervalHandler) intervalHandler(interval);
|
|
|
|
callable();
|
|
|
|
}, matchedTime);
|
2022-10-03 16:30:22 +00:00
|
|
|
};
|
2022-02-21 17:02:41 +00:00
|
|
|
|
|
|
|
|
2022-09-27 18:44:32 +00:00
|
|
|
let lastDrawTime = 0;
|
2022-02-21 17:02:41 +00:00
|
|
|
|
2022-09-27 18:44:32 +00:00
|
|
|
let lockedRedraw = getByPath(watchface, ["Properties","Redraw","Locked"]) || 60000;
|
|
|
|
let unlockedRedraw = getByPath(watchface, ["Properties","Redraw","Unlocked"]) || 1000;
|
|
|
|
let defaultRedraw = getByPath(watchface, ["Properties","Redraw","Default"]) || "Always";
|
|
|
|
let redrawEvents = getByPath(watchface, ["Properties","Redraw","Events"]);
|
|
|
|
let clearOnRedraw = getByPath(watchface, ["Properties","Redraw","Clear"]);
|
|
|
|
let events = getByPath(watchface, ["Properties","Events"]);
|
2022-02-21 17:02:41 +00:00
|
|
|
|
2022-09-27 18:44:32 +00:00
|
|
|
//print("events", events);
|
|
|
|
//print("redrawEvents", redrawEvents);
|
2022-02-21 17:02:41 +00:00
|
|
|
|
2022-09-27 18:44:32 +00:00
|
|
|
let initialDrawTimeoutUnlocked;
|
|
|
|
let initialDrawTimeoutLocked;
|
2022-10-03 16:30:22 +00:00
|
|
|
|
|
|
|
let handleLock = function(isLocked, forceRedraw){
|
2022-09-27 18:44:32 +00:00
|
|
|
//print("isLocked", Bangle.isLocked());
|
|
|
|
for (let i of unlockedDrawInterval){
|
|
|
|
//print("Clearing unlocked", i);
|
|
|
|
clearInterval(i);
|
2022-03-03 17:42:48 +00:00
|
|
|
}
|
2022-09-27 18:44:32 +00:00
|
|
|
for (let i of lockedDrawInterval){
|
|
|
|
//print("Clearing locked", i);
|
|
|
|
clearInterval(i);
|
|
|
|
}
|
|
|
|
unlockedDrawInterval = [];
|
|
|
|
lockedDrawInterval = [];
|
|
|
|
|
|
|
|
if (!isLocked){
|
|
|
|
if (forceRedraw || !redrawEvents || (redrawEvents.includes("unlock"))){
|
|
|
|
//print("Redrawing on unlock", isLocked);
|
|
|
|
initialDraw(watchfaceResources, watchface);
|
|
|
|
}
|
2022-10-05 17:17:24 +00:00
|
|
|
if (initialDrawTimeoutUnlocked){
|
|
|
|
//print("clear initialDrawTimeUnlocked timet", initialDrawTimeoutUnlocked);
|
|
|
|
clearTimeout(initialDrawTimeoutUnlocked);
|
|
|
|
}
|
2022-09-27 18:44:32 +00:00
|
|
|
initialDrawTimeoutUnlocked = setMatchedInterval(()=>{
|
|
|
|
//print("Redrawing on unlocked interval");
|
|
|
|
initialDraw(watchfaceResources, watchface);
|
|
|
|
},unlockedRedraw, (v)=>{
|
|
|
|
//print("New matched unlocked interval", v);
|
|
|
|
unlockedDrawInterval.push(v);
|
|
|
|
}, lastDrawTime);
|
|
|
|
if (!events || events.includes("HRM")) Bangle.setHRMPower(1, "imageclock");
|
|
|
|
if (!events || events.includes("pressure")) Bangle.setBarometerPower(1, 'imageclock');
|
|
|
|
} else {
|
|
|
|
if (forceRedraw || !redrawEvents || (redrawEvents.includes("lock"))){
|
|
|
|
//print("Redrawing on lock", isLocked);
|
|
|
|
initialDraw(watchfaceResources, watchface);
|
|
|
|
}
|
2022-10-05 17:17:24 +00:00
|
|
|
if (initialDrawTimeoutLocked){
|
|
|
|
clearTimeout(initialDrawTimeoutLocked);
|
|
|
|
//print("clear initialDrawTimeLocked timet", initialDrawTimeoutLocked);
|
|
|
|
}
|
2022-09-27 18:44:32 +00:00
|
|
|
initialDrawTimeoutLocked = setMatchedInterval(()=>{
|
|
|
|
//print("Redrawing on locked interval");
|
|
|
|
initialDraw(watchfaceResources, watchface);
|
|
|
|
},lockedRedraw, (v)=>{
|
|
|
|
//print("New matched locked interval", v);
|
|
|
|
lockedDrawInterval.push(v);
|
|
|
|
}, lastDrawTime);
|
|
|
|
Bangle.setHRMPower(0, "imageclock");
|
|
|
|
Bangle.setBarometerPower(0, 'imageclock');
|
2022-03-03 17:42:48 +00:00
|
|
|
}
|
2022-10-03 16:30:22 +00:00
|
|
|
};
|
2022-02-19 01:34:37 +00:00
|
|
|
|
2022-03-13 13:02:18 +00:00
|
|
|
|
2022-09-27 18:44:32 +00:00
|
|
|
let showWidgetsChanged = false;
|
|
|
|
let currentDragDistance = 0;
|
2022-03-13 13:02:18 +00:00
|
|
|
|
2022-10-03 16:30:22 +00:00
|
|
|
let restoreWidgetDraw = function(){
|
2022-09-27 18:44:32 +00:00
|
|
|
if (global.WIDGETS) {
|
|
|
|
for (let w in global.WIDGETS) {
|
|
|
|
let wd = global.WIDGETS[w];
|
|
|
|
wd.draw = originalWidgetDraw[w];
|
|
|
|
wd.area = originalWidgetArea[w];
|
|
|
|
}
|
|
|
|
}
|
2022-10-03 16:30:22 +00:00
|
|
|
};
|
2022-09-27 18:44:32 +00:00
|
|
|
|
2022-10-03 16:30:22 +00:00
|
|
|
let handleDrag = function(e){
|
2022-09-27 18:44:32 +00:00
|
|
|
//print("handleDrag");
|
2022-03-13 13:02:18 +00:00
|
|
|
currentDragDistance += e.dy;
|
|
|
|
if (Math.abs(currentDragDistance) < 10) return;
|
|
|
|
dragDown = currentDragDistance > 0;
|
|
|
|
currentDragDistance = 0;
|
|
|
|
if (!showWidgets && dragDown){
|
|
|
|
//print("Enable widgets");
|
2022-09-27 18:44:32 +00:00
|
|
|
restoreWidgetDraw();
|
2022-03-13 13:02:18 +00:00
|
|
|
showWidgetsChanged = true;
|
|
|
|
}
|
|
|
|
if (showWidgets && !dragDown){
|
|
|
|
//print("Disable widgets");
|
|
|
|
clearWidgetsDraw();
|
|
|
|
firstDraw = true;
|
|
|
|
showWidgetsChanged = true;
|
|
|
|
}
|
|
|
|
if (showWidgetsChanged){
|
|
|
|
showWidgetsChanged = false;
|
|
|
|
//print("Draw after widget change");
|
|
|
|
showWidgets = dragDown;
|
|
|
|
initialDraw();
|
|
|
|
}
|
2022-10-03 16:30:22 +00:00
|
|
|
};
|
2022-02-19 01:34:37 +00:00
|
|
|
|
2022-09-27 18:44:32 +00:00
|
|
|
Bangle.on('drag', handleDrag);
|
2022-03-13 13:02:18 +00:00
|
|
|
|
2022-09-27 18:44:32 +00:00
|
|
|
if (!events || events.includes("pressure")){
|
|
|
|
Bangle.on('pressure', handlePressure);
|
|
|
|
try{
|
|
|
|
Bangle.setBarometerPower(1, 'imageclock');
|
|
|
|
} catch (e){
|
2022-10-05 17:17:24 +00:00
|
|
|
//print("Error during barometer power up", e);
|
2022-02-22 21:40:34 +00:00
|
|
|
}
|
|
|
|
}
|
2022-09-27 18:44:32 +00:00
|
|
|
if (!events || events.includes("HRM")) {
|
|
|
|
Bangle.on('HRM', handleHrm);
|
|
|
|
Bangle.setHRMPower(1, "imageclock");
|
|
|
|
}
|
|
|
|
if (!events || events.includes("lock")) {
|
|
|
|
Bangle.on('lock', handleLock);
|
|
|
|
}
|
|
|
|
if (!events || events.includes("charging")) {
|
|
|
|
Bangle.on('charging', handleCharging);
|
|
|
|
}
|
2022-02-22 21:40:34 +00:00
|
|
|
|
2022-09-27 18:44:32 +00:00
|
|
|
let originalWidgetDraw = {};
|
|
|
|
let originalWidgetArea = {};
|
|
|
|
|
2022-10-03 16:30:22 +00:00
|
|
|
let clearWidgetsDraw = function(){
|
2022-09-27 18:44:32 +00:00
|
|
|
//print("Clear widget draw calls");
|
|
|
|
if (global.WIDGETS) {
|
|
|
|
originalWidgetDraw = {};
|
|
|
|
originalWidgetArea = {};
|
|
|
|
for (let w in global.WIDGETS) {
|
|
|
|
let wd = global.WIDGETS[w];
|
|
|
|
originalWidgetDraw[w] = wd.draw;
|
|
|
|
originalWidgetArea[w] = wd.area;
|
|
|
|
wd.draw = () => {};
|
|
|
|
wd.area = "";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-30 16:05:53 +00:00
|
|
|
handleLock(Bangle.isLocked(), true);
|
2022-09-27 18:44:32 +00:00
|
|
|
|
|
|
|
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;
|
2022-09-29 21:34:53 +00:00
|
|
|
delete showWidgets;
|
2022-09-30 16:05:53 +00:00
|
|
|
delete firstDraw;
|
2022-02-22 21:40:34 +00:00
|
|
|
|
2022-10-04 20:16:01 +00:00
|
|
|
delete Bangle.printPerfLog;
|
|
|
|
if (settings.perflog){
|
|
|
|
delete Bangle.resetPerfLog;
|
|
|
|
delete performanceLog;
|
|
|
|
}
|
|
|
|
|
2022-09-27 18:44:32 +00:00
|
|
|
cleanupDelays();
|
|
|
|
restoreWidgetDraw();
|
|
|
|
}
|
|
|
|
});
|
2022-10-04 20:16:01 +00:00
|
|
|
|
2022-10-03 14:56:41 +00:00
|
|
|
Bangle.loadWidgets();
|
|
|
|
clearWidgetsDraw();
|
2022-09-27 18:44:32 +00:00
|
|
|
}
|