tawasuyu

tawasuyu/llimphi

Sovereign retained-mode GPU UI framework in Rust (wgpu+vello+taffy+parley), Elm loop, 40+ widgets.

Rust 660Markdown 302TOML 157RON 312382 Definitions

⎇ main llimphi-wasm-demo-counter/src/lib.rs Rust · 79 lines · 2.3 KB History Who touched what raw

chore: refresco desde el monorepo — 27 crates nuevos (anim, lottie, svg, mesh, image, layer, test, wire-view, widgets rag-sidebar/router/lazy-list/rive-button) y sync de los 95 existentes 93253cc22 · Sergio ·

1//! Contador Elm canónico de Llimphi, como app WASM Tier 3.
2//!
3//! Gemelo de `llimphi-ui/examples/counter.rs`, pero `Model`/`update`/`view`
4//! corren del lado guest; el host materializa el `WireNode` y rebota los clicks.
5//! Compilar con `scripts/build-wasm-demo.sh`.
6
7use llimphi_wasm_app_sdk::{
8    col, export_wasm_app, row, text, Align, Dim, Justify, TextAlign, Ui, WasmApp, WireNode,
9};
10
11/// Mensajes del contador. Sólo `Clone`: no cruzan la frontera (lo hace el
12/// EventPayload), así que no necesitan (de)serializar.
13#[derive(Clone)]
14pub enum Msg {
15    Increment,
16    Reset,
17}
18
19pub struct Counter {
20    n: u32,
21}
22
23impl WasmApp for Counter {
24    type Msg = Msg;
25
26    fn init() -> Self {
27        Counter { n: 0 }
28    }
29
30    fn update(&mut self, msg: Msg) {
31        match msg {
32            Msg::Increment => self.n = self.n.saturating_add(1),
33            Msg::Reset => self.n = 0,
34        }
35    }
36
37    fn view(&self, ui: &mut Ui<Msg>) -> WireNode {
38        let number = text(self.n.to_string(), 160.0, [230, 240, 250, 255])
39            .text_align(TextAlign::Center)
40            .grow(1.0)
41            .width(Dim::Pct(1.0))
42            .align(Align::Center)
43            .justify(Justify::Center);
44
45        // El +1 es el primer control registrado ⇒ EventId 0; reset ⇒ 1.
46        let inc = ui
47            .button("+1", 28.0, [10, 30, 20, 255], Msg::Increment)
48            .text_align(TextAlign::Center)
49            .fill([60, 200, 130, 255])
50            .radius(12.0)
51            .size(Dim::Px(160.0), Dim::Px(56.0))
52            .align(Align::Center)
53            .justify(Justify::Center);
54
55        let reset = ui
56            .button("reset", 22.0, [30, 10, 10, 255], Msg::Reset)
57            .text_align(TextAlign::Center)
58            .fill([220, 80, 80, 255])
59            .radius(12.0)
60            .size(Dim::Px(120.0), Dim::Px(56.0))
61            .align(Align::Center)
62            .justify(Justify::Center);
63
64        let buttons = row(vec![inc, reset])
65            .gap(16.0)
66            .justify(Justify::Center)
67            .width(Dim::Pct(1.0))
68            .height(Dim::Px(56.0));
69
70        col(vec![number, buttons])
71            .gap(24.0)
72            .pad(32.0)
73            .fill([20, 24, 32, 255])
74            .width(Dim::Pct(1.0))
75            .height(Dim::Pct(1.0))
76    }
77}
78
79export_wasm_app!(Counter);