GPU-accelerated UI toolkit (Vulkan)
git clone https://git.lucas.co/cce-ui.git
examples/frost_pair.rs (4K)
1 //! Three frosted plates, one recipe each, over a bright/dark checker — the
2 //! per-plate frost exit test of `docs/rfc-material.md` § 7 step 3.
3 //!
4 //! Left: compression 0 (the backdrop's luminance passes through). Middle:
5 //! compression 0.85 (the plate holds its own key). Right: a CLEAR plate
6 //! (radius 0 — one clean sample, tinted). Same tint on all three, the
7 //! designer's `#05050840`. Measured from a shadow screenshot as the swing in
8 //! mean luminance between the bright and dark checker columns under each
9 //! plate: the middle plate must swing far less than the left one, and the
10 //! right one must show the checker's edges sharp.
11 //!
12 //! Run it ONLY in a shadow session (`cce-shadow spawn`), never from the live
13 //! shell.
14
15 use cce_ui::engine::{Application, EngineState, LogicalPosition, LogicalSize, WindowSettings};
16 use cce_ui::scene::layout::Rect;
17 use cce_ui::scene::paint::{DisplayList, PaintCtx, PlateSpec};
18 use cce_ui::scene::{Frost, Material};
19 use cce_ui::widget::{ElementState, KeyEvent, MouseButton, MouseScrollDelta};
20 use wayland_client::QueueHandle;
21
22 /// Logical layout: 12 checker columns of `COL` px; three plates in thirds.
23 pub const COL: f32 = 35.0;
24 pub const W: f32 = 12.0 * COL;
25 pub const H: f32 = 210.0;
26 pub const PLATE_Y: f32 = 30.0;
27 pub const PLATE_H: f32 = H - 60.0;
28 pub const PLATE_INSET: f32 = 10.0;
29
30 /// The three recipes, left to right: (compression, radius).
31 pub const RECIPES: [(f32, f32); 3] = [(0.0, Frost::DEFAULT_RADIUS), (0.85, Frost::DEFAULT_RADIUS), (0.0, 0.0)];
32
33 /// The designer's tint, `#05050840` gamma-decoded.
34 pub const TINT: [f32; 4] = [0.0015, 0.0015, 0.0024, 0.25];
35
36 pub fn plate_rect(i: usize) -> Rect {
37 let third = W / 3.0;
38 Rect { x: PLATE_INSET + i as f32 * third, y: PLATE_Y, width: third - 2.0 * PLATE_INSET, height: PLATE_H }
39 }
40
41 struct FrostPair;
42
43 impl Application for FrostPair {
44 type Message = ();
45
46 fn new(_qh: &QueueHandle<EngineState<Self>>, _sender: calloop::channel::Sender<Self::Message>) -> Self {
47 FrostPair
48 }
49
50 fn settings(&self) -> WindowSettings {
51 WindowSettings {
52 title: "frost pair".to_string(),
53 app_id: "cce-frost-pair".to_string(),
54 width: W as u32,
55 height: H as u32,
56 fullscreen: false,
57 min_size: None,
58 }
59 }
60
61 fn update(&mut self, _msg: Self::Message, _needs_rebuild: &mut bool, _exit: &mut bool) {}
62 fn tick(&mut self, _dt: f32, _needs_rebuild: &mut bool) {}
63
64 fn display_list(&mut self, size: LogicalSize, scale: f64) -> Option<DisplayList> {
65 cce_ui::scale::set_scale_factor(scale as f32);
66 let (w, h) = (size.width as f32, size.height as f32);
67 let mut pc = PaintCtx::new();
68 pc.plate_spec(&PlateSpec {
69 rect: Rect { x: 0.0, y: 0.0, width: w, height: h },
70 material: Material::opaque([0.2, 0.2, 0.22, 1.0]),
71 window_corners: (true, true, true, true),
72 depth: cce_ui::layout::bevel_width(),
73 });
74 for i in 0..12 {
75 let c = if i % 2 == 0 { [1.0, 1.0, 1.0, 1.0] } else { [0.0, 0.0, 0.0, 1.0] };
76 pc.rounded_rect(Rect { x: i as f32 * COL, y: 0.0, width: COL, height: h }, 0.0, (false, false, false, false), c);
77 }
78 for (i, (k, radius)) in RECIPES.iter().enumerate() {
79 let m = Material::opaque(TINT).with_frost(Frost::Frosted { compression: *k, refraction: 0.0, radius: *radius });
80 pc.plate_spec(&PlateSpec { rect: plate_rect(i), material: m, window_corners: (false, false, false, false), depth: 6.0 });
81 }
82 Some(pc.finish())
83 }
84
85 fn handle_pointer_move(&mut self, _pos: LogicalPosition, _needs_rebuild: &mut bool) {}
86 fn handle_mouse_input(&mut self, _b: MouseButton, _s: ElementState, _p: LogicalPosition, _n: &mut bool) -> Option<Self::Message> {
87 None
88 }
89 fn handle_mouse_wheel(&mut self, _d: &MouseScrollDelta, _p: LogicalPosition, _n: &mut bool) {}
90 fn handle_key_input(&mut self, _e: &KeyEvent, _n: &mut bool) -> Option<Self::Message> {
91 None
92 }
93 }
94
95 fn main() {
96 cce_ui::engine::run::<FrostPair>();
97 }