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