Merge pull request #3569 from aemkai/master

blc: Updated Binary LED Clock
master
Rob Pilling 2024-09-30 08:42:46 +01:00 committed by GitHub
commit b8fa3b03f2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 263 additions and 129 deletions

View File

@ -1 +1,4 @@
0.10: New app introduced to the app loader!
0.20: skipped (internal revision)
0.30: skipped (internal revision)
0.40: added functionality for customizing colors

View File

@ -9,5 +9,9 @@ From top to bottom the watch face shows four rows of leds:
* day (yellow leds, top row)
* month (yellow leds, bottom row)
As usual, luminous leds represent a logical one, dark leds a logcal '0'.
The colors are default colors and can be changed at the settings page, also, the outer ring can be disabled.
The rightmost LED represents 1, the second 2, the third 4, the next 8 and so on, i.e. values are the powers of two.
As usual, luminous leds represent a logical one, and "dark" leds a logcal '0'. Dark means the color of the background.
Widgets aren't affected and are shown as normal.

View File

@ -2,135 +2,181 @@
{ // must be inside our own scope here so that when we are unloaded everything disappears
// we also define functions using 'let fn = function() {..}' for the same reason. function decls are global
let drawTimeout;
// Actually draw the watch face
let draw = function()
{
// Bangle.js2 -> 176x176
var x_rgt = g.getWidth();
var y_bot = g.getHeight();
//var x_cntr = x_rgt / 2;
var y_cntr = y_bot / 18*7; // not to high because of widget-field (1/3 is to high)
g.reset().clearRect(Bangle.appRect); // clear whole background (w/o widgets)
let white = [1,1,1];
let red = [1,0,0];
let green = [0,1,0];
//let blue = [0,0,1];
let yellow = [1,1,0];
//let magenta = [1,0,1];
//let cyan = [0,1,1];
let black = [0,0,0];
let bord_col = white;
let col_off = black;
var col = new Array(red, green, yellow, yellow); // [R,G,B]
let pot_2 = [1, 2, 4, 8, 16, 32]; // array with powers of two, because power-op (**)
// doesn't work -> maybe also faster
var nr_lines = 4; // 4 rows: hour (hr), minute (min), day (day), month (mon)
// Arrays: [hr, min, day, mon]
//No of Bits: 5 6 5 4
let msbits = [4, 5, 4, 3]; // MSB = No bits - 1
let rad = [12, 12, 8, 8]; // radiuses for each row
var x_dist = 28;
let y_dist = [0, 30, 60, 85]; // y-position from y_centr for each row from top
// don't calc. automatic as for x, because of different spaces
var x_offs_rgt = 16; // distance from right border (layout)
const SETTINGSFILE = "BinaryClk.settings.json";
// Date-Time-Array: 4x6 Bit
//var idx_hr = 0;
//var idx_min = 1;
//var idx_day = 2;
//var idx_mon = 3;
var dt_bit_arr = [[0, 0, 0, 0, 0, 0],[0, 0, 0, 0, 0, 0],[0, 0, 0, 0, 0, 0],[0, 0, 0, 0, 0, 0]];
// variables defined from settings
let HourCol;
let MinCol;
let DayCol;
let MonCol;
let RingOn;
var date_time = new Date();
var hr = date_time.getHours(); // 0..23
var min = date_time.getMinutes(); // 0..59
var day = date_time.getDate(); // 1..31
var mon = date_time.getMonth() + 1; // GetMonth() -> 0..11
// color arrays
// !!! don't change order unless change oder in BinaryClk.settings.js !!!
// !!! order must correspond to each other between arrays !!!
let LED_Colors = ["#FFF", "#F00", "#0F0", "#00F", "#FF0", "#F0F", "#0FF", "#000"];
let LED_ColorNames = ["white", "red", "green", "blue", "yellow", "magenta", "cyan", "black"];
let dt_array = [hr, min, day, mon];
////////////////////////////////////////
// compute bit-pattern from time/date and draw leds
////////////////////////////////////////
var line_cnt = 0;
var cnt = 0;
var bit_cnt = 0;
while (line_cnt < nr_lines)
{
////////////////////////////////////////
// compute bit-pattern
bit_cnt = msbits[line_cnt];
while (bit_cnt >= 0)
{
if (dt_array[line_cnt] >= pot_2[bit_cnt])
{
dt_array[line_cnt] -= pot_2[bit_cnt];
dt_bit_arr[line_cnt][bit_cnt] = 1;
}
else
{
dt_bit_arr[line_cnt][bit_cnt] = 0;
}
bit_cnt--;
}
////////////////////////////////////////
// draw leds (first white border for black screen, then led itself)
cnt = 0;
while (cnt <= msbits[line_cnt])
{
g.setColor(bord_col[0], bord_col[1], bord_col[2]);
g.drawCircle(x_rgt-x_offs_rgt-cnt*x_dist, y_cntr-20+y_dist[line_cnt], rad[line_cnt]);
if (dt_bit_arr[line_cnt][cnt] == 1)
{
g.setColor(col[line_cnt][0], col[line_cnt][1], col[line_cnt][2]);
}
else
{
g.setColor(col_off[0], col_off[1], col_off[2]);
}
g.fillCircle(x_rgt-x_offs_rgt-cnt*x_dist, y_cntr-20+y_dist[line_cnt], rad[line_cnt]-1);
cnt++;
}
line_cnt++;
}
// queue next draw
if (drawTimeout) clearTimeout(drawTimeout);
drawTimeout = setTimeout(function()
// load settings
let loadSettings = function()
{
drawTimeout = undefined;
draw();
}, 60000 - (Date.now() % 60000));
};
function def (value, def) {return value !== undefined ? value : def;}
// Show launcher when middle button pressed
Bangle.setUI(
{
mode : "clock",
remove : function()
{
// Called to unload all of the clock app
if (drawTimeout) clearTimeout(drawTimeout);
drawTimeout = undefined;
var settings = require('Storage').readJSON(SETTINGSFILE, true) || {};
// get name from setting, find index of name and assign corresponding color code by index
HourCol = LED_Colors[LED_ColorNames.indexOf(def(settings.HourCol, "red"))];
MinCol = LED_Colors[LED_ColorNames.indexOf(def(settings.MinCol, "green"))];
DayCol = LED_Colors[LED_ColorNames.indexOf(def(settings.DayCol, "yellow"))];
MonCol = LED_Colors[LED_ColorNames.indexOf(def(settings.MonCol, "yellow"))];
RingOn = def(settings.RingOn, true);
delete settings; // settings in local var -> no more required
}
});
// Load widgets
Bangle.loadWidgets();
draw();
setTimeout(Bangle.drawWidgets,0);
let drawTimeout;
// actually draw the watch face
let draw = function()
{
// Bangle.js2 -> 176x176
var x_rgt = g.getWidth();
var y_bot = g.getHeight();
//var x_cntr = x_rgt / 2;
var y_cntr = y_bot / 18*7;
g.reset().clearRect(Bangle.appRect); // clear whole background (w/o widgets)
var white = "#FFF";
var black = "#000";
var bord_col = white;
var col_off = black;
var col = new Array(HourCol, MinCol, DayCol, MonCol); // each #rgb
if (g.theme.dark)
{
bord_col = white;
col_off = black;
}
else
{
bord_col = black;
col_off = white;
}
let pwr2 = [1, 2, 4, 8, 16, 32]; // array with powers of 2, because poweroperator '**' doesnt work
// maybe also faster
var no_lines = 4; // 4 rows: hour (hr), minute (min), day (day), month (mon)
var no_hour = 5;
var no_min = 6;
var no_day = 5;
var no_mon = 4;
// arrays: [hr, min, day, mon]
let msbits = [no_hour-1, no_min-1, no_day-1, no_mon-1]; // MSB = No bits - 1
let rad = [13, 13, 9, 9]; // radiuses for each row
var x_dist = 29;
let y_dist = [0, 35, 75, 100]; // y-position from y_centr for each row from top
// don't calc. automatic as for x, because of different spaces
var x_offs_rgt = 15; // offset from right border (layout)
var y_offs_cntr = 25; // vertical offset from center
////////////////////////////////////////
// compute bit-pattern from time/date and draw leds
////////////////////////////////////////
// date-time-array: 4x6 bit
//var idx_hour = 0;
//var idx_min = 1;
//var idx_day = 2;
//var idx_mon = 3;
var dt_bit_arr = [[0, 0, 0, 0, 0, 0],[0, 0, 0, 0, 0, 0],[0, 0, 0, 0, 0, 0],[0, 0, 0, 0, 0, 0]];
var date_time = new Date();
var hour = date_time.getHours(); // 0..23
var min = date_time.getMinutes(); // 0..59
var day = date_time.getDate(); // 1..31
var mon = date_time.getMonth() + 1; // GetMonth() -> 0..11
let dt_array = [hour, min, day, mon];
var line_cnt = 0;
var cnt = 0;
var bit_cnt = 0;
while (line_cnt < no_lines)
{
////////////////////////////////////////
// compute bit-pattern
bit_cnt = msbits[line_cnt];
while (bit_cnt >= 0)
{
if (dt_array[line_cnt] >= pwr2[bit_cnt])
{
dt_array[line_cnt] -= pwr2[bit_cnt];
dt_bit_arr[line_cnt][bit_cnt] = 1;
}
else
{
dt_bit_arr[line_cnt][bit_cnt] = 0;
}
bit_cnt--;
}
////////////////////////////////////////
// draw leds (and border, if enabled)
cnt = 0;
while (cnt <= msbits[line_cnt])
{
if (RingOn) // draw outer ring, if enabled
{
g.setColor(bord_col);
g.drawCircle(x_rgt-x_offs_rgt-cnt*x_dist, y_cntr-y_offs_cntr+y_dist[line_cnt], rad[line_cnt]);
}
if (dt_bit_arr[line_cnt][cnt] == 1)
{
g.setColor(col[line_cnt]);
}
else
{
g.setColor(col_off);
}
g.fillCircle(x_rgt-x_offs_rgt-cnt*x_dist, y_cntr-y_offs_cntr+y_dist[line_cnt], rad[line_cnt]-1);
cnt++;
}
line_cnt++;
}
// queue next draw
if (drawTimeout) clearTimeout(drawTimeout);
drawTimeout = setTimeout(function()
{
drawTimeout = undefined;
draw();
}, 60000 - (Date.now() % 60000));
}
// Init the settings of the app
loadSettings();
// Show launcher when middle button pressed
Bangle.setUI(
{
mode : "clock",
remove : function()
{
// Called to unload all of the clock app
if (drawTimeout) clearTimeout(drawTimeout);
drawTimeout = undefined;
}
});
// Load widgets
Bangle.loadWidgets();
draw();
setTimeout(Bangle.drawWidgets,0);
}

72
apps/blc/blc.settings.js Normal file
View File

@ -0,0 +1,72 @@
// Change settings for BinaryClk
(function(back){
// color array -- don't change order unless change oder in BinaryClk.js
let LED_ColorNames = ["white", "red", "green", "blue", "yellow", "magenta", "cyan", "black"];
var FILE = "BinaryClk.settings.json";
// Load settings
var settings = Object.assign({
HourCol: "red",
MinCol: "green",
DayCol: "yellow",
MonCol: "yellow",
RingOn: true,
}, require('Storage').readJSON(FILE, true) || {});
function writeSettings(){
require('Storage').writeJSON(FILE, settings);
}
// Helper method which uses int-based menu item for set of string values
function stringItems(startvalue, writer, 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 => {
writer(values[v]);
writeSettings();
}
};
}
// Helper method which breaks string set settings down to local settings object
function stringInSettings(name, values) {
return stringItems(settings[name], v => settings[name] = v, values);
}
// Show the menu
var mainmenu = {
"" : {
"title" : "BinaryCLK"
},
"< Back" : () => back(),
'Color Hour.:': stringInSettings("HourCol", LED_ColorNames),
'Color Minute:': stringInSettings("MinCol", LED_ColorNames),
'Color Day': stringInSettings("DayCol", LED_ColorNames),
'Color Month:': stringInSettings("MonCol", LED_ColorNames),
'LED ring on/off': {
value: (settings.RingOn !== undefined ? settings.RingOn : true),
onchange: v => {
settings.RingOn = v;
writeSettings();
}
},
};
// Show submenues
//var submenu1 = {
//"": {
// "title": "Show sub1..."
//},
//"< Back": () => E.showMenu(mainmenu),
//"ItemName": stringInSettings("settingsVar", ["Yes", "No", "DontCare"]),
//};
E.showMenu(mainmenu);
});

View File

@ -0,0 +1,7 @@
{
"HourCol": "red",
"MinCol": "green",
"DayCol": "yellow",
"MonCol": "yellow",
"RingOn": true
}

View File

@ -1,10 +1,10 @@
{
"id":"blc",
"name":"Binary LED Clock",
"version": "0.10",
"description": "Binary LED Clock with date",
"version": "0.40",
"description": "a binary LED-Clock with time and date and customizable LED-colors",
"icon":"blc-icon.png",
"screenshots": [{"url":"screenshot_blc.bmp"}],
"screenshots": [{"url":"screenshot_blc_1.bmp"},{"url":"screenshot_blc_2.bmp"}],
"type": "clock",
"tags": "clock",
"supports": ["BANGLEJS2"],
@ -12,6 +12,8 @@
"readme": "README.md",
"storage": [
{"name":"blc.app.js","url":"blc.js"},
{"name":"blc.settings.js","url":"blc.settings.js"},
{"name":"blc.img","url":"blc-icon.js","evaluate":true}
]
],
"data": [{"name":"blc.settings.json"}]
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB