git.lucas.co / cce-ui
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 }