Merge pull request #1703 from Ronin0000-Github-Bangle-js-Fork-2/master
LCARS clock custom themingpull/1719/head
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
|
|
Before Width: | Height: | Size: 795 B After Width: | Height: | Size: 789 B |
Before Width: | Height: | Size: 772 B After Width: | Height: | Size: 760 B |
Before Width: | Height: | Size: 791 B After Width: | Height: | Size: 771 B |
Before Width: | Height: | Size: 769 B After Width: | Height: | Size: 742 B |
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
},
|
||||
}
|
||||
});
|
||||
})
|
||||
|
|
|
@ -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.",
|
||||
|
|