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 2v04master
parent
b4b882d523
commit
95d4c710bc
|
|
@ -185,7 +185,7 @@ about the app.
|
|||
"name": "Readable name", // readable name
|
||||
"icon": "icon.png", // icon in apps/
|
||||
"description": "...", // long description
|
||||
"type":"...", // optional(if app) - 'app' or 'widget'
|
||||
"type":"...", // optional(if app) - 'app'/'widget'/'launch'
|
||||
"tags": "", // comma separated tag list for searching
|
||||
|
||||
"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.
|
||||
* 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
|
||||
|
||||
## Coding hints
|
||||
|
|
|
|||
67
apps.json
67
apps.json
|
|
@ -6,7 +6,21 @@
|
|||
"description": "This is needed by Bangle.js to automatically load the clock, menu, widgets and settings",
|
||||
"tags": "tool,system",
|
||||
"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
|
||||
},
|
||||
|
|
@ -26,7 +40,7 @@
|
|||
{ "id": "mclock",
|
||||
"name": "Morphing Clock",
|
||||
"icon": "clock-morphing.png",
|
||||
"version":"0.01",
|
||||
"version":"0.02",
|
||||
"description": "7 segment clock that morphs between minutes and hours",
|
||||
"tags": "clock",
|
||||
"type":"clock",
|
||||
|
|
@ -56,7 +70,7 @@
|
|||
{ "id": "wclock",
|
||||
"name": "Word Clock",
|
||||
"icon": "clock-word.png",
|
||||
"version":"0.01",
|
||||
"version":"0.02",
|
||||
"description": "Display Time as Text",
|
||||
"tags": "clock",
|
||||
"type":"clock",
|
||||
|
|
@ -70,7 +84,7 @@
|
|||
{ "id": "aclock",
|
||||
"name": "Analog Clock",
|
||||
"icon": "clock-analog.png",
|
||||
"version":"0.01",
|
||||
"version":"0.02",
|
||||
"description": "An Analog Clock",
|
||||
"tags": "clock",
|
||||
"type":"clock",
|
||||
|
|
@ -84,7 +98,7 @@
|
|||
{ "id": "clck3x2",
|
||||
"name": "3x2 Pixel Clock",
|
||||
"icon": "clock3x2.png",
|
||||
"version":"0.01",
|
||||
"version":"0.02",
|
||||
"description": "This is a simple clock using minimalistic 3x2 pixel numerical digits",
|
||||
"tags": "clock",
|
||||
"storage": [
|
||||
|
|
@ -359,17 +373,20 @@
|
|||
{"name":"=route"}
|
||||
]
|
||||
},
|
||||
|
||||
|
||||
|
||||
{
|
||||
"id": "start",
|
||||
"id": "ncstart",
|
||||
"name": "NCEU Startup",
|
||||
"icon": "start.png",
|
||||
"version":"0.01",
|
||||
"description": "NodeConfEU 2019 Startup Sequence",
|
||||
"version":"0.02",
|
||||
"description": "NodeConfEU 2019 'First Start' Sequence",
|
||||
"tags": "start",
|
||||
"storage": [
|
||||
{"name":"+start","url":"start.json"},
|
||||
{"name":"-start","url":"start.js"},
|
||||
{"name":"*start","url":"start-icon.js","evaluate":true},
|
||||
{"name":"+ncstart","url":"start.json"},
|
||||
{"name":".boot3","url":"start.js"},
|
||||
{"name":"*ncstart","url":"start-icon.js","evaluate":true},
|
||||
{"name":"*bangle","url":"start-bangle.js","evaluate":true},
|
||||
{"name":"*nceu","url":"start-nceu.js","evaluate":true},
|
||||
{"name":"*nfr","url":"start-nfr.js","evaluate":true},
|
||||
|
|
@ -378,16 +395,16 @@
|
|||
],
|
||||
"sortorder" : -1
|
||||
},
|
||||
{ "id": "funrun5",
|
||||
{ "id": "ncfrun",
|
||||
"name": "NCEU 5K Fun Run",
|
||||
"icon": "nceu-funrun.png",
|
||||
"version":"0.01",
|
||||
"description": "Display a map of the NodeConf EU 2019 5K Fun Run route and your location on it",
|
||||
"tags": "health",
|
||||
"storage": [
|
||||
{"name":"+funrun5","url":"nceu-funrun.json"},
|
||||
{"name":"-funrun5","url":"nceu-funrun.js"},
|
||||
{"name":"*funrun5","url":"nceu-funrun-icon.js","evaluate":true}
|
||||
{"name":"+ncfrun","url":"nceu-funrun.json"},
|
||||
{"name":"-ncfrun","url":"nceu-funrun.js"},
|
||||
{"name":"*ncfrun","url":"nceu-funrun-icon.js","evaluate":true}
|
||||
],
|
||||
"sortorder" : -1
|
||||
},
|
||||
|
|
@ -404,10 +421,13 @@
|
|||
],
|
||||
"sortorder" : -1
|
||||
},
|
||||
|
||||
|
||||
|
||||
{ "id": "sclock",
|
||||
"name": "Simple Clock",
|
||||
"icon": "clock-simple.png",
|
||||
"version":"0.01",
|
||||
"version":"0.02",
|
||||
"description": "Simple Digital Clock",
|
||||
"tags": "clock",
|
||||
"type":"clock",
|
||||
|
|
@ -421,7 +441,7 @@
|
|||
{ "id": "stclck",
|
||||
"name": "Simple 12H Clock",
|
||||
"icon": "clock-simple.png",
|
||||
"version":"0.01",
|
||||
"version":"0.02",
|
||||
"description": "Simple Digital 12-Hour Clock",
|
||||
"tags": "clock",
|
||||
"type":"clock",
|
||||
|
|
@ -543,7 +563,7 @@
|
|||
{ "id": "miclock",
|
||||
"name": "Mixed Clock",
|
||||
"icon": "clock-mixed.png",
|
||||
"version":"0.01",
|
||||
"version":"0.02",
|
||||
"description": "A mix of analog and digital Clock",
|
||||
"tags": "clock",
|
||||
"type":"clock",
|
||||
|
|
@ -557,7 +577,7 @@
|
|||
{ "id": "bclock",
|
||||
"name": "Binary Clock",
|
||||
"icon": "clock-binary.png",
|
||||
"version":"0.01",
|
||||
"version":"0.02",
|
||||
"description": "A simple binary clock watch face",
|
||||
"tags": "clock",
|
||||
"type":"clock",
|
||||
|
|
@ -625,9 +645,9 @@
|
|||
]
|
||||
},
|
||||
{ "id": "blobclk",
|
||||
"name": "Large Digit Clock",
|
||||
"name": "Large Digit Blob Clock",
|
||||
"icon": "clock-blob.png",
|
||||
"version":"0.02",
|
||||
"version":"0.03",
|
||||
"description": "A clock with big digits",
|
||||
"tags": "clock",
|
||||
"type":"clock",
|
||||
|
|
@ -641,7 +661,7 @@
|
|||
{ "id": "boldclk",
|
||||
"name": "Bold Clock",
|
||||
"icon": "bold_clock.png",
|
||||
"version":"0.01",
|
||||
"version":"0.02",
|
||||
"description": "Simple, readable and practical clock",
|
||||
"tags": "clock",
|
||||
"type":"clock",
|
||||
|
|
@ -679,6 +699,7 @@
|
|||
{ "id": "berlinc",
|
||||
"name": "Berlin Clock",
|
||||
"icon": "berlin-clock.png",
|
||||
"version":"0.02",
|
||||
"description": "Berlin Clock (see https://en.wikipedia.org/wiki/Mengenlehreuhr)",
|
||||
"tags": "clock",
|
||||
"type":"clock",
|
||||
|
|
@ -692,7 +713,7 @@
|
|||
{ "id": "ctrclk",
|
||||
"name": "Centerclock",
|
||||
"icon": "app.png",
|
||||
"version":"0.01",
|
||||
"version":"0.02",
|
||||
"description": "Watch-centered digital 24h clock with date in dd.mm.yyyy format.",
|
||||
"tags": "clock",
|
||||
"type":"clock",
|
||||
|
|
|
|||
|
|
@ -1,16 +1,12 @@
|
|||
(() => {
|
||||
|
||||
// place your const, vars, functions or classes here
|
||||
|
||||
|
||||
// special function to handle display switch on
|
||||
Bangle.on('lcdPower', (on) => {
|
||||
if (on) {
|
||||
drawWidgets();
|
||||
// call your app function here
|
||||
}});
|
||||
// If you clear the screen, do Bangle.drawWidgets();
|
||||
}
|
||||
});
|
||||
|
||||
g.clear();
|
||||
// call your app function here
|
||||
|
||||
})();
|
||||
|
|
|
|||
|
|
@ -1,14 +1,13 @@
|
|||
/* run widgets in their own function scope so they don't interfere with
|
||||
currently-running apps */
|
||||
(() => {
|
||||
|
||||
// add the width
|
||||
var xpos = WIDGETPOS.tr-<the widget width>;
|
||||
WIDGETPOS.tr-=<the widget width plus some extra pixel to keep distance to others>;
|
||||
var xpos = WIDGETPOS.tr-24;/*<the widget width>*/;
|
||||
WIDGETPOS.tr-= 28;/* the widget width plus some extra pixel to keep distance to others */;
|
||||
|
||||
// draw your widget at xpos
|
||||
function draw() {
|
||||
|
||||
// add your code
|
||||
|
||||
}
|
||||
|
||||
// add your widget
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
0.02: Modified for use with new bootloader and firmware
|
||||
|
|
@ -1,5 +1,3 @@
|
|||
(function(){
|
||||
g.clear();
|
||||
const p = Math.PI/2;
|
||||
const PRad = Math.PI/180;
|
||||
|
||||
|
|
@ -53,11 +51,11 @@
|
|||
|
||||
function onMinute() {
|
||||
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);
|
||||
minuteDate = new Date();
|
||||
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);
|
||||
if(minuteDate.getHours() >= 0 && minuteDate.getMinutes() === 0) {
|
||||
Bangle.buzz();
|
||||
|
|
@ -77,16 +75,20 @@
|
|||
drawAll();
|
||||
}
|
||||
|
||||
startTimers();
|
||||
|
||||
Bangle.on('lcdPower',function(on) {
|
||||
if (on) {
|
||||
g.clear();
|
||||
drawWidgets();
|
||||
Bangle.drawWidgets();
|
||||
startTimers();
|
||||
}else {
|
||||
clearTimers();
|
||||
}
|
||||
});
|
||||
|
||||
})();
|
||||
g.clear();
|
||||
Bangle.loadWidgets();
|
||||
Bangle.drawWidgets();
|
||||
drawAll();
|
||||
startTimers();
|
||||
// Show launcher when middle button pressed
|
||||
setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"});
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
0.02: Modified for use with new bootloader and firmware
|
||||
|
|
@ -1,4 +1,3 @@
|
|||
(() => {
|
||||
const canvasWidth = 290;
|
||||
const numberOfColumns = 6;
|
||||
const drawFullGrid = false;
|
||||
|
|
@ -102,5 +101,9 @@
|
|||
});
|
||||
|
||||
g.clear();
|
||||
Bangle.loadWidgets();
|
||||
Bangle.drawWidgets();
|
||||
setInterval(() => { drawClock(); }, 1000);
|
||||
})();
|
||||
drawClock();
|
||||
// Show launcher when middle button pressed
|
||||
setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"});
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
0.02: Modified for use with new bootloader and firmware
|
||||
|
|
@ -1,5 +1,3 @@
|
|||
(() => {
|
||||
|
||||
// place your const, vars, functions or classes here
|
||||
fields = [ 4 , 4 , 11 , 4 ];
|
||||
width = g.getWidth();
|
||||
|
|
@ -49,17 +47,19 @@
|
|||
|
||||
// special function to handle display switch on
|
||||
Bangle.on('lcdPower', (on) => {
|
||||
g.clear();
|
||||
if (on) {
|
||||
drawWidgets();
|
||||
Bangle.drawWidgets();
|
||||
// call your app function here
|
||||
drawBerlinClock();
|
||||
}});
|
||||
|
||||
// call your app function here
|
||||
|
||||
// refesh every 15 sec
|
||||
setInterval(drawBerlinClock, 15E3);
|
||||
|
||||
g.clear();
|
||||
Bangle.loadWidgets();
|
||||
Bangle.drawWidgets();
|
||||
drawBerlinClock();
|
||||
|
||||
})();
|
||||
// Show launcher when middle button pressed
|
||||
setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"});
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
0.02: Improve performance when screen wakes
|
||||
Only draw widgets after clearing screen - they update automatically
|
||||
Remove 'faceUp' check as it's automatic
|
||||
0.03: Modified for use with new bootloader and firmware
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
(function(){
|
||||
const buf = Graphics.createArrayBuffer(144,200,1,{msb:true});
|
||||
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
|
||||
|
|
@ -87,10 +86,11 @@
|
|||
}
|
||||
function startTimers() {
|
||||
g.clear();
|
||||
try { if (drawWidgets) { drawWidgets();} } catch(err) {}
|
||||
Bangle.drawWidgets();
|
||||
intervalRef = setInterval(redraw,1000);
|
||||
redraw();
|
||||
}
|
||||
Bangle.loadWidgets();
|
||||
startTimers();
|
||||
Bangle.on('lcdPower',function(on) {
|
||||
if (on) {
|
||||
|
|
@ -99,4 +99,5 @@
|
|||
clearTimers();
|
||||
}
|
||||
});
|
||||
})();
|
||||
// Show launcher when middle button pressed
|
||||
setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"});
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
0.02: Modified for use with new bootloader and firmware
|
||||
|
|
@ -1,5 +1,3 @@
|
|||
(() => {
|
||||
// https://www.espruino.com/Image+Converter
|
||||
var hour_hand = {
|
||||
width : 61, height : 8, bpp : 1,
|
||||
transparent : 0,
|
||||
|
|
@ -123,7 +121,7 @@
|
|||
Bangle.on('lcdPower', (on) => {
|
||||
if (on) {
|
||||
//console.log("lcdPower: on");
|
||||
try { if (drawWidgets) { drawWidgets();} } catch(err) {}
|
||||
Bangle.drawWidgets();
|
||||
startTimers();
|
||||
} else {
|
||||
//console.log("lcdPower: off");
|
||||
|
|
@ -140,7 +138,8 @@
|
|||
});
|
||||
|
||||
g.clear();
|
||||
//Bangle.setLCDPower(true);
|
||||
Bangle.loadWidgets();
|
||||
Bangle.drawWidgets();
|
||||
startTimers();
|
||||
|
||||
})();
|
||||
// Show launcher when middle button pressed
|
||||
setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"});
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,117 +1,10 @@
|
|||
E.setFlags({pretokenise:1});
|
||||
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(); }
|
||||
// This runs after a 'fresh' boot
|
||||
var settings;
|
||||
try {
|
||||
settings = require("Storage").readJSON('@setting');
|
||||
} catch (e) {
|
||||
settings = {}
|
||||
}
|
||||
// load widgets
|
||||
require("Storage").list().filter(a=>a[0]=='=').forEach(widget=>eval(require("Storage").read(widget)));
|
||||
setTimeout(drawWidgets,100);
|
||||
// load clock if specified
|
||||
var clockApp = settings.clock;
|
||||
if (clockApp) clockApp = require("Storage").read(clockApp)
|
||||
|
|
@ -127,4 +20,3 @@ if (startapp) {
|
|||
if (clockApp) eval(clockApp);
|
||||
else E.showMessage("No Clock Found");
|
||||
delete clockApp;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"name":"Bootloader","type":"boot"
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
0.02: Modified for use with new bootloader and firmware
|
||||
|
|
@ -1,5 +1,3 @@
|
|||
(function(){
|
||||
|
||||
const ox=10; // x offset
|
||||
const oy=80;
|
||||
const pw=20; // pixel width
|
||||
|
|
@ -60,7 +58,7 @@
|
|||
|
||||
function drawTime() {
|
||||
g.clear();
|
||||
drawWidgets();
|
||||
Bangle.drawWidgets();
|
||||
|
||||
let d = Date();
|
||||
let h = d.getHours();
|
||||
|
|
@ -82,12 +80,6 @@
|
|||
idTimeout = setTimeout(drawTime, delta);
|
||||
}
|
||||
|
||||
Bangle.on('gesture', function(gesture) {
|
||||
if (gesture && !Bangle.isLCDOn()) {
|
||||
Bangle.setLCDPower(true);
|
||||
}
|
||||
});
|
||||
|
||||
// special function to handle display switch on
|
||||
Bangle.on('lcdPower', function(on){
|
||||
if (on) {
|
||||
|
|
@ -99,6 +91,7 @@
|
|||
}
|
||||
});
|
||||
|
||||
Bangle.loadWidgets();
|
||||
drawTime();
|
||||
|
||||
})();
|
||||
// Show launcher when middle button pressed
|
||||
setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"});
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
0.02: Modified for use with new bootloader and firmware
|
||||
|
|
@ -1,4 +1,3 @@
|
|||
(function () {
|
||||
let bigCustomFont = [
|
||||
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='),
|
||||
|
|
@ -150,14 +149,15 @@
|
|||
}
|
||||
|
||||
start();
|
||||
|
||||
Bangle.loadWidgets();
|
||||
Bangle.drawWidgets();
|
||||
Bangle.on('lcdPower', function (on) {
|
||||
if (on) {
|
||||
drawWidgets();
|
||||
start();
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
stop();
|
||||
}
|
||||
});
|
||||
})();
|
||||
|
||||
// Show launcher when middle button pressed
|
||||
setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"});
|
||||
|
|
|
|||
|
|
@ -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"});
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"name":"Launcher","type":"launch",
|
||||
"src":"-launch"
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 899 B |
|
|
@ -0,0 +1 @@
|
|||
0.02: Modified for use with new bootloader and firmware
|
||||
|
|
@ -1,4 +1,3 @@
|
|||
(function(){ // make our own scope so this is GC'd when intervals are cleared
|
||||
// Offscreen buffer
|
||||
var buf = Graphics.createArrayBuffer(240,86,1,{msb:true});
|
||||
function flip() {
|
||||
|
|
@ -178,14 +177,16 @@ function showTime() {
|
|||
}
|
||||
|
||||
Bangle.on('lcdPower',function(on) {
|
||||
if (on) {
|
||||
if (on)
|
||||
showTime();
|
||||
drawWidgets();
|
||||
}
|
||||
});
|
||||
|
||||
g.clear();
|
||||
Bangle.loadWidgets();
|
||||
Bangle.drawWidgets();
|
||||
// Update time once a second
|
||||
setInterval(showTime, 1000);
|
||||
showTime();
|
||||
})();
|
||||
|
||||
// Show launcher when middle button pressed
|
||||
setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"});
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
0.02: Modified for use with new bootloader and firmware
|
||||
|
|
@ -1,6 +1,4 @@
|
|||
/* jshint esversion: 6 */
|
||||
(function() {
|
||||
|
||||
const Radius = { "center": 8, "hour": 78, "min": 95, "dots": 102 };
|
||||
const Center = { "x": 120, "y": 132 };
|
||||
|
||||
|
|
@ -73,14 +71,15 @@
|
|||
g.fillCircle(Center.x, Center.y, Radius.center);
|
||||
}
|
||||
Bangle.on('lcdPower', function(on) {
|
||||
if (on) {
|
||||
drawWidgets();
|
||||
if (on)
|
||||
drawMixedClock();
|
||||
}
|
||||
});
|
||||
|
||||
g.clear();
|
||||
Bangle.loadWidgets();
|
||||
Bangle.drawWidgets();
|
||||
setInterval(drawMixedClock, 5E3);
|
||||
drawMixedClock();
|
||||
|
||||
})();
|
||||
// Show launcher when middle button pressed
|
||||
setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"});
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name":"5K Fun Run","type":"app",
|
||||
"icon":"*funrun5",
|
||||
"src":"-funrun5",
|
||||
"icon":"*ncfrun",
|
||||
"src":"-ncfrun",
|
||||
"sortorder":-1
|
||||
}
|
||||
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
|
|
@ -0,0 +1,2 @@
|
|||
0.02: Modified for use with new bootloader and firmware
|
||||
Renamed as nodeconf-specific
|
||||
|
|
@ -124,9 +124,9 @@ function cleanup() {
|
|||
s.erase('*bangle');
|
||||
s.erase('*nodew');
|
||||
s.erase('*tf');
|
||||
s.erase('+start');
|
||||
s.erase('-start');
|
||||
s.erase('*start');
|
||||
s.erase('+ncstart');
|
||||
s.erase('.boot3');
|
||||
s.erase('*ncstart');
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"name": "NCEU Start",
|
||||
"type": "app",
|
||||
"icon": "*ncstart",
|
||||
"src": ".boot3"
|
||||
}
|
||||
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
|
|
@ -0,0 +1 @@
|
|||
0.02: Modified for use with new bootloader and firmware
|
||||
|
|
@ -1,6 +1,4 @@
|
|||
/* jshint esversion: 6 */
|
||||
(function() {
|
||||
|
||||
const timeFontSize = 6;
|
||||
const dateFontSize = 3;
|
||||
const gmtFontSize = 2;
|
||||
|
|
@ -53,14 +51,13 @@
|
|||
|
||||
// handle switch display on by pressing BTN1
|
||||
Bangle.on('lcdPower', function(on) {
|
||||
if (on) {
|
||||
drawWidgets();
|
||||
drawSimpleClock();
|
||||
}
|
||||
if (on) drawSimpleClock();
|
||||
});
|
||||
|
||||
// clean app screen
|
||||
g.clear();
|
||||
Bangle.loadWidgets();
|
||||
Bangle.drawWidgets();
|
||||
|
||||
// refesh every 15 sec
|
||||
setInterval(drawSimpleClock, 15E3);
|
||||
|
|
@ -68,4 +65,5 @@
|
|||
// draw now
|
||||
drawSimpleClock();
|
||||
|
||||
})();
|
||||
// Show launcher when middle button pressed
|
||||
setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"});
|
||||
|
|
|
|||
|
|
@ -1,6 +0,0 @@
|
|||
{
|
||||
"name": "Start",
|
||||
"type": "app",
|
||||
"icon": "*start",
|
||||
"src": "-start"
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
0.02: Modified for use with new bootloader and firmware
|
||||
|
|
@ -1,5 +1,4 @@
|
|||
/* jshint esversion: 6 */
|
||||
(function() {
|
||||
const timeFontSize = 6;
|
||||
const dateFontSize = 3;
|
||||
const gmtFontSize = 2;
|
||||
|
|
@ -51,18 +50,20 @@
|
|||
|
||||
// handle switch display on by pressing BTN1
|
||||
Bangle.on("lcdPower", function(on) {
|
||||
if (on) {
|
||||
drawWidgets();
|
||||
if (on)
|
||||
drawSimpleClock();
|
||||
}
|
||||
});
|
||||
|
||||
// clean app screen
|
||||
g.clear();
|
||||
Bangle.loadWidgets();
|
||||
Bangle.drawWidgets();
|
||||
|
||||
// refesh every 15 sec
|
||||
setInterval(drawSimpleClock, 15e3);
|
||||
setInterval(drawSimpleClock, 15E3);
|
||||
|
||||
// draw now
|
||||
drawSimpleClock();
|
||||
})();
|
||||
|
||||
// Show launcher when middle button pressed
|
||||
setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"});
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
0.02: Modified for use with new bootloader and firmware
|
||||
|
|
@ -1,6 +1,4 @@
|
|||
/* jshint esversion: 6 */
|
||||
(function() {
|
||||
|
||||
const allWords = [
|
||||
"ATWENTYD",
|
||||
"QUARTERY",
|
||||
|
|
@ -119,14 +117,14 @@
|
|||
}
|
||||
|
||||
Bangle.on('lcdPower', function(on) {
|
||||
if (on) {
|
||||
drawWidgets();
|
||||
drawWordClock();
|
||||
}
|
||||
if (on) drawWordClock();
|
||||
});
|
||||
|
||||
g.clear();
|
||||
Bangle.loadWidgets();
|
||||
Bangle.drawWidgets();
|
||||
setInterval(drawWordClock, 1E4);
|
||||
drawWordClock();
|
||||
|
||||
})();
|
||||
// Show launcher when middle button pressed
|
||||
setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"});
|
||||
|
|
|
|||
Loading…
Reference in New Issue