From 0cca59144d150548472c4d3e723e51a07d748d52 Mon Sep 17 00:00:00 2001
From: Martin Boonk
Date: Mon, 28 Feb 2022 20:21:31 +0100
Subject: [PATCH] Allow collapsing the watchface tree down to an array
---
apps/imageclock/app.js | 144 ++++++++++++++++++++++--------------
apps/imageclock/custom.html | 65 +++++++++++++---
2 files changed, 146 insertions(+), 63 deletions(-)
diff --git a/apps/imageclock/app.js b/apps/imageclock/app.js
index 38f7752c3..c4d31c09c 100644
--- a/apps/imageclock/app.js
+++ b/apps/imageclock/app.js
@@ -547,66 +547,99 @@ function drawMultiState(element, offset){
endPerfLog("drawMultiState");
}
-function draw(element, offset){
- startPerfLog("draw_"+ path.join("_"));
- var initial = !element;
- if (initial){
- element = face;
- if (!offset) offset ={};
- if (!offset.X) offset.X = 0;
- if (!offset.Y) offset.Y = 0;
- g.clear();
+function drawIteratively(items){
+ //print("drawIteratively");
+ startPerfLog("drawIteratively");
+ for (var c of items){
+ startPerfLog("drawIteratively_handling_" + c.type);
+ if (c.value.HideOn && c.value.HideOn == "Lock" && Bangle.isLocked()){
+ //print("Hiding", current);
+ continue;
+ }
+ switch(c.type){
+ case "MultiState":
+ drawMultiState(c.value, zeroOffset);
+ break;
+ case "Image":
+ drawImage(c.value, zeroOffset);
+ break;
+ case "CodedImage":
+ drawCodedImage(c.value, zeroOffset);
+ break;
+ case "Number":
+ drawNumber(c.value, zeroOffset);
+ break;
+ case "Poly":
+ drawPoly(c.value, zeroOffset);
+ break;
+ case "Scale":
+ drawScale(c.value, zeroOffset);
+ break;
+ }
+ endPerfLog("drawIteratively_handling_" + c.type);
}
+ endPerfLog("drawIteratively");
+}
+function draw(root, path, offset){
+ //print("draw", path);
+ startPerfLog("draw_"+ path.join("_"));
+
+ var element = getByPath(root, path);
var elementOffset = updateOffset(element, offset);
setColors(elementOffset);
//print("Using offset", elementOffset);
+ if (Array.isArray(element))
+ drawIteratively(element);
+ else {
+ //print("Using offset", elementOffset);
- for (var current in element){
- //print("Handling ", current, " with offset ", elementOffset);
- startPerfLog("draw_handling_"+ path.join("_")+"_"+current);
- var currentElement = element[current];
- try {
- switch(current){
- case "X":
- case "Y":
- case "Properties":
- case "ForegroundColor":
- case "BackgroundColor":
- case "HideOn":
- //Nothing to draw for these
- break;
- case "MultiState":
- drawMultiState(currentElement, elementOffset);
- break;
- case "Image":
- drawImage(currentElement, elementOffset);
- break;
- case "CodedImage":
- drawCodedImage(currentElement, elementOffset);
- break;
- case "Number":
- drawNumber(currentElement, elementOffset);
- break;
- case "Poly":
- drawPoly(currentElement, elementOffset);
- break;
- case "Scale":
- drawScale(currentElement, elementOffset);
- break;
- default:
- //print("Enter next level", elementOffset);
- if (currentElement.HideOn && currentElement.HideOn == "Lock" && Bangle.isLocked()){
+ for (var current in element){
+ //print("Handling ", current, " with offset ", elementOffset);
+ startPerfLog("draw_handling_"+ path.join("_")+"_"+current);
+ var currentElement = element[current];
+ try {
+ switch(current){
+ case "X":
+ case "Y":
+ case "Properties":
+ case "ForegroundColor":
+ case "BackgroundColor":
+ case "HideOn":
//print("Hiding", current);
- continue;
- }
- draw(currentElement, elementOffset);
- //print("Done next level");
+ break;
+ case "MultiState":
+ drawMultiState(currentElement, elementOffset);
+ break;
+ case "Image":
+ drawImage(currentElement, elementOffset);
+ break;
+ case "CodedImage":
+ drawCodedImage(currentElement, elementOffset);
+ break;
+ case "Number":
+ drawNumber(currentElement, elementOffset);
+ break;
+ case "Poly":
+ drawPoly(currentElement, elementOffset);
+ break;
+ case "Scale":
+ drawScale(currentElement, elementOffset);
+ break;
+ default:
+ //print("Enter next level", elementOffset);
+ if (currentElement.HideOn && currentElement.HideOn == "Lock" && Bangle.isLocked()){
+ //print("Hiding", current);
+ continue;
+ }
+ draw(root, path.concat(current), elementOffset);
+ //print("Done next level");
+ }
+ endPerfLog("draw_handling_"+ path.join("_")+"_"+current);
+ //print("Drawing of", current, "in", (Date.now() - start).toFixed(0), "ms");
+ } catch (e){
+ print("Error during drawing of", current, "in", element, e, e.stack);
}
- endPerfLog("draw_handling_"+ path.join("_")+"_"+current);
- //print("Drawing of", current, "in", (Date.now() - start).toFixed(0), "ms");
- } catch (e){
- print("Error during drawing of", current, "in", element, e, e.stack);
}
}
//print("Finished drawing loop");
@@ -629,17 +662,20 @@ function initialDraw(){
if (!isDrawing){
//print(new Date().toISOString(), "Can draw,", requestedDraws, "draws requested so far");
isDrawing = true;
+ startPerfLog("initialDraw_g.clear");
+ g.clear();
+ endPerfLog("initialDraw_g.clear");
requestedDraws = 0;
//print(new Date().toISOString(), "Drawing start");
startPerfLog("initialDraw");
- draw(undefined, zeroOffset);
+ draw(face, [], zeroOffset);
endPerfLog("initialDraw");
//print(new Date().toISOString(), "Drawing done", (Date.now() - start).toFixed(0));
isDrawing = false;
if (requestedDraws > 0){
//print(new Date().toISOString(), "Had deferred drawing left, drawing again");
requestedDraws = 0;
- draw(undefined, zeroOffset);
+ setTimeout(initialDraw, 10);
}
}
}
diff --git a/apps/imageclock/custom.html b/apps/imageclock/custom.html
index 477eb3371..29686b8a3 100644
--- a/apps/imageclock/custom.html
+++ b/apps/imageclock/custom.html
@@ -23,6 +23,8 @@
Options:
+
+
Select watchface folder:
@@ -510,6 +512,56 @@
return restructureAmazfitFormat(jsonString);
}
}
+
+ function combineProperty(name, source, target){
+ if (source[name] && target[name]){
+ if (Array.isArray(target[name])){
+ target[name] = target[name].concat(source[name]);
+ target[name].filter((item, i) => target[name].indexOf(item) === i)
+ } else if (typeof target[name] == "number"){
+ target[name] = source[name] + target[name];
+ }
+ } else if (source[name]){
+ target[name] = source[name]
+ }
+ }
+
+ function collapseTree(element, props){
+ var result = [];
+ if (typeof element == "string" || typeof element == "number") return [];
+ for (var c in element){
+ var next = element[c];
+
+ combineProperty("X",element,next);
+ combineProperty("Y",element,next);
+ combineProperty("HideOn",element,next);
+ combineProperty("ForegroundColor",element,next);
+ combineProperty("BackgroundColor",element,next);
+ combineProperty("RotationValue",element,next);
+ combineProperty("RotationOffset",element,next);
+ combineProperty("MinRotationValue",element,next);
+ combineProperty("MaxRotationValue",element,next);
+
+ if (["MultiState","Image","CodedImage","Number","Poly","Scale"].includes(c)){
+ result.push({type:c, value: element[c]});
+ } else {
+ result = result.concat(collapseTree(element[c]));
+ }
+ }
+ return result;
+ }
+
+ function postProcess(){
+ if (document.getElementById('useDataFile').checked){
+ moveData(resultJson);
+ console.log("Created data file", resourceDataString, resourceDataOffset, resultJson);
+ }
+
+ if (document.getElementById('collapseTree').checked){
+ faceJson = { Collapsed: collapseTree(faceJson,{X:0,Y:0})};
+ console.log("After collapsing", faceJson);
+ }
+ }
function imageLoaded() {
var options = {};
@@ -592,24 +644,19 @@
if (handledFiles == expectedFiles){
if (!isNativeFormat()) {
performFileChanges().then(()=>{
+ postProcess();
+
rootZip.file("face.json", JSON.stringify(faceJson, null, 2));
rootZip.file("info.json", JSON.stringify(infoJson, null, 2));
- if (document.getElementById('useDataFile').checked){
- moveData(resultJson);
- console.log("Created data file", resourceDataString, resourceDataOffset, resultJson);
- }
document.getElementById('btnSave').disabled = false;
document.getElementById('btnSaveFace').disabled = false;
document.getElementById('btnSaveZip').disabled = false;
document.getElementById('btnUpload').disabled = false;
});
} else {
-
- if (true){
- moveData(resultJson);
- console.log("Created data file", resourceDataString, resourceDataOffset, resultJson);
- }
+ postProcess();
+
document.getElementById('btnSave').disabled = false;
document.getElementById('btnSaveFace').disabled = false;
document.getElementById('btnUpload').disabled = false;