group.rs

 1use crate::{
 2    AnyElement, AppContext, Bounds, Element, ElementId, IdentifiedElement, Interactive,
 3    MouseEventListeners, ParentElement, Pixels, SharedString, Styled, ViewContext,
 4};
 5use collections::HashMap;
 6use refineable::Cascade;
 7use smallvec::SmallVec;
 8
 9#[derive(Default)]
10struct GroupBounds(HashMap<SharedString, SmallVec<[Bounds<Pixels>; 1]>>);
11
12pub fn group_bounds(name: &SharedString, cx: &mut AppContext) -> Option<Bounds<Pixels>> {
13    cx.default_global::<GroupBounds>()
14        .0
15        .get(name)
16        .and_then(|bounds_stack| bounds_stack.last().cloned())
17}
18
19pub struct Group<E> {
20    name: SharedString,
21    child: E,
22}
23
24impl<E> Group<E> {
25    pub fn new(name: SharedString, child: E) -> Self {
26        Group { name, child }
27    }
28}
29
30impl<E: Element> Element for Group<E> {
31    type ViewState = E::ViewState;
32    type ElementState = E::ElementState;
33
34    fn element_id(&self) -> Option<ElementId> {
35        self.child.element_id()
36    }
37
38    fn layout(
39        &mut self,
40        state: &mut Self::ViewState,
41        element_state: Option<Self::ElementState>,
42        cx: &mut ViewContext<Self::ViewState>,
43    ) -> (crate::LayoutId, Self::ElementState) {
44        self.child.layout(state, element_state, cx)
45    }
46
47    fn paint(
48        &mut self,
49        bounds: Bounds<Pixels>,
50        state: &mut Self::ViewState,
51        element_state: &mut Self::ElementState,
52        cx: &mut ViewContext<Self::ViewState>,
53    ) {
54        cx.default_global::<GroupBounds>()
55            .0
56            .entry(self.name.clone())
57            .or_default()
58            .push(bounds);
59        self.child.paint(bounds, state, element_state, cx);
60        cx.default_global::<GroupBounds>()
61            .0
62            .get_mut(&self.name)
63            .unwrap()
64            .pop();
65    }
66}
67
68impl<E: ParentElement> ParentElement for Group<E> {
69    type State = E::State;
70
71    fn children_mut(&mut self) -> &mut SmallVec<[AnyElement<Self::State>; 2]> {
72        self.child.children_mut()
73    }
74}
75
76impl<E> IdentifiedElement for Group<E> where E: IdentifiedElement {}
77
78impl<E> Styled for Group<E>
79where
80    E: Styled,
81{
82    type Style = E::Style;
83
84    fn style_cascade(&mut self) -> &mut Cascade<E::Style> {
85        self.child.style_cascade()
86    }
87
88    fn declared_style(&mut self) -> &mut <Self::Style as refineable::Refineable>::Refinement {
89        self.child.declared_style()
90    }
91}
92
93impl<S: 'static + Send + Sync, E: Interactive<S> + Styled> Interactive<S> for Group<E> {
94    fn listeners(&mut self) -> &mut MouseEventListeners<S> {
95        self.child.listeners()
96    }
97}