GPU-accelerated UI toolkit (Vulkan)
git clone https://git.lucas.co/cce-ui.git
fix: bring lattice_probe and two examples up to the current APIs
`graph_emits_grout_and_axes` still expected the cell-and-grout grid: one
Grout draw plus two axis quads. Since the 2026-09-22 lattice change,
`Graph::paint_grid` draws one quad per grid line and two heavier axes.
The test is now `graph_paints_its_lattice_as_lines_and_axes`: it pins
the pitch, origin and line width (which it used to take from the user's
config.kdl) and checks each line's position, the two axes, and that
nothing else is drawn.
carve_union_demo and trigger_near_roll_warning passed a bare colour to
`PaintCtx::plate` / `bevel`, which take a `&Material` since the plate
prims gained one (2e1abb3). Their colours are opaque, so they now pass
`Material::opaque`. `cargo test -p cce-ui` builds again.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
examples/carve_union_demo.rs | 3 +-
examples/trigger_near_roll_warning.rs | 5 ++--
tests/lattice_probe.rs | 55 ++++++++++++++++++++++++++++++-----
3 files changed, 53 insertions(+), 10 deletions(-)
diff --git a/examples/carve_union_demo.rs b/examples/carve_union_demo.rs
index 18154b1..5cc69ef 100644
--- a/examples/carve_union_demo.rs
+++ b/examples/carve_union_demo.rs
@@ -8,6 +8,7 @@
use cce_ui::engine::{Application, EngineState, LogicalPosition, LogicalSize, WindowSettings};
use cce_ui::scene::layout::Rect;
use cce_ui::scene::paint::{DisplayList, PaintCtx};
+use cce_ui::scene::Material;
use cce_ui::widget::{ElementState, KeyEvent, MouseButton, MouseScrollDelta};
use wayland_client::QueueHandle;
@@ -59,7 +60,7 @@ impl Application for DemoApp {
pc.plate(
Rect { x: 0.0, y: 0.0, width: w, height: h },
(12.0, 12.0, 12.0, 12.0),
- [0.42, 0.44, 0.50, 1.0],
+ &Material::opaque([0.42, 0.44, 0.50, 1.0]),
cce_ui::layout::bevel_width(),
);
let wall = 10.0;
diff --git a/examples/trigger_near_roll_warning.rs b/examples/trigger_near_roll_warning.rs
index 96b6801..2aae8c6 100644
--- a/examples/trigger_near_roll_warning.rs
+++ b/examples/trigger_near_roll_warning.rs
@@ -17,6 +17,7 @@
use cce_ui::engine::{Application, EngineState, LogicalPosition, LogicalSize, WindowSettings};
use cce_ui::scene::layout::Rect;
use cce_ui::scene::paint::{DisplayList, PaintCtx};
+use cce_ui::scene::Material;
use cce_ui::widget::{ElementState, KeyEvent, MouseButton, MouseScrollDelta};
use wayland_client::QueueHandle;
@@ -67,7 +68,7 @@ impl Application for TriggerApp {
pc.plate(
Rect { x: 0.0, y: 0.0, width: w, height: h },
(12.0, 12.0, 12.0, 12.0),
- [0.13, 0.13, 0.16, 1.0],
+ &Material::opaque([0.13, 0.13, 0.16, 1.0]),
roll,
);
// 2. A later plate overlapping where the carve goes: the occlusion
@@ -76,7 +77,7 @@ impl Application for TriggerApp {
pc.bevel(
Rect { x: 40.0, y: 100.0, width: 200.0, height: 80.0 },
(6.0, 6.0, 6.0, 6.0),
- [0.20, 0.20, 0.25, 1.0],
+ &Material::opaque([0.20, 0.20, 0.25, 1.0]),
3.0,
);
// 3. Full-ring untinted recess hugging the left edge: its shaded
diff --git a/tests/lattice_probe.rs b/tests/lattice_probe.rs
index 00244e3..ab643b2 100644
--- a/tests/lattice_probe.rs
+++ b/tests/lattice_probe.rs
@@ -19,23 +19,64 @@ fn lattice_survives_tessellation_inside_a_clip() {
assert!(modes.contains(&13.0), "no lattice batch; modes={modes:?}");
}
+/// The graph grid is a LATTICE of lines (since 2026-09-22): one quad per
+/// line centred on its pitch coordinate, clipped to the rect, plus the two
+/// heavier axes through the (0, 0) crossing. It used to be cells with grout
+/// between them, one `Grout` draw, which is why this test once asserted that.
#[test]
-fn graph_emits_grout_and_axes() {
+fn graph_paints_its_lattice_as_lines_and_axes() {
use cce_ui::widget::GraphController;
+ // The one style value this path reads. Pinned, or the user's config.kdl
+ // decides the answer (a width of 0 turns the lines off entirely). This
+ // binary builds cce-ui without cfg(test), so the write is to the shared
+ // registry, which no other test in this file reads.
+ cce_ui::layout::set_graph_line_width(1.0);
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_pitch(60.0, 50.0);
g.set_grid_origin(50.0, 50.0);
+ g.set_network_opacity(1.0);
g.set_show_network_grid(true);
- // The designer hard-codes a uniform background; that must not hide the relief.
+ // The designer hard-codes a uniform background; that must not hide the grid.
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(rect, &mut pc);
let dl = pc.finish();
- let n_grout = dl.items.iter().filter(|i| matches!(i.prim, Prim::Grout { .. })).count();
- let n_quad = dl.items.iter().filter(|i| matches!(i.prim, Prim::Quad { .. })).count();
- assert_eq!((n_grout, n_quad), (1, 2), "one grout draw + two axis lines");
+
+ assert!(!dl.items.iter().any(|i| matches!(i.prim, Prim::Grout { .. })), "the lattice draws no grout");
+ let quads: Vec<Rect> = dl
+ .items
+ .iter()
+ .filter_map(|i| match i.prim {
+ Prim::Quad { rect, .. } => Some(rect),
+ _ => None,
+ })
+ .collect();
+
+ // Verticals at x = 50 + 60c inside 40..640: 50, 110 … 590, ten of them;
+ // horizontals at y = 50 + 50r inside 40..340: 50, 100 … 300, six. No line
+ // sits within half a width of an edge, so none is clipped to a sliver.
+ let mut verticals: Vec<f32> = quads
+ .iter()
+ .filter(|q| q.width == 1.0 && q.height == rect.height)
+ .map(|q| q.x + 0.5)
+ .collect();
+ let mut horizontals: Vec<f32> = quads
+ .iter()
+ .filter(|q| q.height == 1.0 && q.width == rect.width)
+ .map(|q| q.y + 0.5)
+ .collect();
+ verticals.sort_by(f32::total_cmp);
+ horizontals.sort_by(f32::total_cmp);
+ assert_eq!(verticals, (0..10).map(|c| 50.0 + 60.0 * c as f32).collect::<Vec<_>>());
+ assert_eq!(horizontals, (0..6).map(|r| 50.0 + 50.0 * r as f32).collect::<Vec<_>>());
+
+ // The axes: 2 px, across the whole rect, centred on the origin.
+ let axes: Vec<&Rect> = quads.iter().filter(|q| q.width == 2.0 || q.height == 2.0).collect();
+ assert_eq!(axes.len(), 2, "two origin axes; quads: {quads:?}");
+ assert!(axes.iter().any(|q| q.height == 2.0 && q.y == 49.0 && q.width == rect.width));
+ assert!(axes.iter().any(|q| q.width == 2.0 && q.x == 49.0 && q.height == rect.height));
+ assert_eq!(quads.len(), 10 + 6 + 2, "nothing else is painted; quads: {quads:?}");
}
#[test]