From 1d7fc122297f6848f2fac27c95e4d2a923ab37d1 Mon Sep 17 00:00:00 2001 From: Antonio Scandurra Date: Fri, 27 May 2022 10:47:54 +0200 Subject: [PATCH] Add right-click support to `MouseEventHandler` --- crates/gpui/src/app.rs | 7 +++ .../gpui/src/elements/mouse_event_handler.rs | 22 ++++++++++ crates/gpui/src/platform/event.rs | 3 +- crates/gpui/src/platform/mac/event.rs | 1 + crates/gpui/src/presenter.rs | 43 +++++++++++++++++++ crates/gpui/src/scene.rs | 2 + 6 files changed, 77 insertions(+), 1 deletion(-) diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index 37bb86570b..5c8f49ac18 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -462,6 +462,7 @@ impl TestAppContext { titlebar_height: 0., hovered_region_ids: Default::default(), clicked_region_id: None, + right_clicked_region_id: None, refreshing: false, }; f(view, &mut render_cx) @@ -1082,6 +1083,7 @@ impl MutableAppContext { titlebar_height, hovered_region_ids: Default::default(), clicked_region_id: None, + right_clicked_region_id: None, refreshing: false, }) .unwrap(), @@ -3410,6 +3412,7 @@ pub struct RenderParams { pub titlebar_height: f32, pub hovered_region_ids: HashSet, pub clicked_region_id: Option, + pub right_clicked_region_id: Option, pub refreshing: bool, } @@ -3419,6 +3422,7 @@ pub struct RenderContext<'a, T: View> { pub(crate) view_type: PhantomData, pub(crate) hovered_region_ids: HashSet, pub(crate) clicked_region_id: Option, + pub(crate) right_clicked_region_id: Option, pub app: &'a mut MutableAppContext, pub titlebar_height: f32, pub refreshing: bool, @@ -3428,6 +3432,7 @@ pub struct RenderContext<'a, T: View> { pub struct MouseState { pub hovered: bool, pub clicked: bool, + pub right_clicked: bool, } impl<'a, V: View> RenderContext<'a, V> { @@ -3440,6 +3445,7 @@ impl<'a, V: View> RenderContext<'a, V> { titlebar_height: params.titlebar_height, hovered_region_ids: params.hovered_region_ids.clone(), clicked_region_id: params.clicked_region_id, + right_clicked_region_id: params.right_clicked_region_id, refreshing: params.refreshing, } } @@ -3461,6 +3467,7 @@ impl<'a, V: View> RenderContext<'a, V> { MouseState { hovered: self.hovered_region_ids.contains(®ion_id), clicked: self.clicked_region_id == Some(region_id), + right_clicked: self.right_clicked_region_id == Some(region_id), } } diff --git a/crates/gpui/src/elements/mouse_event_handler.rs b/crates/gpui/src/elements/mouse_event_handler.rs index a9535667fd..1ca4c13fc8 100644 --- a/crates/gpui/src/elements/mouse_event_handler.rs +++ b/crates/gpui/src/elements/mouse_event_handler.rs @@ -20,6 +20,8 @@ pub struct MouseEventHandler { cursor_style: Option, mouse_down_handler: Option>, click_handler: Option>, + right_mouse_down_handler: Option>, + right_click_handler: Option>, drag_handler: Option>, padding: Padding, } @@ -38,6 +40,8 @@ impl MouseEventHandler { cursor_style: None, mouse_down_handler: None, click_handler: None, + right_mouse_down_handler: None, + right_click_handler: None, drag_handler: None, padding: Default::default(), } @@ -64,6 +68,22 @@ impl MouseEventHandler { self } + pub fn on_right_mouse_down( + mut self, + handler: impl Fn(Vector2F, &mut EventContext) + 'static, + ) -> Self { + self.right_mouse_down_handler = Some(Rc::new(handler)); + self + } + + pub fn on_right_click( + mut self, + handler: impl Fn(Vector2F, usize, &mut EventContext) + 'static, + ) -> Self { + self.right_click_handler = Some(Rc::new(handler)); + self + } + pub fn on_drag(mut self, handler: impl Fn(Vector2F, &mut EventContext) + 'static) -> Self { self.drag_handler = Some(Rc::new(handler)); self @@ -117,6 +137,8 @@ impl Element for MouseEventHandler { hover: None, click: self.click_handler.clone(), mouse_down: self.mouse_down_handler.clone(), + right_click: self.right_click_handler.clone(), + right_mouse_down: self.right_mouse_down_handler.clone(), drag: self.drag_handler.clone(), }); diff --git a/crates/gpui/src/platform/event.rs b/crates/gpui/src/platform/event.rs index b32ab952c7..61cfa99bfe 100644 --- a/crates/gpui/src/platform/event.rs +++ b/crates/gpui/src/platform/event.rs @@ -43,6 +43,7 @@ pub enum Event { }, RightMouseUp { position: Vector2F, + click_count: usize, }, NavigateMouseDown { position: Vector2F, @@ -72,7 +73,7 @@ impl Event { | Event::LeftMouseUp { position, .. } | Event::LeftMouseDragged { position } | Event::RightMouseDown { position, .. } - | Event::RightMouseUp { position } + | Event::RightMouseUp { position, .. } | Event::NavigateMouseDown { position, .. } | Event::NavigateMouseUp { position, .. } | Event::MouseMoved { position, .. } => Some(*position), diff --git a/crates/gpui/src/platform/mac/event.rs b/crates/gpui/src/platform/mac/event.rs index 9d07177b16..4d3aa6cf9a 100644 --- a/crates/gpui/src/platform/mac/event.rs +++ b/crates/gpui/src/platform/mac/event.rs @@ -178,6 +178,7 @@ impl Event { native_event.locationInWindow().x as f32, window_height - native_event.locationInWindow().y as f32, ), + click_count: native_event.clickCount() as usize, }), NSEventType::NSOtherMouseDown => { let direction = match native_event.buttonNumber() { diff --git a/crates/gpui/src/presenter.rs b/crates/gpui/src/presenter.rs index 42149feca8..9a8a77258e 100644 --- a/crates/gpui/src/presenter.rs +++ b/crates/gpui/src/presenter.rs @@ -33,6 +33,7 @@ pub struct Presenter { last_mouse_moved_event: Option, hovered_region_ids: HashSet, clicked_region: Option, + right_clicked_region: Option, prev_drag_position: Option, titlebar_height: f32, } @@ -58,6 +59,7 @@ impl Presenter { last_mouse_moved_event: None, hovered_region_ids: Default::default(), clicked_region: None, + right_clicked_region: None, prev_drag_position: None, titlebar_height, } @@ -100,6 +102,10 @@ impl Presenter { titlebar_height: self.titlebar_height, hovered_region_ids: self.hovered_region_ids.clone(), clicked_region_id: self.clicked_region.as_ref().map(MouseRegion::id), + right_clicked_region_id: self + .right_clicked_region + .as_ref() + .map(MouseRegion::id), refreshing: false, }) .unwrap(), @@ -118,6 +124,10 @@ impl Presenter { titlebar_height: self.titlebar_height, hovered_region_ids: self.hovered_region_ids.clone(), clicked_region_id: self.clicked_region.as_ref().map(MouseRegion::id), + right_clicked_region_id: self + .right_clicked_region + .as_ref() + .map(MouseRegion::id), refreshing: true, }) .unwrap(); @@ -181,6 +191,7 @@ impl Presenter { refreshing, hovered_region_ids: self.hovered_region_ids.clone(), clicked_region_id: self.clicked_region.as_ref().map(MouseRegion::id), + right_clicked_region_id: self.right_clicked_region.as_ref().map(MouseRegion::id), titlebar_height: self.titlebar_height, app: cx, } @@ -207,6 +218,7 @@ impl Presenter { let mut hovered_regions = Vec::new(); let mut unhovered_regions = Vec::new(); let mut clicked_region = None; + let mut right_clicked_region = None; let mut dragged_region = None; match event { @@ -233,6 +245,27 @@ impl Presenter { } } } + Event::RightMouseDown { position, .. } => { + for region in self.mouse_regions.iter().rev() { + if region.bounds.contains_point(position) { + invalidated_views.push(region.view_id); + self.right_clicked_region = Some(region.clone()); + break; + } + } + } + Event::RightMouseUp { + position, + click_count, + .. + } => { + if let Some(region) = self.right_clicked_region.take() { + invalidated_views.push(region.view_id); + if region.bounds.contains_point(position) { + right_clicked_region = Some((region, position, click_count)); + } + } + } Event::MouseMoved { position, left_mouse_down, @@ -311,6 +344,14 @@ impl Presenter { } } + if let Some((right_clicked_region, position, click_count)) = right_clicked_region { + if let Some(right_click_callback) = right_clicked_region.right_click { + event_cx.with_current_view(right_clicked_region.view_id, |event_cx| { + right_click_callback(position, click_count, event_cx); + }) + } + } + if let Some((dragged_region, delta)) = dragged_region { if let Some(drag_callback) = dragged_region.drag { event_cx.with_current_view(dragged_region.view_id, |event_cx| { @@ -389,6 +430,7 @@ pub struct LayoutContext<'a> { titlebar_height: f32, hovered_region_ids: HashSet, clicked_region_id: Option, + right_clicked_region_id: Option, } impl<'a> LayoutContext<'a> { @@ -418,6 +460,7 @@ impl<'a> LayoutContext<'a> { titlebar_height: self.titlebar_height, hovered_region_ids: self.hovered_region_ids.clone(), clicked_region_id: self.clicked_region_id, + right_clicked_region_id: self.right_clicked_region_id, refreshing: self.refreshing, }; f(view, &mut render_cx) diff --git a/crates/gpui/src/scene.rs b/crates/gpui/src/scene.rs index caeae3c89f..843a3b62d6 100644 --- a/crates/gpui/src/scene.rs +++ b/crates/gpui/src/scene.rs @@ -52,6 +52,8 @@ pub struct MouseRegion { pub hover: Option>, pub mouse_down: Option>, pub click: Option>, + pub right_mouse_down: Option>, + pub right_click: Option>, pub drag: Option>, }