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
pull/148/head
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
"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

View File

@ -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",

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
Bangle.on('lcdPower', (on) => {
if (on) {
// call your app function here
// If you clear the screen, do Bangle.drawWidgets();
}
});
// special function to handle display switch on
Bangle.on('lcdPower', (on) => {
if (on) {
drawWidgets();
// call your app function here
}});
g.clear();
// call your app function here
})();
g.clear();
// call your app function here

View File

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

1
apps/aclock/ChangeLog Normal file
View File

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

View File

@ -1,92 +1,94 @@
(function(){
const p = Math.PI/2;
const PRad = Math.PI/180;
let intervalRefMin = null;
let intervalRefSec = null;
let minuteDate = new Date();
let secondDate = new Date();
function seconds(angle, r) {
const a = angle*PRad;
const x = 120+Math.sin(a)*r;
const y = 120-Math.cos(a)*r;
g.fillRect(x-1,y-1,x+1,y+1);
}
function hand(angle, r1,r2) {
const a = angle*PRad;
const r3 = 3;
g.fillPoly([
120+Math.sin(a)*r1,
120-Math.cos(a)*r1,
120+Math.sin(a+p)*r3,
120-Math.cos(a+p)*r3,
120+Math.sin(a)*r2,
120-Math.cos(a)*r2,
120+Math.sin(a-p)*r3,
120-Math.cos(a-p)*r3]);
}
function drawAll() {
g.clear();
const p = Math.PI/2;
const PRad = Math.PI/180;
let intervalRefMin = null;
let intervalRefSec = null;
let minuteDate = new Date();
let secondDate = new Date();
function seconds(angle, r) {
const a = angle*PRad;
const x = 120+Math.sin(a)*r;
const y = 120-Math.cos(a)*r;
g.fillRect(x-1,y-1,x+1,y+1);
secondDate = minuteDate = new Date();
// draw hands first
onMinute();
// draw seconds
g.setColor(0,0,0.6);
for (let i=0;i<60;i++)
seconds(360*i/60, 90);
onSecond();
}
function onSecond() {
g.setColor(0,0,0.6);
seconds(360*secondDate.getSeconds()/60, 90);
g.setColor(1,0,0);
secondDate = new Date();
seconds(360*secondDate.getSeconds()/60, 90);
g.setColor(1,1,1);
}
function onMinute() {
g.setColor(0,0,0);
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() + (minuteDate.getMinutes()/60))/12, -10, 50);
hand(360*minuteDate.getMinutes()/60, -10, 82);
if(minuteDate.getHours() >= 0 && minuteDate.getMinutes() === 0) {
Bangle.buzz();
}
function hand(angle, r1,r2) {
const a = angle*PRad;
const r3 = 3;
g.fillPoly([
120+Math.sin(a)*r1,
120-Math.cos(a)*r1,
120+Math.sin(a+p)*r3,
120-Math.cos(a+p)*r3,
120+Math.sin(a)*r2,
120-Math.cos(a)*r2,
120+Math.sin(a-p)*r3,
120-Math.cos(a-p)*r3]);
}
function drawAll() {
}
function clearTimers() {
if(intervalRefMin) {clearInterval(intervalRefMin);}
if(intervalRefSec) {clearInterval(intervalRefSec);}
}
function startTimers() {
minuteDate = new Date();
secondDate = new Date();
intervalRefSec = setInterval(onSecond,1000);
intervalRefMin = setInterval(onMinute,60*1000);
drawAll();
}
Bangle.on('lcdPower',function(on) {
if (on) {
g.clear();
secondDate = minuteDate = new Date();
// draw hands first
onMinute();
// draw seconds
g.setColor(0,0,0.6);
for (let i=0;i<60;i++)
seconds(360*i/60, 90);
onSecond();
}
function onSecond() {
g.setColor(0,0,0.6);
seconds(360*secondDate.getSeconds()/60, 90);
g.setColor(1,0,0);
secondDate = new Date();
seconds(360*secondDate.getSeconds()/60, 90);
g.setColor(1,1,1);
}
function onMinute() {
g.setColor(0,0,0);
hand(360*minuteDate.getHours()/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.getMinutes()/60, -10, 82);
if(minuteDate.getHours() >= 0 && minuteDate.getMinutes() === 0) {
Bangle.buzz();
}
Bangle.drawWidgets();
startTimers();
}else {
clearTimers();
}
});
function clearTimers() {
if(intervalRefMin) {clearInterval(intervalRefMin);}
if(intervalRefSec) {clearInterval(intervalRefSec);}
}
function startTimers() {
minuteDate = new Date();
secondDate = new Date();
intervalRefSec = setInterval(onSecond,1000);
intervalRefMin = setInterval(onMinute,60*1000);
drawAll();
}
startTimers();
Bangle.on('lcdPower',function(on) {
if (on) {
g.clear();
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"});

1
apps/bclock/ChangeLog Normal file
View File

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

View File

@ -1,106 +1,109 @@
(() => {
const canvasWidth = 290;
const numberOfColumns = 6;
const drawFullGrid = false;
const canvasWidth = 290;
const numberOfColumns = 6;
const drawFullGrid = false;
const colpos = canvasWidth / numberOfColumns - 10;
const binSize = (canvasWidth / numberOfColumns) / 3;
const colpos = canvasWidth / numberOfColumns - 10;
const binSize = (canvasWidth / numberOfColumns) / 3;
const findBinary = target => {
return [
[0, 0, 0, 0], // 0
[1, 0, 0, 0], // 1
[0, 1, 0, 0], // 2
[1, 1, 0, 0], // 3
[0, 0, 1, 0], // 4
[1, 0, 1, 0], // 5
[0, 1, 1, 0], // 6
[1, 1, 1, 0], // 7
[0, 0, 0, 1], // 8
[1, 0, 0, 1], // 9
][target];
const findBinary = target => {
return [
[0, 0, 0, 0], // 0
[1, 0, 0, 0], // 1
[0, 1, 0, 0], // 2
[1, 1, 0, 0], // 3
[0, 0, 1, 0], // 4
[1, 0, 1, 0], // 5
[0, 1, 1, 0], // 6
[1, 1, 1, 0], // 7
[0, 0, 0, 1], // 8
[1, 0, 0, 1], // 9
][target];
};
const getCurrentTime = () => {
const flattenArray = (array = []) => [].concat.apply([], array);
const format = number => {
const numberStr = number.toString();
return numberStr.length === 1 ? ["0", numberStr] : numberStr.split("");
};
const now = new Date();
return flattenArray([now.getHours(), now.getMinutes(), now.getSeconds()].map(format));
};
const getCurrentTime = () => {
const flattenArray = (array = []) => [].concat.apply([], array);
const format = number => {
const numberStr = number.toString();
return numberStr.length === 1 ? ["0", numberStr] : numberStr.split("");
};
const now = new Date();
return flattenArray([now.getHours(), now.getMinutes(), now.getSeconds()].map(format));
};
let prevFrame = [];
const drawColumn = (position = 0, column = [0, 0, 0, 0]) => {
const maxDotsPerColumn = [2, 4, 3, 4, 3, 4];
let prevFrame = [];
const drawColumn = (position = 0, column = [0, 0, 0, 0]) => {
const maxDotsPerColumn = [2, 4, 3, 4, 3, 4];
const columnPos = position * colpos;
let pos = colpos / 2 + 45;
const frame = column.reverse();
const drawDot = fn => g[fn]((columnPos + colpos / 2), pos, binSize);
const columnPos = position * colpos;
let pos = colpos / 2 + 45;
const frame = column.reverse();
const drawDot = fn => g[fn]((columnPos + colpos / 2), pos, binSize);
for (let i = 0; i < frame.length; i += 1) {
if (i + maxDotsPerColumn[position] >= 4 || drawFullGrid) {
if (prevFrame && prevFrame[position] && prevFrame[position][i]) {
if (frame[i] !== prevFrame[position][i]) {
// subsequent draw
g.clearRect((columnPos + colpos / 2) - 15, pos - 15, (columnPos + colpos / 2) + 20, pos + 20);
if (frame[i]) {
drawDot('fillCircle');
} else {
drawDot('drawCircle');
}
}
} else {
// First draw
for (let i = 0; i < frame.length; i += 1) {
if (i + maxDotsPerColumn[position] >= 4 || drawFullGrid) {
if (prevFrame && prevFrame[position] && prevFrame[position][i]) {
if (frame[i] !== prevFrame[position][i]) {
// subsequent draw
g.clearRect((columnPos + colpos / 2) - 15, pos - 15, (columnPos + colpos / 2) + 20, pos + 20);
if (frame[i]) {
drawDot('fillCircle');
} else {
drawDot('drawCircle');
}
}
} else {
// First draw
if (frame[i]) {
drawDot('fillCircle');
} else {
drawDot('drawCircle');
}
}
pos += colpos;
}
};
pos += colpos;
}
};
const drawClock = () => {
const data = getCurrentTime().map(findBinary);
for (let i = 0; i < data.length; i += 1) {
drawColumn(i, data[i]);
}
prevFrame = data;
};
// Themes
const drawTheme = (idx) => () => {
idx += 1;
const themes = [
[[0, 0, 0], [1, 1, 1]],
[[1, 1, 1], [0, 0, 0]],
[[0, 0, 0], [1, 0, 0]],
[[0, 0, 0], [0, 1, 0]],
[[0, 0, 0], [0, 0, 1]],
];
if (idx >= themes.length) idx = 0;
const color = themes[idx];
g.setBgColor.apply(g, color[0]);
g.setColor.apply(g, color[1]);
g.clear();
};
const nextTheme = drawTheme(0);
setWatch(() => {
prevFrame = [];
Bangle.beep();
nextTheme();
}, BTN1, { repeat: true });
Bangle.on('lcdPower', on => {
if (on) drawClock();
});
const drawClock = () => {
const data = getCurrentTime().map(findBinary);
for (let i = 0; i < data.length; i += 1) {
drawColumn(i, data[i]);
}
prevFrame = data;
};
// Themes
const drawTheme = (idx) => () => {
idx += 1;
const themes = [
[[0, 0, 0], [1, 1, 1]],
[[1, 1, 1], [0, 0, 0]],
[[0, 0, 0], [1, 0, 0]],
[[0, 0, 0], [0, 1, 0]],
[[0, 0, 0], [0, 0, 1]],
];
if (idx >= themes.length) idx = 0;
const color = themes[idx];
g.setBgColor.apply(g, color[0]);
g.setColor.apply(g, color[1]);
g.clear();
setInterval(() => { drawClock(); }, 1000);
})();
};
const nextTheme = drawTheme(0);
setWatch(() => {
prevFrame = [];
Bangle.beep();
nextTheme();
}, BTN1, { repeat: true });
Bangle.on('lcdPower', on => {
if (on) drawClock();
});
g.clear();
Bangle.loadWidgets();
Bangle.drawWidgets();
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,65 +1,65 @@
(() => {
// place your const, vars, functions or classes here
fields = [ 4 , 4 , 11 , 4 ];
width = g.getWidth();
height = g.getHeight();
rowHeight = height/4;
rowlights = [];
// place your const, vars, functions or classes here
fields = [ 4 , 4 , 11 , 4 ];
width = g.getWidth();
height = g.getHeight();
rowHeight = height/4;
rowlights = [];
function drawBerlinClock() {
var now = new Date();
rowlights[0] = Math.floor(now.getHours() / 5);
rowlights[1] = now.getHours() % 5;
rowlights[2] = Math.floor(now.getMinutes() / 5);
rowlights[3] = now.getMinutes() % 5;
function drawBerlinClock() {
var now = new Date();
rowlights[0] = Math.floor(now.getHours() / 5);
rowlights[1] = now.getHours() % 5;
rowlights[2] = Math.floor(now.getMinutes() / 5);
rowlights[3] = now.getMinutes() % 5;
g.clear();
g.drawRect(0,0,width,height);
for (row = 0 ; row < 4 ; row++) {
nfields = fields[row];
boxWidth = width/nfields;
for (col = 0 ; col < nfields ; col++) {
x1 = col*boxWidth;
y1 = row*rowHeight;
x2 = (col+1)*boxWidth;
y2 = (row+1)*rowHeight;
g.setColor(1,1,1);
g.drawRect(x1,y1,x2,y2);
if (col<rowlights[row]) {
if (row === 2 ) {
if (((col+1) % 3) === 0) {
g.setColor(1,0,0);
} else {
g.setColor(1,1,0);
}
} else {
g.setColor(1,0,0);
}
g.fillRect(x1+2,y1+2,x2-2,y2-2);
g.clear();
g.drawRect(0,0,width,height);
for (row = 0 ; row < 4 ; row++) {
nfields = fields[row];
boxWidth = width/nfields;
for (col = 0 ; col < nfields ; col++) {
x1 = col*boxWidth;
y1 = row*rowHeight;
x2 = (col+1)*boxWidth;
y2 = (row+1)*rowHeight;
g.setColor(1,1,1);
g.drawRect(x1,y1,x2,y2);
if (col<rowlights[row]) {
if (row === 2 ) {
if (((col+1) % 3) === 0) {
g.setColor(1,0,0);
} else {
g.setColor(1,1,0);
}
} else {
g.setColor(1,0,0);
}
g.fillRect(x1+2,y1+2,x2-2,y2-2);
}
}
}
}
// special function to handle display switch on
Bangle.on('lcdPower', (on) => {
if (on) {
drawWidgets();
// call your app function here
drawBerlinClock();
}});
// special function to handle display switch on
Bangle.on('lcdPower', (on) => {
g.clear();
if (on) {
Bangle.drawWidgets();
// call your app function here
drawBerlinClock();
}});
// call your app function here
// refesh every 15 sec
setInterval(drawBerlinClock, 15E3);
// refesh every 15 sec
setInterval(drawBerlinClock, 15E3);
drawBerlinClock();
})();
g.clear();
Bangle.loadWidgets();
Bangle.drawWidgets();
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
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

View File

@ -1,102 +1,103 @@
(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
[0,1,1,1,3,0,0,1,1,1,0,0,1,1,1,0,0,1,1,1,0,0,1,1,1],//1
[1,1,1,1,3,0,0,1,1,1,2,1,1,1,4,1,1,1,0,0,1,1,1,1,1],//2
[1,1,1,1,3,0,0,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1],//3
[1,1,0,1,1,1,1,0,1,1,1,1,1,1,1,5,1,1,1,1,0,0,1,1,1],//4
[1,1,1,1,1,1,1,1,0,0,5,1,1,1,3,0,0,1,1,1,1,1,1,1,1],//5
[1,1,1,1,1,1,1,1,0,0,1,1,1,1,3,1,1,0,1,1,1,1,1,1,1],//6
[1,1,1,1,3,0,0,1,1,1,0,2,1,1,1,0,1,1,1,0,0,1,1,1,0],//7
[1,1,1,1,3,1,1,0,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1],//8
[1,1,1,1,3,1,1,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1] //9
];
let intervalRef = null;
let digits = [-1,-1,-1,-1,-1,-1];
function flip() {
g.setColor(1,1,1);
g.drawImage({width:buf.getWidth(),height:buf.getHeight(),buffer:buf.buffer},55,26);
}
function drawPixel(ox,oy,x,y,r,p) {
let x1 = ox+x*(r*2+1);
let y1 = oy+y*(r*2+1);
let xmid = x1+r;
let ymid = y1+r;
let x2 = xmid+r;
let y2 = ymid+r;
if (p > 0) {
if (p > 1) {
buf.setColor(0,0,0);
buf.fillRect(x1,y1,x2,y2);
}
buf.setColor(1,1,1);
} else {
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
[0,1,1,1,3,0,0,1,1,1,0,0,1,1,1,0,0,1,1,1,0,0,1,1,1],//1
[1,1,1,1,3,0,0,1,1,1,2,1,1,1,4,1,1,1,0,0,1,1,1,1,1],//2
[1,1,1,1,3,0,0,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1],//3
[1,1,0,1,1,1,1,0,1,1,1,1,1,1,1,5,1,1,1,1,0,0,1,1,1],//4
[1,1,1,1,1,1,1,1,0,0,5,1,1,1,3,0,0,1,1,1,1,1,1,1,1],//5
[1,1,1,1,1,1,1,1,0,0,1,1,1,1,3,1,1,0,1,1,1,1,1,1,1],//6
[1,1,1,1,3,0,0,1,1,1,0,2,1,1,1,0,1,1,1,0,0,1,1,1,0],//7
[1,1,1,1,3,1,1,0,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1],//8
[1,1,1,1,3,1,1,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1] //9
];
let intervalRef = null;
let digits = [-1,-1,-1,-1,-1,-1];
function flip() {
g.setColor(1,1,1);
g.drawImage({width:buf.getWidth(),height:buf.getHeight(),buffer:buf.buffer},55,26);
}
function drawPixel(ox,oy,x,y,r,p) {
let x1 = ox+x*(r*2+1);
let y1 = oy+y*(r*2+1);
let xmid = x1+r;
let ymid = y1+r;
let x2 = xmid+r;
let y2 = ymid+r;
if (p > 0) {
if (p > 1) {
buf.setColor(0,0,0);
}
if (p < 2) {
buf.fillRect(x1,y1,x2,y2);
} else if (p === 2) {
buf.fillPoly([xmid,y1,x2,y1,x2,y2,x1,y2,x1,ymid]);
} else if (p === 3) {
buf.fillPoly([x1,y1,xmid,y1,x2,ymid,x2,y2,x1,y2]);
} else if (p === 4) {
buf.fillPoly([x1,y1,x2,y1,x2,ymid,xmid,y2,x1,y2]);
} else if (p === 5) {
buf.fillPoly([x1,y1,x2,y1,x2,y2,xmid,y2,x1,ymid]);
}
buf.setColor(1,1,1);
} else {
buf.setColor(0,0,0);
}
function redraw() {
let time = new Date();
let hours = time.getHours();
let mins = time.getMinutes();
let secs = time.getSeconds();
if (p < 2) {
buf.fillRect(x1,y1,x2,y2);
} else if (p === 2) {
buf.fillPoly([xmid,y1,x2,y1,x2,y2,x1,y2,x1,ymid]);
} else if (p === 3) {
buf.fillPoly([x1,y1,xmid,y1,x2,ymid,x2,y2,x1,y2]);
} else if (p === 4) {
buf.fillPoly([x1,y1,x2,y1,x2,ymid,xmid,y2,x1,y2]);
} else if (p === 5) {
buf.fillPoly([x1,y1,x2,y1,x2,y2,xmid,y2,x1,ymid]);
}
}
function redraw() {
let time = new Date();
let hours = time.getHours();
let mins = time.getMinutes();
let secs = time.getSeconds();
let newDigits = [Math.floor(hours/10),hours%10,Math.floor(mins/10),mins%10,Math.floor(secs/10),secs%10];
let newDigits = [Math.floor(hours/10),hours%10,Math.floor(mins/10),mins%10,Math.floor(secs/10),secs%10];
for (var p = 0;p<25;p++) {
var px = p%5;
var py = Math.floor(p/5);
if (digits[0] === -1 || NUMBERS[newDigits[0]][p] !== NUMBERS[digits[0]][p] ) {
drawPixel(0,20,px,py,6,NUMBERS[newDigits[0]][p]);
}
if (digits[1] === -1 || NUMBERS[newDigits[1]][p] !== NUMBERS[digits[1]][p] ) {
drawPixel(78,20,px,py,6,NUMBERS[newDigits[1]][p]);
}
if (digits[2] === -1 || NUMBERS[newDigits[2]][p] !== NUMBERS[digits[2]][p] ) {
drawPixel(0,92,px,py,6,NUMBERS[newDigits[2]][p]);
}
if (digits[3] === -1 || NUMBERS[newDigits[3]][p] !== NUMBERS[digits[3]][p] ) {
drawPixel(78,92,px,py,6,NUMBERS[newDigits[3]][p]);
}
if (digits[4] === -1 || NUMBERS[newDigits[4]][p] !== NUMBERS[digits[4]][p] ) {
drawPixel(69,164,px,py,3,NUMBERS[newDigits[4]][p]);
}
if (digits[5] === -1 || NUMBERS[newDigits[5]][p] !== NUMBERS[digits[5]][p] ) {
drawPixel(108,164,px,py,3,NUMBERS[newDigits[5]][p]);
}
for (var p = 0;p<25;p++) {
var px = p%5;
var py = Math.floor(p/5);
if (digits[0] === -1 || NUMBERS[newDigits[0]][p] !== NUMBERS[digits[0]][p] ) {
drawPixel(0,20,px,py,6,NUMBERS[newDigits[0]][p]);
}
digits = newDigits;
flip();
}
function clearTimers() {
if(intervalRef) {
clearInterval(intervalRef);
intervalRef = undefined;
if (digits[1] === -1 || NUMBERS[newDigits[1]][p] !== NUMBERS[digits[1]][p] ) {
drawPixel(78,20,px,py,6,NUMBERS[newDigits[1]][p]);
}
if (digits[2] === -1 || NUMBERS[newDigits[2]][p] !== NUMBERS[digits[2]][p] ) {
drawPixel(0,92,px,py,6,NUMBERS[newDigits[2]][p]);
}
if (digits[3] === -1 || NUMBERS[newDigits[3]][p] !== NUMBERS[digits[3]][p] ) {
drawPixel(78,92,px,py,6,NUMBERS[newDigits[3]][p]);
}
if (digits[4] === -1 || NUMBERS[newDigits[4]][p] !== NUMBERS[digits[4]][p] ) {
drawPixel(69,164,px,py,3,NUMBERS[newDigits[4]][p]);
}
if (digits[5] === -1 || NUMBERS[newDigits[5]][p] !== NUMBERS[digits[5]][p] ) {
drawPixel(108,164,px,py,3,NUMBERS[newDigits[5]][p]);
}
}
function startTimers() {
g.clear();
try { if (drawWidgets) { drawWidgets();} } catch(err) {}
intervalRef = setInterval(redraw,1000);
redraw();
digits = newDigits;
flip();
}
function clearTimers() {
if(intervalRef) {
clearInterval(intervalRef);
intervalRef = undefined;
}
startTimers();
Bangle.on('lcdPower',function(on) {
if (on) {
startTimers();
} else {
clearTimers();
}
});
})();
}
function startTimers() {
g.clear();
Bangle.drawWidgets();
intervalRef = setInterval(redraw,1000);
redraw();
}
Bangle.loadWidgets();
startTimers();
Bangle.on('lcdPower',function(on) {
if (on) {
startTimers();
} else {
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,146 +1,145 @@
(() => {
// https://www.espruino.com/Image+Converter
var hour_hand = {
width : 61, height : 8, bpp : 1,
transparent : 0,
buffer : E.toArrayBuffer(atob("/////////////////////////////////////////////////////////////////////////////////w=="))
};
var minute_hand = {
width : 110, height : 4, bpp : 1,
transparent : 0,
buffer : E.toArrayBuffer(atob("/////////////////////////////////////////////////////////////////////////w=="))
};
var hour_hand = {
width : 61, height : 8, bpp : 1,
transparent : 0,
buffer : E.toArrayBuffer(atob("/////////////////////////////////////////////////////////////////////////////////w=="))
};
var minute_hand = {
width : 110, height : 4, bpp : 1,
transparent : 0,
buffer : E.toArrayBuffer(atob("/////////////////////////////////////////////////////////////////////////w=="))
};
//g.fillRect(0,24,239,239); // Apps area
let intervalRef = null;
const p180 = Math.PI/180;
const clock_center = {x:Math.floor((240-1)/2), y:24+Math.floor((239-24)/2)};
// ={ x: 119, y: 131 }
const radius = Math.floor((239-24+1)/2); // =108
//g.fillRect(0,24,239,239); // Apps area
let intervalRef = null;
const p180 = Math.PI/180;
const clock_center = {x:Math.floor((240-1)/2), y:24+Math.floor((239-24)/2)};
// ={ x: 119, y: 131 }
const radius = Math.floor((239-24+1)/2); // =108
let tick0 = Graphics.createArrayBuffer(30,8,1);
tick0.fillRect(0,0,tick0.getWidth()-1, tick0.getHeight()-1);
let tick5 = Graphics.createArrayBuffer(20,6,1);
tick5.fillRect(0,0,tick5.getWidth()-1, tick5.getHeight()-1);
let tick1 = Graphics.createArrayBuffer(8,4,1);
tick1.fillRect(0,0,tick1.getWidth()-1, tick1.getHeight()-1);
let tick0 = Graphics.createArrayBuffer(30,8,1);
tick0.fillRect(0,0,tick0.getWidth()-1, tick0.getHeight()-1);
let tick5 = Graphics.createArrayBuffer(20,6,1);
tick5.fillRect(0,0,tick5.getWidth()-1, tick5.getHeight()-1);
let tick1 = Graphics.createArrayBuffer(8,4,1);
tick1.fillRect(0,0,tick1.getWidth()-1, tick1.getHeight()-1);
function big_wheel_x(angle){
return clock_center.x + radius * Math.cos(angle*p180);
}
function big_wheel_y(angle){
return clock_center.y + radius * Math.sin(angle*p180);
}
function rotate_around_x(center_x, angle, tick){
return center_x + Math.cos(angle*p180) * tick.getWidth()/2;
}
function rotate_around_y(center_y, angle, tick){
return center_y + Math.sin(angle*p180) * tick.getWidth()/2;
}
function hour_pos_x(angle){
return clock_center.x + Math.cos(angle*p180) * hour_hand.width/2;
}
function hour_pos_y(angle){
return clock_center.y + Math.sin(angle*p180) * hour_hand.width/2;
}
function minute_pos_x(angle){
return clock_center.x + Math.cos(angle*p180) * minute_hand.width/2;
}
function minute_pos_y(angle){
return clock_center.y + Math.sin(angle*p180) * minute_hand.width/2;
}
function minute_angle(date){
//let minutes = date.getMinutes() + date.getSeconds()/60;
let minutes = date.getMinutes();
return 6*minutes - 90;
}
function hour_angle(date){
let hours= date.getHours() + date.getMinutes()/60;
return 30*hours - 90;
}
function big_wheel_x(angle){
return clock_center.x + radius * Math.cos(angle*p180);
}
function big_wheel_y(angle){
return clock_center.y + radius * Math.sin(angle*p180);
}
function rotate_around_x(center_x, angle, tick){
return center_x + Math.cos(angle*p180) * tick.getWidth()/2;
}
function rotate_around_y(center_y, angle, tick){
return center_y + Math.sin(angle*p180) * tick.getWidth()/2;
}
function hour_pos_x(angle){
return clock_center.x + Math.cos(angle*p180) * hour_hand.width/2;
}
function hour_pos_y(angle){
return clock_center.y + Math.sin(angle*p180) * hour_hand.width/2;
}
function minute_pos_x(angle){
return clock_center.x + Math.cos(angle*p180) * minute_hand.width/2;
}
function minute_pos_y(angle){
return clock_center.y + Math.sin(angle*p180) * minute_hand.width/2;
}
function minute_angle(date){
//let minutes = date.getMinutes() + date.getSeconds()/60;
let minutes = date.getMinutes();
return 6*minutes - 90;
}
function hour_angle(date){
let hours= date.getHours() + date.getMinutes()/60;
return 30*hours - 90;
}
function draw_clock(){
//console.log("draw_clock");
let date = new Date();
//g.clear();
g.setBgColor(0,0,0);
g.setColor(0,0,0);
g.fillRect(0,24,239,239); // clear app area
g.setColor(1,1,1);
function draw_clock(){
//console.log("draw_clock");
let date = new Date();
//g.clear();
g.setBgColor(0,0,0);
g.setColor(0,0,0);
g.fillRect(0,24,239,239); // clear app area
g.setColor(1,1,1);
// draw cross lines for testing
// g.setColor(1,0,0);
// g.drawLine(clock_center.x - radius, clock_center.y, clock_center.x + radius, clock_center.y);
// g.drawLine(clock_center.x, clock_center.y - radius, clock_center.x, clock_center.y + radius);
// draw cross lines for testing
// g.setColor(1,0,0);
// g.drawLine(clock_center.x - radius, clock_center.y, clock_center.x + radius, clock_center.y);
// g.drawLine(clock_center.x, clock_center.y - radius, clock_center.x, clock_center.y + radius);
g.setColor(1,1,1);
let ticks = [0, 90, 180, 270];
ticks.forEach((item)=>{
let agl = item+180;
g.drawImage(tick0.asImage(), rotate_around_x(big_wheel_x(item), agl, tick0), rotate_around_y(big_wheel_y(item), agl, tick0), {rotate:agl*p180});
});
ticks = [30, 60, 120, 150, 210, 240, 300, 330];
ticks.forEach((item)=>{
let agl = item+180;
g.drawImage(tick5.asImage(), rotate_around_x(big_wheel_x(item), agl, tick5), rotate_around_y(big_wheel_y(item), agl, tick5), {rotate:agl*p180});
});
let hour_agl = hour_angle(date);
let minute_agl = minute_angle(date);
g.drawImage(hour_hand, hour_pos_x(hour_agl), hour_pos_y(hour_agl), {rotate:hour_agl*p180}); //
g.drawImage(minute_hand, minute_pos_x(minute_agl), minute_pos_y(minute_agl), {rotate:minute_agl*p180}); //
g.setColor(1,1,1);
g.fillCircle(clock_center.x, clock_center.y, 6);
g.setColor(0,0,0);
g.fillCircle(clock_center.x, clock_center.y, 3);
// draw minute ticks. Takes long time to draw!
g.setColor(1,1,1);
for (var i=0; i<60; i++){
let agl = i*6+180;
g.drawImage(tick1.asImage(), rotate_around_x(big_wheel_x(i*6), agl, tick1), rotate_around_y(big_wheel_y(i*6), agl, tick1), {rotate:agl*p180});
}
g.flip();
//console.log(date);
}
function clearTimers(){
//console.log("clearTimers");
if(intervalRef) {
clearInterval(intervalRef);
intervalRef = null;
//console.log("interval is cleared");
}
}
function startTimers(){
//console.log("startTimers");
if(intervalRef) clearTimers();
intervalRef = setInterval(draw_clock, 60*1000);
//console.log("interval is set");
draw_clock();
}
Bangle.on('lcdPower', (on) => {
if (on) {
//console.log("lcdPower: on");
try { if (drawWidgets) { drawWidgets();} } catch(err) {}
startTimers();
} else {
//console.log("lcdPower: off");
clearTimers();
}
g.setColor(1,1,1);
let ticks = [0, 90, 180, 270];
ticks.forEach((item)=>{
let agl = item+180;
g.drawImage(tick0.asImage(), rotate_around_x(big_wheel_x(item), agl, tick0), rotate_around_y(big_wheel_y(item), agl, tick0), {rotate:agl*p180});
});
Bangle.on('faceUp',function(up){
//console.log("faceUp: " + up + " LCD: " + Bangle.isLCDOn());
if (up && !Bangle.isLCDOn()) {
//console.log("faceUp and LCD off");
clearTimers();
Bangle.setLCDPower(true);
}
ticks = [30, 60, 120, 150, 210, 240, 300, 330];
ticks.forEach((item)=>{
let agl = item+180;
g.drawImage(tick5.asImage(), rotate_around_x(big_wheel_x(item), agl, tick5), rotate_around_y(big_wheel_y(item), agl, tick5), {rotate:agl*p180});
});
g.clear();
//Bangle.setLCDPower(true);
startTimers();
let hour_agl = hour_angle(date);
let minute_agl = minute_angle(date);
g.drawImage(hour_hand, hour_pos_x(hour_agl), hour_pos_y(hour_agl), {rotate:hour_agl*p180}); //
g.drawImage(minute_hand, minute_pos_x(minute_agl), minute_pos_y(minute_agl), {rotate:minute_agl*p180}); //
g.setColor(1,1,1);
g.fillCircle(clock_center.x, clock_center.y, 6);
g.setColor(0,0,0);
g.fillCircle(clock_center.x, clock_center.y, 3);
})();
// draw minute ticks. Takes long time to draw!
g.setColor(1,1,1);
for (var i=0; i<60; i++){
let agl = i*6+180;
g.drawImage(tick1.asImage(), rotate_around_x(big_wheel_x(i*6), agl, tick1), rotate_around_y(big_wheel_y(i*6), agl, tick1), {rotate:agl*p180});
}
g.flip();
//console.log(date);
}
function clearTimers(){
//console.log("clearTimers");
if(intervalRef) {
clearInterval(intervalRef);
intervalRef = null;
//console.log("interval is cleared");
}
}
function startTimers(){
//console.log("startTimers");
if(intervalRef) clearTimers();
intervalRef = setInterval(draw_clock, 60*1000);
//console.log("interval is set");
draw_clock();
}
Bangle.on('lcdPower', (on) => {
if (on) {
//console.log("lcdPower: on");
Bangle.drawWidgets();
startTimers();
} else {
//console.log("lcdPower: off");
clearTimers();
}
});
Bangle.on('faceUp',function(up){
//console.log("faceUp: " + up + " LCD: " + Bangle.isLCDOn());
if (up && !Bangle.isLCDOn()) {
//console.log("faceUp and LCD off");
clearTimers();
Bangle.setLCDPower(true);
}
});
g.clear();
Bangle.loadWidgets();
Bangle.drawWidgets();
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,130 +1,22 @@
E.setFlags({pretokenise:1});
var startapp;
// This runs after a 'fresh' boot
var settings;
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;
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)
if (!clockApp) {
var clockApps = require("Storage").list().filter(a=>a[0]=='+').map(app=>{
try { return require("Storage").readJSON(app); }
catch (e) {}
}).filter(app=>app.type=="clock").sort((a, b) => a.sortorder - b.sortorder);
if (clockApps && clockApps.length > 0)
clockApp = require("Storage").read(clockApps[0].src);
delete clockApps;
}
if (clockApp) eval(clockApp);
else E.showMessage("No Clock Found");
delete clockApp;
settings = require("Storage").readJSON('@setting');
} catch (e) {
settings = {}
}
// load clock if specified
var clockApp = settings.clock;
if (clockApp) clockApp = require("Storage").read(clockApp)
if (!clockApp) {
var clockApps = require("Storage").list().filter(a=>a[0]=='+').map(app=>{
try { return require("Storage").readJSON(app); }
catch (e) {}
}).filter(app=>app.type=="clock").sort((a, b) => a.sortorder - b.sortorder);
if (clockApps && clockApps.length > 0)
clockApp = require("Storage").read(clockApps[0].src);
delete clockApps;
}
if (clockApp) eval(clockApp);
else E.showMessage("No Clock Found");
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,104 +1,97 @@
(function(){
const ox=10; // x offset
const oy=80;
const pw=20; // pixel width
const ps=5; // pixel spacing
const ds=10; // digit spacing
const ms=20; // middle space
const ox=10; // x offset
const oy=80;
const pw=20; // pixel width
const ps=5; // pixel spacing
const ds=10; // digit spacing
const ms=20; // middle space
const x00=ox; // digit 0, pixel 0, x position
const x01=x00+pw+ps;
const x10=x01+pw+ds;
const x11=x10+pw+ps;
const x20=x11+pw+ms;
const x21=x20+pw+ps;
const x30=x21+pw+ds;
const x31=x30+pw+ps;
const xSpace=[[x00,x01], // all pixel x spacing
[x10,x11],
[x20,x21],
[x30,x31]];
const x00=ox; // digit 0, pixel 0, x position
const x01=x00+pw+ps;
const x10=x01+pw+ds;
const x11=x10+pw+ps;
const x20=x11+pw+ms;
const x21=x20+pw+ps;
const x30=x21+pw+ds;
const x31=x30+pw+ps;
const xSpace=[[x00,x01], // all pixel x spacing
[x10,x11],
[x20,x21],
[x30,x31]];
const y0=oy; // y spacing
const y1=y0+pw+ps;
const y2=y1+pw+ps;
const ySpace=[y0, y1, y2];
const y0=oy; // y spacing
const y1=y0+pw+ps;
const y2=y1+pw+ps;
const ySpace=[y0, y1, y2];
const pixels = [[[0,0], // digit on/off pixels
[1,1],
[1,1]],
[[0,1], // digit 1
[0,1],
[0,1]],
[[0,1],
[1,0],
[1,1]],
[[1,1],
[0,1],
[1,1]],
[[1,0],
[1,1],
[0,1]],
[[1,1],
[1,0],
[0,1]],
[[1,0],
[1,1],
[1,1]],
[[1,1],
[0,1],
[0,1]],
[[1,1],
[1,1],
[1,1]],
[[1,1],
[1,1],
[0,1]]];
const pixels = [[[0,0], // digit on/off pixels
[1,1],
[1,1]],
[[0,1], // digit 1
[0,1],
[0,1]],
[[0,1],
[1,0],
[1,1]],
[[1,1],
[0,1],
[1,1]],
[[1,0],
[1,1],
[0,1]],
[[1,1],
[1,0],
[0,1]],
[[1,0],
[1,1],
[1,1]],
[[1,1],
[0,1],
[0,1]],
[[1,1],
[1,1],
[1,1]],
[[1,1],
[1,1],
[0,1]]];
let idTimeout = null;
let idTimeout = null;
function drawTime() {
g.clear();
Bangle.drawWidgets();
function drawTime() {
g.clear();
drawWidgets();
let d = Date();
let h = d.getHours();
let m = d.getMinutes();
let digits = [Math.floor(h/10), h%10, Math.floor(m/10), m%10]; // time digits
let d = Date();
let h = d.getHours();
let m = d.getMinutes();
let digits = [Math.floor(h/10), h%10, Math.floor(m/10), m%10]; // time digits
for (let id=0; id<4; id++){
for (let xp=0; xp<2; xp++){
for (let yp=0; yp<3; yp++){
if (pixels[digits[id]][yp][xp]==1){
g.fillRect(xSpace[id][xp], ySpace[yp], xSpace[id][xp]+pw, ySpace[yp]+pw);
}
for (let id=0; id<4; id++){
for (let xp=0; xp<2; xp++){
for (let yp=0; yp<3; yp++){
if (pixels[digits[id]][yp][xp]==1){
g.fillRect(xSpace[id][xp], ySpace[yp], xSpace[id][xp]+pw, ySpace[yp]+pw);
}
}
}
let t = d.getSeconds()*1000 + d.getMilliseconds();
let delta = (60000 - t) % 60000; // time till next minute
idTimeout = setTimeout(drawTime, delta);
}
Bangle.on('gesture', function(gesture) {
if (gesture && !Bangle.isLCDOn()) {
Bangle.setLCDPower(true);
let t = d.getSeconds()*1000 + d.getMilliseconds();
let delta = (60000 - t) % 60000; // time till next minute
idTimeout = setTimeout(drawTime, delta);
}
// special function to handle display switch on
Bangle.on('lcdPower', function(on){
if (on) {
drawTime();
} else {
if(idTimeout) {
clearTimeout(idTimeout);
}
});
}
});
// special function to handle display switch on
Bangle.on('lcdPower', function(on){
if (on) {
drawTime();
} else {
if(idTimeout) {
clearTimeout(idTimeout);
}
}
});
drawTime();
})();
Bangle.loadWidgets();
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,163 +1,163 @@
(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='),
atob('Jg8dGiAaKBsoKA==')
];
let smallCustomFont = [
atob(
'AAAAAAAAAAfkAAwAAAwAAACQf8CQf8CQAAGIJEf+JEE4AAMMMQBgCMMMAAAYMkTEMkAYBkAAwAgAAAHwIIQEAAQEIIHwAABAFQDgBADgFQBABABAHwBABAAAACAMAABABABABABAAAAEAAAEAYAgDAEAYAAAP4QkRESEP4AAEEIEf8AEAAMMQUQUQkPEAAIIQEREREO4AABwCQEQIQf8AAeISESESER4AAH4KESESEB4AAYAQAQcTgcAAAO4REREREO4AAPAQkQkQoPwAACIAAACCMAABACgEQIIAACQCQCQCQCQAAIIEQCgBAAAMAQAQ0RAOAAAP4QETkUUUUP0AAP8RARARAP8AAf8REREREO4AAP4QEQEQEIIAAf8QEQEIIHwAAf8REREREQEAAf8RARARAQAAAP4QEQEREJ4AAf8BABABAf8AAQEf8QEAAAYAEQEf4QAAAf8BACgEQYMAAf8AEAEAEAEAAf8IAEACAEAIAf8AAf8EACABAf8AAP4QEQEQEP4AAf8RARARAOAAAP4QEQEQGP6AAf8RgRQRIOEAAOIREREREI4AAQAQAf8QAQAAAf4AEAEAEf4AAeABwAMBweAAAf8AIAQAgAQAIf8AAYMGwBAGwYMAAYAGAB8GAYAAAQMQ0REWEYEAAf8QEAAMACABgAQAMAAQEf8AAIAQAgAQAIAAAACACACACACAAgAwAAAAYCkCkCkB8AAf8CECECEB4AAB4CECECEBIAAB4CECECEf8AAB4CUCUCUBwAACAP8SAQAAAB4CFCFCFD+AAf8CACACAB8AACET8AEAAACABT+AAf8AgBQCIAEAAQEf8AEAAD8CACAD8CACAB8AAD8CACACAB8AAB4CECECEB4AAD/CECECEB4AAB4CECECED/AAD8BACACACAAABICkCkCkAYAACAP4CECEAAD4AEAEAED8AADAAwAMAwDAAAD4AEAEA4AEAED4AACMBQAgBQCMAAD4AFAFAFD+AACMCUCkDECEAABAO4QEQEAAf8AAQEQEO4BAAAYAgAQAQAIAwAAAAAAAAAAAAA'),
atob(
'BQIEBgYGBwMEBAcGAwYCBwYFBgYGBgYGBgYCAwUGBQYHBgYGBgYGBgYEBgYGCAYGBgYGBgYGBggGBgYDBgMGBgMGBgYGBgUGBgQEBgQIBgYGBgYGBQYGCAYGBgUCBQcF')
];
let interval = null;
let middleX = 120;
let middleY = 106;
let lineLength = 114;
let lineY1 = middleY - 10;
let lineY2 = middleY + 60;
let clearRectSegmentY1 = middleY - 9;
let clearRectSegmentY2 = middleY + 59;
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='),
atob('Jg8dGiAaKBsoKA==')
];
let smallCustomFont = [
atob(
'AAAAAAAAAAfkAAwAAAwAAACQf8CQf8CQAAGIJEf+JEE4AAMMMQBgCMMMAAAYMkTEMkAYBkAAwAgAAAHwIIQEAAQEIIHwAABAFQDgBADgFQBABABAHwBABAAAACAMAABABABABABAAAAEAAAEAYAgDAEAYAAAP4QkRESEP4AAEEIEf8AEAAMMQUQUQkPEAAIIQEREREO4AABwCQEQIQf8AAeISESESER4AAH4KESESEB4AAYAQAQcTgcAAAO4REREREO4AAPAQkQkQoPwAACIAAACCMAABACgEQIIAACQCQCQCQCQAAIIEQCgBAAAMAQAQ0RAOAAAP4QETkUUUUP0AAP8RARARAP8AAf8REREREO4AAP4QEQEQEIIAAf8QEQEIIHwAAf8REREREQEAAf8RARARAQAAAP4QEQEREJ4AAf8BABABAf8AAQEf8QEAAAYAEQEf4QAAAf8BACgEQYMAAf8AEAEAEAEAAf8IAEACAEAIAf8AAf8EACABAf8AAP4QEQEQEP4AAf8RARARAOAAAP4QEQEQGP6AAf8RgRQRIOEAAOIREREREI4AAQAQAf8QAQAAAf4AEAEAEf4AAeABwAMBweAAAf8AIAQAgAQAIf8AAYMGwBAGwYMAAYAGAB8GAYAAAQMQ0REWEYEAAf8QEAAMACABgAQAMAAQEf8AAIAQAgAQAIAAAACACACACACAAgAwAAAAYCkCkCkB8AAf8CECECEB4AAB4CECECEBIAAB4CECECEf8AAB4CUCUCUBwAACAP8SAQAAAB4CFCFCFD+AAf8CACACAB8AACET8AEAAACABT+AAf8AgBQCIAEAAQEf8AEAAD8CACAD8CACAB8AAD8CACACAB8AAB4CECECEB4AAD/CECECEB4AAB4CECECED/AAD8BACACACAAABICkCkCkAYAACAP4CECEAAD4AEAEAED8AADAAwAMAwDAAAD4AEAEA4AEAED4AACMBQAgBQCMAAD4AFAFAFD+AACMCUCkDECEAABAO4QEQEAAf8AAQEQEO4BAAAYAgAQAQAIAwAAAAAAAAAAAAA'),
atob(
'BQIEBgYGBwMEBAcGAwYCBwYFBgYGBgYGBgYCAwUGBQYHBgYGBgYGBgYEBgYGCAYGBgYGBgYGBggGBgYDBgMGBgMGBgYGBgUGBgQEBgQIBgYGBgYGBQYGCAYGBgUCBQcF')
];
let interval = null;
let middleX = 120;
let middleY = 106;
let lineLength = 114;
let lineY1 = middleY - 10;
let lineY2 = middleY + 60;
let clearRectSegmentY1 = middleY - 9;
let clearRectSegmentY2 = middleY + 59;
function setBigFont () {
g.setFontCustom(
bigCustomFont[0],
48,
bigCustomFont[1],
58
);
function setBigFont () {
g.setFontCustom(
bigCustomFont[0],
48,
bigCustomFont[1],
58
);
}
function setSmallFont () {
g.setFontCustom(
smallCustomFont[0],
32,
smallCustomFont[1],
12
);
}
function drawSegment (align, base, str) {
let point = base;
let maxSegmentWidth = g.stringWidth('00');
if (align === 'r') {
point = base - g.stringWidth(str) / 2;
}
function setSmallFont () {
g.setFontCustom(
smallCustomFont[0],
32,
smallCustomFont[1],
12
);
if (align === 'c') {
point = base + (maxSegmentWidth / 2) -
(g.stringWidth(str) / 2);
}
g.setColor(1, 1, 1);
g.drawString(str, point, middleY - 4, false);
}
function drawSegment (align, base, str) {
let point = base;
let maxSegmentWidth = g.stringWidth('00');
if (align === 'r') {
point = base - g.stringWidth(str) / 2;
}
if (align === 'c') {
point = base + (maxSegmentWidth / 2) -
(g.stringWidth(str) / 2);
}
g.setColor(1, 1, 1);
g.drawString(str, point, middleY - 4, false);
function drawDots (center) {
g.setColor(0xFD20);
g.fillCircle(center, middleY + 10, 2);
g.fillCircle(center, middleY + 40, 2);
}
function drawLines () {
g.setColor(0.5, 0.5, 0.5);
g.drawLine(middleX - lineLength, lineY1, middleX + lineLength, lineY1);
g.drawLine(middleX - lineLength, lineY2, middleX + lineLength, lineY2);
}
function drawDate (str) {
let maxSegmentWidth = 236;
g.setColor(0.5, 0.5, 0.5);
g.setColor(0.5, 0.5, 0.5);
g.drawString(str, (maxSegmentWidth) - (g.stringWidth(str)), middleY - 22,
false);
}
function fixedDigits (numb) {
if (numb < 10) {
return '0' + numb;
}
return numb.toString();
}
function drawDots (center) {
g.setColor(0xFD20);
g.fillCircle(center, middleY + 10, 2);
g.fillCircle(center, middleY + 40, 2);
}
function drawLines () {
g.setColor(0.5, 0.5, 0.5);
g.drawLine(middleX - lineLength, lineY1, middleX + lineLength, lineY1);
g.drawLine(middleX - lineLength, lineY2, middleX + lineLength, lineY2);
}
function drawDate (str) {
let maxSegmentWidth = 236;
g.setColor(0.5, 0.5, 0.5);
g.setColor(0.5, 0.5, 0.5);
g.drawString(str, (maxSegmentWidth) - (g.stringWidth(str)), middleY - 22,
false);
}
function fixedDigits (numb) {
if (numb < 10) {
return '0' + numb;
}
return numb.toString();
}
function step () {
let d = new Date();
let hour = d.getHours();
let minute = d.getMinutes();
let second = d.getSeconds();
let day = d.getDate();
let month = d.getMonth() + 1;
let year = d.getFullYear();
let dateStr = fixedDigits(day) + '.' + fixedDigits(month) + '.' + year;
//hour = "00";
//minute = "00";
//second = "00";
setBigFont();
let drawDot1 = false;
let drawDot2 = false;
if (step.lastHour !== hour) {
g.clearRect(0, clearRectSegmentY1, 240, clearRectSegmentY2);
drawSegment('l', middleX - 120, fixedDigits(hour));
drawDot1 = true;
drawDot2 = true;
step.lastMinute = null;
step.lastSecond = null;
}
if (step.lastMinute !== minute) {
g.clearRect(middleX - 41, clearRectSegmentY1, 240, clearRectSegmentY2);
drawSegment('c', middleX - 37, fixedDigits(minute));
drawDot1 = true;
drawDot2 = true;
step.lastSecond = null;
}
if (step.lastSecond !== second) {
g.clearRect(middleX + 42, clearRectSegmentY1, 240, clearRectSegmentY2);
drawSegment('r', middleX + 82, fixedDigits(second));
drawDot2 = true;
}
if (drawDot1) {
drawDots(middleX - 41);
}
if (drawDot2) {
drawDots(middleX + 41);
}
if (step.lastDate !== dateStr) {
g.clearRect(0, middleY - 22, 240, middleY - 12);
setSmallFont();
drawDate(dateStr);
}
step.lastDate = dateStr;
step.lastHour = hour;
step.lastMinute = minute;
step.lastSecond = second;
}
function stop () {
if (interval) {
clearInterval(interval);
}
}
function start () {
if (interval) {
clearInterval(interval);
}
drawLines();
step.lastDate = null;
step.lastHour = null;
function step () {
let d = new Date();
let hour = d.getHours();
let minute = d.getMinutes();
let second = d.getSeconds();
let day = d.getDate();
let month = d.getMonth() + 1;
let year = d.getFullYear();
let dateStr = fixedDigits(day) + '.' + fixedDigits(month) + '.' + year;
//hour = "00";
//minute = "00";
//second = "00";
setBigFont();
let drawDot1 = false;
let drawDot2 = false;
if (step.lastHour !== hour) {
g.clearRect(0, clearRectSegmentY1, 240, clearRectSegmentY2);
drawSegment('l', middleX - 120, fixedDigits(hour));
drawDot1 = true;
drawDot2 = true;
step.lastMinute = null;
step.lastSecond = null;
interval = setInterval(step, 1000);
step();
}
if (step.lastMinute !== minute) {
g.clearRect(middleX - 41, clearRectSegmentY1, 240, clearRectSegmentY2);
drawSegment('c', middleX - 37, fixedDigits(minute));
drawDot1 = true;
drawDot2 = true;
step.lastSecond = null;
}
if (step.lastSecond !== second) {
g.clearRect(middleX + 42, clearRectSegmentY1, 240, clearRectSegmentY2);
drawSegment('r', middleX + 82, fixedDigits(second));
drawDot2 = true;
}
if (drawDot1) {
drawDots(middleX - 41);
}
if (drawDot2) {
drawDots(middleX + 41);
}
if (step.lastDate !== dateStr) {
g.clearRect(0, middleY - 22, 240, middleY - 12);
setSmallFont();
drawDate(dateStr);
}
step.lastDate = dateStr;
step.lastHour = hour;
step.lastMinute = minute;
step.lastSecond = second;
}
start();
function stop () {
if (interval) {
clearInterval(interval);
}
}
Bangle.on('lcdPower', function (on) {
if (on) {
drawWidgets();
start();
}
else {
stop();
}
});
})();
function start () {
if (interval) {
clearInterval(interval);
}
drawLines();
step.lastDate = null;
step.lastHour = null;
step.lastMinute = null;
step.lastSecond = null;
interval = setInterval(step, 1000);
step();
}
start();
Bangle.loadWidgets();
Bangle.drawWidgets();
Bangle.on('lcdPower', function (on) {
if (on) {
start();
} else {
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
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"});

1
apps/miclock/ChangeLog Normal file
View File

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

View File

@ -1,86 +1,85 @@
/* jshint esversion: 6 */
(function() {
const Radius = { "center": 8, "hour": 78, "min": 95, "dots": 102 };
const Center = { "x": 120, "y": 132 };
const Radius = { "center": 8, "hour": 78, "min": 95, "dots": 102 };
const Center = { "x": 120, "y": 132 };
function rotatePoint(x, y, d) {
rad = -1 * d / 180 * Math.PI;
var sin = Math.sin(rad);
var cos = Math.cos(rad);
xn = ((Center.x + x * cos - y * sin) + 0.5) | 0;
yn = ((Center.y + x * sin - y * cos) + 0.5) | 0;
p = [xn, yn];
return p;
}
function rotatePoint(x, y, d) {
rad = -1 * d / 180 * Math.PI;
var sin = Math.sin(rad);
var cos = Math.cos(rad);
xn = ((Center.x + x * cos - y * sin) + 0.5) | 0;
yn = ((Center.y + x * sin - y * cos) + 0.5) | 0;
p = [xn, yn];
return p;
function drawMixedClock() {
var date = new Date();
var dateArray = date.toString().split(" ");
var point = [];
var minute = date.getMinutes();
var hour = date.getHours();
var radius;
// draw date
g.setColor(0x7be0);
g.setFont("6x8", 2);
g.setFontAlign(-1, 0);
g.drawString(dateArray[0] + ' ', 4, 35, true);
g.drawString(' ' + dateArray[2], 4, 225, true);
g.setFontAlign(1, 0);
g.drawString(dateArray[1], 237, 35, true);
g.drawString(dateArray[3], 237, 225, true);
// draw hour and minute dots
g.setColor(0xFD20); // orange
for (i = 0; i < 60; i++) {
radius = (i % 5) ? 2 : 4;
point = rotatePoint(0, Radius.dots, i * 6);
g.fillCircle(point[0], point[1], radius);
}
function drawMixedClock() {
// erase last minutes hand
g.setColor(0);
point = rotatePoint(0, Radius.min, (minute - 1) * 6);
g.drawLine(Center.x, Center.y, point[0], point[1]);
var date = new Date();
var dateArray = date.toString().split(" ");
var point = [];
var minute = date.getMinutes();
var hour = date.getHours();
var radius;
// erase last two hour hands
g.setColor(0);
p = rotatePoint(0, Radius.hour, hour % 12 * 30 + (minute - 2) / 2 | 0);
g.drawLine(Center.x, Center.y, p[0], p[1]);
point = rotatePoint(0, Radius.hour, hour % 12 * 30 + (minute - 1) / 2 | 0);
g.drawLine(Center.x, Center.y, point[0], point[1]);
// draw date
g.setColor(0x7be0);
g.setFont("6x8", 2);
g.setFontAlign(-1, 0);
g.drawString(dateArray[0] + ' ', 4, 35, true);
g.drawString(' ' + dateArray[2], 4, 225, true);
g.setFontAlign(1, 0);
g.drawString(dateArray[1], 237, 35, true);
g.drawString(dateArray[3], 237, 225, true);
// draw digital time
g.setFont("6x8", 3);
g.setColor(0x7be0);
g.setFontAlign(0, 0);
g.drawString(dateArray[4].substr(0, 5), 120, 180, true);
// draw hour and minute dots
g.setColor(0xFD20); // orange
for (i = 0; i < 60; i++) {
radius = (i % 5) ? 2 : 4;
point = rotatePoint(0, Radius.dots, i * 6);
g.fillCircle(point[0], point[1], radius);
}
// draw new minute hand
point = rotatePoint(0, Radius.min, minute * 6);
g.setColor(0xFFFF);
g.drawLine(Center.x, Center.y, point[0], point[1]);
// draw new hour hand
point = rotatePoint(0, Radius.hour, hour % 12 * 30 + date.getMinutes() / 2 | 0);
g.setColor(0xFFFF);
g.drawLine(Center.x, Center.y, point[0], point[1]);
// erase last minutes hand
g.setColor(0);
point = rotatePoint(0, Radius.min, (minute - 1) * 6);
g.drawLine(Center.x, Center.y, point[0], point[1]);
// erase last two hour hands
g.setColor(0);
p = rotatePoint(0, Radius.hour, hour % 12 * 30 + (minute - 2) / 2 | 0);
g.drawLine(Center.x, Center.y, p[0], p[1]);
point = rotatePoint(0, Radius.hour, hour % 12 * 30 + (minute - 1) / 2 | 0);
g.drawLine(Center.x, Center.y, point[0], point[1]);
// draw digital time
g.setFont("6x8", 3);
g.setColor(0x7be0);
g.setFontAlign(0, 0);
g.drawString(dateArray[4].substr(0, 5), 120, 180, true);
// draw new minute hand
point = rotatePoint(0, Radius.min, minute * 6);
g.setColor(0xFFFF);
g.drawLine(Center.x, Center.y, point[0], point[1]);
// draw new hour hand
point = rotatePoint(0, Radius.hour, hour % 12 * 30 + date.getMinutes() / 2 | 0);
g.setColor(0xFFFF);
g.drawLine(Center.x, Center.y, point[0], point[1]);
// draw center
g.setColor(0xFD20);
g.fillCircle(Center.x, Center.y, Radius.center);
}
Bangle.on('lcdPower', function(on) {
if (on) {
drawWidgets();
drawMixedClock();
}
});
g.clear();
setInterval(drawMixedClock, 5E3);
// draw center
g.setColor(0xFD20);
g.fillCircle(Center.x, Center.y, Radius.center);
}
Bangle.on('lcdPower', function(on) {
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"});

View File

@ -1,6 +1,6 @@
{
"name":"5K Fun Run","type":"app",
"icon":"*funrun5",
"src":"-funrun5",
"icon":"*ncfrun",
"src":"-ncfrun",
"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('*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();
}

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,71 +1,69 @@
/* jshint esversion: 6 */
(function() {
const timeFontSize = 6;
const dateFontSize = 3;
const gmtFontSize = 2;
const font = "6x8";
const timeFontSize = 6;
const dateFontSize = 3;
const gmtFontSize = 2;
const font = "6x8";
const xyCenter = g.getWidth() / 2;
const yposTime = 75;
const yposDate = 130;
const yposYear = 175;
const yposGMT = 220;
const xyCenter = g.getWidth() / 2;
const yposTime = 75;
const yposDate = 130;
const yposYear = 175;
const yposGMT = 220;
function drawSimpleClock() {
function drawSimpleClock() {
// get date
var d = new Date();
var da = d.toString().split(" ");
// get date
var d = new Date();
var da = d.toString().split(" ");
// drawSting centered
g.setFontAlign(0, 0);
// draw time
var time = da[4].substr(0, 5);
var [hours, minutes] = time.split(":");
var meridian = "AM";
if (Number(hours) > 12) {
hours -= String(Number(hours) - 12);
meridian = "PM";
}
g.setFont(font, timeFontSize);
g.drawString(`${hours}:${minutes}`, xyCenter, yposTime, true);
g.setFont(font, gmtFontSize);
g.drawString(meridian, xyCenter + 100, yposTime + 10, true);
// draw Day, name of month, Date
var date = [da[0], da[1], da[2]].join(" ");
g.setFont(font, dateFontSize);
g.drawString(date, xyCenter, yposDate, true);
// draw year
g.setFont(font, dateFontSize);
g.drawString(d.getFullYear(), xyCenter, yposYear, true);
// draw gmt
var gmt = da[5];
g.setFont(font, gmtFontSize);
g.drawString(gmt, xyCenter, yposGMT, true);
// drawSting centered
g.setFontAlign(0, 0);
// draw time
var time = da[4].substr(0, 5);
var [hours, minutes] = time.split(":");
var meridian = "AM";
if (Number(hours) > 12) {
hours -= String(Number(hours) - 12);
meridian = "PM";
}
g.setFont(font, timeFontSize);
g.drawString(`${hours}:${minutes}`, xyCenter, yposTime, true);
g.setFont(font, gmtFontSize);
g.drawString(meridian, xyCenter + 100, yposTime + 10, true);
// handle switch display on by pressing BTN1
Bangle.on('lcdPower', function(on) {
if (on) {
drawWidgets();
drawSimpleClock();
}
});
// draw Day, name of month, Date
var date = [da[0], da[1], da[2]].join(" ");
g.setFont(font, dateFontSize);
// clean app screen
g.clear();
g.drawString(date, xyCenter, yposDate, true);
// refesh every 15 sec
setInterval(drawSimpleClock, 15E3);
// draw now
drawSimpleClock();
// draw year
g.setFont(font, dateFontSize);
g.drawString(d.getFullYear(), xyCenter, yposYear, true);
})();
// draw gmt
var gmt = da[5];
g.setFont(font, gmtFontSize);
g.drawString(gmt, xyCenter, yposGMT, true);
}
// handle switch display on by pressing BTN1
Bangle.on('lcdPower', function(on) {
if (on) drawSimpleClock();
});
// clean app screen
g.clear();
Bangle.loadWidgets();
Bangle.drawWidgets();
// refesh every 15 sec
setInterval(drawSimpleClock, 15E3);
// draw now
drawSimpleClock();
// Show launcher when middle button pressed
setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"});

View File

@ -18,7 +18,7 @@ Bangle.HID = E.toUint8Array(atob("BQEJBqEBhQIFBxngKecVACUBdQGVCIEClQF1CIEBlQV1AQ
try { // disable advertising if BLE should be off
if (!s.ble) NRF.sleep();
else NRF.wake();
} catch(e) {}
} catch(e) {}
if (!s.vibrate) Bangle.buzz=Promise.resolve;
if (!s.beep) Bangle.beep=Promise.resolve;
Bangle.setLCDTimeout(s.timeout);

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,68 +1,69 @@
/* jshint esversion: 6 */
(function() {
const timeFontSize = 6;
const dateFontSize = 3;
const gmtFontSize = 2;
const font = "6x8";
const timeFontSize = 6;
const dateFontSize = 3;
const gmtFontSize = 2;
const font = "6x8";
const xyCenter = g.getWidth() / 2;
const yposTime = 75;
const yposDate = 130;
const yposYear = 175;
const yposGMT = 220;
const xyCenter = g.getWidth() / 2;
const yposTime = 75;
const yposDate = 130;
const yposYear = 175;
const yposGMT = 220;
function drawSimpleClock() {
// get date
var d = new Date();
var da = d.toString().split(" ");
function drawSimpleClock() {
// get date
var d = new Date();
var da = d.toString().split(" ");
// drawSting centered
g.setFontAlign(0, 0);
// drawSting centered
g.setFontAlign(0, 0);
// draw time
var time = da[4].substr(0, 5).split(":");
var hours = time[0],
minutes = time[1];
var meridian = "AM";
if (Number(hours) > 12) {
hours -= String(Number(hours) - 12);
meridian = "PM";
}
g.setFont(font, timeFontSize);
g.drawString(`${hours}:${minutes}`, xyCenter, yposTime, true);
g.setFont(font, gmtFontSize);
g.drawString(meridian, xyCenter + 102, yposTime + 10, true);
// draw Day, name of month, Date
var date = [da[0], da[1], da[2]].join(" ");
g.setFont(font, dateFontSize);
g.drawString(date, xyCenter, yposDate, true);
// draw year
g.setFont(font, dateFontSize);
g.drawString(d.getFullYear(), xyCenter, yposYear, true);
// draw gmt
var gmt = da[5];
g.setFont(font, gmtFontSize);
g.drawString(gmt, xyCenter, yposGMT, true);
// draw time
var time = da[4].substr(0, 5).split(":");
var hours = time[0],
minutes = time[1];
var meridian = "AM";
if (Number(hours) > 12) {
hours -= String(Number(hours) - 12);
meridian = "PM";
}
g.setFont(font, timeFontSize);
g.drawString(`${hours}:${minutes}`, xyCenter, yposTime, true);
g.setFont(font, gmtFontSize);
g.drawString(meridian, xyCenter + 102, yposTime + 10, true);
// handle switch display on by pressing BTN1
Bangle.on("lcdPower", function(on) {
if (on) {
drawWidgets();
drawSimpleClock();
}
});
// draw Day, name of month, Date
var date = [da[0], da[1], da[2]].join(" ");
g.setFont(font, dateFontSize);
// clean app screen
g.clear();
g.drawString(date, xyCenter, yposDate, true);
// refesh every 15 sec
setInterval(drawSimpleClock, 15e3);
// draw year
g.setFont(font, dateFontSize);
g.drawString(d.getFullYear(), xyCenter, yposYear, true);
// draw now
drawSimpleClock();
})();
// draw gmt
var gmt = da[5];
g.setFont(font, gmtFontSize);
g.drawString(gmt, xyCenter, yposGMT, true);
}
// handle switch display on by pressing BTN1
Bangle.on("lcdPower", function(on) {
if (on)
drawSimpleClock();
});
// clean app screen
g.clear();
Bangle.loadWidgets();
Bangle.drawWidgets();
// refesh every 15 sec
setInterval(drawSimpleClock, 15E3);
// draw now
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,132 +1,130 @@
/* jshint esversion: 6 */
(function() {
const allWords = [
"ATWENTYD",
"QUARTERY",
"FIVEHALF",
"DPASTORO",
"FIVEIGHT",
"SIXTHREE",
"TWELEVEN",
"FOURNINE"
];
const hours = {
0: ["", 0, 0],
1: ["ONE", 17, 47, 77],
2: ["TWO", 06, 16, 17],
3: ["THREE", 35, 45, 55, 65, 75],
4: ["FOUR", 07, 17, 27, 37],
5: ["FIVE", 04, 14, 24, 34],
6: ["SIX", 05, 15, 25],
7: ["SEVEN", 05, 46, 56, 66, 67],
8: ["EIGHT", 34, 44, 54, 64, 74],
9: ["NINE", 47, 57, 67, 77],
10: ["TEN", 74, 75, 76],
11: ["ELEVEN", 26, 36, 46, 56, 66, 76],
12: ["TWELVE", 06, 16, 26, 36, 56, 66]
};
const allWords = [
"ATWENTYD",
"QUARTERY",
"FIVEHALF",
"DPASTORO",
"FIVEIGHT",
"SIXTHREE",
"TWELEVEN",
"FOURNINE"
];
const hours = {
0: ["", 0, 0],
1: ["ONE", 17, 47, 77],
2: ["TWO", 06, 16, 17],
3: ["THREE", 35, 45, 55, 65, 75],
4: ["FOUR", 07, 17, 27, 37],
5: ["FIVE", 04, 14, 24, 34],
6: ["SIX", 05, 15, 25],
7: ["SEVEN", 05, 46, 56, 66, 67],
8: ["EIGHT", 34, 44, 54, 64, 74],
9: ["NINE", 47, 57, 67, 77],
10: ["TEN", 74, 75, 76],
11: ["ELEVEN", 26, 36, 46, 56, 66, 76],
12: ["TWELVE", 06, 16, 26, 36, 56, 66]
};
const mins = {
0: ["A", 0, 0],
1: ["FIVE", 02, 12, 22, 32],
2: ["TEN", 10, 30, 40],
3: ["QUARTER", 01, 11, 21, 31, 41, 51, 61],
4: ["TWENTY", 10, 20, 30, 40, 50, 60],
5: ["HALF", 42, 52, 62, 72],
6: ["PAST", 13, 23, 33, 43],
7: ["TO", 43, 53]
};
const mins = {
0: ["A", 0, 0],
1: ["FIVE", 02, 12, 22, 32],
2: ["TEN", 10, 30, 40],
3: ["QUARTER", 01, 11, 21, 31, 41, 51, 61],
4: ["TWENTY", 10, 20, 30, 40, 50, 60],
5: ["HALF", 42, 52, 62, 72],
6: ["PAST", 13, 23, 33, 43],
7: ["TO", 43, 53]
};
// offsets and incerments
const xs = 35;
const ys = 31;
const dy = 22;
const dx = 25;
// offsets and incerments
const xs = 35;
const ys = 31;
const dy = 22;
const dx = 25;
// font size and color
const fontSize = 3; // "6x8"
const passivColor = 0x3186 /*grey*/ ;
const activeColor = 0xF800 /*red*/ ;
// font size and color
const fontSize = 3; // "6x8"
const passivColor = 0x3186 /*grey*/ ;
const activeColor = 0xF800 /*red*/ ;
function drawWordClock() {
function drawWordClock() {
// get time
var t = new Date();
var h = t.getHours();
var m = t.getMinutes();
var time = ("0" + h).substr(-2) + ":" + ("0" + m).substr(-2);
// get time
var t = new Date();
var h = t.getHours();
var m = t.getMinutes();
var time = ("0" + h).substr(-2) + ":" + ("0" + m).substr(-2);
var hidx;
var midx;
var midxA = [];
var hidx;
var midx;
var midxA = [];
g.setFont("6x8",fontSize);
g.setColor(passivColor);
g.setFontAlign(0, -1, 0);
g.setFont("6x8",fontSize);
g.setColor(passivColor);
g.setFontAlign(0, -1, 0);
// draw allWords
var c;
var y = ys;
var x = xs;
allWords.forEach((line) => {
x = xs;
for (c in line) {
g.drawString(line[c], x, y);
x += dx;
}
y += dy;
});
// calc indexes
midx = Math.round(m / 5);
hidx = h % 12;
if (hidx === 0) { hidx = 12; }
if (midx > 6) {
if (midx == 12) { midx = 0; }
hidx++;
}
if (midx !== 0) {
if (midx <= 6) {
midxA = [midx, 6];
} else {
midxA = [12 - midx, 7];
}
}
// write hour in active color
g.setColor(activeColor);
hours[hidx][0].split('').forEach((c, pos) => {
x = xs + (hours[hidx][pos + 1] / 10 | 0) * dx;
y = ys + (hours[hidx][pos + 1] % 10) * dy;
g.drawString(c, x, y);
});
// write min words in active color
midxA.forEach(idx => {
mins[idx][0].split('').forEach((c, pos) => {
x = xs + (mins[idx][pos + 1] / 10 | 0) * dx;
y = ys + (mins[idx][pos + 1] % 10) * dy;
g.drawString(c, x, y);
});
});
// display digital time
g.setColor(activeColor);
g.clearRect(0, 215, 240, 240);
g.drawString(time, 120, 215);
}
Bangle.on('lcdPower', function(on) {
if (on) {
drawWidgets();
drawWordClock();
// draw allWords
var c;
var y = ys;
var x = xs;
allWords.forEach((line) => {
x = xs;
for (c in line) {
g.drawString(line[c], x, y);
x += dx;
}
y += dy;
});
g.clear();
setInterval(drawWordClock, 1E4);
drawWordClock();
// calc indexes
midx = Math.round(m / 5);
hidx = h % 12;
if (hidx === 0) { hidx = 12; }
if (midx > 6) {
if (midx == 12) { midx = 0; }
hidx++;
}
if (midx !== 0) {
if (midx <= 6) {
midxA = [midx, 6];
} else {
midxA = [12 - midx, 7];
}
}
})();
// write hour in active color
g.setColor(activeColor);
hours[hidx][0].split('').forEach((c, pos) => {
x = xs + (hours[hidx][pos + 1] / 10 | 0) * dx;
y = ys + (hours[hidx][pos + 1] % 10) * dy;
g.drawString(c, x, y);
});
// write min words in active color
midxA.forEach(idx => {
mins[idx][0].split('').forEach((c, pos) => {
x = xs + (mins[idx][pos + 1] / 10 | 0) * dx;
y = ys + (mins[idx][pos + 1] % 10) * dy;
g.drawString(c, x, y);
});
});
// display digital time
g.setColor(activeColor);
g.clearRect(0, 215, 240, 240);
g.drawString(time, 120, 215);
}
Bangle.on('lcdPower', function(on) {
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"});