pixel_widgets/widget/
layers.rs

1use crate::draw::Primitive;
2use crate::event::{Event, Key};
3use crate::layout::{Rectangle, Size};
4use crate::node::{GenericNode, IntoNode, Node};
5use crate::style::Stylesheet;
6use crate::widget::{Context, Widget};
7
8/// Stack child widgets on top of each other, while only the topmost receives events.
9pub struct Layers<'a, T> {
10    layers: Vec<Layer<'a, T>>,
11    background: Option<Node<'a, T>>,
12}
13
14struct Layer<'a, T> {
15    node: Node<'a, T>,
16    id: u64,
17}
18
19/// State for [`Layers`](struct.Layers.html)
20pub struct State {
21    cursor_x: f32,
22    cursor_y: f32,
23    order: Vec<u64>,
24    background_focused: bool,
25}
26
27impl<'a, T: 'a> Layers<'a, T> {
28    /// Construct a new `Layers` widget
29    pub fn new() -> Self {
30        Self {
31            layers: Vec::new(),
32            background: None,
33        }
34    }
35
36    /// Adds a child widget
37    pub fn push(mut self, layer: impl IntoNode<'a, T>) -> Self {
38        if self.background.is_none() {
39            self.background = Some(layer.into_node());
40        } else {
41            let node = layer.into_node();
42            let id = node.get_key();
43            self.layers.push(Layer { node, id });
44        }
45        self
46    }
47
48    /// Adds child widgets using an iterator
49    pub fn extend<I: IntoIterator<Item = N>, N: IntoNode<'a, T> + 'a>(mut self, iter: I) -> Self {
50        let mut iter = iter.into_iter();
51        if self.background.is_none() {
52            self.background = iter.next().map(IntoNode::into_node);
53        }
54        self.layers.extend(iter.map(|layer| {
55            let node = layer.into_node();
56            let id = node.get_key();
57            Layer { node, id }
58        }));
59        self
60    }
61
62    fn ordered_layers<'b>(layers: &'b mut Vec<Layer<'a, T>>, state: &mut State) -> Vec<&'b mut Layer<'a, T>> {
63        let mut result = layers.iter_mut().collect::<Vec<_>>();
64
65        let mut index = 0;
66        for order_id in state.order.iter() {
67            if let Some(pos) = result.iter().position(|layer| layer.id.eq(order_id)) {
68                result.swap(pos, index);
69                index += 1;
70            }
71        }
72
73        state.order.clear();
74        state.order.extend(result.iter().map(|l| l.id));
75
76        result
77    }
78}
79
80impl<'a, T: 'a> Default for Layers<'a, T> {
81    fn default() -> Self {
82        Self {
83            layers: vec![],
84            background: None,
85        }
86    }
87}
88
89impl<'a, T: 'a + Send> Widget<'a, T> for Layers<'a, T> {
90    type State = State;
91
92    fn mount(&self) -> Self::State {
93        State::default()
94    }
95
96    fn widget(&self) -> &'static str {
97        "layers"
98    }
99
100    fn len(&self) -> usize {
101        self.layers.len() + if self.background.is_some() { 1 } else { 0 }
102    }
103
104    fn visit_children(&mut self, visitor: &mut dyn FnMut(&mut dyn GenericNode<'a, T>)) {
105        for background in self.background.iter_mut() {
106            visitor(&mut **background);
107        }
108        for layer in self.layers.iter_mut() {
109            visitor(&mut *layer.node);
110        }
111    }
112
113    fn size(&self, _: &State, style: &Stylesheet) -> (Size, Size) {
114        (style.width, style.height)
115    }
116
117    fn focused(&self, _: &State) -> bool {
118        self.layers.iter().any(|layer| layer.node.focused())
119            || self.background.as_ref().map(|bg| bg.focused()).unwrap_or(false)
120    }
121
122    fn event(
123        &mut self,
124        state: &mut State,
125        layout: Rectangle,
126        clip: Rectangle,
127        _: &Stylesheet,
128        event: Event,
129        context: &mut Context<T>,
130    ) {
131        let mut ordered_layers = Layers::ordered_layers(&mut self.layers, &mut *state);
132
133        if self.background.as_ref().map(|bg| bg.focused()).unwrap_or(false) {
134            self.background.as_mut().unwrap().event(layout, clip, event, context);
135            return;
136        }
137
138        for layer in ordered_layers.iter_mut() {
139            if layer.node.focused() {
140                layer.node.event(layout, clip, event, context);
141                return;
142            }
143        }
144
145        match event {
146            Event::Cursor(mut x, mut y) => {
147                state.cursor_x = x;
148                state.cursor_y = y;
149                // make sure that hovering always works regardless of the active layer
150                for layer in ordered_layers.iter_mut() {
151                    layer.node.event(layout, clip, Event::Cursor(x, y), context);
152                    if layer.node.hit(layout, clip, x, y) {
153                        // I hate this hack, but this will stop layers hidden behind the current from being hovered
154                        x = f32::INFINITY;
155                        y = f32::INFINITY;
156                    }
157                }
158                if let Some(bg) = self.background.as_mut() {
159                    bg.event(layout, clip, Event::Cursor(x, y), context)
160                }
161                return;
162            }
163            Event::Press(Key::LeftMouseButton) => {
164                let x = state.cursor_x;
165                let y = state.cursor_y;
166                if let Some(hit_index) = ordered_layers.iter_mut().enumerate().find_map(move |(i, l)| {
167                    if l.node.hit(layout, clip, x, y) {
168                        Some(i)
169                    } else {
170                        None
171                    }
172                }) {
173                    if hit_index != 0 || state.background_focused {
174                        state.background_focused = false;
175                        if hit_index != 0 {
176                            ordered_layers[0].node.event(layout, clip, event, context);
177                        }
178                        let rm = ordered_layers.remove(hit_index);
179                        ordered_layers.insert(0, rm);
180                        ordered_layers[0].node.event(layout, clip, Event::Cursor(x, y), context);
181                    }
182                } else if !state.background_focused {
183                    state.background_focused = true;
184                    if !ordered_layers.is_empty() {
185                        ordered_layers[0].node.event(layout, clip, event, context);
186                    }
187                    if let Some(bg) = self.background.as_mut() {
188                        bg.event(layout, clip, Event::Cursor(x, y), context)
189                    }
190                }
191            }
192            _ => (),
193        }
194
195        if let Some(bg) = self.background.as_mut() {
196            bg.event(layout, clip, event, context)
197        }
198        for layer in ordered_layers.iter_mut() {
199            layer.node.event(layout, clip, event, context);
200        }
201
202        state.order.clear();
203        state.order.extend(ordered_layers.into_iter().map(|l| l.id));
204    }
205
206    fn draw(&mut self, state: &mut State, layout: Rectangle, clip: Rectangle, _: &Stylesheet) -> Vec<Primitive<'a>> {
207        let mut result = Vec::new();
208        if let Some(bg) = self.background.as_mut() {
209            result.extend(bg.draw(layout, clip));
210        }
211        Self::ordered_layers(&mut self.layers, &mut *state)
212            .into_iter()
213            .rev()
214            .fold(result, |mut result, layer| {
215                result.extend(layer.node.draw(layout, clip));
216                result
217            })
218    }
219}
220
221impl<'a, T: 'a + Send> IntoNode<'a, T> for Layers<'a, T> {
222    fn into_node(self) -> Node<'a, T> {
223        Node::from_widget(self)
224    }
225}
226
227impl Default for State {
228    fn default() -> Self {
229        Self {
230            cursor_x: 0.0,
231            cursor_y: 0.0,
232            order: Vec::new(),
233            background_focused: true,
234        }
235    }
236}