Merge branch 'master' of github.com:espruino/BangleApps

pull/1790/head
Gordon Williams 2022-05-03 12:29:38 +01:00
commit 5bc4ecac48
17 changed files with 189 additions and 36 deletions

1
.gitignore vendored
View File

@ -11,3 +11,4 @@ tests/Layout/bin/tmp.*
tests/Layout/testresult.bmp
apps.local.json
_site
.jekyll-cache

View File

@ -1,2 +1,3 @@
0.01: New App!
0.02: Set Bangle.js 2 compatible
0.03: Add setting to hide the widget

View File

@ -2,13 +2,15 @@
"id": "gpsautotime",
"name": "GPS auto time",
"shortName": "GPS auto time",
"version": "0.02",
"version": "0.03",
"description": "A widget that automatically updates the Bangle.js time to the GPS time whenever there is a valid GPS fix.",
"icon": "widget.png",
"type": "widget",
"tags": "widget,gps",
"supports": ["BANGLEJS","BANGLEJS2"],
"storage": [
{"name":"gpsautotime.wid.js","url":"widget.js"}
]
{"name":"gpsautotime.wid.js","url":"widget.js"},
{"name":"gpsautotime.settings.js","url":"settings.js"}
],
"data": [{"name":"gpsautotime.json"}]
}

View File

@ -0,0 +1,25 @@
(function(back) {
var FILE = "gpsautotime.json";
// Load settings
var settings = Object.assign({
show: true,
}, require('Storage').readJSON(FILE, true) || {});
function writeSettings() {
require('Storage').writeJSON(FILE, settings);
}
// Show the menu
E.showMenu({
"" : { "title" : "GPS auto time" },
"< Back" : () => back(),
'Show widget?': {
value: !!settings.show, // !! converts undefined to false
format: v => v?"Show":"Hide",
onchange: v => {
settings.show = v;
writeSettings();
}
},
});
})

View File

@ -1,6 +1,13 @@
(() => {
var lastTimeSet = 0;
var settings = Object.assign({
// default values
show: true,
}, require('Storage').readJSON("gpsautotime.json", true) || {});
const show = settings.show;
delete settings;
Bangle.on('GPS',function(fix) {
if (fix.fix) {
var curTime = fix.time.getTime()/1000;
@ -14,8 +21,9 @@
// add your widget
WIDGETS["gpsAutoTime"]={
area:"tl", // tl (top left), tr (top right), bl (bottom left), br (bottom right)
width: 28, // width of the widget
width: show ? 4*6+2 : 0, // width of the widget
draw: function() {
if (!show) return;
g.reset(); // reset the graphics context to defaults (color/font/etc)
g.setFont("6x8");
if ((getTime() - lastTimeSet) <= 60) {
@ -27,7 +35,9 @@
}
};
setInterval(function() {
WIDGETS["gpsAutoTime"].draw(WIDGETS["gpsAutoTime"]);
}, 1*60000); // update every minute
})()
if (show) {
setInterval(function() {
WIDGETS["gpsAutoTime"].draw(WIDGETS["gpsAutoTime"]);
}, 1*60000); // update every minute
}
})();

View File

@ -1 +1,2 @@
0.01: New App!
0.02: Introduced settings to customize the layout and functionality of the keyboard.

View File

@ -2,6 +2,17 @@
A library that provides an on-screen keyboard for text input.
## Settings
Text size - small or big text font. Default=Big. Suggested=Small.
Offset keyboard - display the keyboard on top, making it faster to see what character you have selected. Default=No. Suggested=Yes.
Loop around - should the keyboard highlight loop around when going past the edges? Default=Yes. Suggested=No.
One-to-one input and release to select - should the input correspond directly to discrete areas on the screen, instead of being handled by scaled relative changes in position on swipes? Default=No. Suggested=Yes.
Speed scaling - how much should a swipe move the highligt on the keyboard? Higher number corresponds to slower movement. Not applicable if using one-to-one input. Default=24. Suggested=15.
## Usage
In your app's metadata, add:

View File

@ -69,13 +69,24 @@ var KEYEXTRA = [
String.fromCharCode(27,91,53,126), // 0x84 page up
String.fromCharCode(27,91,54,126), // 0x85 page down
];
var settings = Object.assign({
// default values
textSize: 1,
offsetKeyboard: 0,
loopAround: 1,
oneToOne: 0,
speedScaling: 24
}, require('Storage').readJSON("kbtouch.settings.json", true) || {});
// state
const R = Bangle.appRect;
var kbx = 0, kby = 0, kbdx = 0, kbdy = 0, kbShift = false, flashToggle = false;
const PX=12, PY=16, DRAGSCALE=24;
var xoff = 3, yoff = g.getHeight()-PY*4;
const PX=12, PY=16, DRAGSCALE=settings.speedScaling;
var xoff = 3, yoff = g.getHeight()-PY*(4+5*settings.offsetKeyboard);
function draw() {
"ram";
var map = kbShift ? KEYMAPUPPER : KEYMAPLOWER;
//g.drawImage(KEYIMG,0,yoff);
g.reset().setFont("6x8:2");
@ -88,9 +99,9 @@ function draw() {
g.drawString(map[1],xoff,yoff+PY);
g.drawString(map[2],xoff,yoff+PY*2);
g.drawString(map[3],xoff,yoff+PY*3);
var l = g.setFont("6x8:4").wrapString(text+(flashToggle?"_":" "), R.w-8);
if (l.length>2) l=l.slice(-2);
g.drawString(l.join("\n"),R.x+4,R.y+4);
var l = g.setFont(settings.textSize ? "6x8:4":"6x8:2").wrapString(text+(flashToggle?"_":" "), R.w-8);
if (l.length>2+2*settings.textSize) l=l.slice(-(2+2*settings.textSize));
g.drawString(l.join("\n"),R.x+4,R.y+4 +82*settings.offsetKeyboard);
g.flip();
}
@ -104,24 +115,49 @@ function draw() {
return new Promise((resolve,reject) => {
Bangle.setUI({mode:"custom", drag:e=>{
kbdx += e.dx;
kbdy += e.dy;
var dx = Math.round(kbdx/DRAGSCALE), dy = Math.round(kbdy/DRAGSCALE);
kbdx -= dx*DRAGSCALE;
kbdy -= dy*DRAGSCALE;
if (dx || dy) {
kbx = (kbx+dx+15)%15;
kby = (kby+dy+4)%4;
if (settings.oneToOne) {
kbx = Math.max(Math.min(Math.floor((e.x-16) / (6*2)) , 13) , 0);
kby = Math.max(Math.min(Math.floor((e.y-120) / (8*2)) , 3) , 0);
//print(e.y, kby, e.x, kbx);
}
if (!settings.oneToOne) {
kbdx += e.dx;
kbdy += e.dy;
var dx = Math.round(kbdx/DRAGSCALE), dy = Math.round(kbdy/DRAGSCALE);
kbdx -= dx*DRAGSCALE;
kbdy -= dy*DRAGSCALE;
if (dx || dy) {
if (settings.loopAround) {
kbx = (kbx+dx+15)%15;
kby = (kby+dy+4)%4;
} else {
kbx = Math.max(Math.min((kbx+dx),13),0);
kby = Math.max(Math.min((kby+dy),3),0);
}
}
}
draw();
if (!e.b && e.y>Bangle.appRect.y && settings.oneToOne /*&& settings.releaseToSelect*/) {
var map = kbShift ? KEYMAPUPPER : KEYMAPLOWER;
var ch = map[kby][kbx];
if (ch=="\2") kbShift=!kbShift;
else if (ch=="\b") text = text.slice(0,-1);
else text += ch;
Bangle.buzz(20);
draw();
}
},touch:()=>{
var map = kbShift ? KEYMAPUPPER : KEYMAPLOWER;
var ch = map[kby][kbx];
if (ch=="\2") kbShift=!kbShift;
else if (ch=="\b") text = text.slice(0,-1);
else text += ch;
Bangle.buzz(20);
draw();
if ( !settings.oneToOne /*|| !settings.releaseToSelect*/) {
var map = kbShift ? KEYMAPUPPER : KEYMAPLOWER;
var ch = map[kby][kbx];
if (ch=="\2") kbShift=!kbShift;
else if (ch=="\b") text = text.slice(0,-1);
else text += ch;
Bangle.buzz(20);
draw();
}
},back:()=>{
clearInterval(flashInterval);
Bangle.setUI();

View File

@ -1,6 +1,6 @@
{ "id": "kbtouch",
"name": "Touch keyboard",
"version":"0.01",
"version":"0.02",
"description": "A library for text input via onscreen keyboard",
"icon": "app.png",
"type":"textinput",
@ -9,6 +9,7 @@
"screenshots": [{"url":"screenshot.png"}],
"readme": "README.md",
"storage": [
{"name":"textinput","url":"lib.js"}
{"name":"textinput","url":"lib.js"},
{"name":"kbtouch.settings.js","url":"settings.js"}
]
}

59
apps/kbtouch/settings.js Normal file
View File

@ -0,0 +1,59 @@
(function(back) {
function settings() {
let settings = require('Storage').readJSON("kbtouch.settings.json", true) || {};
if (settings.textSize===undefined) settings.textSize=1;
if (settings.offsetKeyboard===undefined) settings.offsetKeyboard=0;
if (settings.loopAround===undefined) settings.loopAround=1;
if (settings.oneToOne===undefined) settings.oneToOne=0;
if (settings.speedScaling===undefined) settings.speedScaling=24;
return settings;
}
function updateSetting(setting, value) {
let settings = require('Storage').readJSON("kbtouch.settings.json", true) || {};
settings[setting] = value;
require('Storage').writeJSON("kbtouch.settings.json", settings);
}
var mainmenu = {
"" : { "title" : /*LANG*/"Touch Keyboard" },
"< Back" : back,
/*LANG*/'Text size': {
value: settings().textSize,
min: 0, max: 1,
format: v => [/*LANG*/"Small",/*LANG*/"Big"][v],
onchange: v => updateSetting("textSize", v)
},
/*LANG*/'Offset keyboard': {
value: settings().offsetKeyboard,
min: 0, max: 1,
format: v => [/*LANG*/"No",/*LANG*/"Yes"][v],
onchange: v => updateSetting("offsetKeyboard", v)
},
/*LANG*/'Loop around': {
value: settings().loopAround,
min: 0, max: 1,
format: v => [/*LANG*/"No",/*LANG*/"Yes"][v],
onchange: v => updateSetting("loopAround", v)
},
/*LANG*/'One-to-one input and release to select': {
value: settings().oneToOne,
min: 0, max: 1,
format: v => [/*LANG*/"No",/*LANG*/"Yes"][v],
onchange: v => updateSetting("oneToOne", v)
},
/*LANG*/'Speed scaling': {
value: settings().speedScaling,
min: 1, max: 24, step : 1,
format: v => v,
onchange: v => updateSetting("speedScaling", v)
}
///*LANG*/'Release to select': {
// value: 1|settings().fontSize,
// min: 0, max: 1,
// format: v => [/*LANG*/"No",/*LANG*/"Yes"][v],
// onchange: v => updateSetting("releaseToSelect", v)
//}
};
E.showMenu(mainmenu);
})

View File

@ -5,3 +5,4 @@
0.05: Refactor decodeTime() to scheduling library
0.06: Add logging
use Layout library and display ETA
0.07: Add check for day of week

View File

@ -1,5 +1,7 @@
# Sleep Phase Alarm
The alarm must be in the next 24h.
The display shows:
- the current time

View File

@ -51,8 +51,10 @@ active.forEach(alarm => {
if (dateAlarm < now) { // dateAlarm in the past, add 24h
dateAlarm.setTime(dateAlarm.getTime() + (24*60*60*1000));
}
if (nextAlarm === undefined || dateAlarm < nextAlarm) {
nextAlarm = dateAlarm;
if ((alarm.dow >> dateAlarm.getDay()) & 1) { // check valid day of week
if (nextAlarm === undefined || dateAlarm < nextAlarm) {
nextAlarm = dateAlarm;
}
}
});
@ -80,7 +82,7 @@ function drawApp() {
layout.date.label = locale.time(now, BANGLEJS2 && Bangle.isLocked() ? 1 : 0); // hide seconds on bangle 2
const diff = nextAlarm - now;
const diffHour = Math.floor((diff % 86400000) / 3600000).toString();
const diffMinutes = Math.round(((diff % 86400000) % 3600000) / 60000).toString();
const diffMinutes = Math.floor(((diff % 86400000) % 3600000) / 60000).toString();
layout.eta.label = "ETA: -"+ diffHour + ":" + diffMinutes.padStart(2, '0');
layout.render();
}

View File

@ -2,7 +2,7 @@
"id": "sleepphasealarm",
"name": "SleepPhaseAlarm",
"shortName": "SleepPhaseAlarm",
"version": "0.06",
"version": "0.07",
"description": "Uses the accelerometer to estimate sleep and wake states with the principle of Estimation of Stationary Sleep-segments (ESS, see https://ubicomp.eti.uni-siegen.de/home/datasets/ichi14/index.html.en). This app will read the next alarm from the alarm application and will wake you up to 30 minutes early at the best guessed time when you are almost already awake.",
"icon": "app.png",
"tags": "alarm",

View File

@ -1,2 +1,3 @@
0.01: Initial version
0.02: Do not warn multiple times for the same exceedance
0.03: Fix crash

View File

@ -2,7 +2,7 @@
"id": "widbaroalarm",
"name": "Barometer Alarm Widget",
"shortName": "Barometer Alarm",
"version": "0.02",
"version": "0.03",
"description": "A widget that can alarm on when the pressure reaches defined thresholds.",
"icon": "widget.png",
"type": "widget",

View File

@ -104,7 +104,7 @@
saveSetting("lastHighWarningTs", 0);
}
if (!alreadyWarned) {
if (history3.length > 0 && !alreadyWarned) {
// 3h change detection
const drop3halarm = setting("drop3halarm");
const raise3halarm = setting("raise3halarm");