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}