div.rs

  1use crate::{
  2    element::{AnyElement, Element, IntoElement, Layout, ParentElement},
  3    interactive::{InteractionHandlers, Interactive},
  4    layout_context::LayoutContext,
  5    paint_context::PaintContext,
  6    style::{Style, StyleHelpers, Styleable},
  7};
  8use anyhow::Result;
  9use gpui::{LayoutId, RenderContext};
 10use refineable::{Refineable, RefinementCascade};
 11use smallvec::SmallVec;
 12
 13pub struct Div<V: 'static> {
 14    styles: RefinementCascade<Style>,
 15    handlers: InteractionHandlers<V>,
 16    children: SmallVec<[AnyElement<V>; 2]>,
 17}
 18
 19pub fn div<V>() -> Div<V> {
 20    Div {
 21        styles: Default::default(),
 22        handlers: Default::default(),
 23        children: Default::default(),
 24    }
 25}
 26
 27impl<V: 'static> Element<V> for Div<V> {
 28    type PaintState = ();
 29
 30    fn layout(
 31        &mut self,
 32        view: &mut V,
 33        cx: &mut LayoutContext<V>,
 34    ) -> Result<(LayoutId, Self::PaintState)>
 35    where
 36        Self: Sized,
 37    {
 38        let style = self.computed_style();
 39        let pop_text_style = style.text_style().map_or(false, |style| {
 40            cx.push_text_style(cx.text_style().clone().refined(&style));
 41            true
 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        paint_state: &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().map_or(false, |style| {
 68            cx.push_text_style(cx.text_style().clone().refined(&style));
 69            true
 70        });
 71        style.paint_background(layout.bounds, cx);
 72        self.interaction_handlers()
 73            .paint(layout.order, layout.bounds, cx);
 74        for child in &mut self.children {
 75            child.paint(view, cx);
 76        }
 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}