2022-09-27 18:44:48 +00:00
|
|
|
{
|
|
|
|
const s = require("Storage");
|
2022-11-04 14:57:14 +00:00
|
|
|
const settings = Object.assign({
|
|
|
|
showClocks: true,
|
|
|
|
fullscreen: false,
|
|
|
|
direct: false,
|
|
|
|
oneClickExit: false,
|
|
|
|
swipeExit: false,
|
|
|
|
timeOut:"Off"
|
|
|
|
}, s.readJSON("iconlaunch.json", true) || {});
|
|
|
|
|
2022-09-27 18:44:48 +00:00
|
|
|
if (!settings.fullscreen) {
|
2022-10-13 20:26:33 +00:00
|
|
|
Bangle.loadWidgets();
|
2022-09-27 18:44:48 +00:00
|
|
|
Bangle.drawWidgets();
|
2022-12-15 11:41:27 +00:00
|
|
|
} else { // for fast-load, if we had widgets then we should hide them
|
|
|
|
require("widget_utils").hide();
|
2022-05-24 00:18:26 +00:00
|
|
|
}
|
2022-11-04 14:57:14 +00:00
|
|
|
let launchCache = s.readJSON("iconlaunch.cache.json", true)||{};
|
|
|
|
let launchHash = s.hash(/\.info/);
|
2022-10-20 16:46:06 +00:00
|
|
|
if (launchCache.hash!=launchHash) {
|
2023-07-22 10:02:34 +00:00
|
|
|
launchCache = {
|
|
|
|
hash : launchHash,
|
|
|
|
apps : s.list(/\.info$/)
|
2022-10-30 16:37:45 +00:00
|
|
|
.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};})
|
2022-10-20 16:46:06 +00:00
|
|
|
.filter(app=>app && (app.type=="app" || (app.type=="clock" && settings.showClocks) || !app.type))
|
|
|
|
.sort((a,b)=>{
|
2022-10-30 16:37:45 +00:00
|
|
|
let n=(0|a.sortorder)-(0|b.sortorder);
|
2022-10-20 16:46:06 +00:00
|
|
|
if (n) return n; // do sortorder first
|
|
|
|
if (a.name<b.name) return -1;
|
|
|
|
if (a.name>b.name) return 1;
|
|
|
|
return 0;
|
|
|
|
}) };
|
2022-11-04 14:57:14 +00:00
|
|
|
s.writeJSON("iconlaunch.cache.json", launchCache);
|
2022-10-20 16:46:06 +00:00
|
|
|
}
|
2022-11-16 20:59:58 +00:00
|
|
|
|
2023-07-22 10:02:34 +00:00
|
|
|
// cache items
|
2023-07-22 11:06:26 +00:00
|
|
|
const ICON_MISSING = atob("MDABAAAAAAAAAAAAAAAAAAABAAAAAAADgAAAAAAGwAAAAAAMYAAAAAAYMAAAAAAwGAAAAABgDAAAAADABgAAAAGAAwAAAAMAAYAAAAYP4MAAAAw//GAAABh4/jAAADD4fhgAAGD8PwwAAMD8PwYAAYD8PwMAAwD8PwGABgB4fwDADAAAfgBgGAAAfgAwMAAA+AAYGAAB8AAwDAABwABgBgADgADAAwADAAGAAYADAAMAAMAAAAYAAGAAAAwAADADgBgAABgHwDAAAAwPwGAAAAYP4MAAAAMPwYAAAAGPwwAAAADHhgAAAABgDAAAAAAwGAAAAAAYMAAAAAAMYAAAAAAGwAAAAAADgAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
|
2023-07-22 10:02:34 +00:00
|
|
|
let count = 0;
|
|
|
|
launchCache.items = [];
|
|
|
|
for (let c of launchCache.apps){
|
|
|
|
let i = Math.floor(count/3);
|
|
|
|
if (!launchCache.items[i])
|
|
|
|
launchCache.items.push([]);
|
|
|
|
launchCache.items[Math.floor(count/3)].push(c);
|
2023-07-22 11:06:26 +00:00
|
|
|
if (c.icon)
|
|
|
|
c.icondata = s.read(c.icon);
|
|
|
|
else
|
|
|
|
c.icondata = ICON_MISSING;
|
2023-07-22 10:02:34 +00:00
|
|
|
count++;
|
|
|
|
}
|
|
|
|
|
2022-09-27 18:44:48 +00:00
|
|
|
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 itemSize = iconSize + whitespace;
|
2022-11-16 20:59:58 +00:00
|
|
|
|
2022-10-06 18:06:12 +00:00
|
|
|
let drawItem = function(itemI, r) {
|
2022-09-27 18:44:48 +00:00
|
|
|
let x = 0;
|
2023-07-22 10:02:34 +00:00
|
|
|
let apps = launchCache.items[itemI];
|
2023-07-22 11:06:26 +00:00
|
|
|
let i = itemI * appsN;
|
2023-07-22 10:02:34 +00:00
|
|
|
let selectedApp;
|
|
|
|
let currentApp;
|
2023-07-22 10:24:35 +00:00
|
|
|
let layers=[];
|
|
|
|
let selectedRect;
|
2023-07-22 10:02:34 +00:00
|
|
|
for (currentApp of apps) {
|
|
|
|
i++;
|
2022-09-27 18:44:48 +00:00
|
|
|
x += whitespace;
|
2023-07-22 11:06:26 +00:00
|
|
|
layers.push({x:x+r.x,y:r.y,image:currentApp.icondata});
|
2022-09-27 18:44:48 +00:00
|
|
|
if (selectedItem == i) {
|
2023-07-22 10:02:34 +00:00
|
|
|
selectedApp = currentApp;
|
2023-07-22 10:24:35 +00:00
|
|
|
selectedRect = [
|
2022-09-27 18:44:48 +00:00
|
|
|
x + r.x - 1,
|
|
|
|
r.y - 1,
|
|
|
|
x + r.x + iconSize + 1,
|
|
|
|
r.y + iconSize + 1
|
2023-07-22 10:24:35 +00:00
|
|
|
];
|
2022-09-27 18:44:48 +00:00
|
|
|
}
|
|
|
|
x += iconSize;
|
|
|
|
}
|
2023-07-22 10:32:53 +00:00
|
|
|
if (selectedRect) g.clearRect(r.x, r.y, r.x + r.w - 1, r.y + r.h - 1);
|
2023-07-22 10:24:35 +00:00
|
|
|
g.drawImages(layers);
|
|
|
|
if (selectedRect) g.drawRect.apply(null, selectedRect);
|
2023-07-22 10:02:34 +00:00
|
|
|
if (selectedApp) drawText(itemI, r.y, selectedApp);
|
2022-10-06 18:06:12 +00:00
|
|
|
};
|
2022-11-16 20:59:58 +00:00
|
|
|
|
2023-07-22 10:02:34 +00:00
|
|
|
let drawText = function(i, appY, selectedApp) {
|
2022-09-27 18:44:48 +00:00
|
|
|
const idy = (selectedItem - (selectedItem % 3)) / 3;
|
2023-07-22 10:02:34 +00:00
|
|
|
if (i != idy) return;
|
2022-11-16 20:59:58 +00:00
|
|
|
appY = appY + itemSize/2;
|
2022-09-27 18:44:48 +00:00
|
|
|
g.setFontAlign(0, 0, 0);
|
|
|
|
g.setFont("12x20");
|
|
|
|
const rect = g.stringMetrics(selectedApp.name);
|
|
|
|
g.clearRect(
|
2022-11-16 20:59:58 +00:00
|
|
|
R.w / 2 - rect.width / 2 - 2,
|
|
|
|
appY - rect.height / 2 - 2,
|
|
|
|
R.w / 2 + rect.width / 2 + 1,
|
|
|
|
appY + rect.height / 2 + 1
|
2022-09-27 18:44:48 +00:00
|
|
|
);
|
|
|
|
g.drawString(selectedApp.name, R.w / 2, appY);
|
2022-10-06 18:06:12 +00:00
|
|
|
};
|
2022-11-16 20:59:58 +00:00
|
|
|
|
2022-10-06 18:06:12 +00:00
|
|
|
let selectItem = function(id, e) {
|
2022-09-27 18:44:48 +00:00
|
|
|
const iconN = E.clip(Math.floor((e.x - R.x) / itemSize), 0, appsN - 1);
|
|
|
|
const appId = id * appsN + iconN;
|
2022-10-21 15:19:39 +00:00
|
|
|
if( settings.direct && launchCache.apps[appId])
|
2022-09-27 18:44:48 +00:00
|
|
|
{
|
2022-11-15 16:56:28 +00:00
|
|
|
load(launchCache.apps[appId].src);
|
2022-09-27 18:44:48 +00:00
|
|
|
return;
|
|
|
|
}
|
2022-10-21 15:19:39 +00:00
|
|
|
if (appId == selectedItem && launchCache.apps[appId]) {
|
|
|
|
const app = launchCache.apps[appId];
|
2022-09-27 18:44:48 +00:00
|
|
|
if (!app.src || s.read(app.src) === undefined) {
|
|
|
|
E.showMessage( /*LANG*/ "App Source\nNot found");
|
|
|
|
} else {
|
2022-11-15 16:56:28 +00:00
|
|
|
load(app.src);
|
2022-09-27 18:44:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
selectedItem = appId;
|
2022-11-16 20:59:58 +00:00
|
|
|
if (scroller) scroller.draw();
|
2022-10-06 18:06:12 +00:00
|
|
|
};
|
2022-10-21 15:19:39 +00:00
|
|
|
const itemsN = Math.ceil(launchCache.apps.length / appsN);
|
2022-11-16 20:59:58 +00:00
|
|
|
|
2023-03-02 19:11:34 +00:00
|
|
|
let idWatch = null;
|
2022-11-16 20:59:58 +00:00
|
|
|
let options = {
|
|
|
|
h: itemSize,
|
|
|
|
c: itemsN,
|
|
|
|
draw: drawItem,
|
|
|
|
select: selectItem,
|
2022-11-14 17:42:06 +00:00
|
|
|
remove: function() {
|
|
|
|
if (timeout) clearTimeout(timeout);
|
2022-11-16 20:59:58 +00:00
|
|
|
Bangle.removeListener("drag", updateTimeout);
|
|
|
|
Bangle.removeListener("touch", updateTimeout);
|
|
|
|
Bangle.removeListener("swipe", swipeHandler);
|
2022-12-15 11:41:27 +00:00
|
|
|
if (settings.fullscreen) { // for fast-load, if we hid widgets then we should show them again
|
|
|
|
require("widget_utils").show();
|
|
|
|
}
|
2023-03-02 19:11:34 +00:00
|
|
|
if(idWatch) clearWatch(idWatch);
|
|
|
|
},
|
|
|
|
btn:Bangle.showClock
|
2022-10-30 16:37:45 +00:00
|
|
|
};
|
2023-03-02 19:11:34 +00:00
|
|
|
|
|
|
|
//work both the fullscreen and the oneClickExit
|
|
|
|
if( settings.fullscreen && settings.oneClickExit)
|
|
|
|
{
|
|
|
|
idWatch=setWatch(function(e) {
|
|
|
|
Bangle.showClock();
|
|
|
|
}, BTN, {repeat:false, edge:'rising' });
|
|
|
|
|
|
|
|
}
|
|
|
|
else if( settings.oneClickExit )
|
|
|
|
{
|
|
|
|
options.back=Bangle.showClock;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2022-10-30 16:37:45 +00:00
|
|
|
|
2022-11-16 20:59:58 +00:00
|
|
|
let scroller = E.showScroller(options);
|
|
|
|
|
2022-11-06 11:42:11 +00:00
|
|
|
let timeout;
|
|
|
|
const updateTimeout = function(){
|
2022-11-04 14:57:14 +00:00
|
|
|
if (settings.timeOut!="Off"){
|
|
|
|
let time=parseInt(settings.timeOut); //the "s" will be trimmed by the parseInt
|
2022-11-06 11:42:11 +00:00
|
|
|
if (timeout) clearTimeout(timeout);
|
2022-11-15 16:19:58 +00:00
|
|
|
timeout = setTimeout(Bangle.showClock,time*1000);
|
2022-11-06 11:42:11 +00:00
|
|
|
}
|
2022-11-14 17:42:06 +00:00
|
|
|
};
|
|
|
|
|
2022-11-16 20:59:58 +00:00
|
|
|
let swipeHandler = (h,_) => { if(settings.swipeExit && h==1) { Bangle.showClock(); } };
|
|
|
|
|
|
|
|
Bangle.on("swipe", swipeHandler)
|
|
|
|
Bangle.on("drag", updateTimeout);
|
|
|
|
Bangle.on("touch", updateTimeout);
|
2022-10-30 16:37:45 +00:00
|
|
|
|
2022-11-16 20:59:58 +00:00
|
|
|
updateTimeout();
|
2023-03-02 19:11:34 +00:00
|
|
|
}
|