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}