div.rs

  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> Div<V, StatefulInteraction<V>, FocusDisabled>
157where
158    V: 'static + Send + Sync,
159{
160    pub fn focusable(
161        self,
162        handle: &FocusHandle,
163    ) -> Div<V, StatefulInteraction<V>, FocusEnabled<V>> {
164        Div {
165            interaction: self.interaction,
166            focus: handle.clone().into(),
167            children: self.children,
168            group: self.group,
169            base_style: self.base_style,
170        }
171    }
172}
173
174impl<V> Div<V, StatelessInteraction<V>, FocusDisabled>
175where
176    V: 'static + Send + Sync,
177{
178    pub fn focusable(
179        self,
180        handle: &FocusHandle,
181    ) -> Div<V, StatefulInteraction<V>, FocusEnabled<V>> {
182        Div {
183            interaction: self.interaction.into_stateful(handle),
184            focus: handle.clone().into(),
185            children: self.children,
186            group: self.group,
187            base_style: self.base_style,
188        }
189    }
190}
191
192impl<V, I> Focusable for Div<V, I, FocusEnabled<V>>
193where
194    I: ElementInteraction<V>,
195    V: 'static + Send + Sync,
196{
197    fn focus_listeners(&mut self) -> &mut FocusListeners<V> {
198        &mut self.focus.focus_listeners
199    }
200
201    fn handle(&self) -> &FocusHandle {
202        &self.focus.focus_handle
203    }
204
205    fn set_focus_style(&mut self, style: StyleRefinement) {
206        self.focus.focus_style = style;
207    }
208
209    fn set_focus_in_style(&mut self, style: StyleRefinement) {
210        self.focus.focus_in_style = style;
211    }
212
213    fn set_in_focus_style(&mut self, style: StyleRefinement) {
214        self.focus.in_focus_style = style;
215    }
216}
217
218impl<V, I, F> Element for Div<V, I, F>
219where
220    I: ElementInteraction<V>,
221    F: ElementFocus<V>,
222    V: 'static + Send + Sync,
223{
224    type ViewState = V;
225    type ElementState = InteractiveElementState;
226
227    fn id(&self) -> Option<ElementId> {
228        self.interaction
229            .as_stateful()
230            .map(|identified| identified.id.clone())
231    }
232
233    fn initialize(
234        &mut self,
235        view_state: &mut Self::ViewState,
236        element_state: Option<Self::ElementState>,
237        cx: &mut ViewContext<Self::ViewState>,
238    ) -> Self::ElementState {
239        self.focus.initialize(cx, |focus_handle, cx| {
240            self.interaction
241                .initialize(element_state, focus_handle, cx, |cx| {
242                    for child in &mut self.children {
243                        child.initialize(view_state, cx);
244                    }
245                })
246        })
247    }
248
249    fn layout(
250        &mut self,
251        view_state: &mut Self::ViewState,
252        element_state: &mut Self::ElementState,
253        cx: &mut ViewContext<Self::ViewState>,
254    ) -> LayoutId {
255        let style = self.compute_style(Bounds::default(), element_state, cx);
256        style.apply_text_style(cx, |cx| {
257            self.with_element_id(cx, |this, _global_id, cx| {
258                let layout_ids = this
259                    .children
260                    .iter_mut()
261                    .map(|child| child.layout(view_state, cx))
262                    .collect::<Vec<_>>();
263                cx.request_layout(&style, layout_ids)
264            })
265        })
266    }
267
268    fn paint(
269        &mut self,
270        bounds: Bounds<Pixels>,
271        view_state: &mut Self::ViewState,
272        element_state: &mut Self::ElementState,
273        cx: &mut ViewContext<Self::ViewState>,
274    ) {
275        self.with_element_id(cx, |this, _global_id, cx| {
276            if let Some(group) = this.group.clone() {
277                GroupBounds::push(group, bounds, cx);
278            }
279
280            let style = this.compute_style(bounds, element_state, cx);
281            let z_index = style.z_index.unwrap_or(0);
282
283            // Paint background and event handlers.
284            cx.stack(z_index, |cx| {
285                cx.stack(0, |cx| {
286                    style.paint(bounds, cx);
287
288                    this.focus.paint(bounds, cx);
289                    this.interaction.paint(bounds, element_state, cx);
290                });
291
292                cx.stack(1, |cx| {
293                    style.apply_text_style(cx, |cx| {
294                        style.apply_overflow(bounds, cx, |cx| {
295                            for child in &mut this.children {
296                                child.paint(view_state, None, cx);
297                            }
298                        })
299                    })
300                });
301            });
302
303            if let Some(group) = this.group.as_ref() {
304                GroupBounds::pop(group, cx);
305            }
306        })
307    }
308}
309
310impl<V, I, F> IntoAnyElement<V> for Div<V, I, F>
311where
312    I: ElementInteraction<V>,
313    F: ElementFocus<V>,
314    V: 'static + Send + Sync,
315{
316    fn into_any(self) -> AnyElement<V> {
317        AnyElement::new(self)
318    }
319}
320
321impl<V, I, F> ParentElement for Div<V, I, F>
322where
323    I: ElementInteraction<V>,
324    F: ElementFocus<V>,
325    V: 'static + Send + Sync,
326{
327    fn children_mut(&mut self) -> &mut SmallVec<[AnyElement<Self::ViewState>; 2]> {
328        &mut self.children
329    }
330}
331
332impl<V, I, F> Styled for Div<V, I, F>
333where
334    I: ElementInteraction<V>,
335    F: ElementFocus<V>,
336    V: 'static + Send + Sync,
337{
338    fn style(&mut self) -> &mut StyleRefinement {
339        &mut self.base_style
340    }
341}
342
343impl<V, I, F> StatelessInteractive for Div<V, I, F>
344where
345    I: ElementInteraction<V>,
346    F: ElementFocus<V>,
347    V: 'static + Send + Sync,
348{
349    fn stateless_interactivity(&mut self) -> &mut StatelessInteraction<V> {
350        self.interaction.as_stateless_mut()
351    }
352}
353
354impl<V, F> StatefulInteractive for Div<V, StatefulInteraction<V>, F>
355where
356    F: ElementFocus<V>,
357    V: 'static + Send + Sync,
358{
359    fn stateful_interactivity(&mut self) -> &mut StatefulInteraction<Self::ViewState> {
360        &mut self.interaction
361    }
362}