1
0
Fork 0

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

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

View File

@ -185,7 +185,7 @@ about the app.
"name": "Readable name", // readable name
"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"});