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");
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue