group.rs

  1use crate::{
  2    AnyElement, AppContext, Bounds, Element, ElementId, IdentifiedElement, Interactive,
  3    IntoAnyElement, 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> IntoAnyElement<E::ViewState> for Group<E> {
 31    fn into_any(self) -> AnyElement<E::ViewState> {
 32        AnyElement::new(self)
 33    }
 34}
 35
 36impl<E: Element> Element for Group<E> {
 37    type ViewState = E::ViewState;
 38    type ElementState = E::ElementState;
 39
 40    fn element_id(&self) -> Option<ElementId> {
 41        self.child.element_id()
 42    }
 43
 44    fn layout(
 45        &mut self,
 46        state: &mut Self::ViewState,
 47        element_state: Option<Self::ElementState>,
 48        cx: &mut ViewContext<Self::ViewState>,
 49    ) -> (crate::LayoutId, Self::ElementState) {
 50        self.child.layout(state, element_state, cx)
 51    }
 52
 53    fn paint(
 54        &mut self,
 55        bounds: Bounds<Pixels>,
 56        state: &mut Self::ViewState,
 57        element_state: &mut Self::ElementState,
 58        cx: &mut ViewContext<Self::ViewState>,
 59    ) {
 60        cx.default_global::<GroupBounds>()
 61            .0
 62            .entry(self.name.clone())
 63            .or_default()
 64            .push(bounds);
 65        self.child.paint(bounds, state, element_state, cx);
 66        cx.default_global::<GroupBounds>()
 67            .0
 68            .get_mut(&self.name)
 69            .unwrap()
 70            .pop();
 71    }
 72}
 73
 74impl<E: ParentElement> ParentElement for Group<E> {
 75    type State = E::State;
 76
 77    fn children_mut(&mut self) -> &mut SmallVec<[AnyElement<Self::State>; 2]> {
 78        self.child.children_mut()
 79    }
 80}
 81
 82impl<E> IdentifiedElement for Group<E> where E: IdentifiedElement {}
 83
 84impl<E> Styled for Group<E>
 85where
 86    E: Styled,
 87{
 88    type Style = E::Style;
 89
 90    fn style_cascade(&mut self) -> &mut Cascade<E::Style> {
 91        self.child.style_cascade()
 92    }
 93
 94    fn declared_style(&mut self) -> &mut <Self::Style as refineable::Refineable>::Refinement {
 95        self.child.declared_style()
 96    }
 97}
 98
 99impl<S: 'static + Send + Sync, E: Interactive<S> + Styled> Interactive<S> for Group<E> {
100    fn listeners(&mut self) -> &mut MouseEventListeners<S> {
101        self.child.listeners()
102    }
103}