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#[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)>;