1use crate::{
2 AnyElement, BorrowWindow, Bounds, Element, ElementFocus, ElementId, ElementInteraction,
3 FocusDisabled, FocusEnabled, FocusHandle, FocusListeners, Focusable, GlobalElementId,
4 GroupBounds, InteractiveElementState, IntoAnyElement, LayoutId, Overflow, ParentElement,
5 Pixels, Point, SharedString, StatefulInteraction, StatefulInteractive, StatelessInteraction,
6 StatelessInteractive, Style, StyleRefinement, Styled, ViewContext,
7};
8use parking_lot::Mutex;
9use refineable::Refineable;
10use smallvec::SmallVec;
11use std::sync::Arc;
12
13#[derive(Default, Clone)]
14pub struct ScrollState(Arc<Mutex<Point<Pixels>>>);
15
16impl ScrollState {
17 pub fn x(&self) -> Pixels {
18 self.0.lock().x
19 }
20
21 pub fn set_x(&self, value: Pixels) {
22 self.0.lock().x = value;
23 }
24
25 pub fn y(&self) -> Pixels {
26 self.0.lock().y
27 }
28
29 pub fn set_y(&self, value: Pixels) {
30 self.0.lock().y = value;
31 }
32}
33
34pub struct Div<
35 V: 'static + Send + Sync,
36 I: ElementInteraction<V> = StatelessInteraction<V>,
37 F: ElementFocus<V> = FocusDisabled,
38> {
39 interaction: I,
40 focus: F,
41 children: SmallVec<[AnyElement<V>; 2]>,
42 group: Option<SharedString>,
43 base_style: StyleRefinement,
44}
45
46pub fn div<V>() -> Div<V, StatelessInteraction<V>, FocusDisabled>
47where
48 V: 'static + Send + Sync,
49{
50 Div {
51 interaction: StatelessInteraction::default(),
52 focus: FocusDisabled,
53 children: SmallVec::new(),
54 group: None,
55 base_style: StyleRefinement::default(),
56 }
57}
58
59impl<V, F> Div<V, StatelessInteraction<V>, F>
60where
61 F: ElementFocus<V>,
62 V: 'static + Send + Sync,
63{
64 pub fn id(self, id: impl Into<ElementId>) -> Div<V, StatefulInteraction<V>, F> {
65 Div {
66 interaction: id.into().into(),
67 focus: self.focus,
68 children: self.children,
69 group: self.group,
70 base_style: self.base_style,
71 }
72 }
73}
74
75impl<V, I, F> Div<V, I, F>
76where
77 I: ElementInteraction<V>,
78 F: ElementFocus<V>,
79 V: 'static + Send + Sync,
80{
81 pub fn group(mut self, group: impl Into<SharedString>) -> Self {
82 self.group = Some(group.into());
83 self
84 }
85
86 pub fn z_index(mut self, z_index: u32) -> Self {
87 self.base_style.z_index = Some(z_index);
88 self
89 }
90
91 pub fn overflow_hidden(mut self) -> Self {
92 self.base_style.overflow.x = Some(Overflow::Hidden);
93 self.base_style.overflow.y = Some(Overflow::Hidden);
94 self
95 }
96
97 pub fn overflow_hidden_x(mut self) -> Self {
98 self.base_style.overflow.x = Some(Overflow::Hidden);
99 self
100 }
101
102 pub fn overflow_hidden_y(mut self) -> Self {
103 self.base_style.overflow.y = Some(Overflow::Hidden);
104 self
105 }
106
107 pub fn overflow_scroll(mut self, _scroll_state: ScrollState) -> Self {
108 // todo!("impl scrolling")
109 // self.scroll_state = Some(scroll_state);
110 self.base_style.overflow.x = Some(Overflow::Scroll);
111 self.base_style.overflow.y = Some(Overflow::Scroll);
112 self
113 }
114
115 pub fn overflow_x_scroll(mut self, _scroll_state: ScrollState) -> Self {
116 // todo!("impl scrolling")
117 // self.scroll_state = Some(scroll_state);
118 self.base_style.overflow.x = Some(Overflow::Scroll);
119 self
120 }
121
122 pub fn overflow_y_scroll(mut self, _scroll_state: ScrollState) -> Self {
123 // todo!("impl scrolling")
124 // self.scroll_state = Some(scroll_state);
125 self.base_style.overflow.y = Some(Overflow::Scroll);
126 self
127 }
128
129 fn with_element_id<R>(
130 &mut self,
131 cx: &mut ViewContext<V>,
132 f: impl FnOnce(&mut Self, Option<GlobalElementId>, &mut ViewContext<V>) -> R,
133 ) -> R {
134 if let Some(id) = self.id() {
135 cx.with_element_id(id, |global_id, cx| f(self, Some(global_id), cx))
136 } else {
137 f(self, None, cx)
138 }
139 }
140
141 pub fn compute_style(
142 &self,
143 bounds: Bounds<Pixels>,
144 state: &InteractiveElementState,
145 cx: &mut ViewContext<V>,
146 ) -> Style {
147 let mut computed_style = Style::default();
148 computed_style.refine(&self.base_style);
149 self.focus.refine_style(&mut computed_style, cx);
150 self.interaction
151 .refine_style(&mut computed_style, bounds, state, cx);
152 computed_style
153 }
154}
155
156impl<V, I> Div<V, I, FocusDisabled>
157where
158 I: ElementInteraction<V>,
159 V: 'static + Send + Sync,
160{
161 pub fn focusable(self, handle: &FocusHandle) -> Div<V, I, FocusEnabled<V>> {
162 Div {
163 interaction: self.interaction,
164 focus: handle.clone().into(),
165 children: self.children,
166 group: self.group,
167 base_style: self.base_style,
168 }
169 }
170}
171
172impl<V, I> Focusable for Div<V, I, FocusEnabled<V>>
173where
174 I: ElementInteraction<V>,
175 V: 'static + Send + Sync,
176{
177 fn focus_listeners(&mut self) -> &mut FocusListeners<V> {
178 &mut self.focus.focus_listeners
179 }
180
181 fn handle(&self) -> &FocusHandle {
182 &self.focus.focus_handle
183 }
184
185 fn set_focus_style(&mut self, style: StyleRefinement) {
186 self.focus.focus_style = style;
187 }
188
189 fn set_focus_in_style(&mut self, style: StyleRefinement) {
190 self.focus.focus_in_style = style;
191 }
192
193 fn set_in_focus_style(&mut self, style: StyleRefinement) {
194 self.focus.in_focus_style = style;
195 }
196}
197
198impl<V, I, F> Element for Div<V, I, F>
199where
200 I: ElementInteraction<V>,
201 F: ElementFocus<V>,
202 V: 'static + Send + Sync,
203{
204 type ViewState = V;
205 type ElementState = InteractiveElementState;
206
207 fn id(&self) -> Option<ElementId> {
208 self.interaction
209 .as_stateful()
210 .map(|identified| identified.id.clone())
211 }
212
213 fn initialize(
214 &mut self,
215 view_state: &mut Self::ViewState,
216 element_state: Option<Self::ElementState>,
217 cx: &mut ViewContext<Self::ViewState>,
218 ) -> Self::ElementState {
219 self.interaction.initialize(cx, |cx| {
220 self.focus.initialize(cx, |cx| {
221 for child in &mut self.children {
222 child.initialize(view_state, cx);
223 }
224 });
225 });
226 element_state.unwrap_or_default()
227 }
228
229 fn layout(
230 &mut self,
231 view_state: &mut Self::ViewState,
232 element_state: &mut Self::ElementState,
233 cx: &mut ViewContext<Self::ViewState>,
234 ) -> LayoutId {
235 let style = self.compute_style(Bounds::default(), element_state, cx);
236 style.apply_text_style(cx, |cx| {
237 self.with_element_id(cx, |this, _global_id, cx| {
238 let layout_ids = this
239 .children
240 .iter_mut()
241 .map(|child| child.layout(view_state, cx))
242 .collect::<Vec<_>>();
243 cx.request_layout(&style, layout_ids)
244 })
245 })
246 }
247
248 fn paint(
249 &mut self,
250 bounds: Bounds<Pixels>,
251 view_state: &mut Self::ViewState,
252 element_state: &mut Self::ElementState,
253 cx: &mut ViewContext<Self::ViewState>,
254 ) {
255 self.with_element_id(cx, |this, _global_id, cx| {
256 if let Some(group) = this.group.clone() {
257 GroupBounds::push(group, bounds, cx);
258 }
259
260 let style = this.compute_style(bounds, element_state, cx);
261 let z_index = style.z_index.unwrap_or(0);
262
263 // Paint background and event handlers.
264 cx.stack(z_index, |cx| {
265 cx.stack(0, |cx| {
266 style.paint(bounds, cx);
267
268 this.focus.paint(bounds, cx);
269 this.interaction.paint(bounds, element_state, cx);
270 });
271
272 cx.stack(1, |cx| {
273 style.apply_text_style(cx, |cx| {
274 style.apply_overflow(bounds, cx, |cx| {
275 for child in &mut this.children {
276 child.paint(view_state, None, cx);
277 }
278 })
279 })
280 });
281 });
282
283 if let Some(group) = this.group.as_ref() {
284 GroupBounds::pop(group, cx);
285 }
286 })
287 }
288}
289
290impl<V, I, F> IntoAnyElement<V> for Div<V, I, F>
291where
292 I: ElementInteraction<V>,
293 F: ElementFocus<V>,
294 V: 'static + Send + Sync,
295{
296 fn into_any(self) -> AnyElement<V> {
297 AnyElement::new(self)
298 }
299}
300
301impl<V, I, F> ParentElement for Div<V, I, F>
302where
303 I: ElementInteraction<V>,
304 F: ElementFocus<V>,
305 V: 'static + Send + Sync,
306{
307 fn children_mut(&mut self) -> &mut SmallVec<[AnyElement<Self::ViewState>; 2]> {
308 &mut self.children
309 }
310}
311
312impl<V, I, F> Styled for Div<V, I, F>
313where
314 I: ElementInteraction<V>,
315 F: ElementFocus<V>,
316 V: 'static + Send + Sync,
317{
318 fn style(&mut self) -> &mut StyleRefinement {
319 &mut self.base_style
320 }
321}
322
323impl<V, I, F> StatelessInteractive for Div<V, I, F>
324where
325 I: ElementInteraction<V>,
326 F: ElementFocus<V>,
327 V: 'static + Send + Sync,
328{
329 fn stateless_interactivity(&mut self) -> &mut StatelessInteraction<V> {
330 self.interaction.as_stateless_mut()
331 }
332}
333
334impl<V, F> StatefulInteractive for Div<V, StatefulInteraction<V>, F>
335where
336 F: ElementFocus<V>,
337 V: 'static + Send + Sync,
338{
339 fn stateful_interactivity(&mut self) -> &mut StatefulInteraction<Self::ViewState> {
340 &mut self.interaction
341 }
342}