GPU-accelerated UI toolkit (Vulkan)
git clone https://git.lucas.co/cce-ui.git
examples/trigger_near_roll_warning.rs (4.1K)
1 //! Deliberately fires the debug-build "near-roll carve lost grouping" warning
2 //! (`near_roll_fallback_reason` in `backend/window_runner.rs`), so the loud
3 //! path can be seen working: a window plate opens the grouping window, a later
4 //! Bevel plate overlaps where the carve will go, and a full-ring recess hugging
5 //! the left roll is then rejected by the occlusion rule — groupable geometry,
6 //! still-open enclosing plate, shaded region in the roll band, dynamic
7 //! rejection. Expect one line on stderr:
8 //!
9 //! plate-carve: near-roll recess (2,110 260x60) lost grouping — a later
10 //! plate overlaps the carve's shaded region; ...
11 //!
12 //! Debug builds only (`cargo run -p cce-ui --example trigger_near_roll_warning`
13 //! inside a Wayland session — a cce-shadow instance works); a release build
14 //! compiles the warning out and prints nothing. Exits by itself after a few
15 //! frames.
16
17 use cce_ui::engine::{AppSender, Application, LogicalPosition, LogicalSize, WindowSettings};
18 use cce_ui::scene::layout::Rect;
19 use cce_ui::scene::paint::{DisplayList, PaintCtx};
20 use cce_ui::scene::Material;
21 use cce_ui::widget::{ElementState, KeyEvent, MouseButton, MouseScrollDelta};
22
23 struct TriggerApp {
24 ticks: u32,
25 }
26
27 impl Application for TriggerApp {
28 type Message = ();
29
30 fn create(_sender: AppSender<Self::Message>) -> Self {
31 Self { ticks: 0 }
32 }
33
34 fn settings(&self) -> WindowSettings {
35 WindowSettings {
36 title: "near-roll trigger".into(),
37 app_id: "cce-trigger-near-roll".into(),
38 width: 800,
39 height: 600,
40 fullscreen: false,
41 min_size: None,
42 }
43 }
44
45 fn update(&mut self, _msg: (), _needs_rebuild: &mut bool, _exit: &mut bool) {}
46
47 fn tick(&mut self, _dt: f32, needs_rebuild: &mut bool) {
48 // Keep rendering a few frames so the first real present definitely
49 // carried the display list, then leave. (The warning itself prints
50 // once regardless of how many frames run.)
51 self.ticks += 1;
52 *needs_rebuild = true;
53 if self.ticks > 20 {
54 std::process::exit(0);
55 }
56 }
57
58 fn display_list(&mut self, size: LogicalSize, _scale: f64) -> Option<DisplayList> {
59 let mut pc = PaintCtx::new();
60 let (w, h) = (size.width, size.height);
61 let roll = cce_ui::layout::bevel_width();
62
63 // 1. The window plate — opens the carve-grouping window.
64 pc.plate(
65 Rect { x: 0.0, y: 0.0, width: w, height: h },
66 (12.0, 12.0, 12.0, 12.0),
67 &Material::opaque([0.13, 0.13, 0.16, 1.0]),
68 roll,
69 );
70 // 2. A later plate overlapping where the carve goes: the occlusion
71 // rule must reject grouping (the carve's shading would land beneath
72 // these pixels in the window plate's earlier draw).
73 pc.bevel(
74 Rect { x: 40.0, y: 100.0, width: 200.0, height: 80.0 },
75 (6.0, 6.0, 6.0, 6.0),
76 &Material::opaque([0.20, 0.20, 0.25, 1.0]),
77 3.0,
78 );
79 // 3. Full-ring untinted recess hugging the left edge: its shaded
80 // region (rect inflated by depth/2 + 2) reaches into the window
81 // plate's roll band, so the fallback is the loud case.
82 pc.recess(
83 Rect { x: 2.0, y: 110.0, width: 260.0, height: 60.0 },
84 (6.0, 6.0, 6.0, 6.0),
85 6.0,
86 );
87 Some(pc.finish())
88 }
89
90 fn display_list_text(&self) -> bool {
91 true
92 }
93
94 fn handle_pointer_move(&mut self, _pos: LogicalPosition, _needs_rebuild: &mut bool) {}
95 fn handle_mouse_input(
96 &mut self,
97 _button: MouseButton,
98 _state: ElementState,
99 _pos: LogicalPosition,
100 _needs_rebuild: &mut bool,
101 ) -> Option<()> {
102 None
103 }
104 fn handle_mouse_wheel(
105 &mut self,
106 _delta: &MouseScrollDelta,
107 _pos: LogicalPosition,
108 _needs_rebuild: &mut bool,
109 ) {
110 }
111 fn handle_key_input(&mut self, _event: &KeyEvent, _needs_rebuild: &mut bool) -> Option<()> {
112 None
113 }
114 }
115
116 fn main() {
117 cce_ui::engine::run::<TriggerApp>();
118 }