Merge pull request #2541 from halemmerich/iconlaunch

Iconlaunch - Use firmware E.showScroller
pull/2542/head^2
Gordon Williams 2023-01-30 09:34:39 +00:00 committed by GitHub
commit 431d8c5fd6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 33 additions and 106 deletions

View File

@ -6,7 +6,3 @@ This launcher shows 9 apps per screen, making it much faster to navigate versus
![A screenshot](screenshot1.png) ![A screenshot](screenshot1.png)
![Another screenshot](screenshot2.png) ![Another screenshot](screenshot2.png)
## Technical note
The app uses `E.showScroller`'s code in the app but not the function itself because `E.showScroller` doesn't report the position of a press to the select function.

View File

@ -32,13 +32,14 @@
}) }; }) };
s.writeJSON("iconlaunch.cache.json", launchCache); s.writeJSON("iconlaunch.cache.json", launchCache);
} }
let scroll = 0;
let selectedItem = -1; let selectedItem = -1;
const R = Bangle.appRect; const R = Bangle.appRect;
const iconSize = 48; const iconSize = 48;
const appsN = Math.floor(R.w / iconSize); const appsN = Math.floor(R.w / iconSize);
const whitespace = (R.w - appsN * iconSize) / (appsN + 1); const whitespace = (R.w - appsN * iconSize) / (appsN + 1);
const itemSize = iconSize + whitespace; const itemSize = iconSize + whitespace;
let drawItem = function(itemI, r) { let drawItem = function(itemI, r) {
g.clearRect(r.x, r.y, r.x + r.w - 1, r.y + r.h - 1); g.clearRect(r.x, r.y, r.x + r.w - 1, r.y + r.h - 1);
let x = 0; let x = 0;
@ -61,36 +62,26 @@
} }
x += iconSize; x += iconSize;
} }
drawText(itemI); drawText(itemI, r.y);
}; };
let drawItemAuto = function(i) {
let y = idxToY(i); let drawText = function(i, appY) {
g.reset().setClipRect(R.x, y, R.x2, y + itemSize);
drawItem(i, {
x: R.x,
y: y,
w: R.w,
h: itemSize
});
g.setClipRect(0, 0, g.getWidth() - 1, g.getHeight() - 1);
};
let lastIsDown = false;
let drawText = function(i) {
const selectedApp = launchCache.apps[selectedItem]; const selectedApp = launchCache.apps[selectedItem];
const idy = (selectedItem - (selectedItem % 3)) / 3; const idy = (selectedItem - (selectedItem % 3)) / 3;
if (!selectedApp || i != idy) return; if (!selectedApp || i != idy) return;
const appY = idxToY(idy) + iconSize / 2; appY = appY + itemSize/2;
g.setFontAlign(0, 0, 0); g.setFontAlign(0, 0, 0);
g.setFont("12x20"); g.setFont("12x20");
const rect = g.stringMetrics(selectedApp.name); const rect = g.stringMetrics(selectedApp.name);
g.clearRect( g.clearRect(
R.w / 2 - rect.width / 2, R.w / 2 - rect.width / 2 - 2,
appY - rect.height / 2, appY - rect.height / 2 - 2,
R.w / 2 + rect.width / 2, R.w / 2 + rect.width / 2 + 1,
appY + rect.height / 2 appY + rect.height / 2 + 1
); );
g.drawString(selectedApp.name, R.w / 2, appY); g.drawString(selectedApp.name, R.w / 2, appY);
}; };
let selectItem = function(id, e) { let selectItem = function(id, e) {
const iconN = E.clip(Math.floor((e.x - R.x) / itemSize), 0, appsN - 1); const iconN = E.clip(Math.floor((e.x - R.x) / itemSize), 0, appsN - 1);
const appId = id * appsN + iconN; const appId = id * appsN + iconN;
@ -108,96 +99,32 @@
} }
} }
selectedItem = appId; selectedItem = appId;
drawItems(); if (scroller) scroller.draw();
}; };
let idxToY = function(i) {
return i * itemSize + R.y - (scroll & ~1);
};
let YtoIdx = function(y) {
return Math.floor((y + (scroll & ~1) - R.y) / itemSize);
};
let drawItems = function() {
g.reset().clearRect(R.x, R.y, R.x2, R.y2);
g.setClipRect(R.x, R.y, R.x2, R.y2);
let a = YtoIdx(R.y);
let b = Math.min(YtoIdx(R.y2), 99);
for (let i = a; i <= b; i++)
drawItem(i, {
x: R.x,
y: idxToY(i),
w: R.w,
h: itemSize,
});
g.setClipRect(0, 0, g.getWidth() - 1, g.getHeight() - 1);
};
drawItems();
g.flip();
const itemsN = Math.ceil(launchCache.apps.length / appsN); const itemsN = Math.ceil(launchCache.apps.length / appsN);
let onDrag = function(e) {
updateTimeout(); let back = ()=>{};
g.setColor(g.theme.fg); if (settings.oneClickExit) back = Bangle.showClock;
g.setBgColor(g.theme.bg);
let dy = e.dy; let options = {
if (scroll + R.h - dy > itemsN * itemSize) { h: itemSize,
dy = scroll + R.h - itemsN * itemSize; c: itemsN,
} draw: drawItem,
if (scroll - dy < 0) { select: selectItem,
dy = scroll; back: back,
}
scroll -= dy;
scroll = E.clip(scroll, 0, itemSize * (itemsN - 1));
g.setClipRect(R.x, R.y, R.x2, R.y2);
g.scroll(0, dy);
if (dy < 0) {
g.setClipRect(R.x, R.y2 - (1 - dy), R.x2, R.y2);
let i = YtoIdx(R.y2 - (1 - dy));
let y = idxToY(i);
while (y < R.y2) {
drawItem(i, {
x: R.x,
y: y,
w: R.w,
h: itemSize,
});
i++;
y += itemSize;
}
} else {
g.setClipRect(R.x, R.y, R.x2, R.y + dy);
let i = YtoIdx(R.y + dy);
let y = idxToY(i);
while (y > R.y - itemSize) {
drawItem(i, {
x: R.x,
y: y,
w: R.w,
h: itemSize,
});
y -= itemSize;
i--;
}
}
g.setClipRect(0, 0, g.getWidth() - 1, g.getHeight() - 1);
};
let mode = {
mode: "custom",
drag: onDrag,
touch: (_, e) => {
if (e.y < R.y - 4) return;
updateTimeout();
let i = YtoIdx(e.y);
selectItem(i, e);
},
swipe: (h,_) => { if(settings.swipeExit && h==1) { Bangle.showClock(); } },
btn: _=> { if (settings.oneClickExit) Bangle.showClock(); },
remove: function() { remove: function() {
if (timeout) clearTimeout(timeout); if (timeout) clearTimeout(timeout);
Bangle.removeListener("drag", updateTimeout);
Bangle.removeListener("touch", updateTimeout);
Bangle.removeListener("swipe", swipeHandler);
if (settings.fullscreen) { // for fast-load, if we hid widgets then we should show them again if (settings.fullscreen) { // for fast-load, if we hid widgets then we should show them again
require("widget_utils").show(); require("widget_utils").show();
} }
} }
}; };
let scroller = E.showScroller(options);
let timeout; let timeout;
const updateTimeout = function(){ const updateTimeout = function(){
if (settings.timeOut!="Off"){ if (settings.timeOut!="Off"){
@ -207,7 +134,11 @@
} }
}; };
updateTimeout(); let swipeHandler = (h,_) => { if(settings.swipeExit && h==1) { Bangle.showClock(); } };
Bangle.on("swipe", swipeHandler)
Bangle.on("drag", updateTimeout);
Bangle.on("touch", updateTimeout);
Bangle.setUI(mode); updateTimeout();
} }