diff --git a/apps/imageclock/ChangeLog b/apps/imageclock/ChangeLog index 262794250..283506afa 100644 --- a/apps/imageclock/ChangeLog +++ b/apps/imageclock/ChangeLog @@ -9,3 +9,4 @@ Show/Hide widgets with swipe up or down 0.08: Use default Bangle formatter for booleans 0.09: Support new fast app switching +0.10: Fix clock not correctly refreshing when drawing in timeouts option is not on diff --git a/apps/imageclock/app.js b/apps/imageclock/app.js index 28de9d1df..e8fc80af9 100644 --- a/apps/imageclock/app.js +++ b/apps/imageclock/app.js @@ -1,8 +1,21 @@ let unlockedDrawInterval = []; let lockedDrawInterval = []; let showWidgets = false; +let firstDraw = true; { + 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); + 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")); @@ -49,12 +62,12 @@ let showWidgets = false; let p1; if (settings.perflog){ - startPerfLog = function(name){ + Bangle.startPerfLog = function(name){ let time = getTime(); if (!performanceLog.start) performanceLog.start={}; performanceLog.start[name] = time; }; - endPerfLog = function (name){ + Bangle.endPerfLog = function (name){ let time = getTime(); if (!performanceLog.last) performanceLog.last={}; let duration = time - performanceLog.start[name]; @@ -67,7 +80,7 @@ let showWidgets = false; performanceLog.count[name]++; }; - printPerfLog = function(){ + Bangle.printPerfLog = function(){ let result = ""; let keys = []; for (let c in performanceLog.cum){ @@ -82,20 +95,20 @@ let showWidgets = false; let delayTimeouts = []; - function delay(t) { + let delay = function(t) { return new Promise(function (resolve) { delayTimeouts.push(setTimeout(resolve, t)); }); - } + }; - function cleanupDelays(){ + let cleanupDelays = function(){ for (let t of delayTimeouts){ clearTimeout(t); } delayTimeouts = []; - } + }; - function prepareImg(resource){ + let prepareImg = function(resource){ startPerfLog("prepareImg"); //print("prepareImg: ", resource); @@ -110,9 +123,9 @@ let showWidgets = false; } endPerfLog("prepareImg"); return resource; - } + }; - function getByPath(object, path, lastElem){ + let getByPath = function(object, path, lastElem){ startPerfLog("getByPath"); //print("getByPath", path,lastElem); let current = object; @@ -133,21 +146,21 @@ let showWidgets = false; return undefined; } return current; - } + }; - function splitNumberToDigits(num){ + let splitNumberToDigits = function(num){ return String(num).split('').map(item => Number(item)); - } + }; - function isChangedNumber(element){ + let isChangedNumber = function(element){ return element.lastDrawnValue != getValue(element.Value); - } + }; - function isChangedMultistate(element){ + let isChangedMultistate = function(element){ return element.lastDrawnValue != getMultistate(element.Value); - } + }; - function drawNumber(graphics, resources, element){ + let drawNumber = function(graphics, resources, element){ startPerfLog("drawNumber"); let number = getValue(element.Value); let spacing = element.Spacing ? element.Spacing : 0; @@ -258,9 +271,9 @@ let showWidgets = false; element.lastDrawnValue = number; endPerfLog("drawNumber"); - } + }; - function drawElement(graphics, resources, pos, element, lastElem){ + let drawElement = function(graphics, resources, pos, element, lastElem){ startPerfLog("drawElement"); let cacheKey = "_"+(lastElem?lastElem:"nole"); if (!element.cachedImage) element.cachedImage={}; @@ -304,26 +317,26 @@ let showWidgets = false; endPerfLog("drawElement_g.drawImage"); } endPerfLog("drawElement"); - } + }; - function getValue(value, defaultValue){ + let getValue = function(value, defaultValue){ if (typeof value == "string"){ return numbers[value](); } if (value == undefined) return defaultValue; return value; - } + }; - function getMultistate(name, defaultValue){ + let getMultistate = function(name, defaultValue){ if (typeof name == "string"){ return multistates[name](); } else { if (name == undefined) return defaultValue; } return undefined; - } + }; - function drawScale(graphics, resources, scale){ + let drawScale = function(graphics, resources, scale){ startPerfLog("drawScale"); //print("drawScale", scale); let segments = scale.Segments; @@ -341,9 +354,9 @@ let showWidgets = false; scale.lastDrawnValue = segmentsToDraw; endPerfLog("drawScale"); - } + }; - function drawImage(graphics, resources, image, name){ + let drawImage = function(graphics, resources, image, name){ startPerfLog("drawImage"); //print("drawImage", image.X, image.Y, name); if (image.Value && image.Steps){ @@ -357,9 +370,9 @@ let showWidgets = false; } endPerfLog("drawImage"); - } + }; - function drawCodedImage(graphics, resources, image){ + let drawCodedImage = function(graphics, resources, image){ startPerfLog("drawCodedImage"); let code = getValue(image.Value); //print("drawCodedImage", image, code); @@ -386,9 +399,9 @@ let showWidgets = false; image.lastDrawnValue = code; startPerfLog("drawCodedImage"); - } + }; - function getWeatherCode(){ + let getWeatherCode = function(){ let jsonWeather = require("Storage").readJSON('weather.json'); let weather = (jsonWeather && jsonWeather.weather) ? jsonWeather.weather : undefined; @@ -396,9 +409,9 @@ let showWidgets = false; return weather.code; } return undefined; - } + }; - function getWeatherTemperature(){ + let getWeatherTemperature = function(){ let jsonWeather = require("Storage").readJSON('weather.json'); let weather = (jsonWeather && jsonWeather.weather) ? jsonWeather.weather : undefined; @@ -415,25 +428,25 @@ let showWidgets = false; } } return result; - } + }; - function scaledown(value, min, max){ + let scaledown = function(value, min, max){ //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; - } + }; - function radians(rotation){ + let radians = function(rotation){ let value = scaledown(rotation.RotationValue, rotation.MinRotationValue, rotation.MaxRotationValue); value -= rotation.RotationOffset ? rotation.RotationOffset : 0; value *= 360; value *= Math.PI / 180; return value; - } + }; - function drawPoly(graphics, resources, element){ + let drawPoly = function(graphics, resources, element){ startPerfLog("drawPoly"); let vertices = []; @@ -463,9 +476,9 @@ let showWidgets = false; } endPerfLog("drawPoly"); - } + }; - function drawRect(graphics, resources, element){ + let drawRect = function(graphics, resources, element){ startPerfLog("drawRect"); let vertices = []; @@ -479,9 +492,9 @@ let showWidgets = false; endPerfLog("drawRect_g.fillRect"); } endPerfLog("drawRect"); - } + }; - function drawCircle(graphics, resources, element){ + let drawCircle = function(graphics, resources, element){ startPerfLog("drawCircle"); if (element.Filled){ @@ -494,7 +507,7 @@ let showWidgets = false; endPerfLog("drawCircle_g.drawCircle"); } endPerfLog("drawCircle"); - } + }; let numbers = {}; numbers.Hour = () => { return new Date().getHours(); }; @@ -547,7 +560,7 @@ let showWidgets = false; multistates.WeatherTemperatureUnit = () => { return getWeatherTemperature().unit; }; multistates.StepsGoal = () => { return (numbers.Steps() >= (settings.stepsgoal || 10000)) ? "on": "off"; }; - function drawMultiState(graphics, resources, element){ + let drawMultiState = function(graphics, resources, element){ startPerfLog("drawMultiState"); //print("drawMultiState", element); let value = multistates[element.Value](); @@ -555,7 +568,7 @@ let showWidgets = false; drawImage(graphics, resources, element, value); element.lastDrawnValue = value; endPerfLog("drawMultiState"); - } + }; let pulse,alt,temp,press; @@ -569,7 +582,7 @@ let showWidgets = false; let deferredTimout; - function initialDraw(resources, face){ + let initialDraw = function(resources, face){ //print("Free memory", process.memory(false).free); requestedDraws++; if (!isDrawing){ @@ -613,9 +626,9 @@ let showWidgets = false; } //else { //print("queued draw"); //} - } + }; - function handleHrm(e){ + let handleHrm = function(e){ if (e.confidence > 70){ pulse = e.bpm; if (!redrawEvents || redrawEvents.includes("HRM") && !Bangle.isLocked()){ @@ -623,9 +636,9 @@ let showWidgets = false; initialDraw(watchfaceResources, watchface); } } - } + }; - function handlePressure(e){ + let handlePressure = function(e){ alt = e.altitude; temp = e.temperature; press = e.pressure; @@ -633,23 +646,23 @@ let showWidgets = false; //print("Redrawing on pressure"); initialDraw(watchfaceResources, watchface); } - } + }; - function handleCharging(e){ + let handleCharging = function(e){ if (!redrawEvents || redrawEvents.includes("charging") && !Bangle.isLocked()){ //print("Redrawing on charging"); initialDraw(watchfaceResources, watchface); } - } + }; - function getMatchedWaitingTime(time){ + let getMatchedWaitingTime = function(time){ let result = time - (Date.now() % time); //print("Matched timeout", time, result); return result; - } + }; - function setMatchedInterval(callable, time, intervalHandler, delay){ + let setMatchedInterval = function(callable, time, intervalHandler, delay){ //print("Setting matched interval for", time, intervalHandler); let matchedTime = getMatchedWaitingTime(time + delay); return setTimeout(()=>{ @@ -657,11 +670,10 @@ let showWidgets = false; if (intervalHandler) intervalHandler(interval); callable(); }, matchedTime); - } + }; let lastDrawTime = 0; - let firstDraw = true; let lockedRedraw = getByPath(watchface, ["Properties","Redraw","Locked"]) || 60000; let unlockedRedraw = getByPath(watchface, ["Properties","Redraw","Unlocked"]) || 1000; @@ -676,7 +688,7 @@ let showWidgets = false; let initialDrawTimeoutUnlocked; let initialDrawTimeoutLocked; - function handleLock(isLocked, forceRedraw){ + let handleLock = function(isLocked, forceRedraw){ //print("isLocked", Bangle.isLocked()); for (let i of unlockedDrawInterval){ //print("Clearing unlocked", i); @@ -694,6 +706,7 @@ let showWidgets = false; //print("Redrawing on unlock", isLocked); initialDraw(watchfaceResources, watchface); } + if (initialDrawTimeoutUnlocked) clearTimeout(initialDrawTimeoutUnlocked); initialDrawTimeoutUnlocked = setMatchedInterval(()=>{ //print("Redrawing on unlocked interval"); initialDraw(watchfaceResources, watchface); @@ -708,6 +721,7 @@ let showWidgets = false; //print("Redrawing on lock", isLocked); initialDraw(watchfaceResources, watchface); } + if (initialDrawTimeoutLocked) clearTimeout(initialDrawTimeoutLocked); initialDrawTimeoutLocked = setMatchedInterval(()=>{ //print("Redrawing on locked interval"); initialDraw(watchfaceResources, watchface); @@ -718,13 +732,13 @@ let showWidgets = false; Bangle.setHRMPower(0, "imageclock"); Bangle.setBarometerPower(0, 'imageclock'); } - } + }; let showWidgetsChanged = false; let currentDragDistance = 0; - function restoreWidgetDraw(){ + let restoreWidgetDraw = function(){ if (global.WIDGETS) { for (let w in global.WIDGETS) { let wd = global.WIDGETS[w]; @@ -732,9 +746,9 @@ let showWidgets = false; wd.area = originalWidgetArea[w]; } } - } + }; - function handleDrag(e){ + let handleDrag = function(e){ //print("handleDrag"); currentDragDistance += e.dy; if (Math.abs(currentDragDistance) < 10) return; @@ -757,7 +771,7 @@ let showWidgets = false; showWidgets = dragDown; initialDraw(); } - } + }; Bangle.on('drag', handleDrag); @@ -783,7 +797,7 @@ let showWidgets = false; let originalWidgetDraw = {}; let originalWidgetArea = {}; - function clearWidgetsDraw(){ + let clearWidgetsDraw = function(){ //print("Clear widget draw calls"); if (global.WIDGETS) { originalWidgetDraw = {}; @@ -798,10 +812,7 @@ let showWidgets = false; } } - if (!global.WIDGETS) Bangle.loadWidgets(); - clearWidgetsDraw(); - - handleLock(Bangle.isLocked()); + handleLock(Bangle.isLocked(), true); Bangle.setUI({ mode : "clock", @@ -832,9 +843,13 @@ let showWidgets = false; } delete lockedDrawInterval; delete showWidgets; + delete firstDraw; cleanupDelays(); restoreWidgetDraw(); } }); + + Bangle.loadWidgets(); + clearWidgetsDraw(); } diff --git a/apps/imageclock/metadata.json b/apps/imageclock/metadata.json index 8a3fd5939..47db30f90 100644 --- a/apps/imageclock/metadata.json +++ b/apps/imageclock/metadata.json @@ -2,7 +2,7 @@ "id": "imageclock", "name": "Imageclock", "shortName": "Imageclock", - "version": "0.09", + "version": "0.10", "type": "clock", "description": "BETA!!! File formats still subject to change --- This app is a highly customizable watchface. To use it, you need to select a watchface. You can build the watchfaces yourself without programming anything. All you need to do is write some json and create image files.", "icon": "app.png",