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        style.paint_foreground(layout.bounds, cx);
 77        if pop_text_style {
 78            cx.pop_text_style();
 79        }
 80    }
 81}
 82
 83impl<V> Styleable for Div<V> {
 84    type Style = Style;
 85
 86    fn style_cascade(&mut self) -> &mut RefinementCascade<Self::Style> {
 87        &mut self.styles
 88    }
 89
 90    fn declared_style(&mut self) -> &mut <Self::Style as Refineable>::Refinement {
 91        self.styles.base()
 92    }
 93}
 94
 95impl<V> StyleHelpers for Div<V> {}
 96
 97impl<V> Interactive<V> for Div<V> {
 98    fn interaction_handlers(&mut self) -> &mut InteractionHandlers<V> {
 99        &mut self.handlers
100    }
101}
102
103impl<V: 'static> ParentElement<V> for Div<V> {
104    fn children_mut(&mut self) -> &mut SmallVec<[AnyElement<V>; 2]> {
105        &mut self.children
106    }
107}
108
109impl<V: 'static> IntoElement<V> for Div<V> {
110    type Element = Self;
111
112    fn into_element(self) -> Self::Element {
113        self
114    }
115}