diff --git a/apps/iconlaunch/ChangeLog b/apps/iconlaunch/ChangeLog index 8bad496bf..f9d143fca 100644 --- a/apps/iconlaunch/ChangeLog +++ b/apps/iconlaunch/ChangeLog @@ -21,4 +21,5 @@ 0.15: Ensure that we hide widgets if in fullscreen mode (So that widgets are still hidden if launcher is fast-loaded) 0.16: Use firmware provided E.showScroller method -0.17: fix fullscreen with oneClickExit +0.17: fix fullscreen with oneClickExit +0.18: Better performance diff --git a/apps/iconlaunch/app.js b/apps/iconlaunch/app.js index 9f8cedb0f..03e743885 100644 --- a/apps/iconlaunch/app.js +++ b/apps/iconlaunch/app.js @@ -9,7 +9,6 @@ timeOut:"Off" }, s.readJSON("iconlaunch.json", true) || {}); - if (!settings.fullscreen) { Bangle.loadWidgets(); Bangle.drawWidgets(); @@ -19,9 +18,9 @@ let launchCache = s.readJSON("iconlaunch.cache.json", true)||{}; let launchHash = s.hash(/\.info/); if (launchCache.hash!=launchHash) { - launchCache = { - hash : launchHash, - apps : s.list(/\.info$/) + launchCache = { + hash : launchHash, + apps : s.list(/\.info$/) .map(app=>{let a=s.readJSON(app,1);return a&&{name:a.name,type:a.type,icon:a.icon,sortorder:a.sortorder,src:a.src};}) .filter(app=>app && (app.type=="app" || (app.type=="clock" && settings.showClocks) || !app.type)) .sort((a,b)=>{ @@ -34,42 +33,66 @@ s.writeJSON("iconlaunch.cache.json", launchCache); } + // cache items + const ICON_MISSING = s.read("iconlaunch.na.img"); + let count = 0; + let selectedItem = -1; const R = Bangle.appRect; const iconSize = 48; const appsN = Math.floor(R.w / iconSize); - const whitespace = (R.w - appsN * iconSize) / (appsN + 1); + const whitespace = Math.floor((R.w - appsN * iconSize) / (appsN + 1)); + const iconYoffset = Math.floor(whitespace/4)-1; const itemSize = iconSize + whitespace; + launchCache.items = {}; + for (let c of launchCache.apps){ + let i = Math.floor(count/appsN); + if (!launchCache.items[i]) + launchCache.items[i] = {}; + launchCache.items[i][(count%3)] = c; + count++; + } + + let texted; let drawItem = function(itemI, r) { - g.clearRect(r.x, r.y, r.x + r.w - 1, r.y + r.h - 1); - let x = 0; - for (let i = itemI * appsN; i < appsN * (itemI + 1); i++) { - if (!launchCache.apps[i]) break; - x += whitespace; - if (!launchCache.apps[i].icon) { - g.setFontAlign(0, 0, 0).setFont("12x20:2").drawString("?", x + r.x + iconSize / 2, r.y + iconSize / 2); - } else { - if (!launchCache.apps[i].icondata) launchCache.apps[i].icondata = s.read(launchCache.apps[i].icon); - g.drawImage(launchCache.apps[i].icondata, x + r.x, r.y); - } - if (selectedItem == i) { - g.drawRect( - x + r.x - 1, - r.y - 1, - x + r.x + iconSize + 1, - r.y + iconSize + 1 - ); - } - x += iconSize; + "jit"; + let x = whitespace; + let i = itemI * appsN - 1; + let selectedApp; + let c; + let selectedRect; + let item = launchCache.items[itemI]; + if (texted == itemI){ + g.clearRect(r.x, r.y, r.x + r.w - 1, r.y + r.h - 1); + texted = undefined; + } + for (c of item) { + i++; + let id = c.icondata || (c.iconData = (c.icon ? s.read(c.icon) : ICON_MISSING)); + g.drawImage(id,x + r.x - 1, r.y + iconYoffset - 1, x + r.x + iconSize, r.y + iconYoffset + iconSize); + if (selectedItem == i) { + selectedApp = c; + selectedRect = [ + x + r.x - 1, + r.y + iconYoffset - 1, + x + r.x + iconSize, + r.y + iconYoffset + iconSize + ]; + } + x += iconSize + whitespace; + } + if (selectedRect) { + g.drawRect.apply(null, selectedRect); + drawText(itemI, r.y, selectedApp); + texted=itemI; } - drawText(itemI, r.y); }; - let drawText = function(i, appY) { - const selectedApp = launchCache.apps[selectedItem]; + let drawText = function(i, appY, selectedApp) { + "jit"; const idy = (selectedItem - (selectedItem % 3)) / 3; - if (!selectedApp || i != idy) return; + if (i != idy) return; appY = appY + itemSize/2; g.setFontAlign(0, 0, 0); g.setFont("12x20"); diff --git a/apps/iconlaunch/metadata.json b/apps/iconlaunch/metadata.json index 35a7907bd..e17830ca6 100644 --- a/apps/iconlaunch/metadata.json +++ b/apps/iconlaunch/metadata.json @@ -2,7 +2,7 @@ "id": "iconlaunch", "name": "Icon Launcher", "shortName" : "Icon launcher", - "version": "0.17", + "version": "0.18", "icon": "app.png", "description": "A launcher inspired by smartphones, with an icon-only scrollable menu.", "tags": "tool,system,launcher", @@ -10,7 +10,8 @@ "supports": ["BANGLEJS2"], "storage": [ { "name": "iconlaunch.app.js", "url": "app.js" }, - { "name": "iconlaunch.settings.js", "url": "settings.js" } + { "name": "iconlaunch.settings.js", "url": "settings.js" }, + { "name": "iconlaunch.na.img", "url": "na.img" } ], "data": [{"name":"iconlaunch.json"},{"name":"iconlaunch.cache.json"}], "screenshots": [{ "url": "screenshot1.png" }, { "url": "screenshot2.png" }], diff --git a/apps/iconlaunch/na.img b/apps/iconlaunch/na.img new file mode 100644 index 000000000..10f4a8f82 Binary files /dev/null and b/apps/iconlaunch/na.img differ diff --git a/apps/iconlaunch/settings.js b/apps/iconlaunch/settings.js index f4c0599f7..3278075e4 100644 --- a/apps/iconlaunch/settings.js +++ b/apps/iconlaunch/settings.js @@ -16,8 +16,7 @@ } const timeOutChoices = [/*LANG*/"Off", "10s", "15s", "20s", "30s"]; const appMenu = { - "": { "title": /*LANG*/"Launcher" }, - /*LANG*/"< Back": back, + "": { "title": /*LANG*/"Launcher", back: back }, /*LANG*/"Show Clocks": { value: settings.showClocks == true, onchange: (m) => {