iced_graphics/
layer.rs

1//! Draw and stack layers of graphical primitives.
2use crate::core::{Rectangle, Transformation};
3
4/// A layer of graphical primitives.
5///
6/// Layers normally dictate a set of primitives that are
7/// rendered in a specific order.
8pub trait Layer: Default {
9    /// Creates a new [`Layer`] with the given bounds.
10    fn with_bounds(bounds: Rectangle) -> Self;
11
12    /// Flushes and settles any pending group of primitives in the [`Layer`].
13    ///
14    /// This will be called when a [`Layer`] is finished. It allows layers to efficiently
15    /// record primitives together and defer grouping until the end.
16    fn flush(&mut self);
17
18    /// Resizes the [`Layer`] to the given bounds.
19    fn resize(&mut self, bounds: Rectangle);
20
21    /// Clears all the layers contents and resets its bounds.
22    fn reset(&mut self);
23}
24
25/// A stack of layers used for drawing.
26#[derive(Debug)]
27pub struct Stack<T: Layer> {
28    layers: Vec<T>,
29    transformations: Vec<Transformation>,
30    previous: Vec<usize>,
31    current: usize,
32    active_count: usize,
33}
34
35impl<T: Layer> Stack<T> {
36    /// Creates a new empty [`Stack`].
37    pub fn new() -> Self {
38        Self {
39            layers: vec![T::default()],
40            transformations: vec![Transformation::IDENTITY],
41            previous: vec![],
42            current: 0,
43            active_count: 1,
44        }
45    }
46
47    /// Returns a mutable reference to the current [`Layer`] of the [`Stack`], together with
48    /// the current [`Transformation`].
49    #[inline]
50    pub fn current_mut(&mut self) -> (&mut T, Transformation) {
51        let transformation = self.transformation();
52
53        (&mut self.layers[self.current], transformation)
54    }
55
56    /// Returns the current [`Transformation`] of the [`Stack`].
57    #[inline]
58    pub fn transformation(&self) -> Transformation {
59        self.transformations.last().copied().unwrap()
60    }
61
62    /// Pushes a new clipping region in the [`Stack`]; creating a new layer in the
63    /// process.
64    pub fn push_clip(&mut self, bounds: Rectangle) {
65        self.previous.push(self.current);
66
67        self.current = self.active_count;
68        self.active_count += 1;
69
70        let bounds = bounds * self.transformation();
71
72        if self.current == self.layers.len() {
73            self.layers.push(T::with_bounds(bounds));
74        } else {
75            self.layers[self.current].resize(bounds);
76        }
77    }
78
79    /// Pops the current clipping region from the [`Stack`] and restores the previous one.
80    ///
81    /// The current layer will be recorded for drawing.
82    pub fn pop_clip(&mut self) {
83        self.flush();
84
85        self.current = self.previous.pop().unwrap();
86    }
87
88    /// Pushes a new [`Transformation`] in the [`Stack`].
89    ///
90    /// Future drawing operations will be affected by this new [`Transformation`] until
91    /// it is popped using [`pop_transformation`].
92    ///
93    /// [`pop_transformation`]: Self::pop_transformation
94    pub fn push_transformation(&mut self, transformation: Transformation) {
95        self.transformations
96            .push(self.transformation() * transformation);
97    }
98
99    /// Pops the current [`Transformation`] in the [`Stack`].
100    pub fn pop_transformation(&mut self) {
101        let _ = self.transformations.pop();
102    }
103
104    /// Returns an iterator over mutable references to the layers in the [`Stack`].
105    pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
106        self.flush();
107
108        self.layers[..self.active_count].iter_mut()
109    }
110
111    /// Returns an iterator over immutable references to the layers in the [`Stack`].
112    pub fn iter(&self) -> impl Iterator<Item = &T> {
113        self.layers[..self.active_count].iter()
114    }
115
116    /// Returns the slice of layers in the [`Stack`].
117    pub fn as_slice(&self) -> &[T] {
118        &self.layers[..self.active_count]
119    }
120
121    /// Flushes and settles any primitives in the current layer of the [`Stack`].
122    pub fn flush(&mut self) {
123        self.layers[self.current].flush();
124    }
125
126    /// Clears the layers of the [`Stack`], allowing reuse.
127    ///
128    /// This will normally keep layer allocations for future drawing operations.
129    pub fn clear(&mut self) {
130        for layer in self.layers[..self.active_count].iter_mut() {
131            layer.reset();
132        }
133
134        self.current = 0;
135        self.active_count = 1;
136        self.previous.clear();
137    }
138}
139
140impl<T: Layer> Default for Stack<T> {
141    fn default() -> Self {
142        Self::new()
143    }
144}