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