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