div.rs

  1use crate::{
  2    element::{AnyElement, Element, IntoElement, Layout, ParentElement},
  3    layout_context::LayoutContext,
  4    paint_context::PaintContext,
  5    style::{Style, StyleHelpers, Styleable},
  6    InteractionHandlers, Interactive,
  7};
  8use anyhow::Result;
  9use gpui::LayoutId;
 10use refineable::{Refineable, RefinementCascade};
 11use smallvec::SmallVec;
 12use util::ResultExt;
 13
 14pub struct Div<V: 'static> {
 15    styles: RefinementCascade<Style>,
 16    handlers: InteractionHandlers<V>,
 17    children: SmallVec<[AnyElement<V>; 2]>,
 18}
 19
 20pub fn div<V>() -> Div<V> {
 21    Div {
 22        styles: Default::default(),
 23        handlers: Default::default(),
 24        children: Default::default(),
 25    }
 26}
 27
 28impl<V: 'static> Element<V> for Div<V> {
 29    type PaintState = ();
 30
 31    fn layout(
 32        &mut self,
 33        view: &mut V,
 34        cx: &mut LayoutContext<V>,
 35    ) -> Result<(LayoutId, Self::PaintState)>
 36    where
 37        Self: Sized,
 38    {
 39        let style = self.computed_style();
 40        let pop_text_style = style.text_style(cx).map_or(false, |style| {
 41            cx.push_text_style(&style).log_err().is_some()
 42        });
 43
 44        let children = self
 45            .children
 46            .iter_mut()
 47            .map(|child| child.layout(view, cx))
 48            .collect::<Result<Vec<LayoutId>>>()?;
 49
 50        if pop_text_style {
 51            cx.pop_text_style();
 52        }
 53
 54        Ok((cx.add_layout_node(style, children)?, ()))
 55    }
 56
 57    fn paint(
 58        &mut self,
 59        view: &mut V,
 60        layout: &Layout,
 61        _: &mut Self::PaintState,
 62        cx: &mut PaintContext<V>,
 63    ) where
 64        Self: Sized,
 65    {
 66        let style = &self.computed_style();
 67        let pop_text_style = style.text_style(cx).map_or(false, |style| {
 68            cx.push_text_style(&style).log_err().is_some()
 69        });
 70        style.paint_background(layout.bounds, cx);
 71        self.interaction_handlers()
 72            .paint(layout.order, layout.bounds, cx);
 73        for child in &mut self.children {
 74            child.paint(view, layout.bounds.origin(), cx);
 75        }
 76        if pop_text_style {
 77            cx.pop_text_style();
 78        }
 79    }
 80}
 81
 82impl<V> Styleable for Div<V> {
 83    type Style = Style;
 84
 85    fn style_cascade(&mut self) -> &mut RefinementCascade<Self::Style> {
 86        &mut self.styles
 87    }
 88
 89    fn declared_style(&mut self) -> &mut <Self::Style as Refineable>::Refinement {
 90        self.styles.base()
 91    }
 92}
 93
 94impl<V> StyleHelpers for Div<V> {}
 95
 96impl<V> Interactive<V> for Div<V> {
 97    fn interaction_handlers(&mut self) -> &mut InteractionHandlers<V> {
 98        &mut self.handlers
 99    }
100}
101
102impl<V: 'static> ParentElement<V> for Div<V> {
103    fn children_mut(&mut self) -> &mut SmallVec<[AnyElement<V>; 2]> {
104        &mut self.children
105    }
106}
107
108impl<V: 'static> IntoElement<V> for Div<V> {
109    type Element = Self;
110
111    fn into_element(self) -> Self::Element {
112        self
113    }
114}