1use std::{any::Any, rc::Rc};
2
3use crate::{
4 adapter::Adapter,
5 style::{DefinedLength, Display, ElementStyle, Fill, Length, Overflow, Position},
6};
7use anyhow::Result;
8use derive_more::{Deref, DerefMut};
9use gpui::{
10 scene::MouseClick, EngineLayout, LayoutContext as LegacyLayoutContext,
11 PaintContext as LegacyPaintContext,
12};
13use playground_macros::tailwind_lengths;
14pub use taffy::tree::NodeId;
15
16#[derive(Deref, DerefMut)]
17pub struct LayoutContext<'a, 'b, 'c, 'd, V> {
18 pub(crate) legacy_cx: &'d mut LegacyLayoutContext<'a, 'b, 'c, V>,
19}
20
21#[derive(Deref, DerefMut)]
22pub struct PaintContext<'a, 'b, 'c, 'd, V> {
23 #[deref]
24 #[deref_mut]
25 pub(crate) legacy_cx: &'d mut LegacyPaintContext<'a, 'b, 'c, V>,
26 pub(crate) scene: &'d mut gpui::SceneBuilder,
27}
28
29pub struct Layout<'a, E: ?Sized> {
30 pub from_engine: EngineLayout,
31 pub from_element: &'a mut E,
32}
33
34pub struct ElementHandlers<V> {
35 click: Option<Rc<dyn Fn(&mut V, MouseClick)>>,
36}
37
38pub struct ElementMetadata<V> {
39 pub style: ElementStyle,
40 pub handlers: ElementHandlers<V>,
41}
42
43impl<V> Default for ElementMetadata<V> {
44 fn default() -> Self {
45 Self {
46 style: ElementStyle::default(),
47 handlers: ElementHandlers::default(),
48 }
49 }
50}
51
52impl<V> Default for ElementHandlers<V> {
53 fn default() -> Self {
54 ElementHandlers { click: None }
55 }
56}
57
58pub trait Element<V: 'static>: 'static {
59 type Layout: 'static;
60
61 fn style_mut(&mut self) -> &mut ElementStyle;
62 fn handlers_mut(&mut self) -> &mut ElementHandlers<V>;
63 fn layout(&mut self, view: &mut V, cx: &mut LayoutContext<V>)
64 -> Result<(NodeId, Self::Layout)>;
65 fn paint<'a>(
66 &mut self,
67 layout: Layout<Self::Layout>,
68 view: &mut V,
69 cx: &mut PaintContext<V>,
70 ) -> Result<()>;
71
72 /// Convert to a dynamically-typed element suitable for layout and paint.
73 fn into_any(self) -> AnyElement<V>
74 where
75 Self: 'static + Sized,
76 {
77 AnyElement {
78 element: Box::new(self) as Box<dyn ElementObject<V>>,
79 layout: None,
80 }
81 }
82
83 fn adapt(self) -> Adapter<V>
84 where
85 Self: Sized,
86 Self: Element<V>,
87 {
88 Adapter(self.into_any())
89 }
90
91 fn click(mut self, handler: impl Fn(&mut V, MouseClick) + 'static) -> Self
92 where
93 Self: Sized,
94 {
95 self.handlers_mut().click = Some(Rc::new(move |view, event| {
96 handler(view, event);
97 }));
98 self
99 }
100
101 // Display ////////////////////
102
103 fn block(mut self) -> Self
104 where
105 Self: Sized,
106 {
107 self.style_mut().display = Display::Block;
108 self
109 }
110
111 fn flex(mut self) -> Self
112 where
113 Self: Sized,
114 {
115 self.style_mut().display = Display::Flex;
116 self
117 }
118
119 fn grid(mut self) -> Self
120 where
121 Self: Sized,
122 {
123 self.style_mut().display = Display::Grid;
124 self
125 }
126
127 // style::Overflow ///////////////////
128
129 fn overflow_visible(mut self) -> Self
130 where
131 Self: Sized,
132 {
133 self.style_mut().overflow.x = Overflow::Visible;
134 self.style_mut().overflow.y = Overflow::Visible;
135 self
136 }
137
138 fn overflow_hidden(mut self) -> Self
139 where
140 Self: Sized,
141 {
142 self.style_mut().overflow.x = Overflow::Hidden;
143 self.style_mut().overflow.y = Overflow::Hidden;
144 self
145 }
146
147 fn overflow_scroll(mut self) -> Self
148 where
149 Self: Sized,
150 {
151 self.style_mut().overflow.x = Overflow::Scroll;
152 self.style_mut().overflow.y = Overflow::Scroll;
153 self
154 }
155
156 fn overflow_x_visible(mut self) -> Self
157 where
158 Self: Sized,
159 {
160 self.style_mut().overflow.x = Overflow::Visible;
161 self
162 }
163
164 fn overflow_x_hidden(mut self) -> Self
165 where
166 Self: Sized,
167 {
168 self.style_mut().overflow.x = Overflow::Hidden;
169 self
170 }
171
172 fn overflow_x_scroll(mut self) -> Self
173 where
174 Self: Sized,
175 {
176 self.style_mut().overflow.x = Overflow::Scroll;
177 self
178 }
179
180 fn overflow_y_visible(mut self) -> Self
181 where
182 Self: Sized,
183 {
184 self.style_mut().overflow.y = Overflow::Visible;
185 self
186 }
187
188 fn overflow_y_hidden(mut self) -> Self
189 where
190 Self: Sized,
191 {
192 self.style_mut().overflow.y = Overflow::Hidden;
193 self
194 }
195
196 fn overflow_y_scroll(mut self) -> Self
197 where
198 Self: Sized,
199 {
200 self.style_mut().overflow.y = Overflow::Scroll;
201 self
202 }
203
204 // Position ///////////////////
205
206 fn relative(mut self) -> Self
207 where
208 Self: Sized,
209 {
210 self.style_mut().position = Position::Relative;
211 self
212 }
213
214 fn absolute(mut self) -> Self
215 where
216 Self: Sized,
217 {
218 self.style_mut().position = Position::Absolute;
219
220 self
221 }
222
223 #[tailwind_lengths]
224 fn inset_(mut self, length: DefinedLength) -> Self
225 where
226 Self: Sized,
227 {
228 self.style_mut().inset.top = length;
229 self.style_mut().inset.right = length;
230 self.style_mut().inset.bottom = length;
231 self.style_mut().inset.left = length;
232 self
233 }
234
235 fn w(mut self, width: impl Into<Length>) -> Self
236 where
237 Self: Sized,
238 {
239 self.style_mut().size.width = width.into();
240 self
241 }
242
243 fn w_auto(mut self) -> Self
244 where
245 Self: Sized,
246 {
247 self.style_mut().size.width = Length::Auto;
248 self
249 }
250
251 #[tailwind_lengths]
252 fn w_(mut self, length: DefinedLength) -> Self
253 where
254 Self: Sized,
255 {
256 self.style_mut().size.width = length;
257 self
258 }
259
260 #[tailwind_lengths]
261 fn min_w_(mut self, length: DefinedLength) -> Self
262 where
263 Self: Sized,
264 {
265 self.style_mut().min_size.width = length;
266 self
267 }
268
269 fn h(mut self, height: impl Into<Length>) -> Self
270 where
271 Self: Sized,
272 {
273 self.style_mut().size.height = height.into();
274 self
275 }
276
277 fn h_auto(mut self) -> Self
278 where
279 Self: Sized,
280 {
281 self.style_mut().size.height = Length::Auto;
282 self
283 }
284
285 #[tailwind_lengths]
286 fn h_(mut self, height: DefinedLength) -> Self
287 where
288 Self: Sized,
289 {
290 self.style_mut().size.height = height;
291 self
292 }
293
294 #[tailwind_lengths]
295 fn min_h_(mut self, length: DefinedLength) -> Self
296 where
297 Self: Sized,
298 {
299 self.style_mut().min_size.height = length;
300 self
301 }
302
303 fn fill(mut self, fill: impl Into<Fill>) -> Self
304 where
305 Self: Sized,
306 {
307 self.style_mut().fill = fill.into();
308 self
309 }
310}
311
312pub trait ElementObject<V> {
313 fn style_mut(&mut self) -> &mut ElementStyle;
314 fn handlers_mut(&mut self) -> &mut ElementHandlers<V>;
315 fn layout(&mut self, view: &mut V, cx: &mut LayoutContext<V>)
316 -> Result<(NodeId, Box<dyn Any>)>;
317 fn paint(
318 &mut self,
319 layout: Layout<dyn Any>,
320 view: &mut V,
321 cx: &mut PaintContext<V>,
322 ) -> Result<()>;
323}
324
325impl<V: 'static, E: Element<V>> ElementObject<V> for E {
326 fn style_mut(&mut self) -> &mut ElementStyle {
327 Element::style_mut(self)
328 }
329
330 fn handlers_mut(&mut self) -> &mut ElementHandlers<V> {
331 Element::handlers_mut(self)
332 }
333
334 fn layout(
335 &mut self,
336 view: &mut V,
337 cx: &mut LayoutContext<V>,
338 ) -> Result<(NodeId, Box<dyn Any>)> {
339 let (node_id, layout) = self.layout(view, cx)?;
340 let layout = Box::new(layout) as Box<dyn Any>;
341 Ok((node_id, layout))
342 }
343
344 fn paint(
345 &mut self,
346 layout: Layout<dyn Any>,
347 view: &mut V,
348 cx: &mut PaintContext<V>,
349 ) -> Result<()> {
350 let layout = Layout {
351 from_engine: layout.from_engine,
352 from_element: layout.from_element.downcast_mut::<E::Layout>().unwrap(),
353 };
354
355 self.paint(layout, view, cx)
356 }
357
358 // fn clone_object(&self) -> Box<dyn ElementObject<V>> {
359 // Box::new(Clone::clone(self))
360 // }
361}
362
363pub struct AnyElement<V> {
364 element: Box<dyn ElementObject<V>>,
365 layout: Option<(NodeId, Box<dyn Any>)>,
366}
367
368impl<V> AnyElement<V> {
369 pub fn layout(&mut self, view: &mut V, cx: &mut LayoutContext<V>) -> Result<NodeId> {
370 let (node_id, layout) = self.element.layout(view, cx)?;
371 self.layout = Some((node_id, layout));
372 Ok(node_id)
373 }
374
375 pub fn paint(&mut self, view: &mut V, cx: &mut PaintContext<V>) -> Result<()> {
376 let (layout_node_id, element_layout) =
377 self.layout.as_mut().expect("paint called before layout");
378
379 let layout = Layout {
380 from_engine: cx
381 .layout_engine()
382 .unwrap()
383 .computed_layout(*layout_node_id)
384 .expect("you can currently only use playground elements within an adapter"),
385 from_element: element_layout.as_mut(),
386 };
387
388 self.element.paint(layout, view, cx)
389 }
390}
391
392impl<V: 'static> Element<V> for AnyElement<V> {
393 type Layout = ();
394
395 fn style_mut(&mut self) -> &mut ElementStyle {
396 self.element.style_mut()
397 }
398
399 fn handlers_mut(&mut self) -> &mut ElementHandlers<V> {
400 self.element.handlers_mut()
401 }
402
403 fn layout(
404 &mut self,
405 view: &mut V,
406 cx: &mut LayoutContext<V>,
407 ) -> Result<(NodeId, Self::Layout)> {
408 Ok((self.layout(view, cx)?, ()))
409 }
410
411 fn paint(&mut self, layout: Layout<()>, view: &mut V, cx: &mut PaintContext<V>) -> Result<()> {
412 self.paint(view, cx)
413 }
414}