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