1use crate::{
2 AnonymousElementKind, AnyElement, Bounds, Clickable, ClickableElement, ClickableElementState,
3 Element, ElementId, ElementKind, Hoverable, HoverableElement, IdentifiedElementKind,
4 IntoAnyElement, LayoutId, LayoutNode, LayoutNodeElement, Overflow, Pixels, Point, SharedString,
5 Style, StyleCascade, StyleRefinement, Styled, ViewContext, ClickListeners,
6};
7use parking_lot::Mutex;
8use smallvec::SmallVec;
9use std::sync::Arc;
10
11#[derive(Default, Clone)]
12pub struct ScrollState(Arc<Mutex<Point<Pixels>>>);
13
14impl ScrollState {
15 pub fn x(&self) -> Pixels {
16 self.0.lock().x
17 }
18
19 pub fn set_x(&self, value: Pixels) {
20 self.0.lock().x = value;
21 }
22
23 pub fn y(&self) -> Pixels {
24 self.0.lock().y
25 }
26
27 pub fn set_y(&self, value: Pixels) {
28 self.0.lock().y = value;
29 }
30}
31
32pub struct Div<V: 'static + Send + Sync, K: ElementKind>(
33 ClickableElement<HoverableElement<LayoutNodeElement<V, K>>>,
34);
35
36impl<V: 'static + Send + Sync, K: ElementKind> Div<V, K> {
37 pub fn group(mut self, group: impl Into<SharedString>) -> Self {
38 *self.0.group_mut() = Some(group.into());
39 self
40 }
41
42 pub fn z_index(mut self, z_index: u32) -> Self {
43 self.base_style().z_index = Some(z_index);
44 self
45 }
46
47 pub fn overflow_hidden(mut self) -> Self {
48 self.base_style().overflow.x = Some(Overflow::Hidden);
49 self.base_style().overflow.y = Some(Overflow::Hidden);
50 self
51 }
52
53 pub fn overflow_hidden_x(mut self) -> Self {
54 self.base_style().overflow.x = Some(Overflow::Hidden);
55 self
56 }
57
58 pub fn overflow_hidden_y(mut self) -> Self {
59 self.base_style().overflow.y = Some(Overflow::Hidden);
60 self
61 }
62
63 pub fn overflow_scroll(mut self, _scroll_state: ScrollState) -> Self {
64 // todo!("impl scrolling")
65 // self.scroll_state = Some(scroll_state);
66 self.base_style().overflow.x = Some(Overflow::Scroll);
67 self.base_style().overflow.y = Some(Overflow::Scroll);
68 self
69 }
70
71 pub fn overflow_x_scroll(mut self, _scroll_state: ScrollState) -> Self {
72 // todo!("impl scrolling")
73 // self.scroll_state = Some(scroll_state);
74 self.base_style().overflow.x = Some(Overflow::Scroll);
75 self
76 }
77
78 pub fn overflow_y_scroll(mut self, _scroll_state: ScrollState) -> Self {
79 // todo!("impl scrolling")
80 // self.scroll_state = Some(scroll_state);
81 self.base_style().overflow.y = Some(Overflow::Scroll);
82 self
83 }
84
85 fn base_style(&mut self) -> &mut StyleRefinement {
86 self.style_cascade().base()
87 }
88}
89
90impl<V: 'static + Send + Sync> Div<V, AnonymousElementKind> {
91 pub fn id(self, id: impl Into<ElementId>) -> Div<V, IdentifiedElementKind> {
92 Div(self.0.replace_child(|hoverable| {
93 hoverable.replace_child(|layout_node| layout_node.identify(id))
94 }))
95 }
96}
97
98impl<V: 'static + Send + Sync, K: ElementKind> LayoutNode<V, K> for Div<V, K> {
99 fn children_mut(&mut self) -> &mut SmallVec<[AnyElement<V>; 2]> {
100 self.0.children_mut()
101 }
102
103 fn group_mut(&mut self) -> &mut Option<SharedString> {
104 self.0.group_mut()
105 }
106}
107
108impl<V: 'static + Send + Sync, K: ElementKind> Styled for Div<V, K> {
109 fn style_cascade(&mut self) -> &mut StyleCascade {
110 self.0.style_cascade()
111 }
112
113 fn computed_style(&mut self) -> &Style {
114 self.0.computed_style()
115 }
116}
117
118impl<V: 'static + Send + Sync, K: ElementKind> Hoverable for Div<V, K> {
119 fn hover_style(&mut self) -> &mut StyleRefinement {
120 self.0.hover_style()
121 }
122}
123
124impl<V: 'static + Send + Sync> Clickable for Div<V, IdentifiedElementKind> {
125 fn active_style(&mut self) -> &mut StyleRefinement {
126 self.0.active_style()
127 }
128
129 fn listeners(&mut self) -> &mut ClickListeners<V> {
130 self.0.listeners()
131 }
132}
133
134impl<V, K> IntoAnyElement<V> for Div<V, K>
135where
136 V: 'static + Send + Sync,
137 K: ElementKind,
138{
139 fn into_any(self) -> AnyElement<V> {
140 AnyElement::new(self)
141 }
142}
143
144impl<V, K> Element for Div<V, K>
145where
146 V: 'static + Send + Sync,
147 K: ElementKind,
148{
149 type ViewState = V;
150 type ElementState = ClickableElementState<()>;
151
152 fn id(&self) -> Option<ElementId> {
153 self.0.id()
154 }
155
156 fn layout(
157 &mut self,
158 state: &mut Self::ViewState,
159 element_state: Option<Self::ElementState>,
160 cx: &mut ViewContext<Self::ViewState>,
161 ) -> (LayoutId, Self::ElementState) {
162 self.0.layout(state, element_state, cx)
163 }
164
165 fn paint(
166 &mut self,
167 bounds: Bounds<Pixels>,
168 state: &mut Self::ViewState,
169 element_state: &mut Self::ElementState,
170 cx: &mut ViewContext<Self::ViewState>,
171 ) {
172 self.0.paint(bounds, state, element_state, cx);
173 }
174}