GPU-accelerated UI toolkit (Vulkan)
git clone https://git.lucas.co/cce-ui.git
examples/frost_pair.rs (3.9K)
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::{AppSender, Application, 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
21 /// Logical layout: 12 checker columns of `COL` px; three plates in thirds.
22 pub const COL: f32 = 35.0;
23 pub const W: f32 = 12.0 * COL;
24 pub const H: f32 = 210.0;
25 pub const PLATE_Y: f32 = 30.0;
26 pub const PLATE_H: f32 = H - 60.0;
27 pub const PLATE_INSET: f32 = 10.0;
28
29 /// The three recipes, left to right: (compression, radius).
30 pub const RECIPES: [(f32, f32); 3] = [(0.0, Frost::DEFAULT_RADIUS), (0.85, Frost::DEFAULT_RADIUS), (0.0, 0.0)];
31
32 /// The designer's tint, `#05050840` gamma-decoded.
33 pub const TINT: [f32; 4] = [0.0015, 0.0015, 0.0024, 0.25];
34
35 pub fn plate_rect(i: usize) -> Rect {
36 let third = W / 3.0;
37 Rect { x: PLATE_INSET + i as f32 * third, y: PLATE_Y, width: third - 2.0 * PLATE_INSET, height: PLATE_H }
38 }
39
40 struct FrostPair;
41
42 impl Application for FrostPair {
43 type Message = ();
44
45 fn create(_sender: AppSender<Self::Message>) -> Self {
46 FrostPair
47 }
48
49 fn settings(&self) -> WindowSettings {
50 WindowSettings {
51 title: "frost pair".to_string(),
52 app_id: "cce-frost-pair".to_string(),
53 width: W as u32,
54 height: H as u32,
55 fullscreen: false,
56 min_size: None,
57 }
58 }
59
60 fn update(&mut self, _msg: Self::Message, _needs_rebuild: &mut bool, _exit: &mut bool) {}
61 fn tick(&mut self, _dt: f32, _needs_rebuild: &mut bool) {}
62
63 fn display_list(&mut self, size: LogicalSize, scale: f64) -> Option<DisplayList> {
64 cce_ui::scale::set_scale_factor(scale as f32);
65 let (w, h) = (size.width, size.height);
66 let mut pc = PaintCtx::new();
67 pc.plate_spec(&PlateSpec {
68 rect: Rect { x: 0.0, y: 0.0, width: w, height: h },
69 material: Material::opaque([0.2, 0.2, 0.22, 1.0]),
70 window_corners: (true, true, true, true),
71 depth: cce_ui::layout::bevel_width(),
72 });
73 for i in 0..12 {
74 let c = if i % 2 == 0 { [1.0, 1.0, 1.0, 1.0] } else { [0.0, 0.0, 0.0, 1.0] };
75 pc.rounded_rect(Rect { x: i as f32 * COL, y: 0.0, width: COL, height: h }, 0.0, (false, false, false, false), c);
76 }
77 for (i, (k, radius)) in RECIPES.iter().enumerate() {
78 let m = Material::opaque(TINT).with_frost(Frost::Frosted { compression: *k, refraction: 0.0, radius: *radius });
79 pc.plate_spec(&PlateSpec { rect: plate_rect(i), material: m, window_corners: (false, false, false, false), depth: 6.0 });
80 }
81 Some(pc.finish())
82 }
83
84 fn handle_pointer_move(&mut self, _pos: LogicalPosition, _needs_rebuild: &mut bool) {}
85 fn handle_mouse_input(&mut self, _b: MouseButton, _s: ElementState, _p: LogicalPosition, _n: &mut bool) -> Option<Self::Message> {
86 None
87 }
88 fn handle_mouse_wheel(&mut self, _d: &MouseScrollDelta, _p: LogicalPosition, _n: &mut bool) {}
89 fn handle_key_input(&mut self, _e: &KeyEvent, _n: &mut bool) -> Option<Self::Message> {
90 None
91 }
92 }
93
94 fn main() {
95 cce_ui::engine::run::<FrostPair>();
96 }