element.rs

  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}