scene.rs

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