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