status bar
git clone https://git.lucas.co/cce-status-interface.git
feat: light module circle wears the module-box fill (sphere-lit when raised)
The circle takes box_bg_color — same fill, opacity and per-pixel
compositor backdrop blur as every module box — instead of the bare
ring. With box_bevel=raised the disc draws through the Sphere prim,
the circular sibling of the lit-plate treatment; its highlight azimuth
IS light_source_position, so the module now visually indicates the
very direction it stands for. Flat Circle prim otherwise; the optional
ring stroke stays available (thickness > 0) but is off.
Co-Authored-By: Claude Fable 5 <[email protected]>
src/main.rs | 24 +++++++++++++++++++-----
src/modules.rs | 21 ++++++++-------------
2 files changed, 27 insertions(+), 18 deletions(-)
diff --git a/src/main.rs b/src/main.rs
index 5061102..59745ca 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1453,14 +1453,28 @@ impl cce_ui::engine::Application for StatusApp {
if rb.corners.2 { rb.radius } else { 0.0 },
if rb.corners.3 { rb.radius } else { 0.0 },
);
- // Outlined shapes: no bevel treatment. A full circle draws as an
- // Arc ring — the rounded-rect corner family is the squircle
- // (corner_shape), which reads as a rounded SQUARE at half-extent
- // radius — anything else as a Border prim (fill + stroke).
+ // True-shape boxes (the light module's circle): no bevel
+ // treatment. A full circle draws through the Circle/Arc prims —
+ // the rounded-rect corner family is the squircle (corner_shape),
+ // which reads as a rounded SQUARE at half-extent radius — with
+ // the fill and stroke each optional. Anything else outlined goes
+ // through the Border prim (fill + stroke).
if let Some((border_color, thickness)) = rb.border {
if (rb.w - rb.h).abs() < 0.5 && (rb.radius - rb.w / 2.0).abs() < 0.5 {
let r = rb.w / 2.0;
- pc.arc(rb.x + r, rb.y + r, r, thickness, 0.0, std::f32::consts::TAU, border_color);
+ if rb.color[3] > 0.001 {
+ // With raised module boxes (lit plates), the circle
+ // takes the sphere-lit disc — the circular sibling of
+ // the plate treatment, same light and material.
+ if matches!(self.box_bevel, Some(StatusBoxBevel::Raised)) {
+ pc.sphere(rb.x + r, rb.y + r, r, rb.color);
+ } else {
+ pc.circle(rb.x + r, rb.y + r, r, rb.color);
+ }
+ }
+ if thickness > 0.05 {
+ pc.arc(rb.x + r, rb.y + r, r, thickness, 0.0, std::f32::consts::TAU, border_color);
+ }
} else {
pc.border(rect, radii, rb.color, border_color, thickness);
}
diff --git a/src/modules.rs b/src/modules.rs
index 4f548d2..f4c38b4 100644
--- a/src/modules.rs
+++ b/src/modules.rs
@@ -878,7 +878,7 @@ impl StatusModule for LightSourceModule {
_font_system: &mut FontSystem,
_font_family: &str,
_font_size: f32,
- normal_color: [f32; 4],
+ _normal_color: [f32; 4],
bar_h: f32,
_scale_factor: f64,
_text_prims: &mut Vec<crate::TextPrim>,
@@ -888,30 +888,25 @@ impl StatusModule for LightSourceModule {
_layout_bounds: &mut Option<LayoutBounds>,
_tray_items: &HashMap<String, TrayItem>,
_tray_item_bounds: &mut Vec<TrayIconBounds>,
- _box_bg_color: Option<[f32; 4]>,
+ box_bg_color: Option<[f32; 4]>,
_status_box_radius: f32,
rounded_boxes: &mut Vec<RoundedBox>,
_padding: f32,
) {
let d = w.min(bar_h);
- // normal_color is raw sRGB (a text color); the ring draws through the
- // quad pipeline, which expects linear — convert so the stroke reads
- // as the same shade as module text.
- let ring = [
- normal_color[0].powf(2.2),
- normal_color[1].powf(2.2),
- normal_color[2].powf(2.2),
- 1.0,
- ];
+ // The circle wears the module-box fill: same color, opacity and
+ // (per-pixel, compositor-side) backdrop blur as every other module's
+ // box — just circle-shaped and empty of content.
rounded_boxes.push(RoundedBox {
x: x + (w - d) / 2.0,
y: (bar_h - d) / 2.0,
w: d,
h: d,
radius: d / 2.0,
- color: [0.0, 0.0, 0.0, 0.0],
+ color: box_bg_color.unwrap_or([0.0, 0.0, 0.0, 0.0]),
corners: (true, true, true, true),
- border: Some((ring, 1.5)),
+ // Circle marker; zero thickness = fill only, no stroke.
+ border: Some(([0.0; 4], 0.0)),
});
}
}