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

commit84f1bae21c16852442b7895004418232612a0bb9
parent374950e2ce
authorLucas Galante <[email protected]>
date2026-09-20 19:57
Graph: the grid relief is gated on visibility, not uniform_background

The lattice (and the gap quads before it) was gated on both, and the
designer hard-codes uniform_background = true — its network grid was never
drawn at all. uniform_background describes the widget's own background
fill and has nothing to say about relief. Found by counting lattice prims
in the tessellated frame under CCE_PLATE_DEBUG; the new integration test
pins both halves: a lattice survives tessellation inside a clip as a
mode-13 batch, and the graph emits it with a uniform background.

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

 src/widget/display/graph.rs |  9 ++++++++-
 tests/lattice_probe.rs      | 39 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 47 insertions(+), 1 deletion(-)

diff --git a/src/widget/display/graph.rs b/src/widget/display/graph.rs
index d9a4cfb..3202163 100644
--- a/src/widget/display/graph.rs
+++ b/src/widget/display/graph.rs
@@ -409,7 +409,14 @@ impl Graph {
         // Half the narrower rail, the same clamp the desktop grid applies.
         let run = (self.skipped_col_w.min(self.skipped_row_h) * 0.5).max(1.0);
 
-        if self.show_network_grid && !self.uniform_background && step_x >= 4.0 && step_y >= 4.0 {
+        // Gated on the grid's visibility ONLY — not on `uniform_background`,
+        // which describes the widget's own background fill (cell colour over
+        // the whole rect vs the near-clear one) and has nothing to say about
+        // relief. The old cell/gap quads were gated on both, and the designer
+        // hard-codes uniform_background = true, so its network grid was never
+        // drawn at all — found 2026-09-20 by counting lattice prims in the
+        // tessellated frame under CCE_PLATE_DEBUG.
+        if self.show_network_grid && step_x >= 4.0 && step_y >= 4.0 {
             pc.lattice(
                 rect,
                 (step_x, step_y),
diff --git a/tests/lattice_probe.rs b/tests/lattice_probe.rs
new file mode 100644
index 0000000..026b66a
--- /dev/null
+++ b/tests/lattice_probe.rs
@@ -0,0 +1,39 @@
+use cce_ui::scene::layout::Rect;
+use cce_ui::scene::paint::{PaintCtx, Prim};
+
+#[test]
+fn lattice_survives_tessellation_inside_a_clip() {
+    let mut pc = PaintCtx::new();
+    let clip = Rect { x: 40.0, y: 40.0, width: 600.0, height: 300.0 };
+    pc.clip(clip, |pc| {
+        pc.lattice(clip, (85.0, 43.0), (60.0, 60.0), (71.0, 31.0), 6.0, 6.0);
+        pc.groove((40.0, 100.0), (640.0, 100.0), 2.0, 2.0, clip);
+    });
+    let dl = pc.finish();
+    let kinds: Vec<String> = dl.items.iter().map(|i| format!("{:?}", std::mem::discriminant(&i.prim))).collect();
+    let n_lattice = dl.items.iter().filter(|i| matches!(i.prim, Prim::Lattice { .. })).count();
+    assert_eq!(n_lattice, 1, "display list: {kinds:?}");
+    let (verts, batches, _, _) = cce_ui::backend::window_runner::tessellate_display_list(&dl, 1280.0, 720.0, 2.0);
+    let modes: Vec<f32> = batches.iter().filter_map(|b| b.plate.as_ref().map(|p| p.mode)).collect();
+    eprintln!("verts={} batches={} plate modes={modes:?}", verts.len(), batches.len());
+    assert!(modes.contains(&13.0), "no lattice batch; modes={modes:?}");
+}
+
+#[test]
+fn graph_emits_grid_relief() {
+    use cce_ui::widget::GraphController;
+    let mut g = cce_ui::widget::Graph::new();
+    g.set_grid_sizes(71.0, 31.0);
+    g.set_skipped_sizes(12.0, 14.0);
+    g.set_grid_origin(50.0, 50.0);
+    g.set_show_network_grid(true);
+    // The designer hard-codes a uniform background; that must not hide the relief.
+    g.set_uniform_background(true);
+    let mut pc = PaintCtx::new();
+    let rect = Rect { x: 40.0, y: 40.0, width: 600.0, height: 300.0 };
+    g.paint_grid_relief(rect, &mut pc);
+    let dl = pc.finish();
+    let n_lattice = dl.items.iter().filter(|i| matches!(i.prim, Prim::Lattice { .. })).count();
+    let n_groove = dl.items.iter().filter(|i| matches!(i.prim, Prim::Groove { .. })).count();
+    assert_eq!((n_lattice, n_groove), (1, 2));
+}