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}