1use core::f32;
2
3use crate::{color::ColorU, geometry::rect::RectF};
4pub struct Scene {
5 scale_factor: f32,
6 layers: Vec<Layer>,
7 active_layer_stack: Vec<usize>,
8}
9
10#[derive(Default)]
11pub struct Layer {
12 clip_bounds: Option<RectF>,
13 quads: Vec<Quad>,
14 shadows: Vec<Shadow>,
15}
16
17#[derive(Default, Debug)]
18pub struct Quad {
19 pub bounds: RectF,
20 pub background: Option<ColorU>,
21 pub border: Border,
22 pub corner_radius: f32,
23}
24
25pub struct Shadow {
26 pub bounds: RectF,
27 pub corner_radius: f32,
28 pub sigma: f32,
29 pub color: ColorU,
30}
31
32#[derive(Clone, Copy, Default, Debug)]
33pub struct Border {
34 pub width: f32,
35 pub color: Option<ColorU>,
36 pub top: bool,
37 pub right: bool,
38 pub bottom: bool,
39 pub left: bool,
40}
41
42impl Scene {
43 pub fn new(scale_factor: f32) -> Self {
44 Scene {
45 scale_factor,
46 layers: vec![Layer::default()],
47 active_layer_stack: vec![0],
48 }
49 }
50
51 pub fn scale_factor(&self) -> f32 {
52 self.scale_factor
53 }
54
55 pub fn layers(&self) -> &[Layer] {
56 self.layers.as_slice()
57 }
58
59 // pub fn push_layer(&mut self, clip_bounds: Option<RectF>) {
60
61 // }
62
63 // pub fn pop_layer(&mut self) {
64 // assert!(self.active_layer_stack.len() > 1);
65 // self.active_layer_stack.pop();
66 // }
67
68 pub fn push_quad(&mut self, quad: Quad) {
69 self.active_layer().push_quad(quad)
70 }
71
72 pub fn push_shadow(&mut self, shadow: Shadow) {
73 self.active_layer().push_shadow(shadow)
74 }
75
76 fn active_layer(&mut self) -> &mut Layer {
77 &mut self.layers[*self.active_layer_stack.last().unwrap()]
78 }
79}
80
81impl Layer {
82 fn push_quad(&mut self, quad: Quad) {
83 self.quads.push(quad);
84 }
85
86 pub fn quads(&self) -> &[Quad] {
87 self.quads.as_slice()
88 }
89
90 fn push_shadow(&mut self, shadow: Shadow) {
91 self.shadows.push(shadow);
92 }
93
94 pub fn shadows(&self) -> &[Shadow] {
95 self.shadows.as_slice()
96 }
97}
98
99impl Border {
100 pub fn new(width: f32, color: impl Into<ColorU>) -> Self {
101 Self {
102 width,
103 color: Some(color.into()),
104 top: false,
105 left: false,
106 bottom: false,
107 right: false,
108 }
109 }
110
111 pub fn all(width: f32, color: impl Into<ColorU>) -> Self {
112 Self {
113 width,
114 color: Some(color.into()),
115 top: true,
116 left: true,
117 bottom: true,
118 right: true,
119 }
120 }
121
122 pub fn top(width: f32, color: impl Into<ColorU>) -> Self {
123 let mut border = Self::new(width, color);
124 border.top = true;
125 border
126 }
127
128 pub fn left(width: f32, color: impl Into<ColorU>) -> Self {
129 let mut border = Self::new(width, color);
130 border.left = true;
131 border
132 }
133
134 pub fn bottom(width: f32, color: impl Into<ColorU>) -> Self {
135 let mut border = Self::new(width, color);
136 border.bottom = true;
137 border
138 }
139
140 pub fn right(width: f32, color: impl Into<ColorU>) -> Self {
141 let mut border = Self::new(width, color);
142 border.right = true;
143 border
144 }
145
146 pub fn with_sides(mut self, top: bool, left: bool, bottom: bool, right: bool) -> Self {
147 self.top = top;
148 self.left = left;
149 self.bottom = bottom;
150 self.right = right;
151 self
152 }
153
154 fn all_sides(&self) -> bool {
155 self.top && self.left && self.bottom && self.right
156 }
157}