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