GPU-accelerated UI toolkit (Vulkan)
git clone https://git.lucas.co/cce-ui.git
refactor: relief material lives at style.surface.relief; add section depth key
bevel_depth / bevel_width move out of the compositor's window_manager
domain (which never consumed them) to style.surface.relief.depth/.width,
joining the other surface material styling; the old spellings stay
accepted as compat aliases. New style.container.section.depth (default
1.0) scales the params pane's section-well carve — wall width and channel
cap together — so sections can read deeper or shallower than the DE-wide
relief; past 1.0 the roll crosses the control groove by explicit choice.
Co-Authored-By: Claude Fable 5 <[email protected]>
src/layout.rs | 20 ++++++++++++++++++--
src/widget/container/parameters_bg.rs | 20 ++++++++++++++++----
2 files changed, 34 insertions(+), 6 deletions(-)
diff --git a/src/layout.rs b/src/layout.rs
index b23155e..720c0b9 100644
--- a/src/layout.rs
+++ b/src/layout.rs
@@ -114,8 +114,13 @@ fn flatten_json_to_flat_props(val: &serde_json::Value, prefix: &str, flat_props:
"style.control.toggle.border_color" => "toggle_border_color",
"style.control.toggle.corner_radius" => "toggle_corner_radius",
"window_manager.light_source_position" => "light_source_position",
- "window_manager.bevel_depth" => "bevel_depth",
- "window_manager.bevel_width" => "bevel_width",
+ // The DE's relief material: canonical home style.surface.relief
+ // (these shade every bevel/boss/recess in the toolkit — the
+ // compositor never read them, so the old window_manager
+ // spelling survives only as a compat alias).
+ "style.surface.relief.depth" | "window_manager.bevel_depth" => "bevel_depth",
+ "style.surface.relief.width" | "window_manager.bevel_width" => "bevel_width",
+ "style.container.section.depth" => "section_depth",
"window_manager.bevel_shader" => "bevel_shader",
"window_manager.control_relief" => "control_relief",
"window_manager.corner_shape" => "corner_shape",
@@ -1404,6 +1409,17 @@ pub fn set_control_panel_gap(gap: f32) {
}
}
+/// The section carves' depth multiplier (`style.container.section.depth`,
+/// default 1.0): scales the params pane's section-well wall — width and step
+/// together — relative to the DE-wide relief material, so sections can read
+/// deeper or shallower than the controls around them. Values past 1.0 let the
+/// roll widen across the channel groove between the well wall and its packed
+/// controls; tune to taste.
+pub fn section_depth() -> f32 {
+ lazy_init_style_registry();
+ get_style_registry().read().unwrap().get_float("section_depth").unwrap_or(1.0)
+}
+
pub fn section_padding() -> f32 {
use std::sync::Once;
static INIT: Once = Once::new();
diff --git a/src/widget/container/parameters_bg.rs b/src/widget/container/parameters_bg.rs
index c13f9dd..de2a302 100644
--- a/src/widget/container/parameters_bg.rs
+++ b/src/widget/container/parameters_bg.rs
@@ -78,6 +78,16 @@ const SCROLL_ACTIVE_HOLD: f32 = 0.7;
/// reliefs on either side (control bevel, section wall) shade the channel into a
/// narrow 3D groove.
const CHANNEL: f32 = 3.0;
+
+/// The section carve's wall width: the DE relief scaled by the section depth
+/// multiplier (`style.container.section.depth`), capped against the row height
+/// (safety) and the control channel — the channel cap scales WITH the
+/// multiplier, so deepening sections is an explicit choice to let the roll
+/// cross the groove.
+fn section_carve_depth(h: f32) -> f32 {
+ let sd = crate::layout::section_depth().max(0.0);
+ (crate::layout::bevel_width() * sd).min(h * 0.2).min(CHANNEL * sd)
+}
/// Vertical pitch between consecutive rows — one channel; rows abut.
const ROW_GAP: f32 = CHANNEL;
/// How far a section's title box overhangs its header row upward, and the box's height.
@@ -1030,8 +1040,10 @@ impl ParametersBg {
if let Some((cx, cy, cw, ch)) = content {
// Capped at the channel: the well's wall must roll off inside the
// groove between it and the controls packed one CHANNEL inside,
- // not shade across their faces.
- let depth = crate::layout::bevel_width().min(ch * 0.2).min(CHANNEL);
+ // not shade across their faces. `section_depth` scales wall and
+ // channel cap together — past 1.0 the roll crosses the groove
+ // by choice.
+ let depth = section_carve_depth(ch);
// Tab strip: the title box itself, sitting flush on the body's top
// edge (the header row above it stays plain plate), bottom open.
// A wall FADES OUT over the carve width approaching a suppressed
@@ -1075,7 +1087,7 @@ impl ParametersBg {
}
}
} else {
- let depth = crate::layout::bevel_width().min(th * 0.2).min(CHANNEL);
+ let depth = section_carve_depth(th);
out.push((tx, ty, tw, th, r4(SECTION_R), depth, false, all));
}
}
@@ -1193,7 +1205,7 @@ impl ParametersBg {
for (title, content) in self.section_boxes() {
let (tx, _ty, tw, _th) = title;
if let Some((cx, cy, cw, ch)) = content {
- let depth = crate::layout::bevel_width().min(ch * 0.2).min(CHANNEL);
+ let depth = section_carve_depth(ch);
let throat_r = tx + tw;
if cx + cw > throat_r + 2.0 * SECTION_FILLET_R {
out.push((