forked from FOSS/BangleApps
271 lines
5.1 KiB
JavaScript
271 lines
5.1 KiB
JavaScript
/* UI GLOBALS */
|
|
|
|
//const HOUR_SCENE = 0;
|
|
//const MIN_SCENE = 1;
|
|
//const SEC_SCENE = 2;
|
|
const COUNTDOWN_SCENE = 3;
|
|
|
|
var currentScene = 0;
|
|
|
|
//var btn1Watch;
|
|
//var btn2Watch;
|
|
//var btn3Watch;
|
|
|
|
var drawInterval;
|
|
|
|
/* STATE GLOBALS */
|
|
|
|
var menuTime = new Uint8Array([0,0,0]);
|
|
var countdownTime = menuTime.slice(0);
|
|
var show = [true, true, true];
|
|
|
|
/* COUNTDOWN CONSTANTS */
|
|
|
|
const HOUR_INDEX = 0;
|
|
const MIN_INDEX = 1;
|
|
const SEC_INDEX = 2;
|
|
|
|
var flashIndex = HOUR_INDEX;
|
|
|
|
/* logic */
|
|
|
|
function setCountdownTime() {
|
|
countdownTime = menuTime.slice(0);
|
|
}
|
|
|
|
function countDownFinished() {
|
|
return countdownTime[HOUR_INDEX] <= 0 &&
|
|
countdownTime[MIN_INDEX] <= 0 &&
|
|
countdownTime[SEC_INDEX] <= 0;
|
|
}
|
|
|
|
function alertCountdownFinished() {
|
|
if (drawInterval) return;
|
|
Bangle.buzz()
|
|
.then(() => new Promise(resolve => setTimeout(resolve, 200)))
|
|
.then(() => Bangle.buzz());
|
|
setTimeout(alertCountdownFinished, 2000);
|
|
}
|
|
|
|
function unsetDrawInterval() {
|
|
clearInterval(drawInterval);
|
|
drawInterval = undefined;
|
|
}
|
|
|
|
function decrementCountdownTime() {
|
|
const allZero = countDownFinished();
|
|
|
|
if(allZero) {
|
|
return;
|
|
}
|
|
|
|
if (countdownTime[SEC_INDEX] !== 0) {
|
|
countdownTime[SEC_INDEX] = countdownTime[SEC_INDEX] - 1;
|
|
return;
|
|
}
|
|
|
|
countdownTime[SEC_INDEX] = 59;
|
|
|
|
if (countdownTime[MIN_INDEX] !== 0) {
|
|
countdownTime[MIN_INDEX] = countdownTime[MIN_INDEX] - 1;
|
|
return;
|
|
}
|
|
|
|
countdownTime[MIN_INDEX] = 59;
|
|
|
|
if (countdownTime[HOUR_INDEX] !== 0) {
|
|
countdownTime[HOUR_INDEX] = countdownTime[HOUR_INDEX] - 1;
|
|
return;
|
|
}
|
|
}
|
|
|
|
function toggleShow(timeIndex) {
|
|
show[timeIndex] = !show[timeIndex];
|
|
}
|
|
|
|
function twoPadded(i) {
|
|
return i.length < 2 ? "0" + i : i;
|
|
}
|
|
|
|
function getTimeString(t) {
|
|
let hour = t[HOUR_INDEX].toString();
|
|
let min = t[MIN_INDEX].toString();
|
|
let sec = t[SEC_INDEX].toString();
|
|
|
|
hour = show[HOUR_INDEX] ? twoPadded(hour) : " ";
|
|
min = show[MIN_INDEX] ? twoPadded(min) : " ";
|
|
sec = show[SEC_INDEX] ? twoPadded(sec) : " ";
|
|
|
|
return hour + ":" + min + ":" + sec;
|
|
}
|
|
|
|
/* drawing */
|
|
|
|
/*
|
|
shamelessly stollen from Bluetooth Music Controls
|
|
https://github.com/espruino/BangleApps/blob/6b09377414e02d575b8335bb051c831ecc9da9d9/apps/hidmsic/hid-music.js#L42
|
|
*/
|
|
function drawArrows() {
|
|
function c(a) {
|
|
return {
|
|
width: 8,
|
|
height: a.length,
|
|
bpp: 1,
|
|
buffer: (new Uint8Array(a)).buffer
|
|
};
|
|
}
|
|
const d = g.getWidth() - 18;
|
|
g.drawImage(c([16,56,124,254,16,16,16,16]),d,40);
|
|
g.drawImage(c([16,16,16,16,254,124,56,16]),d,194);
|
|
g.drawImage(c([0,8,12,14,255,14,12,8]),d,116);
|
|
}
|
|
|
|
function drawTime(input) {
|
|
g.clear();
|
|
g.setFontAlign(0,0);
|
|
g.setFont("4x6",5);
|
|
g.drawString(input, g.getWidth() / 2, g.getHeight() / 2);
|
|
}
|
|
|
|
function drawMenu() {
|
|
const timeString = getTimeString(menuTime);
|
|
drawTime(timeString);
|
|
drawArrows();
|
|
}
|
|
|
|
function drawCountdown() {
|
|
const timeString = getTimeString(countdownTime);
|
|
drawTime(timeString);
|
|
}
|
|
|
|
/* button callbacks */
|
|
|
|
function getMaxSelectableTime() {
|
|
return flashIndex === HOUR_INDEX ? 23 : 59;
|
|
}
|
|
|
|
/* btn1 */
|
|
|
|
function incrementMenuTime() {
|
|
const maxTime = getMaxSelectableTime();
|
|
const currentTime = menuTime[flashIndex];
|
|
const newTime = currentTime < maxTime ? currentTime + 1 : 0;
|
|
menuTime[flashIndex] = newTime;
|
|
}
|
|
|
|
/* btn2 */
|
|
|
|
function incrementScene() {
|
|
currentScene++;
|
|
}
|
|
|
|
function incrementFlashIndex() {
|
|
flashIndex++;
|
|
}
|
|
|
|
function showAll() {
|
|
for(var i = 0; i < show.length; i++) {
|
|
show[i] = true;
|
|
}
|
|
}
|
|
|
|
function showFlashIndex() {
|
|
show[flashIndex] = true;
|
|
}
|
|
|
|
function hideFlashIndex() {
|
|
show[flashIndex] = false;
|
|
}
|
|
|
|
function next() {
|
|
incrementScene();
|
|
|
|
if (currentScene === COUNTDOWN_SCENE) {
|
|
showAll();
|
|
startCountdownScene();
|
|
} else {
|
|
showFlashIndex();
|
|
incrementFlashIndex();
|
|
hideFlashIndex();
|
|
}
|
|
}
|
|
|
|
/* btn3 */
|
|
|
|
function decrementMenuTime() {
|
|
const maxTime = getMaxSelectableTime();
|
|
const currentTime = menuTime[flashIndex];
|
|
const newTime = currentTime > 0 ? currentTime - 1 : maxTime;
|
|
menuTime[flashIndex] = newTime;
|
|
}
|
|
|
|
/* watches */
|
|
|
|
function setupMenuWatches() {
|
|
clearWatch();
|
|
/*btn1Watch =*/ setWatch(incrementMenuTime, BTN1, {repeat: true});
|
|
/*btn2Watch =*/ setWatch(next, BTN2, {repeat: true});
|
|
/*btn3Watch =*/ setWatch(decrementMenuTime, BTN3, {repeat: true});
|
|
}
|
|
|
|
function setupCountdownWatches() {
|
|
clearWatch();
|
|
/*btn2Watch =*/ setWatch(main, BTN2, {repeat: true});
|
|
}
|
|
|
|
/* scenes */
|
|
|
|
function menu() {
|
|
drawMenu();
|
|
toggleShow(flashIndex);
|
|
}
|
|
|
|
function countdown() {
|
|
decrementCountdownTime();
|
|
drawCountdown();
|
|
|
|
if (countDownFinished()) {
|
|
unsetDrawInterval();
|
|
alertCountdownFinished();
|
|
}
|
|
}
|
|
|
|
/* init */
|
|
|
|
function unsetDrawInterval() {
|
|
if (!drawInterval) return;
|
|
clearInterval(drawInterval);
|
|
drawInterval = undefined;
|
|
}
|
|
|
|
function startMenuScene() {
|
|
setupMenuWatches();
|
|
unsetDrawInterval();
|
|
menu();
|
|
drawInterval = setInterval(menu, 500);
|
|
}
|
|
|
|
function startCountdownScene() {
|
|
setupCountdownWatches();
|
|
unsetDrawInterval();
|
|
setCountdownTime();
|
|
showAll();
|
|
drawCountdown();
|
|
drawInterval = setInterval(countdown, 1000);
|
|
}
|
|
|
|
/* main */
|
|
|
|
function reset() {
|
|
currentScene = 0;
|
|
flashIndex = HOUR_INDEX;
|
|
hideFlashIndex();
|
|
}
|
|
|
|
function main() {
|
|
reset();
|
|
startMenuScene();
|
|
}
|
|
|
|
main();
|