forked from FOSS/BangleApps
multiclock - new bangle 2 compatible
parent
ed9daa139a
commit
6f5b902adb
18
apps.json
18
apps.json
|
@ -2683,22 +2683,22 @@
|
||||||
{
|
{
|
||||||
"id": "multiclock",
|
"id": "multiclock",
|
||||||
"name": "Multi Clock",
|
"name": "Multi Clock",
|
||||||
"version": "0.13",
|
"version": "0.07",
|
||||||
"description": "Clock with multiple faces - Big, Analogue, Digital, Text, Time-Date.\n Switch between faces with BTN1 & BTN3",
|
"description": "Clock with multiple faces - Big, Analogue, Digital, Text, Time-Date.\n Switch between faces with BTN1 & BTN3",
|
||||||
"icon": "multiclock.png",
|
"icon": "multiclock.png",
|
||||||
"type": "clock",
|
"type": "clock",
|
||||||
"tags": "clock",
|
"tags": "clock",
|
||||||
"supports": ["BANGLEJS"],
|
"supports": ["BANGLEJS","BANGLEJS2"],
|
||||||
"readme": "README.md",
|
"readme": "README.md",
|
||||||
"allow_emulator": true,
|
"allow_emulator": true,
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"multiclock.app.js","url":"clock.js"},
|
{"name":"multiclock.app.js","url":"multiclock.app.js"},
|
||||||
{"name":"big.face.js","url":"big.js"},
|
{"name":"big.face.js","url":"big.face.js"},
|
||||||
{"name":"ana.face.js","url":"ana.js"},
|
{"name":"ana.face.js","url":"ana.face.js"},
|
||||||
{"name":"digi.face.js","url":"digi.js"},
|
{"name":"digi.face.js","url":"digi.face.js"},
|
||||||
{"name":"txt.face.js","url":"txt.js"},
|
{"name":"txt.face.js","url":"txt.face.js"},
|
||||||
{"name":"timdat.face.js","url":"timdat.js"},
|
{"name":"dk.face.js","url":"dk.face.js"},
|
||||||
{"name":"ped.face.js","url":"ped.js"},
|
{"name":"nifty.face.js","url":"nifty.face.js"},
|
||||||
{"name":"multiclock.img","url":"multiclock-icon.js","evaluate":true}
|
{"name":"multiclock.img","url":"multiclock-icon.js","evaluate":true}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,13 +1,10 @@
|
||||||
0.01: New App!
|
0.01: Initial version
|
||||||
0.02: Separate *.face.js files for faces
|
0.02: Add pinned clock facility
|
||||||
0.03: Renaming
|
0.03: Lnng touch switch to night clock - ANCS off, dimmed
|
||||||
0.04: Bug Fixes
|
0.04: use theme, font heights etc
|
||||||
0.05: Add README
|
0.05: make Bangle compatible
|
||||||
0.06: Add txt clock
|
0.06: add minute tick for efficiency and nifty A clock
|
||||||
0.07: Add Time Date clock and fix font sizes
|
0.07: compatible with Bang;e.js 2
|
||||||
0.08: Add pinned clock face
|
|
||||||
0.09: Added Pedometer clock
|
|
||||||
0.10: Added GPS and Grid Ref clock faces
|
|
||||||
0.11: Updated Pedometer clock to retrieve steps from either wpedom or activepedom
|
|
||||||
0.12: Removed GPS and Grid Ref clock faces, superceded by GPS setup and Walkers Clock
|
|
||||||
0.13: Localised digi.js and timdat.js
|
|
||||||
|
|
|
@ -1,52 +0,0 @@
|
||||||
# Multiclock
|
|
||||||
|
|
||||||
This is a clock app that supports multiple clock faces. The user can switch between faces while retaining widget state which makes the switch fast and preserves state such as bluetooth connections. Currently there are four clock faces as shown below. To my eye, these faces look better when widgets are hidden using **widviz**.
|
|
||||||
|
|
||||||
### Analog Clock Face
|
|
||||||

|
|
||||||
|
|
||||||
### Digital Clock Face
|
|
||||||

|
|
||||||
|
|
||||||
### Big Digit Clock Face
|
|
||||||

|
|
||||||
|
|
||||||
### Text Clock Face
|
|
||||||

|
|
||||||
|
|
||||||
### Time and Date Clock Face
|
|
||||||
|
|
||||||
|
|
||||||
## Controls
|
|
||||||
Clock faces are kept in a circular list.
|
|
||||||
|
|
||||||
*BTN1* - switches to the next clock face.
|
|
||||||
|
|
||||||
*BTN2* - switches to the app launcher.
|
|
||||||
|
|
||||||
*BTN3* - switches to the previous clock face.
|
|
||||||
|
|
||||||
## Adding a new face
|
|
||||||
Clock faces are described in javascript storage files named `name.face.js`. For example, the Analog Clock Face is described in `ana.face.js`. These files have the following structure:
|
|
||||||
|
|
||||||
```
|
|
||||||
(() => {
|
|
||||||
function getFace(){
|
|
||||||
function onSecond(){
|
|
||||||
//draw digits, hands etc
|
|
||||||
}
|
|
||||||
function drawAll(){
|
|
||||||
//draw background + initial state of digits, hands etc
|
|
||||||
}
|
|
||||||
return {init:drawAll, tick:onSecond};
|
|
||||||
}
|
|
||||||
return getFace;
|
|
||||||
})();
|
|
||||||
```
|
|
||||||
For those familiar with the structure of widgets, this is similar, however, there is an additional level of function nesting. This means that although faces are loaded when the clock app starts running they are not instantiated until their `getFace` function is called, i.e. memory is not allocated to structures such as image buffer arrays declared in `getFace` until the face is selected. Consequently, adding a face does not require a lot of extra memory.
|
|
||||||
|
|
||||||
The app at start up loads all files `*.face.js`. The simplest way of adding a face is thus to load it into `Storage` using the WebIDE. Similarly, to remove an unwanted face, simply delete it from `Storage` using the WebIDE.
|
|
||||||
|
|
||||||
## Support
|
|
||||||
|
|
||||||
Please report bugs etc. by raising an issue [here](https://github.com/jeffmer/JeffsBangleAppsDev).
|
|
|
@ -5,54 +5,60 @@
|
||||||
const p = Math.PI/2;
|
const p = Math.PI/2;
|
||||||
const PRad = Math.PI/180;
|
const PRad = Math.PI/180;
|
||||||
|
|
||||||
|
var cx = g.getWidth()/2;
|
||||||
|
var cy = 12+g.getHeight()/2;
|
||||||
|
var scale = (g.getHeight()-24)/(240-24);
|
||||||
|
scale = scale>=1 ? 1 : scale;
|
||||||
|
|
||||||
function seconds(angle, r) {
|
function seconds(angle, r) {
|
||||||
const a = angle*PRad;
|
const a = angle*PRad;
|
||||||
const x = 120+Math.sin(a)*r;
|
const x = cx+Math.sin(a)*r;
|
||||||
const y = 134-Math.cos(a)*r;
|
const y = cy-Math.cos(a)*r;
|
||||||
if (angle % 90 == 0) {
|
if (angle % 90 == 0) {
|
||||||
g.setColor(0,1,1);
|
g.setColor(g.theme.fg2);
|
||||||
g.fillRect(x-6,y-6,x+6,y+6);
|
g.fillRect(x-6,y-6,x+6,y+6);
|
||||||
} else if (angle % 30 == 0){
|
} else if (angle % 30 == 0){
|
||||||
g.setColor(0,1,1);
|
g.setColor(g.theme.fg);
|
||||||
g.fillRect(x-4,y-4,x+4,y+4);
|
g.fillRect(x-4,y-4,x+4,y+4);
|
||||||
} else {
|
} else {
|
||||||
g.setColor(1,1,1);
|
g.setColor(g.theme.fg);
|
||||||
g.fillRect(x-1,y-1,x+1,y+1);
|
g.fillRect(x-1,y-1,x+1,y+1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function hand(angle, r1,r2, r3) {
|
function hand(angle, r1,r2, r3) {
|
||||||
|
r1 = scale*r1; r2=scale*r2; r3 = scale*r3;
|
||||||
const a = angle*PRad;
|
const a = angle*PRad;
|
||||||
g.fillPoly([
|
g.fillPoly([
|
||||||
120+Math.sin(a)*r1,
|
cx+Math.sin(a)*r1,
|
||||||
134-Math.cos(a)*r1,
|
cy-Math.cos(a)*r1,
|
||||||
120+Math.sin(a+p)*r3,
|
cx+Math.sin(a+p)*r3,
|
||||||
134-Math.cos(a+p)*r3,
|
cy-Math.cos(a+p)*r3,
|
||||||
120+Math.sin(a)*r2,
|
cx+Math.sin(a)*r2,
|
||||||
134-Math.cos(a)*r2,
|
cy-Math.cos(a)*r2,
|
||||||
120+Math.sin(a-p)*r3,
|
cx+Math.sin(a-p)*r3,
|
||||||
134-Math.cos(a-p)*r3]);
|
cy-Math.cos(a-p)*r3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
var minuteDate;
|
var minuteDate;
|
||||||
var secondDate;
|
var secondDate;
|
||||||
|
|
||||||
function onSecond() {
|
function onSecond() {
|
||||||
g.setColor(0,0,0);
|
g.setColor(g.theme.bg);
|
||||||
hand(360*secondDate.getSeconds()/60, -5, 90, 3);
|
hand(360*secondDate.getSeconds()/60, -5, 90, 3);
|
||||||
if (secondDate.getSeconds() === 0) {
|
if (secondDate.getSeconds() === 0) {
|
||||||
hand(360*(minuteDate.getHours() + (minuteDate.getMinutes()/60))/12, -16, 60, 7);
|
hand(360*(minuteDate.getHours() + (minuteDate.getMinutes()/60))/12, -16, 60, 7);
|
||||||
hand(360*minuteDate.getMinutes()/60, -16, 86, 7);
|
hand(360*minuteDate.getMinutes()/60, -16, 86, 7);
|
||||||
minuteDate = new Date();
|
minuteDate = new Date();
|
||||||
}
|
}
|
||||||
g.setColor(1,1,1);
|
g.setColor(g.theme.fg);
|
||||||
hand(360*(minuteDate.getHours() + (minuteDate.getMinutes()/60))/12, -16, 60, 7);
|
hand(360*(minuteDate.getHours() + (minuteDate.getMinutes()/60))/12, -16, 60, 7);
|
||||||
hand(360*minuteDate.getMinutes()/60, -16, 86, 7);
|
hand(360*minuteDate.getMinutes()/60, -16, 86, 7);
|
||||||
g.setColor(0,1,1);
|
g.setColor(g.theme.fg2);
|
||||||
secondDate = new Date();
|
secondDate = new Date();
|
||||||
hand(360*secondDate.getSeconds()/60, -5, 90, 3);
|
hand(360*secondDate.getSeconds()/60, -5, 90, 3);
|
||||||
g.setColor(0,0,0);
|
g.setColor(g.theme.bg);
|
||||||
g.fillCircle(120,134,2);
|
g.fillCircle(cx,cy,2);
|
||||||
}
|
}
|
||||||
|
|
||||||
function drawAll() {
|
function drawAll() {
|
||||||
|
@ -60,11 +66,11 @@
|
||||||
// draw seconds
|
// draw seconds
|
||||||
g.setColor(1,1,1);
|
g.setColor(1,1,1);
|
||||||
for (let i=0;i<60;i++)
|
for (let i=0;i<60;i++)
|
||||||
seconds(360*i/60, 100);
|
seconds(360*i/60, 100*scale);
|
||||||
onSecond();
|
onSecond();
|
||||||
}
|
}
|
||||||
|
|
||||||
return {init:drawAll, tick:onSecond};
|
return {init:drawAll, tick:onSecond, tickpersec:true};
|
||||||
}
|
}
|
||||||
|
|
||||||
return getFace;
|
return getFace;
|
Binary file not shown.
Before Width: | Height: | Size: 44 KiB |
|
@ -1,19 +0,0 @@
|
||||||
{ "id": "multiclock",
|
|
||||||
"name": "Multi Clock",
|
|
||||||
"icon": "multiclock.png",
|
|
||||||
"version":"0.06",
|
|
||||||
"description": "Clock with multiple faces - Big, Analogue, Digital, Text.\n Switch between faces with BT1 & BTN3",
|
|
||||||
"readme": "README.md",
|
|
||||||
"tags": "clock",
|
|
||||||
"type":"clock",
|
|
||||||
"allow_emulator":false,
|
|
||||||
"storage": [
|
|
||||||
{"name":"multiclock.app.js","url":"clock.min.js"},
|
|
||||||
{"name":"big.face.js","url":"big.min.js"},
|
|
||||||
{"name":"ana.face.js","url":"ana.min.js"},
|
|
||||||
{"name":"digi.face.js","url":"digi.min.js"},
|
|
||||||
{"name":"txt.face.js","url":"txt.min.js"},
|
|
||||||
{"name":"ped.face.js","url":"ped.js"},
|
|
||||||
{"name":"multiclock.img","url":"multiclock-icon.js","evaluate":true}
|
|
||||||
]
|
|
||||||
},
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
(() => {
|
||||||
|
|
||||||
|
function getFace(){
|
||||||
|
|
||||||
|
const W = g.getWidth();
|
||||||
|
const H = g.getHeight();
|
||||||
|
const F = 132*H/240; // reasonable approximation
|
||||||
|
|
||||||
|
function drawTime() {
|
||||||
|
d = new Date()
|
||||||
|
g.reset();
|
||||||
|
var da = d.toString().split(" ");
|
||||||
|
var time = da[4].substr(0, 5).split(":");
|
||||||
|
var hours = time[0],
|
||||||
|
minutes = time[1];
|
||||||
|
g.clearRect(0,24,W-1,H-1);
|
||||||
|
g.setColor(g.theme.fg);
|
||||||
|
g.setFont("Vector",F);
|
||||||
|
g.setFontAlign(0,-1);
|
||||||
|
g.drawString(hours,W/2,24,true);
|
||||||
|
g.setColor(g.theme.fg2);
|
||||||
|
g.drawString(minutes,W/2,12+H/2,true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return {init:drawTime, tick:drawTime, tickpersecond:false};
|
||||||
|
}
|
||||||
|
|
||||||
|
return getFace;
|
||||||
|
|
||||||
|
})();
|
|
@ -1,32 +0,0 @@
|
||||||
(() => {
|
|
||||||
|
|
||||||
function getFace(){
|
|
||||||
|
|
||||||
function drawTime(d) {
|
|
||||||
g.reset();
|
|
||||||
var da = d.toString().split(" ");
|
|
||||||
var time = da[4].substr(0, 5).split(":");
|
|
||||||
var hours = time[0],
|
|
||||||
minutes = time[1];
|
|
||||||
g.clearRect(0,24,239,239);
|
|
||||||
g.setColor(1,1,1);
|
|
||||||
g.setFont("Vector",132);
|
|
||||||
g.drawString(hours,50,24,true);
|
|
||||||
g.drawString(minutes,50,132,true);
|
|
||||||
}
|
|
||||||
|
|
||||||
function onSecond(){
|
|
||||||
var t = new Date();
|
|
||||||
if (t.getSeconds() === 0) drawTime(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
function drawAll(){
|
|
||||||
drawTime(new Date());
|
|
||||||
}
|
|
||||||
|
|
||||||
return {init:drawAll, tick:onSecond};
|
|
||||||
}
|
|
||||||
|
|
||||||
return getFace;
|
|
||||||
|
|
||||||
})();
|
|
Binary file not shown.
Before Width: | Height: | Size: 40 KiB |
|
@ -1 +1 @@
|
||||||
require("heatshrink").decompress(atob("mEwwkEogA/AFGIAAQVVDKQWHDB1IC5OECx8z///mYYOBoWDCoIADnBJLFwQWGDAgwIEYU/CQXwh4EC+YwKBIOPFQYXE//4C5BGCIQgXF/5IILo4XGMIQXHLoYXIMIRGMC45IHC4KkGC45IBC4yNEC5KRBC7h2HC5B4GC5EggQXOBwvygEAl6QHC4sikRGEhGAJAgNBC75HIgZHNO48AgIJER54xCiYXKa5AxCGAjvPGA4XIwYXHbQs4C46QGGAbZDB4IXEPBQAEOwwXDJBJGEC4xILIxQwDSJCNDFwwXDMIh0ELoQXIJARhDC4hdCIw4wEDAQXDCwQuIGAgABmYXBmYHDFxIYGAAoWLJIgAGCxgYJCxwZGCqIA/AC4A="))
|
require("heatshrink").decompress(atob("mEwwkEogA/AFGIAAQVVDKQWHDB1IC5OECx8z///mYYOBoWDCoIADnBJLFwQWGDAgwIEYU/CQXwh4EC+YwKBIOPFQYXE//4C5BGCIQgXF/5IILo4XGMIQXHLoYXIMIRGMC45IHC4KkGC45IBC4yNEC5KRBC7h2HC5B4GC5EggQXOBwvygEAl6QHC4sikRGEhGAJAgNBC75HIgZHNO48AgIJER54xCiYXKa5AxCGAjvPGA4XIwYXHbQs4C46QGGAbZDB4IXEPBQAEOwwXDJBJGEC4xILIxQwDSJCNDFwwXDMIh0ELoQXIJARhDC4hdCIw4wEDAQXDCwQuIGAgABmYXBmYHDFxIYGAAoWLJIgAGCxgYJCxwZGCqIA/AC4A="))
|
Binary file not shown.
|
@ -0,0 +1 @@
|
||||||
|
{"id":"clock","name":"Clock","type":"clock","src":"clock.app.js","icon":"clock.img","version":"0.06","files":"clock.info,clock.app.js,big.face.js,ana.face.js,digi.face.js,txt.face.js"}
|
|
@ -1,69 +0,0 @@
|
||||||
var FACES = [];
|
|
||||||
var STOR = require("Storage");
|
|
||||||
STOR.list(/\.face\.js$/).forEach(face=>FACES.push(eval(require("Storage").read(face))));
|
|
||||||
var lastface = STOR.readJSON("multiclock.json")||{pinned:0};
|
|
||||||
var iface = lastface.pinned;
|
|
||||||
var face = FACES[iface]();
|
|
||||||
var intervalRefSec;
|
|
||||||
|
|
||||||
function stopdraw() {
|
|
||||||
if(intervalRefSec) {intervalRefSec=clearInterval(intervalRefSec);}
|
|
||||||
}
|
|
||||||
|
|
||||||
function startdraw() {
|
|
||||||
g.clear();
|
|
||||||
g.reset();
|
|
||||||
Bangle.drawWidgets();
|
|
||||||
face.init();
|
|
||||||
intervalRefSec = setInterval(face.tick,1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
function setButtons(){
|
|
||||||
function newFace(inc){
|
|
||||||
var n = FACES.length-1;
|
|
||||||
iface+=inc;
|
|
||||||
iface = iface>n?0:iface<0?n:iface;
|
|
||||||
stopdraw();
|
|
||||||
face = FACES[iface]();
|
|
||||||
startdraw();
|
|
||||||
}
|
|
||||||
function finish(){
|
|
||||||
if (lastface.pinned!=iface){
|
|
||||||
lastface.pinned=iface;
|
|
||||||
STOR.write("multiclock.json",lastface);
|
|
||||||
}
|
|
||||||
Bangle.showLauncher();
|
|
||||||
}
|
|
||||||
setWatch(finish, BTN2, {repeat:false,edge:"falling"});
|
|
||||||
setWatch(newFace.bind(null,1), BTN1, {repeat:true,edge:"rising"});
|
|
||||||
setWatch(newFace.bind(null,-1), BTN3, {repeat:true,edge:"rising"});
|
|
||||||
}
|
|
||||||
|
|
||||||
var SCREENACCESS = {
|
|
||||||
withApp:true,
|
|
||||||
request:function(){
|
|
||||||
this.withApp=false;
|
|
||||||
stopdraw();
|
|
||||||
clearWatch();
|
|
||||||
},
|
|
||||||
release:function(){
|
|
||||||
this.withApp=true;
|
|
||||||
startdraw();
|
|
||||||
setButtons();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Bangle.on('lcdPower',function(on) {
|
|
||||||
if (!SCREENACCESS.withApp) return;
|
|
||||||
if (on) {
|
|
||||||
startdraw();
|
|
||||||
} else {
|
|
||||||
stopdraw();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
g.clear();
|
|
||||||
Bangle.loadWidgets();
|
|
||||||
startdraw();
|
|
||||||
setButtons();
|
|
||||||
|
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
|
@ -0,0 +1,38 @@
|
||||||
|
(() => {
|
||||||
|
|
||||||
|
function getFace(){
|
||||||
|
|
||||||
|
var W = g.getWidth();
|
||||||
|
var H = g.getHeight();
|
||||||
|
var scale = w/240;
|
||||||
|
|
||||||
|
var buf = Graphics.createArrayBuffer(W,92,1,{msb:true});
|
||||||
|
function flip() {
|
||||||
|
g.setColor(g.theme.fg);
|
||||||
|
g.drawImage({width:buf.getWidth(),height:buf.getHeight(),buffer:buf.buffer},0,H/2-46);
|
||||||
|
}
|
||||||
|
|
||||||
|
var W = g.getWidth();
|
||||||
|
var H = g.getHeight();
|
||||||
|
|
||||||
|
function drawTime() {
|
||||||
|
buf.clear();
|
||||||
|
buf.setColor(1);
|
||||||
|
var d = new Date();
|
||||||
|
var da = d.toString().split(" ");
|
||||||
|
var time = da[4];
|
||||||
|
buf.setFont("Vector",54*scale);
|
||||||
|
buf.setFontAlign(0,-1);
|
||||||
|
buf.drawString(time,W/2,0);
|
||||||
|
buf.setFont("6x8",2);
|
||||||
|
buf.setFontAlign(0,-1);
|
||||||
|
var date = d.toString().substr(0,15);
|
||||||
|
buf.drawString(date, W/2, 70);
|
||||||
|
flip();
|
||||||
|
}
|
||||||
|
return {init:drawTime, tick:drawTime, tickpersec:true};
|
||||||
|
}
|
||||||
|
|
||||||
|
return getFace;
|
||||||
|
|
||||||
|
})();
|
|
@ -1,33 +0,0 @@
|
||||||
(() => {
|
|
||||||
|
|
||||||
var locale = require("locale");
|
|
||||||
|
|
||||||
function getFace(){
|
|
||||||
|
|
||||||
var buf = Graphics.createArrayBuffer(240,92,1,{msb:true});
|
|
||||||
function flip() {
|
|
||||||
g.setColor(1,1,1);
|
|
||||||
g.drawImage({width:buf.getWidth(),height:buf.getHeight(),buffer:buf.buffer},0,85);
|
|
||||||
}
|
|
||||||
|
|
||||||
function drawTime() {
|
|
||||||
buf.clear();
|
|
||||||
buf.setColor(1);
|
|
||||||
var d = new Date();
|
|
||||||
var da = d.toString().split(" ");
|
|
||||||
var time = da[4];
|
|
||||||
buf.setFont("Vector",54);
|
|
||||||
buf.setFontAlign(0,-1);
|
|
||||||
buf.drawString(time,buf.getWidth()/2,0);
|
|
||||||
buf.setFont("6x8",2);
|
|
||||||
buf.setFontAlign(0,-1);
|
|
||||||
var date = locale.dow(d, 1) + " " + locale.date(d, 1);
|
|
||||||
buf.drawString(date, buf.getWidth()/2, 70);
|
|
||||||
flip();
|
|
||||||
}
|
|
||||||
return {init:drawTime, tick:drawTime};
|
|
||||||
}
|
|
||||||
|
|
||||||
return getFace;
|
|
||||||
|
|
||||||
})();
|
|
Binary file not shown.
Before Width: | Height: | Size: 47 KiB |
|
@ -0,0 +1,40 @@
|
||||||
|
(() => {
|
||||||
|
function getFace(){
|
||||||
|
|
||||||
|
const locale = require("locale");
|
||||||
|
|
||||||
|
var W = g.getWidth();
|
||||||
|
var H = g.getHeight();
|
||||||
|
var scale = W/240;
|
||||||
|
|
||||||
|
function drawClock(){
|
||||||
|
var now=Date();
|
||||||
|
d=now.toString().split(' ');
|
||||||
|
var min=d[4].substr(3,2);
|
||||||
|
var sec=d[4].substr(-2);
|
||||||
|
var tm=d[4].substring(0,5);
|
||||||
|
var hr=d[4].substr(0,2);
|
||||||
|
lastmin=min;
|
||||||
|
g.reset();
|
||||||
|
g.clearRect(0,24,W-1,H-1);
|
||||||
|
g.setColor(g.theme.fg);
|
||||||
|
g.setFontAlign(0,-1);
|
||||||
|
g.setFontVector(80*scale);
|
||||||
|
g.drawString(tm,4+W/2,H/2-80*scale);
|
||||||
|
g.setFontVector(36*scale);
|
||||||
|
g.setColor(g.theme.fg2);
|
||||||
|
d[1] = locale.month(now,3);
|
||||||
|
d[0] = locale.dow(now,3);
|
||||||
|
var dt=d[0]+" "+d[1]+" "+d[2];//+" "+d[3];
|
||||||
|
g.drawString(dt,W/2,H/2);
|
||||||
|
g.flip();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return {init:drawClock, tick:drawClock, tickpersec:false};
|
||||||
|
}
|
||||||
|
|
||||||
|
return getFace;
|
||||||
|
|
||||||
|
})();
|
||||||
|
|
|
@ -0,0 +1,85 @@
|
||||||
|
var FACES = [];
|
||||||
|
var STOR = require("Storage");
|
||||||
|
STOR.list(/\.face\.js$/).forEach(face=>FACES.push(eval(require("Storage").read(face))));
|
||||||
|
var lastface = STOR.readJSON("clock.json") || {pinned:0}
|
||||||
|
var iface = lastface.pinned;
|
||||||
|
var face = FACES[iface]();
|
||||||
|
var intervalRefSec;
|
||||||
|
var intervalRefSec;
|
||||||
|
var tickTimeout;
|
||||||
|
|
||||||
|
function stopdraw() {
|
||||||
|
if(intervalRefSec) {intervalRefSec=clearInterval(intervalRefSec);}
|
||||||
|
if(tickTimeout) {tickTimeout=clearTimeout(tickTimeout);}
|
||||||
|
g.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
function queueMinuteTick(f) {
|
||||||
|
if (tickTimeout) clearTimeout(drawTimeout);
|
||||||
|
tickTimeout = setTimeout(function() {
|
||||||
|
tickTimeout = undefined;
|
||||||
|
f();
|
||||||
|
}, 60000 - (Date.now() % 60000));
|
||||||
|
}
|
||||||
|
|
||||||
|
function startdraw() {
|
||||||
|
g.reset();
|
||||||
|
face.init();
|
||||||
|
if (face.tickpersec)
|
||||||
|
intervalRefSec = setInterval(face.tick,1000);
|
||||||
|
else
|
||||||
|
queueMinuteTick(face.tick);
|
||||||
|
wOS.drawWidgets();
|
||||||
|
}
|
||||||
|
|
||||||
|
var SCREENACCESS = {
|
||||||
|
withApp:true,
|
||||||
|
request:function(){
|
||||||
|
this.withApp=false;
|
||||||
|
stopdraw();
|
||||||
|
},
|
||||||
|
release:function(){
|
||||||
|
this.withapp=true;
|
||||||
|
startdraw();
|
||||||
|
setButtons();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Bangle.on('lcdPower',function(b) {
|
||||||
|
if (!SCREENACCESS.withApp) return;
|
||||||
|
if (b) {
|
||||||
|
startdraw();
|
||||||
|
} else {
|
||||||
|
stopdraw();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function setButtons(){
|
||||||
|
function newFace(inc){
|
||||||
|
if (!inc) Bangle.showLauncher();
|
||||||
|
else {
|
||||||
|
var n = FACES.length-1;
|
||||||
|
iface+=inc;
|
||||||
|
iface = iface>n?0:iface<0?n:iface;
|
||||||
|
stopdraw();
|
||||||
|
face = FACES[iface]();
|
||||||
|
startdraw();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Bangle.setUI("leftright", newFace);
|
||||||
|
}
|
||||||
|
|
||||||
|
E.on('kill',()=>{
|
||||||
|
if (iface!=lastface.pinned){
|
||||||
|
lastface.pinned=iface;
|
||||||
|
STOR.write("clock.json",lastface);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Bangle.loadWidgets();
|
||||||
|
g.clear();
|
||||||
|
startdraw();
|
||||||
|
setButtons();
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
(() => {
|
||||||
|
function getFace(){
|
||||||
|
|
||||||
|
const locale = require("locale");
|
||||||
|
const is12Hour = (require("Storage").readJSON("setting.json", 1) || {})["12hour"];
|
||||||
|
|
||||||
|
const scale = g.getWidth() / 176;
|
||||||
|
|
||||||
|
const widget = 24;
|
||||||
|
|
||||||
|
const viewport = {
|
||||||
|
width: g.getWidth(),
|
||||||
|
height: g.getHeight(),
|
||||||
|
}
|
||||||
|
|
||||||
|
const center = {
|
||||||
|
x: viewport.width / 2,
|
||||||
|
y: Math.round(((viewport.height - widget) / 2) + widget),
|
||||||
|
}
|
||||||
|
|
||||||
|
function d02(value) {
|
||||||
|
return ('0' + value).substr(-2);
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawClock() {
|
||||||
|
g.reset();
|
||||||
|
g.clearRect(0, widget, viewport.width, viewport.height);
|
||||||
|
var now = new Date();
|
||||||
|
const hour = d02(now.getHours() - (is12Hour && now.getHours() > 12 ? 12 : 0));
|
||||||
|
const minutes = d02(now.getMinutes());
|
||||||
|
const day = d02(now.getDay());
|
||||||
|
const month = d02(now.getMonth() + 1);
|
||||||
|
const year = now.getFullYear();
|
||||||
|
const month2 = locale.month(now, 3);
|
||||||
|
const day2 = locale.dow(now, 3);
|
||||||
|
g.setFontAlign(1, 0).setFont("Vector", 90 * scale);
|
||||||
|
g.drawString(hour, center.x + 32 * scale, center.y - 31 * scale);
|
||||||
|
g.drawString(minutes, center.x + 32 * scale, center.y + 46 * scale);
|
||||||
|
g.fillRect(center.x + 30 * scale, center.y - 72 * scale, center.x + 32 * scale, center.y + 74 * scale);
|
||||||
|
g.setFontAlign(-1, 0).setFont("Vector", 16 * scale);
|
||||||
|
g.drawString(year, center.x + 40 * scale, center.y - 62 * scale);
|
||||||
|
g.drawString(month, center.x + 40 * scale, center.y - 44 * scale);
|
||||||
|
g.drawString(day, center.x + 40 * scale, center.y - 26 * scale);
|
||||||
|
g.drawString(month2, center.x + 40 * scale, center.y + 48 * scale);
|
||||||
|
g.drawString(day2, center.x + 40 * scale, center.y + 66 * scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return {init:drawClock, tick:drawClock, tickpersec:false};
|
||||||
|
}
|
||||||
|
|
||||||
|
return getFace;
|
||||||
|
|
||||||
|
})();
|
||||||
|
|
|
@ -1,41 +0,0 @@
|
||||||
(() => {
|
|
||||||
|
|
||||||
function getFace(){
|
|
||||||
|
|
||||||
function draw() {
|
|
||||||
let steps = "-";
|
|
||||||
let show_steps = false;
|
|
||||||
|
|
||||||
// only attempt to get steps if activepedom is loaded
|
|
||||||
if (WIDGETS.activepedom !== undefined) {
|
|
||||||
steps = WIDGETS.activepedom.getSteps();
|
|
||||||
} else if (WIDGETS.wpedom !== undefined) {
|
|
||||||
steps = WIDGETS.wpedom.getSteps();
|
|
||||||
}
|
|
||||||
|
|
||||||
var d = new Date();
|
|
||||||
var da = d.toString().split(" ");
|
|
||||||
var time = da[4].substr(0,5);
|
|
||||||
|
|
||||||
g.reset();
|
|
||||||
g.clearRect(0,24,239,239);
|
|
||||||
g.setFont("Vector", 80);
|
|
||||||
g.setColor(1,1,1); // white
|
|
||||||
g.setFontAlign(0, -1);
|
|
||||||
g.drawString(time, g.getWidth()/2, 60);
|
|
||||||
g.setColor(0,255,0); // green
|
|
||||||
g.setFont("Vector", 60);
|
|
||||||
g.drawString(steps, g.getWidth()/2, 160);
|
|
||||||
}
|
|
||||||
|
|
||||||
function onSecond(){
|
|
||||||
var t = new Date();
|
|
||||||
if ((t.getSeconds() % 5) === 0) draw();
|
|
||||||
}
|
|
||||||
|
|
||||||
return {init:draw, tick:onSecond};
|
|
||||||
}
|
|
||||||
|
|
||||||
return getFace;
|
|
||||||
|
|
||||||
})();
|
|
|
@ -1,47 +0,0 @@
|
||||||
(() => {
|
|
||||||
var locale = require("locale");
|
|
||||||
var dayFirst = ["en_GB", "en_IN", "en_NAV", "de_DE", "nl_NL", "fr_FR", "en_NZ", "en_AU", "de_AT", "en_IL", "es_ES", "fr_BE", "de_CH", "fr_CH", "it_CH", "it_IT", "tr_TR", "pt_BR", "cs_CZ", "pt_PT"];
|
|
||||||
var withDot = ["de_DE", "nl_NL", "de_AT", "de_CH", "hu_HU", "cs_CZ", "sl_SI"];
|
|
||||||
|
|
||||||
function getFace(){
|
|
||||||
|
|
||||||
var lastmin=-1;
|
|
||||||
function drawClock(){
|
|
||||||
var d=Date();
|
|
||||||
if (d.getMinutes()==lastmin) return;
|
|
||||||
var tm=d.toString().split(' ')[4].substring(0,5);
|
|
||||||
lastmin=d.getMinutes();
|
|
||||||
g.reset();
|
|
||||||
g.clearRect(0,24,239,239);
|
|
||||||
var w=g.getWidth();
|
|
||||||
g.setColor(0xffff);
|
|
||||||
g.setFontVector(80);
|
|
||||||
g.drawString(tm,4+(w-g.stringWidth(tm))/2,64);
|
|
||||||
g.setFontVector(36);
|
|
||||||
g.setColor(0x07ff);
|
|
||||||
var dt=locale.dow(d, 1) + " ";
|
|
||||||
if (dayFirst.includes(locale.name)) {
|
|
||||||
dt+=d.getDate();
|
|
||||||
if (withDot.includes(locale.name)) {
|
|
||||||
dt+=".";
|
|
||||||
}
|
|
||||||
dt+=" " + locale.month(d, 1);
|
|
||||||
} else {
|
|
||||||
dt+=locale.month(d, 1) + " " + d.getDate();
|
|
||||||
}
|
|
||||||
g.drawString(dt,(w-g.stringWidth(dt))/2,160);
|
|
||||||
g.flip();
|
|
||||||
}
|
|
||||||
|
|
||||||
function drawFirst(){
|
|
||||||
lastmin=-1;
|
|
||||||
drawClock();
|
|
||||||
}
|
|
||||||
|
|
||||||
return {init:drawFirst, tick:drawClock};
|
|
||||||
}
|
|
||||||
|
|
||||||
return getFace;
|
|
||||||
|
|
||||||
})();
|
|
||||||
|
|
|
@ -1,8 +1,14 @@
|
||||||
(() => {
|
(() => {
|
||||||
|
|
||||||
function getFace(){
|
function getFace(){
|
||||||
|
|
||||||
function drawTime(d) {
|
|
||||||
|
var W = g.getWidth();
|
||||||
|
var H = g.getHeight();
|
||||||
|
var scale = W/240;
|
||||||
|
var F = 44 * scale;
|
||||||
|
|
||||||
|
function drawTime() {
|
||||||
function convert(n){
|
function convert(n){
|
||||||
var t0 = [" ","one","two","three","four","five","six","seven","eight","nine"];
|
var t0 = [" ","one","two","three","four","five","six","seven","eight","nine"];
|
||||||
var t1 = ["ten","eleven","twelve","thirteen","fourteen","fifteen","sixteen","seventeen","eighteen","nineteen"];
|
var t1 = ["ten","eleven","twelve","thirteen","fourteen","fifteen","sixteen","seventeen","eighteen","nineteen"];
|
||||||
|
@ -13,28 +19,25 @@
|
||||||
return "error";
|
return "error";
|
||||||
}
|
}
|
||||||
g.reset();
|
g.reset();
|
||||||
g.clearRect(0,40,239,210);
|
g.clearRect(0,24,W-1,H-1);
|
||||||
g.setColor(1,1,1);
|
var d = new Date();
|
||||||
|
g.setColor(g.theme.fg);
|
||||||
g.setFontAlign(0,0);
|
g.setFontAlign(0,0);
|
||||||
g.setFont("Vector",44);
|
g.setFont("Vector",44);
|
||||||
var txt = convert(d.getHours());
|
var txt = convert(d.getHours());
|
||||||
g.drawString(txt.top,120,60);
|
g.setColor(g.theme.fg);
|
||||||
g.drawString(txt.bot,120,100);
|
g.drawString(txt.top,W/2,H/2-2*F);
|
||||||
|
g.setColor(g.theme.fg2);
|
||||||
|
g.drawString(txt.bot,W/2,H/2-F);
|
||||||
txt = convert(d.getMinutes());
|
txt = convert(d.getMinutes());
|
||||||
g.drawString(txt.top,120,140);
|
g.setColor(g.theme.fg);
|
||||||
g.drawString(txt.bot,120,180);
|
g.drawString(txt.top,W/2,H/2);
|
||||||
|
g.setColor(g.theme.fg2);
|
||||||
|
g.drawString(txt.bot,W/2,H/2+F);
|
||||||
}
|
}
|
||||||
|
|
||||||
function onSecond(){
|
|
||||||
var t = new Date();
|
|
||||||
if (t.getSeconds() === 0) drawTime(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
function drawAll(){
|
return {init:drawTime, tick:drawTime, tickpersec:false};
|
||||||
drawTime(new Date());
|
|
||||||
}
|
|
||||||
|
|
||||||
return {init:drawAll, tick:onSecond};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return getFace;
|
return getFace;
|
Binary file not shown.
Before Width: | Height: | Size: 51 KiB |
Loading…
Reference in New Issue