mirror of https://github.com/espruino/BangleApps
Allow collapsing the watchface tree down to an array
parent
dfd127f498
commit
0cca59144d
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
Options:</br>
|
||||
<input type="checkbox" id="useDataFile" name="mode" checked/>
|
||||
<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>Select watchface folder:</br><input type="file" id="fileLoader" name="files[]" multiple directory="" webkitdirectory="" moxdirectory="" /></p>
|
||||
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue