Merge branch 'espruino:master' into master

pull/1241/head
Peer David 2022-01-06 12:00:16 +01:00 committed by GitHub
commit ac8dfe5c44
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 662 additions and 90 deletions

View File

@ -936,7 +936,7 @@
"id": "widbatpc",
"name": "Battery Level Widget (with percentage)",
"shortName": "Battery Widget",
"version": "0.15",
"version": "0.16",
"description": "Show the current battery level and charging status in the top right of the clock, with charge percentage",
"icon": "widget.png",
"type": "widget",
@ -1501,7 +1501,7 @@
{
"id": "gpsinfo",
"name": "GPS Info",
"version": "0.06",
"version": "0.07",
"description": "An application that displays information about altitude, lat/lon, satellites and time",
"icon": "gps-info.png",
"type": "app",
@ -2430,7 +2430,7 @@
{
"id": "calendar",
"name": "Calendar",
"version": "0.05",
"version": "0.06",
"description": "Simple calendar",
"icon": "calendar.png",
"screenshots": [{"url":"screenshot_calendar.png"}],
@ -4239,8 +4239,9 @@
{
"id": "antonclk",
"name": "Anton Clock",
"version": "0.03",
"description": "A simple clock using the bold Anton font.",
"version": "0.04",
"description": "A clock using the bold Anton font, optionally showing seconds and date in ISO-8601 format.",
"readme":"README.md",
"icon": "app.png",
"screenshots": [{"url":"screenshot.png"}],
"type": "clock",
@ -4249,8 +4250,10 @@
"allow_emulator": true,
"storage": [
{"name":"antonclk.app.js","url":"app.js"},
{"name":"antonclk.settings.js","url":"settings.js"},
{"name":"antonclk.img","url":"app-icon.js","evaluate":true}
]
],
"data": [{"name":"antonclk.json"}]
},
{
"id": "waveclk",
@ -5162,15 +5165,16 @@
{
"id": "promenu",
"name": "Pro Menu",
"version": "0.01",
"description": "Replace Bangle.js 1's built in menu function.",
"version": "0.02",
"description": "Replace the built in menu function. Supports Bangle.js 1 and Bangle.js 2.",
"icon": "icon.png",
"type": "boot",
"tags": "system",
"supports": ["BANGLEJS"],
"supports": ["BANGLEJS","BANGLEJS2"],
"screenshots": [{"url":"pro-menu-screenshot.png"}],
"storage": [
{"name":"promenu.boot.js","url":"boot.js"},
{"name":"promenu.boot.js","url":"boot.js","supports": ["BANGLEJS"]},
{"name":"promenu.boot.js","url":"bootb2.js","supports": ["BANGLEJS2"]},
{"name":"promenu.img","url":"promenuIcon.js","evaluate":true}
]
},
@ -5427,5 +5431,22 @@
{"name":"puzzle15.img","url":"puzzle15.app-icon.js","evaluate":true}
],
"data": [{"name":"puzzle15.json"}]
},
{
"id": "flipper",
"name": "flipper",
"version": "0.01",
"description": "Switch between dark and light theme and vice versa, combine with pattern launcher and swipe to flip.",
"readme":"README.md",
"screenshots": [{"url":"flipper.png"}],
"icon": "flipper.png",
"type": "app",
"tags": "game",
"supports": ["BANGLEJS2"],
"allow_emulator": true,
"storage": [
{"name":"flipper.app.js","url":"flipper.app.js"},
{"name":"flipper.img","url":"flipper.icon.js","evaluate":true}
]
}
]

View File

@ -1,3 +1,4 @@
0.01: New App!
0.02: Load widgets after setUI so widclk knows when to hide
0.03: Clock now shows day of week under date.
0.04: Clock can optionally show seconds, date optionally in ISO-8601 format, weekdays and uppercase configurable, too.

77
apps/antonclk/README.md Normal file
View File

@ -0,0 +1,77 @@
# Anton Clock - Large font digital watch with seconds and date
Anton clock uses the "Anton" bold font to show the time in a clear, easily readable manner. On the Bangle.js 2, the time can be read easily even if the screen is locked and unlit.
## Features
The basic time representation only shows hours and minutes of the current time. However, Anton clock can show additional information:
* Seconds can be shown, either always or only if the screen is unlocked.
* To help easy recognition, the seconds can be coloured in blue on the Bangle.js 2.
* Date can be shown in three different formats:
* ISO-8601: 2021-12-19
* short local format: 19/12/2021, 19.12.2021
* long local format: DEC 19 2021
* Weekday can be shown (on seconds screen only instead of year)
## Usage
Install Anton clock through the Bangle.js app loader.
Configure it through the default Bangle.js configuration mechanism
(Settings app, "Apps" menu, "Anton clock" submenu).
If you like it, make it your default watch face
(Settings app, "System" menu, "Clock" submenu, select "Anton clock").
## Configuration
Anton clock is configured by the standard settings mechanism of Bangle.js's operating system:
Open the "Settings" app, then the "Apps" submenu and below it the "Anton clock" menu.
You configure Anton clock through several "on/off" switches in two menus.
### The main menu
The main menu contains several settings covering Anton clock in general.
* **Seconds...** - Opens the submenu for configuring the presentation of the current time's seconds.
* **Date** - Format of the date representation. Possible values are
* **Long** - "Long" date format in the current locale. Usually with the month as name, not number.
* **Short** - "Short" date format in the current locale. Usually with the month as number.
* **ISO8601** - Show the date in ISO-8601 format (YYYY-MM-DD), irrespective of the current locale.
* **Show Weekday** - Weekday is shown in the time presentation without seconds.
Weekday name depends on the current locale.
If seconds are shown, the weekday is never shown as there is not enough space on the watch face.
* **Uppercase** - Weekday name and month name in the long format are converted to upper case letters.
This can improve readability.
* **Vector font** - Use the built-in vector font for dates and weekday.
This can improve readability.
Otherwise, a scaled version of the built-in 6x8 pixels font is used.
### The "Seconds" submenu
The "Seconds" submenu configures how (and if) seconds are shown on the "Anton" watch face.
* **Show** - Configure when the seconds should be shown at all:
* **Never** - Seconds are never shown.
In this case, hour and minute are a bit more centered on the screen and the clock will always only update every minute.
This saves battery power.
* **Unlocked** - Seconds are shown if the display is unlocked.
On locked displays, only hour, minutes, date and optionally the weekday are shown.
_This option is highly recommended on the Bangle.js 2!_
* **Always** - Seconds are _always_ shown, irrespective of the display's unlock state.
_Enabling this option increases power consumption as the watch face will update once per second instead of once per minute._
* **With ":"** - If enabled, a colon ":" is prepended to the seconds.
This resembles the usual time representation "hh:mm:ss", even though the seconds are printed on a separate line.
* **Color** - If enabled, seconds are shown in blue instead of black.
If the date is shown on the seconds screen, it is colored read instead of black.
This make the visual orientation much easier on the watch face.
* **Date** - It is possible to show the date together with the seconds:
* **No** - Date is _not_ shown in the seconds screen.
In this case, the seconds are centered below hour and minute.
* **Year** - Date is shown with day, month, and year. If "Date" in the main settings is configured to _ISO8601_, this is used here, too. Otherwise, the short local format is used.
* **Weekday** - Date is shown with day, month, and weekday.
The date is coloured in red if the "Coloured" option is chosen.
## Compatibility
Anton clock makes use of core Bangle.js 2 features (coloured display, display lock state). It also runs on the Bangle.js 1 but these features are not available there due to hardware restrictions.

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 759 B

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 696 B

After

Width:  |  Height:  |  Size: 1.6 KiB

99
apps/antonclk/settings.js Normal file
View File

@ -0,0 +1,99 @@
// Settings menu for the enhanced Anton clock
(function(back) {
var FILE = "antonclk.json";
// Load settings
var settings = Object.assign({
secondsOnUnlock: false,
}, require('Storage').readJSON(FILE, true) || {});
function writeSettings() {
require('Storage').writeJSON(FILE, settings);
}
// Helper method which uses int-based menu item for set of string values
function stringItems(startvalue, writer, values) {
return {
value: (startvalue === undefined ? 0 : values.indexOf(startvalue)),
format: v => values[v],
min: 0,
max: values.length - 1,
wrap: true,
step: 1,
onchange: v => {
writer(values[v]);
writeSettings();
}
};
}
// Helper method which breaks string set settings down to local settings object
function stringInSettings(name, values) {
return stringItems(settings[name], v => settings[name] = v, values);
}
var mainmenu = {
"": {
"title": "Anton clock"
},
"< Back": () => back(),
"Seconds...": () => E.showMenu(secmenu),
"Date": stringInSettings("dateOnMain", ["Short", "Long", "ISO8601"]),
"Show Weekday": {
value: (settings.weekDay !== undefined ? settings.weekDay : true),
format: v => v ? "On" : "Off",
onchange: v => {
settings.weekDay = v;
writeSettings();
}
},
"Uppercase": {
value: (settings.upperCase !== undefined ? settings.upperCase : false),
format: v => v ? "On" : "Off",
onchange: v => {
settings.upperCase = v;
writeSettings();
}
},
"Vector font": {
value: (settings.vectorFont !== undefined ? settings.vectorFont : false),
format: v => v ? "On" : "Off",
onchange: v => {
settings.vectorFont = v;
writeSettings();
}
},
};
// Submenu
var secmenu = {
"": {
"title": "Show seconds..."
},
"< Back": () => E.showMenu(mainmenu),
"Show": stringInSettings("secondsMode", ["Never", "Unlocked", "Always"]),
"With \":\"": {
value: (settings.secondsWithColon !== undefined ? settings.secondsWithColon : false),
format: v => v ? "On" : "Off",
onchange: v => {
settings.secondsWithColon = v;
writeSettings();
}
},
"Color": {
value: (settings.secondsColoured !== undefined ? settings.secondsColoured : false),
format: v => v ? "On" : "Off",
onchange: v => {
settings.secondsColoured = v;
writeSettings();
}
},
"Date": stringInSettings("dateOnSecs", ["No", "Year", "Weekday"])
};
// Actually display the menu
E.showMenu(mainmenu);
});
// end of file

View File

@ -3,3 +3,4 @@
0.03: Add setting to start week on Sunday
0.04: Add setting to switch color schemes. On Bangle 2 non-dithering colors will be used by default. Use localized names for months and days of the week (Language app needed).
0.05: Update calendar weekend colors for start on Sunday
0.06: Use larger font for dates

View File

@ -206,6 +206,8 @@ function drawCalendar(date) {
y2 - 1
);
}
require("Font8x12").add(Graphics);
g.setFont("8x12", fontSize);
g.setColor(day < 50 ? fgOtherMonth : fgSameMonth);
g.drawString(
(day > 50 ? day - 50 : day).toString(),

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@ -11,4 +11,4 @@ The year itself begins on the December solstice. Because that always happens, th
The epoch (year numbering) begins in the last year when the perihelion coincided with the June solstice, near the beginning of the Holocene era. That astronomical basis makes the calendar free from politics, religion, or geography.
While the year number remains cardinal, BTN5 toggles between cardinal and ordinal for the rest of the calendar segments. BTN4 adds or removes a quickly changing digit to or from the clock.
While the year number remains cardinal, tapping on the right side of the watch face toggles between cardinal and ordinal for the rest of the calendar segments. Tapping on the left adds or removes a quickly changing digit to or from the clock.

View File

@ -14,11 +14,11 @@ const A1 = [30,30,30,30,31,31,31,31,31,31,30,30];
const B1 = [30,30,30,30,30,31,31,31,31,31,30,30];
const B2 = [30,30,30,30,31,31,31,31,31,30,30,30];
const timeColour = "#ffffff";
const dateColours = ["#ff0000","#ff8000","#ffff00","#00ff00","#0080ff","#ff00ff","#ffffff"];
const dateColours = ["#ff0000","#ffa500","#ffff00","#00b800","#8383ff","#ff00ff","#ff0080"]; //blue was 0000ff
const calen10 = {"size":26,"pt0":[18-g_x_off,16],"step":[16,0],"dx":-4.5,"dy":-4.5}; // positioning for usual calendar line ft w 32, 32-g, step 20
const calen7 = {"size":26,"pt0":[48-g_x_off,16],"step":[16,0],"dx":-4.5,"dy":-4.5}; // positioning for S-day calendar line ft w 32, 62-g, step 20
const time5 = {"size":36,"pt0":[46-g_x_off,24],"step":[22,0],"dx":-6.5,"dy":-6.5}; // positioning for lull time line ft w 48, 64-g, step 30
const time6 = {"size":36,"pt0":[36-g_x_off,24],"step":[22,0],"dx":-6.5,"dy":-6.5}; // positioning for twinkling time line ft w 48, 48-g, step 30
const time5 = {"size":42,"pt0":[39-g_x_off,24],"step":[26,0],"dx":-6.5,"dy":-6.5}; // positioning for lull time line ft w 48, 64-g, step 30
const time6 = {"size":42,"pt0":[26-g_x_off,24],"step":[26,0],"dx":-6.5,"dy":-6.5}; // positioning for twinkling time line ft w 48, 48-g, step 30
const baseYear = 11584;
const baseDate = Date(2020,11,21); // month values run from 0 to 11
let accum = new Date(baseDate.getTime());
@ -206,7 +206,7 @@ function modeTime()
{
timeActiveUntil = new Date();
timeActiveUntil.setDate(timeActiveUntil.getDate());
timeActiveUntil.setSeconds(timeActiveUntil.getSeconds()+15);
timeActiveUntil.setSeconds(timeActiveUntil.getSeconds()+86400);
if (typeof drawtime_timeout !== 'undefined')
{
clearTimeout(drawtime_timeout);

1
apps/flipper/ChangeLog Normal file
View File

@ -0,0 +1 @@
0.01: first release

20
apps/flipper/README.md Normal file
View File

@ -0,0 +1,20 @@
# Flipper
![](flipper.png)
*A utility to switch from the dark to the light theme and vice versa*
* If the current theme is dark it will switch to the light theme
* If the current theme is light it will switch to the dark theme
* Combine with the awesome pattern launcher and it saves loads of time
## Demo Video
There's no screenshot but there is a [demo video.](https://espruino.microco.sm/api/v1/files/9caa1afef7e4cce1d9b518af2dd271f1a57c5ecc.mp4)
## Future Enhancements
* Nothing left to add
Written by: [Hugh Barney](https://github.com/hughbarney) For support and discussion please post in the [Bangle JS Forum](http://forum.espruino.com/microcosms/1424/)

View File

@ -0,0 +1,39 @@
const storage = require('Storage');
let settings = storage.readJSON('setting.json', 1);
function cl(x) { return g.setColor(x).getColor(); }
function upd(th) {
g.theme = th;
settings.theme = th;
storage.write('setting.json', settings);
delete g.reset;
g._reset = g.reset;
g.reset = function(n) { return g._reset().setColor(th.fg).setBgColor(th.bg); };
g.clear = function(n) { if (n) g.reset(); return g.clearRect(0,0,g.getWidth(),g.getHeight()); };
g.clear(1);
}
function flipTheme() {
if (!g.theme.dark) {
upd({
fg:cl("#fff"), bg:cl("#000"),
fg2:cl("#0ff"), bg2:cl("#000"),
fgH:cl("#fff"), bgH:cl("#00f"),
dark:true
});
} else {
upd({
fg:cl("#000"), bg:cl("#fff"),
fg2:cl("#000"), bg2:cl("#cff"),
fgH:cl("#000"), bgH:cl("#0ff"),
dark:false
});
}
}
Bangle.loadWidgets();
Bangle.drawWidgets();
flipTheme();
setTimeout(load, 20);

View File

@ -0,0 +1 @@
require("heatshrink").decompress(atob("mEw4X/AAO/mMUzs975K+ggLKysUAYNVqoLFitUoAKBqtQBYkJBIQABqwLEgQLEqtABggJDqkVBaoNCBZQwEgILWgoJENYsVBIcVBYpDEgpSIBYMBKQg6CuogCBY1UgoLCXAQLDqAsDBYhSBqEJHAoLDoEBcQ4LBEwILIMooLdIg4LaVoyaGERLcFao4LIdRAACYYUQBY5RKAH4Ar"))

BIN
apps/flipper/flipper.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 644 B

View File

@ -2,4 +2,5 @@
0.03: Show number of satellites while waiting for fix
0.04: Add Maidenhead readout of GPS location
0.05: Refactor to use 'layout' library for multi-device support
0.06: Added number of satellites in view and fixed crash with GPS time
0.06: Add number of satellites in view and fix crash with GPS time
0.07: Resolve one FIFO_FULL case and exit App with button press

View File

@ -19,6 +19,7 @@ var lastFix = {
var SATinView = 0;
var nofBD = 0;
var nofGP = 0;
var listenerGPSraw = 1;
function formatTime(now) {
if (now == undefined) {
@ -93,6 +94,10 @@ function onGPS(fix) {
}
lastFix = fix;
if (fix.fix) {
if (listenerGPSraw == 1) {
Bangle.removeListener('GPS-raw', onGPSraw);
listenerGPSraw = 0;
}
var locale = require("locale");
var satellites = fix.satellites;
var maidenhead = getMaidenHead(fix.lat,fix.lon);
@ -104,6 +109,10 @@ function onGPS(fix) {
layout.sat.label = "Satellites: "+satellites;
layout.maidenhead.label = "Maidenhead: "+maidenhead;
} else {
if (listenerGPSraw == 0) {
Bangle.on('GPS-raw', onGPSraw);
listenerGPSraw = 1;
}
layout.sat.label = fix.satellites;
layout.progress.label = "in view: " + SATinView;
}
@ -111,15 +120,26 @@ function onGPS(fix) {
}
function onGPSraw(nmea) {
if (nmea.slice(3,6) == "GSV") {
// console.log(nmea);
if (nmea.slice(0,7) == "$BDGSV,") nofBD = Number(nmea.slice(11,13));
if (nmea.slice(0,7) == "$GPGSV,") nofGP = Number(nmea.slice(11,13));
SATinView = nofBD + nofGP;
}
if (nmea.slice(0,7) == "$BDGSV,") nofBD = Number(nmea.slice(11,13));
if (nmea.slice(0,7) == "$GPGSV,") nofGP = Number(nmea.slice(11,13));
SATinView = nofBD + nofGP;
}
Bangle.loadWidgets();
Bangle.drawWidgets();
Bangle.on('GPS', onGPS);
Bangle.on('GPS-raw', onGPSraw);
function exitApp() {
Bangle.setGPSPower(0, "app");
Bangle.removeListener('GPS-raw', onGPSraw);
Bangle.removeListener('GPS', onGPS);
load();
}
setWatch(_=>exitApp(), BTN1);
if (global.BTN2) {
setWatch(_=>exitApp(), BTN2);
setWatch(_=>exitApp(), BTN3);
}

View File

@ -1 +1,2 @@
0.01: New App!
0.02: Add Bangle.js 2 Support

View File

@ -70,7 +70,7 @@ E.showMenu = function(items) {
if(g.theme.dark){
fillRectRnd(x+2,iy+1,x2,iy+options.fontHeight-3,7,hl ? g.theme.bgH : g.theme.bg+20);
}else{
fillRectRnd(x+2,iy+1,x2,iy+options.fontHeight-3,7,hl ? g.theme.bgH : g.theme.bg-10);
fillRectRnd(x+2,iy+1,x2,iy+options.fontHeight-3,7,hl ? g.theme.bgH : g.theme.bg-20);
}
g.setColor(hl ? g.theme.fgH : g.theme.fg);
g.setFontAlign(-1,-1);

142
apps/promenu/bootb2.js Normal file
View File

@ -0,0 +1,142 @@
E.showMenu = function(items) {
function RectRnd(x1,y1,x2,y2,r) {
pp = [];
pp.push.apply(pp,g.quadraticBezier([x2-r,y1, x2,y1,x2,y1+r]));
pp.push.apply(pp,g.quadraticBezier([x2,y2-r,x2,y2,x2-r,y2]));
pp.push.apply(pp,g.quadraticBezier([x1+r,y2,x1,y2,x1,y2-r]));
pp.push.apply(pp,g.quadraticBezier([x1,y1+r,x1,y1,x1+r,y1]));
return pp;
}
function fillRectRnd(x1,y1,x2,y2,r,c) {
g.setColor(c);
g.fillPoly(RectRnd(x1,y1,x2,y2,r),1);
g.setColor(255,255,255);
}
function drawRectRnd(x1,y1,x2,y2,r,c) {
g.setColor(c);
g.drawPoly(RectRnd(x1,y1,x2,y2,r),1);
g.setColor(255,255,255);
}
g.reset().clearRect(Bangle.appRect); // clear if no menu supplied
Bangle.setLCDPower(1); // ensure screen is on
if (!items) {
Bangle.setUI();
return;
}
var menuItems = Object.keys(items);
var options = items[""];
if (options) menuItems.splice(menuItems.indexOf(""),1);
if (!(options instanceof Object)) options = {};
options.fontHeight = options.fontHeight||25;
if (options.selected === undefined)
options.selected = 0;
var ar = Bangle.appRect;
var x = ar.x;
var x2 = ar.x2;
var y = ar.y;
var y2 = ar.y2 - 12; // padding at end for arrow
if (options.title)
y += 22;
var loc = require("locale");
var l = {
lastIdx : 0,
draw : function(rowmin,rowmax) {
var rows = 0|Math.min((y2-y) / options.fontHeight,menuItems.length);
var idx = E.clip(options.selected-( rows>>1),0,menuItems.length-rows);
if (idx!=l.lastIdx) rowmin=undefined; // redraw all if we scrolled
l.lastIdx = idx;
var iy = y;
g.reset().setFontAlign(0,-1,0).setFont('12x20');
if (options.predraw) options.predraw(g);
if (rowmin===undefined && options.title)
g.drawString(options.title,(x+x2)/2,y-21).drawLine(x,y-2,x2,y-2).
setColor(g.theme.fg).setBgColor(g.theme.bg);
iy += 4;
if (rowmin!==undefined) {
if (idx<rowmin) {
iy += options.fontHeight*(rowmin-idx);
idx=rowmin;
}
if (idx+rows>rowmax) {
rows = 1+rowmax-rowmin;
}
}
while (rows--) {
var name = menuItems[idx];
var item = items[name];
var hl = (idx==options.selected && !l.selectEdit);
if(g.theme.dark){
fillRectRnd(x,iy,x2,iy+options.fontHeight-3,7,hl ? g.theme.bgH : g.theme.bg+40);
}else{
fillRectRnd(x,iy,x2,iy+options.fontHeight-3,7,hl ? g.theme.bgH : g.theme.bg-20);
}
g.setColor(hl ? g.theme.fgH : g.theme.fg);
g.setFontAlign(-1,-1);
var v = item.value;
v = loc.translate(""+v);
if(loc.translate(name).length >= 17-v.length && "object" == typeof item){
if (item.format) v=item.format(v);
g.drawString(loc.translate(name).substring(0, 12-v.length)+"...",x+3.7,iy+2.7);
}else{
if(loc.translate(name).length >= 15){
g.drawString(loc.translate(name).substring(0, 15)+"...",x+3.7,iy+2.7);
}else{
g.drawString(loc.translate(name),x+3.7,iy+2.7);
}
}
if ("object" == typeof item) {
var xo = x2;
var v = item.value;
if (item.format) v=item.format(v);
v = loc.translate(""+v);
if (l.selectEdit && idx==options.selected) {
xo -= 24 + 1;
g.setColor(g.theme.fgH).drawImage("\x0c\x05\x81\x00 \x07\x00\xF9\xF0\x0E\x00@",xo,iy+(options.fontHeight-10)/2,{scale:2});
}
g.setFontAlign(1,-1);
g.drawString(v,xo-2,iy+1);
}
g.setColor(g.theme.fg);
iy += options.fontHeight;
idx++;
}
g.setFontAlign(-1,-1);
g.setColor((idx<menuItems.length)?g.theme.fg:g.theme.bg).fillPoly([72,166,104,166,88,174]);
g.flip();
},
select : function() {
var item = items[menuItems[options.selected]];
if ("function" == typeof item) item(l);
else if ("object" == typeof item) {
// if a number, go into 'edit mode'
if ("number" == typeof item.value)
l.selectEdit = l.selectEdit?undefined:item;
else { // else just toggle bools
if ("boolean" == typeof item.value) item.value=!item.value;
if (item.onchange) item.onchange(item.value);
}
l.draw();
}
},
move : function(dir) {
var item = l.selectEdit;
if (item) {
item.value -= (dir||1)*(item.step||1);
if (item.min!==undefined && item.value<item.min) item.value = item.wrap ? item.max : item.min;
if (item.max!==undefined && item.value>item.max) item.value = item.wrap ? item.min : item.max;
if (item.onchange) item.onchange(item.value);
l.draw(options.selected,options.selected);
} else {
var lastSelected=options.selected;
options.selected = (dir+options.selected+menuItems.length)%menuItems.length;
l.draw(Math.min(lastSelected,options.selected), Math.max(lastSelected,options.selected));
}
}
};
l.draw();
Bangle.setUI("updown",dir => {
if (dir) l.move(dir);
else l.select();
});
return l;
};

View File

@ -12,3 +12,4 @@
0.13: Fillbar setting added, see README
0.14: Fix drawing the bar when charging
0.15: Added option to always display the icon when charging (useful if 'hide if charge greater than' is enabled)
0.16: Increase screen update rate when charging

View File

@ -1,6 +1,9 @@
(function(){
const intervalLow = 60000; // update time when not charging
const intervalHigh = 2000; // update time when charging
let COLORS = {};
if (process.env.HWVERSION == 1) {
COLORS = {
'white': -1, // White
@ -17,13 +20,13 @@
'high': "#0f0", // Green
'ok': "#ff0", // Orange
'low': "#f00", // Red
};
};
}
const SETTINGS_FILE = 'widbatpc.json'
const SETTINGS_FILE = 'widbatpc.json';
let settings
let settings;
function loadSettings() {
settings = require('Storage').readJSON(SETTINGS_FILE, 1) || {}
settings = require('Storage').readJSON(SETTINGS_FILE, 1) || {};
const DEFAULTS = {
'color': 'By Level',
'percentage': true,
@ -32,17 +35,17 @@
'alwaysoncharge': false,
};
Object.keys(DEFAULTS).forEach(k=>{
if (settings[k]===undefined) settings[k]=DEFAULTS[k]
if (settings[k]===undefined) settings[k]=DEFAULTS[k];
});
}
function setting(key) {
if (!settings) { loadSettings() }
if (!settings) { loadSettings(); }
return settings[key];
}
const levelColor = (l) => {
// "charging" is very bright -> percentage is hard to read, "high" is ok(ish)
const green = setting('percentage') ? COLORS.high : COLORS.charging
const green = setting('percentage') ? COLORS.high : COLORS.charging;
switch (setting('color')) {
case 'Monochrome': return COLORS.white; // no chance of reading the percentage here :-(
case 'Green': return green;
@ -59,10 +62,11 @@
if (l >= 15) return COLORS.ok;
return COLORS.low;
}
}
};
const chargerColor = () => {
return (setting('color') === 'Monochrome') ? COLORS.white : COLORS.charging
}
return (setting('color') === 'Monochrome') ? COLORS.white : COLORS.charging;
};
// sets width, returns true if it changed
function setWidth() {
var w = 40;
@ -77,6 +81,7 @@
WIDGETS["batpc"].width = w;
return changed;
}
function draw() {
// if hidden, don't draw
if (!WIDGETS["batpc"].width) return;
@ -106,11 +111,11 @@
if (!setting('percentage')) {
return;
}
let gfx = g
let gfx = g;
if (setting('color') === 'Monochrome') {
// draw text inverted on battery level
gfx = Graphics.createCallback(g.getWidth(),g.getHeight(), 1,
(x,y) => {g.setPixel(x,y,x<=xl?0:-1)})
(x,y) => {g.setPixel(x,y,x<=xl?0:-1);});
}
gfx.setFontAlign(-1,-1);
if (l >= 100) {
@ -122,19 +127,24 @@
gfx.drawString(l, x + 6, y + 4);
}
}
// reload widget, e.g. when settings have changed
function reload() {
loadSettings()
loadSettings();
// need to redraw all widgets, because changing the "charger" setting
// can affect the width and mess with the whole widget layout
setWidth()
setWidth();
g.clear();
Bangle.drawWidgets();
}
// update widget - redraw just widget, or all widgets if size changed
function update() {
if (setWidth()) Bangle.drawWidgets();
else WIDGETS["batpc"].draw();
if (Bangle.isCharging()) changeInterval(id, intervalHigh);
else changeInterval(id, intervalLow);
}
Bangle.on('charging',function(charging) {
@ -142,20 +152,13 @@
update();
g.flip();
});
var batteryInterval;
Bangle.on('lcdPower', function(on) {
if (on) {
update();
// refresh once a minute if LCD on
if (!batteryInterval)
batteryInterval = setInterval(update, 60000);
} else {
if (batteryInterval) {
clearInterval(batteryInterval);
batteryInterval = undefined;
}
}
if (on) update();
});
var id = setInterval(()=>WIDGETS["batpc"].draw(), intervalLow);
WIDGETS["batpc"]={area:"tr",width:40,draw:draw,reload:reload};
setWidth();
})()
})();