tawasuyu

tawasuyu/llimphi

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

Rust 660Markdown 302TOML 157RON 312382 Definiciones

⎇ main llimphi-ui/examples/content_type.rs Rust · 103 líneas · 3.1 KB Historia Quién tocó qué crudo

chore: refresco desde el monorepo — vello 0.9 / wgpu 29, 120 miembros d251eb32b · Sergio ·

1//! Declarar el **tipo de contenido** de la ventana (`wp_content_type_v1`).
2//!
3//! Cicla `None → Photo → Video → Game` con cada click y se lo declara al
4//! compositor por [`Handle::set_content_type`]. No cambia nada de lo que se
5//! pinta: es una pista para que el compositor ajuste su política (mirada deja de
6//! animar su fondo de marca ante contenido con ritmo propio, y decide VRR y
7//! tearing con lo mismo).
8//!
9//! Corre con: `cargo run -p llimphi-ui --example content_type --release`.
10//!
11//! Para **ver el protocolo en el cable** (que es como se verificó el puente
12//! winit↔wayland-client):
13//!
14//! ```sh
15//! WAYLAND_DEBUG=1 cargo run -p llimphi-ui --example content_type --release 2>&1 \
16//!   | grep content_type
17//! ```
18//!
19//! Tienen que aparecer el `get_surface_content_type` y un `set_content_type`
20//! por cada click. Si no aparece ninguno, el compositor no expone el global (el
21//! módulo avisa por stderr una sola vez y sigue sin romper nada).
22
23use llimphi_ui::llimphi_layout::taffy::{
24    prelude::{percent, Dimension, Size, Style},
25    AlignItems, JustifyContent,
26};
27use llimphi_ui::llimphi_raster::peniko::Color;
28use llimphi_ui::{App, ContentType, Handle, View};
29
30#[derive(Clone)]
31enum Msg {
32    Ciclar,
33}
34
35struct Demo;
36
37fn siguiente(k: ContentType) -> ContentType {
38    match k {
39        ContentType::None => ContentType::Photo,
40        ContentType::Photo => ContentType::Video,
41        ContentType::Video => ContentType::Game,
42        ContentType::Game => ContentType::None,
43    }
44}
45
46fn nombre(k: ContentType) -> &'static str {
47    match k {
48        ContentType::None => "none",
49        ContentType::Photo => "photo",
50        ContentType::Video => "video",
51        ContentType::Game => "game",
52    }
53}
54
55impl App for Demo {
56    type Model = ContentType;
57    type Msg = Msg;
58
59    fn title() -> &'static str {
60        "llimphi · content type"
61    }
62
63    fn init(handle: &Handle<Self::Msg>) -> Self::Model {
64        // Declarar el estado inicial también: el compositor arranca asumiendo
65        // `none`, y una app que nace mostrando video quiere decirlo ya.
66        handle.set_content_type(ContentType::None);
67        ContentType::None
68    }
69
70    fn update(model: Self::Model, msg: Self::Msg, handle: &Handle<Self::Msg>) -> Self::Model {
71        match msg {
72            Msg::Ciclar => {
73                let nuevo = siguiente(model);
74                handle.set_content_type(nuevo);
75                nuevo
76            }
77        }
78    }
79
80    fn view(model: &Self::Model) -> View<Self::Msg> {
81        View::new(Style {
82            size: Size {
83                width: percent(1.0_f32),
84                height: Dimension::auto(),
85            },
86            flex_grow: 1.0,
87            align_items: Some(AlignItems::CENTER),
88            justify_content: Some(JustifyContent::CENTER),
89            ..Default::default()
90        })
91        .fill(Color::from_rgba8(16, 18, 26, 255))
92        .text(
93            format!("content type: {}", nombre(*model)),
94            42.0,
95            Color::from_rgba8(230, 240, 250, 255),
96        )
97        .on_click(Msg::Ciclar)
98    }
99}
100
101fn main() {
102    llimphi_ui::run::<Demo>();
103}