Simplify adapter

Nathan Sobo created

Change summary

crates/gpui/playground/src/adapter.rs    | 42 +++++------------
crates/gpui/playground/src/element.rs    | 37 +++++++++++++--
crates/gpui/playground/src/playground.rs | 62 ++-----------------------
crates/gpui/playground/src/view.rs       | 22 +++++++++
crates/gpui/src/app/window.rs            |  1 
crates/gpui/src/elements.rs              | 10 +++
6 files changed, 81 insertions(+), 93 deletions(-)

Detailed changes

crates/gpui/playground/src/adapter.rs 🔗

@@ -5,25 +5,22 @@ use util::ResultExt;
 use crate::element::AnyElement;
 
 #[derive(Clone)]
-pub struct Adapter<V> {
-    view: V,
-    element: AnyElement<V>,
-}
+pub struct Adapter<V>(pub(crate) AnyElement<V>);
 
-impl<V: 'static> gpui::Element<Adapter<V>> for Adapter<V> {
+impl<V: 'static> gpui::Element<V> for Adapter<V> {
     type LayoutState = ();
     type PaintState = ();
 
     fn layout(
         &mut self,
         constraint: gpui::SizeConstraint,
-        view: &mut Self,
-        legacy_cx: &mut gpui::LayoutContext<Self>,
+        view: &mut V,
+        legacy_cx: &mut gpui::LayoutContext<V>,
     ) -> (gpui::geometry::vector::Vector2F, Self::LayoutState) {
         legacy_cx.push_layout_engine();
         let node = self
-            .element
-            .layout(&mut self.view, &mut LayoutContext { legacy_cx })
+            .0
+            .layout(view, &mut LayoutContext { legacy_cx })
             .log_err();
 
         if let Some(node) = node {
@@ -41,11 +38,11 @@ impl<V: 'static> gpui::Element<Adapter<V>> for Adapter<V> {
         bounds: RectF,
         visible_bounds: RectF,
         layout: &mut (),
-        adapter: &mut Self,
-        legacy_cx: &mut gpui::PaintContext<Self>,
+        view: &mut V,
+        legacy_cx: &mut gpui::PaintContext<V>,
     ) -> Self::PaintState {
         let mut cx = PaintContext { legacy_cx, scene };
-        self.element.paint(&mut adapter.view, &mut cx).log_err();
+        self.0.paint(view, &mut cx).log_err();
     }
 
     fn rect_for_text_range(
@@ -55,8 +52,8 @@ impl<V: 'static> gpui::Element<Adapter<V>> for Adapter<V> {
         visible_bounds: RectF,
         layout: &Self::LayoutState,
         paint: &Self::PaintState,
-        view: &Adapter<V>,
-        cx: &gpui::ViewContext<Adapter<V>>,
+        view: &V,
+        cx: &gpui::ViewContext<V>,
     ) -> Option<RectF> {
         todo!()
     }
@@ -66,22 +63,9 @@ impl<V: 'static> gpui::Element<Adapter<V>> for Adapter<V> {
         bounds: RectF,
         layout: &Self::LayoutState,
         paint: &Self::PaintState,
-        view: &Adapter<V>,
-        cx: &gpui::ViewContext<Adapter<V>>,
+        view: &V,
+        cx: &gpui::ViewContext<V>,
     ) -> gpui::serde_json::Value {
         todo!()
     }
 }
-
-impl<V: 'static> gpui::Entity for Adapter<V> {
-    type Event = ();
-}
-
-impl<V: 'static> gpui::View for Adapter<V>
-where
-    V: Clone,
-{
-    fn render(&mut self, cx: &mut gpui::ViewContext<'_, '_, Self>) -> gpui::AnyElement<Self> {
-        gpui::Element::into_any(self.clone())
-    }
-}

crates/gpui/playground/src/element.rs 🔗

@@ -10,14 +10,14 @@ pub use taffy::tree::NodeId;
 
 #[derive(Deref, DerefMut)]
 pub struct LayoutContext<'a, 'b, 'c, 'd, V> {
-    pub(crate) legacy_cx: &'d mut LegacyLayoutContext<'a, 'b, 'c, Adapter<V>>,
+    pub(crate) legacy_cx: &'d mut LegacyLayoutContext<'a, 'b, 'c, V>,
 }
 
 #[derive(Deref, DerefMut)]
 pub struct PaintContext<'a, 'b, 'c, 'd, V> {
     #[deref]
     #[deref_mut]
-    pub(crate) legacy_cx: &'d mut LegacyPaintContext<'a, 'b, 'c, Adapter<V>>,
+    pub(crate) legacy_cx: &'d mut LegacyPaintContext<'a, 'b, 'c, V>,
     pub(crate) scene: &'d mut gpui::SceneBuilder,
 }
 
@@ -37,6 +37,14 @@ pub trait Element<V: 'static>: 'static + Clone {
         }
     }
 
+    fn adapt(self) -> Adapter<V>
+    where
+        Self: Sized,
+        Self: Element<V>,
+    {
+        Adapter(self.into_any())
+    }
+
     // Display ////////////////////
 
     fn block(mut self) -> Self
@@ -200,14 +208,15 @@ pub trait Element<V: 'static>: 'static + Clone {
 }
 
 pub trait ElementObject<V> {
-    fn clone_object(&self) -> Box<dyn ElementObject<V>>;
+    fn style_mut(&mut self) -> &mut Style;
     fn layout(&mut self, view: &mut V, cx: &mut LayoutContext<V>) -> Result<NodeId>;
     fn paint(&mut self, layout: Layout, view: &mut V, cx: &mut PaintContext<V>) -> Result<()>;
+    fn clone_object(&self) -> Box<dyn ElementObject<V>>;
 }
 
 impl<V: 'static, E: Element<V>> ElementObject<V> for E {
-    fn clone_object(&self) -> Box<dyn ElementObject<V>> {
-        Box::new(Clone::clone(self))
+    fn style_mut(&mut self) -> &mut Style {
+        self.style_mut()
     }
 
     fn layout(&mut self, view: &mut V, cx: &mut LayoutContext<V>) -> Result<NodeId> {
@@ -217,6 +226,10 @@ impl<V: 'static, E: Element<V>> ElementObject<V> for E {
     fn paint(&mut self, layout: Layout, view: &mut V, cx: &mut PaintContext<V>) -> Result<()> {
         self.paint(layout, view, cx)
     }
+
+    fn clone_object(&self) -> Box<dyn ElementObject<V>> {
+        Box::new(Clone::clone(self))
+    }
 }
 
 pub struct AnyElement<V> {
@@ -250,3 +263,17 @@ impl<V> Clone for AnyElement<V> {
         }
     }
 }
+
+impl<V: 'static> Element<V> for AnyElement<V> {
+    fn style_mut(&mut self) -> &mut Style {
+        self.element.style_mut()
+    }
+
+    fn layout(&mut self, view: &mut V, cx: &mut LayoutContext<V>) -> Result<NodeId> {
+        self.layout(view, cx)
+    }
+
+    fn paint(&mut self, layout: Layout, view: &mut V, cx: &mut PaintContext<V>) -> Result<()> {
+        self.paint(view, cx)
+    }
+}

crates/gpui/playground/src/playground.rs 🔗

@@ -3,22 +3,20 @@ use element::{AnyElement, Element};
 use frame::frame;
 use log::LevelFilter;
 use simplelog::SimpleLogger;
-use taffy::tree::NodeId;
 
 fn main() {
     SimpleLogger::init(LevelFilter::Info, Default::default()).expect("could not initialize logger");
 
     gpui::App::new(()).unwrap().run(|cx| {
+        cx.add_window(Default::default(), |_| {
+            view(|_| workspace(&rose_pine::moon()))
+        });
         cx.platform().activate(true);
-
-        // cx.add_window(
-        //     Default::default(),
-        //     // |_| view(|_| Playground::new()),
-        // );
     });
 }
 
 use themes::{rose_pine, ThemeColors};
+use view::view;
 
 mod adapter;
 mod color;
@@ -26,60 +24,10 @@ mod element;
 mod frame;
 mod style;
 mod themes;
+mod view;
 
 pub struct Playground<V: 'static>(AnyElement<V>);
 
-impl<V: 'static> gpui::Element<V> for Playground<V> {
-    type LayoutState = NodeId;
-
-    type PaintState = ();
-
-    fn layout(
-        &mut self,
-        constraint: gpui::SizeConstraint,
-        view: &mut V,
-        cx: &mut gpui::LayoutContext<V>,
-    ) -> (gpui::geometry::vector::Vector2F, Self::LayoutState) {
-        todo!()
-    }
-
-    fn paint(
-        &mut self,
-        scene: &mut gpui::SceneBuilder,
-        bounds: gpui::geometry::rect::RectF,
-        visible_bounds: gpui::geometry::rect::RectF,
-        layout: &mut Self::LayoutState,
-        view: &mut V,
-        cx: &mut gpui::PaintContext<V>,
-    ) -> Self::PaintState {
-        todo!()
-    }
-
-    fn rect_for_text_range(
-        &self,
-        range_utf16: std::ops::Range<usize>,
-        bounds: gpui::geometry::rect::RectF,
-        visible_bounds: gpui::geometry::rect::RectF,
-        layout: &Self::LayoutState,
-        paint: &Self::PaintState,
-        view: &V,
-        cx: &gpui::ViewContext<V>,
-    ) -> Option<gpui::geometry::rect::RectF> {
-        todo!()
-    }
-
-    fn debug(
-        &self,
-        bounds: gpui::geometry::rect::RectF,
-        layout: &Self::LayoutState,
-        paint: &Self::PaintState,
-        view: &V,
-        cx: &gpui::ViewContext<V>,
-    ) -> gpui::serde_json::Value {
-        todo!()
-    }
-}
-
 impl<V> Playground<V> {
     pub fn new() -> Self {
         Self(workspace(&rose_pine::moon()).into_any())

crates/gpui/playground/src/view.rs 🔗

@@ -0,0 +1,22 @@
+use crate::element::{AnyElement, Element};
+use gpui::{Element as _, ViewContext};
+
+pub fn view<F, E>(mut render: F) -> ViewFn
+where
+    F: 'static + FnMut(&mut ViewContext<ViewFn>) -> E,
+    E: Element<ViewFn>,
+{
+    ViewFn(Box::new(move |cx| (render)(cx).into_any()))
+}
+
+pub struct ViewFn(Box<dyn FnMut(&mut ViewContext<ViewFn>) -> AnyElement<ViewFn>>);
+
+impl gpui::Entity for ViewFn {
+    type Event = ();
+}
+
+impl gpui::View for ViewFn {
+    fn render(&mut self, cx: &mut ViewContext<Self>) -> gpui::AnyElement<Self> {
+        (self.0)(cx).adapt().into_any()
+    }
+}

crates/gpui/src/app/window.rs 🔗

@@ -1461,6 +1461,7 @@ impl ToJson for SizeConstraint {
     }
 }
 
+#[derive(Clone)]
 pub struct ChildView {
     view_id: usize,
     view_name: &'static str,

crates/gpui/src/elements.rs 🔗

@@ -33,8 +33,8 @@ use crate::{
         rect::RectF,
         vector::{vec2f, Vector2F},
     },
-    json, Action, LayoutContext, PaintContext, SceneBuilder, SizeConstraint, View, ViewContext,
-    WeakViewHandle, WindowContext,
+    json, Action, Entity, LayoutContext, PaintContext, SceneBuilder, SizeConstraint, View,
+    ViewContext, WeakViewHandle, WindowContext,
 };
 use anyhow::{anyhow, Result};
 use collections::HashMap;
@@ -564,6 +564,12 @@ impl<V: 'static> Element<V> for AnyElement<V> {
     }
 }
 
+impl Entity for AnyElement<()> {
+    type Event = ();
+}
+
+// impl View for AnyElement<()> {}
+
 pub struct RootElement<V> {
     element: AnyElement<V>,
     view: WeakViewHandle<V>,