Merge pull request #2499 from glemco/master

weather: redraw clock_info on update and provide color field
master
Gordon Williams 2023-01-16 09:04:49 +00:00 committed by GitHub
commit 48fb1f5ff3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 158 additions and 88 deletions

View File

@ -40,3 +40,4 @@
Now re-adds widgets if they were hidden when fast-loading
0.22: Fixed crash if item has no image and cutting long overflowing text
0.23: Setting circles colours per clkinfo and not position
0.24: Using suggested color from clock_info if set as default and available

View File

@ -116,11 +116,13 @@ let draw = function() {
queueDraw();
}
let getCircleColor = function(item, clkmenu) {
let getCircleColor = function(item, data, clkmenu) {
let colorKey = clkmenu.name;
if(!clkmenu.dynamic) colorKey += "/"+item.name;
colorKey += "_color";
let color = settings[colorKey];
//use default color only if no other color is set
if(data.color && !color) return data.color;
if (color && color != "") return color;
return g.theme.fg;
}
@ -137,10 +139,12 @@ let getGradientColor = function(color, percent) {
if (color == "green-red") {
let colorIndex = Math.round(colorList.length * percent);
return colorList[Math.min(colorIndex, colorList.length) - 1] || "#00ff00";
//return g.blendColor('#00ff00', '#ff0000', percent); //mostly dithering
}
if (color == "red-green") {
let colorIndex = colorList.length - Math.round(colorList.length * percent);
return colorList[Math.min(colorIndex, colorList.length)] || "#ff0000";
//return g.blendColor('#ff0000', '#00ff00', percent);
}
colorList = [
'#0000ff', '#8800ff', '#ff00ff', '#ff0088', '#ff0000'
@ -148,10 +152,12 @@ let getGradientColor = function(color, percent) {
if (color == "blue-red") {
let colorIndex = Math.round(colorList.length * percent);
return colorList[Math.min(colorIndex, colorList.length) - 1] || "#0000ff";
//return g.blendColor('#0000ff', '#ff0000', percent);
}
if (color == "red-blue") {
let colorIndex = colorList.length - Math.round(colorList.length * percent);
return colorList[Math.min(colorIndex, colorList.length)] || "#ff0000";
//return g.blendColor('#ff0000', '#0000ff', percent);
}
return color;
}
@ -177,7 +183,7 @@ let drawEmpty = function(img, w, color) {
let drawCircle = function(index, item, data, clkmenu) {
var w = circlePosX[index-1];
drawCircleBackground(w);
const color = getCircleColor(item, clkmenu);
const color = getCircleColor(item, data, clkmenu);
//drawEmpty(info? info.img : null, w, color);
var img = data.img;
var percent = 1; //fill up if no range

View File

@ -7,13 +7,10 @@
"Bangle/Steps_color":"#0000ff",
"Bangle/HRM_color":"green-red",
"Bangle/Altitude_color":"#00ff00",
"Weather/conditionWithTemperature_color":"#ffff00",
"Weather/condition_color":"#00ffff",
"Weather/humidity_color":"#00ffff",
"Weather/wind_color":"fg",
"Weather/temperature_color":"blue-red",
"Alarms_color":"#00ff00",
"Agenda_color":"#ff0000",
"circle1colorizeIcon": true,
"circle2colorizeIcon": true,
"circle3colorizeIcon": true,

View File

@ -1,7 +1,7 @@
{ "id": "circlesclock",
"name": "Circles clock",
"shortName":"Circles clock",
"version":"0.23",
"version":"0.24",
"description": "A clock with three or four circles for different data at the bottom in a probably familiar style",
"icon": "app.png",
"screenshots": [{"url":"screenshot-dark.png"}, {"url":"screenshot-light.png"}, {"url":"screenshot-dark-4.png"}, {"url":"screenshot-light-4.png"}],

View File

@ -20,3 +20,4 @@
0.21: Updated clkinfo icon.
0.22: Automatic translation of strings, some left untranslated.
0.23: Update clock_info to avoid a redraw
0.24: Redraw clock_info on update and provide color field for condition

View File

@ -1,28 +1,36 @@
(function() {
var weather = {
temp: "?",
hum: "?",
wind: "?",
txt: "?",
};
var weather;
var weatherLib = require("weather");
var weatherJson = require("Storage").readJSON('weather.json');
if(weatherJson !== undefined && weatherJson.weather !== undefined){
weather = weatherJson.weather;
function updateWeather() {
weather = weatherLib.get();
if(weather){
weather.temp = require("locale").temp(weather.temp-273.15);
weather.hum = weather.hum + "%";
weather.wind = require("locale").speed(weather.wind).match(/^(\D*\d*)(.*)$/);
weather.wind = Math.round(weather.wind[1]) + "kph";
} else {
weather = {
temp: "?",
hum: "?",
wind: "?",
txt: "?",
};
}
}
updateWeather();
function weatherIcon(code) {
var ovr = Graphics.createArrayBuffer(24,24,1,{msb:true});
require("weather").drawIcon({code:code},12,12,12,ovr);
weatherLib.drawIcon({code:code},12,12,12,ovr);
var img = ovr.asImage();
img.transparent = 0;
//for (var i=0;i<img.buffer.length;i++) img.buffer[i]^=255;
return img;
//g.setColor("#0ff").drawImage(img, 42, 42);
}
function _updater() {
updateWeather();
this.emit("redraw");
}
//FIXME ranges are somehow arbitrary
@ -31,42 +39,61 @@
img: atob("GBiBAABAAARGAAYEAADgACP4wDf8gAf+AA/+AE/4AG/jwA/v4A8P8AR/8DH/8AH//AP//g///g///g///gf//AAAAABkwABMgABMgA=="),
items: [
{
name: "conditionWithTemperature",
//TODO get this configurable
name: "conditionWithData",
hasRange : true,
get: () => ({ text: weather.temp, img: weatherIcon(weather.code),
color: weatherLib.getColor(weather.code),
v: parseInt(weather.temp), min: -30, max: 55}),
show: function() {},
hide: function () {}
show: function() {
this.updater = _updater.bind(this);
weatherLib.on("update", this.updater);
},
hide: function () { weatherLib.removeListener("update", this.updater); }
},
{
name: "condition",
get: () => ({ text: weather.txt, img: weatherIcon(weather.code),
color: weatherLib.getColor(weather.code),
v: weather.code}),
show: function() {},
hide: function () {}
show: function() {
this.updater = _updater.bind(this);
weatherLib.on("update", this.updater);
},
hide: function () { weatherLib.removeListener("update", this.updater); }
},
{
name: "temperature",
hasRange : true,
get: () => ({ text: weather.temp, img: atob("GBiBAAA8AAB+AADnAADDAADDAADDAADDAADDAADbAADbAADbAADbAADbAADbAAHbgAGZgAM8wAN+wAN+wAM8wAGZgAHDgAD/AAA8AA=="),
v: parseInt(weather.temp), min: -30, max: 55}),
show: function() {},
hide: function () {}
show: function() {
this.updater = _updater.bind(this);
weatherLib.on("update", this.updater);
},
hide: function () { weatherLib.removeListener("update", this.updater); }
},
{
name: "humidity",
hasRange : true,
get: () => ({ text: weather.hum, img: atob("GBiBAAAEAAAMAAAOAAAfAAAfAAA/gAA/gAI/gAY/AAcfAA+AQA+A4B/A4D/B8D/h+D/j+H/n/D/n/D/n/B/H/A+H/AAH/AAD+AAA8A=="),
v: parseInt(weather.hum), min: 0, max: 100}),
show: function() {},
hide: function () {}
show: function() {
this.updater = _updater.bind(this);
weatherLib.on("update", this.updater);
},
hide: function () { weatherLib.removeListener("update", this.updater); }
},
{
name: "wind",
hasRange : true,
get: () => ({ text: weather.wind, img: atob("GBiBAAHgAAPwAAYYAAwYAAwMfAAY/gAZh3/xg//hgwAAAwAABg///g//+AAAAAAAAP//wH//4AAAMAAAMAAYMAAYMAAMcAAP4AADwA=="),
v: parseInt(weather.wind), min: 0, max: 118}),
show: function() {},
hide: function () {}
show: function() {
this.updater = _updater.bind(this);
weatherLib.on("update", this.updater);
},
hide: function () { weatherLib.removeListener("update", this.updater); }
},
]
};

View File

@ -53,6 +53,98 @@ exports.get = function() {
scheduleExpiry(storage.readJSON('weather.json')||{});
function getPalette(monochrome, ovr) {
var palette;
if(monochrome) {
palette = {
sun: '#FFF',
cloud: '#FFF',
bgCloud: '#FFF',
rain: '#FFF',
lightning: '#FFF',
snow: '#FFF',
mist: '#FFF',
background: '#000'
};
} else {
if (B2) {
if (ovr.theme.dark) {
palette = {
sun: '#FF0',
cloud: '#FFF',
bgCloud: '#777', // dithers on B2, but that's ok
rain: '#0FF',
lightning: '#FF0',
snow: '#FFF',
mist: '#FFF'
};
} else {
palette = {
sun: '#FF0',
cloud: '#777', // dithers on B2, but that's ok
bgCloud: '#000',
rain: '#00F',
lightning: '#FF0',
snow: '#0FF',
mist: '#0FF'
};
}
} else {
if (ovr.theme.dark) {
palette = {
sun: '#FE0',
cloud: '#BBB',
bgCloud: '#777',
rain: '#0CF',
lightning: '#FE0',
snow: '#FFF',
mist: '#FFF'
};
} else {
palette = {
sun: '#FC0',
cloud: '#000',
bgCloud: '#777',
rain: '#07F',
lightning: '#FC0',
snow: '#CCC',
mist: '#CCC'
};
}
}
}
return palette;
}
exports.getColor = function(code) {
const codeGroup = Math.round(code / 100);
const palette = getPalette(0, g);
const cloud = g.blendColor(palette.cloud, palette.bgCloud, .5); //theme independent
switch (codeGroup) {
case 2: return g.blendColor(cloud, palette.lightning, .5);
case 3: return palette.rain;
case 5:
switch (code) {
case 511: return palette.snow;
case 520: return g.blendColor(palette.rain, palette.sun, .5);
case 521: return g.blendColor(palette.rain, palette.sun, .5);
case 522: return g.blendColor(palette.rain, palette.sun, .5);
case 531: return g.blendColor(palette.rain, palette.sun, .5);
default: return palette.rain;
}
case 6: return palette.snow;
case 7: return palette.mist;
case 8:
switch (code) {
case 800: return palette.sun;
case 801: return palette.sun;
case 802: return cloud;
default: return cloud;
}
default: return cloud;
}
}
/**
*
* @param cond Weather condition, as one of:
@ -71,63 +163,8 @@ exports.drawIcon = function(cond, x, y, r, ovr) {
ovr = g;
monochrome=0;
}
if(monochrome) {
palette = {
sun: '#FFF',
cloud: '#FFF',
bgCloud: '#FFF',
rain: '#FFF',
lightning: '#FFF',
snow: '#FFF',
mist: '#FFF',
background: '#000'
};
} else
if (B2) {
if (ovr.theme.dark) {
palette = {
sun: '#FF0',
cloud: '#FFF',
bgCloud: '#777', // dithers on B2, but that's ok
rain: '#0FF',
lightning: '#FF0',
snow: '#FFF',
mist: '#FFF'
};
} else {
palette = {
sun: '#FF0',
cloud: '#777', // dithers on B2, but that's ok
bgCloud: '#000',
rain: '#00F',
lightning: '#FF0',
snow: '#0FF',
mist: '#0FF'
};
}
} else {
if (ovr.theme.dark) {
palette = {
sun: '#FE0',
cloud: '#BBB',
bgCloud: '#777',
rain: '#0CF',
lightning: '#FE0',
snow: '#FFF',
mist: '#FFF'
};
} else {
palette = {
sun: '#FC0',
cloud: '#000',
bgCloud: '#777',
rain: '#07F',
lightning: '#FC0',
snow: '#CCC',
mist: '#CCC'
};
}
}
palette = getPalette(monochrome, ovr);
function drawSun(x, y, r) {
ovr.setColor(palette.sun);

View File

@ -1,7 +1,7 @@
{
"id": "weather",
"name": "Weather",
"version": "0.23",
"version": "0.24",
"description": "Show Gadgetbridge weather report",
"icon": "icon.png",
"screenshots": [{"url":"screenshot.png"}],

View File

@ -15,8 +15,9 @@ Note that each item is an object with:
{
'text' // the text to display for this item
'short' : (optional) a shorter text to display for this item (at most 6 characters)
'short' // optional: a shorter text to display for this item (at most 6 characters)
'img' // optional: a 24x24px image to display for this item
'color' // optional: a color string (like "#ffffff") to color the icon in compatible clocks
'v' // (if hasRange==true) a numerical value
'min','max' // (if hasRange==true) a minimum and maximum numerical value (if this were to be displayed as a guage)
}