From bb95d58c7942bc96d681e815e3e99e271a933fe9 Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Tue, 27 Apr 2021 11:37:14 -0600 Subject: [PATCH] Relay hover events to tabs Co-Authored-By: Max Brunsfeld --- gpui/src/app.rs | 10 ++++++++- gpui/src/elements/mouse_event_handler.rs | 22 ++++++++++--------- gpui/src/presenter.rs | 27 ++++++++++++++++++------ zed/src/workspace/pane.rs | 3 ++- 4 files changed, 44 insertions(+), 18 deletions(-) diff --git a/gpui/src/app.rs b/gpui/src/app.rs index 425f940e6a..a8c636b060 100644 --- a/gpui/src/app.rs +++ b/gpui/src/app.rs @@ -788,7 +788,15 @@ impl MutableAppContext { } } - let actions = presenter.borrow_mut().dispatch_event(event, ctx.as_ref()); + let (actions, invalidated_views) = + presenter.borrow_mut().dispatch_event(event, ctx.as_ref()); + + ctx.window_invalidations + .entry(window_id) + .or_default() + .updated + .extend(invalidated_views.into_iter()); + for action in actions { ctx.dispatch_action_any( window_id, diff --git a/gpui/src/elements/mouse_event_handler.rs b/gpui/src/elements/mouse_event_handler.rs index 2cd41ca0c4..7554b53a6b 100644 --- a/gpui/src/elements/mouse_event_handler.rs +++ b/gpui/src/elements/mouse_event_handler.rs @@ -10,7 +10,7 @@ pub struct MouseEventHandler { child: ElementBox, } -#[derive(Clone, Copy, Default)] +#[derive(Clone, Copy, Debug, Default)] pub struct MouseState { hovered: bool, clicked: bool, @@ -66,36 +66,38 @@ impl Element for MouseEventHandler { _: &mut Self::PaintState, ctx: &mut EventContext, ) -> bool { + let handled_in_child = self.child.dispatch_event(event, ctx); + self.state.map(ctx.app, |state| match event { Event::MouseMoved { position } => { let mouse_in = bounds.contains_point(*position); if state.hovered != mouse_in { state.hovered = mouse_in; - // ctx.notify(); + ctx.notify(); true } else { - false + handled_in_child } } Event::LeftMouseDown { position, .. } => { - if bounds.contains_point(*position) { + if !handled_in_child && bounds.contains_point(*position) { state.clicked = true; - // ctx.notify(); + ctx.notify(); true } else { - false + handled_in_child } } Event::LeftMouseUp { .. } => { - if state.clicked { + if !handled_in_child && state.clicked { state.clicked = false; - // ctx.notify(); + ctx.notify(); true } else { - false + handled_in_child } } - _ => false, + _ => handled_in_child, }) } diff --git a/gpui/src/presenter.rs b/gpui/src/presenter.rs index 6efa214995..bbf1069790 100644 --- a/gpui/src/presenter.rs +++ b/gpui/src/presenter.rs @@ -9,7 +9,11 @@ use crate::{ }; use pathfinder_geometry::vector::{vec2f, Vector2F}; use serde_json::json; -use std::{any::Any, collections::HashMap, sync::Arc}; +use std::{ + any::Any, + collections::{HashMap, HashSet}, + sync::Arc, +}; pub struct Presenter { window_id: usize, @@ -114,20 +118,25 @@ impl Presenter { } } - pub fn dispatch_event(&mut self, event: Event, app: &AppContext) -> Vec { + pub fn dispatch_event( + &mut self, + event: Event, + app: &AppContext, + ) -> (Vec, HashSet) { if let Some(root_view_id) = app.root_view_id(self.window_id) { let mut ctx = EventContext { rendered_views: &mut self.rendered_views, - actions: Vec::new(), + actions: Default::default(), font_cache: &self.font_cache, text_layout_cache: &self.text_layout_cache, - view_stack: Vec::new(), + view_stack: Default::default(), + invalidated_views: Default::default(), app, }; ctx.dispatch_event(root_view_id, &event); - ctx.actions + (ctx.actions, ctx.invalidated_views) } else { - Vec::new() + Default::default() } } @@ -214,6 +223,7 @@ pub struct EventContext<'a> { pub text_layout_cache: &'a TextLayoutCache, pub app: &'a AppContext, view_stack: Vec, + invalidated_views: HashSet, } impl<'a> EventContext<'a> { @@ -236,6 +246,11 @@ impl<'a> EventContext<'a> { arg: Box::new(arg), }); } + + pub fn notify(&mut self) { + self.invalidated_views + .insert(*self.view_stack.last().unwrap()); + } } pub struct DebugContext<'a> { diff --git a/zed/src/workspace/pane.rs b/zed/src/workspace/pane.rs index bac92f5ab4..4767f30fda 100644 --- a/zed/src/workspace/pane.rs +++ b/zed/src/workspace/pane.rs @@ -229,7 +229,8 @@ impl Pane { row.add_child( Expanded::new( 1.0, - MouseEventHandler::new::(0, ctx, |mouse_state| { + MouseEventHandler::new::(item.id(), ctx, |mouse_state| { + log::info!("mouse event handler {:?}", mouse_state); ConstrainedBox::new( EventHandler::new(container.boxed()) .on_mouse_down(move |ctx| {