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

examples/grouped_recess_probe.rs (4.1K)

 1 //! A visual check that a recess GROUPED into its plate as a CSG feature
 2 //! shades like the same recess drawn as an overlay. Left plate: the recesses
 3 //! group (nothing else is painted between the plate and them). Right plate:
 4 //! the same recesses, but a transparent quad painted first closes the plate's
 5 //! grouping window, so each one falls back to the overlay. The two columns
 6 //! should read alike on every device — compare `CCE_VK_DEVICE=discrete`
 7 //! against the default. `CCE_PLATE_DEBUG=1` prints the grouping verdicts.
 8 //! Run inside a Wayland session (a cce-shadow instance works):
 9 //! `cargo run --release -p cce-ui --example grouped_recess_probe`.
10 
11 use cce_ui::engine::{AppSender, Application, LogicalPosition, LogicalSize, WindowSettings};
12 use cce_ui::scene::layout::Rect;
13 use cce_ui::scene::paint::{DisplayList, PaintCtx};
14 use cce_ui::scene::Material;
15 use cce_ui::widget::{ElementState, KeyEvent, MouseButton, MouseScrollDelta};
16 
17 struct ProbeApp;
18 
19 /// The probe's recesses, relative to a plate's top-left: (rect, radius,
20 /// depth) at the sizes the parameter pane uses — a text box, a toggle's
21 /// track, a colour well — and a couple of deeper ones.
22 fn recesses(x: f32, y: f32) -> Vec<(Rect, f32, f32)> {
23     let w = cce_ui::layout::bevel_width();
24     let mut out = Vec::new();
25     let mut yy = y + 30.0;
26     for (h, wide) in [(20.0, 260.0), (20.0, 120.0), (28.0, 260.0), (40.0, 260.0), (70.0, 260.0)] {
27         let depth = w.min(h * 0.2);
28         out.push((Rect { x: x + 30.0, y: yy, width: wide, height: h }, (h * 0.5).min(8.0), depth));
29         yy += h + 24.0;
30     }
31     out
32 }
33 
34 impl Application for ProbeApp {
35     type Message = ();
36 
37     fn create(_sender: AppSender<()>) -> Self {
38         Self
39     }
40 
41     fn settings(&self) -> WindowSettings {
42         WindowSettings {
43             title: "grouped recess probe".into(),
44             app_id: "cce-grouped-recess-probe".into(),
45             width: 720,
46             height: 400,
47             fullscreen: false,
48             min_size: None,
49         }
50     }
51 
52     fn update(&mut self, _msg: (), _needs_rebuild: &mut bool, _exit: &mut bool) {}
53 
54     fn tick(&mut self, _dt: f32, _needs_rebuild: &mut bool) {}
55 
56     fn display_list(&mut self, size: LogicalSize, _scale: f64) -> Option<DisplayList> {
57         let mut pc = PaintCtx::new();
58         let (w, h) = (size.width, size.height);
59         let half = (w - 30.0) * 0.5;
60         let bevel = cce_ui::layout::bevel_width();
61         for (i, x) in [10.0, 20.0 + half].into_iter().enumerate() {
62             let plate = Rect { x, y: 10.0, width: half, height: h - 20.0 };
63             pc.plate(plate, (16.0, 16.0, 16.0, 16.0), &Material::pane(), bevel);
64             if i == 1 {
65                 // Ordinary geometry between the plate and its carves closes
66                 // the grouping window: every recess below is an overlay.
67                 pc.quad(Rect { x: x + 1.0, y: 11.0, width: 1.0, height: 1.0 }, [0.0; 4]);
68             }
69             for (r, radius, depth) in recesses(x, 10.0) {
70                 pc.recess(r, (radius, radius, radius, radius), depth);
71             }
72             // A boss, and a recess running into the plate's roll — the
73             // junction grouping exists for (the overlay fades out there
74             // instead, so the two columns differ by design at its right end).
75             let boss = Rect { x: x + 30.0, y: h - 60.0, width: 120.0, height: 30.0 };
76             pc.boss(boss, (8.0, 8.0, 8.0, 8.0), 6.0);
77             let edge = Rect { x: x + 180.0, y: h - 60.0, width: half - 180.0 - 2.0, height: 30.0 };
78             pc.recess(edge, (8.0, 8.0, 8.0, 8.0), 6.0);
79         }
80         Some(pc.finish())
81     }
82 
83     fn display_list_text(&self) -> bool {
84         true
85     }
86 
87     fn handle_pointer_move(&mut self, _pos: LogicalPosition, _needs_rebuild: &mut bool) {}
88     fn handle_mouse_input(&mut self, _b: MouseButton, _s: ElementState, _p: LogicalPosition, _r: &mut bool) -> Option<()> {
89         None
90     }
91     fn handle_mouse_wheel(&mut self, _d: &MouseScrollDelta, _p: LogicalPosition, _r: &mut bool) {}
92     fn handle_key_input(&mut self, _e: &KeyEvent, _r: &mut bool) -> Option<()> {
93         None
94     }
95 }
96 
97 fn main() {
98     cce_ui::engine::run::<ProbeApp>();
99 }