Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 3 additions & 8 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,9 @@ reports/
.*.sw?
*.kate-swp
gnupg/

# Package build artifacts
.github/copilot-instructions.md
.github/instructions/*
.github/agents/*
*.deb
*.rpm
*.buildinfo
Expand All @@ -46,9 +47,3 @@ packaging/debian/coolerdash/
packaging/debian/files
packaging/debian/*.substvars
packaging/debian/*.log

# GitHub-specific ignores
# AI Copilot instructions (only relevant for developers)
.github/copilot-instructions.md
.github/instructions/copilot-instructions.md
.github/instructions/BEST_PRACTICES.instructions.md
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.1.2
2.1.3
35 changes: 34 additions & 1 deletion etc/coolercontrol/plugins/coolerdash/ui/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -438,23 +438,47 @@ <h3 style="margin-bottom: 16px; font-size: 16px; color: var(--text-dim);">Layout
<div class="grid grid-3">
<div class="form-group">
<label class="form-label">Border Thickness</label>
<span class="form-hint">0 = no border</span>
<input type="number" name="layout.bar_border" class="form-control" min="0" max="10" step="0.1">
</div>

<div class="form-group">
<label class="form-label">Border Enabled</label>
<span class="form-hint">Toggle bar border on/off</span>
<select name="layout.bar_border_enabled" class="form-control">
<option value="1">Enabled</option>
<option value="0">Disabled</option>
</select>
</div>

<div class="form-group">
<label class="form-label">Label Left Margin</label>
<input type="number" name="layout.label_margin_left" class="form-control" min="0" max="20">
</div>
</div>

<div class="grid grid-3">
<div class="form-group">
<label class="form-label">Label Bar Margin</label>
<input type="number" name="layout.label_margin_bar" class="form-control" min="0" max="20">
</div>

<div class="form-group"></div>
<div class="form-group"></div>
</div>

<h3 style="margin: 24px 0 16px; font-size: 16px; color: var(--text-dim);">Colors</h3>

<div class="grid grid-2">
<div class="form-group">
<label class="form-label">Display Background</label>
<span class="form-hint">Main background color</span>
<div class="color-group">
<input type="color" id="color_display_background" class="color-swatch" onchange="updateColorRGB('color_display_background', 'rgb_display_background')">
<span class="color-rgb" id="rgb_display_background"></span>
</div>
</div>

<div class="form-group">
<label class="form-label">Bar Background</label>
<div class="color-group">
Expand Down Expand Up @@ -751,10 +775,12 @@ <h3 style="margin: 24px 0 16px; font-size: 16px; color: var(--text-dim);">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 },
Expand Down Expand Up @@ -997,6 +1023,7 @@ <h3 style="margin: 24px 0 16px; font-size: 16px; color: var(--text-dim);">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');
Expand All @@ -1023,7 +1050,12 @@ <h3 style="margin: 24px 0 16px; font-size: 16px; color: var(--text-dim);">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') {
Expand All @@ -1038,6 +1070,7 @@ <h3 style="margin: 24px 0 16px; font-size: 16px; color: var(--text-dim);">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);
Expand Down
29 changes: 25 additions & 4 deletions src/device/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

/**
Expand Down Expand Up @@ -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);
}

/**
Expand All @@ -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},
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
8 changes: 5 additions & 3 deletions src/device/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/**
Expand Down Expand Up @@ -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;

Expand Down
34 changes: 20 additions & 14 deletions src/mods/circle.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down
20 changes: 12 additions & 8 deletions src/mods/dual.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}

/**
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -703,4 +707,4 @@ void draw_dual_image(const struct Config *config)
{
log_message(LOG_WARNING, "Skipping dual LCD upload - device not available");
}
}
}