mirror of
https://github.com/zed-industries/zed.git
synced 2025-02-12 05:27:07 +00:00
gpui2: Add on_hover events
This commit is contained in:
parent
d73c54f604
commit
26e64fb843
2 changed files with 64 additions and 0 deletions
|
@ -333,6 +333,37 @@ pub trait StatefulInteractive<V: 'static>: StatelessInteractive<V> {
|
||||||
}));
|
}));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn on_hover(mut self, listener: impl 'static + Fn(&mut V, bool, &mut ViewContext<V>)) -> Self
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
debug_assert!(
|
||||||
|
self.stateful_interaction().hover_listener.is_none(),
|
||||||
|
"calling on_hover more than once on the same element is not supported"
|
||||||
|
);
|
||||||
|
self.stateful_interaction().hover_listener = Some(Box::new(listener));
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
fn tooltip<W>(
|
||||||
|
mut self,
|
||||||
|
build_tooltip: impl Fn(&mut V, &mut ViewContext<V>) -> View<W> + 'static,
|
||||||
|
) -> Self
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
W: 'static + Render,
|
||||||
|
{
|
||||||
|
debug_assert!(
|
||||||
|
self.stateful_interaction().tooltip_builder.is_none(),
|
||||||
|
"calling tooltip more than once on the same element is not supported"
|
||||||
|
);
|
||||||
|
self.stateful_interaction().tooltip_builder = Some(Box::new(move |view_state, cx| {
|
||||||
|
build_tooltip(view_state, cx).into()
|
||||||
|
}));
|
||||||
|
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ElementInteraction<V: 'static>: 'static {
|
pub trait ElementInteraction<V: 'static>: 'static {
|
||||||
|
@ -568,6 +599,24 @@ pub trait ElementInteraction<V: 'static>: 'static {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(hover_listener) = stateful.hover_listener.take() {
|
||||||
|
let was_hovered = element_state.hover_state.clone();
|
||||||
|
let has_mouse_down = element_state.pending_mouse_down.lock().is_some();
|
||||||
|
cx.on_mouse_event(move |view_state, event: &MouseMoveEvent, phase, cx| {
|
||||||
|
if phase != DispatchPhase::Bubble {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let is_hovered = bounds.contains_point(&event.position) && !has_mouse_down;
|
||||||
|
let mut was_hovered = was_hovered.lock();
|
||||||
|
|
||||||
|
if is_hovered != was_hovered.clone() {
|
||||||
|
*was_hovered = is_hovered;
|
||||||
|
drop(was_hovered);
|
||||||
|
hover_listener(view_state, is_hovered, cx);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
let active_state = element_state.active_state.clone();
|
let active_state = element_state.active_state.clone();
|
||||||
if active_state.lock().is_none() {
|
if active_state.lock().is_none() {
|
||||||
let active_group_bounds = stateful
|
let active_group_bounds = stateful
|
||||||
|
@ -639,6 +688,8 @@ pub struct StatefulInteraction<V> {
|
||||||
active_style: StyleRefinement,
|
active_style: StyleRefinement,
|
||||||
group_active_style: Option<GroupStyle>,
|
group_active_style: Option<GroupStyle>,
|
||||||
drag_listener: Option<DragListener<V>>,
|
drag_listener: Option<DragListener<V>>,
|
||||||
|
hover_listener: Option<HoverListener<V>>,
|
||||||
|
tooltip_builder: Option<TooltipBuilder<V>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<V: 'static> ElementInteraction<V> for StatefulInteraction<V> {
|
impl<V: 'static> ElementInteraction<V> for StatefulInteraction<V> {
|
||||||
|
@ -666,6 +717,8 @@ impl<V> From<ElementId> for StatefulInteraction<V> {
|
||||||
stateless: StatelessInteraction::default(),
|
stateless: StatelessInteraction::default(),
|
||||||
click_listeners: SmallVec::new(),
|
click_listeners: SmallVec::new(),
|
||||||
drag_listener: None,
|
drag_listener: None,
|
||||||
|
hover_listener: None,
|
||||||
|
tooltip_builder: None,
|
||||||
active_style: StyleRefinement::default(),
|
active_style: StyleRefinement::default(),
|
||||||
group_active_style: None,
|
group_active_style: None,
|
||||||
}
|
}
|
||||||
|
@ -695,6 +748,8 @@ impl<V> StatelessInteraction<V> {
|
||||||
stateless: self,
|
stateless: self,
|
||||||
click_listeners: SmallVec::new(),
|
click_listeners: SmallVec::new(),
|
||||||
drag_listener: None,
|
drag_listener: None,
|
||||||
|
hover_listener: None,
|
||||||
|
tooltip_builder: None,
|
||||||
active_style: StyleRefinement::default(),
|
active_style: StyleRefinement::default(),
|
||||||
group_active_style: None,
|
group_active_style: None,
|
||||||
}
|
}
|
||||||
|
@ -746,6 +801,7 @@ impl ActiveState {
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct InteractiveElementState {
|
pub struct InteractiveElementState {
|
||||||
active_state: Arc<Mutex<ActiveState>>,
|
active_state: Arc<Mutex<ActiveState>>,
|
||||||
|
hover_state: Arc<Mutex<bool>>,
|
||||||
pending_mouse_down: Arc<Mutex<Option<MouseDownEvent>>>,
|
pending_mouse_down: Arc<Mutex<Option<MouseDownEvent>>>,
|
||||||
scroll_offset: Option<Arc<Mutex<Point<Pixels>>>>,
|
scroll_offset: Option<Arc<Mutex<Point<Pixels>>>>,
|
||||||
}
|
}
|
||||||
|
@ -1097,6 +1153,10 @@ pub type ClickListener<V> = Box<dyn Fn(&mut V, &ClickEvent, &mut ViewContext<V>)
|
||||||
pub(crate) type DragListener<V> =
|
pub(crate) type DragListener<V> =
|
||||||
Box<dyn Fn(&mut V, Point<Pixels>, &mut ViewContext<V>) -> AnyDrag + 'static>;
|
Box<dyn Fn(&mut V, Point<Pixels>, &mut ViewContext<V>) -> AnyDrag + 'static>;
|
||||||
|
|
||||||
|
pub(crate) type HoverListener<V> = Box<dyn Fn(&mut V, bool, &mut ViewContext<V>) + 'static>;
|
||||||
|
|
||||||
|
pub(crate) type TooltipBuilder<V> = Box<dyn Fn(&mut V, &mut ViewContext<V>) -> AnyView + 'static>;
|
||||||
|
|
||||||
pub type KeyListener<V> = Box<
|
pub type KeyListener<V> = Box<
|
||||||
dyn Fn(
|
dyn Fn(
|
||||||
&mut V,
|
&mut V,
|
||||||
|
|
|
@ -1399,6 +1399,10 @@ impl Pane {
|
||||||
.group("")
|
.group("")
|
||||||
.id(item.id())
|
.id(item.id())
|
||||||
.cursor_pointer()
|
.cursor_pointer()
|
||||||
|
.on_hover(|_, hovered, _| {
|
||||||
|
dbg!(hovered);
|
||||||
|
})
|
||||||
|
// .tooltip(|pane, cx| cx.create_view( tooltip.child("Hovering the tab"))
|
||||||
// .on_drag(move |pane, cx| pane.render_tab(ix, item.boxed_clone(), detail, cx))
|
// .on_drag(move |pane, cx| pane.render_tab(ix, item.boxed_clone(), detail, cx))
|
||||||
// .drag_over::<DraggedTab>(|d| d.bg(cx.theme().colors().element_drop_target))
|
// .drag_over::<DraggedTab>(|d| d.bg(cx.theme().colors().element_drop_target))
|
||||||
// .on_drop(|_view, state: View<DraggedTab>, cx| {
|
// .on_drop(|_view, state: View<DraggedTab>, cx| {
|
||||||
|
|
Loading…
Reference in a new issue