repose_core/
view.rs

1use crate::{Color, Modifier, Rect, Transform};
2use std::rc::Rc;
3
4pub type ViewId = u64;
5
6pub type Callback = Rc<dyn Fn()>;
7pub type ScrollCallback = Rc<dyn Fn(f32) -> f32>;
8
9#[derive(Clone)]
10pub enum ViewKind {
11    Surface,
12    Box,
13    Row,
14    Column,
15    Stack,
16    ScrollV {
17        on_scroll: Option<ScrollCallback>,
18        set_viewport_height: Option<Rc<dyn Fn(f32)>>,
19        get_scroll_offset: Option<Rc<dyn Fn() -> f32>>,
20    },
21    Text {
22        text: String,
23        color: Color,
24        font_size: f32,
25    },
26    Button {
27        text: String,
28        on_click: Option<Callback>,
29    },
30    TextField {
31        state_key: ViewId,
32        hint: String,
33        on_change: Option<Rc<dyn Fn(String)>>,
34        on_submit: Option<Rc<dyn Fn(String)>>,
35    },
36    Checkbox {
37        checked: bool,
38        label: String,
39        on_change: Option<Rc<dyn Fn(bool)>>,
40    },
41    RadioButton {
42        selected: bool,
43        label: String,
44        on_select: Option<Callback>,
45    },
46    Switch {
47        checked: bool,
48        label: String,
49        on_change: Option<Rc<dyn Fn(bool)>>,
50    },
51    Slider {
52        value: f32,
53        min: f32,
54        max: f32,
55        step: Option<f32>,
56        label: String,
57        on_change: Option<CallbackF32>,
58    },
59    RangeSlider {
60        start: f32,
61        end: f32,
62        min: f32,
63        max: f32,
64        step: Option<f32>,
65        label: String,
66        on_change: Option<CallbackRange>,
67    },
68    ProgressBar {
69        value: f32,
70        min: f32,
71        max: f32,
72        label: String,
73        circular: bool,
74    },
75}
76
77impl std::fmt::Debug for ViewKind {
78    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
79        match self {
80            ViewKind::Checkbox { checked, label, .. } => f
81                .debug_struct("Checkbox")
82                .field("checked", checked)
83                .field("label", label)
84                .finish(),
85            ViewKind::RadioButton {
86                selected, label, ..
87            } => f
88                .debug_struct("RadioButton")
89                .field("selected", selected)
90                .field("label", label)
91                .finish(),
92            ViewKind::Switch { checked, label, .. } => f
93                .debug_struct("Switch")
94                .field("checked", checked)
95                .field("label", label)
96                .finish(),
97            ViewKind::Surface => write!(f, "Surface"),
98            ViewKind::Box => write!(f, "Box"),
99            ViewKind::Row => write!(f, "Row"),
100            ViewKind::Column => write!(f, "Column"),
101            ViewKind::Stack => write!(f, "Stack"),
102            ViewKind::ScrollV { .. } => write!(f, "ScrollV"),
103            ViewKind::Text {
104                text,
105                color,
106                font_size,
107            } => f
108                .debug_struct("Text")
109                .field("text", text)
110                .field("color", color)
111                .field("font_size", font_size)
112                .finish(),
113            ViewKind::Button { text, .. } => f
114                .debug_struct("Button")
115                .field("text", text)
116                .field("on_click", &"<callback>")
117                .finish(),
118            ViewKind::TextField {
119                state_key,
120                hint,
121                on_change,
122                on_submit,
123            } => f
124                .debug_struct("TextField")
125                .field("state_key", state_key)
126                .field("hint", hint)
127                .finish(),
128            ViewKind::Slider {
129                value,
130                min,
131                max,
132                step,
133                label,
134                ..
135            } => f
136                .debug_struct("Slider")
137                .field("value", value)
138                .field("min", min)
139                .field("max", max)
140                .field("step", step)
141                .field("label", label)
142                .finish(),
143            ViewKind::RangeSlider {
144                start,
145                end,
146                min,
147                max,
148                step,
149                label,
150                ..
151            } => f
152                .debug_struct("RangeSlider")
153                .field("start", start)
154                .field("end", end)
155                .field("min", min)
156                .field("max", max)
157                .field("step", step)
158                .field("label", label)
159                .finish(),
160            ViewKind::ProgressBar {
161                value,
162                min,
163                max,
164                label,
165                circular,
166            } => f
167                .debug_struct("ProgressBar")
168                .field("value", value)
169                .field("min", min)
170                .field("max", max)
171                .field("label", label)
172                .field("circular", circular)
173                .finish(),
174        }
175    }
176}
177
178#[derive(Clone, Debug)]
179pub struct View {
180    pub id: ViewId,
181    pub kind: ViewKind,
182    pub modifier: Modifier,
183    pub children: Vec<View>,
184    pub semantics: Option<crate::semantics::Semantics>,
185}
186
187impl View {
188    pub fn new(id: ViewId, kind: ViewKind) -> Self {
189        View {
190            id,
191            kind,
192            modifier: Modifier::default(),
193            children: vec![],
194            semantics: None,
195        }
196    }
197    pub fn modifier(mut self, m: Modifier) -> Self {
198        self.modifier = m;
199        self
200    }
201    pub fn with_children(mut self, kids: Vec<View>) -> Self {
202        self.children = kids;
203        self
204    }
205    pub fn semantics(mut self, s: crate::semantics::Semantics) -> Self {
206        self.semantics = Some(s);
207        self
208    }
209}
210
211/// Renderable scene
212#[derive(Clone, Debug, Default)]
213pub struct Scene {
214    pub clear_color: Color,
215    pub nodes: Vec<SceneNode>,
216}
217
218#[derive(Clone, Debug)]
219pub enum SceneNode {
220    Rect {
221        rect: Rect,
222        color: Color,
223        radius: f32,
224    },
225    Border {
226        rect: Rect,
227        color: Color,
228        width: f32,
229        radius: f32,
230    },
231    Text {
232        rect: Rect,
233        text: String,
234        color: Color,
235        size: f32,
236    },
237    PushClip {
238        rect: Rect,
239        radius: f32,
240    },
241    PopClip,
242    PushTransform {
243        transform: Transform,
244    },
245    PopTransform,
246}
247
248pub type CallbackF32 = Rc<dyn Fn(f32)>;
249pub type CallbackRange = Rc<dyn Fn(f32, f32)>;