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}