added cutelauncher
parent
945086a331
commit
8ed9656b0f
|
|
@ -0,0 +1 @@
|
|||
require("heatshrink").decompress(atob("lUvwIFCjwKDj/gAgf+Agf/BQUP+f8AgXwn/AAgP4gYKBAgMAv/Ag4EBAQIECBQODDgfxAgUA/wxIAgIUD///GIX/HgUP/f8GII2B/4xDIoN/w/4JgIXB/hKCEwX/DoIEBLQQlC+B9CCgUHwAUCgJFBCgV4Cix3BCgMH74UCgfn+AUBgZZBCgIjBWoMegP+AIMHwKGBn/h8ISBgf+vAEBBQPeAgUDRQKaCv//IgIzBAgYKBAgZTCAAoA="));
|
||||
|
|
@ -0,0 +1,182 @@
|
|||
{
|
||||
let settings = Object.assign(
|
||||
{
|
||||
showClocks: false,
|
||||
showLaunchers: false,
|
||||
direct: false,
|
||||
swipeExit: true,
|
||||
timeOut: 'Off',
|
||||
},
|
||||
require('Storage').readJSON('cutelauncher.json', true) || {}
|
||||
);
|
||||
|
||||
let s = require('Storage');
|
||||
// Borrowed caching from Icon Launcher, code by halemmerich.
|
||||
let launchCache = s.readJSON('launch.cache.json', true) || {};
|
||||
let launchHash = require('Storage').hash(/\.info/);
|
||||
if (launchCache.hash != launchHash) {
|
||||
launchCache = {
|
||||
hash: launchHash,
|
||||
apps: s
|
||||
.list(/\.info$/)
|
||||
.map((app) => {
|
||||
var 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) => {
|
||||
var n = (0 | a.sortorder) - (0 | b.sortorder);
|
||||
if (n) return n; // do sortorder first
|
||||
if (a.name < b.name) return -1;
|
||||
if (a.name > b.name) return 1;
|
||||
return 0;
|
||||
}),
|
||||
};
|
||||
s.writeJSON('launch.cache.json', launchCache);
|
||||
}
|
||||
let apps = launchCache.apps;
|
||||
apps.forEach((app) => {
|
||||
if (app.icon) app.icon = s.read(app.icon); // should just be a link to a memory area
|
||||
else app.icon = s.read('placeholder.img');
|
||||
});
|
||||
|
||||
let Napps = apps.length;
|
||||
let Npages = Math.ceil(Napps / 4);
|
||||
let maxPage = Npages - 1;
|
||||
let selected = -1;
|
||||
let oldselected = -1;
|
||||
let page = 0;
|
||||
|
||||
require('Font8x16').add(Graphics);
|
||||
Bangle.drawWidgets = () => { };
|
||||
Bangle.loadWidgets = () => { };
|
||||
|
||||
let drawIcon = function (p, n, selected) {
|
||||
let coords = { x: (n % 2) * 88, y: n > 1 ? 88 : 0, w: 88, h: 88 };
|
||||
if (selected) {
|
||||
g.setColor(g.theme.bgH).fillRect(coords);
|
||||
g.setColor(g.theme.fgH);
|
||||
} else {
|
||||
g.setColor(g.theme.bg).fillRect(coords);
|
||||
g.setColor(g.theme.fg);
|
||||
}
|
||||
|
||||
try {
|
||||
let icon = apps[p * 4 + n].icon;
|
||||
let iconWidth = icon.width || 48;
|
||||
let iconHeight = icon.height || 48;
|
||||
let maxSize = 48;
|
||||
let scale = Math.min(maxSize / iconWidth, maxSize / iconHeight);
|
||||
let scaledWidth = Math.floor(iconWidth * scale);
|
||||
let scaledHeight = Math.floor(iconHeight * scale);
|
||||
|
||||
// Get text height to center everything
|
||||
g.setFontAlign(0, -1, 0).setFont('8x16');
|
||||
let text = g.wrapString(apps[p * 4 + n].name, 88).join('\n');
|
||||
let textHeight = text.split('\n').length * 16;
|
||||
|
||||
let totalHeight = scaledHeight + 4 + textHeight; // 4px padding between icon and text
|
||||
let startY = coords.y + (88 - totalHeight) / 2;
|
||||
|
||||
// Draw icon centered horizontally and as part of vertical group
|
||||
let iconX = coords.x + (88 - scaledWidth) / 2;
|
||||
let iconY = startY;
|
||||
g.drawImage(icon, iconX, iconY, { scale: scale });
|
||||
|
||||
// Draw text below icon
|
||||
g.drawString(text, coords.x + coords.w / 2, startY + scaledHeight + 4);
|
||||
} catch (e) { }
|
||||
};
|
||||
|
||||
let drawPage = function (p) {
|
||||
g.reset();
|
||||
g.setColor(g.theme.bg).fillRect(0, 0, 175, 175);
|
||||
for (let i = 0; i < 4; i++) {
|
||||
if (!apps[p * 4 + i]) return i;
|
||||
drawIcon(p, i, selected == i && !settings.direct);
|
||||
}
|
||||
g.flip();
|
||||
};
|
||||
|
||||
drawPage(0);
|
||||
|
||||
let swipeListenerDt = function (dirLeftRight, dirUpDown) {
|
||||
updateTimeoutToClock();
|
||||
selected = -1;
|
||||
oldselected = -1;
|
||||
if (settings.swipeExit && dirLeftRight == 1) Bangle.showClock();
|
||||
if (dirUpDown == -1 || dirLeftRight == -1) {
|
||||
++page;
|
||||
if (page > maxPage) page = 0;
|
||||
drawPage(page);
|
||||
} else if (dirUpDown == 1 || (dirLeftRight == 1 && !settings.swipeExit)) {
|
||||
--page;
|
||||
if (page < 0) page = maxPage;
|
||||
drawPage(page);
|
||||
}
|
||||
};
|
||||
|
||||
let isTouched = function (p, n) {
|
||||
if (n < 0 || n > 3) return false;
|
||||
let x1 = (n % 2) * 88;
|
||||
let y1 = n > 1 ? 88 : 0;
|
||||
let x2 = x1 + 88;
|
||||
let y2 = y1 + 88;
|
||||
return p.x > x1 && p.y > y1 && p.x < x2 && p.y < y2;
|
||||
};
|
||||
|
||||
let touchListenerDt = function (_, p) {
|
||||
updateTimeoutToClock();
|
||||
let i;
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (page * 4 + i < Napps) {
|
||||
if (isTouched(p, i)) {
|
||||
drawIcon(page, i, true && !settings.direct);
|
||||
if (selected >= 0 || settings.direct) {
|
||||
if (selected != i && !settings.direct) {
|
||||
drawIcon(page, selected, false);
|
||||
} else {
|
||||
load(apps[page * 4 + i].src);
|
||||
}
|
||||
}
|
||||
selected = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((i == 4 || page * 4 + i > Napps) && selected >= 0) {
|
||||
drawIcon(page, selected, false);
|
||||
selected = -1;
|
||||
}
|
||||
};
|
||||
|
||||
Bangle.setUI({
|
||||
mode: 'custom',
|
||||
swipe: swipeListenerDt,
|
||||
touch: touchListenerDt,
|
||||
remove: () => {
|
||||
if (timeoutToClock) clearTimeout(timeoutToClock);
|
||||
},
|
||||
});
|
||||
|
||||
// taken from Icon Launcher with minor alterations
|
||||
let timeoutToClock;
|
||||
const updateTimeoutToClock = function () {
|
||||
if (settings.timeOut != 'Off') {
|
||||
let time = parseInt(settings.timeOut); //the "s" will be trimmed by the parseInt
|
||||
if (timeoutToClock) clearTimeout(timeoutToClock);
|
||||
timeoutToClock = setTimeout(Bangle.showClock, time * 1000);
|
||||
}
|
||||
};
|
||||
updateTimeoutToClock();
|
||||
|
||||
if (Bangle.backHandler) clearWatch(Bangle.backHandler);
|
||||
Bangle.backHandler = setWatch(Bangle.showClock, BTN1, { debounce: 100 });
|
||||
} // end of app scope
|
||||
|
||||
// setUI now also needs to clear up our back button touch handler
|
||||
Bangle.setUI = (old => function () {
|
||||
if (Bangle.backHandler) clearWatch(Bangle.backHandler);
|
||||
delete Bangle.backHandler;
|
||||
return old.apply(this, arguments);
|
||||
})(Bangle.setUI);
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 1012 B |
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"id": "cutelauncher",
|
||||
"name": "Cute Launcher",
|
||||
"version": "0.01",
|
||||
"description": "A simple launcher app for Bangle.js 2 that makes use of the full touchscreen",
|
||||
"icon": "app.png",
|
||||
"type": "launch",
|
||||
"tags": "tool,system,launcher",
|
||||
"supports": [
|
||||
"BANGLEJS2"
|
||||
],
|
||||
"storage": [
|
||||
{
|
||||
"name": "cutelauncher.app.js",
|
||||
"url": "app.js"
|
||||
},
|
||||
{
|
||||
"name": "cutelauncher.img",
|
||||
"url": "app-icon.js",
|
||||
"evaluate": true
|
||||
}
|
||||
]
|
||||
}
|
||||
Loading…
Reference in New Issue