Skip to main content

selectable_text/
selectable_text.rs

1//! Texto seleccionable **fuera del editor**: arrastrá el mouse sobre los
2//! párrafos para resaltar y Ctrl/Cmd+C para copiar al portapapeles. La
3//! selección la maneja el runtime (`View::selectable(key)`) — la app no
4//! guarda estado de selección en su `Model`.
5//!
6//! Corre con: `cargo run -p llimphi-ui --example selectable_text --release`.
7
8use llimphi_ui::llimphi_layout::taffy::{
9    prelude::{length, percent, Dimension, FlexDirection, Rect, Size, Style},
10    AlignItems,
11};
12use llimphi_ui::llimphi_raster::peniko::Color;
13use llimphi_ui::llimphi_text::Alignment;
14use llimphi_ui::{App, Handle, View};
15
16struct Demo;
17
18const PARRAFOS: [&str; 3] = [
19    "Arrastrá el cursor sobre este texto para seleccionarlo. La selección \
20     vive en el runtime de Llimphi, no en el Model de la app.",
21    "Cada párrafo tiene su propia key estable; empezar a arrastrar en otro \
22     reemplaza la selección anterior. Ctrl+C (o Cmd+C en macOS) copia el \
23     rango resaltado al portapapeles del sistema.",
24    "No es un editor: es texto de sólo lectura que igual se puede leer, \
25     resaltar y copiar — labels, párrafos, celdas, salidas de consola.",
26];
27
28impl App for Demo {
29    type Model = ();
30    type Msg = ();
31
32    fn title() -> &'static str {
33        "llimphi · texto seleccionable"
34    }
35
36    fn init(_: &Handle<Self::Msg>) -> Self::Model {}
37
38    fn update(_: Self::Model, _: Self::Msg, _: &Handle<Self::Msg>) -> Self::Model {}
39
40    fn view(_: &Self::Model) -> View<Self::Msg> {
41        let mut children: Vec<View<()>> = vec![View::new(Style {
42            size: Size {
43                width: percent(1.0_f32),
44                height: Dimension::auto(),
45            },
46            ..Default::default()
47        })
48        .text_aligned(
49            "Texto seleccionable (arrastrá + Ctrl/Cmd+C)",
50            22.0,
51            Color::from_rgba8(230, 240, 250, 255),
52            Alignment::Start,
53        )];
54
55        for (i, p) in PARRAFOS.iter().enumerate() {
56            children.push(
57                View::new(Style {
58                    size: Size {
59                        width: percent(1.0_f32),
60                        height: Dimension::auto(),
61                    },
62                    ..Default::default()
63                })
64                .text_aligned(
65                    *p,
66                    16.0,
67                    Color::from_rgba8(205, 214, 226, 255),
68                    Alignment::Start,
69                )
70                // La línea clave: cada párrafo es seleccionable con una key
71                // estable (su índice). El resaltado + copy los hace el runtime.
72                .selectable(i as u64),
73            );
74        }
75
76        View::new(Style {
77            flex_direction: FlexDirection::Column,
78            size: Size {
79                width: percent(1.0_f32),
80                height: percent(1.0_f32),
81            },
82            gap: Size {
83                width: length(0.0_f32),
84                height: length(20.0_f32),
85            },
86            padding: Rect {
87                left: length(40.0_f32),
88                right: length(40.0_f32),
89                top: length(36.0_f32),
90                bottom: length(36.0_f32),
91            },
92            align_items: Some(AlignItems::Start),
93            ..Default::default()
94        })
95        .fill(Color::from_rgba8(20, 24, 32, 255))
96        .children(children)
97    }
98}
99
100fn main() {
101    llimphi_ui::run::<Demo>();
102}