WIP

Antonio Scandurra created

Change summary

crates/gpui3/src/elements.rs           |   1 
crates/gpui3/src/elements/hoverable.rs | 125 +++++++++++----------------
crates/gpui3/src/styled.rs             |  12 +-
3 files changed, 58 insertions(+), 80 deletions(-)

Detailed changes

crates/gpui3/src/elements/hoverable.rs 🔗

@@ -1,23 +1,11 @@
 use crate::{
-    element::{AnyElement, Element, IntoElement, Layout, ParentElement},
-    interactive::{InteractionHandlers, Interactive},
-    style::{Style, StyleHelpers, Styleable},
-    ViewContext,
+    Bounds, Element, Interactive, MouseEventListeners, Pixels, Style, Styled, ViewContext,
 };
 use anyhow::Result;
-use gpui::{geometry::vector::Vector2F, platform::MouseMovedEvent, LayoutId};
-use refineable::{CascadeSlot, Refineable, RefinementCascade};
-use smallvec::SmallVec;
+use refineable::{CascadeSlot, RefinementCascade};
 use std::{cell::Cell, rc::Rc};
 
-pub struct Hoverable<E: Styleable> {
-    hovered: Rc<Cell<bool>>,
-    cascade_slot: CascadeSlot,
-    hovered_style: <E::Style as Refineable>::Refinement,
-    child: E,
-}
-
-pub fn hoverable<E: Styleable>(mut child: E) -> Hoverable<E> {
+pub fn hoverable<E: Styled>(mut child: E) -> Hoverable<E> {
     Hoverable {
         hovered: Rc::new(Cell::new(false)),
         cascade_slot: child.style_cascade().reserve(),
@@ -26,80 +14,69 @@ pub fn hoverable<E: Styleable>(mut child: E) -> Hoverable<E> {
     }
 }
 
-impl<E: Styleable> Styleable for Hoverable<E> {
+pub struct Hoverable<E: Styled> {
+    hovered: Rc<Cell<bool>>,
+    cascade_slot: CascadeSlot,
+    hovered_style: RefinementCascade<E::Style>,
+    child: E,
+}
+
+impl<E> Styled for Hoverable<E>
+where
+    E: Styled,
+{
     type Style = E::Style;
 
-    fn style_cascade(&mut self) -> &mut RefinementCascade<Self::Style> {
+    fn style_cascade(&mut self) -> &mut RefinementCascade<E::Style> {
         self.child.style_cascade()
     }
 
-    fn declared_style(&mut self) -> &mut <Self::Style as Refineable>::Refinement {
+    fn declared_style(&mut self) -> &mut <Self::Style as refineable::Refineable>::Refinement {
         &mut self.hovered_style
     }
 }
 
-impl<V: 'static, E: Element<V> + Styleable> Element<V> for Hoverable<E> {
-    type PaintState = E::PaintState;
+impl<S: 'static + Send + Sync, E: Interactive<S> + Styled> Interactive<S> for Hoverable<E> {
+    fn listeners(&mut self) -> &mut MouseEventListeners<S> {
+        self.child.listeners()
+    }
+}
+
+impl<E: Element + Styled> Element for Hoverable<E> {
+    type State = E::State;
+    type FrameState = E::FrameState;
 
     fn layout(
         &mut self,
-        view: &mut V,
-        cx: &mut ViewContext<V>,
-    ) -> Result<(LayoutId, Self::PaintState)>
-    where
-        Self: Sized,
-    {
-        Ok(self.child.layout(view, cx)?)
+        state: &mut Self::State,
+        cx: &mut ViewContext<Self::State>,
+    ) -> Result<(crate::LayoutId, Self::FrameState)> {
+        Ok(self.child.layout(state, cx)?)
     }
 
     fn paint(
         &mut self,
-        view: &mut V,
-        parent_origin: Vector2F,
-        layout: &Layout,
-        paint_state: &mut Self::PaintState,
-        cx: &mut ViewContext<V>,
-    ) where
-        Self: Sized,
-    {
-        let bounds = layout.bounds + parent_origin;
-        self.hovered.set(bounds.contains_point(cx.mouse_position()));
-
-        let slot = self.cascade_slot;
-        let style = self.hovered.get().then_some(self.hovered_style.clone());
-        self.style_cascade().set(slot, style);
-
-        let hovered = self.hovered.clone();
-        cx.on_event(layout.order, move |_view, _: &MouseMovedEvent, cx| {
-            cx.bubble_event();
-            if bounds.contains_point(cx.mouse_position()) != hovered.get() {
-                cx.repaint();
-            }
-        });
-
-        self.child
-            .paint(view, parent_origin, layout, paint_state, cx);
-    }
-}
-
-impl<E: Styleable<Style = Style>> StyleHelpers for Hoverable<E> {}
-
-impl<V: 'static, E: Interactive<V> + Styleable> Interactive<V> for Hoverable<E> {
-    fn interaction_handlers(&mut self) -> &mut InteractionHandlers<V> {
-        self.child.interaction_handlers()
-    }
-}
-
-impl<V: 'static, E: ParentElement<V> + Styleable> ParentElement<V> for Hoverable<E> {
-    fn children_mut(&mut self) -> &mut SmallVec<[AnyElement<V>; 2]> {
-        self.child.children_mut()
-    }
-}
-
-impl<V: 'static, E: Element<V> + Styleable> IntoElement<V> for Hoverable<E> {
-    type Element = Self;
-
-    fn into_element(self) -> Self::Element {
-        self
+        bounds: Bounds<Pixels>,
+        state: &mut Self::State,
+        frame_state: &mut Self::FrameState,
+        cx: &mut ViewContext<Self::State>,
+    ) -> Result<()> {
+        todo!()
+        // self.hovered.set(bounds.contains_point(cx.mouse_position()));
+
+        // let slot = self.cascade_slot;
+        // let style = self.hovered.get().then_some(self.hovered_style.clone());
+        // self.style_cascade().set(slot, style);
+
+        // let hovered = self.hovered.clone();
+        // cx.on_event(layout.order, move |_view, _: &MouseMovedEvent, cx| {
+        //     cx.bubble_event();
+        //     if bounds.contains_point(cx.mouse_position()) != hovered.get() {
+        //         cx.repaint();
+        //     }
+        // });
+
+        // self.child
+        //     .paint(view, parent_origin, layout, paint_state, cx);
     }
 }

crates/gpui3/src/styled.rs 🔗

@@ -10,12 +10,12 @@ pub trait Styled {
         Self::Style::from_refinement(&self.style_cascade().merged())
     }
 
-    // fn hover(self) -> Hoverable<Self>
-    // where
-    //     Self: Sized,
-    // {
-    //     hoverable(self)
-    // }
+    fn hover(self) -> Hoverable<Self>
+    where
+        Self: Sized,
+    {
+        hoverable(self)
+    }
 
     // fn active(self) -> Pressable<Self>
     // where