barclock: use Layout library
parent
de3feaff45
commit
3401dd99c4
|
|
@ -5,4 +5,4 @@
|
||||||
0.05: Clock does not start if app Languages is not installed
|
0.05: Clock does not start if app Languages is not installed
|
||||||
0.06: Improve accuracy
|
0.06: Improve accuracy
|
||||||
0.07: Update to use Bangle.setUI instead of setWatch
|
0.07: Update to use Bangle.setUI instead of setWatch
|
||||||
0.08: Use theme colors
|
0.08: Use theme colors, Layout library
|
||||||
|
|
@ -13,46 +13,48 @@ let locale = require("locale");
|
||||||
locale.dayFirst = /3.*2/.test(localized);
|
locale.dayFirst = /3.*2/.test(localized);
|
||||||
|
|
||||||
locale.hasMeridian = false;
|
locale.hasMeridian = false;
|
||||||
if (typeof locale.meridian==="function") { // function does not exists if languages app is not installed
|
if (typeof locale.meridian==="function") { // function does not exist if languages app is not installed
|
||||||
locale.hasMeridian = (locale.meridian(date)!=="");
|
locale.hasMeridian = (locale.meridian(date)!=="");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
const screen = {
|
Bangle.loadWidgets();
|
||||||
width: g.getWidth(),
|
function renderBar(l) {
|
||||||
height: g.getWidth(),
|
if (!this.fraction) {
|
||||||
middle: g.getWidth()/2,
|
// zero-size fillRect stills draws one line of pixels, we don't want that
|
||||||
center: g.getHeight()/2,
|
return;
|
||||||
};
|
}
|
||||||
|
const width = this.fraction*l.w;
|
||||||
|
g.fillRect(l.x, l.y, width-1, l.y+l.height-1);
|
||||||
|
}
|
||||||
|
|
||||||
// hardcoded "settings"
|
const Layout = require("Layout");
|
||||||
const settings = {
|
const layout = new Layout({
|
||||||
time: {
|
type: "v", c: [
|
||||||
font: "6x8",
|
{
|
||||||
size: (is12Hour && locale.hasMeridian) ? 6 : 8,
|
type: "h", c: [
|
||||||
middle: screen.middle,
|
{id: "time", label: "88:88", type: "txt", font: "6x8:5", bgCol: g.theme.bg}, // size updated below
|
||||||
center: screen.center,
|
{id: "ampm", label: " ", type: "txt", font: "6x8:2", bgCol: g.theme.bg},
|
||||||
ampm: {
|
],
|
||||||
color: -1,
|
|
||||||
font: "6x8",
|
|
||||||
size: 2,
|
|
||||||
},
|
},
|
||||||
},
|
{id: "bar", type: "custom", fraction: 0, fillx: 1, height: 6, col: g.theme.fg2, render: renderBar},
|
||||||
date: {
|
{height: 40},
|
||||||
font: "Vector",
|
{id: "date", type: "txt", font: "10%", valign: 1},
|
||||||
size: 20,
|
],
|
||||||
middle: screen.height-20, // at bottom of screen
|
}, false, {lazy: true});
|
||||||
center: screen.center,
|
// adjustments based on screen size and whether we display am/pm
|
||||||
},
|
let thickness; // bar thickness, same as time font "pixel block" size
|
||||||
bar: {
|
if (is12Hour) {
|
||||||
top: 155, // just below time
|
// Maximum font size = (<screen width> - <ampm: 2chars * (2*6)px>) / (5chars * 6px)
|
||||||
thickness: 6, // matches 24h time "pixel" size
|
thickness = Math.floor((g.getWidth()-24)/(5*6));
|
||||||
},
|
} else {
|
||||||
};
|
layout.ampm.label = "";
|
||||||
|
thickness = Math.floor(g.getWidth()/(5*6));
|
||||||
|
}
|
||||||
|
layout.bar.height = thickness+1;
|
||||||
|
layout.time.font = "6x8:"+thickness;
|
||||||
|
layout.update();
|
||||||
|
|
||||||
const SECONDS_PER_MINUTE = 60;
|
function timeText(date) {
|
||||||
|
|
||||||
const timeText = function(date) {
|
|
||||||
if (!is12Hour) {
|
if (!is12Hour) {
|
||||||
return locale.time(date, true);
|
return locale.time(date, true);
|
||||||
}
|
}
|
||||||
|
|
@ -64,81 +66,39 @@ const timeText = function(date) {
|
||||||
date12.setHours(hours-12);
|
date12.setHours(hours-12);
|
||||||
}
|
}
|
||||||
return locale.time(date12, true);
|
return locale.time(date12, true);
|
||||||
};
|
}
|
||||||
const ampmText = function(date) {
|
function ampmText(date) {
|
||||||
return is12Hour ? locale.meridian(date) : "";
|
return (is12Hour && locale.hasMeridian)? locale.meridian(date) : "";
|
||||||
};
|
}
|
||||||
|
function dateText(date) {
|
||||||
const dateText = function(date) {
|
|
||||||
const dayName = locale.dow(date, true),
|
const dayName = locale.dow(date, true),
|
||||||
month = locale.month(date, true),
|
month = locale.month(date, true),
|
||||||
day = date.getDate();
|
day = date.getDate();
|
||||||
const dayMonth = locale.dayFirst ? `${day} ${month}` : `${month} ${day}`;
|
const dayMonth = locale.dayFirst ? `${day} ${month}` : `${month} ${day}`;
|
||||||
return `${dayName} ${dayMonth}`;
|
return `${dayName} ${dayMonth}`;
|
||||||
};
|
}
|
||||||
|
|
||||||
const drawDateTime = function(date) {
|
draw = function draw() {
|
||||||
const t = settings.time;
|
if (!Bangle.isLCDOn()) {return;} // no drawing, also no new update scheduled
|
||||||
g.setFont(t.font, t.size);
|
|
||||||
g.setFontAlign(0, 0); // centered
|
|
||||||
g.drawString(timeText(date), t.center, t.middle, true);
|
|
||||||
if (is12Hour && locale.hasMeridian) {
|
|
||||||
const a = settings.time.ampm;
|
|
||||||
g.setFont(a.font, a.size);
|
|
||||||
g.setFontAlign(1, -1); // right top
|
|
||||||
// at right edge of screen, aligned with time bottom
|
|
||||||
const left = screen.width-a.size*2,
|
|
||||||
top = t.middle+t.size-a.size;
|
|
||||||
g.drawString(ampmText(date), left, top, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
const d = settings.date;
|
|
||||||
g.setFont(d.font, d.size);
|
|
||||||
g.setFontAlign(0, 0); // centered
|
|
||||||
g.drawString(dateText(date), d.center, d.middle, true);
|
|
||||||
};
|
|
||||||
|
|
||||||
const drawBar = function(date) {
|
|
||||||
const b = settings.bar;
|
|
||||||
const seconds = date.getSeconds();
|
|
||||||
if (seconds===0) {
|
|
||||||
// zero-size rect stills draws one line of pixels, we don't want that
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const fraction = seconds/SECONDS_PER_MINUTE,
|
|
||||||
width = fraction*screen.width;
|
|
||||||
g.setColor(g.theme.fg2).fillRect(0, b.top, width, b.top+b.thickness);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
let lastSeconds;
|
|
||||||
const draw = function(redraw) {
|
|
||||||
if (!Bangle.isLCDOn()) {return;}
|
|
||||||
g.reset();
|
|
||||||
const date = new Date();
|
const date = new Date();
|
||||||
const seconds = date.getSeconds();
|
layout.time.label = timeText(date);
|
||||||
if (redraw||lastSeconds>seconds) {
|
layout.ampm.label = ampmText(date);
|
||||||
// force redraw at start of new minute
|
layout.date.label = dateText(date);
|
||||||
g.clear();
|
const SECONDS_PER_MINUTE = 60;
|
||||||
Bangle.drawWidgets();
|
layout.bar.fraction = date.getSeconds()/SECONDS_PER_MINUTE;
|
||||||
drawDateTime(date);
|
layout.render();
|
||||||
}
|
// schedule update at start of next second
|
||||||
// the bar only gets larger, so drawing on top of the previous one is fine
|
|
||||||
drawBar(date);
|
|
||||||
lastSeconds = seconds;
|
|
||||||
// schedule next update
|
|
||||||
const millis = date.getMilliseconds();
|
const millis = date.getMilliseconds();
|
||||||
setTimeout(draw, 1000-millis);
|
setTimeout(draw, 1000-millis);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
Bangle.loadWidgets();
|
|
||||||
// Show launcher when button pressed
|
// Show launcher when button pressed
|
||||||
Bangle.setUI("clock");
|
Bangle.setUI("clock");
|
||||||
|
|
||||||
Bangle.on("lcdPower", function(on) {
|
Bangle.on("lcdPower", function(on) {
|
||||||
if (on) {
|
if (on) {
|
||||||
draw(true);
|
draw();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
draw(true);
|
g.reset().clear();
|
||||||
|
Bangle.drawWidgets();
|
||||||
|
draw();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue