scene.rs

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