Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Desktop Launcher] Fast load to clockface on B2 #2235

Merged
merged 13 commits into from Nov 7, 2022
2 changes: 2 additions & 0 deletions apps/dtlaunch/ChangeLog
Expand Up @@ -14,3 +14,5 @@
0.14: Don't move pages when doing exit swipe - Bangle 2.
0.15: 'Swipe to exit'-code is slightly altered to be more reliable - Bangle 2.
0.16: Use default Bangle formatter for booleans
0.17: Bangle 2: Fast loading on exit to clock face. Added option for exit to
clock face by timeout.
136 changes: 86 additions & 50 deletions apps/dtlaunch/app-b2.js
@@ -1,28 +1,32 @@
{ // must be inside our own scope here so that when we are unloaded everything disappears

/* Desktop launcher
*
*/

var settings = Object.assign({
let settings = Object.assign({
showClocks: true,
showLaunchers: true,
direct: false,
oneClickExit:false,
swipeExit: false
oneClickExit: false,
swipeExit: false,
timeOut: "Off"
}, require('Storage').readJSON("dtlaunch.json", true) || {});

if( settings.oneClickExit)
setWatch(_=> load(), BTN1);

var s = require("Storage");
var apps = s.list(/\.info$/).map(app=>{
var a=s.readJSON(app,1);
if (settings.oneClickExit) {
var buttonWatch = setWatch(_=> returnToClock(), BTN1, {edge: 'falling'});
}

let s = require("Storage");
var 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=="launch" && settings.showLaunchers) || !app.type));

apps.sort((a,b)=>{
var n=(0|a.sortorder)-(0|b.sortorder);
let 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;
Expand All @@ -33,29 +37,28 @@ apps.forEach(app=>{
app.icon = s.read(app.icon); // should just be a link to a memory area
});

var Napps = apps.length;
var Npages = Math.ceil(Napps/4);
var maxPage = Npages-1;
var selected = -1;
var oldselected = -1;
var page = 0;
let Napps = apps.length;
let Npages = Math.ceil(Napps/4);
let maxPage = Npages-1;
let selected = -1;
let oldselected = -1;
let page = 0;
const XOFF = 24;
const YOFF = 30;

function draw_icon(p,n,selected) {
var x = (n%2)*72+XOFF;
var y = n>1?72+YOFF:YOFF;
let drawIcon= function(p,n,selected) {
let x = (n%2)*72+XOFF;
let y = n>1?72+YOFF:YOFF;
(selected?g.setColor(g.theme.fgH):g.setColor(g.theme.bg)).fillRect(x+11,y+3,x+60,y+52);
g.clearRect(x+12,y+4,x+59,y+51);
g.setColor(g.theme.fg);
try{g.drawImage(apps[p*4+n].icon,x+12,y+4);} catch(e){}
g.setFontAlign(0,-1,0).setFont("6x8",1);
var txt = apps[p*4+n].name.replace(/([a-z])([A-Z])/g, "$1 $2").split(" ");
var lineY = 0;
var line = "";
while (txt.length > 0){
var c = txt.shift();

let txt = apps[p*4+n].name.replace(/([a-z])([A-Z])/g, "$1 $2").split(" ");
let lineY = 0;
let line = "";
while (txt.length > 0){
let c = txt.shift();
if (c.length + 1 + line.length > 13){
if (line.length > 0){
g.drawString(line.trim(),x+36,y+54+lineY*8);
Expand All @@ -67,54 +70,60 @@ function draw_icon(p,n,selected) {
}
}
g.drawString(line.trim(),x+36,y+54+lineY*8);
}
};

function drawPage(p){
let drawPage = function(p){
thyttan marked this conversation as resolved.
Show resolved Hide resolved
g.reset();
g.clearRect(0,24,175,175);
var O = 88+YOFF/2-12*(Npages/2);
for (var j=0;j<Npages;j++){
var y = O+j*12;
let O = 88+YOFF/2-12*(Npages/2);
for (let j=0;j<Npages;j++){
let y = O+j*12;
g.setColor(g.theme.fg);
if (j==page) g.fillCircle(XOFF/2,y,4);
else g.drawCircle(XOFF/2,y,4);
}
for (var i=0;i<4;i++) {
for (let i=0;i<4;i++) {
if (!apps[p*4+i]) return i;
draw_icon(p,i,selected==i && !settings.direct);
drawIcon(p,i,selected==i && !settings.direct);
}
g.flip();
}
};

Bangle.loadWidgets();
//g.clear();
Bangle.drawWidgets();
drawPage(0);

Bangle.on("swipe",(dirLeftRight, dirUpDown)=>{
let swipeListenerDt = function(dirLeftRight, dirUpDown){
selected = 0;
oldselected=-1;
if(settings.swipeExit && dirLeftRight==1) load();
if(settings.swipeExit && dirLeftRight==1) returnToClock();
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);
}
});
};
Bangle.on("swipe",swipeListenerDt);

function isTouched(p,n){
let isTouched = function(p,n){
if (n<0 || n>3) return false;
var x1 = (n%2)*72+XOFF; var y1 = n>1?72+YOFF:YOFF;
var x2 = x1+71; var y2 = y1+81;
let x1 = (n%2)*72+XOFF; let y1 = n>1?72+YOFF:YOFF;
let x2 = x1+71; let y2 = y1+81;
return (p.x>x1 && p.y>y1 && p.x<x2 && p.y<y2);
}
};

Bangle.on("touch",(_,p)=>{
var i;
let touchListenerDt = function(_,p){
let i;
for (i=0;i<4;i++){
if((page*4+i)<Napps){
if (isTouched(p,i)) {
draw_icon(page,i,true && !settings.direct);
drawIcon(page,i,true && !settings.direct);
if (selected>=0 || settings.direct) {
if (selected!=i && !settings.direct){
draw_icon(page,selected,false);
drawIcon(page,selected,false);
} else {
load(apps[page*4+i].src);
}
Expand All @@ -125,12 +134,39 @@ Bangle.on("touch",(_,p)=>{
}
}
if ((i==4 || (page*4+i)>Napps) && selected>=0) {
draw_icon(page,selected,false);
drawIcon(page,selected,false);
selected=-1;
}
});
};
Bangle.on("touch",touchListenerDt);

Bangle.loadWidgets();
g.clear();
Bangle.drawWidgets();
drawPage(0);
const returnToClock = function() {
Bangle.setUI();
if (buttonWatch) {
clearWatch(buttonWatch);
delete buttonWatch;
}
if (timeoutToClock) {
clearTimeout(timeoutToClock);
delete timeoutToClock;
}
Bangle.removeListener("swipe", swipeListenerDt);
Bangle.removeListener("touch", touchListenerDt);
var apps = [];
delete apps;
delete returnToClock;
setTimeout(eval, 0, s.read(".bootcde"));
};

// taken from Icon Launcher with minor alterations
var 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(returnToClock,time*1000);
}
};
updateTimeoutToClock();

} // end of app scope
2 changes: 1 addition & 1 deletion apps/dtlaunch/metadata.json
@@ -1,7 +1,7 @@
{
"id": "dtlaunch",
"name": "Desktop Launcher",
"version": "0.16",
"version": "0.17",
"description": "Desktop style App Launcher with six (four for Bangle 2) apps per page - fast access if you have lots of apps installed.",
"screenshots": [{"url":"shot1.png"},{"url":"shot2.png"},{"url":"shot3.png"}],
"icon": "icon.png",
Expand Down
31 changes: 22 additions & 9 deletions apps/dtlaunch/settings-b2.js
Expand Up @@ -6,50 +6,63 @@
showLaunchers: true,
direct: false,
oneClickExit:false,
swipeExit: false
swipeExit: false,
timeOut: "Off"
}, require('Storage').readJSON(FILE, true) || {});

function writeSettings() {
require('Storage').writeJSON(FILE, settings);
}

const timeOutChoices = [/*LANG*/"Off", "10s", "15s", "20s", "30s"];

E.showMenu({
"" : { "title" : "Desktop launcher" },
"< Back" : () => back(),
'Show clocks': {
/*LANG*/"< Back" : () => back(),
/*LANG*/'Show clocks': {
value: settings.showClocks,
onchange: v => {
settings.showClocks = v;
writeSettings();
}
},
'Show launchers': {
/*LANG*/'Show launchers': {
value: settings.showLaunchers,
onchange: v => {
settings.showLaunchers = v;
writeSettings();
}
},
'Direct launch': {
/*LANG*/'Direct launch': {
value: settings.direct,
onchange: v => {
settings.direct = v;
writeSettings();
}
},
'Swipe Exit': {
/*LANG*/'Swipe Exit': {
value: settings.swipeExit,
onchange: v => {
settings.swipeExit = v;
writeSettings();
}
},
'One click exit': {
/*LANG*/'One click exit': {
value: settings.oneClickExit,
onchange: v => {
settings.oneClickExit = v;
writeSettings();
}
}
},
/*LANG*/'Time Out': { // Adapted from Icon Launcher
value: timeOutChoices.indexOf(settings.timeOut),
min: 0,
max: timeOutChoices.length-1,
format: v => timeOutChoices[v],
onchange: v => {
settings.timeOut = timeOutChoices[v];
writeSettings();
}
},
});
})
});