Massive refactor - Make all clocks responsible for loading widgets if they want them, and for loading the launcher on BTN2.

Also make bootloader try and polyfill missing stuff from 2v04
master
Gordon Williams 2020-01-17 11:43:26 +00:00
parent b4b882d523
commit 95d4c710bc
50 changed files with 1239 additions and 1207 deletions

View File

@ -185,7 +185,7 @@ about the app.
"name": "Readable name", // readable name "name": "Readable name", // readable name
"icon": "icon.png", // icon in apps/ "icon": "icon.png", // icon in apps/
"description": "...", // long description "description": "...", // long description
"type":"...", // optional(if app) - 'app' or 'widget' "type":"...", // optional(if app) - 'app'/'widget'/'launch'
"tags": "", // comma separated tag list for searching "tags": "", // comma separated tag list for searching
"custom": "custom.html", // if supplied, apps/custom.html is loaded in an "custom": "custom.html", // if supplied, apps/custom.html is loaded in an
@ -210,7 +210,7 @@ about the app.
``` ```
* name, icon and description present the app in the app loader. * name, icon and description present the app in the app loader.
* tags is used for grouping apps in the library, separate multiple entries by comma. Known tags are `tool`, `system`, `clock`, `game`, `sound`, `gps`, `widget` or empty. * tags is used for grouping apps in the library, separate multiple entries by comma. Known tags are `tool`, `system`, `clock`, `game`, `sound`, `gps`, `widget`, `launcher` or empty.
* storage is used to identify the app files and how to handle them * storage is used to identify the app files and how to handle them
## Coding hints ## Coding hints

View File

@ -6,7 +6,21 @@
"description": "This is needed by Bangle.js to automatically load the clock, menu, widgets and settings", "description": "This is needed by Bangle.js to automatically load the clock, menu, widgets and settings",
"tags": "tool,system", "tags": "tool,system",
"storage": [ "storage": [
{"name":".bootcde","url":"bootloader.js"} {"name":".boot0","url":"boot0.js"},
{"name":".bootcde","url":"bootloader.js"},
{"name":"+boot","url":"bootloader.json"}
],
"sortorder" : -10
},
{ "id": "launch",
"name": "Launcher",
"icon": "app.png",
"version":"0.01",
"description": "This is needed by Bangle.js to display a menu allowing you to choose your own applications. You can replace this with a customised launcher.",
"tags": "tool,system,launcher",
"storage": [
{"name":"+launch","url":"app.json"},
{"name":"-launch","url":"app.js"}
], ],
"sortorder" : -10 "sortorder" : -10
}, },
@ -26,7 +40,7 @@
{ "id": "mclock", { "id": "mclock",
"name": "Morphing Clock", "name": "Morphing Clock",
"icon": "clock-morphing.png", "icon": "clock-morphing.png",
"version":"0.01", "version":"0.02",
"description": "7 segment clock that morphs between minutes and hours", "description": "7 segment clock that morphs between minutes and hours",
"tags": "clock", "tags": "clock",
"type":"clock", "type":"clock",
@ -56,7 +70,7 @@
{ "id": "wclock", { "id": "wclock",
"name": "Word Clock", "name": "Word Clock",
"icon": "clock-word.png", "icon": "clock-word.png",
"version":"0.01", "version":"0.02",
"description": "Display Time as Text", "description": "Display Time as Text",
"tags": "clock", "tags": "clock",
"type":"clock", "type":"clock",
@ -70,7 +84,7 @@
{ "id": "aclock", { "id": "aclock",
"name": "Analog Clock", "name": "Analog Clock",
"icon": "clock-analog.png", "icon": "clock-analog.png",
"version":"0.01", "version":"0.02",
"description": "An Analog Clock", "description": "An Analog Clock",
"tags": "clock", "tags": "clock",
"type":"clock", "type":"clock",
@ -84,7 +98,7 @@
{ "id": "clck3x2", { "id": "clck3x2",
"name": "3x2 Pixel Clock", "name": "3x2 Pixel Clock",
"icon": "clock3x2.png", "icon": "clock3x2.png",
"version":"0.01", "version":"0.02",
"description": "This is a simple clock using minimalistic 3x2 pixel numerical digits", "description": "This is a simple clock using minimalistic 3x2 pixel numerical digits",
"tags": "clock", "tags": "clock",
"storage": [ "storage": [
@ -359,17 +373,20 @@
{"name":"=route"} {"name":"=route"}
] ]
}, },
{ {
"id": "start", "id": "ncstart",
"name": "NCEU Startup", "name": "NCEU Startup",
"icon": "start.png", "icon": "start.png",
"version":"0.01", "version":"0.02",
"description": "NodeConfEU 2019 Startup Sequence", "description": "NodeConfEU 2019 'First Start' Sequence",
"tags": "start", "tags": "start",
"storage": [ "storage": [
{"name":"+start","url":"start.json"}, {"name":"+ncstart","url":"start.json"},
{"name":"-start","url":"start.js"}, {"name":".boot3","url":"start.js"},
{"name":"*start","url":"start-icon.js","evaluate":true}, {"name":"*ncstart","url":"start-icon.js","evaluate":true},
{"name":"*bangle","url":"start-bangle.js","evaluate":true}, {"name":"*bangle","url":"start-bangle.js","evaluate":true},
{"name":"*nceu","url":"start-nceu.js","evaluate":true}, {"name":"*nceu","url":"start-nceu.js","evaluate":true},
{"name":"*nfr","url":"start-nfr.js","evaluate":true}, {"name":"*nfr","url":"start-nfr.js","evaluate":true},
@ -378,16 +395,16 @@
], ],
"sortorder" : -1 "sortorder" : -1
}, },
{ "id": "funrun5", { "id": "ncfrun",
"name": "NCEU 5K Fun Run", "name": "NCEU 5K Fun Run",
"icon": "nceu-funrun.png", "icon": "nceu-funrun.png",
"version":"0.01", "version":"0.01",
"description": "Display a map of the NodeConf EU 2019 5K Fun Run route and your location on it", "description": "Display a map of the NodeConf EU 2019 5K Fun Run route and your location on it",
"tags": "health", "tags": "health",
"storage": [ "storage": [
{"name":"+funrun5","url":"nceu-funrun.json"}, {"name":"+ncfrun","url":"nceu-funrun.json"},
{"name":"-funrun5","url":"nceu-funrun.js"}, {"name":"-ncfrun","url":"nceu-funrun.js"},
{"name":"*funrun5","url":"nceu-funrun-icon.js","evaluate":true} {"name":"*ncfrun","url":"nceu-funrun-icon.js","evaluate":true}
], ],
"sortorder" : -1 "sortorder" : -1
}, },
@ -404,10 +421,13 @@
], ],
"sortorder" : -1 "sortorder" : -1
}, },
{ "id": "sclock", { "id": "sclock",
"name": "Simple Clock", "name": "Simple Clock",
"icon": "clock-simple.png", "icon": "clock-simple.png",
"version":"0.01", "version":"0.02",
"description": "Simple Digital Clock", "description": "Simple Digital Clock",
"tags": "clock", "tags": "clock",
"type":"clock", "type":"clock",
@ -421,7 +441,7 @@
{ "id": "stclck", { "id": "stclck",
"name": "Simple 12H Clock", "name": "Simple 12H Clock",
"icon": "clock-simple.png", "icon": "clock-simple.png",
"version":"0.01", "version":"0.02",
"description": "Simple Digital 12-Hour Clock", "description": "Simple Digital 12-Hour Clock",
"tags": "clock", "tags": "clock",
"type":"clock", "type":"clock",
@ -543,7 +563,7 @@
{ "id": "miclock", { "id": "miclock",
"name": "Mixed Clock", "name": "Mixed Clock",
"icon": "clock-mixed.png", "icon": "clock-mixed.png",
"version":"0.01", "version":"0.02",
"description": "A mix of analog and digital Clock", "description": "A mix of analog and digital Clock",
"tags": "clock", "tags": "clock",
"type":"clock", "type":"clock",
@ -557,7 +577,7 @@
{ "id": "bclock", { "id": "bclock",
"name": "Binary Clock", "name": "Binary Clock",
"icon": "clock-binary.png", "icon": "clock-binary.png",
"version":"0.01", "version":"0.02",
"description": "A simple binary clock watch face", "description": "A simple binary clock watch face",
"tags": "clock", "tags": "clock",
"type":"clock", "type":"clock",
@ -625,9 +645,9 @@
] ]
}, },
{ "id": "blobclk", { "id": "blobclk",
"name": "Large Digit Clock", "name": "Large Digit Blob Clock",
"icon": "clock-blob.png", "icon": "clock-blob.png",
"version":"0.02", "version":"0.03",
"description": "A clock with big digits", "description": "A clock with big digits",
"tags": "clock", "tags": "clock",
"type":"clock", "type":"clock",
@ -641,7 +661,7 @@
{ "id": "boldclk", { "id": "boldclk",
"name": "Bold Clock", "name": "Bold Clock",
"icon": "bold_clock.png", "icon": "bold_clock.png",
"version":"0.01", "version":"0.02",
"description": "Simple, readable and practical clock", "description": "Simple, readable and practical clock",
"tags": "clock", "tags": "clock",
"type":"clock", "type":"clock",
@ -679,6 +699,7 @@
{ "id": "berlinc", { "id": "berlinc",
"name": "Berlin Clock", "name": "Berlin Clock",
"icon": "berlin-clock.png", "icon": "berlin-clock.png",
"version":"0.02",
"description": "Berlin Clock (see https://en.wikipedia.org/wiki/Mengenlehreuhr)", "description": "Berlin Clock (see https://en.wikipedia.org/wiki/Mengenlehreuhr)",
"tags": "clock", "tags": "clock",
"type":"clock", "type":"clock",
@ -692,7 +713,7 @@
{ "id": "ctrclk", { "id": "ctrclk",
"name": "Centerclock", "name": "Centerclock",
"icon": "app.png", "icon": "app.png",
"version":"0.01", "version":"0.02",
"description": "Watch-centered digital 24h clock with date in dd.mm.yyyy format.", "description": "Watch-centered digital 24h clock with date in dd.mm.yyyy format.",
"tags": "clock", "tags": "clock",
"type":"clock", "type":"clock",

View File

@ -1,16 +1,12 @@
(() => {
// place your const, vars, functions or classes here // place your const, vars, functions or classes here
// special function to handle display switch on // special function to handle display switch on
Bangle.on('lcdPower', (on) => { Bangle.on('lcdPower', (on) => {
if (on) { if (on) {
drawWidgets();
// call your app function here // call your app function here
}}); // If you clear the screen, do Bangle.drawWidgets();
}
});
g.clear(); g.clear();
// call your app function here // call your app function here
})();

View File

@ -1,14 +1,13 @@
/* run widgets in their own function scope so they don't interfere with
currently-running apps */
(() => { (() => {
// add the width // add the width
var xpos = WIDGETPOS.tr-<the widget width>; var xpos = WIDGETPOS.tr-24;/*<the widget width>*/;
WIDGETPOS.tr-=<the widget width plus some extra pixel to keep distance to others>; WIDGETPOS.tr-= 28;/* the widget width plus some extra pixel to keep distance to others */;
// draw your widget at xpos // draw your widget at xpos
function draw() { function draw() {
// add your code // add your code
} }
// add your widget // add your widget

1
apps/aclock/ChangeLog Normal file
View File

@ -0,0 +1 @@
0.02: Modified for use with new bootloader and firmware

View File

@ -1,5 +1,3 @@
(function(){
g.clear();
const p = Math.PI/2; const p = Math.PI/2;
const PRad = Math.PI/180; const PRad = Math.PI/180;
@ -53,11 +51,11 @@
function onMinute() { function onMinute() {
g.setColor(0,0,0); g.setColor(0,0,0);
hand(360*minuteDate.getHours()/12, -10, 50); hand(360*(minuteDate.getHours() + (minuteDate.getMinutes()/60))/12, -10, 50);
hand(360*minuteDate.getMinutes()/60, -10, 82); hand(360*minuteDate.getMinutes()/60, -10, 82);
minuteDate = new Date(); minuteDate = new Date();
g.setColor(1,1,1); g.setColor(1,1,1);
hand(360*minuteDate.getHours()/12, -10, 50); hand(360*(minuteDate.getHours() + (minuteDate.getMinutes()/60))/12, -10, 50);
hand(360*minuteDate.getMinutes()/60, -10, 82); hand(360*minuteDate.getMinutes()/60, -10, 82);
if(minuteDate.getHours() >= 0 && minuteDate.getMinutes() === 0) { if(minuteDate.getHours() >= 0 && minuteDate.getMinutes() === 0) {
Bangle.buzz(); Bangle.buzz();
@ -77,16 +75,20 @@
drawAll(); drawAll();
} }
startTimers();
Bangle.on('lcdPower',function(on) { Bangle.on('lcdPower',function(on) {
if (on) { if (on) {
g.clear(); g.clear();
drawWidgets(); Bangle.drawWidgets();
startTimers(); startTimers();
}else { }else {
clearTimers(); clearTimers();
} }
}); });
})(); g.clear();
Bangle.loadWidgets();
Bangle.drawWidgets();
drawAll();
startTimers();
// Show launcher when middle button pressed
setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"});

1
apps/bclock/ChangeLog Normal file
View File

@ -0,0 +1 @@
0.02: Modified for use with new bootloader and firmware

View File

@ -1,4 +1,3 @@
(() => {
const canvasWidth = 290; const canvasWidth = 290;
const numberOfColumns = 6; const numberOfColumns = 6;
const drawFullGrid = false; const drawFullGrid = false;
@ -102,5 +101,9 @@
}); });
g.clear(); g.clear();
Bangle.loadWidgets();
Bangle.drawWidgets();
setInterval(() => { drawClock(); }, 1000); setInterval(() => { drawClock(); }, 1000);
})(); drawClock();
// Show launcher when middle button pressed
setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"});

1
apps/berlinc/ChangeLog Normal file
View File

@ -0,0 +1 @@
0.02: Modified for use with new bootloader and firmware

View File

@ -1,5 +1,3 @@
(() => {
// place your const, vars, functions or classes here // place your const, vars, functions or classes here
fields = [ 4 , 4 , 11 , 4 ]; fields = [ 4 , 4 , 11 , 4 ];
width = g.getWidth(); width = g.getWidth();
@ -49,17 +47,19 @@
// special function to handle display switch on // special function to handle display switch on
Bangle.on('lcdPower', (on) => { Bangle.on('lcdPower', (on) => {
g.clear();
if (on) { if (on) {
drawWidgets(); Bangle.drawWidgets();
// call your app function here // call your app function here
drawBerlinClock(); drawBerlinClock();
}}); }});
// call your app function here
// refesh every 15 sec // refesh every 15 sec
setInterval(drawBerlinClock, 15E3); setInterval(drawBerlinClock, 15E3);
g.clear();
Bangle.loadWidgets();
Bangle.drawWidgets();
drawBerlinClock(); drawBerlinClock();
// Show launcher when middle button pressed
})(); setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"});

View File

@ -1,3 +1,4 @@
0.02: Improve performance when screen wakes 0.02: Improve performance when screen wakes
Only draw widgets after clearing screen - they update automatically Only draw widgets after clearing screen - they update automatically
Remove 'faceUp' check as it's automatic Remove 'faceUp' check as it's automatic
0.03: Modified for use with new bootloader and firmware

View File

@ -1,4 +1,3 @@
(function(){
const buf = Graphics.createArrayBuffer(144,200,1,{msb:true}); const buf = Graphics.createArrayBuffer(144,200,1,{msb:true});
const NUMBERS = [ const NUMBERS = [
[1,1,1,1,3,1,1,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1],//0 [1,1,1,1,3,1,1,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1],//0
@ -87,10 +86,11 @@
} }
function startTimers() { function startTimers() {
g.clear(); g.clear();
try { if (drawWidgets) { drawWidgets();} } catch(err) {} Bangle.drawWidgets();
intervalRef = setInterval(redraw,1000); intervalRef = setInterval(redraw,1000);
redraw(); redraw();
} }
Bangle.loadWidgets();
startTimers(); startTimers();
Bangle.on('lcdPower',function(on) { Bangle.on('lcdPower',function(on) {
if (on) { if (on) {
@ -99,4 +99,5 @@
clearTimers(); clearTimers();
} }
}); });
})(); // Show launcher when middle button pressed
setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"});

1
apps/boldclk/ChangeLog Normal file
View File

@ -0,0 +1 @@
0.02: Modified for use with new bootloader and firmware

View File

@ -1,5 +1,3 @@
(() => {
// https://www.espruino.com/Image+Converter
var hour_hand = { var hour_hand = {
width : 61, height : 8, bpp : 1, width : 61, height : 8, bpp : 1,
transparent : 0, transparent : 0,
@ -123,7 +121,7 @@
Bangle.on('lcdPower', (on) => { Bangle.on('lcdPower', (on) => {
if (on) { if (on) {
//console.log("lcdPower: on"); //console.log("lcdPower: on");
try { if (drawWidgets) { drawWidgets();} } catch(err) {} Bangle.drawWidgets();
startTimers(); startTimers();
} else { } else {
//console.log("lcdPower: off"); //console.log("lcdPower: off");
@ -140,7 +138,8 @@
}); });
g.clear(); g.clear();
//Bangle.setLCDPower(true); Bangle.loadWidgets();
Bangle.drawWidgets();
startTimers(); startTimers();
// Show launcher when middle button pressed
})(); setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"});

42
apps/boot/boot0.js Normal file
View File

@ -0,0 +1,42 @@
// This ALWAYS runs at boot
E.setFlags({pretokenise:1});
// All of this is just shim for older Bangles
if (!Bangle.loadWidgets) {
Bangle.loadWidgets = function(){
global.WIDGETPOS={tl:32,tr:g.getWidth()-32,bl:32,br:g.getWidth()-32};
global.WIDGETS={};
require("Storage").list().filter(a=>a[0]=='=').forEach(widget=>eval(require("Storage").read(widget)));
};
Bangle.drawWidgets = function(){
for(var w of WIDGETS)w.draw()
};
Bangle.showLauncher = function(){
var l = require("Storage").list().filter(a=>a[0]=='+').map(app=>{
try { return require("Storage").readJSON(app); } catch (e) {}
}).find(app=>app.type=="launch");
if (l) load(l.src);
else E.showMessage("Launcher\nnot found");
};
var _load = load;
global.load = function(x) {
if (!x) _load(x);
else setTimeout(function(){
// attempt to remove any currently-running code
delete Bangle.buzz;
delete Bangle.beep;
Bangle.setLCDOffset&&Bangle.setLCDOffset(0);
Bangle.setLCDMode("direct");
g.clear();
clearInterval();
clearWatch();
Bangle.removeAllListeners();
NRF.removeAllListeners();
Bluetooth.removeAllListeners();
E.removeAllListeners();
delete GB;
delete WIDGETS;
delete WIDGETPOS;
setTimeout('eval(require("Storage").read("'+x+'"));',20);
},20);
}
}

View File

@ -1,117 +1,10 @@
E.setFlags({pretokenise:1}); // This runs after a 'fresh' boot
var startapp;
try {
startapp = require('Storage').readJSON('+start');
} catch (e) {}
if (startapp) {
eval(require("Storage").read(startapp.src));
} else {
setWatch(function displayMenu() {
Bangle.setLCDOffset(0); // remove notifications
Bangle.setLCDMode("direct");
g.clear();
// attempt to remove any currently-running code
clearInterval();
clearWatch();
Bangle.removeAllListeners();
NRF.removeAllListeners();
Bluetooth.removeAllListeners();
E.removeAllListeners();
delete GB;
delete WIDGETS;
delete WIDGETPOS;
delete drawWidgets;
var s = require("Storage");
var apps = s.list().filter(a=>a[0]=='+').map(app=>{
try { return s.readJSON(app); }
catch (e) { return {name:"DEAD: "+app.substr(1)} }
}).filter(app=>app.type=="app" || app.type=="clock" || !app.type);
apps.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;
});
var selected = 0;
var menuScroll = 0;
var menuShowing = false;
function drawMenu() {
g.setFont("6x8",2);
g.setFontAlign(-1,0);
var n = 3;
if (selected>=n+menuScroll) menuScroll = 1+selected-n;
if (selected<menuScroll) menuScroll = selected;
if (menuScroll) g.fillPoly([120,0,100,20,140,20]);
else g.clearRect(100,0,140,20);
if (apps.length>n+menuScroll) g.fillPoly([120,239,100,219,140,219]);
else g.clearRect(100,219,140,239);
for (var i=0;i<n;i++) {
var app = apps[i+menuScroll];
if (!app) break;
var y = 24+i*64;
if (i+menuScroll==selected) {
g.setColor(0.3,0.3,0.3);
g.fillRect(0,y,239,y+63);
g.setColor(1,1,1);
g.drawRect(0,y,239,y+63);
} else
g.clearRect(0,y,239,y+63);
g.drawString(app.name,64,y+32);
var icon=undefined;
if (app.icon) icon = s.read(app.icon);
if (icon) try {g.drawImage(icon,8,y+8);} catch(e){}
}
}
drawMenu();
setWatch(function() {
if (selected>0) {
selected--;
drawMenu();
}
}, BTN1, {repeat:true});
setWatch(function() {
if (selected+1<apps.length) {
selected++;
drawMenu();
}
}, BTN3, {repeat:true});
setWatch(function() { // run
if (!apps[selected].src) return;
clearWatch();
g.clear(1);
g.setFont("6x8",2);
g.setFontAlign(0,0);
g.drawString("Loading...",120,120);
// if clock, just set the default setting and restart
if (apps[selected].type=="clock") {
try {
var settings = require("Storage").readJSON('@setting');
settings.clock = apps[selected].src;
require("Storage").write('@setting',settings);
} catch (e) { }
load();
} else {
// load like this so we ensure we've cleared out our RAM
setTimeout(process.memory,10); // force GC
setTimeout('eval(require("Storage").read("'+apps[selected].src+'"));',20);
}
}, BTN2, {repeat:true,edge:"falling"});
}, BTN2, {repeat:false,edge:"falling"}); // menu on middle button
var WIDGETPOS={tl:32,tr:g.getWidth()-32,bl:32,br:g.getWidth()-32};
var WIDGETS={};
function drawWidgets() { for (var w of WIDGETS) w.draw(); }
var settings; var settings;
try { try {
settings = require("Storage").readJSON('@setting'); settings = require("Storage").readJSON('@setting');
} catch (e) { } catch (e) {
settings = {} settings = {}
} }
// load widgets
require("Storage").list().filter(a=>a[0]=='=').forEach(widget=>eval(require("Storage").read(widget)));
setTimeout(drawWidgets,100);
// load clock if specified // load clock if specified
var clockApp = settings.clock; var clockApp = settings.clock;
if (clockApp) clockApp = require("Storage").read(clockApp) if (clockApp) clockApp = require("Storage").read(clockApp)
@ -127,4 +20,3 @@ if (startapp) {
if (clockApp) eval(clockApp); if (clockApp) eval(clockApp);
else E.showMessage("No Clock Found"); else E.showMessage("No Clock Found");
delete clockApp; delete clockApp;
}

View File

@ -0,0 +1,3 @@
{
"name":"Bootloader","type":"boot"
}

1
apps/clck3x2/ChangeLog Normal file
View File

@ -0,0 +1 @@
0.02: Modified for use with new bootloader and firmware

View File

@ -1,5 +1,3 @@
(function(){
const ox=10; // x offset const ox=10; // x offset
const oy=80; const oy=80;
const pw=20; // pixel width const pw=20; // pixel width
@ -60,7 +58,7 @@
function drawTime() { function drawTime() {
g.clear(); g.clear();
drawWidgets(); Bangle.drawWidgets();
let d = Date(); let d = Date();
let h = d.getHours(); let h = d.getHours();
@ -82,12 +80,6 @@
idTimeout = setTimeout(drawTime, delta); idTimeout = setTimeout(drawTime, delta);
} }
Bangle.on('gesture', function(gesture) {
if (gesture && !Bangle.isLCDOn()) {
Bangle.setLCDPower(true);
}
});
// special function to handle display switch on // special function to handle display switch on
Bangle.on('lcdPower', function(on){ Bangle.on('lcdPower', function(on){
if (on) { if (on) {
@ -99,6 +91,7 @@
} }
}); });
Bangle.loadWidgets();
drawTime(); drawTime();
// Show launcher when middle button pressed
})(); setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"});

1
apps/ctrclk/ChangeLog Normal file
View File

@ -0,0 +1 @@
0.02: Modified for use with new bootloader and firmware

View File

@ -1,4 +1,3 @@
(function () {
let bigCustomFont = [ let bigCustomFont = [
atob( atob(
'AAAA/+AAAAAAB///wAAAAB////8AAAA/////+AAAP/////8AAD//////8AAf/8AAf/8AD/8AAAH/4Af+AAAAD/wD/gAAAAD/gf4AAAAAH+D/AAAAAAP8P4AAAAAAf5/AAAAAAA/n4AAAAAAB+/gAAAAAAH/+AAAAAAAf/wAAAAAAA//AAAAAAAD/8AAAAAAAP/4AAAAAAB//gAAAAAAH9+AAAAAAAfn8AAAAAAD+fwAAAAAAP4/gAAAAAB/D/AAAAAAP8H/AAAAAB/gP+AAAAAf8Af/AAAAH/gA//gAAD/8AB//8AH//gAB//////8AAB//////AAAB/////wAAAA////4AAAAAP//4AAAAAAAAAAAAAAGAAAAAAAAA8AAAAAAAAH8AAAAAAAA/wAAAAAAAH+AAAAAAAA/wAAAAAAAH+AAAAAAAA/wAAAAAAAH////////w/////////H////////8/////////3//////////////////8AAAAAAAAAAAAAAAAAADAAAAAAAAAcQAAAAAAAHzwAAAAAAA/PwAAAAAAH9/AAAAAAB/34AAAAAAP/fgAAAAAD//+AAAAAAf//wAAAAAH///AAAAAA///8AAAAAH///4AAAAB/4//gAAAAP/D/+AAAAD/wP34AAAAf+A/fwAAAD/wD8/gAAA/8APz/AAAH/gA/H+AAB/4AD8f8AAP/AAPw/8AD/wAA/B/+A/+AAD8D////wAAPwH///8AAA/AH///gAAD8AH//4AAAPwAH/+AAAAAAAAAAAAAAD8AAAAAAAAPwAAAAAAAA/AAgAAAAD/8AHAAAAAP/wB8AAAAA//APwAAAAD/8D/AAAAAP/wf8AAAAB//H/wAAAAH/8//gAAAAfv//+AAAAD+///8AAAAP7//fwAAAB/P/w/gAAAP8/+D/AAAB/j/wH+AAAP8P8AP8AAB/w/gAf8AAf+D4AA/8AH/wPAAB////+AwAAD////gCAAAH///8AAAAAH///AAAAAAD//wAAAAAAA/wAAAAAAAAAAAAAAAAAAAQAAAAAAAAHAAAAAAAAD8AAAAAAAA/wAAAAAAAP/AAAAAAAD/8AAAAAAB//wAAAAAAf//AAAAAAH//8AAAAAB//PwAAAAAf/w/AAAAAP/8D8AAAAD//APwAAAA//gA/AAAAP/4AD8AAAH/+AAPwAAB//gAA/AAAf/4AAD8AAH/8AAAPwAD//AAAA/AAP/wAAAD8AA/8AAAAPwAD/AAAAA/gAPgAAA/////4AAAD////+AAAAP////wAAAA/////AAAAD////8AAAAAA/AAAAAAAAD8AAAAAAAAPwAAAAAAAAAAAAAA8AAAAAAAB/wAAAAAAD//AAAAAP///8AAAAA////wAAAAD////AAAAAP///8AAAAA//4PwAAAAH/8A/gAAAAf/wB+AAAAB+/AH4AAAAP78AfwAAAA/vwA/AAAAH8/AD+AAAA/z8AP8AAAD+PwAf4AAAf4/AA/wAAH/D8AD/gAA/4PwAH/gAf/A/AAP/8f/4AAAAf////AAAAAf///wAAAAA///8AAAAAAf//AAAAAAAH/gAAAAAAAAAAAAAAAAH/4AAAAAAP//8AAAAAD///+AAAAB////8AAAAf////8AAAH//8f/4AAA//8AD/wAAP//AAD/gAB//wAAH/AAP/+AAAH+AB//wAAAP4AP/+AAAAfwB//wAAAB/AP9/AAAAD+B/n4AAAAH4H8/gAAAAfg/j8AAAAB/H8PwAAAAH8fw/AAAAAPz+D8AAAAA/P4PwAAAAD9/A/AAAAAf38D8AAAAB/fgP4AAAAH5+A/gAAAAfv4B/AAAAD+/gH8AAAAPz+AP4AAAB/PwA/wAAAP8/AB/gAAB/gAAD/AAAP8AAAP+AAD/gAAAf+AA/8AAAA//gf/gAAAA////8AAAAB////gAAAAB///4AAAAAB//+AAAAAAA//AAAAAAAAAAAAPwAAAAAAAA/AAAAAAAAD8AAAAAAAAfwAAAAAAAP/AAAAAAAH/8AAAAAAD//wAAAAAD///AAAAAB///8AAAAA///vwAAAA///w/AAAAP//wD8AAAP//4APwAAH//8AA/AAD//+AAD8AD//+AAAPwB///AAAA/A///gAAAD8f//wAAAAP///4AAAAA///4AAAAAD//8AAAAAAP/+AAAAAAA/+AAAAAAAD/AAAAAAAAPgAAAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAD/AAAAAAAH//wAAAAAB///wAAAAAf///wAAAAD////wAAAAf////gAAAH/wAf/AAAA/8AAP+AAAD/AAAf8AAAf4AAAf4AAD/AAAA/gB/P4AAAB/A///AAAAH8H//8AAAAP4///gAAAAfn//+AAAAB+f//wAAAAH/+B/AAAAAf/4H8AAAAA//APwAAAAD/8A/AAAAAP/4H8AAAAB/fw/wAAAAH9///gAAAAfj//+AAAAB+P//4AAAAP4P//wAAAA/gf//gAAAH8APD/AAAA/wAAH8AAAH+AAAf8AAA/wAAA/4AAH/AAAB/4AB/4AAAD/8A//AAAAH////wAAAAP///+AAAAAP///gAAAAAP//4AAAAAAH/+AAAAAAAAAAAAAAA/wAAAAAAA//8AAAAAAP//+AAAAAD///8AAAAA////8AAAAH////4AAAA/+AD/wAAAH/AAD/gAAA/4AAD/AAAH+AAAH+AAAfwAAAP8APz+AAAAfwA/P4AAAA/gH9/AAAAD+Af34AAAAH4B+fgAAAAfwH7+AAAAA/A/v4AAAAD8D+/AAAAAPwPz8AAAAA/B/PwAAAAD8P8/gAAAAPw/j+AAAAA/H8H4AAAAH8/wfgAAAAf3+B/AAAAB+fwH8AAAAP//AP4AAAB//4A/wAAAH//AB/gAAA//4AD/AAAP//AAH+AAB//wAAf+AAf/+AAAf/AP//gAAA/////8AAAB/////AAAAB////wAAAAB///4AAAAAB//4AAAAAAAAAAAAAAA='), 'AAAA/+AAAAAAB///wAAAAB////8AAAA/////+AAAP/////8AAD//////8AAf/8AAf/8AD/8AAAH/4Af+AAAAD/wD/gAAAAD/gf4AAAAAH+D/AAAAAAP8P4AAAAAAf5/AAAAAAA/n4AAAAAAB+/gAAAAAAH/+AAAAAAAf/wAAAAAAA//AAAAAAAD/8AAAAAAAP/4AAAAAAB//gAAAAAAH9+AAAAAAAfn8AAAAAAD+fwAAAAAAP4/gAAAAAB/D/AAAAAAP8H/AAAAAB/gP+AAAAAf8Af/AAAAH/gA//gAAD/8AB//8AH//gAB//////8AAB//////AAAB/////wAAAA////4AAAAAP//4AAAAAAAAAAAAAAGAAAAAAAAA8AAAAAAAAH8AAAAAAAA/wAAAAAAAH+AAAAAAAA/wAAAAAAAH+AAAAAAAA/wAAAAAAAH////////w/////////H////////8/////////3//////////////////8AAAAAAAAAAAAAAAAAADAAAAAAAAAcQAAAAAAAHzwAAAAAAA/PwAAAAAAH9/AAAAAAB/34AAAAAAP/fgAAAAAD//+AAAAAAf//wAAAAAH///AAAAAA///8AAAAAH///4AAAAB/4//gAAAAP/D/+AAAAD/wP34AAAAf+A/fwAAAD/wD8/gAAA/8APz/AAAH/gA/H+AAB/4AD8f8AAP/AAPw/8AD/wAA/B/+A/+AAD8D////wAAPwH///8AAA/AH///gAAD8AH//4AAAPwAH/+AAAAAAAAAAAAAAD8AAAAAAAAPwAAAAAAAA/AAgAAAAD/8AHAAAAAP/wB8AAAAA//APwAAAAD/8D/AAAAAP/wf8AAAAB//H/wAAAAH/8//gAAAAfv//+AAAAD+///8AAAAP7//fwAAAB/P/w/gAAAP8/+D/AAAB/j/wH+AAAP8P8AP8AAB/w/gAf8AAf+D4AA/8AH/wPAAB////+AwAAD////gCAAAH///8AAAAAH///AAAAAAD//wAAAAAAA/wAAAAAAAAAAAAAAAAAAAQAAAAAAAAHAAAAAAAAD8AAAAAAAA/wAAAAAAAP/AAAAAAAD/8AAAAAAB//wAAAAAAf//AAAAAAH//8AAAAAB//PwAAAAAf/w/AAAAAP/8D8AAAAD//APwAAAA//gA/AAAAP/4AD8AAAH/+AAPwAAB//gAA/AAAf/4AAD8AAH/8AAAPwAD//AAAA/AAP/wAAAD8AA/8AAAAPwAD/AAAAA/gAPgAAA/////4AAAD////+AAAAP////wAAAA/////AAAAD////8AAAAAA/AAAAAAAAD8AAAAAAAAPwAAAAAAAAAAAAAA8AAAAAAAB/wAAAAAAD//AAAAAP///8AAAAA////wAAAAD////AAAAAP///8AAAAA//4PwAAAAH/8A/gAAAAf/wB+AAAAB+/AH4AAAAP78AfwAAAA/vwA/AAAAH8/AD+AAAA/z8AP8AAAD+PwAf4AAAf4/AA/wAAH/D8AD/gAA/4PwAH/gAf/A/AAP/8f/4AAAAf////AAAAAf///wAAAAA///8AAAAAAf//AAAAAAAH/gAAAAAAAAAAAAAAAAH/4AAAAAAP//8AAAAAD///+AAAAB////8AAAAf////8AAAH//8f/4AAA//8AD/wAAP//AAD/gAB//wAAH/AAP/+AAAH+AB//wAAAP4AP/+AAAAfwB//wAAAB/AP9/AAAAD+B/n4AAAAH4H8/gAAAAfg/j8AAAAB/H8PwAAAAH8fw/AAAAAPz+D8AAAAA/P4PwAAAAD9/A/AAAAAf38D8AAAAB/fgP4AAAAH5+A/gAAAAfv4B/AAAAD+/gH8AAAAPz+AP4AAAB/PwA/wAAAP8/AB/gAAB/gAAD/AAAP8AAAP+AAD/gAAAf+AA/8AAAA//gf/gAAAA////8AAAAB////gAAAAB///4AAAAAB//+AAAAAAA//AAAAAAAAAAAAPwAAAAAAAA/AAAAAAAAD8AAAAAAAAfwAAAAAAAP/AAAAAAAH/8AAAAAAD//wAAAAAD///AAAAAB///8AAAAA///vwAAAA///w/AAAAP//wD8AAAP//4APwAAH//8AA/AAD//+AAD8AD//+AAAPwB///AAAA/A///gAAAD8f//wAAAAP///4AAAAA///4AAAAAD//8AAAAAAP/+AAAAAAA/+AAAAAAAD/AAAAAAAAPgAAAAAAAAwAAAAAAAAAAAAAAAAAAAAAAAD/AAAAAAAH//wAAAAAB///wAAAAAf///wAAAAD////wAAAAf////gAAAH/wAf/AAAA/8AAP+AAAD/AAAf8AAAf4AAAf4AAD/AAAA/gB/P4AAAB/A///AAAAH8H//8AAAAP4///gAAAAfn//+AAAAB+f//wAAAAH/+B/AAAAAf/4H8AAAAA//APwAAAAD/8A/AAAAAP/4H8AAAAB/fw/wAAAAH9///gAAAAfj//+AAAAB+P//4AAAAP4P//wAAAA/gf//gAAAH8APD/AAAA/wAAH8AAAH+AAAf8AAA/wAAA/4AAH/AAAB/4AB/4AAAD/8A//AAAAH////wAAAAP///+AAAAAP///gAAAAAP//4AAAAAAH/+AAAAAAAAAAAAAAA/wAAAAAAA//8AAAAAAP//+AAAAAD///8AAAAA////8AAAAH////4AAAA/+AD/wAAAH/AAD/gAAA/4AAD/AAAH+AAAH+AAAfwAAAP8APz+AAAAfwA/P4AAAA/gH9/AAAAD+Af34AAAAH4B+fgAAAAfwH7+AAAAA/A/v4AAAAD8D+/AAAAAPwPz8AAAAA/B/PwAAAAD8P8/gAAAAPw/j+AAAAA/H8H4AAAAH8/wfgAAAAf3+B/AAAAB+fwH8AAAAP//AP4AAAB//4A/wAAAH//AB/gAAA//4AD/AAAP//AAH+AAB//wAAf+AAf/+AAAf/AP//gAAA/////8AAAB/////AAAAB////wAAAAB///4AAAAAB//4AAAAAAAAAAAAAAA='),
@ -150,14 +149,15 @@
} }
start(); start();
Bangle.loadWidgets();
Bangle.drawWidgets();
Bangle.on('lcdPower', function (on) { Bangle.on('lcdPower', function (on) {
if (on) { if (on) {
drawWidgets();
start(); start();
} } else {
else {
stop(); stop();
} }
}); });
})();
// Show launcher when middle button pressed
setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"});

66
apps/launch/app.js Normal file
View File

@ -0,0 +1,66 @@
var s = require("Storage");
var apps = s.list().filter(a=>a[0]=='+').map(app=>{
try { return s.readJSON(app); }
catch (e) { return {name:"DEAD: "+app.substr(1)} }
}).filter(app=>app.type=="app" || app.type=="clock" || !app.type);
apps.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;
});
var selected = 0;
var menuScroll = 0;
var menuShowing = false;
function drawMenu() {
g.setFont("6x8",2);
g.setFontAlign(-1,0);
var n = 3;
if (selected>=n+menuScroll) menuScroll = 1+selected-n;
if (selected<menuScroll) menuScroll = selected;
if (menuScroll) g.fillPoly([120,0,100,20,140,20]);
else g.clearRect(100,0,140,20);
if (apps.length>n+menuScroll) g.fillPoly([120,239,100,219,140,219]);
else g.clearRect(100,219,140,239);
for (var i=0;i<n;i++) {
var app = apps[i+menuScroll];
if (!app) break;
var y = 24+i*64;
if (i+menuScroll==selected) {
g.setColor(0.3,0.3,0.3);
g.fillRect(0,y,239,y+63);
g.setColor(1,1,1);
g.drawRect(0,y,239,y+63);
} else
g.clearRect(0,y,239,y+63);
g.drawString(app.name,64,y+32);
var icon=undefined;
if (app.icon) icon = s.read(app.icon);
if (icon) try {g.drawImage(icon,8,y+8);} catch(e){}
}
}
drawMenu();
setWatch(function() {
if (selected>0) {
selected--;
drawMenu();
}
}, BTN1, {repeat:true});
setWatch(function() {
if (selected+1<apps.length) {
selected++;
drawMenu();
}
}, BTN3, {repeat:true});
setWatch(function() { // run
if (!apps[selected].src) return;
if (require("Storage").read(apps[selected].src)===undefined) {
E.showMessage("App Source\nNot found");
setTimeout(drawMenu, 2000);
} else {
E.showMessage("Loading...");
load(apps[selected].src);
}
}, BTN2, {repeat:true,edge:"falling"});

4
apps/launch/app.json Normal file
View File

@ -0,0 +1,4 @@
{
"name":"Launcher","type":"launch",
"src":"-launch"
}

BIN
apps/launch/app.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 899 B

1
apps/mclock/ChangeLog Normal file
View File

@ -0,0 +1 @@
0.02: Modified for use with new bootloader and firmware

View File

@ -1,4 +1,3 @@
(function(){ // make our own scope so this is GC'd when intervals are cleared
// Offscreen buffer // Offscreen buffer
var buf = Graphics.createArrayBuffer(240,86,1,{msb:true}); var buf = Graphics.createArrayBuffer(240,86,1,{msb:true});
function flip() { function flip() {
@ -178,14 +177,16 @@ function showTime() {
} }
Bangle.on('lcdPower',function(on) { Bangle.on('lcdPower',function(on) {
if (on) { if (on)
showTime(); showTime();
drawWidgets();
}
}); });
g.clear(); g.clear();
Bangle.loadWidgets();
Bangle.drawWidgets();
// Update time once a second // Update time once a second
setInterval(showTime, 1000); setInterval(showTime, 1000);
showTime(); showTime();
})();
// Show launcher when middle button pressed
setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"});

1
apps/miclock/ChangeLog Normal file
View File

@ -0,0 +1 @@
0.02: Modified for use with new bootloader and firmware

View File

@ -1,6 +1,4 @@
/* jshint esversion: 6 */ /* jshint esversion: 6 */
(function() {
const Radius = { "center": 8, "hour": 78, "min": 95, "dots": 102 }; const Radius = { "center": 8, "hour": 78, "min": 95, "dots": 102 };
const Center = { "x": 120, "y": 132 }; const Center = { "x": 120, "y": 132 };
@ -73,14 +71,15 @@
g.fillCircle(Center.x, Center.y, Radius.center); g.fillCircle(Center.x, Center.y, Radius.center);
} }
Bangle.on('lcdPower', function(on) { Bangle.on('lcdPower', function(on) {
if (on) { if (on)
drawWidgets();
drawMixedClock(); drawMixedClock();
}
}); });
g.clear(); g.clear();
Bangle.loadWidgets();
Bangle.drawWidgets();
setInterval(drawMixedClock, 5E3); setInterval(drawMixedClock, 5E3);
drawMixedClock(); drawMixedClock();
})(); // Show launcher when middle button pressed
setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"});

View File

@ -1,6 +1,6 @@
{ {
"name":"5K Fun Run","type":"app", "name":"5K Fun Run","type":"app",
"icon":"*funrun5", "icon":"*ncfrun",
"src":"-funrun5", "src":"-ncfrun",
"sortorder":-1 "sortorder":-1
} }

View File

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

2
apps/ncstart/ChangeLog Normal file
View File

@ -0,0 +1,2 @@
0.02: Modified for use with new bootloader and firmware
Renamed as nodeconf-specific

View File

@ -124,9 +124,9 @@ function cleanup() {
s.erase('*bangle'); s.erase('*bangle');
s.erase('*nodew'); s.erase('*nodew');
s.erase('*tf'); s.erase('*tf');
s.erase('+start'); s.erase('+ncstart');
s.erase('-start'); s.erase('.boot3');
s.erase('*start'); s.erase('*ncstart');
return Promise.resolve(); return Promise.resolve();
} }

6
apps/ncstart/start.json Normal file
View File

@ -0,0 +1,6 @@
{
"name": "NCEU Start",
"type": "app",
"icon": "*ncstart",
"src": ".boot3"
}

View File

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

1
apps/sclock/ChangeLog Normal file
View File

@ -0,0 +1 @@
0.02: Modified for use with new bootloader and firmware

View File

@ -1,6 +1,4 @@
/* jshint esversion: 6 */ /* jshint esversion: 6 */
(function() {
const timeFontSize = 6; const timeFontSize = 6;
const dateFontSize = 3; const dateFontSize = 3;
const gmtFontSize = 2; const gmtFontSize = 2;
@ -53,14 +51,13 @@
// handle switch display on by pressing BTN1 // handle switch display on by pressing BTN1
Bangle.on('lcdPower', function(on) { Bangle.on('lcdPower', function(on) {
if (on) { if (on) drawSimpleClock();
drawWidgets();
drawSimpleClock();
}
}); });
// clean app screen // clean app screen
g.clear(); g.clear();
Bangle.loadWidgets();
Bangle.drawWidgets();
// refesh every 15 sec // refesh every 15 sec
setInterval(drawSimpleClock, 15E3); setInterval(drawSimpleClock, 15E3);
@ -68,4 +65,5 @@
// draw now // draw now
drawSimpleClock(); drawSimpleClock();
})(); // Show launcher when middle button pressed
setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"});

View File

@ -1,6 +0,0 @@
{
"name": "Start",
"type": "app",
"icon": "*start",
"src": "-start"
}

1
apps/stclck/ChangeLog Normal file
View File

@ -0,0 +1 @@
0.02: Modified for use with new bootloader and firmware

View File

@ -1,5 +1,4 @@
/* jshint esversion: 6 */ /* jshint esversion: 6 */
(function() {
const timeFontSize = 6; const timeFontSize = 6;
const dateFontSize = 3; const dateFontSize = 3;
const gmtFontSize = 2; const gmtFontSize = 2;
@ -51,18 +50,20 @@
// handle switch display on by pressing BTN1 // handle switch display on by pressing BTN1
Bangle.on("lcdPower", function(on) { Bangle.on("lcdPower", function(on) {
if (on) { if (on)
drawWidgets();
drawSimpleClock(); drawSimpleClock();
}
}); });
// clean app screen // clean app screen
g.clear(); g.clear();
Bangle.loadWidgets();
Bangle.drawWidgets();
// refesh every 15 sec // refesh every 15 sec
setInterval(drawSimpleClock, 15e3); setInterval(drawSimpleClock, 15E3);
// draw now // draw now
drawSimpleClock(); drawSimpleClock();
})();
// Show launcher when middle button pressed
setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"});

1
apps/wclock/ChangeLog Normal file
View File

@ -0,0 +1 @@
0.02: Modified for use with new bootloader and firmware

View File

@ -1,6 +1,4 @@
/* jshint esversion: 6 */ /* jshint esversion: 6 */
(function() {
const allWords = [ const allWords = [
"ATWENTYD", "ATWENTYD",
"QUARTERY", "QUARTERY",
@ -119,14 +117,14 @@
} }
Bangle.on('lcdPower', function(on) { Bangle.on('lcdPower', function(on) {
if (on) { if (on) drawWordClock();
drawWidgets();
drawWordClock();
}
}); });
g.clear(); g.clear();
Bangle.loadWidgets();
Bangle.drawWidgets();
setInterval(drawWordClock, 1E4); setInterval(drawWordClock, 1E4);
drawWordClock(); drawWordClock();
})(); // Show launcher when middle button pressed
setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"});