barclock: use Layout library

master
Richard de Boer 2021-10-02 16:52:36 +02:00
parent de3feaff45
commit 3401dd99c4
2 changed files with 56 additions and 96 deletions

View File

@ -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

View File

@ -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) {
const t = settings.time;
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; draw = function draw() {
g.setFont(d.font, d.size); if (!Bangle.isLCDOn()) {return;} // no drawing, also no new update scheduled
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();