1use serde::Deserialize;
2use serde_json::json;
3use std::borrow::Cow;
4
5use crate::{
6 color::Color,
7 fonts::{FontId, GlyphId},
8 geometry::{rect::RectF, vector::Vector2F},
9 json::ToJson,
10};
11
12pub struct Scene {
13 scale_factor: f32,
14 layers: Vec<Layer>,
15 active_layer_stack: Vec<usize>,
16}
17
18#[derive(Default)]
19pub struct Layer {
20 clip_bounds: Option<RectF>,
21 quads: Vec<Quad>,
22 shadows: Vec<Shadow>,
23 glyphs: Vec<Glyph>,
24 icons: Vec<Icon>,
25 paths: Vec<Path>,
26}
27
28#[derive(Default, Debug)]
29pub struct Quad {
30 pub bounds: RectF,
31 pub background: Option<Color>,
32 pub border: Border,
33 pub corner_radius: f32,
34}
35
36#[derive(Debug)]
37pub struct Shadow {
38 pub bounds: RectF,
39 pub corner_radius: f32,
40 pub sigma: f32,
41 pub color: Color,
42}
43
44#[derive(Debug)]
45pub struct Glyph {
46 pub font_id: FontId,
47 pub font_size: f32,
48 pub id: GlyphId,
49 pub origin: Vector2F,
50 pub color: Color,
51}
52
53pub struct Icon {
54 pub bounds: RectF,
55 pub svg: usvg::Tree,
56 pub path: Cow<'static, str>,
57 pub color: Color,
58}
59
60#[derive(Clone, Copy, Default, Debug)]
61pub struct Border {
62 pub width: f32,
63 pub color: Color,
64 pub top: bool,
65 pub right: bool,
66 pub bottom: bool,
67 pub left: bool,
68}
69
70impl<'de> Deserialize<'de> for Border {
71 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
72 where
73 D: serde::Deserializer<'de>,
74 {
75 #[derive(Deserialize)]
76 struct BorderData {
77 pub width: f32,
78 pub color: Color,
79 #[serde(default)]
80 pub top: bool,
81 #[serde(default)]
82 pub right: bool,
83 #[serde(default)]
84 pub bottom: bool,
85 #[serde(default)]
86 pub left: bool,
87 }
88
89 let data = BorderData::deserialize(deserializer)?;
90 let mut border = Border {
91 width: data.width,
92 color: data.color,
93 top: data.top,
94 bottom: data.bottom,
95 left: data.left,
96 right: data.right,
97 };
98 if !border.top && !border.bottom && !border.left && !border.right {
99 border.top = true;
100 border.bottom = true;
101 border.left = true;
102 border.right = true;
103 }
104 Ok(border)
105 }
106}
107
108#[derive(Debug)]
109pub struct Path {
110 pub bounds: RectF,
111 pub color: Color,
112 pub vertices: Vec<PathVertex>,
113}
114
115#[derive(Debug)]
116pub struct PathVertex {
117 pub xy_position: Vector2F,
118 pub st_position: Vector2F,
119}
120
121impl Scene {
122 pub fn new(scale_factor: f32) -> Self {
123 Scene {
124 scale_factor,
125 layers: vec![Layer::new(None)],
126 active_layer_stack: vec![0],
127 }
128 }
129
130 pub fn scale_factor(&self) -> f32 {
131 self.scale_factor
132 }
133
134 pub fn layers(&self) -> &[Layer] {
135 self.layers.as_slice()
136 }
137
138 pub fn push_layer(&mut self, clip_bounds: Option<RectF>) {
139 let ix = self.layers.len();
140 self.layers.push(Layer::new(clip_bounds));
141 self.active_layer_stack.push(ix);
142 }
143
144 pub fn pop_layer(&mut self) {
145 assert!(self.active_layer_stack.len() > 1);
146 self.active_layer_stack.pop();
147 }
148
149 pub fn push_quad(&mut self, quad: Quad) {
150 self.active_layer().push_quad(quad)
151 }
152
153 pub fn push_shadow(&mut self, shadow: Shadow) {
154 self.active_layer().push_shadow(shadow)
155 }
156
157 pub fn push_glyph(&mut self, glyph: Glyph) {
158 self.active_layer().push_glyph(glyph)
159 }
160
161 pub fn push_icon(&mut self, icon: Icon) {
162 self.active_layer().push_icon(icon)
163 }
164
165 pub fn push_path(&mut self, path: Path) {
166 self.active_layer().push_path(path);
167 }
168
169 fn active_layer(&mut self) -> &mut Layer {
170 &mut self.layers[*self.active_layer_stack.last().unwrap()]
171 }
172}
173
174impl Layer {
175 pub fn new(clip_bounds: Option<RectF>) -> Self {
176 Self {
177 clip_bounds,
178 quads: Vec::new(),
179 shadows: Vec::new(),
180 glyphs: Vec::new(),
181 icons: Vec::new(),
182 paths: Vec::new(),
183 }
184 }
185
186 pub fn clip_bounds(&self) -> Option<RectF> {
187 self.clip_bounds
188 }
189
190 fn push_quad(&mut self, quad: Quad) {
191 self.quads.push(quad);
192 }
193
194 pub fn quads(&self) -> &[Quad] {
195 self.quads.as_slice()
196 }
197
198 fn push_shadow(&mut self, shadow: Shadow) {
199 self.shadows.push(shadow);
200 }
201
202 pub fn shadows(&self) -> &[Shadow] {
203 self.shadows.as_slice()
204 }
205
206 fn push_glyph(&mut self, glyph: Glyph) {
207 self.glyphs.push(glyph);
208 }
209
210 pub fn glyphs(&self) -> &[Glyph] {
211 self.glyphs.as_slice()
212 }
213
214 pub fn push_icon(&mut self, icon: Icon) {
215 self.icons.push(icon);
216 }
217
218 pub fn icons(&self) -> &[Icon] {
219 self.icons.as_slice()
220 }
221
222 fn push_path(&mut self, path: Path) {
223 if !path.bounds.is_empty() {
224 self.paths.push(path);
225 }
226 }
227
228 pub fn paths(&self) -> &[Path] {
229 self.paths.as_slice()
230 }
231}
232
233impl Border {
234 pub fn new(width: f32, color: Color) -> Self {
235 Self {
236 width,
237 color,
238 top: false,
239 left: false,
240 bottom: false,
241 right: false,
242 }
243 }
244
245 pub fn all(width: f32, color: Color) -> Self {
246 Self {
247 width,
248 color,
249 top: true,
250 left: true,
251 bottom: true,
252 right: true,
253 }
254 }
255
256 pub fn top(width: f32, color: Color) -> Self {
257 let mut border = Self::new(width, color);
258 border.top = true;
259 border
260 }
261
262 pub fn left(width: f32, color: Color) -> Self {
263 let mut border = Self::new(width, color);
264 border.left = true;
265 border
266 }
267
268 pub fn bottom(width: f32, color: Color) -> Self {
269 let mut border = Self::new(width, color);
270 border.bottom = true;
271 border
272 }
273
274 pub fn right(width: f32, color: Color) -> Self {
275 let mut border = Self::new(width, color);
276 border.right = true;
277 border
278 }
279
280 pub fn with_sides(mut self, top: bool, left: bool, bottom: bool, right: bool) -> Self {
281 self.top = top;
282 self.left = left;
283 self.bottom = bottom;
284 self.right = right;
285 self
286 }
287
288 pub fn top_width(&self) -> f32 {
289 if self.top {
290 self.width
291 } else {
292 0.0
293 }
294 }
295
296 pub fn left_width(&self) -> f32 {
297 if self.left {
298 self.width
299 } else {
300 0.0
301 }
302 }
303}
304
305impl ToJson for Border {
306 fn to_json(&self) -> serde_json::Value {
307 let mut value = json!({});
308 if self.top {
309 value["top"] = json!(self.width);
310 }
311 if self.right {
312 value["right"] = json!(self.width);
313 }
314 if self.bottom {
315 value["bottom"] = json!(self.width);
316 }
317 if self.left {
318 value["left"] = json!(self.width);
319 }
320 value
321 }
322}