forked from FOSS/BangleApps
Merge branch 'espruino:master' into torch
commit
08bcf49e77
|
@ -0,0 +1 @@
|
|||
0.01: First version
|
|
@ -0,0 +1,5 @@
|
|||
# BarWatch - an experimental watch
|
||||
|
||||
For too long the watches have shown the time with digits or hands. No more!
|
||||
With this stylish watch the time is represented by bars. Up to 24 as the day goes by.
|
||||
Practical? Not really, but a different look!
|
|
@ -0,0 +1 @@
|
|||
require("heatshrink").decompress(atob("l0uwkE/4A/AH4A/AB0gicQmUB+EPgEigExh8gj8A+ECAgMQn4WCgcACyotWC34W/C34W/CycACw0wgYWFBYIWCAAc/+YGHCAgNFACkxl8hGYwAMLYUvCykQC34WycoIW/C34W0gAWTmUjkUzkbmSAFY="))
|
|
@ -0,0 +1,76 @@
|
|||
// timeout used to update every minute
|
||||
var drawTimeout;
|
||||
|
||||
// schedule a draw for the next minute
|
||||
function queueDraw() {
|
||||
if (drawTimeout) clearTimeout(drawTimeout);
|
||||
drawTimeout = setTimeout(function() {
|
||||
drawTimeout = undefined;
|
||||
draw();
|
||||
}, 60000 - (Date.now() % 60000));
|
||||
}
|
||||
|
||||
|
||||
function draw() {
|
||||
g.reset();
|
||||
|
||||
if(g.theme.dark){
|
||||
g.setColor(1,1,1);
|
||||
}else{
|
||||
g.setColor(0,0,0);
|
||||
}
|
||||
|
||||
// work out how to display the current time
|
||||
var d = new Date();
|
||||
var h = d.getHours(), m = d.getMinutes();
|
||||
|
||||
// hour bars
|
||||
var bx_offset = 10, by_offset = 35;
|
||||
var b_width = 8, b_height = 60;
|
||||
var b_space = 5;
|
||||
|
||||
for(var i=0; i<h; i++){
|
||||
if(i > 11){
|
||||
by_offset = 105;
|
||||
}
|
||||
var iter = i % 12;
|
||||
//console.log(iter);
|
||||
g.fillRect(bx_offset+(b_width*(iter+1))+(b_space*iter),
|
||||
by_offset,
|
||||
bx_offset+(b_width*iter)+(b_space*iter),
|
||||
by_offset+b_height);
|
||||
}
|
||||
|
||||
// minute bar
|
||||
if(h > 11){
|
||||
by_offset = 105;
|
||||
}
|
||||
var m_bar = h % 12;
|
||||
if(m != 0){
|
||||
g.fillRect(bx_offset+(b_width*(m_bar+1))+(b_space*m_bar),
|
||||
by_offset+b_height-m,
|
||||
bx_offset+(b_width*m_bar)+(b_space*m_bar),
|
||||
by_offset+b_height);
|
||||
}
|
||||
|
||||
// queue draw in one minute
|
||||
queueDraw();
|
||||
}
|
||||
|
||||
// Clear the screen once, at startup
|
||||
g.clear();
|
||||
// draw immediately at first
|
||||
draw();
|
||||
// Stop updates when LCD is off, restart when on
|
||||
Bangle.on('lcdPower',on=>{
|
||||
if (on) {
|
||||
draw(); // draw immediately, queue redraw
|
||||
} else { // stop draw timer
|
||||
if (drawTimeout) clearTimeout(drawTimeout);
|
||||
drawTimeout = undefined;
|
||||
}
|
||||
});
|
||||
|
||||
Bangle.setUI("clock");
|
||||
Bangle.loadWidgets();
|
||||
Bangle.drawWidgets();
|
Binary file not shown.
After Width: | Height: | Size: 973 B |
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"id": "barwatch",
|
||||
"name": "BarWatch",
|
||||
"shortName":"BarWatch",
|
||||
"version":"0.01",
|
||||
"description": "A watch that displays the time using bars. One bar for each hour.",
|
||||
"readme": "README.md",
|
||||
"icon": "screenshot.png",
|
||||
"tags": "clock",
|
||||
"type": "clock",
|
||||
"allow_emulator":true,
|
||||
"screenshots" : [ { "url": "screenshot.png" } ],
|
||||
"supports" : ["BANGLEJS2"],
|
||||
"storage": [
|
||||
{"name":"barwatch.app.js","url":"app.js"},
|
||||
{"name":"barwatch.img","url":"app-icon.js","evaluate":true}
|
||||
]
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
|
@ -3,3 +3,4 @@
|
|||
0.03: Made the code shorter and somewhat more readable by writing some functions. Also made it work as a library where it returns the text once finished. The keyboard is now made to exit correctly when the 'back' event is called. The keyboard now uses theme colors correctly, although it still looks best with dark theme. The numbers row is now solidly green - except for highlights.
|
||||
0.04: Now displays the opened text string at launch.
|
||||
0.05: Now scrolls text when string gets longer than screen width.
|
||||
0.06: The code is now more reliable and the input snappier. Widgets will be drawn if present.
|
||||
|
|
|
@ -1,12 +1,9 @@
|
|||
//Keep banglejs screen on for 100 sec at 0.55 power level for development purposes
|
||||
//Bangle.setLCDTimeout(30);
|
||||
//Bangle.setLCDPower(1);
|
||||
|
||||
exports.input = function(options) {
|
||||
options = options||{};
|
||||
var text = options.text;
|
||||
if ("string"!=typeof text) text="";
|
||||
|
||||
|
||||
var R = Bangle.appRect;
|
||||
var BGCOLOR = g.theme.bg;
|
||||
var HLCOLOR = g.theme.fg;
|
||||
var ABCCOLOR = g.toColor(1,0,0);//'#FF0000';
|
||||
|
@ -17,35 +14,38 @@ exports.input = function(options) {
|
|||
var SMALLFONTWIDTH = parseInt(SMALLFONT.charAt(0)*parseInt(SMALLFONT.charAt(-1)));
|
||||
|
||||
var ABC = 'abcdefghijklmnopqrstuvwxyz'.toUpperCase();
|
||||
var ABCPADDING = (g.getWidth()-6*ABC.length)/2;
|
||||
var ABCPADDING = ((R.x+R.w)-6*ABC.length)/2;
|
||||
|
||||
var NUM = ' 1234567890!?,.- ';
|
||||
var NUMHIDDEN = ' 1234567890!?,.- ';
|
||||
var NUMPADDING = (g.getWidth()-6*NUM.length)/2;
|
||||
var NUMPADDING = ((R.x+R.w)-6*NUM.length)/2;
|
||||
|
||||
var rectHeight = 40;
|
||||
|
||||
|
||||
var delSpaceLast;
|
||||
|
||||
function drawAbcRow() {
|
||||
g.clear();
|
||||
try { // Draw widgets if they are present in the current app.
|
||||
if (WIDGETS) Bangle.drawWidgets();
|
||||
} catch (_) {}
|
||||
g.setFont(SMALLFONT);
|
||||
g.setColor(ABCCOLOR);
|
||||
g.drawString(ABC, ABCPADDING, g.getHeight()/2);
|
||||
g.fillRect(0, g.getHeight()-26, g.getWidth(), g.getHeight());
|
||||
g.setFontAlign(-1, -1, 0);
|
||||
g.drawString(ABC, ABCPADDING, (R.y+R.h)/2);
|
||||
g.fillRect(0, (R.y+R.h)-26, (R.x+R.w), (R.y+R.h));
|
||||
}
|
||||
|
||||
function drawNumRow() {
|
||||
g.setFont(SMALLFONT);
|
||||
g.setColor(NUMCOLOR);
|
||||
g.drawString(NUM, NUMPADDING, g.getHeight()/4);
|
||||
g.setFontAlign(-1, -1, 0);
|
||||
g.drawString(NUM, NUMPADDING, (R.y+R.h)/4);
|
||||
|
||||
g.fillRect(NUMPADDING, g.getHeight()-rectHeight*4/3, g.getWidth()-NUMPADDING, g.getHeight()-rectHeight*2/3);
|
||||
g.fillRect(NUMPADDING, (R.y+R.h)-rectHeight*4/3, (R.x+R.w)-NUMPADDING, (R.y+R.h)-rectHeight*2/3);
|
||||
}
|
||||
|
||||
function updateTopString() {
|
||||
"ram"
|
||||
g.setColor(BGCOLOR);
|
||||
g.fillRect(0,4+20,176,13+20);
|
||||
g.setColor(0.2,0,0);
|
||||
|
@ -54,13 +54,10 @@ exports.input = function(options) {
|
|||
g.setColor(0.7,0,0);
|
||||
g.fillRect(rectLen+5,4+20,rectLen+10,13+20);
|
||||
g.setColor(1,1,1);
|
||||
g.setFontAlign(-1, -1, 0);
|
||||
g.drawString(text.length<=27? text.substr(-27, 27) : '<- '+text.substr(-24,24), 5, 5+20);
|
||||
}
|
||||
|
||||
drawAbcRow();
|
||||
drawNumRow();
|
||||
updateTopString();
|
||||
|
||||
var abcHL;
|
||||
var abcHLPrev = -10;
|
||||
var numHL;
|
||||
|
@ -68,194 +65,182 @@ exports.input = function(options) {
|
|||
var type = '';
|
||||
var typePrev = '';
|
||||
var largeCharOffset = 6;
|
||||
|
||||
|
||||
function resetChars(char, HLPrev, typePadding, heightDivisor, rowColor) {
|
||||
"ram"
|
||||
"ram";
|
||||
// Small character in list
|
||||
g.setColor(rowColor);
|
||||
g.setFont(SMALLFONT);
|
||||
g.drawString(char, typePadding + HLPrev*6, g.getHeight()/heightDivisor);
|
||||
g.setFontAlign(-1, -1, 0);
|
||||
g.drawString(char, typePadding + HLPrev*6, (R.y+R.h)/heightDivisor);
|
||||
// Large character
|
||||
g.setColor(BGCOLOR);
|
||||
g.fillRect(0,g.getHeight()/3,176,g.getHeight()/3+24);
|
||||
//g.drawString(charSet.charAt(HLPrev), typePadding + HLPrev*6 -largeCharOffset, g.getHeight()/3);; //Old implementation where I find the shape and place of letter to remove instead of just a rectangle.
|
||||
g.fillRect(0,(R.y+R.h)/3,176,(R.y+R.h)/3+24);
|
||||
//g.drawString(charSet.charAt(HLPrev), typePadding + HLPrev*6 -largeCharOffset, (R.y+R.h)/3);; //Old implementation where I find the shape and place of letter to remove instead of just a rectangle.
|
||||
// mark in the list
|
||||
}
|
||||
function showChars(char, HL, typePadding, heightDivisor) {
|
||||
"ram"
|
||||
"ram";
|
||||
// mark in the list
|
||||
g.setColor(HLCOLOR);
|
||||
g.setFont(SMALLFONT);
|
||||
if (char != 'del' && char != 'space') g.drawString(char, typePadding + HL*6, g.getHeight()/heightDivisor);
|
||||
g.setFontAlign(-1, -1, 0);
|
||||
if (char != 'del' && char != 'space') g.drawString(char, typePadding + HL*6, (R.y+R.h)/heightDivisor);
|
||||
// show new large character
|
||||
g.setFont(BIGFONT);
|
||||
g.drawString(char, typePadding + HL*6 -largeCharOffset, g.getHeight()/3);
|
||||
g.drawString(char, typePadding + HL*6 -largeCharOffset, (R.y+R.h)/3);
|
||||
g.setFont(SMALLFONT);
|
||||
}
|
||||
|
||||
|
||||
function initDraw() {
|
||||
//var R = Bangle.appRect; // To make sure it's properly updated. Not sure if this is needed.
|
||||
drawAbcRow();
|
||||
drawNumRow();
|
||||
updateTopString();
|
||||
}
|
||||
initDraw();
|
||||
//setTimeout(initDraw, 0); // So Bangle.appRect reads the correct environment. It would draw off to the side sometimes otherwise.
|
||||
|
||||
function changeCase(abcHL) {
|
||||
g.setColor(BGCOLOR);
|
||||
g.drawString(ABC, ABCPADDING, g.getHeight()/2);
|
||||
g.setFontAlign(-1, -1, 0);
|
||||
g.drawString(ABC, ABCPADDING, (R.y+R.h)/2);
|
||||
if (ABC.charAt(abcHL) == ABC.charAt(abcHL).toUpperCase()) ABC = ABC.toLowerCase();
|
||||
else ABC = ABC.toUpperCase();
|
||||
g.setColor(ABCCOLOR);
|
||||
g.drawString(ABC, ABCPADDING, g.getHeight()/2);
|
||||
g.drawString(ABC, ABCPADDING, (R.y+R.h)/2);
|
||||
}
|
||||
return new Promise((resolve,reject) => {
|
||||
// Interpret touch input
|
||||
// Interpret touch input
|
||||
Bangle.setUI({
|
||||
mode: 'custom',
|
||||
back: ()=>{
|
||||
Bangle.setUI();
|
||||
g.clearRect(Bangle.appRect);
|
||||
resolve(text);
|
||||
},
|
||||
drag: function(event) {
|
||||
mode: 'custom',
|
||||
back: ()=>{
|
||||
Bangle.setUI();
|
||||
g.clearRect(Bangle.appRect);
|
||||
resolve(text);
|
||||
},
|
||||
drag: function(event) {
|
||||
"ram";
|
||||
// ABCDEFGHIJKLMNOPQRSTUVWXYZ
|
||||
// Choose character by draging along red rectangle at bottom of screen
|
||||
if (event.y >= ( (R.y+R.h) - 12 )) {
|
||||
// Translate x-position to character
|
||||
if (event.x < ABCPADDING) { abcHL = 0; }
|
||||
else if (event.x >= 176-ABCPADDING) { abcHL = 25; }
|
||||
else { abcHL = Math.floor((event.x-ABCPADDING)/6); }
|
||||
|
||||
// ABCDEFGHIJKLMNOPQRSTUVWXYZ
|
||||
// Choose character by draging along red rectangle at bottom of screen
|
||||
if (event.y >= ( g.getHeight() - 12 )) {
|
||||
// Translate x-position to character
|
||||
if (event.x < ABCPADDING) { abcHL = 0; }
|
||||
else if (event.x >= 176-ABCPADDING) { abcHL = 25; }
|
||||
else { abcHL = Math.floor((event.x-ABCPADDING)/6); }
|
||||
// Datastream for development purposes
|
||||
//print(event.x, event.y, event.b, ABC.charAt(abcHL), ABC.charAt(abcHLPrev));
|
||||
|
||||
// Datastream for development purposes
|
||||
//print(event.x, event.y, event.b, ABC.charAt(abcHL), ABC.charAt(abcHLPrev));
|
||||
// Unmark previous character and mark the current one...
|
||||
// Handling switching between letters and numbers/punctuation
|
||||
if (typePrev != 'abc') resetChars(NUM.charAt(numHLPrev), numHLPrev, NUMPADDING, 4, NUMCOLOR);
|
||||
|
||||
// Unmark previous character and mark the current one...
|
||||
// Handling switching between letters and numbers/punctuation
|
||||
if (typePrev != 'abc') resetChars(NUM.charAt(numHLPrev), numHLPrev, NUMPADDING, 4, NUMCOLOR);
|
||||
|
||||
if (abcHL != abcHLPrev) {
|
||||
resetChars(ABC.charAt(abcHLPrev), abcHLPrev, ABCPADDING, 2, ABCCOLOR);
|
||||
showChars(ABC.charAt(abcHL), abcHL, ABCPADDING, 2);
|
||||
if (abcHL != abcHLPrev) {
|
||||
resetChars(ABC.charAt(abcHLPrev), abcHLPrev, ABCPADDING, 2, ABCCOLOR);
|
||||
showChars(ABC.charAt(abcHL), abcHL, ABCPADDING, 2);
|
||||
}
|
||||
// Print string at top of screen
|
||||
if (event.b == 0) {
|
||||
text = text + ABC.charAt(abcHL);
|
||||
updateTopString();
|
||||
|
||||
// Autoswitching letter case
|
||||
if (ABC.charAt(abcHL) == ABC.charAt(abcHL).toUpperCase()) changeCase(abcHL);
|
||||
}
|
||||
// Update previous character to current one
|
||||
abcHLPrev = abcHL;
|
||||
typePrev = 'abc';
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// 12345678901234567890
|
||||
// Choose number or puctuation by draging on green rectangle
|
||||
else if ((event.y < ( g.getHeight() - 12 )) && (event.y > ( g.getHeight() - 52 ))) {
|
||||
// Translate x-position to character
|
||||
if (event.x < NUMPADDING) { numHL = 0; }
|
||||
else if (event.x > 176-NUMPADDING) { numHL = NUM.length-1; }
|
||||
else { numHL = Math.floor((event.x-NUMPADDING)/6); }
|
||||
|
||||
// Datastream for development purposes
|
||||
//print(event.x, event.y, event.b, NUM.charAt(numHL), NUM.charAt(numHLPrev));
|
||||
|
||||
// Unmark previous character and mark the current one...
|
||||
// Handling switching between letters and numbers/punctuation
|
||||
if (typePrev != 'num') resetChars(ABC.charAt(abcHLPrev), abcHLPrev, ABCPADDING, 2, ABCCOLOR);
|
||||
|
||||
if (numHL != numHLPrev) {
|
||||
resetChars(NUM.charAt(numHLPrev), numHLPrev, NUMPADDING, 4, NUMCOLOR);
|
||||
showChars(NUM.charAt(numHL), numHL, NUMPADDING, 4);
|
||||
}
|
||||
// Print string at top of screen
|
||||
if (event.b == 0) {
|
||||
g.setColor(HLCOLOR);
|
||||
// Backspace if releasing before list of numbers/punctuation
|
||||
if (event.x < NUMPADDING) {
|
||||
// show delete sign
|
||||
showChars('del', 0, g.getWidth()/2 +6 -27 , 4);
|
||||
delSpaceLast = 1;
|
||||
text = text.slice(0, -1);
|
||||
updateTopString();
|
||||
//print(text);
|
||||
}
|
||||
// Append space if releasing after list of numbers/punctuation
|
||||
else if (event.x > g.getWidth()-NUMPADDING) {
|
||||
//show space sign
|
||||
showChars('space', 0, g.getWidth()/2 +6 -6*3*5/2 , 4);
|
||||
delSpaceLast = 1;
|
||||
text = text + ' ';
|
||||
updateTopString();
|
||||
//print(text);
|
||||
}
|
||||
// Append selected number/punctuation
|
||||
else {
|
||||
text = text + NUMHIDDEN.charAt(numHL);
|
||||
// Print string at top of screen
|
||||
if (event.b == 0) {
|
||||
text = text + ABC.charAt(abcHL);
|
||||
updateTopString();
|
||||
|
||||
// Autoswitching letter case
|
||||
if ((text.charAt(text.length-1) == '.') || (text.charAt(text.length-1) == '!')) changeCase();
|
||||
if (ABC.charAt(abcHL) == ABC.charAt(abcHL).toUpperCase()) changeCase(abcHL);
|
||||
}
|
||||
// Update previous character to current one
|
||||
abcHLPrev = abcHL;
|
||||
typePrev = 'abc';
|
||||
}
|
||||
// Update previous character to current one
|
||||
numHLPrev = numHL;
|
||||
typePrev = 'num';
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Make a space or backspace by swiping right or left on screen above green rectangle
|
||||
else if (event.y > 20+4) {
|
||||
if (event.b == 0) {
|
||||
g.setColor(HLCOLOR);
|
||||
if (event.x < g.getWidth()/2) {
|
||||
resetChars(ABC.charAt(abcHLPrev), abcHLPrev, ABCPADDING, 2, ABCCOLOR);
|
||||
|
||||
// 12345678901234567890
|
||||
// Choose number or puctuation by draging on green rectangle
|
||||
else if ((event.y < ( (R.y+R.h) - 12 )) && (event.y > ( (R.y+R.h) - 52 ))) {
|
||||
// Translate x-position to character
|
||||
if (event.x < NUMPADDING) { numHL = 0; }
|
||||
else if (event.x > 176-NUMPADDING) { numHL = NUM.length-1; }
|
||||
else { numHL = Math.floor((event.x-NUMPADDING)/6); }
|
||||
|
||||
// Datastream for development purposes
|
||||
//print(event.x, event.y, event.b, NUM.charAt(numHL), NUM.charAt(numHLPrev));
|
||||
|
||||
// Unmark previous character and mark the current one...
|
||||
// Handling switching between letters and numbers/punctuation
|
||||
if (typePrev != 'num') resetChars(ABC.charAt(abcHLPrev), abcHLPrev, ABCPADDING, 2, ABCCOLOR);
|
||||
|
||||
if (numHL != numHLPrev) {
|
||||
resetChars(NUM.charAt(numHLPrev), numHLPrev, NUMPADDING, 4, NUMCOLOR);
|
||||
|
||||
// show delete sign
|
||||
showChars('del', 0, g.getWidth()/2 +6 -27 , 4);
|
||||
delSpaceLast = 1;
|
||||
|
||||
// Backspace and draw string upper right corner
|
||||
text = text.slice(0, -1);
|
||||
updateTopString();
|
||||
if (text.length==0) changeCase(abcHL);
|
||||
//print(text, 'undid');
|
||||
showChars(NUM.charAt(numHL), numHL, NUMPADDING, 4);
|
||||
}
|
||||
else {
|
||||
resetChars(ABC.charAt(abcHLPrev), abcHLPrev, ABCPADDING, 2, ABCCOLOR);
|
||||
resetChars(NUM.charAt(numHLPrev), numHLPrev, NUMPADDING, 4, NUMCOLOR);
|
||||
// Print string at top of screen
|
||||
if (event.b == 0) {
|
||||
g.setColor(HLCOLOR);
|
||||
// Backspace if releasing before list of numbers/punctuation
|
||||
if (event.x < NUMPADDING) {
|
||||
// show delete sign
|
||||
showChars('del', 0, (R.x+R.w)/2 +6 -27 , 4);
|
||||
delSpaceLast = 1;
|
||||
text = text.slice(0, -1);
|
||||
updateTopString();
|
||||
//print(text);
|
||||
}
|
||||
// Append space if releasing after list of numbers/punctuation
|
||||
else if (event.x > (R.x+R.w)-NUMPADDING) {
|
||||
//show space sign
|
||||
showChars('space', 0, (R.x+R.w)/2 +6 -6*3*5/2 , 4);
|
||||
delSpaceLast = 1;
|
||||
text = text + ' ';
|
||||
updateTopString();
|
||||
//print(text);
|
||||
}
|
||||
// Append selected number/punctuation
|
||||
else {
|
||||
text = text + NUMHIDDEN.charAt(numHL);
|
||||
updateTopString();
|
||||
|
||||
//show space sign
|
||||
showChars('space', 0, g.getWidth()/2 +6 -6*3*5/2 , 4);
|
||||
delSpaceLast = 1;
|
||||
// Autoswitching letter case
|
||||
if ((text.charAt(text.length-1) == '.') || (text.charAt(text.length-1) == '!')) changeCase();
|
||||
}
|
||||
}
|
||||
// Update previous character to current one
|
||||
numHLPrev = numHL;
|
||||
typePrev = 'num';
|
||||
}
|
||||
|
||||
// Append space and draw string upper right corner
|
||||
text = text + NUMHIDDEN.charAt(0);
|
||||
updateTopString();
|
||||
//print(text, 'made space');
|
||||
// Make a space or backspace by swiping right or left on screen above green rectangle
|
||||
else if (event.y > 20+4) {
|
||||
if (event.b == 0) {
|
||||
g.setColor(HLCOLOR);
|
||||
if (event.x < (R.x+R.w)/2) {
|
||||
resetChars(ABC.charAt(abcHLPrev), abcHLPrev, ABCPADDING, 2, ABCCOLOR);
|
||||
resetChars(NUM.charAt(numHLPrev), numHLPrev, NUMPADDING, 4, NUMCOLOR);
|
||||
|
||||
// show delete sign
|
||||
showChars('del', 0, (R.x+R.w)/2 +6 -27 , 4);
|
||||
delSpaceLast = 1;
|
||||
|
||||
// Backspace and draw string upper right corner
|
||||
text = text.slice(0, -1);
|
||||
updateTopString();
|
||||
if (text.length==0) changeCase(abcHL);
|
||||
//print(text, 'undid');
|
||||
}
|
||||
else {
|
||||
resetChars(ABC.charAt(abcHLPrev), abcHLPrev, ABCPADDING, 2, ABCCOLOR);
|
||||
resetChars(NUM.charAt(numHLPrev), numHLPrev, NUMPADDING, 4, NUMCOLOR);
|
||||
|
||||
//show space sign
|
||||
showChars('space', 0, (R.x+R.w)/2 +6 -6*3*5/2 , 4);
|
||||
delSpaceLast = 1;
|
||||
|
||||
// Append space and draw string upper right corner
|
||||
text = text + NUMHIDDEN.charAt(0);
|
||||
updateTopString();
|
||||
//print(text, 'made space');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
/* return new Promise((resolve,reject) => {
|
||||
Bangle.setUI({mode:"custom", back:()=>{
|
||||
Bangle.setUI();
|
||||
g.clearRect(Bangle.appRect);
|
||||
Bangle.setUI();
|
||||
resolve(text);
|
||||
}});
|
||||
}); */
|
||||
|
||||
});
|
||||
});
|
||||
};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{ "id": "dragboard",
|
||||
"name": "Dragboard",
|
||||
"version":"0.05",
|
||||
"version":"0.06",
|
||||
"description": "A library for text input via swiping keyboard",
|
||||
"icon": "app.png",
|
||||
"type":"textinput",
|
||||
|
|
|
@ -16,3 +16,6 @@
|
|||
0.16: Use default Bangle formatter for booleans
|
||||
0.17: Bangle 2: Fast loading on exit to clock face. Added option for exit to
|
||||
clock face by timeout.
|
||||
0.18: Move interactions inside setUI. Replace "one click exit" with
|
||||
back-functionality through setUI, adding the red back button as well. Hardware
|
||||
button to exit is no longer an option.
|
||||
|
|
|
@ -8,15 +8,10 @@ let settings = Object.assign({
|
|||
showClocks: true,
|
||||
showLaunchers: true,
|
||||
direct: false,
|
||||
oneClickExit: false,
|
||||
swipeExit: false,
|
||||
timeOut: "Off"
|
||||
}, require('Storage').readJSON("dtlaunch.json", true) || {});
|
||||
|
||||
if (settings.oneClickExit) {
|
||||
var buttonWatch = setWatch(_=> returnToClock(), BTN1, {edge: 'falling'});
|
||||
}
|
||||
|
||||
let s = require("Storage");
|
||||
var apps = s.list(/\.info$/).map(app=>{
|
||||
let a=s.readJSON(app,1);
|
||||
|
@ -91,7 +86,7 @@ let drawPage = function(p){
|
|||
|
||||
Bangle.loadWidgets();
|
||||
//g.clear();
|
||||
Bangle.drawWidgets();
|
||||
//Bangle.drawWidgets();
|
||||
drawPage(0);
|
||||
|
||||
let swipeListenerDt = function(dirLeftRight, dirUpDown){
|
||||
|
@ -106,7 +101,6 @@ let swipeListenerDt = function(dirLeftRight, dirUpDown){
|
|||
drawPage(page);
|
||||
}
|
||||
};
|
||||
Bangle.on("swipe",swipeListenerDt);
|
||||
|
||||
let isTouched = function(p,n){
|
||||
if (n<0 || n>3) return false;
|
||||
|
@ -138,25 +132,18 @@ let touchListenerDt = function(_,p){
|
|||
selected=-1;
|
||||
}
|
||||
};
|
||||
Bangle.on("touch",touchListenerDt);
|
||||
|
||||
const returnToClock = function() {
|
||||
Bangle.setUI();
|
||||
if (buttonWatch) {
|
||||
clearWatch(buttonWatch);
|
||||
delete buttonWatch;
|
||||
}
|
||||
if (timeoutToClock) {
|
||||
clearTimeout(timeoutToClock);
|
||||
delete timeoutToClock;
|
||||
}
|
||||
Bangle.removeListener("swipe", swipeListenerDt);
|
||||
Bangle.removeListener("touch", touchListenerDt);
|
||||
var apps = [];
|
||||
delete apps;
|
||||
delete returnToClock;
|
||||
setTimeout(eval, 0, s.read(".bootcde"));
|
||||
};
|
||||
|
||||
Bangle.setUI({
|
||||
mode : 'custom',
|
||||
back : returnToClock,
|
||||
swipe : swipeListenerDt,
|
||||
touch : touchListenerDt
|
||||
});
|
||||
|
||||
// taken from Icon Launcher with minor alterations
|
||||
var timeoutToClock;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"id": "dtlaunch",
|
||||
"name": "Desktop Launcher",
|
||||
"version": "0.17",
|
||||
"version": "0.18",
|
||||
"description": "Desktop style App Launcher with six (four for Bangle 2) apps per page - fast access if you have lots of apps installed.",
|
||||
"screenshots": [{"url":"shot1.png"},{"url":"shot2.png"},{"url":"shot3.png"}],
|
||||
"icon": "icon.png",
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
showClocks: true,
|
||||
showLaunchers: true,
|
||||
direct: false,
|
||||
oneClickExit:false,
|
||||
swipeExit: false,
|
||||
timeOut: "Off"
|
||||
}, require('Storage').readJSON(FILE, true) || {});
|
||||
|
@ -47,13 +46,6 @@
|
|||
writeSettings();
|
||||
}
|
||||
},
|
||||
/*LANG*/'One click exit': {
|
||||
value: settings.oneClickExit,
|
||||
onchange: v => {
|
||||
settings.oneClickExit = v;
|
||||
writeSettings();
|
||||
}
|
||||
},
|
||||
/*LANG*/'Time Out': { // Adapted from Icon Launcher
|
||||
value: timeOutChoices.indexOf(settings.timeOut),
|
||||
min: 0,
|
||||
|
@ -63,6 +55,6 @@
|
|||
settings.timeOut = timeOutChoices[v];
|
||||
writeSettings();
|
||||
}
|
||||
},
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
@ -12,3 +12,5 @@
|
|||
used Object.assing for the settings
|
||||
fix cache not deleted when "showClocks" options is changed
|
||||
added timeOut to return to the clock
|
||||
0.11: Cleanup timeout when changing to clock
|
||||
Reset timeout on swipe and drag
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
timeOut:"Off"
|
||||
}, s.readJSON("iconlaunch.json", true) || {});
|
||||
|
||||
console.log(settings);
|
||||
if (!settings.fullscreen) {
|
||||
Bangle.loadWidgets();
|
||||
Bangle.drawWidgets();
|
||||
|
@ -133,6 +132,7 @@
|
|||
g.flip();
|
||||
const itemsN = Math.ceil(launchCache.apps.length / appsN);
|
||||
let onDrag = function(e) {
|
||||
updateTimeout();
|
||||
g.setColor(g.theme.fg);
|
||||
g.setBgColor(g.theme.bg);
|
||||
let dy = e.dy;
|
||||
|
@ -182,6 +182,7 @@
|
|||
drag: onDrag,
|
||||
touch: (_, e) => {
|
||||
if (e.y < R.y - 4) return;
|
||||
updateTimeout();
|
||||
let i = YtoIdx(e.y);
|
||||
selectItem(i, e);
|
||||
},
|
||||
|
@ -202,16 +203,23 @@
|
|||
delete idxToY;
|
||||
delete YtoIdx;
|
||||
delete settings;
|
||||
if (timeout) clearTimeout(timeout);
|
||||
setTimeout(eval, 0, s.read(".bootcde"));
|
||||
};
|
||||
|
||||
|
||||
if (settings.oneClickExit) mode.btn = returnToClock;
|
||||
|
||||
let timeout;
|
||||
const updateTimeout = function(){
|
||||
if (settings.timeOut!="Off"){
|
||||
let time=parseInt(settings.timeOut); //the "s" will be trimmed by the parseInt
|
||||
setTimeout(returnToClock,time*1000);
|
||||
if (timeout) clearTimeout(timeout);
|
||||
timeout = setTimeout(returnToClock,time*1000);
|
||||
}
|
||||
}
|
||||
|
||||
updateTimeout();
|
||||
|
||||
Bangle.setUI(mode);
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"id": "iconlaunch",
|
||||
"name": "Icon Launcher",
|
||||
"shortName" : "Icon launcher",
|
||||
"version": "0.10",
|
||||
"version": "0.11",
|
||||
"icon": "app.png",
|
||||
"description": "A launcher inspired by smartphones, with an icon-only scrollable menu.",
|
||||
"tags": "tool,system,launcher",
|
||||
|
|
|
@ -2,3 +2,4 @@
|
|||
0.02: Now keeps user input trace intact by changing how the screen is updated.
|
||||
0.03: Positioning of marker now takes the height of the widget field into account.
|
||||
0.04: Fix issue if going back without typing.
|
||||
0.05: Keep drag-function in ram, hopefully improving performance and input reliability somewhat.
|
||||
|
|
|
@ -139,6 +139,7 @@ exports.getStrokes( (id,s) => Bangle.strokes[id] = Unistroke.new(s) );
|
|||
return new Promise((resolve,reject) => {
|
||||
var l;//last event
|
||||
Bangle.setUI({mode:"custom", drag:e=>{
|
||||
"ram";
|
||||
if (l) g.reset().setColor("#f00").drawLine(l.x,l.y,e.x,e.y);
|
||||
l = e.b ? e : 0;
|
||||
},touch:() => {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{ "id": "kbswipe",
|
||||
"name": "Swipe keyboard",
|
||||
"version":"0.04",
|
||||
"version":"0.05",
|
||||
"description": "A library for text input via PalmOS style swipe gestures (beta!)",
|
||||
"icon": "app.png",
|
||||
"type":"textinput",
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
0.01: New App!
|
||||
0.01: Clone of original SlopeClock
|
||||
0.02: Added configuration
|
||||
|
|
|
@ -11,6 +11,12 @@ Graphics.prototype.setFontPaytoneOne = function(scale) {
|
|||
|
||||
{ // must be inside our own scope here so that when we are unloaded everything disappears
|
||||
// we also define functions using 'let fn = function() {..}' for the same reason. function decls are global
|
||||
|
||||
let settings = Object.assign(
|
||||
require("Storage").readJSON("slopeclockpp.default.json", true) || {},
|
||||
require("Storage").readJSON("slopeclockpp.json", true) || {}
|
||||
);
|
||||
|
||||
let drawTimeout;
|
||||
|
||||
let g2 = Graphics.createArrayBuffer(g.getWidth(),90,1,{msb:true});
|
||||
|
@ -24,7 +30,16 @@ const fontBorder = 4; // offset from left/right
|
|||
const slopeBorder = 10, slopeBorderUpper = 4; // fudge-factor to move minutes down from slope
|
||||
let R,x,y; // middle of the clock face
|
||||
let dateStr = "";
|
||||
let bgColors = g.theme.dark ? ["#ff0","#0ff","#f0f"] : ["#f00","#0f0","#00f"];
|
||||
let bgColors = [];
|
||||
if (g.theme.dark) {
|
||||
if (settings.colorYellow) bgColors.push("#ff0");
|
||||
if (settings.colorCyan) bgColors.push("#0ff");
|
||||
if (settings.colorMagenta) bgColors.push("#f0f");
|
||||
} else {
|
||||
if (settings.colorRed) bgColors.push("#f00");
|
||||
if (settings.colorGreen) bgColors.push("#0f0");
|
||||
if (settings.colorBlue) bgColors.push("#00f");
|
||||
}
|
||||
let bgColor = bgColors[(Math.random()*bgColors.length)|0];
|
||||
|
||||
|
||||
|
@ -95,19 +110,23 @@ let animate = function(isIn, callback) {
|
|||
// draw the date
|
||||
g.setColor(g.theme.bg).setFontAlign(0, 0).setFont("6x15").drawString(dateStr, R.x + R.w/2, R.y+R.h-9);
|
||||
|
||||
if (settings.showSteps) {
|
||||
// draw steps to bottom left
|
||||
const steps = getSteps();
|
||||
if (steps > 0)
|
||||
g.setFontAlign(-1, 0).drawString(shortValue(steps), 3, R.y+R.h-30);
|
||||
}
|
||||
|
||||
// draw weather to top right
|
||||
const weather = getWeather();
|
||||
const tempString = weather ? require("locale").temp(weather.temp - 273.15) : undefined;
|
||||
const code = weather ? weather.code : -1;
|
||||
if (code > -1) {
|
||||
g.setColor(g.theme.fg).setFontAlign(1, 0).drawString(tempString, R.w - 3, y-slope-slopeBorderUpper);
|
||||
const icon = getWeatherIconByCode(code);
|
||||
if (icon) g.drawImage(icon, R.w - 3 - 15, y-slope-slopeBorderUpper - 15 - 15);
|
||||
if (settings.showWeather) {
|
||||
// draw weather to top right
|
||||
const weather = getWeather();
|
||||
const tempString = weather ? require("locale").temp(weather.temp - 273.15) : undefined;
|
||||
const code = weather ? weather.code : -1;
|
||||
if (code > -1) {
|
||||
g.setColor(g.theme.fg).setFontAlign(1, 0).drawString(tempString, R.w - 3, y-slope-slopeBorderUpper);
|
||||
const icon = getWeatherIconByCode(code);
|
||||
if (icon) g.drawImage(icon, R.w - 3 - 15, y-slope-slopeBorderUpper - 15 - 15);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (callback) callback();
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"showSteps": true,
|
||||
"showWeather": true,
|
||||
"colorRed": true,
|
||||
"colorGreen": true,
|
||||
"colorBlue": true,
|
||||
"colorYellow": true,
|
||||
"colorMagenta": true,
|
||||
"colorCyan": true
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
{ "id": "slopeclockpp",
|
||||
"name": "Slope Clock ++",
|
||||
"version":"0.01",
|
||||
"description": "A clock where hours and minutes are divided by a sloping line. When the minute changes, the numbers slide off the screen. This is a clone of the original Slope Clock which shows weather and steps.",
|
||||
"version":"0.02",
|
||||
"description": "A clock where hours and minutes are divided by a sloping line. When the minute changes, the numbers slide off the screen. This is a clone of the original Slope Clock which can show the weather and steps.",
|
||||
"icon": "app.png",
|
||||
"screenshots": [{"url":"screenshot.png"}],
|
||||
"type": "clock",
|
||||
|
@ -9,6 +9,11 @@
|
|||
"supports" : ["BANGLEJS2"],
|
||||
"storage": [
|
||||
{"name":"slopeclockpp.app.js","url":"app.js"},
|
||||
{"name":"slopeclockpp.img","url":"app-icon.js","evaluate":true}
|
||||
]
|
||||
{"name":"slopeclockpp.img","url":"app-icon.js","evaluate":true},
|
||||
{"name":"slopeclockpp.settings.js","url":"settings.js"},
|
||||
{"name":"slopeclockpp.default.json","url":"default.json"}
|
||||
],
|
||||
"data": [
|
||||
{"name":"slopeclockpp.json"}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
(function(back) {
|
||||
const SETTINGS_FILE = "slopeclockpp.json";
|
||||
const storage = require('Storage');
|
||||
let settings = Object.assign(
|
||||
storage.readJSON("slopeclockpp.default.json", true) || {},
|
||||
storage.readJSON(SETTINGS_FILE, true) || {}
|
||||
);
|
||||
|
||||
function save(key, value) {
|
||||
settings[key] = value;
|
||||
storage.write(SETTINGS_FILE, settings);
|
||||
}
|
||||
|
||||
function showMainMenu() {
|
||||
let menu ={
|
||||
'': { 'title': 'Slope Clock ++' },
|
||||
/*LANG*/'< Back': back,
|
||||
/*LANG*/'show steps': {
|
||||
value: !!settings.showSteps,
|
||||
format: () => (settings.showSteps ? 'Yes' : 'No'),
|
||||
onchange: x => save('showSteps', x),
|
||||
},
|
||||
/*LANG*/'show weather': {
|
||||
value: !!settings.showWeather,
|
||||
format: () => (settings.showWeather ? 'Yes' : 'No'),
|
||||
onchange: x => save('showWeather', x),
|
||||
},
|
||||
/*LANG*/'red': {
|
||||
value: !!settings.colorRed,
|
||||
format: () => (settings.colorRed ? 'Yes' : 'No'),
|
||||
onchange: x => save('colorRed', x),
|
||||
},
|
||||
/*LANG*/'green': {
|
||||
value: !!settings.colorGreen,
|
||||
format: () => (settings.colorGreen ? 'Yes' : 'No'),
|
||||
onchange: x => save('colorGreen', x),
|
||||
},
|
||||
/*LANG*/'blue': {
|
||||
value: !!settings.colorBlue,
|
||||
format: () => (settings.colorBlue ? 'Yes' : 'No'),
|
||||
onchange: x => save('colorBlue', x),
|
||||
},
|
||||
/*LANG*/'magenta': {
|
||||
value: !!settings.colorMagenta,
|
||||
format: () => (settings.colorMagenta ? 'Yes' : 'No'),
|
||||
onchange: x => save('colorMagenta', x),
|
||||
},
|
||||
/*LANG*/'cyan': {
|
||||
value: !!settings.colorCyan,
|
||||
format: () => (settings.colorCyan ? 'Yes' : 'No'),
|
||||
onchange: x => save('colorCyan', x),
|
||||
},
|
||||
/*LANG*/'yellow': {
|
||||
value: !!settings.colorYellow,
|
||||
format: () => (settings.colorYellow ? 'Yes' : 'No'),
|
||||
onchange: x => save('colorYellow', x),
|
||||
}
|
||||
};
|
||||
E.showMenu(menu);
|
||||
}
|
||||
|
||||
|
||||
showMainMenu();
|
||||
});
|
2
core
2
core
|
@ -1 +1 @@
|
|||
Subproject commit c3746cd81989852e002a659bdb60071018d84925
|
||||
Subproject commit 73bf64d42b9dac23871cbc60b5ab096132b65549
|
|
@ -162,7 +162,7 @@ window.addEventListener('load', (event) => {
|
|||
<label class="form-switch">
|
||||
<input type="checkbox" id="usage_stats" ${SETTINGS.sendUsageStats?"checked":""}>
|
||||
<i class="form-icon"></i> Send favourite and installed apps to banglejs.com<br/>
|
||||
<small>For 'Sort by Installed/Favourited' functionality</small>
|
||||
<small>For 'Sort by Installed/Favourited' functionality (see <a href="http://www.espruino.com/Privacy">privacy policy</a>)</small>
|
||||
</label>
|
||||
<label class="form-switch">
|
||||
<input type="checkbox" id="remember_device">
|
||||
|
|
|
@ -0,0 +1,163 @@
|
|||
{
|
||||
"env": {
|
||||
// TODO: "espruino": false
|
||||
// TODO: "banglejs": false
|
||||
},
|
||||
"extends": "eslint:recommended",
|
||||
"globals": {
|
||||
// Methods and Fields at https://banglejs.com/reference
|
||||
"Array": "readonly",
|
||||
"ArrayBuffer": "readonly",
|
||||
"ArrayBufferView": "readonly",
|
||||
"Bangle": "readonly",
|
||||
"BluetoothDevice": "readonly",
|
||||
"BluetoothRemoteGATTCharacteristic": "readonly",
|
||||
"BluetoothRemoteGATTServer": "readonly",
|
||||
"BluetoothRemoteGATTService": "readonly",
|
||||
"Boolean": "readonly",
|
||||
"console": "readonly",
|
||||
"DataView": "readonly",
|
||||
"Date": "readonly",
|
||||
"E": "readonly",
|
||||
"Error": "readonly",
|
||||
"Flash": "readonly",
|
||||
"Float32Array": "readonly",
|
||||
"Float64Array": "readonly",
|
||||
"fs": "readonly",
|
||||
"Function": "readonly",
|
||||
"Graphics": "readonly",
|
||||
"heatshrink": "readonly",
|
||||
"I2C": "readonly",
|
||||
"Int16Array": "readonly",
|
||||
"Int32Array": "readonly",
|
||||
"Int8Array": "readonly",
|
||||
"InternalError": "readonly",
|
||||
"JSON": "readonly",
|
||||
"Math": "readonly",
|
||||
"Modules": "readonly",
|
||||
"NRF": "readonly",
|
||||
"Number": "readonly",
|
||||
"Object": "readonly",
|
||||
"OneWire": "readonly",
|
||||
"Pin": "readonly",
|
||||
"process": "readonly",
|
||||
"Promise": "readonly",
|
||||
"ReferenceError": "readonly",
|
||||
"RegExp": "readonly",
|
||||
"Serial": "readonly",
|
||||
"SPI": "readonly",
|
||||
"Storage": "readonly",
|
||||
"StorageFile": "readonly",
|
||||
"String": "readonly",
|
||||
"SyntaxError": "readonly",
|
||||
"tensorflow": "readonly",
|
||||
"TFMicroInterpreter": "readonly",
|
||||
"TypeError": "readonly",
|
||||
"Uint16Array": "readonly",
|
||||
"Uint24Array": "readonly",
|
||||
"Uint32Array": "readonly",
|
||||
"Uint8Array": "readonly",
|
||||
"Uint8ClampedArray": "readonly",
|
||||
"Waveform": "readonly",
|
||||
// Methods and Fields at https://banglejs.com/reference
|
||||
"analogRead": "readonly",
|
||||
"analogWrite": "readonly",
|
||||
"arguments": "readonly",
|
||||
"atob": "readonly",
|
||||
"Bluetooth": "readonly",
|
||||
"BTN": "readonly",
|
||||
"BTN1": "readonly",
|
||||
"BTN2": "readonly",
|
||||
"BTN3": "readonly",
|
||||
"BTN4": "readonly",
|
||||
"BTN5": "readonly",
|
||||
"btoa": "readonly",
|
||||
"changeInterval": "readonly",
|
||||
"clearInterval": "readonly",
|
||||
"clearTimeout": "readonly",
|
||||
"clearWatch": "readonly",
|
||||
"decodeURIComponent": "readonly",
|
||||
"digitalPulse": "readonly",
|
||||
"digitalRead": "readonly",
|
||||
"digitalWrite": "readonly",
|
||||
"dump": "readonly",
|
||||
"echo": "readonly",
|
||||
"edit": "readonly",
|
||||
"encodeURIComponent": "readonly",
|
||||
"eval": "readonly",
|
||||
"getPinMode": "readonly",
|
||||
"getSerial": "readonly",
|
||||
"getTime": "readonly",
|
||||
"global": "readonly",
|
||||
"HIGH": "readonly",
|
||||
"I2C1": "readonly",
|
||||
"Infinity": "readonly",
|
||||
"isFinite": "readonly",
|
||||
"isNaN": "readonly",
|
||||
"LED": "readonly",
|
||||
"LED1": "readonly",
|
||||
"LED2": "readonly",
|
||||
"load": "readonly",
|
||||
"LoopbackA": "readonly",
|
||||
"LoopbackB": "readonly",
|
||||
"LOW": "readonly",
|
||||
"NaN": "readonly",
|
||||
"parseFloat": "readonly",
|
||||
"parseInt": "readonly",
|
||||
"peek16": "readonly",
|
||||
"peek32": "readonly",
|
||||
"peek8": "readonly",
|
||||
"pinMode": "readonly",
|
||||
"poke16": "readonly",
|
||||
"poke32": "readonly",
|
||||
"poke8": "readonly",
|
||||
"print": "readonly",
|
||||
"require": "readonly",
|
||||
"reset": "readonly",
|
||||
"save": "readonly",
|
||||
"Serial1": "readonly",
|
||||
"setBusyIndicator": "readonly",
|
||||
"setInterval": "readonly",
|
||||
"setSleepIndicator": "readonly",
|
||||
"setTime": "readonly",
|
||||
"setTimeout": "readonly",
|
||||
"setWatch": "readonly",
|
||||
"shiftOut": "readonly",
|
||||
"SPI1": "readonly",
|
||||
"Terminal": "readonly",
|
||||
"trace": "readonly",
|
||||
"VIBRATE": "readonly",
|
||||
// Aliases and not defined at https://banglejs.com/reference
|
||||
"g": "readonly",
|
||||
"WIDGETS": "readonly"
|
||||
},
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 11
|
||||
},
|
||||
"rules": {
|
||||
"indent": [
|
||||
"off",
|
||||
2,
|
||||
{
|
||||
"SwitchCase": 1
|
||||
}
|
||||
],
|
||||
"no-case-declarations": "off",
|
||||
"no-constant-condition": "off",
|
||||
"no-delete-var": "off",
|
||||
"no-empty": "off",
|
||||
"no-global-assign": "off",
|
||||
"no-inner-declarations": "off",
|
||||
"no-octal": "off",
|
||||
"no-prototype-builtins": "off",
|
||||
"no-redeclare": "off",
|
||||
"no-unreachable": "warn",
|
||||
"no-cond-assign": "warn",
|
||||
"no-useless-catch": "warn",
|
||||
// TODO: "no-undef": "warn",
|
||||
"no-undef": "off",
|
||||
"no-unused-vars": "off",
|
||||
"no-useless-escape": "off",
|
||||
"no-control-regex" : "off"
|
||||
}
|
||||
}
|
|
@ -82,7 +82,7 @@ ClockFace.prototype.start = function() {
|
|||
/* Some widgets want to know if we're in a clock or not (like chrono, widget clock, etc). Normally
|
||||
.CLOCK is set by Bangle.setUI('clock') but we want to load widgets so we can check appRect and *then*
|
||||
call setUI. see #1864 */
|
||||
Bangle.CLOCK = 1;
|
||||
Bangle.CLOCK = 1;
|
||||
if (this.loadWidgets) Bangle.loadWidgets();
|
||||
if (this.init) this.init.apply(this);
|
||||
if (this._upDown) Bangle.setUI("clockupdown", d=>this._upDown.apply(this,[d]));
|
||||
|
|
|
@ -10,10 +10,13 @@ that can be scrolled through on the clock face.
|
|||
Note that each item is an object with:
|
||||
|
||||
* 'item.name' : friendly name to identify an item (e.g. temperature)
|
||||
* 'item.hasRange' : if `true`, `.get` returns `v/min/max` values (for progress bar/guage)
|
||||
* 'item.get' : function that resolves with:
|
||||
{
|
||||
'text' : the text to display for this item
|
||||
'img' : a 24x24px image to display for this item
|
||||
'v' : (if hasRange==true) a numerical value
|
||||
'min','max' : (if hasRange==true) a minimum and maximum numerical value (if this were to be displayed as a guage)
|
||||
}
|
||||
* 'item.show' : called when item should be shown. Enables updates. Call BEFORE 'get'
|
||||
* 'item.hide' : called when item should be hidden. Disables updates.
|
||||
|
@ -30,7 +33,7 @@ example.clkinfo.js :
|
|||
img: atob("GBiBAAD+AAH+AAH+AAH+AAH/AAOHAAYBgAwAwBgwYBgwYBgwIBAwOBAwOBgYIBgMYBgAYAwAwAYBgAOHAAH/AAH+AAH+AAH+AAD+AA==") }),
|
||||
items: [
|
||||
{ name : "Item1",
|
||||
get : () => ({ text : "TextOfItem1",
|
||||
get : () => ({ text : "TextOfItem1", v : 10, min : 0, max : 100,
|
||||
img : atob("GBiBAAD+AAH+AAH+AAH+AAH/AAOHAAYBgAwAwBgwYBgwYBgwIBAwOBAwOBgYIBgMYBgAYAwAwAYBgAOHAAH/AAH+AAH+AAH+AAD+AA==") }),
|
||||
show : () => {},
|
||||
hide : () => {}
|
||||
|
@ -63,21 +66,29 @@ exports.load = function() {
|
|||
img: atob("GBiBAf8B//4B//4B//4B//4A//x4//n+f/P/P+fPn+fPn+fP3+/Px+/Px+fn3+fzn+f/n/P/P/n+f/x4//4A//4B//4B//4B//8B/w=="),
|
||||
items: [
|
||||
{ name : "Battery",
|
||||
get : () => ({
|
||||
text : E.getBattery() + "%",
|
||||
img : atob(Bangle.isCharging() ? "GBiBAAABgAADwAAHwAAPgACfAAHOAAPkBgHwDwP4Hwf8Pg/+fB//OD//kD//wD//4D//8D//4B//QB/+AD/8AH/4APnwAHAAACAAAA==" : "GBiBAAAAAAAAAAAAAAAAAAAAAD//+P///IAAAr//Ar//Ar//A7//A7//A7//A7//Ar//AoAAAv///D//+AAAAAAAAAAAAAAAAAAAAA==") }),
|
||||
hasRange : true,
|
||||
get : () => { let v = E.getBattery(); return {
|
||||
text : v + "%", v : v, min:0, max:100,
|
||||
img : atob(Bangle.isCharging() ? "GBiBAAABgAADwAAHwAAPgACfAAHOAAPkBgHwDwP4Hwf8Pg/+fB//OD//kD//wD//4D//8D//4B//QB/+AD/8AH/4APnwAHAAACAAAA==" : "GBiBAAAAAAAAAAAAAAAAAAAAAD//+P///IAAAr//Ar//Ar//A7//A7//A7//A7//Ar//AoAAAv///D//+AAAAAAAAAAAAAAAAAAAAA==")
|
||||
}},
|
||||
show : function() { this.interval = setInterval(()=>this.emit('redraw'), 60000); Bangle.on("charging", batteryUpdateHandler); batteryUpdateHandler(); },
|
||||
hide : function() { clearInterval(this.interval); delete this.interval; Bangle.removeListener("charging", batteryUpdateHandler); },
|
||||
},
|
||||
{ name : "Steps", get : () => ({
|
||||
text : Bangle.getHealthStatus("day").steps,
|
||||
img : atob("GBiBAAcAAA+AAA/AAA/AAB/AAB/gAA/g4A/h8A/j8A/D8A/D+AfH+AAH8AHn8APj8APj8AHj4AHg4AADAAAHwAAHwAAHgAAHgAADAA==") }),
|
||||
{ name : "Steps",
|
||||
hasRange : true,
|
||||
get : () => { let v = Bangle.getHealthStatus("day").steps; return {
|
||||
text : v, v : v, min : 0, max : 10000, // TODO: do we have a target step amount anywhere?
|
||||
img : atob("GBiBAAcAAA+AAA/AAA/AAB/AAB/gAA/g4A/h8A/j8A/D8A/D+AfH+AAH8AHn8APj8APj8AHj4AHg4AADAAAHwAAHwAAHgAAHgAADAA==")
|
||||
}},
|
||||
show : function() { Bangle.on("step", stepUpdateHandler); stepUpdateHandler(); },
|
||||
hide : function() { Bangle.removeListener("step", stepUpdateHandler); },
|
||||
},
|
||||
{ name : "HRM", get : () => ({
|
||||
text : Math.round(Bangle.getHealthStatus("last").bpm) + " bpm",
|
||||
img : atob("GBiBAAAAAAAAAAAAAAAAAAAAAADAAADAAAHAAAHjAAHjgAPngH9n/n82/gA+AAA8AAA8AAAcAAAYAAAYAAAAAAAAAAAAAAAAAAAAAA==") }),
|
||||
{ name : "HRM",
|
||||
hasRange : true,
|
||||
get : () => { let v = Math.round(Bangle.getHealthStatus("last").bpm); return {
|
||||
text : v + " bpm", v : v, min : 40, max : 200,
|
||||
img : atob("GBiBAAAAAAAAAAAAAAAAAAAAAADAAADAAAHAAAHjAAHjgAPngH9n/n82/gA+AAA8AAA8AAAcAAAYAAAYAAAAAAAAAAAAAAAAAAAAAA==")
|
||||
}},
|
||||
show : function() { Bangle.setHRMPower(1,"clkinfo"); Bangle.on("HRM", hrmUpdateHandler); hrm = Math.round(Bangle.getHealthStatus("last").bpm); hrmUpdateHandler(); },
|
||||
hide : function() { Bangle.setHRMPower(0,"clkinfo"); Bangle.removeListener("HRM", hrmUpdateHandler); hrm = "--"; },
|
||||
}
|
||||
|
@ -86,9 +97,11 @@ exports.load = function() {
|
|||
var bangleItems = menu[0].items;
|
||||
|
||||
if (Bangle.getPressure){ // Altimeter may not exist
|
||||
bangleItems.push({ name : "Altitude", get : () => ({
|
||||
text : alt,
|
||||
img : atob("GBiBAAAAAAAAAAAAAAAAAAAAAAACAAAGAAAPAAEZgAOwwAPwQAZgYAwAMBgAGBAACDAADGAABv///////wAAAAAAAAAAAAAAAAAAAA==") }),
|
||||
bangleItems.push({ name : "Altitude",
|
||||
get : () => ({
|
||||
text : alt, v : alt,
|
||||
img : atob("GBiBAAAAAAAAAAAAAAAAAAAAAAACAAAGAAAPAAEZgAOwwAPwQAZgYAwAMBgAGBAACDAADGAABv///////wAAAAAAAAAAAAAAAAAAAA==")
|
||||
}),
|
||||
show : function() { this.interval = setInterval(altUpdateHandler, 60000); alt = "--"; altUpdateHandler(); },
|
||||
hide : function() { clearInterval(this.interval); delete this.interval; },
|
||||
});
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
},
|
||||
"scripts": {
|
||||
"lint-apps": "eslint ./apps --ext .js",
|
||||
"test": "node bin/sanitycheck.js && eslint ./apps --ext .js",
|
||||
"test": "node bin/sanitycheck.js && eslint ./apps --ext .js && eslint ./modules --ext .js",
|
||||
"update-local-apps": "./bin/create_apps_json.sh apps.local.json",
|
||||
"local": "npm-watch & npx http-server -a localhost -c-1",
|
||||
"start": "npx http-server -c-1"
|
||||
|
|
Loading…
Reference in New Issue