BangleApps/apps/smpltmr/app.js

196 lines
5.5 KiB
JavaScript
Raw Normal View History

/*
* SIMPLE TIMER
*
* Creator: David Peer
* Date: 02/2022
*
* Modified: Sir Indy
* Date: 05/2022
*/
const Layout = require("Layout");
const alarm = require("sched")
const TIMER_IDX = "smpltmr";
2022-05-01 17:02:15 +00:00
const secondsToTime = (s) => new Object({h:Math.floor((s/3600) % 24), m:Math.floor((s/60) % 60), s:Math.floor(s % 60)});
const clamp = (num, min, max) => Math.min(Math.max(num, min), max);
function formatTime(s) {
var t = secondsToTime(s);
if (t.h) {
return t.h + ':' + ("0" + t.m).substr(-2) + ':' + ("0" + t.s).substr(-2);
} else {
return t.m + ':' + ("0" + t.s).substr(-2);
}
}
var seconds = 5 * 60; // Default to 5 minutes
var drawTimeout;
//var timerRunning = false;
function timerRunning() {
return (alarm.getTimeToAlarm(alarm.getAlarm(TIMER_IDX)) != undefined)
}
const imgArrow = Graphics.createImage(`
2022-05-01 17:02:15 +00:00
x
xxx
xxx
xxxxx
xxxxx
xxx xxx
xxx xxx
xxx xxx
xxx xxx
`);
const imgPause = atob("GBiBAP+B//+B//+B//+B//+B//+B//+B//+B//+B//+B//+B//+B//+B//+B//+B//+B//+B//+B//+B//+B//+B//+B//+B//+B/w==");
const imgPlay = atob("GBiBAIAAAOAAAPgAAP4AAP+AAP/gAP/4AP/+AP//gP//4P//+P///v///v//+P//4P//gP/+AP/4AP/gAP+AAP4AAPgAAOAAAIAAAA==");
function onDrag(event) {
if (timerRunning()) {
Bangle.buzz(40, 0.3);
var diff = -Math.round(event.dy/5);
if (event.x < timePickerLayout.hours.w) {
diff *= 3600;
} else if (event.x > timePickerLayout.mins.x && event.x < timePickerLayout.secs.x) {
diff *= 60;
}
updateTimePicker(diff);
}
}
2022-05-01 17:02:15 +00:00
function onTouch(button, xy) {
var touchMidpoint = timePickerLayout.hours.y + timePickerLayout.hours.h/2;
var diff = 0;
if (timerRunning() && xy.y > 24 && xy.y < touchMidpoint - 10) {
2022-05-01 17:02:15 +00:00
Bangle.buzz(40, 0.3);
diff = 1;
} else if (timerRunning() && xy.y > touchMidpoint + 10 && xy.y < timePickerLayout.btnStart.y) {
2022-05-01 17:02:15 +00:00
Bangle.buzz(40, 0.3);
diff = -1;
} else if (xy.y > timePickerLayout.btnStart.y) {
Bangle.buzz(40, 0.6);
2022-05-01 17:11:00 +00:00
onButton();
2022-05-01 17:02:15 +00:00
return;
}
if (xy.x < timePickerLayout.hours.w) {
diff *= 3600;
} else if (xy.x > timePickerLayout.mins.x && xy.x < timePickerLayout.secs.x) {
diff *= 60;
}
updateTimePicker(diff);
}
2022-05-01 17:02:15 +00:00
function onButton() {
g.clearRect(Bangle.appRect);
if (timerRunning()) {
2022-05-01 17:20:59 +00:00
timerStop();
2022-05-01 17:38:49 +00:00
} else {
timerRun();
2022-05-01 17:02:15 +00:00
}
}
2022-05-01 17:02:15 +00:00
function updateTimePicker(diff) {
seconds = clamp(seconds + (diff || 0), 0, 24 * 3600 - 1);
var set_time = secondsToTime(seconds);
updateLayoutField(timePickerLayout, 'hours', set_time.h);
updateLayoutField(timePickerLayout, 'mins', set_time.m);
updateLayoutField(timePickerLayout, 'secs', set_time.s);
}
2022-05-01 17:02:15 +00:00
function updateTimer() {
var timeToNext = alarm.getTimeToAlarm(alarm.getAlarm(TIMER_IDX));
2022-05-01 17:02:15 +00:00
updateLayoutField(timerLayout, 'timer', formatTime(timeToNext / 1000));
queueDraw(1000);
}
2022-05-01 17:02:15 +00:00
function queueDraw(millisecs) {
if (drawTimeout) clearTimeout(drawTimeout);
drawTimeout = setTimeout(function() {
drawTimeout = undefined;
updateTimer();
}, millisecs - (Date.now() % millisecs));
}
2022-02-23 20:47:22 +00:00
2022-05-01 17:20:59 +00:00
function timerRun() {
alarm.setAlarm(TIMER_IDX, {
2022-05-01 17:02:15 +00:00
vibrate : ".-.-",
hidden: true,
timer : seconds * 1000
});
alarm.reload();
2022-05-01 17:02:15 +00:00
g.clearRect(Bangle.appRect);
timerLayout.render();
updateTimer();
}
2022-02-23 19:10:09 +00:00
2022-05-01 17:20:59 +00:00
function timerStop() {
if (drawTimeout) clearTimeout(drawTimeout);
drawTimeout = undefined;
var timeToNext = alarm.getTimeToAlarm(alarm.getAlarm(TIMER_IDX));
2022-05-01 17:25:55 +00:00
if (timeToNext != undefined) {
seconds = timeToNext / 1000;
}
alarm.setAlarm(TIMER_IDX, undefined);
alarm.reload();
g.clearRect(Bangle.appRect);
timePickerLayout.render();
updateTimePicker();
2022-05-01 17:20:59 +00:00
}
2022-05-01 17:02:15 +00:00
var timePickerLayout = new Layout({
type:"v", c: [
{type:undefined, height:2},
{type:"h", c: [
{type:"v", width:g.getWidth()/3, c: [
{type:"txt", font:"6x8", label:/*LANG*/"Hours", col:g.theme.fg2},
{type:"img", pad:8, src:imgArrow, col:g.theme.fg2},
{type:"txt", font:"20%", label:"00", id:"hours", filly:1, fillx:1},
{type:"img", pad:8, src:imgArrow, col:g.theme.fg2, r:2}
]},
{type:"v", width:g.getWidth()/3, c: [
{type:"txt", font:"6x8", label:/*LANG*/"Minutes", col:g.theme.fg2},
{type:"img", pad:8, src:imgArrow, col:g.theme.fg2},
{type:"txt", font:"20%", label:"00", id:"mins", filly:1, fillx:1},
{type:"img", pad:8, src:imgArrow, col:g.theme.fg2, r:2}
]},
{type:"v", width:g.getWidth()/3, c: [
{type:"txt", font:"6x8", label:/*LANG*/"Seconds", col:g.theme.fg2},
{type:"img", pad:8, src:imgArrow, col:g.theme.fg2},
{type:"txt", font:"20%", label:"00", id:"secs", filly:1, fillx:1},
{type:"img", pad:8, src:imgArrow, col:g.theme.fg2, r:2}
]},
]},
{type:"btn", src:imgPlay, id:"btnStart", fillx:1 }
], filly:1
});
2022-02-23 20:53:27 +00:00
2022-05-01 17:02:15 +00:00
var timerLayout = new Layout({
type:"v", c: [
{type:"txt", font:"22%", label:"0:00", id:"timer", fillx:1, filly:1 },
{type:"btn", src:imgPause, cb: l=>timerStop(), fillx:1 }
], filly:1
2022-02-23 19:10:09 +00:00
});
2022-05-01 17:38:49 +00:00
function updateLayoutField(layout, field, value) {
layout.clear(layout[field]);
layout[field].label = value;
layout.render(layout[field]);
}
Bangle.loadWidgets();
Bangle.drawWidgets();
Bangle.setUI({
mode : "custom",
touch : function(n,e) {onTouch(n,e);},
drag : function(e) {onDrag(e);},
btn : function(n) {onButton();},
});
g.clearRect(Bangle.appRect);
if (timerRunning()) {
timerLayout.render();
updateTimer();
} else {
timePickerLayout.render();
updateTimePicker();
}