tawasuyu/llimphi
Sovereign retained-mode GPU UI framework in Rust (wgpu+vello+taffy+parley), Elm loop, 40+ widgets.
chore: refresco desde el monorepo — vello 0.9 / wgpu 29, 120 miembros
1//! Showcase de `llimphi-widget-button`: tres botones con hover.
2//!
3//! Corre con: `cargo run -p llimphi-widget-button --example showcase --release`.
4
5use llimphi_ui::llimphi_layout::taffy::{
6 prelude::{length, percent, FlexDirection, Size, Style},
7 AlignItems, JustifyContent, Rect,
8};
9use llimphi_ui::llimphi_raster::peniko::Color;
10use llimphi_ui::llimphi_text::Alignment;
11use llimphi_ui::{App, Handle, View};
12use llimphi_widget_button::{button_styled, button_view, ButtonPalette};
13
14#[derive(Clone, Debug)]
15enum Msg {
16 A,
17 B,
18 C,
19}
20
21struct Model {
22 last: Option<Msg>,
23 counter: u32,
24}
25
26struct Showcase;
27
28impl App for Showcase {
29 type Model = Model;
30 type Msg = Msg;
31
32 fn title() -> &'static str {
33 "llimphi · button showcase"
34 }
35
36 fn init(_: &Handle<Msg>) -> Model {
37 Model {
38 last: None,
39 counter: 0,
40 }
41 }
42
43 fn update(model: Model, msg: Msg, _: &Handle<Msg>) -> Model {
44 let mut m = model;
45 m.counter += 1;
46 m.last = Some(msg);
47 m
48 }
49
50 fn view(model: &Model) -> View<Msg> {
51 let palette = ButtonPalette::default();
52 let warning = ButtonPalette {
53 bg: Color::from_rgba8(140, 70, 30, 255),
54 bg_hover: Color::from_rgba8(200, 100, 40, 255),
55 ..palette
56 };
57 let danger = ButtonPalette {
58 bg: Color::from_rgba8(150, 40, 40, 255),
59 bg_hover: Color::from_rgba8(220, 70, 70, 255),
60 ..palette
61 };
62
63 let a = button_view("acción A", &palette, Msg::A);
64 let b = button_view("acción B (warning)", &warning, Msg::B);
65 let c = button_styled(
66 "borrar (left-aligned, fixed width)",
67 Style {
68 size: Size {
69 width: length(320.0_f32),
70 height: length(34.0_f32),
71 },
72 padding: Rect {
73 left: length(12.0_f32),
74 right: length(12.0_f32),
75 top: length(0.0_f32),
76 bottom: length(0.0_f32),
77 },
78 align_items: Some(AlignItems::CENTER),
79 ..Default::default()
80 },
81 Alignment::Start,
82 &danger,
83 Msg::C,
84 );
85
86 let status = View::new(Style {
87 size: Size {
88 width: percent(1.0_f32),
89 height: length(40.0_f32),
90 },
91 ..Default::default()
92 })
93 .text_aligned(
94 format!(
95 "clicks: {} · último: {}",
96 model.counter,
97 match model.last {
98 Some(Msg::A) => "A",
99 Some(Msg::B) => "B",
100 Some(Msg::C) => "C",
101 None => "—",
102 }
103 ),
104 14.0,
105 Color::from_rgba8(180, 190, 205, 255),
106 Alignment::Start,
107 );
108
109 View::new(Style {
110 flex_direction: FlexDirection::Column,
111 size: Size {
112 width: percent(1.0_f32),
113 height: percent(1.0_f32),
114 },
115 gap: Size {
116 width: length(0.0_f32),
117 height: length(14.0_f32),
118 },
119 padding: Rect {
120 left: length(32.0_f32),
121 right: length(32.0_f32),
122 top: length(32.0_f32),
123 bottom: length(32.0_f32),
124 },
125 align_items: Some(AlignItems::START),
126 justify_content: Some(JustifyContent::START),
127 ..Default::default()
128 })
129 .fill(Color::from_rgba8(20, 24, 32, 255))
130 .children(vec![a, b, c, status])
131 }
132}
133
134fn main() {
135 llimphi_ui::run::<Showcase>();
136}