Update to use Bangle.setUI instead of setWatch

pull/765/head
Gordon Williams 2021-06-24 13:12:59 +01:00
parent 0abc0ae213
commit 03ee6aea83
22 changed files with 568 additions and 555 deletions

View File

@ -4,7 +4,7 @@
"tags": "tool,system,b2", "tags": "tool,system,b2",
"type":"bootloader", "type":"bootloader",
"icon": "bootloader.png", "icon": "bootloader.png",
"version":"0.26", "version":"0.27",
"description": "This is needed by Bangle.js to automatically load the clock, menu, widgets and settings", "description": "This is needed by Bangle.js to automatically load the clock, menu, widgets and settings",
"storage": [ "storage": [
{"name":".boot0","url":"boot0.js"}, {"name":".boot0","url":"boot0.js"},
@ -1030,7 +1030,7 @@
{ "id": "bclock", { "id": "bclock",
"name": "Binary Clock", "name": "Binary Clock",
"icon": "clock-binary.png", "icon": "clock-binary.png",
"version":"0.02", "version":"0.03",
"description": "A simple binary clock watch face", "description": "A simple binary clock watch face",
"tags": "clock", "tags": "clock",
"type":"clock", "type":"clock",
@ -1106,9 +1106,9 @@
"name": "Large Digit Blob Clock", "name": "Large Digit Blob Clock",
"shortName" : "Blob Clock", "shortName" : "Blob Clock",
"icon": "clock-blob.png", "icon": "clock-blob.png",
"version":"0.05", "version":"0.06",
"description": "A clock with big digits", "description": "A clock with big digits",
"tags": "clock", "tags": "clock,b2",
"type":"clock", "type":"clock",
"allow_emulator":true, "allow_emulator":true,
"storage": [ "storage": [
@ -1155,7 +1155,7 @@
{ "id": "berlinc", { "id": "berlinc",
"name": "Berlin Clock", "name": "Berlin Clock",
"icon": "berlin-clock.png", "icon": "berlin-clock.png",
"version":"0.03", "version":"0.04",
"description": "Berlin Clock (see https://en.wikipedia.org/wiki/Mengenlehreuhr)", "description": "Berlin Clock (see https://en.wikipedia.org/wiki/Mengenlehreuhr)",
"tags": "clock", "tags": "clock",
"type":"clock", "type":"clock",
@ -1313,7 +1313,7 @@
{ "id": "barclock", { "id": "barclock",
"name": "Bar Clock", "name": "Bar Clock",
"icon": "clock-bar.png", "icon": "clock-bar.png",
"version":"0.06", "version":"0.07",
"description": "A simple digital clock showing seconds as a bar", "description": "A simple digital clock showing seconds as a bar",
"tags": "clock", "tags": "clock",
"type":"clock", "type":"clock",
@ -1572,7 +1572,7 @@
"name": "Numerals Clock", "name": "Numerals Clock",
"shortName": "Numerals Clock", "shortName": "Numerals Clock",
"icon": "numerals.png", "icon": "numerals.png",
"version":"0.08", "version":"0.09",
"description": "A simple big numerals clock", "description": "A simple big numerals clock",
"tags": "numerals,clock", "tags": "numerals,clock",
"type":"clock", "type":"clock",
@ -1986,7 +1986,7 @@
"id": "beebclock", "id": "beebclock",
"name": "Beeb Clock", "name": "Beeb Clock",
"icon": "beebclock.png", "icon": "beebclock.png",
"version":"0.03", "version":"0.04",
"description": "Clock face that may be coincidentally familiar to BBC viewers", "description": "Clock face that may be coincidentally familiar to BBC viewers",
"tags": "clock", "tags": "clock",
"type": "clock", "type": "clock",
@ -2114,7 +2114,7 @@
"name": "Binary Clock", "name": "Binary Clock",
"shortName":"Binary Clock", "shortName":"Binary Clock",
"icon": "app.png", "icon": "app.png",
"version":"0.02", "version":"0.03",
"description": "A binary clock with hours and minutes. BTN1 toggles a digital clock.", "description": "A binary clock with hours and minutes. BTN1 toggles a digital clock.",
"tags": "clock,binary", "tags": "clock,binary",
"type": "clock", "type": "clock",
@ -2755,7 +2755,7 @@
{ "id": "astral", { "id": "astral",
"name": "Astral Clock", "name": "Astral Clock",
"icon": "app-icon.png", "icon": "app-icon.png",
"version":"0.02", "version":"0.03",
"readme": "README.md", "readme": "README.md",
"description": "Clock that calculates and displays Alt Az positions of all planets, Sun as well as several other astronomy targets (customizable) and current Moon phase. Coordinates are calculated by GPS & time and onscreen compass assists orienting. See Readme before using.", "description": "Clock that calculates and displays Alt Az positions of all planets, Sun as well as several other astronomy targets (customizable) and current Moon phase. Coordinates are calculated by GPS & time and onscreen compass assists orienting. See Readme before using.",
"tags": "clock", "tags": "clock",
@ -3223,7 +3223,7 @@
"name": "Bat Clock", "name": "Bat Clock",
"shortName":"Bat Clock", "shortName":"Bat Clock",
"icon": "bat-clock.png", "icon": "bat-clock.png",
"version":"0.01", "version":"0.02",
"description": "Morphing Clock, with an awesome \"The Dark Knight\" themed logo.", "description": "Morphing Clock, with an awesome \"The Dark Knight\" themed logo.",
"tags": "clock", "tags": "clock",
"type": "clock", "type": "clock",
@ -3278,7 +3278,7 @@
{ "id": "mysticdock", { "id": "mysticdock",
"name": "Mystic Dock", "name": "Mystic Dock",
"icon": "mystic-dock.png", "icon": "mystic-dock.png",
"version":"1.0", "version":"1.00",
"description": "A retro-inspired dockface that displays the current time and battery charge while plugged in, and which features an interactive mode that shows the time, date, and a rotating data display line.", "description": "A retro-inspired dockface that displays the current time and battery charge while plugged in, and which features an interactive mode that shows the time, date, and a rotating data display line.",
"tags": "dock", "tags": "dock",
"type":"dock", "type":"dock",

View File

@ -1,2 +1,3 @@
0.01: Create astral clock app 0.01: Create astral clock app
0.02: Fixed Whirlpool galaxy RA/DA, larger compass display, fixed moonphase overlapping battery widget 0.02: Fixed Whirlpool galaxy RA/DA, larger compass display, fixed moonphase overlapping battery widget
0.03: Update to use Bangle.setUI instead of setWatch

View File

@ -796,10 +796,11 @@ Bangle.on('lcdPower', on => {
Bangle.setCompassPower(1); Bangle.setCompassPower(1);
Bangle.setGPSPower(1); Bangle.setGPSPower(1);
// Buttons // Show launcher when button pressed
setWatch(Bangle.showLauncher, BTN2, { repeat: false, edge: "falling" }); Bangle.setClockMode();
setWatch(function () { Bangle.setUI("clockupdown", btn => {
if (btn==0) {
if (!processing) { if (!processing) {
if (!modeswitch) { if (!modeswitch) {
modeswitch = true; modeswitch = true;
@ -809,12 +810,11 @@ setWatch(function () {
else else
modeswitch = false; modeswitch = false;
} }
}, BTN3, { repeat: true }); } else {
setWatch(function () {
if (!processing) if (!processing)
ready_to_compute = true; ready_to_compute = true;
}, BTN1, { repeat: true }); }
});
setWatch(function () { setWatch(function () {
if (!astral_settings.astral_default) { if (!astral_settings.astral_default) {

View File

@ -4,3 +4,4 @@
0.04: Small bugfix 0.04: Small bugfix
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

View File

@ -2,170 +2,168 @@
/** /**
* A simple digital clock showing seconds as a bar * A simple digital clock showing seconds as a bar
**/ **/
{ // Check settings for what type our clock should be
// Check settings for what type our clock should be const is12Hour = (require('Storage').readJSON('setting.json', 1) || {})['12hour']
const is12Hour = (require('Storage').readJSON('setting.json', 1) || {})['12hour'] let locale = require('locale')
let locale = require('locale') { // add some more info to locale
{ // add some more info to locale let date = new Date()
let date = new Date() date.setFullYear(1111)
date.setFullYear(1111) date.setMonth(1, 3) // februari: months are zero-indexed
date.setMonth(1, 3) // februari: months are zero-indexed const localized = locale.date(date, true)
const localized = locale.date(date, true) 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 exists if languages app is not installed
locale.hasMeridian = (locale.meridian(date) !== '') locale.hasMeridian = (locale.meridian(date) !== '')
}
}
const screen = {
width: g.getWidth(),
height: g.getWidth(),
middle: g.getWidth() / 2,
center: g.getHeight() / 2,
} }
// hardcoded "settings" }
const settings = { const screen = {
time: { width: g.getWidth(),
height: g.getWidth(),
middle: g.getWidth() / 2,
center: g.getHeight() / 2,
}
// hardcoded "settings"
const settings = {
time: {
color: -1,
font: '6x8',
size: (is12Hour && locale.hasMeridian) ? 6 : 8,
middle: screen.middle,
center: screen.center,
ampm: {
color: -1, color: -1,
font: '6x8', font: '6x8',
size: (is12Hour && locale.hasMeridian) ? 6 : 8, size: 2,
middle: screen.middle,
center: screen.center,
ampm: {
color: -1,
font: '6x8',
size: 2,
},
}, },
date: { },
color: -1, date: {
font: 'Vector', color: -1,
size: 20, font: 'Vector',
middle: screen.height - 20, // at bottom of screen size: 20,
center: screen.center, middle: screen.height - 20, // at bottom of screen
}, center: screen.center,
bar: { },
color: -1, bar: {
top: 155, // just below time color: -1,
thickness: 6, // matches 24h time "pixel" size top: 155, // just below time
}, thickness: 6, // matches 24h time "pixel" size
} },
const SECONDS_PER_MINUTE = 60
const timeText = function (date) {
if (!is12Hour) {
return locale.time(date, true)
}
const date12 = new Date(date.getTime())
const hours = date12.getHours()
if (hours === 0) {
date12.setHours(12)
} else if (hours > 12) {
date12.setHours(hours - 12)
}
return locale.time(date12, true)
}
const ampmText = function (date) {
return is12Hour ? locale.meridian(date) : ''
}
const dateText = function (date) {
const dayName = locale.dow(date, true),
month = locale.month(date, true),
day = date.getDate()
const dayMonth = locale.dayFirst ? `${day} ${month}` : `${month} ${day}`
return `${dayName} ${dayMonth}`
}
const drawDateTime = function (date) {
const t = settings.time
g.setColor(t.color)
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.setColor(a.color)
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.setColor(d.color)
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(b.color)
g.fillRect(0, b.top, width, b.top + b.thickness)
}
const clearScreen = function () {
g.setColor(0)
const timeTop = settings.time.middle - (settings.time.size * 4)
g.fillRect(0, timeTop, screen.width, screen.height)
}
let lastSeconds, tTick
const tick = function () {
g.reset()
const date = new Date()
const seconds = date.getSeconds()
if (lastSeconds > seconds) {
// new minute
clearScreen()
drawDateTime(date)
}
// 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()
tTick = setTimeout(tick, 1000-millis)
}
const start = function () {
lastSeconds = 99 // force redraw
tick()
}
const stop = function () {
if (tTick) {
clearTimeout(tTick)
tTick = undefined
}
}
// clean app screen
g.clear()
Bangle.loadWidgets()
Bangle.drawWidgets()
// Show launcher when middle button pressed
setWatch(Bangle.showLauncher, BTN2, {repeat: false, edge: 'falling'})
Bangle.on('lcdPower', function (on) {
if (on) {
start()
} else {
stop()
}
})
start()
} }
const SECONDS_PER_MINUTE = 60
const timeText = function (date) {
if (!is12Hour) {
return locale.time(date, true)
}
const date12 = new Date(date.getTime())
const hours = date12.getHours()
if (hours === 0) {
date12.setHours(12)
} else if (hours > 12) {
date12.setHours(hours - 12)
}
return locale.time(date12, true)
}
const ampmText = function (date) {
return is12Hour ? locale.meridian(date) : ''
}
const dateText = function (date) {
const dayName = locale.dow(date, true),
month = locale.month(date, true),
day = date.getDate()
const dayMonth = locale.dayFirst ? `${day} ${month}` : `${month} ${day}`
return `${dayName} ${dayMonth}`
}
const drawDateTime = function (date) {
const t = settings.time
g.setColor(t.color)
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.setColor(a.color)
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.setColor(d.color)
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(b.color)
g.fillRect(0, b.top, width, b.top + b.thickness)
}
const clearScreen = function () {
g.setColor(0)
const timeTop = settings.time.middle - (settings.time.size * 4)
g.fillRect(0, timeTop, screen.width, screen.height)
}
let lastSeconds, tTick
const tick = function () {
g.reset()
const date = new Date()
const seconds = date.getSeconds()
if (lastSeconds > seconds) {
// new minute
clearScreen()
drawDateTime(date)
}
// 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()
tTick = setTimeout(tick, 1000-millis)
}
const start = function () {
lastSeconds = 99 // force redraw
tick()
}
const stop = function () {
if (tTick) {
clearTimeout(tTick)
tTick = undefined
}
}
// clean app screen
g.clear()
Bangle.loadWidgets()
Bangle.drawWidgets()
// Show launcher when button pressed
Bangle.setUI("clock");
Bangle.on('lcdPower', function (on) {
if (on) {
start()
} else {
stop()
}
})
start()

View File

@ -1 +1,2 @@
0.01: App Created! 0.01: App Created!
0.02: Update to use Bangle.setUI instead of setWatch

View File

@ -256,8 +256,5 @@ Bangle.drawWidgets();
timeInterval = setInterval(showTime, 1000); timeInterval = setInterval(showTime, 1000);
showTime(); showTime();
// Show launcher when middle button pressed // Show launcher when button pressed
setWatch(Bangle.showLauncher, BTN2, { Bangle.setUI("clock");
repeat: false,
edge: "falling"
});

View File

@ -1 +1,2 @@
0.02: Modified for use with new bootloader and firmware 0.02: Modified for use with new bootloader and firmware
0.03: Update to use Bangle.setUI instead of setWatch

View File

@ -105,5 +105,5 @@ Bangle.loadWidgets();
Bangle.drawWidgets(); Bangle.drawWidgets();
setInterval(() => { drawClock(); }, 1000); setInterval(() => { drawClock(); }, 1000);
drawClock(); drawClock();
// Show launcher when middle button pressed // Show launcher when button pressed
setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"}); Bangle.setUI("clock");

View File

@ -1,3 +1,4 @@
0.01: Initial commit. Not very efficient, and widgets not working for some reason. 0.01: Initial commit. Not very efficient, and widgets not working for some reason.
0.02: Fixes; widget support 0.02: Fixes; widget support
0.03: Remove hardcoded hour buzz (you can install widchime if you miss it) 0.03: Remove hardcoded hour buzz (you can install widchime if you miss it)
0.04: Update to use Bangle.setUI instead of setWatch

View File

@ -51,341 +51,332 @@ Graphics.prototype.drawRotLine = function (sina, cosa, cx, cy, r1, r2) {
); );
}; };
// Display modes
//
// 0: full-screen
// 1: with widgets
// 2: centred on Bangle (v.1), no widgets or time/date
// 3: centred with time above
// 4: centred with date above
// 5: centred with time and date above
let mode;
(function(g) { // R1, R2: Outer and inner radii of hour marks
// Display modes // RC1, RC2: Outer and inner radii of hub
// // CX, CY: Centre location, relative to buffer (not screen, necessarily)
// 0: full-screen // HW2, MW2: Half-width of hour and minute hand
// 1: with widgets // HR, MR: Length of hour and minute hand, relative to CX,CY
// 2: centred on Bangle (v.1), no widgets or time/date // M: Half-width of gap in hour marks
// 3: centred with time above // HSCALE: Half-width of hour mark as function(0<h<13)
// 4: centred with date above let R1, R2, RC1, RC2, CX, CY, HW2, MW2, HR, MR, M, HSCALE;
// 5: centred with time and date above
let mode;
// R1, R2: Outer and inner radii of hour marks // Screen size
// RC1, RC2: Outer and inner radii of hub const GW = g.getWidth();
// CX, CY: Centre location, relative to buffer (not screen, necessarily) const GH = g.getHeight();
// HW2, MW2: Half-width of hour and minute hand
// HR, MR: Length of hour and minute hand, relative to CX,CY
// M: Half-width of gap in hour marks
// HSCALE: Half-width of hour mark as function(0<h<13)
let R1, R2, RC1, RC2, CX, CY, HW2, MW2, HR, MR, M, HSCALE;
// Screen size // Top margin: the gap taken from the top of the buffer, except when
const GW = g.getWidth(); // in mode 0 (full screen)
const GH = g.getHeight(); let TM;
// Top margin: the gap taken from the top of the buffer, except when // Buffer image. undefined means it needs regenerating
// in mode 0 (full screen) let faceImg;
let TM;
// Buffer image. undefined means it needs regenerating // with_seconds flag determines whether the face is updated every
let faceImg; // second or every minute, and to draw the hand or not.
let with_seconds = true;
// with_seconds flag determines whether the face is updated every // Display flags, determined from `mode` by setMode()
// second or every minute, and to draw the hand or not. let with_widgets = false;
let with_seconds = true; let with_digital_time = true;
let with_digital_date = true;
// Display flags, determined from `mode` by setMode() // Create offscreen buffer for the once-per-minute face draw
let with_widgets = false; const G1 = Graphics.createArrayBuffer(g.getWidth(), g.getHeight(), 1, {msb:true});
let with_digital_time = true;
let with_digital_date = true;
// Create offscreen buffer for the once-per-minute face draw // Precalculate sin/cos for the hour marks. Might be premature
const G1 = Graphics.createArrayBuffer(g.getWidth(), g.getHeight(), 1, {msb:true}); // optimisation, but might as well.
let ss = [], cs = [];
for (let h=1; h<=12; h++) {
const a = Math.PI * h / 6;
ss[h] = Math.sin(a);
cs[h] = Math.cos(a);
}
// Precalculate sin/cos for the hour marks. Might be premature // Draw the face with hour and minute hand. Ideally, we'd separate
// optimisation, but might as well. // the face from the hands and double-buffer, but memory is limited,
let ss = [], cs = []; // so we buffer once and minute, and draw the second hand dynamically
// (with a bit of flicker)
const drawFace = (G) => {
const fw = R1 * 2;
const fh = R1 * 2;
const fw2 = R1;
const fh2 = R1;
let hs = [];
// Wipe the image and start with white
G.clear();
G.setColor(1,1,1);
// Draw the hour marks.
for (let h=1; h<=12; h++) { for (let h=1; h<=12; h++) {
const a = Math.PI * h / 6; hs[h] = HSCALE(h);
ss[h] = Math.sin(a); G.fillRotRect(ss[h], cs[h], CX, CY, -hs[h], hs[h], R2, R1);
cs[h] = Math.cos(a);
} }
// Draw the face with hour and minute hand. Ideally, we'd separate // Draw the hub
// the face from the hands and double-buffer, but memory is limited, G.fillCircle(CX, CY, RC1);
// so we buffer once and minute, and draw the second hand dynamically
// (with a bit of flicker)
const drawFace = (G) => {
const fw = R1 * 2;
const fh = R1 * 2;
const fw2 = R1;
const fh2 = R1;
let hs = [];
// Wipe the image and start with white // Black
G.clear(); G.setColor(0,0,0);
G.setColor(1,1,1);
// Draw the hour marks. // Clear the centre of the hub
for (let h=1; h<=12; h++) { G.fillCircle(CX, CY, RC2);
hs[h] = HSCALE(h);
G.fillRotRect(ss[h], cs[h], CX, CY, -hs[h], hs[h], R2, R1);
// Draw the gap in the hour marks
for (let h=1; h<=12; h++) {
G.fillRotRect(ss[h], cs[h], CX, CY, -M, M, R2-1, R1+1);
}
// Back to white for future draw operations
G.setColor(1,1,1);
// While the buffer remains full-screen, we may trim out the
// bottom of the image so we can shift the whole thing down for
// widgets.
const img = {width:GW,height:GH-TM,buffer:G.buffer};
return img;
};
let hours, minutes, seconds, date;
// Schedule event for calling at the start of the next second
const inOneSecond = (cb) => {
let now = new Date();
clearTimeout();
setTimeout(cb, 1000 - now.getMilliseconds());
};
// Schedule event for calling at the start of the next minute
const inOneMinute = (cb) => {
let now = new Date();
clearTimeout();
setTimeout(cb, 60000 - (now.getSeconds() * 1000 + now.getMilliseconds()));
};
// Draw a fat hour/minute hand
const drawHand = (G, a, w2, r1, r2) =>
G.fillRotRect(Math.sin(a), Math.cos(a), CX, CY, -w2, w2, r1, r2);
// Redraw function
const drawAll = (force) => {
let now = new Date();
if (!faceImg) force = true;
let face_changed = force;
let date_changed = false;
tmp = hours;
hours = now.getHours();
if (tmp !== hours)
face_changed = true;
tmp = minutes;
minutes = now.getMinutes();
if (tmp !== minutes)
face_changed = true;
// If the face has been updated and/or needs a redraw,
// face_changed is true.
let time_changed = face_changed;
// If the screen needs an update, regardless of whether the face
// needs a redraw, time_changed is true.
if (with_seconds) {
// If we're going by second, we always need an update.
seconds = now.getSeconds();
time_changed = true;
}
if (with_digital_date) {
// See if the date has changed. If it has, then we need a
// full-blown redraw of the screen and the face, plus text.
tmp = date;
date = now.getDate();
if (tmp !== date) {
date_changed = true;
face_changed = true; // Should have changed anyway with hour/minute rollover
}
}
if (face_changed) {
// Redraw the face and hands onto the buffer G1.
faceImg = drawFace(G1);
drawHand(G1, Math.PI*hours/6, HW2, RC1, HR);
drawHand(G1, Math.PI*minutes/30, MW2, RC1, MR);
}
// Has the time updated? If so, we'll need to draw something.
if (time_changed) {
// Are we adding text?
if (with_digital_date || with_digital_time) {
// Construct the date/time text to add above the face
let d = now.toString();
let da = d.toString().split(" ");
let txt;
if (with_digital_time) {
txt = da[4].substr(0, 5);
if (with_digital_date)
G1.drawStringDH(txt+',', 24, 0, 'L', GW);
else
G1.drawStringDH(txt, 0, 0, 'C', GW);
}
if (with_digital_date) {
let txt = [da[0], da[1], da[2]].join(" ");
if (with_digital_time)
G1.drawStringDH(txt, -24, 0, 'R', GW);
else
G1.drawStringDH(txt, 0, 0, 'C', GW);
}
} }
// Draw the hub // If the time has updated, we need to _at least_ draw the
G.fillCircle(CX, CY, RC1); // image to the screen.
g.setColor(1,1,1);
// Black g.drawImage({width:GW,
G.setColor(0,0,0); height:GH-TM,
buffer:G1.buffer}, 0, TM);
// Clear the centre of the hub
G.fillCircle(CX, CY, RC2);
// Draw the gap in the hour marks
for (let h=1; h<=12; h++) {
G.fillRotRect(ss[h], cs[h], CX, CY, -M, M, R2-1, R1+1);
}
// Back to white for future draw operations
G.setColor(1,1,1);
// While the buffer remains full-screen, we may trim out the
// bottom of the image so we can shift the whole thing down for
// widgets.
const img = {width:GW,height:GH-TM,buffer:G.buffer};
return img;
};
let hours, minutes, seconds, date;
// Schedule event for calling at the start of the next second
const inOneSecond = (cb) => {
let now = new Date();
clearTimeout();
setTimeout(cb, 1000 - now.getMilliseconds());
};
// Schedule event for calling at the start of the next minute
const inOneMinute = (cb) => {
let now = new Date();
clearTimeout();
setTimeout(cb, 60000 - (now.getSeconds() * 1000 + now.getMilliseconds()));
};
// Draw a fat hour/minute hand
const drawHand = (G, a, w2, r1, r2) =>
G.fillRotRect(Math.sin(a), Math.cos(a), CX, CY, -w2, w2, r1, r2);
// Redraw function
const drawAll = (force) => {
let now = new Date();
if (!faceImg) force = true;
let face_changed = force;
let date_changed = false;
tmp = hours;
hours = now.getHours();
if (tmp !== hours)
face_changed = true;
tmp = minutes;
minutes = now.getMinutes();
if (tmp !== minutes)
face_changed = true;
// If the face has been updated and/or needs a redraw,
// face_changed is true.
let time_changed = face_changed;
// If the screen needs an update, regardless of whether the face
// needs a redraw, time_changed is true.
// and possibly add the second hand
if (with_seconds) { if (with_seconds) {
// If we're going by second, we always need an update. let a = 2.0 * Math.PI * seconds / 60.0;
seconds = now.getSeconds(); g.drawRotLine(Math.sin(a), Math.cos(a), CX, CY+TM, RC1, R1);
time_changed = true;
} }
if (with_digital_date) { // And draw widgets if we're in that mode
// See if the date has changed. If it has, then we need a if (with_widgets)
// full-blown redraw of the screen and the face, plus text. Bangle.drawWidgets();
tmp = date; }
date = now.getDate();
if (tmp !== date) {
date_changed = true;
face_changed = true; // Should have changed anyway with hour/minute rollover
}
}
if (face_changed) { // Schedule to repeat this. A `setTimeout(1000)` isn't good
// Redraw the face and hands onto the buffer G1. // enough, as all the above might've taken some milliseconds and
faceImg = drawFace(G1); // we don't want to drift.
drawHand(G1, Math.PI*hours/6, HW2, RC1, HR); if (with_seconds)
drawHand(G1, Math.PI*minutes/30, MW2, RC1, MR); inOneSecond(drawAll);
} else
inOneMinute(drawAll);
};
// Has the time updated? If so, we'll need to draw something. const setButtons = () => {
if (time_changed) { // Show launcher when button pressed
Bangle.setUI("clockupdown", btn=> {
if (btn==0) changeSeconds();
if (btn==1) { ++mode; setMode(); drawAll(true); }
});
};
// Are we adding text? // Load display parameters based on `mode`
if (with_digital_date || with_digital_time) { const setMode = () => {
// Normalize mode to 0 <= mode <= 5
mode = (6+mode) % 6;
// Construct the date/time text to add above the face // [R1, R2, RC1, RC2, HW2, MW3, HR, MR, M, HSCALE] =
let d = now.toString(); const scales = [
let da = d.toString().split(" "); [120, 84, 17, 12.4, 4.6, 2.2, 8, 2, 1, h => (3.0 + Math.ceil(h/1.5)) ],
let txt; [102, 70, 14.6, 10.7, 3.88, 1.8, 8, 2, 1, h => (2.4 + Math.ceil(h/1.6)) ],
];
if (with_digital_time) { if (mode < 3) {
txt = da[4].substr(0, 5); // Face without time/date text. Might have widgets though.
if (with_digital_date) with_digital_time = with_digital_date = false;
G1.drawStringDH(txt+',', 24, 0, 'L', GW); with_widgets = (mode == 1);
else }
G1.drawStringDH(txt, 0, 0, 'C', GW); else {
} // Face with time/date text, but no widgets
with_digital_time = (mode-2)&1;
with_digital_date = (mode-2)&2;
with_widgets = false;
}
if (with_digital_date) { // Destructure the array to the global display parameters
let txt = [da[0], da[1], da[2]].join(" "); let arr = scales[mode > 0 ? 1 : 0];
if (with_digital_time) R1 = arr[0];
G1.drawStringDH(txt, -24, 0, 'R', GW); R2 = arr[1];
else RC1 = arr[2];
G1.drawStringDH(txt, 0, 0, 'C', GW); RC2 = arr[3];
} HW2 = arr[4];
} MW2 = arr[5];
HR = R2 - arr[6];
MR = R1 - arr[7];
M = arr[8];
HSCALE = arr[9];
TM = with_widgets ? 36 : 0;
// If the time has updated, we need to _at least_ draw the CX = GW/2;
// image to the screen. CY = R1;
g.setColor(1,1,1);
g.drawImage({width:GW,
height:GH-TM,
buffer:G1.buffer}, 0, TM);
// and possibly add the second hand // If we're in the small-face + text regime, we're going to buffer
if (with_seconds) { // the full screen but draw the clock face further down to give
let a = 2.0 * Math.PI * seconds / 60.0; // space for the text.
g.drawRotLine(Math.sin(a), Math.cos(a), CX, CY+TM, RC1, R1); //
} // Compare with modes 0 (full-screen) and 1 (with_widgets==true)
// where the face is drawn at the top of the buffer, but drawn
// lower down the screen (so CY doesn't move)
if (mode > 1) {
CY += 36;
}
// And draw widgets if we're in that mode // We only don't bother redrawing the face from modes 2 to 5, as
if (with_widgets) // they're the same.
Bangle.drawWidgets(); if (!faceImg || mode<3) {
} faceImg = undefined;
}
// Schedule to repeat this. A `setTimeout(1000)` isn't good // Store the settings for next time
// enough, as all the above might've taken some milliseconds and
// we don't want to drift.
if (with_seconds)
inOneSecond(drawAll);
else
inOneMinute(drawAll);
};
const setButtons = () => {
const opts = { repeat: true, edge:'rising', debounce:30};
// BTN1: enable/disable second hand
setWatch(changeSeconds, BTN1, opts);
// BTN2: return to launcher
setWatch(Bangle.showLauncher, BTN2, { repeat:false, edge:'falling' });
// BTN3: change display mode
setWatch(function () { ++mode; setMode(); drawAll(true); }, BTN3, opts);
};
// Load display parameters based on `mode`
const setMode = () => {
// Normalize mode to 0 <= mode <= 5
mode = (6+mode) % 6;
// [R1, R2, RC1, RC2, HW2, MW3, HR, MR, M, HSCALE] =
const scales = [
[120, 84, 17, 12.4, 4.6, 2.2, 8, 2, 1, h => (3.0 + Math.ceil(h/1.5)) ],
[102, 70, 14.6, 10.7, 3.88, 1.8, 8, 2, 1, h => (2.4 + Math.ceil(h/1.6)) ],
];
if (mode < 3) {
// Face without time/date text. Might have widgets though.
with_digital_time = with_digital_date = false;
with_widgets = (mode == 1);
}
else {
// Face with time/date text, but no widgets
with_digital_time = (mode-2)&1;
with_digital_date = (mode-2)&2;
with_widgets = false;
}
// Destructure the array to the global display parameters
let arr = scales[mode > 0 ? 1 : 0];
R1 = arr[0];
R2 = arr[1];
RC1 = arr[2];
RC2 = arr[3];
HW2 = arr[4];
MW2 = arr[5];
HR = R2 - arr[6];
MR = R1 - arr[7];
M = arr[8];
HSCALE = arr[9];
TM = with_widgets ? 36 : 0;
CX = GW/2;
CY = R1;
// If we're in the small-face + text regime, we're going to buffer
// the full screen but draw the clock face further down to give
// space for the text.
//
// Compare with modes 0 (full-screen) and 1 (with_widgets==true)
// where the face is drawn at the top of the buffer, but drawn
// lower down the screen (so CY doesn't move)
if (mode > 1) {
CY += 36;
}
// We only don't bother redrawing the face from modes 2 to 5, as
// they're the same.
if (!faceImg || mode<3) {
faceImg = undefined;
}
// Store the settings for next time
try {
storage.writeJSON(filename, [mode,with_seconds]);
} catch (e) {
console.log(e);
}
// Clear the screen: we need to make sure all parts are cleaned off.
g.clear();
};
const changeSeconds = () => {
with_seconds = !with_seconds;
drawAll(true);
};
Bangle.loadWidgets();
// Restore mode
try { try {
conf = storage.readJSON(filename); storage.writeJSON(filename, [mode,with_seconds]);
mode = conf[0];
with_seconds = conf[1];
} catch (e) { } catch (e) {
console.log(e); console.log(e);
mode = 1;
} }
setButtons(); // Clear the screen: we need to make sure all parts are cleaned off.
setMode(); g.clear();
drawAll(); };
Bangle.on('lcdPower', (on) => { const changeSeconds = () => {
if (on) { with_seconds = !with_seconds;
Bangle.loadWidgets(); drawAll(true);
Bangle.drawWidgets(); };
drawAll();
} else {
clearTimeout();
}
});
})(g); Bangle.loadWidgets();
// Restore mode
try {
conf = storage.readJSON(filename);
mode = conf[0];
with_seconds = conf[1];
} catch (e) {
console.log(e);
mode = 1;
}
setButtons();
setMode();
drawAll();
Bangle.on('lcdPower', (on) => {
if (on) {
Bangle.loadWidgets();
Bangle.drawWidgets();
drawAll();
} else {
clearTimeout();
}
});

View File

@ -1,2 +1,3 @@
0.02: Modified for use with new bootloader and firmware 0.02: Modified for use with new bootloader and firmware
0.03: Shrinked size to avoid cut-off edges on the physical device. BTN3: show date. BTN1: show time in decimal. 0.03: Shrinked size to avoid cut-off edges on the physical device. BTN3: show date. BTN1: show time in decimal.
0.04: Update to use Bangle.setUI instead of setWatch

View File

@ -100,9 +100,11 @@ g.clear();
Bangle.loadWidgets(); Bangle.loadWidgets();
Bangle.drawWidgets(); Bangle.drawWidgets();
drawBerlinClock(); drawBerlinClock();
// Toggle date display, when BTN3 is pressed if (BTN3) {
setWatch(toggleTime,BTN1, { repeat : true, edge: "falling"}); // Toggle date display, when BTN3 is pressed
// Toggle date display, when BTN3 is pressed setWatch(toggleTime,BTN1, { repeat : true, edge: "falling"});
setWatch(toggleDate,BTN3, { repeat : true, edge: "falling"}); // Toggle date display, when BTN3 is pressed
// Show launcher when middle button pressed setWatch(toggleDate,BTN3, { repeat : true, edge: "falling"});
setWatch(Bangle.showLauncher, BTN2, { repeat: false, edge: "falling" }); }
// Show launcher when button pressed
Bangle.setUI("clock");

View File

@ -1,2 +1,3 @@
0.01: New App! 0.01: New App!
0.02: Fixed bug where screen didn't clear so incorrect time displayed. 0.02: Fixed bug where screen didn't clear so incorrect time displayed.
0.03: Update to use Bangle.setUI instead of setWatch

View File

@ -167,12 +167,12 @@ Bangle.on('lcdPower',on=>{
// Load widgets // Load widgets
Bangle.loadWidgets(); Bangle.loadWidgets();
Bangle.drawWidgets(); Bangle.drawWidgets();
// Show launcher when middle button pressed // Show launcher when button pressed
setWatch(Bangle.showLauncher, BTN2, { repeat: false, edge: "falling" }); Bangle.setUI("clockupdown", btn=>{
setWatch(function() { if (btn!=1) return;
if(displayTime == 0){ if(displayTime == 0){
displayTime = 1; displayTime = 1;
} else{ } else{
displayTime = 0; displayTime = 0;
} }
}, BTN, {edge:"rising", debounce:50, repeat:true}); });

View File

@ -4,3 +4,4 @@
0.03: Modified for use with new bootloader and firmware 0.03: Modified for use with new bootloader and firmware
0.04: Modified to account for changes in the behavior of Graphics.fillPoly 0.04: Modified to account for changes in the behavior of Graphics.fillPoly
0.05: Slight increase to draw speed after LCD on 0.05: Slight increase to draw speed after LCD on
0.06: Update to use Bangle.setUI instead of setWatch, allow themes and different size screens

View File

@ -1,4 +1,6 @@
const buf = Graphics.createArrayBuffer(144,200,1,{msb:true}); let big = g.getHeight() > 200;
const buf = Graphics.createArrayBuffer(big ? 144 : 120, big ? 180 : 150,1,{msb:true});
// TODO: convert these to Polys -> much faster and cleaner!
const NUMBERS = [ const NUMBERS = [
[1,1,1,1,3,1,1,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1],//0 [1,1,1,1,3,1,1,0,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1],//0
[0,1,1,1,3,0,0,1,1,1,0,0,1,1,1,0,0,1,1,1,0,0,1,1,1],//1 [0,1,1,1,3,0,0,1,1,1,0,0,1,1,1,0,0,1,1,1,0,0,1,1,1],//1
@ -14,8 +16,10 @@ const NUMBERS = [
let intervalRef = null; let intervalRef = null;
let digits = [-1,-1,-1,-1,-1,-1]; let digits = [-1,-1,-1,-1,-1,-1];
function flip() { function flip() {
g.setColor(1,1,1); g.reset();
g.drawImage({width:buf.getWidth(),height:buf.getHeight(),buffer:buf.buffer},55,26); g.drawImage({width:buf.getWidth(),height:buf.getHeight(),buffer:buf.buffer},
(g.getWidth() - buf.getWidth())/2,
26 + (g.getHeight() - (buf.getHeight()+24))/2);
} }
function drawPixel(ox,oy,x,y,r,p) { function drawPixel(ox,oy,x,y,r,p) {
let x1 = ox+x*(r*2); let x1 = ox+x*(r*2);
@ -53,26 +57,31 @@ function redraw() {
let newDigits = [Math.floor(hours/10),hours%10,Math.floor(mins/10),mins%10,Math.floor(secs/10),secs%10]; let newDigits = [Math.floor(hours/10),hours%10,Math.floor(mins/10),mins%10,Math.floor(secs/10),secs%10];
let s = big?6:5; // size of main digits
let y2 = big?72:55;
let y3 = big?144:110;
for (var p = 0;p<25;p++) { for (var p = 0;p<25;p++) {
var px = p%5; var px = p%5;
var py = Math.floor(p/5); var py = Math.floor(p/5);
if (digits[0] === -1 || NUMBERS[newDigits[0]][p] !== NUMBERS[digits[0]][p] ) { if (digits[0] === -1 || NUMBERS[newDigits[0]][p] !== NUMBERS[digits[0]][p] ) {
drawPixel(0,20,px,py,6,NUMBERS[newDigits[0]][p]); drawPixel(0,0,px,py,s,NUMBERS[newDigits[0]][p]);
} }
if (digits[1] === -1 || NUMBERS[newDigits[1]][p] !== NUMBERS[digits[1]][p] ) { if (digits[1] === -1 || NUMBERS[newDigits[1]][p] !== NUMBERS[digits[1]][p] ) {
drawPixel(78,20,px,py,6,NUMBERS[newDigits[1]][p]); drawPixel(13*s,0,px,py,s,NUMBERS[newDigits[1]][p]);
} }
if (digits[2] === -1 || NUMBERS[newDigits[2]][p] !== NUMBERS[digits[2]][p] ) { if (digits[2] === -1 || NUMBERS[newDigits[2]][p] !== NUMBERS[digits[2]][p] ) {
drawPixel(0,92,px,py,6,NUMBERS[newDigits[2]][p]); drawPixel(0,y2,px,py,s,NUMBERS[newDigits[2]][p]);
} }
if (digits[3] === -1 || NUMBERS[newDigits[3]][p] !== NUMBERS[digits[3]][p] ) { if (digits[3] === -1 || NUMBERS[newDigits[3]][p] !== NUMBERS[digits[3]][p] ) {
drawPixel(78,92,px,py,6,NUMBERS[newDigits[3]][p]); drawPixel(13*s,y2,px,py,s,NUMBERS[newDigits[3]][p]);
} }
if (digits[4] === -1 || NUMBERS[newDigits[4]][p] !== NUMBERS[digits[4]][p] ) { if (digits[4] === -1 || NUMBERS[newDigits[4]][p] !== NUMBERS[digits[4]][p] ) {
drawPixel(69,164,px,py,3,NUMBERS[newDigits[4]][p]); drawPixel(17*s - 3*12,y3,px,py,3,NUMBERS[newDigits[4]][p]);
} }
if (digits[5] === -1 || NUMBERS[newDigits[5]][p] !== NUMBERS[digits[5]][p] ) { if (digits[5] === -1 || NUMBERS[newDigits[5]][p] !== NUMBERS[digits[5]][p] ) {
drawPixel(108,164,px,py,3,NUMBERS[newDigits[5]][p]); drawPixel(17*s,y3,px,py,3,NUMBERS[newDigits[5]][p]);
} }
} }
digits = newDigits; digits = newDigits;
@ -99,5 +108,5 @@ Bangle.on('lcdPower',function(on) {
clearTimers(); clearTimers();
} }
}); });
// Show launcher when middle button pressed // Show launcher when button pressed
setWatch(Bangle.showLauncher, BTN2, {repeat:false,edge:"falling"}); Bangle.setUI("clock");

View File

@ -25,3 +25,4 @@
0.24: Add Bangle.setUI polyfill 0.24: Add Bangle.setUI polyfill
0.25: Fix error in 'no clock app' message 0.25: Fix error in 'no clock app' message
0.26: Remove buzz in setUI polyfill (#750) 0.26: Remove buzz in setUI polyfill (#750)
0.27: Update polyfill for most recent changes

View File

@ -3,6 +3,7 @@ recalculates, but this avoids us doing a whole bunch of reconfiguration most
of the time. */ of the time. */
E.showMessage("Updating boot0..."); E.showMessage("Updating boot0...");
var s = require('Storage').readJSON('setting.json',1)||{}; var s = require('Storage').readJSON('setting.json',1)||{};
var isB2 = process.env.HWVERSION; // Is Bangle.js 2
var boot = ""; var boot = "";
var CRC = E.CRC32(require('Storage').read('setting.json'))+E.CRC32(require('Storage').list(/\.boot\.js/)); var CRC = E.CRC32(require('Storage').read('setting.json'))+E.CRC32(require('Storage').list(/\.boot\.js/));
boot += `if (E.CRC32(require('Storage').read('setting.json'))+E.CRC32(require('Storage').list(/\.boot\.js/))!=${CRC}) { eval(require('Storage').read('bootupdate.js'));} else {\n`; boot += `if (E.CRC32(require('Storage').read('setting.json'))+E.CRC32(require('Storage').list(/\.boot\.js/))!=${CRC}) { eval(require('Storage').read('bootupdate.js'));} else {\n`;
@ -81,9 +82,9 @@ if (s.passkey!==undefined && s.passkey.length==6) boot+=`NRF.setSecurity({passke
if (s.whitelist) boot+=`NRF.on('connect', function(addr) { if (!(require('Storage').readJSON('setting.json',1)||{}).whitelist.includes(addr)) NRF.disconnect(); });\n`; if (s.whitelist) boot+=`NRF.on('connect', function(addr) { if (!(require('Storage').readJSON('setting.json',1)||{}).whitelist.includes(addr)) NRF.disconnect(); });\n`;
// Pre-2v10 firmwares without a theme/setUI // Pre-2v10 firmwares without a theme/setUI
if (!g.theme) { if (!g.theme) {
boot += `g.theme={fg:-1,bg:0,fg2:-1,bg2:7,fgH:-1,bgH:0x02F7};\n`; boot += `g.theme={fg:-1,bg:0,fg2:-1,bg2:7,fgH:-1,bgH:0x02F7,dark:true};\n`;
} }
if (!Bangle.setUI) { if (!Bangle.setUI) { // assume this is just for F18 - Q3 should already have it
boot += `Bangle.setUI=function(mode, cb) { boot += `Bangle.setUI=function(mode, cb) {
if (Bangle.btnWatches) { if (Bangle.btnWatches) {
Bangle.btnWatches.forEach(clearWatch); Bangle.btnWatches.forEach(clearWatch);
@ -114,6 +115,18 @@ else if (mode=="updown") {
Bangle.on("swipe", Bangle.swipeHandler); Bangle.on("swipe", Bangle.swipeHandler);
Bangle.touchHandler = d => {cb();}; Bangle.touchHandler = d => {cb();};
Bangle.on("touch", Bangle.touchHandler); Bangle.on("touch", Bangle.touchHandler);
} else if (mode=="clock") {
Bangle.CLOCK=1;
Bangle.btnWatches = [
setWatch(Bangle.showLauncher, BTN2, {repeat:1,edge:"falling"})
];
} else if (mode=="clockupdown") {
Bangle.CLOCK=1;
Bangle.btnWatches = [
setWatch(function() { cb(-1); }, BTN1, {repeat:1}),
setWatch(function() { cb(1); }, BTN3, {repeat:1}),
setWatch(Bangle.showLauncher, BTN2, {repeat:1,edge:"falling"})
];
} else } else
throw new Error("Unknown UI mode"); throw new Error("Unknown UI mode");
};\n`; };\n`;

View File

@ -6,3 +6,4 @@
0.06: Improve rendering of Numeral 1, fix issue with alarms not showing up 0.06: Improve rendering of Numeral 1, fix issue with alarms not showing up
0.07: Add date on touch and some improvements (see settings and readme) 0.07: Add date on touch and some improvements (see settings and readme)
0.08: Add new draw styles, tidy up draw functionality 0.08: Add new draw styles, tidy up draw functionality
0.09: Tweak for faster rendering

View File

@ -22,16 +22,17 @@ var _12hour = (require("Storage").readJSON("setting.json",1)||{})["12hour"]||fal
var _hCol = ["#ff5555","#ffff00","#FF9901","#2F00FF"]; var _hCol = ["#ff5555","#ffff00","#FF9901","#2F00FF"];
var _mCol = ["#55ff55","#ffffff","#00EFEF","#FFBF00"]; var _mCol = ["#55ff55","#ffffff","#00EFEF","#FFBF00"];
var _rCol = 0; var _rCol = 0;
var scale = g.getWidth()/240;
var interval = 0; var interval = 0;
const REFRESH_RATE = 10E3; const REFRESH_RATE = 10E3;
var drawFuncs = { var drawFuncs = {
fill : function(poly,isHole){ fill : function(poly,isHole){
if (isHole) g.setColor(0); if (isHole) g.setColor(g.theme.bg);
g.fillPoly(poly,true); g.fillPoly(poly,true);
}, },
framefill : function(poly,isHole){ framefill : function(poly,isHole){
var c = g.getColor(); var c = g.getColor();
g.setColor(isHole ? 0 : ((c&0b1111011111011110)>>1)); // 16 bit half bright g.setColor(isHole ? g.theme.bg : ((c&0b1111011111011110)>>1)); // 16 bit half bright
g.fillPoly(poly,true); g.fillPoly(poly,true);
g.setColor(c); g.setColor(c);
g.drawPoly(poly,true); g.drawPoly(poly,true);
@ -48,7 +49,8 @@ var drawFuncs = {
}; };
function translate(tx, ty, p){ function translate(tx, ty, p){
return p.map((x, i)=> x+((i&1)?ty:tx)); //return p.map((x, i)=> x+((i&1)?ty:tx));
return g.transformVertices(p, {x:tx,y:ty,scale:scale});
} }
@ -57,15 +59,14 @@ if (!settings) {
settings = { settings = {
color:0, color:0,
drawMode:"fill", drawMode:"fill",
menuButton:24,
showDate:0 showDate:0
}; };
} }
function drawNum(num,col,x,y,func,funcName){ function drawNum(num,col,x,y,func,funcName){
g.setColor(col); g.setColor(col);
let tx = x*100+25; let tx = (x*100+25) * scale;
let ty = y*104+32; let ty = (y*104+32) * scale;
for (let i=0;i<numerals[num].length;i++){ for (let i=0;i<numerals[num].length;i++){
g.setColor(col); g.setColor(col);
func(translate(tx,ty,numerals[num][i]), i>0); func(translate(tx,ty,numerals[num][i]), i>0);
@ -98,9 +99,9 @@ function setUpdateInt(set){
if (set) interval=setInterval(draw, REFRESH_RATE); if (set) interval=setInterval(draw, REFRESH_RATE);
} }
Bangle.setLCDMode(); g.clear(1);
g.reset().clear(); // Show launcher when button pressed
setWatch(Bangle.showLauncher, settings.menuButton, {repeat:false,edge:"falling"}); Bangle.setUI("clock");
if (settings.color>0) _rCol=settings.color-1; if (settings.color>0) _rCol=settings.color-1;
setUpdateInt(1); setUpdateInt(1);
draw(); draw();

View File

@ -6,14 +6,12 @@
numeralsSettings = { numeralsSettings = {
color:0, color:0,
drawMode:"fill", drawMode:"fill",
menuButton:22,
showDate:0 showDate:0
}; };
updateSettings(); updateSettings();
} }
let numeralsSettings = storage.readJSON('numerals.json',1); let numeralsSettings = storage.readJSON('numerals.json',1);
if (!numeralsSettings) resetSettings(); if (!numeralsSettings) resetSettings();
if (numeralsSettings.menuButton===undefined) numeralsSettings.menuButton=22;
let dm = ["fill","frame","framefill","thickframe"]; let dm = ["fill","frame","framefill","thickframe"];
let col = ["rnd","r/g","y/w","o/c","b/y"]; let col = ["rnd","r/g","y/w","o/c","b/y"];
let btn = [[24,"BTN1"],[22,"BTN2"],[23,"BTN3"],[11,"BTN4"],[16,"BTN5"]]; let btn = [[24,"BTN1"],[22,"BTN2"],[23,"BTN3"],[11,"BTN4"],[16,"BTN5"]];
@ -31,12 +29,6 @@
format: v=>dm[v], format: v=>dm[v],
onchange: v=> { numeralsSettings.drawMode=dm[v]; updateSettings();} onchange: v=> { numeralsSettings.drawMode=dm[v]; updateSettings();}
}, },
"Menu button": {
value: btn.findIndex(e=>e[0]==numeralsSettings.menuButton),
min:0,max:btn.length-1,
format: v=>btn[v][1],
onchange: v=> { numeralsSettings.menuButton=btn[v][0]; updateSettings();}
},
"Date on touch": { "Date on touch": {
value: 0|numeralsSettings.showDate, value: 0|numeralsSettings.showDate,
min:0,max:1, min:0,max:1,