Allow collapsing the watchface tree down to an array

pull/1916/head
Martin Boonk 2022-02-28 20:21:31 +01:00
parent dfd127f498
commit 0cca59144d
2 changed files with 146 additions and 63 deletions

View File

@ -547,66 +547,99 @@ function drawMultiState(element, offset){
endPerfLog("drawMultiState"); endPerfLog("drawMultiState");
} }
function draw(element, offset){ function drawIteratively(items){
startPerfLog("draw_"+ path.join("_")); //print("drawIteratively");
var initial = !element; startPerfLog("drawIteratively");
if (initial){ for (var c of items){
element = face; startPerfLog("drawIteratively_handling_" + c.type);
if (!offset) offset ={}; if (c.value.HideOn && c.value.HideOn == "Lock" && Bangle.isLocked()){
if (!offset.X) offset.X = 0; //print("Hiding", current);
if (!offset.Y) offset.Y = 0; continue;
g.clear(); }
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); var elementOffset = updateOffset(element, offset);
setColors(elementOffset); setColors(elementOffset);
//print("Using offset", elementOffset); //print("Using offset", elementOffset);
if (Array.isArray(element))
drawIteratively(element);
else {
//print("Using offset", elementOffset);
for (var current in element){ for (var current in element){
//print("Handling ", current, " with offset ", elementOffset); //print("Handling ", current, " with offset ", elementOffset);
startPerfLog("draw_handling_"+ path.join("_")+"_"+current); startPerfLog("draw_handling_"+ path.join("_")+"_"+current);
var currentElement = element[current]; var currentElement = element[current];
try { try {
switch(current){ switch(current){
case "X": case "X":
case "Y": case "Y":
case "Properties": case "Properties":
case "ForegroundColor": case "ForegroundColor":
case "BackgroundColor": case "BackgroundColor":
case "HideOn": 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()){
//print("Hiding", current); //print("Hiding", current);
continue; break;
} case "MultiState":
draw(currentElement, elementOffset); drawMultiState(currentElement, elementOffset);
//print("Done next level"); 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"); //print("Finished drawing loop");
@ -629,17 +662,20 @@ function initialDraw(){
if (!isDrawing){ if (!isDrawing){
//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;
startPerfLog("initialDraw_g.clear");
g.clear();
endPerfLog("initialDraw_g.clear");
requestedDraws = 0; requestedDraws = 0;
//print(new Date().toISOString(), "Drawing start"); //print(new Date().toISOString(), "Drawing start");
startPerfLog("initialDraw"); startPerfLog("initialDraw");
draw(undefined, zeroOffset); draw(face, [], zeroOffset);
endPerfLog("initialDraw"); endPerfLog("initialDraw");
//print(new Date().toISOString(), "Drawing done", (Date.now() - start).toFixed(0)); //print(new Date().toISOString(), "Drawing done", (Date.now() - start).toFixed(0));
isDrawing = false; isDrawing = false;
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;
draw(undefined, zeroOffset); setTimeout(initialDraw, 10);
} }
} }
} }

View File

@ -23,6 +23,8 @@
Options:</br> Options:</br>
<input type="checkbox" id="useDataFile" name="mode" checked/> <input type="checkbox" id="useDataFile" name="mode" checked/>
<label for="useDataFile">Use resource data file (image data not in RAM by default)</label></br> <label for="useDataFile">Use resource data file (image data not in RAM by default)</label></br>
<input type="checkbox" id="collapseTree" name="mode" checked/>
<label for="collapseTree">Collapse the tree to a flat representation</label></br>
</p> </p>
<p>Select watchface folder:</br><input type="file" id="fileLoader" name="files[]" multiple directory="" webkitdirectory="" moxdirectory="" /></p> <p>Select watchface folder:</br><input type="file" id="fileLoader" name="files[]" multiple directory="" webkitdirectory="" moxdirectory="" /></p>
@ -510,6 +512,56 @@
return restructureAmazfitFormat(jsonString); 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() { function imageLoaded() {
var options = {}; var options = {};
@ -592,24 +644,19 @@
if (handledFiles == expectedFiles){ if (handledFiles == expectedFiles){
if (!isNativeFormat()) { if (!isNativeFormat()) {
performFileChanges().then(()=>{ performFileChanges().then(()=>{
postProcess();
rootZip.file("face.json", JSON.stringify(faceJson, null, 2)); rootZip.file("face.json", JSON.stringify(faceJson, null, 2));
rootZip.file("info.json", JSON.stringify(infoJson, 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('btnSave').disabled = false;
document.getElementById('btnSaveFace').disabled = false; document.getElementById('btnSaveFace').disabled = false;
document.getElementById('btnSaveZip').disabled = false; document.getElementById('btnSaveZip').disabled = false;
document.getElementById('btnUpload').disabled = false; document.getElementById('btnUpload').disabled = false;
}); });
} else { } else {
postProcess();
if (true){
moveData(resultJson);
console.log("Created data file", resourceDataString, resourceDataOffset, resultJson);
}
document.getElementById('btnSave').disabled = false; document.getElementById('btnSave').disabled = false;
document.getElementById('btnSaveFace').disabled = false; document.getElementById('btnSaveFace').disabled = false;
document.getElementById('btnUpload').disabled = false; document.getElementById('btnUpload').disabled = false;