Merge pull request #1703 from Ronin0000-Github-Bangle-js-Fork-2/master

LCARS clock custom theming
pull/1719/head
Gordon Williams 2022-04-20 10:30:37 +01:00 committed by GitHub
commit 810624d1f8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 116 additions and 36 deletions

View File

@ -17,4 +17,5 @@
0.17: Settings for mph/kph and other minor improvements.
0.18: Fullscreen mode can now be enabled or disabled in the settings.
0.19: Alarms can not go bigger than 100.
0.20: Use alarm for alarm functionality instead of own implementation.
0.20: Use alarm for alarm functionality instead of own implementation.
0.21: Add custom theming.

View File

@ -19,6 +19,7 @@ the "sched" app must be installed on your device.
* Tap on top/bottom of screen 1 to activate an alarm. Depends on widtmr.
* The lower orange line indicates the battery level.
* Display graphs (day or month) for steps + hrm on the second screen.
* Customizable theming colors in the settings menu of the app.
## Data that can be configured
* Steps - Steps loaded via the wpedom app.
@ -43,3 +44,4 @@ Access different screens via tap on the left/ right side of the screen
## Contributors
- [Adam Schmalhofer](https://github.com/adamschmalhofer)
- [Jon Warrington](https://github.com/BartokW)
- [Ronin Stegner](https://github.com/Ronin0000)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 795 B

After

Width:  |  Height:  |  Size: 789 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 772 B

After

Width:  |  Height:  |  Size: 760 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 791 B

After

Width:  |  Height:  |  Size: 771 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 769 B

After

Width:  |  Height:  |  Size: 742 B

View File

@ -1,7 +1,6 @@
const TIMER_IDX = "lcars";
const SETTINGS_FILE = "lcars.setting.json";
const locale = require('locale');
const storage = require('Storage');
const storage = require('Storage')
let settings = {
alarm: -1,
dataRow1: "Steps",
@ -9,6 +8,9 @@ let settings = {
dataRow3: "Battery",
speed: "kph",
fullscreen: false,
themeColor1BG: "#FF9900",
themeColor2BG: "#FF00DC",
themeColor3BG: "#0094FF",
};
let saved_settings = storage.readJSON(SETTINGS_FILE, 1) || settings;
for (const key in saved_settings) {
@ -18,9 +20,9 @@ for (const key in saved_settings) {
/*
* Colors to use
*/
let cBlue = "#0094FF";
let cOrange = "#FF9900";
let cPurple = "#FF00DC";
let color1 = settings.themeColor3BG;
let color2 = settings.themeColor1BG;
let color3 = settings.themeColor2BG;
let cWhite = "#FFFFFF";
let cBlack = "#000000";
let cGrey = "#424242";
@ -33,33 +35,77 @@ let lcarsViewPos = 0;
var plotMonth = false;
/*
* Requirements and globals
*/
function convert24to16(input)
{
let RGB888 = parseInt(input.replace(/^#/, ''), 16);
let r = (RGB888 & 0xFF0000) >> 16;
let g = (RGB888 & 0xFF00) >> 8;
let b = RGB888 & 0xFF;
r = (r * 249 + 1014) >> 11;
g = (g * 253 + 505) >> 10;
b = (b * 249 + 1014) >> 11;
let RGB565 = 0;
RGB565 = RGB565 | (r << 11);
RGB565 = RGB565 | (g << 5);
RGB565 = RGB565 | b;
return "0x"+RGB565.toString(16);
}
var color1C = convert24to16(color1);
var color2C = convert24to16(color2);
var color3C = convert24to16(color3);
/*
* Requirements and globals
*/
var colorPalette = new Uint16Array([
0x0000, // not used
color2C, // second
color3C, // third
0x0000, // not used
color1C, // first
0x0000, // not used
0x0000, // not used
0x0000, // not used
0x0000, // not used
0x0000, // not used
0x0000, // not used
0x0000, // not used
0x0000, // not used
0x0000, // not used
0x0000, // not used
0x0000 // not used
],0,1);
var bgLeftFullscreen = {
width : 27, height : 176, bpp : 3,
transparent : 0,
buffer : require("heatshrink").decompress(atob("AAUM2XLlgCCwAJBBAuy4EAmQIF5cggAIGlmwgYIG2XIF42wF4ImGF4ImHJoQmGJoQdJhZNHNY47CgRNGBIJZHHgRiGBIRQ/KH5QCAFCh/eX5Q/KAwdCAGVbtu27YCCoAJBkuWrNlAQRGCiwRDAQPQBIMJCIYCBsAJBgomEtu0WoQmEy1YBIMBHYttIwQ7FyxQ/KHFlFAQ7F2weCHYplKChRTCCg5TCHw5TMAD0GzVp0wCCBBGaBIMaBAtpwECBA2mwEJBAugDgMmCIwJBF5EABAtoeQQvGCYQdPJoI7LMQzTCLJKAGzAJBO4xQ/KGQA8UP7y/KH5QnAHih/eX5Q/GQ4JCGRJlKCgxTDBAwgCCg5TCHwxTCNA4A=="))
buffer : require("heatshrink").decompress((atob("/4AB+VJkmSAQV///+BAtJn//5IIFkmf/4IGyVP/gIGpMnF41PHIImGF4ImHJoQmGJoIdK8hNHNY47C/JNGBIJZGyYJBQA5GCKH5Q/KAQAoUP7y/KH5QGDoQAy0hGF34JB6RGFr4JB9JkFl4JB+gdFy4JB/QdFpYJB/odFkqrCS4xGCWoyDCKH5Q1GShlJChQLCCg5TCHw5TMAD35FAoIIkgJB8hGGv/8Mg8/+QIFp4cB5IRGBIIvI/4IFybyCF4wTCDp5NBHZZiGz4JBLJKAGk4JBO4xQ/KGQA8UP7y/KH5QnAHih/eX5Q/GQ4JCGRJlKCgxTDBAwgCCg5TCHwxTCNA4"))),
palette: colorPalette
};
var bgLeftNotFullscreen = {
width : 27, height : 152, bpp : 3,
transparent : 0,
buffer : require("heatshrink").decompress(atob("AAUM2XLlgCCwAJBBAuy4EAmQIF5cggAIGlmwgYIG2XIF42wF4ImGF4ImHJoQmGJoQdJhZNHNY47CgRNGBIJZHHgRiGBIRQ/KH5QCAGVbtu27YCCoAJBkuWrNlAQRkCiwRDAQPQBIMJCIYCBsAJBgomEtu0WoQmEy1YBIMBHYttIwQ7FyxQ/KHFlFAQ7F2weCHYplKChRTCCg5TCHw5TMAD0GzVp0wCCBBGaBIMaBAtpwECBA2mwEJBAugDgMmCIwJBF5EABAtoeQQvGCYQdPJoI7LMQzTCLJKAGzAJBO4xQ/KGQA8UP7y/KH5QnAHih/eX5Q/GQ4JCGRJlKCgxTDBAwgCCg5TCHwxTCNA4A="))
buffer : require("heatshrink").decompress((atob("/4AB+VJkmSAQV///+BAtJn//5IIFkmf/4IGyVP/gIGpMnF41PHIImGF4ImHJoQmGJoIdK8hNHNY47C/JNGBIJZGyYJBQA5GCKH5Q/KAQAy0hGF34JB6RGFr4JB9JkFl4JB+gdFy4JB/QdFpYJB/odFkqrCS4xGCWoyhCKH5Q1GShlJChQLCCg5TCHw5TMAD35FAoIIkgJB8hGGv/8Mg8/+QIFp4cB5IRGBIIvI/4IFybyCF4wTCDp5NBHZZiGz4JBLJKAGk4JBO4xQ/KGQA8UP7y/KH5QnAHih/eX5Q/GQ4JCGRJlKCgxTDBAwgCCg5TCHwxTCNA4A=="))),
palette: colorPalette
};
var bgRightFullscreen = {
width : 27, height : 176, bpp : 3,
transparent : 0,
buffer : require("heatshrink").decompress(atob("lmy5YCDBIUyBAmy5AJBhYUG2EAhgIFAQMAgQIGCgQABCg4ABEAwUNFI2AKZHAKZEgGRZTGOIUDQxJxGKH5Q/agwAnUP7y/KH4yGeVYAJrdt23bAQVABIMly1ZsoCCMgUWCIYCB6AJBhIRDAQNgBIMFEwlt2i1CEwmWrAJBgI7FtpGCHYuWKH5QxEwpQDlo7F0A7IqBZBEwo7BCIwCBJo53CJoxiCJpIAdgOmzVpAQR/CgAIEAQJ2CBAoCBBIMmCg1oD4QLGFQUCCjQ+CKYw+CKY4JCKYwoCGRMaGREJDoroCgwdFzBlLKH5QvAHih/eX5Q/KE4A8UP7y/KH5QGDpg7HJoxZCCIx3CJowmCF4yACJox/CgAA="))
buffer : require("heatshrink").decompress((atob("yVJkgCCyf/AAPJBAYCBk4JB8gUFyVP//yBAoCB//5BAwUCAAIUHAAIgGChopGv5TIn5TIz4yLKYxxC/iGI/xxGKH5Q/agwAnUP7y/KH4yGeVYAJ0hGF34JB6RGFr4JB9JkFl4JB+gdFy4JB/QdFpYJB/odFkp4CS4xGCWoyhCKH5QuDoxQCDpI7GDoJZGHYIRGLIQvGO4QvGMQRNJADv+GIqTC/5PGz4JBJ41JBIPJCg2TD4QLGn4JB/gUaHwRTGHwRTHBIRTGNAQyJ8gyI+QdFp4JB/IdFk5lLKH5QvAHih/eX5Q/KE4A8UP7y/KH5QGDpg7HJoxZCCIx3CJowmCF4yACJoyJC/4A=="))),
palette: colorPalette
};
var bgRightNotFullscreen = {
width : 27, height : 152, bpp : 3,
transparent : 0,
buffer : require("heatshrink").decompress(atob("lmy5YCDBIUyBAmy5AJBhYUG2EAhgIFAQMAgQIGCgQABCg4ABEAwUNFI2AKZHAKZEgGRZTGOIUDQxJxGKH5Q/agwAxrdt23bAQVABIMly1ZsoCCMgUWCIYCB6AJBhIRDAQNgBIMFEwlt2i1CEwmWrAJBgI7FtpGCHYuWKH5QxEwpQDlo7F0A7IqBZBEwo7BCIwCBJo53CJoxiCJpIAdgOmzVpAQR/CgAIEAQJ2CBAoCBBIMmCg1oD4QLGFQUCCjQ+CKYw+CKY4JCKYwoCGRMaGREJDoroCgwdFzBlLKH5QvAHih/eX5Q/KE4A8UP7y/KH5QGDpg7HJoxZCCIx3CJowmCF4yACJox/CgA="))
buffer : require("heatshrink").decompress((atob("yVJkgCCyf/AAPJBAYCBk4JB8gUFyVP//yBAoCB//5BAwUCAAIUHAAIgGChopGv5TIn5TIz4yLKYxxC/iGI/xxGKH5Q/agwAx0hGF34JB6RGFr4JB9JkFl4JB+gdFy4JB/QdFpYJB/odFkqrCS4xGCWoyhCKH5QuDoxQCDpI7GDoJZGHYIRGLIQvGO4QvGMQRNJADv+GIqTC/5PGz4JBJ41JBIPJCg2TD4QLGn4JB/gUaHwRTGHwRTHBIRTGNAQyJ8gyI+QdFp4JB/IdFk5lLKH5QvAHih/eX5Q/KE4A8UP7y/KH5QGDpg7HJoxZCCIx3CJowmCF4yACJoyJC/4A="))),
palette: colorPalette
};
var bgLeft = settings.fullscreen ? bgLeftFullscreen : bgLeftNotFullscreen;
@ -125,7 +171,7 @@ Graphics.prototype.setFontAntonioLarge = function(scale) {
*/
var drawTimeout;
function queueDraw() {
// Faster updates during alarm to ensure that it is
// shown correctly...
var timeout = isAlarmEnabled() ? 10000 : 60000;
@ -244,9 +290,8 @@ function drawInfo(){
return;
}
g.setFontAlign(-1, -1, 0);
g.setFontAntonioMedium();
g.setColor(cOrange);
g.setColor(color2);
g.clearRect(120, 10, g.getWidth(), 75);
g.drawString("LCARS", 128, 13);
@ -256,7 +301,7 @@ function drawInfo(){
g.drawString("NOCON", 128, 33);
}
if(Bangle.isLocked()){
g.setColor(cPurple);
g.setColor(color3);
g.drawString("LOCK", 128, 53);
}
}
@ -287,7 +332,7 @@ function drawState(){
g.drawString("STATUS", 23+26, 108);
} else {
// Alarm within symbol
g.setColor(cOrange);
g.setColor(color2);
g.drawString("ALARM", 23+26, 108);
g.setColor(cWhite);
g.setFontAntonioLarge();
@ -302,19 +347,19 @@ function drawPosition0(){
// Draw background image
var offset = settings.fullscreen ? 0 : 24;
g.drawImage(bgLeft, 0, offset);
drawHorizontalBgLine(cBlue, 25, 120, offset, 4);
drawHorizontalBgLine(cBlue, 130, 176, offset, 4);
drawHorizontalBgLine(cPurple, 20, 70, 80, 4);
drawHorizontalBgLine(cPurple, 80, 176, 80, 4);
drawHorizontalBgLine(cOrange, 35, 110, 87, 4);
drawHorizontalBgLine(cOrange, 120, 176, 87, 4);
drawHorizontalBgLine(color1, 25, 120, offset, 4);
drawHorizontalBgLine(color1, 130, 176, offset, 4);
drawHorizontalBgLine(color3, 20, 70, 80, 4);
drawHorizontalBgLine(color3, 80, 176, 80, 4);
drawHorizontalBgLine(color2, 35, 110, 87, 4);
drawHorizontalBgLine(color2, 120, 176, 87, 4);
// The last line is a battery indicator too
var bat = E.getBattery() / 100.0;
var batStart = 19;
var batWidth = 172 - batStart;
var batX2 = parseInt(batWidth * bat + batStart);
drawHorizontalBgLine(cOrange, batStart, batX2, 171, 5);
drawHorizontalBgLine(color2, batStart, batX2, 171, 5);
drawHorizontalBgLine(cGrey, batX2, 172, 171, 5);
for(var i=0; i+batStart<=172; i+=parseInt(batWidth/4)){
drawHorizontalBgLine(cBlack, batStart+i, batStart+i+3, 168, 8)
@ -353,9 +398,9 @@ function drawPosition0(){
// Draw data
g.setFontAlign(-1, -1, 0);
g.setColor(cWhite);
drawData(settings.dataRow1, 97, cOrange);
drawData(settings.dataRow2, 122, cPurple);
drawData(settings.dataRow3, 147, cBlue);
drawData(settings.dataRow1, 97, color2);
drawData(settings.dataRow2, 122, color3);
drawData(settings.dataRow3, 147, color1);
// Draw state
drawState();
@ -366,13 +411,13 @@ function drawPosition1(){
var offset = settings.fullscreen ? 0 : 24;
g.drawImage(bgRight, 149, offset);
if(settings.fullscreen){
drawHorizontalBgLine(cBlue, 0, 140, offset, 4);
drawHorizontalBgLine(color1, 0, 140, offset, 4);
}
drawHorizontalBgLine(cPurple, 0, 80, 80, 4);
drawHorizontalBgLine(cPurple, 90, 150, 80, 4);
drawHorizontalBgLine(cOrange, 0, 50, 87, 4);
drawHorizontalBgLine(cOrange, 60, 140, 87, 4);
drawHorizontalBgLine(cOrange, 0, 150, 171, 5);
drawHorizontalBgLine(color3, 0, 80, 80, 4);
drawHorizontalBgLine(color3, 90, 150, 80, 4);
drawHorizontalBgLine(color2, 0, 50, 87, 4);
drawHorizontalBgLine(color2, 60, 140, 87, 4);
drawHorizontalBgLine(color2, 0, 150, 171, 5);
// Draw steps bars
g.setColor(cWhite);
@ -642,7 +687,6 @@ Bangle.on('charging',function(charging) {
drawState();
});
function feedback(){
Bangle.buzz(40, 0.3);
}

View File

@ -10,6 +10,9 @@
dataRow3: "Temp",
speed: "kph",
fullscreen: false,
themeColor1BG: "#FF9900",
themeColor2BG: "#FF00DC",
themeColor3BG: "#0094FF",
};
let saved_settings = storage.readJSON(SETTINGS_FILE, 1) || settings;
for (const key in saved_settings) {
@ -20,8 +23,11 @@
storage.write(SETTINGS_FILE, settings)
}
var dataOptions = ["Steps", "Battery", "VREF", "HRM", "Temp", "Humidity", "Wind", "Altitude", "CoreT"];
var speedOptions = ["kph", "mph"];
var color_options = ['Green','Orange','Cyan','Purple','Red','Blue','Yellow','White'];
var bg_code = ['#00ff00','#FF9900','#0094FF','#FF00DC','#ff0000','#0000ff','#ffef00','#FFFFFF'];
E.showMenu({
'': { 'title': 'LCARS Clock' },
@ -69,6 +75,33 @@
settings.speed = speedOptions[v];
save();
},
},
'Theme Color 1': {
value: 0 | bg_code.indexOf(settings.themeColor1BG),
min: 0, max: 7,
format: v => color_options[v],
onchange: v => {
settings.themeColor1BG = bg_code[v];
save();
},
},
'Theme Color 2': {
value: 0 | bg_code.indexOf(settings.themeColor2BG),
min: 0, max: 7,
format: v => color_options[v],
onchange: v => {
settings.themeColor2BG = bg_code[v];
save();
},
},
'Theme Color 3': {
value: 0 | bg_code.indexOf(settings.themeColor3BG),
min: 0, max: 7,
format: v => color_options[v],
onchange: v => {
settings.themeColor3BG = bg_code[v];
save();
},
}
});
})

View File

@ -3,7 +3,7 @@
"name": "LCARS Clock",
"shortName":"LCARS",
"icon": "lcars.png",
"version":"0.20",
"version":"0.21",
"readme": "README.md",
"supports": ["BANGLEJS2"],
"description": "Library Computer Access Retrieval System (LCARS) clock.",