Added library to qalarm and created a simple timer app which is an alternative UI.

pull/1513/head
David Peer 2022-03-08 19:03:23 +01:00
parent 29faff8eb8
commit 630ea1a21c
18 changed files with 116 additions and 307 deletions

View File

@ -14,4 +14,3 @@
0.13: Alarm widget state now updates when setting/resetting an alarm
0.14: Order of 'back' menu item
0.15: Fix hour/minute wrapping code for new menu system
0.16: Expose functions for other apps

View File

@ -1,3 +0,0 @@
exports.createTimer = function() {
return 0;
}

View File

@ -2,7 +2,7 @@
"id": "alarm",
"name": "Default Alarm & Timer",
"shortName": "Alarms",
"version": "0.16",
"version": "0.15",
"description": "Set and respond to alarms and timers",
"icon": "app.png",
"tags": "tool,alarm,widget",
@ -12,8 +12,7 @@
{"name":"alarm.boot.js","url":"boot.js"},
{"name":"alarm.js","url":"alarm.js"},
{"name":"alarm.img","url":"app-icon.js","evaluate":true},
{"name":"alarm.wid.js","url":"widget.js"},
{"name":"alarm","url":"lib.js"}
{"name":"alarm.wid.js","url":"widget.js"}
],
"data": [{"name":"alarm.json"}]
}

View File

@ -1,7 +1,7 @@
WIDGETS["alarm"]={area:"tl",width:0,draw:function() {
if (this.width) g.reset().drawImage(atob("GBgBAAAAAAAAABgADhhwDDwwGP8YGf+YMf+MM//MM//MA//AA//AA//AA//AA//AA//AB//gD//wD//wAAAAADwAABgAAAAAAAAA"),this.x,this.y);
},reload:function() {
WIDGETS["alarm"].width = (require('Storage').readJSON('alarm.json',1)||[]).some(alarm=>alarm.on) ? 24 : 0;
}
if (this.width) g.reset().drawImage(atob("GBgBAAAAAAAAABgADhhwDDwwGP8YGf+YMf+MM//MM//MA//AA//AA//AA//AA//AA//AB//gD//wD//wAAAAADwAABgAAAAAAAAA"),this.x,this.y);
},reload:function() {
WIDGETS["alarm"].width = (require('Storage').readJSON('alarm.json',1)||[]).some(alarm=>alarm.on) ? 24 : 0;
}
};
WIDGETS["alarm"].reload();

View File

@ -4,4 +4,4 @@
Fix app icon
Change menu order so 'back' is at the top
0.04: Fix alarm not activating sometimes.
0.05: Include library for other apps.
0.05: Include library that can be used by other apps.

View File

@ -5,8 +5,19 @@ let alarms = require("Storage").readJSON("qalarm.json", 1) || [];
/**
* LIBRARY
*/
function getCurrentTime() {
let time = new Date();
return (
time.getHours() * 3600000 +
time.getMinutes() * 60000 +
time.getSeconds() * 1000
);
}
function alarmExists(alarmIndex){
return alarmIndex > 0 && alarmIndex < alarms.length;
var exists = alarmIndex >= 0 && alarmIndex < alarms.length;
return exists;
}
function isAlarmStarted(alarmIndex){
@ -18,20 +29,23 @@ function isAlarmStarted(alarmIndex){
let t = getCurrentTime();
a = alarms[alarmIndex];
return a.on &&
a.t <= t &&
t <= a.t &&
a.last != time.getDate() &&
(a.timer || a.daysOfWeek[time.getDay()]);
}
function getAlarmMin(alarmIndex){
function getTimerMin(alarmIndex){
if(!isAlarmStarted(alarmIndex)){
return 0;
}
let t = getCurrentTime();
let a = alarms[alarmIndex] ;
return a.t - t * 60;
}
let diff = a.t - getCurrentTime();
// let hrs = Math.floor(t / 3600000);
let mins = Math.round((diff / 60000) % 60);
// return hrs + ":" + ("0" + mins).substr(-2);
return mins;
}
function _reload(){
require("Storage").write("qalarm.json", JSON.stringify(alarms));
@ -41,34 +55,31 @@ function _reload(){
function editTimer(alarmIndex, hrs, mins, secs){
var a = {
timer: 300,
on: true,
rp: false,
as: false,
hard: false,
};
a.timer = hrs * 3600 + mins * 60 + secs;
a.t = (getCurrentTime() + alarm.timer * 1000) % 86400000;
a.t = (getCurrentTime() + a.timer * 1000) % 86400000;
if(alarmExists(a)){
alarms[alarmIndex] = a;
} else {
alarmIndex = alarms.length;
alarms.push(a)
alarmIndex = alarms.length-1;
}
_reload();
return alarmIndex;
}
function deleteAlarm(alarmIndex){
if(!alarmExists(alarmIndex)){
return;
}
alarms.splice(alarmIndex, 1);
_reload();
}
@ -76,6 +87,10 @@ function deleteAlarm(alarmIndex){
// Export functions
exports.alarmExists = alarmExists;
exports.isAlarmStarted = isAlarmStarted;
exports.getAlarmMin = getAlarmMin;
exports.editTimer = editTimer;
exports.deleteAlarm = deleteAlarm;
exports.timerExists = alarmExists;
exports.isTimerStarted = isAlarmStarted;
exports.getTimerMin = getTimerMin;
exports.editTimer = editTimer;
exports.deleteTimer = deleteAlarm;

21
apps/smpltmr/README.md Normal file
View File

@ -0,0 +1,21 @@
# Simple Timer
A simple app to set a timer quickly. Simply tab on top/bottom/left/right
to select the minutes and tab in the middle of the screen to start/stop
the timer. Note that this timer depends on qalarm.
# Overview
If you open the app, you can simply control the timer
by clicking on top, bottom, left or right of the screen.
If you tab at the middle of the screen, the timer is
started / stopped.
![](description.png)
# Creator
[David Peer](https://github.com/peerdavid)
# Thanks to...
Time icon created by <a href="https://www.flaticon.com/free-icons/time" title="time icons">CreativeCons - Flaticon</a>

View File

@ -15,32 +15,26 @@ Bangle.loadWidgets();
const storage = require('Storage');
const alarm = require('qalarm');
let settings;
const screenWidth = g.getWidth();
const screenHeight = g.getHeight();
const cx = parseInt(screenWidth/2);
const cy = parseInt(screenHeight/2)-12;
var minutes = 5;
var interval; //used for the 1 second interval timer
function updateSettings() {
var now = new Date();
const goal = new Date(now.getFullYear(), now.getMonth(), now.getDate(),
now.getHours(), now.getMinutes() + settings.minutes, now.getSeconds());
settings.goal = goal.getTime();
storage.writeJSON('widtmr.json', settings);
if (WIDGETS["widtmr"]) WIDGETS["widtmr"].reload();
}
function resetSettings() {
settings = {
hours : 0,
minutes : 0,
seconds : 0,
started : false,
counter : 0,
goal : 0,
alarmIndex: -1
};
updateSettings();
}
@ -55,15 +49,25 @@ function draw(){
g.clear(1);
Bangle.drawWidgets();
if (interval) {
clearInterval(interval);
}
interval = undefined;
// Write time
g.setFontAlign(0, 0, 0);
g.setFont("Vector", 32).setFontAlign(0,-1);
var started = alarm.isTimerStarted(settings.alarmIndex);
var text = minutes + " min.";
if(started){
var min = alarm.getTimerMin(settings.alarmIndex);
text = min + " min.";
}
print(require("alarm").createTimer());
var text = settings.minutes + " min.";
var rectWidth = parseInt(g.stringWidth(text) / 2);
if(settings.started){
if(started){
interval = setInterval(draw, 1000);
g.setColor("#ff0000");
} else {
g.setColor(g.theme.fg);
@ -74,6 +78,7 @@ function draw(){
g.drawString(text, cx, cy);
}
Bangle.on('touch', function(btn, e){
var left = parseInt(g.getWidth() * 0.25);
var right = g.getWidth() - left;
@ -84,27 +89,34 @@ Bangle.on('touch', function(btn, e){
var isRight = e.x > right;
var isUpper = e.y < upper;
var isLower = e.y > lower;
var isMiddle = !isLeft && !isRight && !isUpper && !isLower;
print(settings.alarmIndex);
var started = alarm.isTimerStarted(settings.alarmIndex);
if(isRight){
settings.minutes += 1;
if(isRight && !started){
minutes += 1;
Bangle.buzz(40, 0.3);
} else if(isLeft){
settings.minutes -= 1;
} else if(isLeft && !started){
minutes -= 1;
Bangle.buzz(40, 0.3);
} else if(isUpper){
settings.minutes += 5;
} else if(isUpper && !started){
minutes += 5;
Bangle.buzz(40, 0.3);
} else if(isLower){
settings.minutes -= 5;
} else if(isLower && !started){
minutes -= 5;
Bangle.buzz(40, 0.3);
} else {
settings.started = !settings.started;
Bangle.buzz(120, 0.6);
}
if(settings.minutes <= 0){
settings.minutes = 0;
settings.started = false;
} else if(isMiddle) {
if(!started){
settings.alarmIndex = alarm.editTimer(settings.alarmIndex, 0, minutes, 0);
print("-----")
print(settings.alarmIndex);
print(alarm.timerExists(settings.alarmIndex))
print(alarm.isTimerStarted(settings.alarmIndex))
print("-----")
} else {
alarm.deleteTimer(settings.alarmIndex);
}
Bangle.buzz(80, 0.6);
}
updateSettings();

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

View File

@ -0,0 +1,17 @@
{
"id": "smpltmr",
"name": "Simple Timer",
"shortName": "Simple Timer",
"version": "0.01",
"description": "A simple app to set a timer.",
"icon": "app.png",
"tags": "tool",
"dependencies": {"qalarm":"app"},
"supports": ["BANGLEJS2"],
"screenshots": [{"url":"screenshot.png"}, {"url": "screenshot_2.png"}],
"readme": "README.md",
"storage": [
{"name":"smpltmr.app.js","url":"app.js"},
{"name":"smpltmr.img","url":"app-icon.js","evaluate":true}
]
}

View File

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -1,67 +0,0 @@
# Timer Widget
This is a fork of the Chrono Widget, but implements a
simpler UI. Additionally, it exposes functions for other
apps or clocks such that they can easily implement a timer.
Currently, it is used by lcars and notanalog.
# Overview
If you open the app, you can simply control the timer
by clicking on top, bottom, left or right of the screen.
If you tab at the middle of the screen, the timer is
started / stopped.
![](description.png)
# Lib
Different functions are exposed by widtmr which enables other
apps to directly use and integrate this functionality:
The following functions are available:
- isStarted() -> boolean
- setStarted(boolean) -> void
- setTimer(t) -> void
- increaseTimer(int) -> void
- decreaseTimer(int) -> void
- getRemainingMinutes() -> int
- getRemainingTime() -> DateTime
- getRemainingTimeStr() -> str
For example if we want to increase the timer by +5 minutes each time
the touch event is fired:
```Javascript
Bangle.loadWidgets();
...
Bangle.on('touch', function(btn, e){
// Set to zero if alarm was disabled before. Otherwise
// it starts from the last setting made by the user.
if(!isAlarmEnabled()){
WIDGETS["widtmr"].setTimer(0);
}
WIDGETS["widtmr"].increaseTimer(5);
WIDGETS["widtmr"].setStarted(true);
});
```
Example to decrease the timer by 5 and stop if 0 is reached:
```Javascript
Bangle.loadWidgets();
...
Bangle.on('touch', function(btn, e){
WIDGETS["widtmr"].decreaseTimer(5);
}
```
You can find implementations and usages in the lcars or notanalog app.
# Creator
[David Peer](https://github.com/peerdavid)
# Thanks to...
Forked from Chrono Widget of [Purple-Tentacle](https://github.com/Purple-Tentacle)
Time icon created by <a href="https://www.flaticon.com/free-icons/time" title="time icons">CreativeCons - Flaticon</a>

View File

@ -1,17 +0,0 @@
{
"id": "widtmr",
"name": "Timer Widget",
"shortName": "Timer Widget",
"version": "0.01",
"description": "Fork from Chrono Widget with a simpler UI and a lib for other apps.",
"icon": "app.png",
"tags": "tool,widget",
"supports": ["BANGLEJS","BANGLEJS2"],
"screenshots": [{"url":"screenshot.png"}, {"url": "screenshot_2.png"}],
"readme": "README.md",
"storage": [
{"name":"widtmr.wid.js","url":"widget.js"},
{"name":"widtmr.app.js","url":"app.js"},
{"name":"widtmr.img","url":"app-icon.js","evaluate":true}
]
}

View File

@ -1,167 +0,0 @@
(() => {
let storage = require('Storage');
var settings;
var interval = 0; //used for the 1 second interval timer
var diff;
//Convert ms to time
function getTime(t) {
var milliseconds = parseInt((t % 1000) / 100),
seconds = Math.floor((t / 1000) % 60),
minutes = Math.floor((t / (1000 * 60)) % 60),
hours = Math.floor((t / (1000 * 60 * 60)) % 24);
return hours.toString().padStart(2,0) + ":" + minutes.toString().padStart(2,0) + ":" + seconds.toString().padStart(2,0);
}
//counts down, calculates and displays
function countDown() {
var now = new Date();
diff = settings.goal - now; //calculate difference
// time is up
if (settings.started && diff < 1000) {
Bangle.buzz(1500);
//write timer off to file
settings.started = false;
storage.writeJSON('widtmr.json', settings);
clearInterval(interval); //stop interval
interval = undefined;
}
// calculates width and redraws accordingly
WIDGETS["widtmr"].redraw();
}
function updateSettings(){
var now = new Date();
const goal = new Date(now.getFullYear(), now.getMonth(), now.getDate(),
now.getHours(), now.getMinutes() + settings.minutes, now.getSeconds());
settings.goal = goal.getTime();
settings.goal = goal.getTime();
storage.writeJSON('widtmr.json', settings);
WIDGETS["widtmr"].reload();
}
/*
* Add the widgets and functions for other apps
*/
WIDGETS["widtmr"]={area:"tl",width:0,draw:function() {
if (!this.width) {
return;
}
g.reset().setFontAlign(0,0).clearRect(this.x,this.y,this.x+this.width,this.y+23);
var scale;
var timeStr;
if (diff < 3600000) { //less than 1 hour left
width = 58;
scale = 2;
timeStr = getTime(diff).substring(3); // remove hour part 00:00:00 -> 00:00
} else { //one hour or more left
width = 48;
scale = 1;
timeStr = getTime(diff); //display hour 00:00:00 but small
}
// Font5x9Numeric7Seg - just build this in as it's tiny
g.setFontCustom(atob("AAAAAAAAAAIAAAQCAQAAAd0BgMBdwAAAAAAAdwAB0RiMRcAAAERiMRdwAcAQCAQdwAcERiMRBwAd0RiMRBwAAEAgEAdwAd0RiMRdwAcERiMRdwAFAAd0QiEQdwAdwRCIRBwAd0BgMBAAABwRCIRdwAd0RiMRAAAd0QiEQAAAAAAAAAA="), 32, atob("BgAAAAAAAAAAAAAAAAYCAAYGBgYGBgYGBgYCAAAAAAAABgYGBgYG"), 9 + (scale<<8));
g.drawString(timeStr, this.x+this.width/2, this.y+12);
}, redraw:function() {
var last = this.width;
if (!settings.started) {
this.width = 0;
} else {
this.width = (diff < 3600000) ? 58 : 48;
}
if (last != this.width) {
Bangle.drawWidgets();
} else {
this.draw();
}
}, reload:function() {
settings = storage.readJSON("widtmr.json",1)||{};
if (interval) {
clearInterval(interval);
}
interval = undefined;
// start countdown each second
if (settings.started) {
interval = setInterval(countDown, 1000);
}
// reset everything
countDown();
}, isStarted: function(){
settings = storage.readJSON("widtmr.json",1)||{started: false};
return settings.started;
}, setStarted: function(started){
settings.started=started;
updateSettings();
}, increaseTimer: function(m){
settings.minutes += m;
updateSettings();
}, decreaseTimer: function(m){
settings.minutes -= m;
if(settings.minutes <= 0){
settings.started=false;
settings.minutes=0;
}
updateSettings();
}, setTimer: function(t){
settings.minutes = Math.max(0, t);
settings.started = t > 0;
updateSettings();
}, getRemainingMinutes: function(){
settings = storage.readJSON("widtmr.json",1)||{started: false};
if(!settings.started){
return -1;
}
var now = new Date();
var diff = settings.goal - now;
return Math.round(diff / (1000*60));
}, getRemainingTimeStr: function(){
settings = storage.readJSON("widtmr.json",1)||{started: false};
if(!settings.started){
return;
}
var now = new Date();
var diff = settings.goal - now;
var timeStr = getTime(diff);
if(diff < 3600000){
timeStr = timeStr.substring(3); // remove hour part 00:00:00 -> 00:00
}
return timeStr;
}, getRemainingTime: function(){
settings = storage.readJSON("widtmr.json",1)||{started: false};
if(!settings.started){
return;
}
var now = new Date();
var diff = settings.goal - now;
return diff;
}
};
// set width correctly, start countdown each second
WIDGETS["widtmr"].reload();
})();