crates/gpui3/src/elements.rs 🔗
@@ -1,4 +1,5 @@
mod div;
+mod hoverable;
mod img;
mod stateless;
mod svg;
Antonio Scandurra created
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(-)
@@ -1,4 +1,5 @@
mod div;
+mod hoverable;
mod img;
mod stateless;
mod svg;
@@ -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);
}
}
@@ -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