git.lucas.co / cce-ui
GPU-accelerated UI toolkit (Vulkan)
git clone https://git.lucas.co/cce-ui.git

commit3d72dae7612a7260a56662c61e3d902088e52485
parent900ae50c0c
authorLucas Galante <[email protected]>
date2026-07-24 14:45
feat: params plate tint is config- and runtime-settable

PARAM_BG becomes the default of a live PARAM_BG_COLOR slot:
style.surface.param.color overrides it from config, set_param_bg_color
retints at runtime (the designer's Style section drives it). rgba
params in the pane now build the alpha-carrying picker — the plate
tint's alpha doubles as its frost strength.

Co-Authored-By: Claude Fable 5 <[email protected]>

 src/color.rs                          | 20 ++++++++++++++++++++
 src/widget/container/parameters_bg.rs | 12 ++++++++++--
 2 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/src/color.rs b/src/color.rs
index 3bb23b6..a9ae58c 100644
--- a/src/color.rs
+++ b/src/color.rs
@@ -636,6 +636,9 @@ fn parse_and_set_colors(content: &str) {
     if let Some(t) = val.pointer("/style/surface/plate/bevel_width").and_then(|v| v.as_f64()) {
         if let Ok(mut lock) = PLATE_BEVEL_WIDTH.write() { *lock = t as f32; }
     }
+    if let Some(c) = get_color("/style/surface/param/color") {
+        if let Ok(mut lock) = PARAM_BG_COLOR.write() { *lock = c; }
+    }
     if let Some(blur) = val.pointer("/style/surface/plate/blur").and_then(|v| v.as_bool()) {
         if let Ok(mut lock) = PLATE_BLUR.write() { *lock = blur; }
     } else if let Some(blur_val) = val.pointer("/style/surface/plate/blur").and_then(|v| v.as_f64()) {
@@ -899,6 +902,23 @@ pub const CANVAS_BG: [f32; 4] = [0.05, 0.05, 0.10, 1.0];
 pub const VIEWPORT_BG: [f32; 4] = [0.0, 0.0, 0.0, 0.0];
 pub const PARAM_BG: [f32; 4] = [0.10, 0.10, 0.14, 0.25];
 
+/// The params pane's plate tint (linear rgba) — [`PARAM_BG`] made live:
+/// `style.surface.param.color` in config overrides it, and apps can retint at
+/// runtime (the designer's Style section "Plate Color"). Alpha doubles as the
+/// frost strength under plate blur.
+static PARAM_BG_COLOR: RwLock<[f32; 4]> = RwLock::new(PARAM_BG);
+
+pub fn param_bg_color() -> [f32; 4] {
+    load_colors_once();
+    *PARAM_BG_COLOR.read().unwrap()
+}
+
+pub fn set_param_bg_color(color: [f32; 4]) {
+    if let Ok(mut lock) = PARAM_BG_COLOR.write() {
+        *lock = color;
+    }
+}
+
 pub const PANEL_MENU_BG: [f32; 4] = [0.08, 0.08, 0.12, 1.0];
 pub const PANEL_MENU_HOVER: [f32; 4] = [0.18, 0.18, 0.25, 1.0];
 pub const PANEL_MENU_FOCUSED: [f32; 4] = [0.08, 0.16, 0.28, 1.0];
diff --git a/src/widget/container/parameters_bg.rs b/src/widget/container/parameters_bg.rs
index bbd2c0f..8099825 100644
--- a/src/widget/container/parameters_bg.rs
+++ b/src/widget/container/parameters_bg.rs
@@ -1242,7 +1242,7 @@ impl Paint for ParametersBg {
         if !self.visible {
             return [0.0, 0.0, 0.0, 0.0];
         }
-        let mut c = colors::PARAM_BG;
+        let mut c = colors::param_bg_color();
         c[3] *= crate::layout::plate_opacity();
         if colors::plate_blur() {
             c[3] = -c[3].abs();
@@ -2280,6 +2280,10 @@ fn parse_hex_to_rgb(s: &str) -> Option<[u8; 3]> {
     crate::color::parse_hex_bytes(s).map(|[r, g, b, _]| [r, g, b])
 }
 
+fn parse_hex_to_rgba(s: &str) -> Option<[u8; 4]> {
+    crate::color::parse_hex_bytes(s)
+}
+
 fn parse_spinbox_range(ptype: &str) -> (i32, i32, i32) {
     if ptype.starts_with("spinbox:") {
         let parts: Vec<&str> = ptype.split(':').collect();
@@ -2406,7 +2410,11 @@ impl ParamController for ParametersBg {
                 }
             }).collect();
             self.colors = self.display_params.iter().map(|p| {
-                if p.2.starts_with("color") || p.2 == "rgb" || p.2 == "rgba" {
+                if p.2 == "rgba" {
+                    // Alpha-carrying param: the full picker, 8-digit hex.
+                    let col = parse_hex_to_rgba(&p.1).unwrap_or([255, 255, 255, 255]);
+                    Some(ColorSelector::new_rgba(col).with_label(&p.0))
+                } else if p.2.starts_with("color") || p.2 == "rgb" {
                     let col = parse_hex_to_rgb(&p.1).unwrap_or([255, 255, 255]);
                     Some(ColorSelector::new(col).with_label(&p.0))
                 } else {