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