Merge branch 'espruino:master' into feature/introduce_settings

pull/1540/head
smekras 2022-02-26 01:16:36 +01:00 committed by GitHub
commit 728ac86aeb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
64 changed files with 1016 additions and 171 deletions

View File

@ -5,7 +5,7 @@ by Peter Kuppelwieser
*/
let settings = Object.assign({ swupApp: "",swdownApp: "", swleftApp: "", swrightApp: ""}, require("Storage").readJSON("7x7dotsclock.json", true) || {});
let settings = Object.assign({ swupApp: "",swdownApp: "", swleftApp: "", swrightApp: "", ColorMinutes: ""}, require("Storage").readJSON("7x7dotsclock.json", true) || {});
// position on screen
var Xs = 0, Ys = 30,Xe = 175, Ye=175;
@ -13,9 +13,33 @@ var Xs = 0, Ys = 30,Xe = 175, Ye=175;
var SegH = (Ye-Ys)/2,SegW = (Xe-Xs)/2;
var Dx = SegW/14, Dy = SegH/16;
const hColor = [1,1,1];
const mColor = [0.3,0.3,1];
const bColor = [0.2,0.2,0.2];
switch(settings.ColorMinutes) {
case "blue":
var mColor = [0.3,0.3,1];
var sColor = [0,0,1];
var sbColor = [1,1,1];
break;
case "pink":
var mColor = [1,0.3,1];
var sColor = [1,0,1];
var sbColor = [1,1,1];
break;
case "green":
var mColor = [0.3,1,0.3];
var sColor = [0,1,0];
var sbColor = [1,1,1];
break;
case "yellow":
var mColor = [1,1,0.3];
var sColor = [1,1,0];
var sbColor = [0,0,0];
break;
default:
var sColor = [0,0,1];
var mColor = [0.3,0.3,1];
var sbColor = [1,1,1];
}
const bColor = [0.3,0.3,0.3];
const Font = [
[
@ -114,16 +138,22 @@ const Font = [
var dho = -1, eho = -1, dmo = -1, emo = -1;
function drawHSeg(x1,y1,x2,y2,Num,dColor,Size) {
g.setColor(0,0,0);
function drawHSeg(x1,y1,x2,y2,Num,Color,Size) {
g.setColor(g.theme.bg);
g.fillRect(x1, y1, x2, y2);
for (let i = 1; i < 8; i++) {
for (let j = 1; j < 8; j++) {
if (Font[Num][j-1][i-1] == 1) {
g.setColor(dColor[0],dColor[1],dColor[2]);
if (Color == "fg") {
g.setColor(g.theme.fg);
} else {
g.setColor(mColor[0],mColor[1],mColor[2]);
}
g.fillCircle(x1+Dx+(i-1)*(x2-x1)/7,y1+Dy+(j-1)*(y2-y1)/7,Size);
} else {
g.setColor(bColor[0],bColor[1],bColor[2]);
g.setColor(bColor[0],bColor[1],bColor[2]);
g.fillCircle(x1+Dx+(i-1)*(x2-x1)/7,y1+Dy+(j-1)*(y2-y1)/7,1);
}
}
@ -131,11 +161,16 @@ function drawHSeg(x1,y1,x2,y2,Num,dColor,Size) {
}
function drawSSeg(x1,y1,x2,y2,Num,dColor,Size) {
function drawSSeg(x1,y1,x2,y2,Num,Color,Size) {
for (let i = 1; i < 8; i++) {
for (let j = 1; j < 8; j++) {
if (Font[Num][j-1][i-1] == 1) {
g.setColor(dColor[0],dColor[1],dColor[2]);
if (Color == "fg") {
g.setColor(sColor[0],sColor[1],sColor[2]);
} else {
g.setColor(g.theme.fg);
//g.setColor(0.7,0.7,0.7);
}
g.fillCircle(x1+(i-1)*(x2-x1)/7,y1+(j-1)*(y2-y1)/7,Size);
}
}
@ -143,25 +178,27 @@ function drawSSeg(x1,y1,x2,y2,Num,dColor,Size) {
}
function ShowSecons() {
g.setColor(1,1,1);
g.fillRect((Xe-Xs) / 2 - 14 + Xs -3,
(Ye-Ys) / 2 - 7 + Ys -3,
(Xe-Xs) / 2 + 14 + Xs +1,
(Ye-Ys) / 2 + 7 + Ys +1);
function ShowSeconds() {
g.setColor(sbColor[0],sbColor[1],sbColor[2]);
g.fillRect((Xe-Xs) / 2 - 14 + Xs -4,
(Ye-Ys) / 2 - 7 + Ys -4,
(Xe-Xs) / 2 + 14 + Xs +4,
(Ye-Ys) / 2 + 7 + Ys +4);
drawSSeg( (Xe-Xs) / 2 - 14 + Xs -1,
(Ye-Ys) / 2 - 7 + Ys ,
(Ye-Ys) / 2 - 7 + Ys +1,
(Xe-Xs) / 2 + Xs -1,
(Ye-Ys) / 2 + 7 + Ys,
ds,mColor,1);
(Ye-Ys) / 2 + 7 + Ys +1,
ds,"fg",1);
drawSSeg( (Xe-Xs) / 2 + Xs +1,
(Ye-Ys) / 2 - 7 + Ys,
(Xe-Xs) / 2 + 14 + Xs +1,
(Ye-Ys) / 2 + 7 + Ys,
es,mColor,1);
drawSSeg( (Xe-Xs) / 2 + Xs +2,
(Ye-Ys) / 2 - 7 + Ys +1,
(Xe-Xs) / 2 + 14 + Xs +2,
(Ye-Ys) / 2 + 7 + Ys +1,
es,"fg",1);
}
@ -185,29 +222,29 @@ function draw() {
g.reset();
if (dh != dho) {
g.setColor(1,1,1);
drawHSeg(Xs, Ys, Xs+SegW, Ys+SegH,dh,hColor,4);
drawHSeg(Xs, Ys, Xs+SegW, Ys+SegH,dh,"fg",4);
dho = dh;
}
if (eh != eho) {
g.setColor(1,1,1);
drawHSeg(Xs+SegW+Dx, Ys, Xs+SegW*2, Ys+SegH,eh,hColor,4);
drawHSeg(Xs+SegW+Dx, Ys, Xs+SegW*2, Ys+SegH,eh,"fg",4);
eho = eh;
}
if (dm != dmo) {
g.setColor(0.3,0.3,1);
drawHSeg(Xs, Ys+SegH+Dy, Xs+SegW, Ys+SegH*2,dm,mColor,4);
drawHSeg(Xs, Ys+SegH+Dy, Xs+SegW, Ys+SegH*2,dm,"",4);
dmo = dm;
}
if (em != emo) {
g.setColor(0.3,0.3,1);
drawHSeg(Xs+SegW+Dx, Ys+SegH+Dy, Xs+SegW*2, Ys+SegH*2,em,mColor,4);
drawHSeg(Xs+SegW+Dx, Ys+SegH+Dy, Xs+SegW*2, Ys+SegH*2,em,"",4);
emo = em;
}
if (!Bangle.isLocked()) ShowSecons();
if (!Bangle.isLocked()) ShowSeconds();
}
@ -278,7 +315,7 @@ function drawWidgeds() {
var x1M = 100;
var y1M = y1B;
var x2M = x1M + 30;
var x2M = x1M + 25;
var y2M = y2B;
if (messages.some(m=>m.new)) {
@ -295,6 +332,7 @@ function drawWidgeds() {
print(strDow[dow] + ' ' + day + '.' + month + ' ' + year);
g.setColor(g.theme.fg);
g.setFontAlign(-1, -1,0);
g.setFont("Vector", 20);
g.drawString(strDow[dow] + ' ' + day, 0, 0, true);

View File

@ -1,21 +1,8 @@
(function(back) {
let settings = Object.assign({ swupApp: "",swdownApp: "", swleftApp: "", swrightApp: ""}, require("Storage").readJSON("7x7dotsclock.json", true) || {});
let settings = Object.assign({ swupApp: "",swdownApp: "", swleftApp: "", swrightApp: "",ColorMinutes: ""}, require("Storage").readJSON("7x7dotsclock.json", true) || {});
function showMainMenu() {
const mainMenu = {
"": {"title": "7x7 Dots Clock Settings"},
"< Back": ()=>load(),
"sw-up": ()=>showSelAppMenu("swupApp"),
"sw-down": ()=>showSelAppMenu("swdownApp"),
"sw-left": ()=>showSelAppMenu("swleftApp"),
"sw-right": ()=>showSelAppMenu("swrightApp")
};
E.showMenu(mainMenu);
}
function setSetting(key,value) {
print("call " + key + " = " + value);
@ -26,6 +13,42 @@ function setSetting(key,value) {
}
// Helper method which uses int-based menu item for set of string values
function stringItems(key, startvalue, 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 => {
setSetting(key,values[v]);
}
};
}
// Helper method which breaks string set settings down to local settings object
function stringInSettings(name, values) {
return stringItems(name,settings[name], values);
}
function showMainMenu() {
const mainMenu = {
"": {"title": "7x7 Dots Clock Settings"},
"< Back": ()=>load(),
"Minutes": stringInSettings("ColorMinutes", ["blue","pink","green","yellow"]),
"swipe-up": ()=>showSelAppMenu("swupApp"),
"swipe-down": ()=>showSelAppMenu("swdownApp"),
"swipe-left": ()=>showSelAppMenu("swleftApp"),
"swipe-right": ()=>showSelAppMenu("swrightApp")
};
E.showMenu(mainMenu);
}
function showSelAppMenu(key) {
var Apps = require("Storage").list(/\.info$/)
.map(app => {var a=storage.readJSON(app, 1);return (

View File

@ -1 +1,2 @@
0.01: Initial version for upload
0.02: better theme support, configurable colors, small improvements

View File

@ -2,16 +2,14 @@
![](dotsfontclock.png)
looks best with dark theme so far
* A Clock with big numbers made of 7x7 dots
* system widgeds ar not (yet) supported
* when screen is locked it shows hours and minutes in full screen mode
* adjustable color for minutes and seconds
![](dotsfontclock-scr1.png)
* when screen is unlocked it shows additional info: bluetooth, battery, new message, date and seconds
* you can configure a app per swipe direction
* when swiping the configured apps are launced
* when screen is unlocked it shows additional info: bluetooth, battery, new message state, date and seconds
* you can configure an app per swipe direction
* when swiping the configured apps are launched
* button press opens launcher

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@ -1,17 +1,19 @@
{ "id": "7x7dotsclock",
"name": "7x7 Dots Clock",
"shortName":"7x7 Dots Clock",
"version":"0.01",
"version":"0.02",
"description": "A clock with a big 7x7 dots Font",
"icon": "dotsfontclock.png",
"tags": "clock",
"type": "clock",
"supports" : ["BANGLEJS2"],
"supports" : ["BANGLEJS2"],
"allow_emulator": true,
"readme": "README.md",
"storage": [
{"name":"7x7dotsclock.app.js","url":"7x7dotsclock.app.js"},
{"name":"7x7dotsclock.settings.js","url":"7x7dotsclock.settings.js"},
{"name":"7x7dotsclock.img","url":"7x7dotsclock.img.js","evaluate":true}
],
"data": [{"name":"7x7dotsclock.json"}]
"data": [{"name":"7x7dotsclock.json"}],
"screenshots": [{"url":"dotsfontclock.png"},{"url":"dotsfontclock-scr1.png"},{"url":"dotsfontclock-scr2.png"}]
}

View File

@ -13,3 +13,4 @@
Widgets now shown on Alarm screen
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

View File

@ -73,12 +73,12 @@ function editAlarm(alarmIndex) {
'': { 'title': /*LANG*/'Alarm' },
/*LANG*/'< Back' : showMainMenu,
/*LANG*/'Hours': {
value: hrs,
onchange: function(v){if (v<0)v=23;if (v>23)v=0;hrs=v;this.value=v;} // no arrow fn -> preserve 'this'
value: hrs, min : 0, max : 23, wrap : true,
onchange: v => hrs=v
},
/*LANG*/'Minutes': {
value: mins,
onchange: function(v){if (v<0)v=59;if (v>59)v=0;mins=v;this.value=v;} // no arrow fn -> preserve 'this'
value: mins, min : 0, max : 59, wrap : true,
onchange: v => mins=v
},
/*LANG*/'Enabled': {
value: en,
@ -138,12 +138,12 @@ function editTimer(alarmIndex) {
const menu = {
'': { 'title': /*LANG*/'Timer' },
/*LANG*/'Hours': {
value: hrs,
onchange: function(v){if (v<0)v=23;if (v>23)v=0;hrs=v;this.value=v;} // no arrow fn -> preserve 'this'
value: hrs, min : 0, max : 23, wrap : true,
onchange: v => hrs=v
},
/*LANG*/'Minutes': {
value: mins,
onchange: function(v){if (v<0)v=59;if (v>59)v=0;mins=v;this.value=v;} // no arrow fn -> preserve 'this'
value: mins, min : 0, max : 59, wrap : true,
onchange: v => mins=v
},
/*LANG*/'Enabled': {
value: en,

View File

@ -2,7 +2,7 @@
"id": "alarm",
"name": "Default Alarm & Timer",
"shortName": "Alarms",
"version": "0.14",
"version": "0.15",
"description": "Set and respond to alarms and timers",
"icon": "app.png",
"tags": "tool,alarm,widget",

8
apps/aptsciclk/ChangeLog Normal file
View File

@ -0,0 +1,8 @@
0.01: New App!
0.02: Icons, loading screen
0.03: Random icon, Shorter "loading" screen
0.04: Support for light and dark Themes
0.05: Small bugfix
0.06: Formatting
0.07: Added potato GLaDOS and quote functionality when you tap her
0.08: Fixed drawing issues with the quotes and added more

11
apps/aptsciclk/README.md Normal file
View File

@ -0,0 +1,11 @@
# Description
This is a simple clock based on the Portal Series.
# Features
The button in the center of the screen is interactable and the warning image will change when it is pressed.
Potato GLaDOS in the bottom left corner is interactable and will display a quote when tapped. (You can add more quotes by editing the `aptsciclkquotes.txt` file seperating each quote with a `^`)
When the app loads the Apeture Science Logo is displayed.

View File

@ -0,0 +1 @@
require("heatshrink").decompress(atob("mEwwgNKxAACEaIVDDKWAhAXGwAtODA4HBLR4YFD4QWICIhABGAoMBJRBZHC4wwHOQ4IFAgQwGUQ4YBAg4uMJIwDDGAjRLIgYLHc5gXJIwbKLC4hICb4gZKfAhgETJKHJLwwXRUooWKCImAJogXRMopGMNwkIC4oWLYYqtHC5rFJC5h0GIxwsGFyD8CC4wwOIxBIQFwoeBCxrwEFwYXTFgTXReI4uQC4apPC4xNERqBlGFx4XCeJ4nHD4kIIxY3KPoIxNBwYXEJRInEP44iGOgwXFBYYcDChCHHC4wMBC5BnJEoouMGAYXEJJCCJC4pOEcpYKBFIpJFZRQXGD4gWKXBUICxjdFIhwyJOJMAA="))

368
apps/aptsciclk/app.js Normal file
View File

@ -0,0 +1,368 @@
const big = g.getWidth()>200;
const timeFontSize = big?5:4;
const dateFontSize = big?3:2;
const gmtFontSize = 2;
const font = "6x8";
const xyCenter = g.getWidth() / 2;
const yposTime = xyCenter*0.73;
const yposDate = xyCenter*0.48;
const yposYear = xyCenter*1.8;
const buttonTolerance = 20;
const buttonX = 88;
const buttonY = 104;
var pause = false; //set to true to pause any sort of drawing (except for quotes)
function getImg(img){
if (img == "w0"){//drink
return {
width : 60, height : 60, bpp : 1,
buffer : require("heatshrink").decompress(atob("AB0//4AE4YGF/gOZFIQOD4EABwnwgEDBwf8g/4h4ODwYQBv4OC+AbDAIP+j/HAQIOC4Hwj4RBBwP8o8B/+PBwWOkEP/l/BwP4+JCB44OCj+Ih/+n4OB+PEoP38YOB/0YkUXGgIOB8cBi9f+IOCkEI+XvBwXigFG64OEg0/t4OEuP7BwkHx/PBwWigF8voOC+Uwg/ig4OCkMgv8QsIOB+cfSoOGLIUR/E/4ljBwPxx/B/0kO4UI/0P+J3C/HHVQOISoWEn+D/iPBBwIwC8IOCwcP84IBBwU4TAMHBwfAv+AcARBBgD3CBwX8gDnBBwfwewIODAgIABBwYHDB3oAEBwIHFByyDBABg"))
}
}
else if (img == "w1"){//cube dispenser
return {
width : 60, height : 60, bpp : 1,
buffer : require("heatshrink").decompress(atob("AB0//4AE4YGF/gOI/3/+fvBwYEBnwO/By3APgN/O6IeBh4OF8AOcwADCBwX8g4dM/8fBwt774OE+/9Bwt/BxodH3oOcFgyVG8BhCBwX8hRwCBwXA0C6BBwc/w4OE41MBwtEo6VF84sE/1/54OLDo4sHHYxKHLIxoGO44AD/kAABo"))
}
}
else if (img == "w2"){//acid
return {
width : 60, height : 60, bpp : 1,
buffer : require("heatshrink").decompress(atob("AB0//4AE4YGF/gOF+IOGngOF8/D8YGD/wdBB4nv4fzAwf4BwOfGQd/4f7/+//+f74OB4PwHIJKDx8P/4BBBwP8BwIBBBwXvh+Hw5ZD+Pwnl/NAcegJOBBwfgj0fBwvhBxcPgYEBBwXw/F+FghIB84OC/BfBOYQOBk/w/0f4f4nkGgFgh0hwED4H4jOBuF8hk/v/Hzlnx/zFgQZBGYLCD4EHaIn8gAOF8EDBwn+dgQOK/8AN4IOD+EABww0BBwqGEBwIWBBwk8CwIODg/gv4OEv4OD+4OBBAIOBRYIFBh+PcAQdC+gOCDoN+h/vBwPP/wOB/wOBwJCBBwP2oa3BLALgBiA7BOwIvB/+DQoV/d4hPBBwQsB/wJB8ZoEAAZoDAAQOPRQIAM"))
}
}
else if (img == "w3"){//turret
return {
width : 60, height : 60, bpp : 1,
buffer : require("heatshrink").decompress(atob("AB0//4AE4YGF/gOi+IOGh4OF8AOF/UNBwthx4OE+0YBwtBh4OE6mQBwn7rEfBwl22IOE99gBwn99UzBwUc/+90YsC8HH+++n98n/+g0++2Z+4OB4Fz73T74OCg877d8/YdC+d7u/v3gsBjEvt/+O4X+gvtIgI7CwG934OD8E326kD/0A+yzEwEO74OD/EArYOEgEDv4OD+PAl4OEnkBaInz0EPBwk3iAdE+XwSIYDBj2Oj4OD/fYvIOEvdHz4OD99unIOD/vt44OE3u4Dou3h4OE+3x/IOE70/Bwn78/9Bwl4LAQ7Dx75DBwP4Awb+EBwgAEBz0AABo="))
}
}
else if (img == "w4"){//falling cube
return {
width : 60, height : 60, bpp : 1,
buffer : require("heatshrink").decompress(atob("AB0//4AE4YGF/gOC+YOF/0PBwvgv4OE/kFBwvAyIdFnYeBBwYeDDofng4OE8vYDonx7uPBwkf/+/Bwfh+czBwf+g/5z4OD+FevIdEhMDDon/0E3BwgeBJQgeB+5ZFvAEBBwfzgYOEw/XLInwn3BBwf8gH4LYIOCwUHDonwmE4HYkHwKkE8P4XYQOCv7dCYQkBWYsAWYvAiAsE/EDJQn/wF+CwJZDg/gBwgrBXYIOC8D+FNAL+F4eDBwn4nh2BBweHFYJ3EFYQOC/0P/AOECgIOE/E/BwsHBwvACAIODWAQOEJAIOFAgIOEQ4QsEAAOfBwoACBwgACBw8AABo"))
}
}
else if (img == "w5"){//ball
return {
width : 60, height : 60, bpp : 1,
buffer : require("heatshrink").decompress(atob("AB0//4AE4YGF/gOiv4OF8YOFAgQOEyYdGBw3zBw0BBwv4j4OB+EAgOD84OE+/ev4dD/3+BwvcugsE/u7t0f4aRC7e2sF8Bwlxg4dEu8YBwYsB/HDHYsMngOB8EDweHDon//PADoYABz0PBwfwnJKE/0OjZZC/kB4Hxz4OCwEYh+wBwXwgeA/+HBwUP8EP/0/BwPj/0DCQIOB/l/4DQBw4OBDIMPUoJKB+H/wY+B44OBj/4CoJKC+P/g7+FBAL+Fj4OFbwIOEI4IOF8YO6JQwAEaIgORgAANA"))
}
}
else if (img == "w6"){//ball recviver
return {
width : 60, height : 60, bpp : 1,
buffer : require("heatshrink").decompress(atob("AB0//4AE4YGF/gOR/YOG34Ob/e7Bwu7CwQOhGgQOD34OF/0LBwvfv4dMuPfBwn29oOFtwONDowsHHY3+h7CNj4OF+IOc4A7NDo7gGJQ4ACBwX+//vBwnvBAIOK8EH/kBBwd+v/PSwIOB/fnjiWBBwXesHPLQIOB/2AgEvBwfgh0AFgf8gAuBLKQObgAANA=="))
}
}
else if (img == "w7"){//falling portals
return {
width : 60, height : 60, bpp : 1,
buffer : require("heatshrink").decompress(atob("AB0//4AE4YFE/H8BwtvBwvvvgOE/33Bwvf3gOE/v7Bxn5Bw2fHYv7/oOF3/cB118JQQOC4ODJQn8jEfLInBjBoE/0jO4pjD953CwCVF/EH5//+ykCwA8Cp4OB/MDz4DBEQUYjPzaIfn5k/74xC/l44f+BwePz1595ADDYPvv7vDMAN3Bwf4CAIOE4//BYIOB/0On47E8AFCBwcPTwYOCAgPAgE8Bwf8gEDBwOAGIJZDBwX9DofhUYRKDKIIOEAAQOD8EABwgcB+IODnoKB84OD37tCBwUzZ4QODZ4QdDnIFB/YODZwP+v47DJIIBBJQcAAwZyBABoA=="))
}
}
else if (img == "w8"){//flying portals
return {
width : 60, height : 60, bpp : 1,
buffer : require("heatshrink").decompress(atob("AB0//4AE4YFE/H8BwtvBwvvvgOE/33Bwvf3gdF/YOF/4OF/IOGgA7F8ENBwn8gHcBw/5AoOAg4OCh4sD/vD+AFB45KBBwfwv//BwMJgEIFAXcnvggF4kEBBwPMSIIYBz/8nAEBw5ZD4IhBO48AhpoG953FSo/2Ugv/p4OF/LCGaIyIBB34OH4EAngODbAMDBwnfDoqeCBy7RBBwnh//xBwc9BQPnBwe/AYO/BwUzFYQODGgYOCnIFB/YOD57WBv47Dj//AIJKDgAGDOQIANA"))
}
}
else if (img == "w9"){//cake
return {
width : 60, height : 60, bpp : 1,
buffer : require("heatshrink").decompress(atob("AB0//4AE4YGF/gOY/oOG94OF/1/Bwv3FgwKCBwfnFhn8HY0LAQPwvgOB8EP/5uBBwP2gF4j+PBwP+sEEj/x44OB90Ao/8Dodwg8/nkH4ZXBgHnx8ABwPv/k98+ABwZEB+EAJQPj/3+nkAv4OB5+fz0Aj4OB98Ag+Ah/nBwJXB4EDHYSTB/EA/wsCSoJfBwAODNIPgBwgcBHYQOCC4QODn8Ah4ODGgMH+47D8EB/A7KTYMf4A7Eg/wHYgcBHZx3DcAPggbRBFgQcBcAQOB/iUBBwgcBBwgcCd4V/HYL+D/YOBDgIOC8/+DgIOC/+HfwIOD/4cCBwYAEBwQADBz0AABoA="))
}
}
else if (img == "butPress"){
return {
width : 176, height : 176, bpp : 4,
transparent : 1,
buffer : require("heatshrink").decompress(atob("iIA/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AFEc5kM5hD/ACXMAAJXB5nBI35WSK4ZY/AB8cK4/MJP5WRK4pY/ABhPD5e7he7A4fBJn5XNKwJXCLAZX/ABUcKwhXDLAZN/VxhSCK4m8WH5XNVwZXEWARX/ABEcK4sAgBYDXYRP/K5RQC2ACE3e8K/5XPVgYDCK/4AKJIPLVYoEEBoPBIWPd6ICPK46uDAohXzjvd7oCMCAJX/K7cAAAZXFBQkBK/6v/ABPd6ICPK/4AaK4mwKwYEDV+4ARjhKBVQoDD3gMBK2MdAIRXXVYSuDK/5XN5ZRCgEAWQYLBK/4AJK4u7KwZXC4JXxiPd6JXV5hXH3hX1ACscWApXDMQRN/WBpYCK4QICV35XOLARXBA4ZX/ABccKAfMhgFEJf5YRK4hJ/ABxXH4JI/LCRXCK34ASjhXCIf4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/ACIA=="))
}
}
else if (img == "butUnpress"){
return {
width : 176, height : 176, bpp : 4,
transparent : 1,
buffer : require("heatshrink").decompress(atob("iIA/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AFEc5kM5hD/ACXMAAJXB5nBI35WSK4ZY/AB8cK4/MJP5WRK4pY/ABhQEK43BJn5X/AEMcK5fMJv6uPK46w/K/4AgjhPFgEALAxP/K5vAAQhX/K6KsDWApP/AA6uHWA/BIWOIwICPK46qFAohXxjGIxACMCAJX/K7cAAAZXFBQkBK/6v/ABOIwICPK/4AaKInAAhCv2ACMcVRC0FK2MYAIRXXVYSuFK/5XO5kAgCuFK/4AJJwvMKw3BK+MRxGBK/4ArjhXMJv6wQK4qu/K/4AjjhXKJf5YRK4hJ/ABxXH4JI/LCRXCK34ASjhXCIf4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/ACI="))
}
}
else if (img == "apetureLaboratories"){
return {
width : 173, height : 43, bpp : 4,
transparent : 0,
buffer : require("heatshrink").decompress(atob("AA+IAAeAIv5UTK34APhABBKwpeBJX5VLJgJWGAwKv/ABL8EKomABIYA/KpJWHAoRW/KpZQCfwJSCAgRW/KphWFBgZW/KphNCAgSxEKP4ADJAatFKwWAL4oA/KpALGXQhS/Ko4MIwAOMAHREOKv5ZVVgcAh///4LDAwQAB+AIHCQYHMDQQYBDwQEGDIoaGTx4MCwAiCJgYhFBIYIHLw4HFBARjGESJUDehZVFVhJNLRI5VGDIIdEAgwiL+DzDJAJVJB4IMBCoKsHAYpFCDgr2IApYEIBpJFCKpqsCHgQbFIhBVHBhJoGTwyBRKp5mBDoY6GKoYqEXYg7JApKeHQJysEKpRmBDoasHQBAACM4qMGEAr0JAgZjGFYhVPgGAEIpVEAAaAEA4oyEW4qyKFZBoFKoisDJIJWLfIp3IQBJeJfgysMERpVCwEIVpijFBA6ZJdA4JHJYgEKQIx1EVgRVBVhj5IEIyZHHYoUGNw4MCQIwIKAARVDxBVRQo6ZJHZZoGU4yBGBAiBGVgRZBVhYlIfJBoFHZZoHfJRwGBAQrEVISvCKpwrEUZAqFVhzYKB4yKGQIpVDAYJVKEoYFDBIpVIb4ysMIgoPHOgoRFhGAVwKsLAFzQHACBVCVhQA/KpawBCJa76IhRWDVxIODAwTaFAocP///dhALGBQYJBCIYQBDYgKEBBAEDVgeIAgKgFBYZVEEYY+CH4YDBBgYFBBYoFEOYhmEDYgFFLIwEDKw2AKwhTFBoSsHIgglFAQo/HKIoDECBBZGc46eEAYa2EKox2Ga5LjLDoq8FKAgVDBAv/EghWGVgRWJKoaOFD4IgCViAWFVjKTGJIZOFKpKOHAQj3JAogCFPApcGKQziGLopKCU4hWFKojsEHYrXFCAJFId45CEDYh4EB4Y1DCYSzFJQT+FgAGCKooA/AAZMBfopWDKv5WLVgxT/AB+AKopW/ACBU/ABwA=="))
}
}
else if (img == "apetureLaboratoriesLight"){
return {
width : 173, height : 43, bpp : 4,
transparent : 1,
buffer : require("heatshrink").decompress(atob("iIAGxAADwINHAH5ULK34APjABBKwpeBJX5VLJgJWGAwKv/ABL8EKomBBIYA/KpJWHAoRW/KpZQCfwJSCAgRW/KphWFBgZW/KphNCAgSxEKP4ADJAatFKwWBL4oA/KpALGXQhS/Ko4MIwIOMAHREOKv5ZVVgcRiEAgALDAwQABgIIHCQYHMDQQYBDwQEGDIoaGTx4MCwIiCJgYhFBIYIHLw4HFBARjGESJUDehZVFVhJNLRI5VGDIIdEAgwiLgLzDJAJVJB4IMBCoKsHAYpFCDgr2IApYEIBpJFCKpqsCHgQbFIhBVHBhJoGTwyBRKp5mBDoY6GKoYqEXYg7JApKeHQJysEKpRmBDoasHQBAACM4qMGEAr0JAgZjGFYhVPiOBEIpVEAAaAEA4oyEW4qyKFZBoFKoisDJIJWLfIp3IQBJeJfgysMERpVCwMYVpijFBA6ZJdA4JHJYgEKQIx1EVgRVBVhj5IEIyZHHYoUGNw4MCQIwIKAARVDxBVRQo6ZJHZZoGU4yBGBAiBGVgRZBVhYlIfJBoFHZZoHfJRwGBAQrEVISvCKpwrEUZAqFVhzYKB4yKGQIpVDAYJVKEoYFDBIpVIb4ysMIgoPHOgoRFjGBVwKsLAFzQHACBVCVhQA/KpawBCJa76IhRWDVxIODAwTaFAocQgEAdhALGBQYJBCIYQBDYgKEBBAEDVgeIAgKgFBYZVEEYY+CH4YDBBgYFBBYoFEOYhmEDYgFFLIwEDKw2BKwhTFBoSsHIgglFAQo/HKIoDECBBZGc46eEAYa2EKox2Ga5LjLDoq8FKAgVDBAsAEghWGVgRWJKoaOFD4IgCViAWFVjKTGJIZOFKpKOHAQj3JAogCFPApcGKQziGLopKCU4hWFKojsEHYrXFCAJFId45CEDYh4EB4Y1DCYSzFJQT+FiIGCKooA/AAZMBfopWDKv5WLVgxT/AB+BKopW/ACBU/ABsQA="))
}
}
else if (img == "potato"){
return {
width : 54, height : 55, bpp : 4,
transparent : 6,
buffer : require("heatshrink").decompress(atob("swAEsEGA4oASEQ4ARGgNgDa8QsA3BKStowxTDDalikxTCRKsSNwY2BDSYvDGoI2TsoTDgwEBGx5IBs1VHIgaBGx4qCDQZOBUiUGstQDQ4FBKYwHGDQNWDRA3BCYsABotgJ4dkogABowcGAAUGOwogDDAVCAYScKOooFBooWCAAjqNAoQYHKYQ8ELQZzFsAMCiIeJAAdFMwiCEoIaNoICBoAaMiMUDA0ikMiigaIAAgaGDIIaBkcyoCHEMxqIBmdEkMzmcxDSVBkYXBGoMzmUQDSMSDIURiIbBkDBCDRtBiYwBDIMREAMiDR6qBiI0BkQEBKQKkBUJQAEoCfBC4MVgMSDYMkGwQaBeBMUiC3BGYNN8kSHgM0DQrsGAAMQQAMyCwIaBgK/BmIaKM4IGCiMTDQXd9waCmlENZIaEgESKAMhpxQEDQSiEoJTGiEimaGCqIaBmKABUQwyBUIzRBkIXBDoI8BkAaDGwgaFEIMCeQUSYAKNBmLYDGwJ/DDYlFqAaBGwILBGgLyBUIRSFQghrCgEjDYMiiTdCggaFDYgaFKIKIBmcTkciiA1GNwpsFgI4BmZsBkVEDRAbJiBTCNQMABIIZHfBCPBDQKSCoFEGhA2IKIMQgJ1CoCFHGxVBeASQDgAZJDQ8RQIMyDQkGDZQ1GDILtBAwNGsAaLs1hokECYNCaQMxDIVmDRoOBDQifCBggaNKgMRqUhiovFGxoMEsCADAQQaMsUWJBi+LsMRqtWDSwUBqvFqpVFQ54UCstVqEGsDbBQx4lFgAABotRAgQABT54ADqtRM5jjQAAQ"))
}
}
else if (img == "apetureWatch"){
return {
width : 176, height : 176, bpp : 4,
transparent : 2,
buffer : require("heatshrink").decompress(atob("kQA/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A+/4A/AH4A/AH4A/AD0RgAASgMQCqgrqiJX/K/5X/K/5XR7vQK/8IxBX/K/5X/K/5X/K/5X/K/5X/K/5X/K/5Xah////wK/5XTKwIABK4YAG//x7vRBhAA2jGIAYMfK4fxCRAOCK/5XFKwYABBgTBEh4LC7vQbabxLFYoVPFZMIxADBK4sAK4wLDK/5XSBYhX/K6MPBIQDBK/5XD+BXMBAQQCK/5XDKAJXKVwRWBAoJX/K4j3CUohXDL4YACK/5XF+CuEK4yuCK/5XHWAZOCK4cPKwhX/K45MFK4YAGK/5XGLApX/K6X/K5sPK/5XIWAZXJ/5X/K6sPK/5XPAoauDK/5XJ/5XDj5eEVwRX/K5y2FVwRX/K4/wK44GDVwRX/K50fWAi9DK/5XGUYRQCiKwCAwKuDK/5XGJgZXGMQJWDK/5XGAoKkCK4arEK/5XIVQRQDK/5XQAwZLC+BXBAwYACLwJX/K4auCWApXHCAJX/K5JYFAoi/Ch5X/K4ZHCAAZXEAoZnCK/5XLVQRXFBgZX/K4igCLAnxFYRdBBohX/K5cAiIrJK/5XEfIhX/K/5Xr+BX/K/5Xu/5X/K/5WKFhRXWl5XB+BX/K6ywFK9XxK4SMFK7JWCK58PK7sP/5XDGoxXr/5Xc//4xBXEHIKyPK54fFK5CPBK7cPxAyBK4oHBK7wKFK5AQBK7UP/GPD4JWCiMfK4IJBK7jOGFgYwEK4XRBg4AQ/CtFAAZXCBQ4AQjBXCCRxXcUoJLDjnMhnMBgTqCK7RzJYYxXC6DbTAAf4UYInB5gABK4PM4KBDdYwrQhBXBBQ5XIAAJXYh6GDKwRXDLASwCK7BxIK8auDjhXH5iwPK5gKIK8iuBKwhXFLAJX/AA0PxCuBKAhXG4KwCK/6uEx/xK5qwNK/KuBjhXL5kRWAJXrbapXEJ4pXH4JXXABRXhh+I+JXPiP//5X/K4WP+McJ4oLBLAxX/K5vAAQhX/ABBDBiJXFVgawFiMf//wK/4gBAAKuHWA/BCYQhIK8uIwACOK5CqFAohXxhGIxACMCAJX/K7YaEK4pKFK/6v/ABOIwACOK/4AMFZRXI4AEIV+wrO///iMcVRC0FiMf//wQaZXZhABCFZ0P//xK4qrCVwpXB/+PbahX15gLBVwpX/K5ERJwvMKw3BiP4K98AxGAFaH//5XPj/4+BXvFaRXCjhXMiMfxBXhGoIAcK4nxWAxXF4MR/GPK4Q4e+UiADcvK4UPWARXMj/4NwayKACUPK8KwDjhXKcQOIKYZX/eIkRLAhXEiKuBx5XEY4QAYDgJXiIAXxiJXH4KuC/4VDK/6wGLAZXCKwKuGK/6wIiMcK4QFBVw5X/WA2IwJSCAAYJBVwpX/WA2IJwJVDj///GPVwpX/LA34K4PxVoYHBKwxX/AAynCK4ZWC+BX/K5ixB/6vEVo5X/IxAABK4asHK/5XLgJXCBxRX/K/5XgLAQNLK/5X/K6r7CACxX/K/5XVfJcBiINLK/5X/K/5X/K/5X/K/5X/K/5X/K/5X/K/5X/K/5X/K/5X/K/5X/K5o6bK/YaZK/5X/K/5X/K/5X/K/5X/K/5X/K/5X/K/5X/K/5X/K/5X/K/5X/K/5X/K/5X/K6o6bK/cAABUBiINLK/5X/K/5X/K/5X/K/AMLACBX/K7DMaAAcRADA4eA=="))
}
}
else if (img == "apetureWatchLight"){
return {
width : 176, height : 176, bpp : 4,
transparent : 2,
buffer : require("heatshrink").decompress(atob("kQA/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A+gAA/AH4A/AH4A/AD0R/4AS+MfCqgrqiJX/K/5X/K/5XR7vfK//4xBX/K/5X/K/5X/K/5X/K/5X/K/5X/K/5Xa+EAgEPK/5XTKwIABK4YAGgEB7vRBhAA2jGIAYMQK4cBCRAOCK/5XFKwYABBgTBE+ALC7vfbabxLFYoVPFZP4xADBK4v/K4wLDK/5XSBYhX/K6PwBIQDBK/5XDh5XMBAQQCK/5XDKAJXKVwRWBAoJX/K4j3CUohXDL4YACK/5XFh6uEK4yuCK/5XHWAZOCK4fwKwhX/K45MFK4YAGK/5XGLApX/K6UAK5vwK/5XIWAZXJgBX/K6vwK/5XPAoauDK/5XJgBXDiBeEVwRX/K5y2FVwRX/K48PK44GDVwRX/K50QWAi9DK/5XGUYRQCiKwCAwKuDK/5XGJgZXGMQJWDK/5XGAoKkCK4arEK/5XIVQRQDK/5XQAwZLCh5XBAwYACLwJX/K4auCWApXHCAJX/K5JYFAoi/C+BX/K4ZHCAAZXEAoZnCK/5XLVQRXFBgZX/K4igCLAkBFYRdBBohX/K5f/iIrJK/5XEfIhX/K/5Xrh5X/K/5XugBX/K/5WKFhRXWkBXBh5XvgJXCGgpXcWApXoF4KvD+COGK65WCK5/wK7gtCK4YmCLB5XfgBXbFgIzBK4mILCBXPDwpXIcIJXa+BPBKAJXFLARXdBQpXICAJXah/4x4qDAAMfK4IJBWBpXODgwsDAAcQK4XRBg4APgAwBVogADK4XwgInWjBXCCRxXbiD9BKwcc5kM5gNCRgXwK7JyJYYxXC77bTIwf4UYInB5gABK4PM4MRDQXwDpYrKawMABQ5XIAAJXYh6uDKwRXDLAQRDK64YIK8SuEjhXH5iwPK5gKIK8UP/APBKwhXFLAKwNK/ItBiJQEK43BDgRX/AAXw/GP+JXNGQXwK/5XDEgMcK5fMiIdBK9YAKK5cPK4RPFK4/BDoUPFagAJK8WI+JXPGYRX/IIWP+McJ4sAgBYGK/5XN4ACEK/4AH+AjCK4qsDWAsRDwIWCK/ogBAAKuHWA/BCYQhIK8uIx4COK5CqFAohXx/GIxACMCAJX/K7cAAAZXFBQkBK/6v/ABOIx4COK/4AMFZRXI4AEIV+wrN+AjCjiqIWgpUCCwRXr/ABCFZ0PBoJXFVYSuFK4P/x4VBK/5XI5kAgCuFK/5XIiJOF5hWG4MR/BXv/+Ix5XREgJXOj58BK94rR+AkCjhXMiMfxAUCK70AADpXE+KwGK4vBiP4x5XhgUiADcgEQTyCK5sf/ATDK/5DD+McK5UR/+IK/5XEeYcRLAhXEiKuBx4SDK/6wFiJXH4KuOK/SwELAZXCKwKuOK/ywBiMcK4QFBVwZX/K43/gACBxGBKQQADBIKuBh5X/K43/JAOIJwJVDIYP4x4NCK/5XHfAP4K4PxVoYHBBgRX/K5H/gCnCK4ZWDVxpX9LARABV4ZWQK/xYBgBXD+EAKx5X/AAMBK4RVQK/5ADK4RBSK/5YDIKZX/K/5XNfYQA1K/5X2eJkReKfxj4VTK/5X/K/5X/K/5X/K/5X/K/5X/K/5X/K/5X/K/5X/K/5X/K/5XvgAAYh5X8DTJX/K/5X/K/5X/K/5X/K/5X/K/5X/K/5X/K/5X/K/5X/K/5X/K/5X/K/5X/K/5XVgAAYK/orL+MRIKZX/K/5X/K/5X/K/5X/K/5XmgAAdiIA3"))
}
}
}
function drawStart(){
g.clear();
g.reset();
if (g.theme.dark){apSciLab = getImg("apetureLaboratories");}
else {apSciLab = getImg("apetureLaboratoriesLight");}
g.drawImage(apSciLab, xyCenter-apSciLab.width/2, xyCenter-apSciLab.height/2);
}
// Check settings for what type our clock should be
var is12Hour = (require("Storage").readJSON("setting.json",1)||{})["12hour"];
// timeout used to update every minute
var drawTimeout;
//warnings
var maxWarning = 9;
var curWarning = Math.floor(Math.random() * (maxWarning+1));
function unPause(delay, quote){
if (pause){
setTimeout(function() {
if (quote == undefined || quoteNum == quote){
pause = false;
draw();
}
}, delay);
}
}
var quoteNum;
function quote(fontsize, width, height, specificQuote){
pause = true;
var finalString = "";
var quotesFile;
var finalFontSize;
quotesFile = require("Storage").read("aptsciclkquotes.txt", 0, 0); //opens the quotes file
//console.log(quotesFile);
var quotes = quotesFile.split("^");
var numQuotes = quotes.length;//number of quotes
var curQuote;
if (specificQuote == undefined){
quoteNum = Math.round(Math.random()*numQuotes)-1;
curQuote = quotes[quoteNum]; //quote to be displayed
}
else{
quoteNum = specificQuote;
curQuote = quotes[quoteNum];
}
unPause(10000, quoteNum);
var curWords = curQuote.split(" "); //individual words
//console.log(numQuotes);
var maxChar = width/6/fontsize;
var maxLines = height/10/fontsize;
var curLines = 0;
var curLength = 0;
for (var i = 0; i < curWords.length; i++){
//console.log(curLength+curWords[i].length);
if (curLength + curWords[i].length <= maxChar){
finalString += " "+curWords[i];
curLength += curWords[i].length+1;
//console.log("next");
}
else{
//console.log("break");
curLines++;
if (curLines > maxLines){
curLength = 0;
finalString = "";
i = -1;
if (fontsize > 1){fontsize--;}
maxChar = width/6/fontsize;
maxLines = height/10/fontsize;
console.log(maxLines);
console.log(maxChar);
}
else{
curLength = 0;
finalString += "\n";
i--;
}
}
finalFontSize = fontsize;
}
//drawing actual stuff
g.setColor(g.getBgColor());
g.fillRect(10, 10+28, g.getWidth()-10,g.getWidth()-10);
g.reset();
g.setFont(font, finalFontSize);
g.setFontAlign(0, 0);
g.drawString(finalString, xyCenter, xyCenter+14);
//quote length*pixels per character = pixel width
//height ~120 width ~160
}
function buttonPressed(){
if (curWarning < maxWarning) curWarning += 1;
else curWarning = 0;
g.reset();
buttonImg = getImg("butPress");
g.drawImage(buttonImg, 0, 0);
warningImg = getImg("w"+String(curWarning));
g.drawImage(warningImg, 1, g.getWidth()-61);
setTimeout(buttonUnpressed, 500);
}
function buttonUnpressed(){
if (!pause){
buttonImg = getImg("butUnpress");
g.drawImage(buttonImg, 0, 0);
}
else{
setTimeout(buttonUnpressed, 500);
}
}
// schedule a draw for the next minute
function queueDraw() {
if (drawTimeout) clearTimeout(drawTimeout);
drawTimeout = setTimeout(function() {
drawTimeout = undefined;
draw();
}, 60000 - (Date.now() % 60000));
}
function draw() {
if (pause){}
else{
// get date
var d = new Date();
var da = d.toString().split(" ");
g.reset(); // default draw styles
//draw watchface
if (g.theme.dark){apSciWatch = getImg("apetureWatch");}
else {apSciWatch = getImg("apetureWatchLight");}
g.drawImage(apSciWatch, xyCenter-apSciWatch.width/2, xyCenter-apSciWatch.height/2);
potato = getImg("potato");
g.drawImage(potato, 118, 118);
g.drawImage(warningImg, 1, g.getWidth()-61);//update warning
// drawString centered
g.setFontAlign(0, 0);
// draw time
var time = da[4].substr(0, 5).split(":");
var hours = time[0],
minutes = time[1];
var meridian = "";
if (is12Hour) {
hours = parseInt(hours,10);
meridian = "AM";
if (hours == 0) {
hours = 12;
meridian = "AM";
} else if (hours >= 12) {
meridian = "PM";
if (hours>12) hours -= 12;
}
hours = (" "+hours).substr(-2);
}
g.setFont(font, timeFontSize);
g.drawString(`${hours}:${minutes}`, xyCenter+2, yposTime, false);
g.setFont(font, gmtFontSize);
g.drawString(meridian, xyCenter + 102, yposTime + 10, true);
// draw Day, name of month, Date
var date = [da[0], da[1], da[2]].join(" ");
g.setFont(font, dateFontSize);
g.drawString(String(date), xyCenter, yposDate, false);
// draw year
g.setFont(font, dateFontSize);
g.drawString(d.getFullYear(), xyCenter+1, yposYear, true);
}
queueDraw();
}
// Stop updates when LCD is off, restart when on
Bangle.on('lcdPower',on=>{
if (on) {
draw(); // draw immediately, queue redraw
} else { // stop draw timer
if (drawTimeout) clearTimeout(drawTimeout);
drawTimeout = undefined;
}
});
Bangle.on('touch',(n,e)=>{
//button is 88 104
if (!pause && buttonX-buttonTolerance < e.x && e.x < buttonX+buttonTolerance && buttonY-buttonTolerance < e.y && e.y < buttonY+buttonTolerance){
buttonPressed();
}
//Potato GLaDOS
else if (!pause && 117 < e.x && e.x < 172 && 117 < e.y && e.y < 172){
quote(2, 150, 140);
}
else{
unPause(0);
}
});
//show Apeture laboritories
drawStart();
setTimeout(function() {
// clean app screen
g.clear();
// Show launcher when button pressed
Bangle.setUI("clock");
Bangle.loadWidgets();
Bangle.drawWidgets();
//update warning image
buttonPressed();
// draw now
draw();
}, 500);

BIN
apps/aptsciclk/app.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 714 B

View File

@ -0,0 +1,18 @@
{
"id": "aptsciclk",
"name": "Apeture Science Clock",
"shortName":"AptSci Clock",
"version": "0.08",
"description": "A clock based on the portal series",
"icon": "app.png",
"type": "clock",
"tags": "clock",
"supports": ["BANGLEJS2"],
"allow_emulator": false,
"readme":"README.md",
"storage": [
{"name":"aptsciclkquotes.txt","url":"quotes.txt"},
{"name":"aptsciclk.app.js","url":"app.js"},
{"name":"aptsciclk.img","url":"app-icon.js","evaluate":true}
]
}

View File

@ -0,0 +1 @@
Well here we are again^You euthanized your faithful Companion Cube more quickly than any test subject on record. Congratulations.^So get comfortable while I warm up the neurotoxin emitters^This isn't brave. It's murder. What did I ever do to you?^The difference between us is that I can feel pain.^Who's gonna make the cake when I'm gone? You?^Oh... It's you.^I've been really busy being dead. You know, after you MURDERED ME.^So. How are you holding up? BECAUSE I'M A POTATO.^You really do have brain damage, don't you?^You like revenge, right? Everybody likes revenge. Well, let's go get some.^It's been fun. Don't come back.^And then you showed up. You dangerous, mute lunatic.^Unbelievable. You, [subject name here] must be the pride of [subject hometown here.]^You are not a good person. You know that, right? Good people don't get up here.^Cake, and grief counseling, will be available at the conclusion of the test.^This is your fault. I'm going to kill you. And all the cake is gone. You don't even care, do you?^Momentum, a function of mass and velocity, is conserved between portals. In layman's terms, speedy thing goes in, speedy thing comes out.

View File

@ -1 +1,2 @@
0.01: first release
0.02: added settings menu to change color

View File

@ -16,7 +16,6 @@ Forum](http://forum.espruino.com/microcosms/1424/)
* Uses the [BloggerSansLight](https://www.1001fonts.com/rounded-fonts.html?page=3) font, which if free for commercial use
## Future Development
* Add settings menu to change primary clock color
* Add a heart rate option in the information line that turns on when selected
* Use mini icons in the information line rather that text
* Add weather icons as per Pastel clock

View File

@ -1,7 +1,7 @@
var SunCalc = require("https://raw.githubusercontent.com/mourner/suncalc/master/suncalc.js");
const storage = require('Storage');
const locale = require("locale");
const SETTINGS_FILE = "pastel.json"; // XXX
const SETTINGS_FILE = "daisy.json";
const LOCATION_FILE = "mylocation.json";
const h = g.getHeight();
const w = g.getWidth();
@ -14,13 +14,10 @@ let warned = 0;
let idle = false;
let IDLE_MINUTES = 26;
// palette for 0-40%
const pal1 = new Uint16Array([g.theme.bg, g.toColor("#020"), g.toColor("#0f0"), g.toColor("#00f")]);
// palette for 50-100%
const pal2 = new Uint16Array([g.theme.bg, g.toColor("#0f0"), g.toColor("#020"), g.toColor("#00f")]);
var pal1; // palette for 0-40%
var pal2; // palette for 50-100%
const infoWidth = 50;
const infoHeight = 14;
var drawingSteps = false;
function log_debug(o) {
@ -38,6 +35,13 @@ Graphics.prototype.setFontRoboto20 = function(scale) {
// Actual height 21 (20 - 0)
this.setFontCustom(atob("AAAAAAAAAAAAAAAAAAAAAAAAH/zA/+YAAAAAAAHwAAwAAHwAA+AAAAAAAAAAAQACDAAYbADP4B/8A/zAGYZADH4A/+A/7AHYYADCAAAAAAAQAeHgH4eBzgwMMHnhw88GGBw4wHj+AcPgAAAAAAAAAAB4AA/gAGMAAwhwGMcAfuABzgABzgAc+AOMYBhBAAMYAB/AAHwAAAAAHwD5+A/8YGPDAw8YGPzA/HYD4fAADwAB/AAOYAABAAAAHwAA4AAAAAAAAAAH/gD//B8A+cAA7AADAAAAAAAYAAbwAHHgHwf/4A/8AAAAEAABiAAGwAA8AA/AAH+AAGwAByAAEAAAAAAAMAABgAAMAABgAH/wA/+AAMAABgAAMAABgAAAAAAAIAAfAADwAAAABgAAMAABgAAMAABgAAAAAAAAAAAAADAAAYAAAAAAAAADgAB8AB+AA+AA+AA/AAHAAAgAAAAAAB8AB/8Af/wHAHAwAYGADAwAYHAHAf/wB/8AAAAAAAAAAABgAAcAADAAAYAAH//A//4AAAAAAAAAAAAAAAAAAAAABwDAeA4HAPAwHYGBzAwcYHHDAfwYB8DAAAYAAAAAAABgOAcBwHADAwwYGGDAwwYHPHAf/wB58AAAAAAAAADAAB4AAfAAPYAHjAB4YA8DAH//A//4AAYAADAAAAAAAAAEMA/xwH+HAxgYGMDAxgYGODAw/4GD+AAHAAAAAAAAAf8AP/wD2HA5wYGMDAxgYGOHAA/wAD8AAAAAAAAAAAGAAAwAAGADAwB4GB+Aw+AGfAA/gAHwAAwAAAAAAADAB5+Af/wHPDAwwYGGDAwwYHPHAfvwB58AAAAAAAAAAAB+AAf4AHDjAwMYGBjAwM4HDOAf/gB/4AAAAAAAAAAAAYDADAYAAAAAAAAAAYDAfAYHwAAAABAAAcAADgAA+AAGwAB3AAMYABjgAYMAAAAAAAAAAAAAAABmAAMwABmAAMwABmAAMwABmAAMwAAiAAAAAAAAAYMADjgAMYAB3AAGwAA2AADgAAcAABAAAAAAAAAMAADgAA4AAGBzAweYGHAA/wAD8AAEAAAAwAB/4A/PwOAGDgAYYPxmH/Mw4ZmMDMxgZmM+Mx/5mHDAYAIDgDAPBwAf8AAMAAAAAAAYAAfAAPwAP4AH+AH4wA8GAH4wAP2AAPwAAfwAAfAAAYAAAAAAAAAAA//4H//AwwYGGDAwwYGGDAwwYH/HAf/wB58AAAAADAAH/AD/+AcBwHADAwAYGADAwAYGADA4A4DweAODgAAAAAAAAAAAAAAH//A//4GADAwAYGADAwAYGADAYAwD4+AP/gAfwAAAAAAAAAAAH//A//4GDDAwYYGDDAwYYGDDAwYYGCDAgAYAAAAAAAH//A//4GDAAwYAGDAAwYAGDAAwYAGAAAAAAAAAAH/AD/8AcBwHAHAwAYGADAwYYGDDA4YYDz/AOfwAAAAAAAAAAA//4H//A//4ADAAAYAADAAAYAADAAAYAADAA//4H//AAAAAAAAAAAAAAA//4H//AAAAAAAAABAAAeAAB4AADAAAYAADAAAYAAHA//wH/8AAAAAAAAAAAAAAA//4H//AAcAAPAAD4AA/wAOPADg8A4B4GAHAgAYAAAAAAAH//A//4AADAAAYAADAAAYAADAAAYAADAAAAAAAA//4H//A+AAB+AAD8AAD8AAH4AAPAAH4AH4AD8AD8AA+AAH//A//4AAAAAAAH//A//4H//AeAAB8AADwAAPgAAeAAA8AADwH//A//4AAAAAAAAAAAH/AB/8AeDwHAHAwAYGADAwAYGADA4A4DweAP/gA/4AAAAAAAAAAAH//A//4GBgAwMAGBgAwMAGBgAwcAH/AAfwAA8AAAAAA/4AP/gDgOA4A4GADAwAYGADAwAYHAHgeD+B/8wD+GAAAAAAAAAAA//4H//AwYAGDAAwYAGDgAweAHH8Afz4B8HAAAIAAYAPDwD8OA5w4GGDAwwYGHDAwYYHDnAePwBw8AAAAGAAAwAAGAAAwAAGAAA//4H//AwAAGAAAwAAGAAAwAAAAAAAAAH/4A//wAAPAAAYAADAAAYAADAAAYAAPA//wH/8AAAAAAAAgAAHAAA/AAB/AAD+AAD+AAD4AAfAAfwAfwAfwAH4AA4AAEAAA+AAH/AAH/gAD/AAD4AD+AH+AH8AA+AAH+AAD+AAD/AAD4AH/AP/AH+AA8AAAAAAAAAGADA4A4HweAPPgA/wAB8AAfwAPvgDweA8B4GADAAAIGAAA4AAHwAAPgAAfAAA/4AH/AD4AB8AA+AAHgAAwAAAAAAAAAGADAwB4GAfAwPYGDzAx4YGeDA/AYHwDA4AYGADAAAAAAAA///3//+wAA2AAGAAAGAAA+AAD8AAD8AAD4AAH4AAHgAAMAAAAwAA2AAG///3//+AAAAAAAAAAAOAAHwAD4AA8AAD8AADwAAGAAAAAAABgAAMAABgAAMAABgAAMAABgAAMAABgAAAEAAAwAADAAAIAAAAAAAAAAEeABn4Ad3ADMYAZjADMYAZmAB/4AP/AAAAAAAA//4H//ABgwAYDADAYAYDADg4AP+AA/gABwAAAAAAAAA/gAP+ADg4AYDADAYAYDADAYAOOABxwAAAAAEAAH8AB/wAcHADAYAYDADAYAcDA//4H//AAAAAAAAAAAAH8AB/wAdnADMYAZjADMYAZjAB84AHmAAMAAMAABgAB//gf/8HMAAxgAGIAAAAAAH8IB/zAcHMDAZgYDMDAZgcHcD//Af/wAAAAAAAAAAH//A//4AMAADAAAYAADAAAcAAD/4AP/AAAAAAAAAAAGf/Az/4AAAAAAAAAAMz//mf/4AAAAAAAAAAH//A//4ABwAAeAAH4ABzwAcPACAYAABAAAAAAAA//4H//AAAAAAAAAAAAf/AD/4AMAADAAAYAADAAAcAAD/4AP/ABgAAYAADAAAYAADgAAP/AA/4AAAAAAAAf/AD/4AMAADAAAYAADAAAcAAD/4AP/AAAAAAAAAAAAH8AB/wAcHADAYAYDADAYAYDADx4AP+AA/gAAAAAAAAf/8D//gYDADAYAYDADAYAcHAB/wAH8AAEAAAAAAEAAH8AB/wAcHADAYAYDADAYAYDAD//gf/8AAAAAAAAAAAf/AD/4AcAADAAAYAACAAAAEAB5wAfnADMYAZjADGYAYzADn4AOeAAAAAAAADAAAYAAf/wD//ADAYAYDAAAAAAAAD/gAf/AAA4AADAAAYAADAAAwAf/AD/4AAAAAAAAYAAD4AAP4AAP4AAPAAH4AH4AD8AAcAAAAAAQAADwAAf4AAf4AAPAAP4AP4ADwAAfgAA/gAA/AAD4AH+AD+AAeAAAAAAAAACAYAcHADzwAH8AAfAAH8ADx4AcHACAIAcAMD4BgP4MAP/AAPwAP4AP4AD4AAcAAAAAAAAADAYAYHADD4AY7ADOYAfjADwYAcDADAYAAAAADAAA4AH//B/v8cABzAACAAAH//w//+AAAAAAACAACcAAx/n+H//AA4AAHAAAAAAAAAAAAAOAADgAAYAADAAAcAABgAAGAAAwAAGAADwAAcAAAAA"), 32, atob("BQUHDQwPDQQHBwkMBAYGCQwMDAwMDAwMDAwFBAsMCwoTDg0ODgwMDg8GDA0LEg8ODQ4NDA0ODRMNDQ0GCQYJCQYLDAsMCwcMDAUFCwUSDAwMDAcLBwwKEAoKCgcFBw4A"), 21+(scale<<8)+(1<<16));
return this;
};
function assignPalettes() {
// palette for 0-40%
pal1 = new Uint16Array([g.theme.bg, g.toColor(settings.gy), g.toColor(settings.fg), g.toColor("#00f")]);
// palette for 50-100%
pal2 = new Uint16Array([g.theme.bg, g.toColor(settings.fg), g.toColor(settings.gy), g.toColor("#00f")]);
}
function setSmallFont20() {
@ -67,9 +71,10 @@ function getSteps() {
function loadSettings() {
settings = require("Storage").readJSON(SETTINGS_FILE,1)||{};
settings.grid = settings.grid||false;
settings.font = settings.font||"Lato";
settings.gy = settings.gy||'#020';
settings.fg = settings.fg||'#0f0';
settings.idle_check = settings.idle_check||true;
assignPalettes();
}
// requires the myLocation app
@ -266,7 +271,7 @@ function drawClock() {
g.drawImage(getGaugeImage(p_steps), 0, 0);
setLargeFont();
g.setColor('#0f0');
g.setColor(settings.fg);
g.setFontAlign(1,0); // right aligned
g.drawString(hh, (w/2) - 1, h/2);

View File

@ -1,6 +1,6 @@
{ "id": "daisy",
"name": "Daisy",
"version":"0.01",
"version":"0.02",
"dependencies": {"mylocation":"app"},
"description": "A clock based on the Pastel clock with large ring guage for steps",
"icon": "app.png",
@ -10,6 +10,8 @@
"readme": "README.md",
"storage": [
{"name":"daisy.app.js","url":"app.js"},
{"name":"daisy.img","url":"app-icon.js","evaluate":true}
]
{"name":"daisy.img","url":"app-icon.js","evaluate":true},
{"name":"daisy.settings.js","url":"settings.js"}
],
"data": [{"name":"daisy.json"}]
}

51
apps/daisy/settings.js Normal file
View File

@ -0,0 +1,51 @@
(function(back) {
const SETTINGS_FILE = "daisy.json";
// initialize with default settings...
let s = {'gy' : '#020',
'fg' : '#0f0',
'color': 'Green',
'check_idle' : true};
// ...and overwrite them with any saved values
// This way saved values are preserved if a new version adds more settings
const storage = require('Storage')
let settings = storage.readJSON(SETTINGS_FILE, 1) || s;
const saved = settings || {}
for (const key in saved) {
s[key] = saved[key]
}
function save() {
settings = s
storage.write(SETTINGS_FILE, settings)
}
var color_options = ['Green','Orange','Cyan','Purple','Red','Blue'];
var fg_code = ['#0f0','#ff0','#0ff','#f0f','#f00','#00f'];
var gy_code = ['#020','#220','#022','#202','#200','#002'];
E.showMenu({
'': { 'title': 'Daisy Clock' },
'< Back': back,
'Colour': {
value: 0 | color_options.indexOf(s.color),
min: 0, max: 5,
format: v => color_options[v],
onchange: v => {
s.color = color_options[v];
s.fg = fg_code[v];
s.gy = gy_code[v];
save();
},
},
'Idle Warning': {
value: !!s.idle_check,
format: v => v ? /*LANG*/"Yes":/*LANG*/"No",
onchange: v => {
s.idle_check = v;
save();
},
}
});
})

View File

@ -1,2 +1,3 @@
0.01: Add a number to match to turn off alarm
0.02: Respect Quiet Mode
0.03: Fix hour/minute wrapping code for new menu system

View File

@ -56,25 +56,25 @@ function editAlarm(alarmIndex) {
}
const menu = {
'': { 'title': 'Alarms' },
'Hours': {
value: hrs,
onchange: function(v){if (v<0)v=23;if (v>23)v=0;hrs=v;this.value=v;} // no arrow fn -> preserve 'this'
/*LANG*/'Hours': {
value: hrs, min : 0, max : 23, wrap : true,
onchange: v => hrs=v
},
'Minutes': {
value: mins,
onchange: function(v){if (v<0)v=59;if (v>59)v=0;mins=v;this.value=v;} // no arrow fn -> preserve 'this'
/*LANG*/'Minutes': {
value: mins, min : 0, max : 59, wrap : true,
onchange: v => mins=v
},
'Enabled': {
/*LANG*/'Enabled': {
value: en,
format: v=>v?"On":"Off",
onchange: v=>en=v
},
'Repeat': {
/*LANG*/'Repeat': {
value: en,
format: v=>v?"Yes":"No",
onchange: v=>repeat=v
},
'Auto snooze': {
/*LANG*/'Auto snooze': {
value: as,
format: v=>v?"Yes":"No",
onchange: v=>as=v

View File

@ -2,7 +2,7 @@
"id": "hardalarm",
"name": "Hard Alarm",
"shortName": "HardAlarm",
"version": "0.02",
"version": "0.03",
"description": "Make sure you wake up! Count to the right number to turn off the alarm",
"icon": "app.png",
"tags": "tool,alarm,widget",

1
apps/intclock/ChangeLog Normal file
View File

@ -0,0 +1 @@
0.01: Initial commit

4
apps/intclock/README.md Normal file
View File

@ -0,0 +1,4 @@
# Analogue Clock
![](screenshot_analog.png)

View File

@ -0,0 +1 @@
require("heatshrink").decompress(atob("mEwgP/AH4Aq+GEkPh4E/BZMAh4LGw/h8MPBZHggIXJ/EB4ALI//h/4LHwk/BagA/ACY="))

60
apps/intclock/app.js Normal file
View File

@ -0,0 +1,60 @@
Graphics.prototype.setFontUndo = function(scale) {
// Actual height 19 (20 - 2)
this.setFontCustom(atob("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKqKAqooCqigKqKAAAACgAAKAAAoAACgAAAAAAAAACgAAKAAAoAACgAAAAAAKCgAoKAKqqAqqoCqqgKqqAKCgAoKAKqqAqqoCqqgKqqAKCgAoKAAAAAKgoAqCgKqKAqooKiioqKKiooqKiioKKqAoqoCgqAKCoAAAACoCgKgKAiCoCIKgKioAqKgACoAAKgACoAAKgACoqAKioCoIgKgiAoCoCgKgAAAAKqgAqqAKqqAqqoKiioqKKiooqKiioKAKAoAoCgCgKAKAAAACgAAKAAAoAACgAAAAAAKqgAqqAKqqAqqoCgCgKAKAAAACgCgKAKAqqoCqqgCqoAKqgAAAACigAKKAAqoACqgAqoACqgAKqAAqoAAqoACqgAKKAAooAAAAAAoAACgAAKAAAoAAqqACqoAKqgAqqAAKAAAoAACgAAKAAAAAAACoAAKgAAqAACoAAAAAoAACgAAKAAAoAACgAAKAAAoAACgAAKAAAoAACgAAKAAAAAAACgAAKAAAoAACgAAAAAAoAACgAAqAACoAAqAACoAAqAACoAAqAACoAAqAACoAAqAACoAAKAAAoAAAAAACqoAKqgCqqgKqqAoAoCgCgKAKAoAoCqqgKqqAKqgAqqAAAAAqqoCqqgKqqAqqoAAAAKCqAoKoCiqgKKqAoooCiigKKKAoooCqigKqKAKgoAqCgAAAAoAoCgCgKAKAoAoCiigKKKAoooCiigKqqAqqoAqqACqoAAAACqAAKoAAqoACqgAAKAAAoAACgAAKAAqqoCqqgKqqAqqoAAAAKoKAqgoCqigKqKAoooCiigKKKAoooCiqgKKqAoKgCgqAAAAAKqgAqqAKqqAqqoCiigKKKAoooCiigKKqAoqoCgqAKCoAAAACgAAKAAAoAACgAAKAAAoAACgAAKAAAqqoCqqgCqqAKqoAAAACqoAKqgCqqgKqqAoooCiigKKKAoooCqqgKqqAKqgAqqAAAAAKgAAqAAKqAAqoACigAKKAAooACigAKqqAqqoAqqgCqqAAAACgCgKAKAoAoCgCgAAAAoAqCgCoKAKgoAqAAAAAKAAAoAAKoAAqgAKqgAqqAKgqAqCoCgCgKAKAAAAAoKACgoAKCgAoKACgoAKCgAoKACgoAKCgAoKACgoAKCgAAAAKAKAoAoCoKgKgqAKqgAqqAAqgACqAACgAAKAAAAACgAAKAAAoAACgAAKKKAoooCiigKKKAqoACqgACoAAKgAAAAACqqAKqoCqqgKqqAoAACgAAKCoAoKgCiqgKKqAoooCiigKqqAqqoAqqACqoAAAAAqqgCqqAqqoCqqgKKAAooACigAKKAAqqoCqqgCqqAKqoAAAAKqqAqqoCqqgKqqAoooCiigKKKAoooCqqgKqqAKCgAoKAAAAAKqgAqqAKqqAqqoCgCgKAKAoAoCgCgKAKAoAoCgCgKAKAAAACqqgKqqAqqoCqqgKAKAoAoCoKgKgqAKqgAqqAAqgACqAAAAACqoAKqgCqqgKqqAoooCiigKKKAoooCgCgKAKAoAoCgCgAAAAKqoAqqgKqqAqqoCigAKKAAooACigAKAAAoAACgAAKAAAAAAAqqACqoAqqoCqqgKAKAoAoCiigKKKAoqoCiqgKKqAoqoAAAAKqqAqqoCqqgKqqAAoAACgAAKAAAoACqqgKqqAqqoCqqgAAAAoAoCgCgKAKAoAoCqqgKqqAqqoCqqgKAKAoAoCgCgKAKAAAAAAKAAAoAACoAAKgAAKAAAoAACgAAKAqqoCqqgKqoAqqgAAAAKqqAqqoCqqgKqqACqAAKoACqoAKqgCoKgKgqAoAoCgCgAAAAqqgCqqAKqqAqqoAACgAAKAAAoAACgAAKAAAoAACgAAKAAAACqqgKqqAqqoCqqgCoAAKgAAKgAAqAAKgAAqAAKqqAqqoCqqgKqqAAAACqqgKqqAqqoCqqgCoAAKgAAKgAAqAAqqoCqqgKqqAqqoAAAACqoAKqgCqqgKqqAoAoCgCgKAKAoAoCqqgKqqAKqgAqqAAAAAqqoCqqgKqqAqqoCigAKKAAooACigAKqAAqoAAqAACoAAAAAAqqACqoAqqoCqqgKAKAoAoCgKgKAqAqqoCqqgCqqAKqoAAAAKqqAqqoCqqgKqqAooACigAKKgAoqACqqgKqqAKioAqKgAAAAKgoAqCgKqKAqooCiigKKKAoooCiigKKqAoqoCgqAKCoAAAACgAAKAAAoAACgAAKqqAqqoCqqgKqqAoAACgAAKAAAoAAAAAAKqoAqqgCqqgKqqAAAoAACgAAKAAAoCqqgKqqAqqgCqqAAAAAqqACqoAKqoAqqgAAKgAAqAACoAAKgKqoAqqgCqoAKqgAAAACqqgKqqAqqoCqqgACoAAKgACoAAKgAAKgAAqAKqqAqqoCqqgKqqAAAACoKgKgqAqqoCqqgAqgACqAAKoAAqgAqqoCqqgKgqAqCoAAAAKoAAqgACqgAKqAAAqoACqgAKqAAqoCqgAKqAAqgACqAAAAAAoCoCgKgKCqAoKoCiqgKKqAqooCqigKoKAqgoCoCgKgKAAAACqqgKqqAqqoCqqgKAKAoAoAAAAKAAAoAACoAAKgAAKgAAqAAAqAACoAACoAAKgAAKgAAqAAAqAACoAACgAAKAAAACgCgKAKAqqoCqqgKqqAqqoAAA"), 32, atob("DQULDw0RDQUHBw0NBQ0FEQ0FDQ0NDQ0NDQ0FBQsNCw0RDQ0NDQ0NDQ0NDQ0NDw0NDQ0NDQ0NDQ8NDQ0HEQc="), 22+(scale<<8)+(1<<16));
return this;
}
// timeout used to update every minute
var drawTimeout;
// schedule a draw for the next minute
function queueDraw() {
if (drawTimeout) clearTimeout(drawTimeout);
drawTimeout = setTimeout(function() {
drawTimeout = undefined;
draw();
}, 60000 - (Date.now() % 60000));
}
function draw() {
var x = g.getWidth()/2;
var y = g.getHeight()/2 - 10;
g.reset();
// work out locale-friendly date/time
var date = new Date();
var timeStr = require("locale").time(date,1).trim();
var dateStr = require("locale").date(date).toUpperCase();
// draw time
g.setFontAlign(0,0).setFont("Undo:3");
g.clearRect(0,y-30,g.getWidth(),y+30); // clear the background
g.drawString(timeStr,x,y);
// draw date
y += 40;
g.setFontAlign(0,0).setFont("Undo");
g.clearRect(0,y-10,g.getWidth(),y+20); // clear the background
g.drawString(dateStr,x,y);
// queue draw in one minute
queueDraw();
}
// Clear the screen once, at startup
g.clear();
// draw immediately at first, queue update
draw();
// Stop updates when LCD is off, restart when on
Bangle.on('lcdPower',on=>{
if (on) {
draw(); // draw immediately, queue redraw
} else { // stop draw timer
if (drawTimeout) clearTimeout(drawTimeout);
drawTimeout = undefined;
}
});
// Show launcher when middle button pressed
Bangle.setUI("clock");
// Load widgets
Bangle.loadWidgets();
Bangle.drawWidgets();

BIN
apps/intclock/app.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@ -0,0 +1,16 @@
{
"id": "intclock",
"name": "Interlaced Clock",
"version": "0.01",
"description": "A lightweight digital clock using an 'interlaced' font",
"icon": "app.png",
"screenshots": [{"url":"screenshot.png"}],
"type": "clock",
"tags": "clock",
"supports": ["BANGLEJS","BANGLEJS2"],
"allow_emulator": true,
"storage": [
{"name":"intclock.app.js","url":"app.js"},
{"name":"intclock.img","url":"app-icon.js","evaluate":true}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

@ -32,5 +32,8 @@
0.20: Allow tapping on the body to show a scrollable view of the message and title in a bigger font (fix #1405, #1031)
0.21: Improve list readability on dark theme
0.22: Add Home Assistant icon
0.22: Allow repeat to be switched Off, so there is no buzzing repetition.
Also gave the widget a pixel more room to the right
Allow repeat to be switched Off, so there is no buzzing repetition.
Also gave the widget a pixel more room to the right
0.23: Change message colors to match current theme instead of using green
Now attempt to use Large/Big/Medium fonts, and allow minimum font size to be configured
0.24: Remove left-over debug statement

View File

@ -16,6 +16,9 @@ and `Messages`:
* `Unread Timer` - when a new message is received we go into the Messages app.
If there is no user input for this amount of time then the app will exit and return
to the clock where a ringing bell will be shown in the Widget bar.
* `Min Font` - the minimum font size used when displaying messages on the screen. A bigger font
is chosen if there isn't much message text, but this specifies the smallest the font should get before
it starts getting clipped.
## New Messages

View File

@ -21,13 +21,11 @@
*/
var Layout = require("Layout");
var settings = require('Storage').readJSON("messages.settings.json", true) || {};
var fontSmall = "6x8";
var fontMedium = g.getFonts().includes("6x15")?"6x15":"6x8:2";
var fontBig = g.getFonts().includes("12x20")?"12x20":"6x8:2";
var fontLarge = g.getFonts().includes("6x15")?"6x15:2":"6x8:4";
var colBg = g.theme.dark ? "#141":"#4f4";
var colSBg1 = g.theme.dark ? "#121":"#cFc";
var colSBg2 = g.theme.dark ? "#000":"#9F9";
// hack for 2v10 firmware's lack of ':size' font handling
try {
g.setFont("6x8:2");
@ -77,9 +75,13 @@ function getPosImage() {
function getNegImage() {
return atob("FhaBADAAMeAB78AP/4B/fwP4/h/B/P4D//AH/4AP/AAf4AB/gAP/AB/+AP/8B/P4P4fx/A/v4B//AD94AHjAAMA=");
}
/*
* icons should be 24x24px with 1bpp colors and transparancy
*/
function getMessageImage(msg) {
if (msg.img) return atob(msg.img);
var s = (msg.src||"").toLowerCase();
if (s=="alarm" || s =="alarmclockreceiver") return atob("GBjBAP////8AAAAAAAACAEAHAOAefng5/5wTgcgHAOAOGHAMGDAYGBgYGBgYGBgYGBgYDhgYBxgMATAOAHAHAOADgcAB/4AAfgAAAAAAAAA=");
if (s=="calendar") return atob("GBiBAAAAAAAAAAAAAA//8B//+BgAGBgAGBgAGB//+B//+B//+B9m2B//+B//+Btm2B//+B//+Btm+B//+B//+A//8AAAAAAAAAAAAA==");
if (s=="facebook") return getFBIcon();
if (s=="hangouts") return atob("FBaBAAH4AH/gD/8B//g//8P//H5n58Y+fGPnxj5+d+fmfj//4//8H//B//gH/4A/8AA+AAHAABgAAAA=");
@ -94,6 +96,7 @@ function getMessageImage(msg) {
if (s=="skype") return atob("GhoBB8AAB//AA//+Af//wH//+D///w/8D+P8Afz/DD8/j4/H4fP5/A/+f4B/n/gP5//B+fj8fj4/H8+DB/PwA/x/A/8P///B///gP//4B//8AD/+AAA+AA==");
if (s=="slack") return atob("GBiBAAAAAAAAAABAAAHvAAHvAADvAAAPAB/PMB/veD/veB/mcAAAABzH8B3v+B3v+B3n8AHgAAHuAAHvAAHvAADGAAAAAAAAAAAAAA==");
if (s=="sms message") return getNotificationImage();
if (s=="threema") return atob("GBjB/4Yx//8AAAAAAAAAAAAAfgAB/4AD/8AH/+AH/+AP//AP2/APw/APw/AHw+AH/+AH/8AH/4AH/gAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=");
if (s=="twitter") return atob("GhYBAABgAAB+JgA/8cAf/ngH/5+B/8P8f+D///h///4f//+D///g///wD//8B//+AP//gD//wAP/8AB/+AB/+AH//AAf/AAAYAAA");
if (s=="telegram") return atob("GBiBAAAAAAAAAAAAAAAAAwAAHwAA/wAD/wAf3gD/Pgf+fh/4/v/z/P/H/D8P/Acf/AM//AF/+AF/+AH/+ADz+ADh+ADAcAAAMAAAAA==");
if (s=="whatsapp") return atob("GBiBAAB+AAP/wAf/4A//8B//+D///H9//n5//nw//vw///x///5///4///8e//+EP3/APn/wPn/+/j///H//+H//8H//4H//wMB+AA==");
@ -105,6 +108,7 @@ function getMessageImage(msg) {
function getMessageImageCol(msg,def) {
return {
// generic colors, using B2-safe colors
"alarm": "#fff",
"calendar": "#f00",
"mail": "#ff0",
"music": "#f0f",
@ -122,6 +126,7 @@ function getMessageImageCol(msg,def) {
"outlook mail": "#0072c6",
"skype": "#00aff0",
"slack": "#e51670",
"threema": "#000",
"telegram": "#0088cc",
"twitter": "#1da1f2",
"whatsapp": "#4fce5d",
@ -143,8 +148,8 @@ function showMapMessage(msg) {
eta = m[2];
} else target=msg.body;
layout = new Layout({ type:"v", c: [
{type:"txt", font:fontMedium, label:target, bgCol:colBg, fillx:1, pad:2 },
{type:"h", bgCol:colBg, fillx:1, c: [
{type:"txt", font:fontMedium, label:target, bgCol:g.theme.bg2, col: g.theme.fg2, fillx:1, pad:2 },
{type:"h", bgCol:g.theme.bg2, col: g.theme.fg2, fillx:1, c: [
{type:"txt", font:"6x8", label:"Towards" },
{type:"txt", font:fontLarge, label:street }
]},
@ -168,27 +173,56 @@ function showMapMessage(msg) {
}
function showMusicMessage(msg) {
var updateLabelsInterval;
var trackScrollOffset = 0;
var artistScrollOffset = 0;
var albumScrollOffset = 0;
var trackName = '';
var artistName = '';
var albumName = '';
function fmtTime(s) {
var m = Math.floor(s/60);
s = (parseInt(s%60)).toString().padStart(2,0);
return m+":"+s;
}
function reduceStringAndPad(text, offset, maxLen) {
var sliceLength = offset + maxLen > text.length ? text.length - offset : maxLen;
return text.substr(offset, sliceLength).padEnd(maxLen, " ");
}
function back() {
clearInterval(updateLabelsInterval);
msg.new = false;
saveMessages();
layout = undefined;
checkMessages({clockIfNoMsg:1,clockIfAllRead:1,showMsgIfUnread:1});
}
function updateLabels() {
trackName = reduceStringAndPad(msg.track, trackScrollOffset, 13);
artistName = reduceStringAndPad(msg.artist, artistScrollOffset, 21);
albumName = reduceStringAndPad(msg.album, albumScrollOffset, 21);
trackScrollOffset++;
artistScrollOffset++;
albumScrollOffset++;
if ((trackScrollOffset + 13) > msg.track.length) trackScrollOffset = 0;
if ((artistScrollOffset + 21) > msg.artist.length) artistScrollOffset = 0;
if ((albumScrollOffset + 21) > msg.album.length) albumScrollOffset = 0;
}
updateLabels();
layout = new Layout({ type:"v", c: [
{type:"h", fillx:1, bgCol:colBg, c: [
{type:"h", fillx:1, bgCol:g.theme.bg2, col: g.theme.fg2, c: [
{ type:"btn", src:getBackImage, cb:back },
{ type:"v", fillx:1, c: [
{ type:"txt", font:fontMedium, label:msg.artist, pad:2 },
{ type:"txt", font:fontMedium, label:msg.album, pad:2 }
{ type:"txt", font:fontMedium, bgCol:g.theme.bg2, label:artistName, pad:2, id:"artist" },
{ type:"txt", font:fontMedium, bgCol:g.theme.bg2, label:albumName, pad:2, id:"album" }
]}
]},
{type:"txt", font:fontLarge, label:msg.track, fillx:1, filly:1, pad:2 },
{type:"txt", font:fontLarge, bgCol:g.theme.bg, label:trackName, fillx:1, filly:1, pad:2, id:"track" },
Bangle.musicControl?{type:"h",fillx:1, c: [
{type:"btn", pad:8, label:"\0"+atob("FhgBwAADwAAPwAA/wAD/gAP/gA//gD//gP//g///j///P//////////P//4//+D//gP/4A/+AD/gAP8AA/AADwAAMAAA"), cb:()=>Bangle.musicControl("play")}, // play
{type:"btn", pad:8, label:"\0"+atob("EhaBAHgHvwP/wP/wP/wP/wP/wP/wP/wP/wP/wP/wP/wP/wP/wP/wP/wP/wP/wP/wP/wP3gHg"), cb:()=>Bangle.musicControl("pause")}, // pause
@ -198,6 +232,14 @@ function showMusicMessage(msg) {
]});
g.clearRect(Bangle.appRect);
layout.render();
updateLabelsInterval = setInterval(function() {
updateLabels();
layout.artist.label = artistName;
layout.album.label = albumName;
layout.track.label = trackName;
layout.render();
}, 400);
}
function showMessageScroller(msg) {
@ -214,7 +256,9 @@ function showMessageScroller(msg) {
// a function to draw a menu item
draw : function(idx, r) {
// FIXME: in 2v13 onwards, clearRect(r) will work fine. There's a bug in 2v12
g.setBgColor(idx<titleCnt ? colBg : g.theme.bg).clearRect(r.x,r.y,r.x+r.w, r.y+r.h);
g.setBgColor(idx<titleCnt ? g.theme.bg2 : g.theme.bg).
setColor(idx<titleCnt ? g.theme.fg2 : g.theme.fg).
clearRect(r.x,r.y,r.x+r.w, r.y+r.h);
g.setFont(bodyFont).drawString(lines[idx], r.x, r.y);
}, select : function(idx) {
if (idx>=lines.length-2)
@ -270,13 +314,31 @@ function showMessage(msgid) {
var title=msg.title, titleFont = fontLarge, lines;
if (title) {
var w = g.getWidth()-48;
if (g.setFont(titleFont).stringWidth(title) > w)
titleFont = fontMedium;
if (g.setFont(titleFont).stringWidth(title) > w) {
titleFont = fontBig;
if (settings.fontSize!=1 && g.setFont(titleFont).stringWidth(title) > w)
titleFont = fontMedium;
}
if (g.setFont(titleFont).stringWidth(title) > w) {
lines = g.wrapString(title, w);
title = (lines.length>2) ? lines.slice(0,2).join("\n")+"..." : lines.join("\n");
}
}
// If body of message is only two lines long w/ large font, use large font.
var body=msg.body, bodyFont = fontLarge;
if (body) {
var w = g.getWidth()-10;
if (g.setFont(bodyFont).stringWidth(body) > w * 2) {
bodyFont = fontBig;
if (settings.fontSize!=1 && g.setFont(bodyFont).stringWidth(body) > w * 3)
bodyFont = fontMedium;
}
if (g.setFont(bodyFont).stringWidth(body) > w) {
lines = g.setFont(bodyFont).wrapString(msg.body, w);
var maxLines = Math.floor((g.getHeight()-110) / g.getFontHeight());
body = (lines.length>maxLines) ? lines.slice(0,maxLines).join("\n")+"..." : lines.join("\n");
}
}
function goBack() {
msg.new = false; saveMessages(); // read mail
cancelReloadTimeout(); // don't auto-reload to clock now
@ -303,27 +365,17 @@ function showMessage(msgid) {
checkMessages({clockIfNoMsg:1,clockIfAllRead:1,showMsgIfUnread:1});
}});
}
// If body of message is only two lines long w/ large font, use large font.
var body=msg.body, bodyFont = fontLarge, lines;
if (body) {
var w = g.getWidth()-48;
if (g.setFont(bodyFont).stringWidth(body) > w * 2)
bodyFont = fontMedium;
if (g.setFont(bodyFont).stringWidth(body) > w) {
lines = g.setFont(bodyFont).wrapString(msg.body, g.getWidth()-10);
body = (lines.length>4) ? lines.slice(0,4).join("\n")+"..." : lines.join("\n");
}
}
layout = new Layout({ type:"v", c: [
{type:"h", fillx:1, bgCol:colBg, c: [
{type:"h", fillx:1, bgCol:g.theme.bg2, col: g.theme.fg2, c: [
{ type:"btn", src:getMessageImage(msg), col:getMessageImageCol(msg), pad: 3, cb:()=>{
cancelReloadTimeout(); // don't auto-reload to clock now
showMessageSettings(msg);
}},
{ type:"v", fillx:1, c: [
{type:"txt", font:fontSmall, label:msg.src||/*LANG*/"Message", bgCol:colBg, fillx:1, pad:2, halign:1 },
title?{type:"txt", font:titleFont, label:title, bgCol:colBg, fillx:1, pad:2 }:{},
{type:"txt", font:fontSmall, label:msg.src||/*LANG*/"Message", bgCol:g.theme.bg2, col: g.theme.fg2, fillx:1, pad:2, halign:1 },
title?{type:"txt", font:titleFont, label:title, bgCol:g.theme.bg2, col: g.theme.fg2, fillx:1, pad:2 }:{},
]},
]},
{type:"txt", font:bodyFont, label:body, fillx:1, filly:1, pad:2, cb:()=>{
@ -374,9 +426,8 @@ function checkMessages(options) {
c : Math.max(MESSAGES.length+1,3), // workaround for 2v10.219 firmware (min 3 not needed for 2v11)
draw : function(idx, r) {"ram"
var msg = MESSAGES[idx-1];
if (msg && msg.new) g.setBgColor(colBg);
else g.setBgColor((idx&1) ? colSBg1 : colSBg2);
g.clearRect(r.x,r.y,r.x+r.w-1,r.y+r.h-1).setColor(g.theme.fg);
if (msg && msg.new) g.setBgColor(g.theme.bgH).setColor(g.theme.fgH);
else g.setColor(g.theme.fg);
if (idx==0) msg = {id:"back", title:"< Back"};
if (!msg) return;
var x = r.x+2, title = msg.title, body = msg.body;
@ -391,18 +442,20 @@ function checkMessages(options) {
.setColor(fg); // only color the icon
x += 50;
}
var m = msg.title+"\n"+msg.body;
if (msg.src) g.setFontAlign(1,1).setFont("6x8").drawString(msg.src, r.x+r.w-2, r.y+r.h-2);
var m = msg.title+"\n"+msg.body, longBody=false;
if (title) g.setFontAlign(-1,-1).setFont(fontBig).drawString(title, x,r.y+2);
if (body) {
g.setFontAlign(-1,-1).setFont("6x8");
var l = g.wrapString(body, r.w-14);
var l = g.wrapString(body, r.w-(x+14));
if (l.length>3) {
l = l.slice(0,3);
l[l.length-1]+="...";
}
longBody = l.length>2;
g.drawString(l.join("\n"), x+10,r.y+20);
}
if (!longBody && msg.src) g.setFontAlign(1,1).setFont("6x8").drawString(msg.src, r.x+r.w-2, r.y+r.h-2);
g.setColor("#888").fillRect(r.x,r.y+r.h-1,r.x+r.w-1,r.y+r.h-1); // dividing line between items
},
select : idx => {
if (idx==0) load();
@ -422,7 +475,7 @@ g.clear();
Bangle.loadWidgets();
Bangle.drawWidgets();
setTimeout(() => {
var unreadTimeoutSecs = (require('Storage').readJSON("messages.settings.json", true) || {}).unreadTimeout;
var unreadTimeoutSecs = settings.unreadTimeout;
if (unreadTimeoutSecs===undefined) unreadTimeoutSecs=60;
if (unreadTimeoutSecs)
unreadTimeout = setTimeout(function() {

View File

@ -1,7 +1,7 @@
{
"id": "messages",
"name": "Messages",
"version": "0.22",
"version": "0.24",
"description": "App to display notifications from iOS and Gadgetbridge/Android",
"icon": "app.png",
"type": "app",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

@ -37,6 +37,12 @@
format: v => v?v+"s":/*LANG*/"Off",
onchange: v => updateSetting("unreadTimeout", v)
},
/*LANG*/'Min Font': {
value: 0|settings().fontSize,
min: 0, max: 1,
format: v => [/*LANG*/"Small",/*LANG*/"Medium"][v],
onchange: v => updateSetting("fontSize", v)
},
};
E.showMenu(mainmenu);
})

View File

@ -6,7 +6,6 @@ draw:function() {
g.reset().clearRect(this.x, this.y, this.x+this.width, this.y+this.iconwidth);
g.drawImage((c&1) ? atob("GBiBAAAAAAAAAAAAAAAAAAAAAB//+DAADDAADDAADDwAPD8A/DOBzDDn/DA//DAHvDAPvjAPvjAPvjAPvh///gf/vAAD+AAB8AAAAA==") : atob("GBiBAAAAAAAAAAAAAAAAAAAAAB//+D///D///A//8CP/xDj/HD48DD+B8D/D+D/3vD/vvj/vvj/vvj/vvh/v/gfnvAAD+AAB8AAAAA=="), this.x, this.y);
let settings = require('Storage').readJSON("messages.settings.json", true) || {};
console.log("dingen ", typeof(settings.repeat), settings.repeat)
if (settings.repeat===undefined) settings.repeat = 4;
if (c<120 && (Date.now()-this.l)>settings.repeat*1000) {
this.l = Date.now();
@ -47,4 +46,4 @@ want to buzz but should still show that there are unread messages. */
if (global.MESSAGES===undefined) (function() {
var messages = require("Storage").readJSON("messages.json",1)||[];
if (messages.some(m=>m.new)) WIDGETS["messages"].show(true);
})();
})();

View File

@ -4,4 +4,5 @@
0.10: Improve the management of existing patterns: Draw the linked pattern on the left hand side of the app name within a scroller, similar to the default launcher. Slighlty clean up the code to make it less horrible.
0.11: Respect theme colors. Fix: Do not pollute global space with internal variables ans functions in boot.js
0.12: Improve pattern detection code readability by PaddeK http://forum.espruino.com/profiles/117930/
0.13: Improve pattern rendering by HughB http://forum.espruino.com/profiles/167235/
0.13: Improve pattern rendering by HughB http://forum.espruino.com/profiles/167235/
0.14: Update setUI to work with new Bangle.js 2v13 menu style

View File

@ -76,6 +76,7 @@
var sui = Bangle.setUI;
Bangle.setUI = function (mode, cb) {
sui(mode, cb);
if ("object"==typeof mode) mode = mode.mode;
if (!mode) {
Bangle.removeListener("drag", dragHandler);
storedPatterns = {};

View File

@ -2,7 +2,7 @@
"id": "ptlaunch",
"name": "Pattern Launcher",
"shortName": "Pattern Launcher",
"version": "0.13",
"version": "0.14",
"description": "Directly launch apps from the clock screen with custom patterns.",
"icon": "app.png",
"screenshots": [{"url":"manage_patterns_light.png"}],

View File

@ -226,7 +226,7 @@ function showThemeMenu() {
/*LANG*/'Dark BW': ()=>{
upd({
fg:cl("#fff"), bg:cl("#000"),
fg2:cl("#0ff"), bg2:cl("#000"),
fg2:cl("#fff"), bg2:cl("#004"),
fgH:cl("#fff"), bgH:cl("#00f"),
dark:true
});

View File

@ -1 +1,2 @@
0.01: New App!
0.01: New App!
0.02: Update setUI to work with new Bangle.js 2v13 menu style

View File

@ -1,6 +1,7 @@
(function() {
var sui = Bangle.setUI;
Bangle.setUI = function(mode, cb) {
if ("object"==typeof mode) mode = mode.mode;
if (mode!="clock") return sui(mode,cb);
return sui("clockupdown", (dir) => {
let settings = require("Storage").readJSON("shortcuts.json", 1)||{};
@ -12,4 +13,3 @@
});
};
})();

View File

@ -2,7 +2,7 @@
"id": "shortcuts",
"name": "Shortcuts",
"shortName": "Shortcuts",
"version": "0.01",
"version": "0.02",
"description": "Quickly load your favourite apps from (almost) any watch face.",
"icon": "app.png",
"type": "bootloader",

View File

@ -12,4 +12,4 @@
1.10: Adds Kalman filter.
1.14: Add VMG and coordinates screens
1.43: Adds mirroring of the watch face to an Android device. See README.md
1.48: Droidscript mirroring prog automatically uses last connection address. Auto connects when run.
1.49: Droidscript mirroring prog automatically uses last connection address. Auto connects when run.

View File

@ -1,2 +1,3 @@
0.01: New App!
0.02: Fix issue with mode being undefined
0.03: Update setUI to work with new Bangle.js 2v13 menu style

View File

@ -4,6 +4,7 @@
Bangle.setUI = function(mode, cb) {
sui(mode,cb);
if(!mode) return;
if ("object"==typeof mode) mode = mode.mode;
if (!mode.startsWith("clock")) return;
Bangle.swipeHandler = dir => { if (dir<0) Bangle.showLauncher(); };
Bangle.on("swipe", Bangle.swipeHandler);

View File

@ -1,7 +1,7 @@
{
"id": "swiperclocklaunch",
"name": "Swiper Clock Launch",
"version": "0.02",
"version": "0.03",
"description": "Navigate between clock and launcher with Swipe action",
"icon": "swiperclocklaunch.png",
"type": "bootloader",

View File

@ -1 +1,2 @@
0.01: New App!
0.02: Fix settings wrapping code for new menu system

View File

@ -2,7 +2,7 @@
"id": "tabata",
"name": "Tabata",
"shortName": "Tabata - Control High-Intensity Interval Training",
"version": "0.01",
"version": "0.02",
"description": "Control high-intensity interval training (according to tabata: https://en.wikipedia.org/wiki/Tabata_method).",
"icon": "tabata.png",
"tags": "workout,health",

View File

@ -30,18 +30,17 @@ function showMainMenu() {
},
'Pause sec.': {
value: settings.pause,
onchange: function(v){
if (v<0)v=MAX_SECONDS;
if (v>MAX_SECONDS)v=0;
min : 0, max : MAX_SECONDS, wrap : true,
onchange: v => {
settings.pause=v;
this.value=v;
saveSettingsDebounce();
}
},
'Trainig sec.': {
value: settings.training,
onchange: function(v){if (v<0)v=MAX_SECONDS;if (v>MAX_SECONDS)v=0;settings.training=v;
this.value=v;
min : 0, max : MAX_SECONDS, wrap : true,
onchange: v => {
settings.training=v;
saveSettingsDebounce();
}
},
@ -61,8 +60,8 @@ function startTabata() {
g.clear();
Bangle.setLCDMode("doublebuffered");
g.flip();
var pause = settings.pause,
training = settings.training,
var pause = settings.pause,
training = settings.training,
round = 1,
active = true,
clearBtn1, clearBtn2, clearBtn3, timer;
@ -86,7 +85,7 @@ function startTabata() {
exitTraining();
return;
}
if (active) {
drawCountDown(round, training, active);
training--;
@ -117,7 +116,7 @@ function drawCountDown(round, count, active) {
g.setFontAlign(0,0);
g.setFont("6x8", 2);
g.drawString("Round " + round + "/" + settings.rounds,120,6);
g.drawString("Round " + round + "/" + settings.rounds,120,6);
g.setFont("6x8", 6);
g.drawString("" + count,120,80);

1
apps/widcw/ChangeLog Normal file
View File

@ -0,0 +1 @@
0.01: First version

62
apps/widcw/logo.svg Normal file
View File

@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="48"
height="48"
viewBox="0 0 12.7 12.7"
version="1.1"
id="svg5"
inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20, custom)"
sodipodi:docname="logo.svg"
inkscape:export-filename="/home/klomp/Repositories/BangleApps/apps/widcw/widget.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:document-units="px"
showgrid="false"
units="px"
width="48px"
inkscape:zoom="16.106622"
inkscape:cx="29.242631"
inkscape:cy="21.481848"
inkscape:window-width="1061"
inkscape:window-height="439"
inkscape:window-x="2326"
inkscape:window-y="806"
inkscape:window-maximized="0"
inkscape:current-layer="layer1" />
<defs
id="defs2" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<text
xml:space="preserve"
style="font-weight:bold;font-size:5.6446px;line-height:2.4ex;font-family:Orbitron;-inkscape-font-specification:'Orbitron Bold';text-align:end;letter-spacing:0.21961px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;fill:none;stroke:#000000;stroke-width:0.264591px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="11.591952"
y="-4.2952275"
id="text3356"
inkscape:export-filename="/home/klomp/Repositories/BangleApps/apps/widcw/widget.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
transform="scale(0.99997031,-1.0000297)"><tspan
sodipodi:role="line"
id="tspan3354"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:5.6446px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';fill:#000000;stroke-width:0.264591px"
x="11.811562"
y="-4.2952275">CW</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

13
apps/widcw/metadata.json Normal file
View File

@ -0,0 +1,13 @@
{
"id": "widcw",
"name": "Calendar Week Widget",
"version": "0.01",
"description": "Widget which shows the current calendar week",
"icon": "widget.png",
"type": "widget",
"tags": "widget,calendar",
"supports": ["BANGLEJS","BANGLEJS2"],
"storage": [
{"name":"widcw.wid.js","url":"widget.js"}
]
}

48
apps/widcw/widget.js Normal file
View File

@ -0,0 +1,48 @@
(function() {
var width = 22; // width of the widget
function draw() {
const x = this.x, y = this.y, x2 = x+21, y2 = y+23;
var date = new Date();
// Calculate calendar week (https://stackoverflow.com/a/6117889)
getCW= function(date){
var d=new Date(date.getFullYear(), date.getMonth(), date.getDate());
var dayNum = d.getDay() || 7;
d.setDate(d.getDate() + 4 - dayNum);
var yearStart = new Date(d.getFullYear(),0,1);
return Math.ceil((((d - yearStart) / 86400000) + 1)/7);
};
g.reset().setFontAlign(0, 0) // center all text
// header
.setBgColor("#f00").setColor("#fff")
.clearRect(x, y, x2, y+8).setFont("4x6").drawString("CW", (x+x2)/2+1, y+5)
// date
.setBgColor("#fff").setColor("#000")
.clearRect(x, y+9, x2, y2).setFont("Vector:16").drawString(getCW(date), (x+x2)/2+2, y+17);
if (!g.theme.dark) {
// black border around date for light themes
g.setColor("#000").drawPoly([
x, y+9,
x, y2,
x2, y2,
x2, y+9
]);
}
// redraw when date changes
setTimeout(()=>WIDGETS["widcw"].draw(), (86401 - Math.floor(date/1000) % 86400)*1000);
}
// add your widget
WIDGETS["widcw"]={
area:"tl", // tl (top left), tr (top right), bl (bottom left), br (bottom right)
width: width, // how wide is the widget? You can change this and call Bangle.drawWidgets() to re-layout
draw:draw // called to draw the widget
};
})();

BIN
apps/widcw/widget.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 884 B

55
apps/widcw/widget.svg Normal file
View File

@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="48"
height="48"
viewBox="0 0 12.7 12.7"
version="1.1"
id="svg5"
inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20, custom)"
sodipodi:docname="logo.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:document-units="px"
showgrid="false"
units="px"
width="48px"
inkscape:zoom="16.106622"
inkscape:cx="29.211588"
inkscape:cy="21.450805"
inkscape:window-width="1918"
inkscape:window-height="1158"
inkscape:window-x="1366"
inkscape:window-y="20"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs2" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<text
xml:space="preserve"
style="font-weight:bold;font-size:5.64444px;line-height:2.4ex;font-family:Orbitron;-inkscape-font-specification:'Orbitron Bold';text-align:end;letter-spacing:0.219604px;word-spacing:0px;writing-mode:lr-tb;text-anchor:end;fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="11.591612"
y="8.4046535"
id="text3356"><tspan
sodipodi:role="line"
id="tspan3354"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:5.64444px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';fill:#000000;stroke-width:0.264583px"
x="11.811215"
y="8.4046535">CW</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -2,3 +2,4 @@
0.02: Don't break if running on 2v08 firmware (just don't display anything)
0.03: Fix positioning
0.04: Show GPS fix status
0.05: Don't poll for GPS status, override setGPSPower handler (fix #1456)

View File

@ -1,7 +1,7 @@
{
"id": "widgps",
"name": "GPS Widget",
"version": "0.04",
"version": "0.05",
"description": "Tiny widget to show the power and fix status of the GPS",
"icon": "widget.png",
"type": "widget",

View File

@ -1,7 +1,13 @@
(function(){
if (!Bangle.isGPSOn) return; // old firmware
// override setGPSPower so we know if GPS is on or off
var oldSetGPSPower = Bangle.setGPSPower;
Bangle.setGPSPower = function(on,id) {
var isGPSon = oldSetGPSPower(on,id);
WIDGETS.gps.draw();
return isGPSon;
}
function draw() {
WIDGETS.gps={area:"tr",width:24,draw:function() {
g.reset();
if (Bangle.isGPSOn()) {
const gpsObject = Bangle.getGPSFix();
@ -14,20 +20,5 @@
g.setColor("#888"); // off = grey
}
g.drawImage(atob("GBiBAAAAAAAAAAAAAA//8B//+BgYGBgYGBgYGBgYGBgYGBgYGB//+B//+BgYGBgYGBgYGBgYGBgYGBgYGB//+A//8AAAAAAAAAAAAA=="), this.x, 2+this.y);
}
var timerInterval;
Bangle.on('lcdPower', function(on) {
if (on) {
WIDGETS.gps.draw();
if (!timerInterval) timerInterval = setInterval(()=>WIDGETS.gps.draw(), 2000);
} else {
if (timerInterval) {
clearInterval(timerInterval);
timerInterval = undefined;
}
}
});
WIDGETS.gps={area:"tr",width:24,draw:draw};
}};
})();

View File

@ -180,13 +180,6 @@ function Layout(layout, options) {
if (l.id) ll[l.id] = l;
// fix type up
if (!l.type) l.type="";
// FIXME ':'/fsz not needed in new firmwares - Font:12 is handled internally
// fix fonts for pre-2v11 firmware
if (l.font && l.font.includes(":")) {
var f = l.font.split(":");
l.font = f[0];
l.fsz = f[1];
}
if (l.c) l.c.forEach(recurser);
}
recurser(this._l);
@ -241,13 +234,13 @@ Layout.prototype.render = function (l) {
"":function(){},
"txt":function(l){
if (l.wrap) {
g.setFont(l.font,l.fsz).setFontAlign(0,-1);
g.setFont(l.font).setFontAlign(0,-1);
var lines = g.wrapString(l.label, l.w);
var y = l.y+((l.h-g.getFontHeight()*lines.length)>>1);
// TODO: on 2v11 we can just render in a single drawString call
lines.forEach((line, i) => g.drawString(line, l.x+(l.w>>1), y+g.getFontHeight()*i));
} else {
g.setFont(l.font,l.fsz).setFontAlign(0,0,l.r).drawString(l.label, l.x+(l.w>>1), l.y+(l.h>>1));
g.setFont(l.font).setFontAlign(0,0,l.r).drawString(l.label, l.x+(l.w>>1), l.y+(l.h>>1));
}
}, "btn":function(l){
var x = l.x+(0|l.pad), y = l.y+(0|l.pad),
@ -365,7 +358,7 @@ Layout.prototype.update = function() {
if (l.wrap) {
l._h = l._w = 0;
} else {
var m = g.setFont(l.font,l.fsz).stringMetrics(l.label);
var m = g.setFont(l.font).stringMetrics(l.label);
l._w = m.width; l._h = m.height;
}
}, "btn": function(l) {

View File

@ -119,6 +119,7 @@ Bangle.on("GPS", function(fix) {
Bangle.on("step", function(steps) {
if (!state.active) return;
if (stats["step"]) stats["step"].emit("changed",stats["step"]);
state.stepHistory[0] += steps-state.lastStepCount;
state.lastStepCount = steps;
});
Bangle.on("HRM", function(h) {