@@ -751,10 +775,12 @@
Labels
bar_width: 98,
bar_gap: 12,
bar_border: 2.0,
+ bar_border_enabled: true,
label_margin_left: 1,
label_margin_bar: 1
},
colors: {
+ display_background: { r: 0, g: 0, b: 0 },
bar_background: { r: 52, g: 52, b: 52 },
bar_border: { r: 192, g: 192, b: 192 },
font_temp: { r: 255, g: 255, b: 255 },
@@ -997,6 +1023,7 @@ Labels
}
// Add colors
+ config.colors.display_background = getColorFromPicker('color_display_background');
config.colors.bar_background = getColorFromPicker('color_bar_background');
config.colors.bar_border = getColorFromPicker('color_bar_border');
config.colors.font_temp = getColorFromPicker('color_font_temp');
@@ -1023,7 +1050,12 @@ Labels
for (const [field, value] of Object.entries(fields)) {
const input = document.querySelector(`[name="${section}.${field}"]`);
if (input && typeof value !== 'object') {
- input.value = value;
+ // Handle boolean values for select elements
+ if (typeof value === 'boolean') {
+ input.value = value ? "1" : "0";
+ } else {
+ input.value = value;
+ }
// Update UI
if (field === 'brightness') {
@@ -1038,6 +1070,7 @@ Labels
// Color pickers
if (config.colors) {
+ if (config.colors.display_background) setupColorPicker('color_display_background', 'rgb_display_background', config.colors.display_background);
if (config.colors.bar_background) setupColorPicker('color_bar_background', 'rgb_bar_background', config.colors.bar_background);
if (config.colors.bar_border) setupColorPicker('color_bar_border', 'rgb_bar_border', config.colors.bar_border);
if (config.colors.font_temp) setupColorPicker('color_font_temp', 'rgb_font_temp', config.colors.font_temp);
diff --git a/src/device/config.c b/src/device/config.c
index 3661fa2..18dbba9 100644
--- a/src/device/config.c
+++ b/src/device/config.c
@@ -159,8 +159,12 @@ static void set_layout_defaults(Config *config)
config->layout_bar_height = 24;
if (config->layout_bar_gap == 0)
config->layout_bar_gap = 12.0f;
- if (config->layout_bar_border == 0.0f)
+ // bar_border: -1 = use default (2.0), 0 = explicitly disabled, >0 = custom value
+ if (config->layout_bar_border < 0.0f)
config->layout_bar_border = 2.0f;
+ // bar_border_enabled: -1 = auto (enabled), 0 = disabled, 1 = enabled
+ if (config->layout_bar_border_enabled < 0)
+ config->layout_bar_border_enabled = 1; // Default: enabled
}
/**
@@ -244,10 +248,11 @@ static void set_temperature_defaults(Config *config)
/**
* @brief Check if color is unset
+ * @details Uses is_set flag - all RGB values (0,0,0 to 255,255,255) are valid.
*/
static inline int is_color_unset(const Color *color)
{
- return (color->r == 0 && color->g == 0 && color->b == 0);
+ return (color->is_set == 0);
}
/**
@@ -265,6 +270,7 @@ typedef struct
static void set_color_defaults(Config *config)
{
ColorDefault color_defaults[] = {
+ {&config->display_background_color, 0, 0, 0}, // Main background (black)
{&config->layout_bar_color_background, 52, 52, 52},
{&config->layout_bar_color_border, 192, 192, 192},
{&config->font_color_temp, 255, 255, 255},
@@ -336,6 +342,7 @@ static int read_color_from_json(json_t *color_obj, Color *color)
color->r = (uint8_t)r_val;
color->g = (uint8_t)g_val;
color->b = (uint8_t)b_val;
+ color->is_set = 1; // Mark as user-defined
return 1;
}
@@ -572,8 +579,18 @@ static void load_layout_from_json(json_t *root, Config *config)
if (bar_border && json_is_number(bar_border))
{
double val = json_number_value(bar_border);
- if (val >= 0 && val <= 10)
+ if (val >= 0.0 && val <= 10.0)
config->layout_bar_border = (float)val;
+ // Note: -1 in JSON means "use default" (handled in set_layout_defaults)
+ }
+
+ json_t *bar_border_enabled = json_object_get(layout, "bar_border_enabled");
+ if (bar_border_enabled)
+ {
+ if (json_is_boolean(bar_border_enabled))
+ config->layout_bar_border_enabled = json_is_true(bar_border_enabled) ? 1 : 0;
+ else if (json_is_integer(bar_border_enabled))
+ config->layout_bar_border_enabled = (int)json_integer_value(bar_border_enabled) != 0 ? 1 : 0;
}
json_t *label_margin_left = json_object_get(layout, "label_margin_left");
@@ -602,6 +619,7 @@ static void load_colors_from_json(json_t *root, Config *config)
if (!colors || !json_is_object(colors))
return;
+ read_color_from_json(json_object_get(colors, "display_background"), &config->display_background_color);
read_color_from_json(json_object_get(colors, "bar_background"), &config->layout_bar_color_background);
read_color_from_json(json_object_get(colors, "bar_border"), &config->layout_bar_color_border);
read_color_from_json(json_object_get(colors, "font_temp"), &config->font_color_temp);
@@ -796,9 +814,12 @@ int load_plugin_config(Config *config, const char *config_path)
return 0;
}
- // Initialize with defaults
+ // Initialize with defaults (memset sets all to 0, including color.is_set = 0)
memset(config, 0, sizeof(Config));
config->display_inscribe_factor = -1.0f; // Sentinel for "auto"
+ config->layout_bar_border = -1.0f; // Sentinel for "use default"
+ config->layout_bar_border_enabled = -1; // Sentinel for "auto" (enabled)
+ // Note: All colors have is_set=0 after memset, so defaults will be applied
// Try to find and load JSON config
const char *json_path = find_config_json(config_path);
diff --git a/src/device/config.h b/src/device/config.h
index 69cbab8..4dd093f 100644
--- a/src/device/config.h
+++ b/src/device/config.h
@@ -29,15 +29,15 @@
/**
* @brief Simple color structure.
- * @details Represents RGB color values with 8-bit components and padding for
- * memory alignment.
+ * @details Represents RGB color values with 8-bit components.
+ * The is_set flag indicates if color was explicitly configured.
*/
typedef struct
{
uint8_t r;
uint8_t g;
uint8_t b;
- uint8_t _pad;
+ uint8_t is_set; // 0 = use default, 1 = user-defined (allows all RGB values)
} Color;
/**
@@ -86,9 +86,11 @@ typedef struct Config
uint16_t layout_bar_height;
uint16_t layout_bar_gap;
float layout_bar_border;
+ int layout_bar_border_enabled; // 1=enabled, 0=disabled, -1=auto (use default)
uint8_t layout_bar_width;
uint8_t layout_label_margin_left;
uint8_t layout_label_margin_bar;
+ Color display_background_color; // Main display background color
Color layout_bar_color_background;
Color layout_bar_color_border;
diff --git a/src/mods/circle.c b/src/mods/circle.c
index 286ee39..0d64711 100644
--- a/src/mods/circle.c
+++ b/src/mods/circle.c
@@ -395,12 +395,15 @@ static void draw_single_sensor(cairo_t *cr, const struct Config *config,
params->corner_radius);
cairo_fill(cr);
- // Bar border
- set_cairo_color(cr, &config->layout_bar_color_border);
- draw_rounded_rectangle_path(cr, bar_x, bar_y, effective_bar_width, bar_height,
- params->corner_radius);
- cairo_set_line_width(cr, config->layout_bar_border);
- cairo_stroke(cr);
+ // Bar border (only if enabled and thickness > 0)
+ if (config->layout_bar_border_enabled && config->layout_bar_border > 0.0f)
+ {
+ set_cairo_color(cr, &config->layout_bar_color_border);
+ draw_rounded_rectangle_path(cr, bar_x, bar_y, effective_bar_width, bar_height,
+ params->corner_radius);
+ cairo_set_line_width(cr, config->layout_bar_border);
+ cairo_stroke(cr);
+ }
// Bar fill (temperature-based)
const float max_temp = config->temp_max_scale;
@@ -432,12 +435,15 @@ static void draw_single_sensor(cairo_t *cr, const struct Config *config,
bar_height, params->corner_radius);
cairo_fill(cr);
- // Liquid bar border
- set_cairo_color(cr, &config->layout_bar_color_border);
- draw_rounded_rectangle_path(cr, bar_x, liquid_bar_y, effective_bar_width,
- bar_height, params->corner_radius);
- cairo_set_line_width(cr, config->layout_bar_border);
- cairo_stroke(cr);
+ // Liquid bar border (only if enabled and thickness > 0)
+ if (config->layout_bar_border_enabled && config->layout_bar_border > 0.0f)
+ {
+ set_cairo_color(cr, &config->layout_bar_color_border);
+ draw_rounded_rectangle_path(cr, bar_x, liquid_bar_y, effective_bar_width,
+ bar_height, params->corner_radius);
+ cairo_set_line_width(cr, config->layout_bar_border);
+ cairo_stroke(cr);
+ }
// Liquid bar fill (0-40°C typical range for AIO coolers)
const float max_liquid_temp = config->temp_liquid_max_scale;
@@ -574,8 +580,8 @@ static void render_display_content(cairo_t *cr, const struct Config *config,
if (!cr || !config || !data || !params)
return;
- // Draw background (black)
- cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
+ // Draw main background
+ set_cairo_color(cr, &config->display_background_color);
cairo_paint(cr);
// Update sensor mode (check if configured interval elapsed)
diff --git a/src/mods/dual.c b/src/mods/dual.c
index dd21cb7..8eb344b 100644
--- a/src/mods/dual.c
+++ b/src/mods/dual.c
@@ -429,12 +429,15 @@ static void draw_single_temperature_bar(cairo_t *cr,
cairo_fill(cr);
}
- // Border
- cairo_set_line_width(cr, config->layout_bar_border);
- set_cairo_color(cr, &config->layout_bar_color_border);
- draw_rounded_rectangle_path(cr, bar_x, bar_y, bar_width,
- config->layout_bar_height, params->corner_radius);
- cairo_stroke(cr);
+ // Border (only if enabled and thickness > 0)
+ if (config->layout_bar_border_enabled && config->layout_bar_border > 0.0f)
+ {
+ cairo_set_line_width(cr, config->layout_bar_border);
+ set_cairo_color(cr, &config->layout_bar_color_border);
+ draw_rounded_rectangle_path(cr, bar_x, bar_y, bar_width,
+ config->layout_bar_height, params->corner_radius);
+ cairo_stroke(cr);
+ }
}
/**
@@ -565,7 +568,8 @@ static void render_display_content(cairo_t *cr, const struct Config *config,
const monitor_sensor_data_t *data,
const ScalingParams *params)
{
- cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
+ // Draw main background
+ set_cairo_color(cr, &config->display_background_color);
cairo_paint(cr);
cairo_select_font_face(cr, config->font_face, CAIRO_FONT_SLANT_NORMAL,
@@ -703,4 +707,4 @@ void draw_dual_image(const struct Config *config)
{
log_message(LOG_WARNING, "Skipping dual LCD upload - device not available");
}
-}
\ No newline at end of file
+}