diff --git a/crates/activity_indicator/src/activity_indicator.rs b/crates/activity_indicator/src/activity_indicator.rs index 8bc84f911c..8de3ceda3c 100644 --- a/crates/activity_indicator/src/activity_indicator.rs +++ b/crates/activity_indicator/src/activity_indicator.rs @@ -3,7 +3,7 @@ use editor::Editor; use futures::StreamExt; use gpui::{ actions, elements::*, platform::CursorStyle, Action, AppContext, Entity, ModelHandle, - MutableAppContext, RenderContext, View, ViewContext, ViewHandle, + MouseButton, MutableAppContext, RenderContext, View, ViewContext, ViewHandle, }; use language::{LanguageRegistry, LanguageServerBinaryStatus}; use project::{LanguageServerProgress, Project}; @@ -317,7 +317,9 @@ impl View for ActivityIndicator { if let Some(action) = action { element = element .with_cursor_style(CursorStyle::PointingHand) - .on_click(move |_, _, cx| cx.dispatch_any_action(action.boxed_clone())); + .on_click(MouseButton::Left, move |_, cx| { + cx.dispatch_any_action(action.boxed_clone()) + }); } element.boxed() diff --git a/crates/auto_update/src/update_notification.rs b/crates/auto_update/src/update_notification.rs index e9c73ef4bc..7863fe900d 100644 --- a/crates/auto_update/src/update_notification.rs +++ b/crates/auto_update/src/update_notification.rs @@ -2,7 +2,7 @@ use crate::ViewReleaseNotes; use gpui::{ elements::{Flex, MouseEventHandler, Padding, ParentElement, Svg, Text}, platform::{AppVersion, CursorStyle}, - Element, Entity, View, ViewContext, + Element, Entity, MouseButton, View, ViewContext, }; use menu::Cancel; use settings::Settings; @@ -62,7 +62,7 @@ impl View for UpdateNotification { .boxed() }) .with_padding(Padding::uniform(5.)) - .on_click(move |_, _, cx| cx.dispatch_action(Cancel)) + .on_click(MouseButton::Left, move |_, cx| cx.dispatch_action(Cancel)) .aligned() .constrained() .with_height(cx.font_cache().line_height(theme.message.text.font_size)) @@ -84,7 +84,9 @@ impl View for UpdateNotification { .boxed() }) .with_cursor_style(CursorStyle::PointingHand) - .on_click(|_, _, cx| cx.dispatch_action(ViewReleaseNotes)) + .on_click(MouseButton::Left, |_, cx| { + cx.dispatch_action(ViewReleaseNotes) + }) .boxed() } } diff --git a/crates/chat_panel/src/chat_panel.rs b/crates/chat_panel/src/chat_panel.rs index a8db280bf8..fa913971df 100644 --- a/crates/chat_panel/src/chat_panel.rs +++ b/crates/chat_panel/src/chat_panel.rs @@ -8,8 +8,8 @@ use gpui::{ elements::*, platform::CursorStyle, views::{ItemType, Select, SelectStyle}, - AppContext, Entity, ModelHandle, MutableAppContext, RenderContext, Subscription, Task, View, - ViewContext, ViewHandle, + AppContext, Entity, ModelHandle, MouseButton, MutableAppContext, RenderContext, Subscription, + Task, View, ViewContext, ViewHandle, }; use menu::Confirm; use postage::prelude::Stream; @@ -320,7 +320,7 @@ impl ChatPanel { .boxed() }) .with_cursor_style(CursorStyle::PointingHand) - .on_click(move |_, _, cx| { + .on_click(MouseButton::Left, move |_, cx| { let rpc = rpc.clone(); let this = this.clone(); cx.spawn(|mut cx| async move { diff --git a/crates/contacts_panel/src/contacts_panel.rs b/crates/contacts_panel/src/contacts_panel.rs index f4010a1278..9fc8f5f22d 100644 --- a/crates/contacts_panel/src/contacts_panel.rs +++ b/crates/contacts_panel/src/contacts_panel.rs @@ -13,8 +13,9 @@ use gpui::{ geometry::{rect::RectF, vector::vec2f}, impl_actions, impl_internal_actions, platform::CursorStyle, - AppContext, ClipboardItem, Element, ElementBox, Entity, ModelHandle, MutableAppContext, - RenderContext, Subscription, View, ViewContext, ViewHandle, WeakModelHandle, WeakViewHandle, + AppContext, ClipboardItem, Element, ElementBox, Entity, ModelHandle, MouseButton, + MutableAppContext, RenderContext, Subscription, View, ViewContext, ViewHandle, WeakModelHandle, + WeakViewHandle, }; use join_project_notification::JoinProjectNotification; use menu::{Confirm, SelectNext, SelectPrev}; @@ -310,7 +311,9 @@ impl ContactsPanel { .boxed() }) .with_cursor_style(CursorStyle::PointingHand) - .on_click(move |_, _, cx| cx.dispatch_action(ToggleExpanded(section))) + .on_click(MouseButton::Left, move |_, cx| { + cx.dispatch_action(ToggleExpanded(section)) + }) .boxed() } @@ -445,7 +448,7 @@ impl ContactsPanel { Some( button .with_cursor_style(CursorStyle::PointingHand) - .on_click(move |_, _, cx| { + .on_click(MouseButton::Left, move |_, cx| { cx.dispatch_action(ToggleProjectOnline { project: Some(open_project.clone()), }) @@ -499,7 +502,7 @@ impl ContactsPanel { } else { CursorStyle::Arrow }) - .on_click(move |_, _, cx| { + .on_click(MouseButton::Left, move |_, cx| { if !is_host { cx.dispatch_global_action(JoinProject { contact: contact.clone(), @@ -563,7 +566,7 @@ impl ContactsPanel { } else { button .with_cursor_style(CursorStyle::PointingHand) - .on_click(move |_, _, cx| { + .on_click(MouseButton::Left, move |_, cx| { let project = project_handle.upgrade(cx.deref_mut()); cx.dispatch_action(ToggleProjectOnline { project }) }) @@ -646,7 +649,7 @@ impl ContactsPanel { .boxed() }) .with_cursor_style(CursorStyle::PointingHand) - .on_click(move |_, _, cx| { + .on_click(MouseButton::Left, move |_, cx| { cx.dispatch_action(RespondToContactRequest { user_id, accept: false, @@ -668,7 +671,7 @@ impl ContactsPanel { .boxed() }) .with_cursor_style(CursorStyle::PointingHand) - .on_click(move |_, _, cx| { + .on_click(MouseButton::Left, move |_, cx| { cx.dispatch_action(RespondToContactRequest { user_id, accept: true, @@ -691,7 +694,9 @@ impl ContactsPanel { }) .with_padding(Padding::uniform(2.)) .with_cursor_style(CursorStyle::PointingHand) - .on_click(move |_, _, cx| cx.dispatch_action(RemoveContact(user_id))) + .on_click(MouseButton::Left, move |_, cx| { + cx.dispatch_action(RemoveContact(user_id)) + }) .flex_float() .boxed(), ); @@ -1078,7 +1083,9 @@ impl View for ContactsPanel { .boxed() }) .with_cursor_style(CursorStyle::PointingHand) - .on_click(|_, _, cx| cx.dispatch_action(contact_finder::Toggle)) + .on_click(MouseButton::Left, |_, cx| { + cx.dispatch_action(contact_finder::Toggle) + }) .boxed(), ) .constrained() @@ -1126,7 +1133,7 @@ impl View for ContactsPanel { }, ) .with_cursor_style(CursorStyle::PointingHand) - .on_click(move |_, _, cx| { + .on_click(MouseButton::Left, move |_, cx| { cx.write_to_clipboard(ClipboardItem::new( info.url.to_string(), )); diff --git a/crates/contacts_panel/src/notifications.rs b/crates/contacts_panel/src/notifications.rs index c02fd73b8f..a80dafdd22 100644 --- a/crates/contacts_panel/src/notifications.rs +++ b/crates/contacts_panel/src/notifications.rs @@ -3,7 +3,7 @@ use client::User; use gpui::{ elements::{Flex, Image, Label, MouseEventHandler, Padding, ParentElement, Text}, platform::CursorStyle, - Action, Element, ElementBox, RenderContext, View, + Action, Element, ElementBox, MouseButton, RenderContext, View, }; use settings::Settings; use std::sync::Arc; @@ -61,7 +61,9 @@ pub fn render_user_notification( }) .with_cursor_style(CursorStyle::PointingHand) .with_padding(Padding::uniform(5.)) - .on_click(move |_, _, cx| cx.dispatch_any_action(dismiss_action.boxed_clone())) + .on_click(MouseButton::Left, move |_, cx| { + cx.dispatch_any_action(dismiss_action.boxed_clone()) + }) .aligned() .constrained() .with_height( @@ -96,7 +98,9 @@ pub fn render_user_notification( .boxed() }) .with_cursor_style(CursorStyle::PointingHand) - .on_click(move |_, _, cx| cx.dispatch_any_action(action.boxed_clone())) + .on_click(MouseButton::Left, move |_, cx| { + cx.dispatch_any_action(action.boxed_clone()) + }) .boxed() }, )) diff --git a/crates/context_menu/src/context_menu.rs b/crates/context_menu/src/context_menu.rs index 39477bc927..7bfe3bb2e8 100644 --- a/crates/context_menu/src/context_menu.rs +++ b/crates/context_menu/src/context_menu.rs @@ -1,7 +1,7 @@ use gpui::{ elements::*, geometry::vector::Vector2F, impl_internal_actions, keymap, platform::CursorStyle, - Action, AppContext, Axis, Entity, MutableAppContext, RenderContext, SizeConstraint, - Subscription, View, ViewContext, + Action, AppContext, Axis, Entity, MouseButton, MutableAppContext, RenderContext, + SizeConstraint, Subscription, View, ViewContext, }; use menu::*; use settings::Settings; @@ -337,7 +337,7 @@ impl ContextMenu { .boxed() }) .with_cursor_style(CursorStyle::PointingHand) - .on_click(move |_, _, cx| { + .on_click(MouseButton::Left, move |_, cx| { cx.dispatch_action(Clicked); cx.dispatch_any_action(action.boxed_clone()); }) @@ -355,7 +355,7 @@ impl ContextMenu { .with_style(style.container) .boxed() }) - .on_mouse_down_out(|_, cx| cx.dispatch_action(Cancel)) - .on_right_mouse_down_out(|_, cx| cx.dispatch_action(Cancel)) + .on_mouse_down_out(MouseButton::Left, |_, cx| cx.dispatch_action(Cancel)) + .on_mouse_down_out(MouseButton::Right, |_, cx| cx.dispatch_action(Cancel)) } } diff --git a/crates/diagnostics/src/items.rs b/crates/diagnostics/src/items.rs index e2961ff3bd..b7c4b2a22d 100644 --- a/crates/diagnostics/src/items.rs +++ b/crates/diagnostics/src/items.rs @@ -1,8 +1,8 @@ use collections::HashSet; use editor::{Editor, GoToNextDiagnostic}; use gpui::{ - elements::*, platform::CursorStyle, serde_json, Entity, ModelHandle, MutableAppContext, - RenderContext, Subscription, View, ViewContext, ViewHandle, WeakViewHandle, + elements::*, platform::CursorStyle, serde_json, Entity, ModelHandle, MouseButton, + MutableAppContext, RenderContext, Subscription, View, ViewContext, ViewHandle, WeakViewHandle, }; use language::Diagnostic; use project::Project; @@ -161,7 +161,7 @@ impl View for DiagnosticIndicator { .boxed() }) .with_cursor_style(CursorStyle::PointingHand) - .on_click(|_, _, cx| cx.dispatch_action(crate::Deploy)) + .on_click(MouseButton::Left, |_, cx| cx.dispatch_action(crate::Deploy)) .with_tooltip::( 0, "Project Diagnostics".to_string(), @@ -201,7 +201,9 @@ impl View for DiagnosticIndicator { .boxed() }) .with_cursor_style(CursorStyle::PointingHand) - .on_click(|_, _, cx| cx.dispatch_action(GoToNextDiagnostic)) + .on_click(MouseButton::Left, |_, cx| { + cx.dispatch_action(GoToNextDiagnostic) + }) .boxed(), ); } diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 72ba6d60af..321c94e2bd 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -30,8 +30,8 @@ use gpui::{ impl_actions, impl_internal_actions, platform::CursorStyle, text_layout, AppContext, AsyncAppContext, ClipboardItem, Element, ElementBox, Entity, - ModelHandle, MutableAppContext, RenderContext, Subscription, Task, View, ViewContext, - ViewHandle, WeakViewHandle, + ModelHandle, MouseButton, MutableAppContext, RenderContext, Subscription, Task, View, + ViewContext, ViewHandle, WeakViewHandle, }; use highlight_matching_bracket::refresh_matching_bracket_highlights; use hover_popover::{hide_hover, HoverState}; @@ -707,7 +707,7 @@ impl CompletionsMenu { }, ) .with_cursor_style(CursorStyle::PointingHand) - .on_mouse_down(move |_, cx| { + .on_mouse_down(MouseButton::Left, move |_, cx| { cx.dispatch_action(ConfirmCompletion { item_ix: Some(item_ix), }); @@ -840,7 +840,7 @@ impl CodeActionsMenu { .boxed() }) .with_cursor_style(CursorStyle::PointingHand) - .on_mouse_down(move |_, cx| { + .on_mouse_down(MouseButton::Left, move |_, cx| { cx.dispatch_action(ConfirmCodeAction { item_ix: Some(item_ix), }); @@ -2674,7 +2674,7 @@ impl Editor { }) .with_cursor_style(CursorStyle::PointingHand) .with_padding(Padding::uniform(3.)) - .on_mouse_down(|_, cx| { + .on_mouse_down(MouseButton::Left, |_, cx| { cx.dispatch_action(ToggleCodeActions { deployed_from_indicator: true, }); diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index 99d60ed9a2..013de1e7df 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -25,7 +25,7 @@ use gpui::{ platform::CursorStyle, text_layout::{self, Line, RunStyle, TextLayoutCache}, AppContext, Axis, Border, CursorRegion, Element, ElementBox, Event, EventContext, KeyDownEvent, - LayoutContext, ModifiersChangedEvent, MouseButton, MouseEvent, MouseMovedEvent, + LayoutContext, ModifiersChangedEvent, MouseButton, MouseButtonEvent, MouseMovedEvent, MutableAppContext, PaintContext, Quad, Scene, ScrollWheelEvent, SizeConstraint, ViewContext, WeakViewHandle, }; @@ -968,7 +968,9 @@ impl EditorElement { .boxed() }) .with_cursor_style(CursorStyle::PointingHand) - .on_click(move |_, _, cx| cx.dispatch_action(jump_action.clone())) + .on_click(MouseButton::Left, move |_, cx| { + cx.dispatch_action(jump_action.clone()) + }) .with_tooltip::( *key, "Jump to Buffer".to_string(), @@ -1483,7 +1485,7 @@ impl Element for EditorElement { } match event { - Event::MouseDown(MouseEvent { + Event::MouseDown(MouseButtonEvent { button: MouseButton::Left, position, cmd, @@ -1501,12 +1503,12 @@ impl Element for EditorElement { paint, cx, ), - Event::MouseDown(MouseEvent { + Event::MouseDown(MouseButtonEvent { button: MouseButton::Right, position, .. }) => self.mouse_right_down(*position, layout, paint, cx), - Event::MouseUp(MouseEvent { + Event::MouseUp(MouseButtonEvent { button: MouseButton::Left, position, .. diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index 075339bba1..2cd6687bcb 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -5401,7 +5401,7 @@ impl RefCounts { #[cfg(test)] mod tests { use super::*; - use crate::{actions, elements::*, impl_actions, MouseButton, MouseEvent}; + use crate::{actions, elements::*, impl_actions, MouseButton, MouseButtonEvent}; use serde::Deserialize; use smol::future::poll_once; use std::{ @@ -5754,7 +5754,7 @@ mod tests { let presenter = cx.presenters_and_platform_windows[&window_id].0.clone(); // Ensure window's root element is in a valid lifecycle state. presenter.borrow_mut().dispatch_event( - Event::MouseDown(MouseEvent { + Event::MouseDown(MouseButtonEvent { position: Default::default(), button: MouseButton::Left, ctrl: false, diff --git a/crates/gpui/src/elements/event_handler.rs b/crates/gpui/src/elements/event_handler.rs index 1fec838788..55e4928ad8 100644 --- a/crates/gpui/src/elements/event_handler.rs +++ b/crates/gpui/src/elements/event_handler.rs @@ -1,11 +1,11 @@ use crate::{ geometry::vector::Vector2F, CursorRegion, DebugContext, Element, ElementBox, Event, - EventContext, LayoutContext, MouseButton, MouseEvent, MouseRegion, NavigationDirection, + EventContext, LayoutContext, MouseButton, MouseButtonEvent, MouseRegion, NavigationDirection, PaintContext, SizeConstraint, }; use pathfinder_geometry::rect::RectF; use serde_json::json; -use std::{any::TypeId, rc::Rc}; +use std::any::TypeId; pub struct EventHandler { child: ElementBox, @@ -82,19 +82,11 @@ impl Element for EventHandler { bounds: visible_bounds, style: Default::default(), }); - cx.scene.push_mouse_region(MouseRegion { - view_id: cx.current_view_id(), - discriminant: Some(discriminant), - bounds: visible_bounds, - hover: Some(Rc::new(|_, _, _| {})), - mouse_down: Some(Rc::new(|_, _| {})), - click: Some(Rc::new(|_, _, _| {})), - right_mouse_down: Some(Rc::new(|_, _| {})), - right_click: Some(Rc::new(|_, _, _| {})), - drag: Some(Rc::new(|_, _, _| {})), - mouse_down_out: Some(Rc::new(|_, _| {})), - right_mouse_down_out: Some(Rc::new(|_, _| {})), - }); + cx.scene.push_mouse_region(MouseRegion::handle_all( + cx.current_view_id(), + Some(discriminant), + visible_bounds, + )); cx.scene.pop_stacking_context(); } self.child.paint(bounds.origin(), visible_bounds, cx); @@ -117,7 +109,7 @@ impl Element for EventHandler { true } else { match event { - Event::MouseDown(MouseEvent { + Event::MouseDown(MouseButtonEvent { button: MouseButton::Left, position, .. @@ -129,7 +121,7 @@ impl Element for EventHandler { } false } - Event::MouseDown(MouseEvent { + Event::MouseDown(MouseButtonEvent { button: MouseButton::Right, position, .. @@ -141,7 +133,7 @@ impl Element for EventHandler { } false } - Event::MouseDown(MouseEvent { + Event::MouseDown(MouseButtonEvent { button: MouseButton::Navigate(direction), position, .. diff --git a/crates/gpui/src/elements/mouse_event_handler.rs b/crates/gpui/src/elements/mouse_event_handler.rs index 832aafaa9e..3a8a5f6d63 100644 --- a/crates/gpui/src/elements/mouse_event_handler.rs +++ b/crates/gpui/src/elements/mouse_event_handler.rs @@ -1,4 +1,4 @@ -use std::{any::TypeId, rc::Rc}; +use std::any::TypeId; use super::Padding; use crate::{ @@ -8,24 +8,16 @@ use crate::{ }, platform::CursorStyle, scene::CursorRegion, - DebugContext, Element, ElementBox, Event, EventContext, LayoutContext, MouseRegion, MouseState, - PaintContext, RenderContext, SizeConstraint, View, + DebugContext, Element, ElementBox, Event, EventContext, LayoutContext, MouseButton, + MouseButtonEvent, MouseMovedEvent, MouseRegion, MouseState, PaintContext, RenderContext, + SizeConstraint, View, }; use serde_json::json; pub struct MouseEventHandler { child: ElementBox, - tag: TypeId, - id: usize, cursor_style: Option, - mouse_down: Option>, - click: Option>, - right_mouse_down: Option>, - right_click: Option>, - mouse_down_out: Option>, - right_mouse_down_out: Option>, - drag: Option>, - hover: Option>, + region: MouseRegion, padding: Padding, } @@ -37,18 +29,9 @@ impl MouseEventHandler { F: FnOnce(MouseState, &mut RenderContext) -> ElementBox, { Self { - id, - tag: TypeId::of::(), child: render_child(cx.mouse_state::(id), cx), cursor_style: None, - mouse_down: None, - click: None, - right_mouse_down: None, - right_click: None, - mouse_down_out: None, - right_mouse_down_out: None, - drag: None, - hover: None, + region: MouseRegion::new(0, Some((TypeId::of::(), id)), Default::default()), padding: Default::default(), } } @@ -60,65 +43,45 @@ impl MouseEventHandler { pub fn on_mouse_down( mut self, - handler: impl Fn(Vector2F, &mut EventContext) + 'static, + button: MouseButton, + handler: impl Fn(MouseButtonEvent, &mut EventContext) + 'static, ) -> Self { - self.mouse_down = Some(Rc::new(handler)); + self.region = self.region.on_down(button, handler); self } pub fn on_click( mut self, - handler: impl Fn(Vector2F, usize, &mut EventContext) + 'static, + button: MouseButton, + handler: impl Fn(MouseButtonEvent, &mut EventContext) + 'static, ) -> Self { - self.click = Some(Rc::new(handler)); - self - } - - pub fn on_right_mouse_down( - mut self, - handler: impl Fn(Vector2F, &mut EventContext) + 'static, - ) -> Self { - self.right_mouse_down = Some(Rc::new(handler)); - self - } - - pub fn on_right_click( - mut self, - handler: impl Fn(Vector2F, usize, &mut EventContext) + 'static, - ) -> Self { - self.right_click = Some(Rc::new(handler)); + self.region = self.region.on_click(button, handler); self } pub fn on_mouse_down_out( mut self, - handler: impl Fn(Vector2F, &mut EventContext) + 'static, + button: MouseButton, + handler: impl Fn(MouseButtonEvent, &mut EventContext) + 'static, ) -> Self { - self.mouse_down_out = Some(Rc::new(handler)); - self - } - - pub fn on_right_mouse_down_out( - mut self, - handler: impl Fn(Vector2F, &mut EventContext) + 'static, - ) -> Self { - self.right_mouse_down_out = Some(Rc::new(handler)); + self.region = self.region.on_down_out(button, handler); self } pub fn on_drag( mut self, - handler: impl Fn(Vector2F, Vector2F, &mut EventContext) + 'static, + button: MouseButton, + handler: impl Fn(Vector2F, MouseMovedEvent, &mut EventContext) + 'static, ) -> Self { - self.drag = Some(Rc::new(handler)); + self.region = self.region.on_drag(button, handler); self } pub fn on_hover( mut self, - handler: impl Fn(Vector2F, bool, &mut EventContext) + 'static, + handler: impl Fn(bool, MouseMovedEvent, &mut EventContext) + 'static, ) -> Self { - self.hover = Some(Rc::new(handler)); + self.region = self.region.on_hover(handler); self } @@ -163,19 +126,9 @@ impl Element for MouseEventHandler { }); } - cx.scene.push_mouse_region(MouseRegion { - view_id: cx.current_view_id(), - discriminant: Some((self.tag, self.id)), - bounds: hit_bounds, - hover: self.hover.clone(), - click: self.click.clone(), - mouse_down: self.mouse_down.clone(), - right_click: self.right_click.clone(), - right_mouse_down: self.right_mouse_down.clone(), - mouse_down_out: self.mouse_down_out.clone(), - right_mouse_down_out: self.right_mouse_down_out.clone(), - drag: self.drag.clone(), - }); + self.region.view_id = cx.current_view_id(); + self.region.bounds = hit_bounds; + cx.scene.push_mouse_region(self.region.clone()); self.child.paint(bounds.origin(), visible_bounds, cx); } diff --git a/crates/gpui/src/elements/tooltip.rs b/crates/gpui/src/elements/tooltip.rs index 9a65b2661d..572d142521 100644 --- a/crates/gpui/src/elements/tooltip.rs +++ b/crates/gpui/src/elements/tooltip.rs @@ -6,8 +6,8 @@ use crate::{ fonts::TextStyle, geometry::{rect::RectF, vector::Vector2F}, json::json, - Action, Axis, ElementStateHandle, LayoutContext, PaintContext, RenderContext, SizeConstraint, - Task, View, + Action, Axis, ElementStateHandle, LayoutContext, MouseMovedEvent, PaintContext, RenderContext, + SizeConstraint, Task, View, }; use serde::Deserialize; use std::{ @@ -91,7 +91,7 @@ impl Tooltip { }; let child = MouseEventHandler::new::, _, _>(id, cx, |_, _| child) - .on_hover(move |position, hover, cx| { + .on_hover(move |hover, MouseMovedEvent { position, .. }, cx| { let window_id = cx.window_id(); if let Some(view_id) = cx.view_id() { if hover { diff --git a/crates/gpui/src/platform/event.rs b/crates/gpui/src/platform/event.rs index 90b5d21fc2..57e945175b 100644 --- a/crates/gpui/src/platform/event.rs +++ b/crates/gpui/src/platform/event.rs @@ -21,20 +21,26 @@ pub struct ModifiersChangedEvent { pub cmd: bool, } -#[derive(Clone, Debug)] +#[derive(Clone, Debug, Default)] pub struct ScrollWheelEvent { pub position: Vector2F, pub delta: Vector2F, pub precise: bool, } -#[derive(Copy, Clone, Debug)] +#[derive(Hash, PartialEq, Eq, Copy, Clone, Debug)] pub enum NavigationDirection { Back, Forward, } -#[derive(Copy, Clone, Debug)] +impl Default for NavigationDirection { + fn default() -> Self { + Self::Back + } +} + +#[derive(Hash, PartialEq, Eq, Copy, Clone, Debug)] pub enum MouseButton { Left, Right, @@ -42,8 +48,26 @@ pub enum MouseButton { Navigate(NavigationDirection), } -#[derive(Clone, Debug)] -pub struct MouseEvent { +impl MouseButton { + pub fn all() -> Vec { + vec![ + MouseButton::Left, + MouseButton::Right, + MouseButton::Middle, + MouseButton::Navigate(NavigationDirection::Back), + MouseButton::Navigate(NavigationDirection::Forward), + ] + } +} + +impl Default for MouseButton { + fn default() -> Self { + Self::Left + } +} + +#[derive(Clone, Debug, Default)] +pub struct MouseButtonEvent { pub button: MouseButton, pub position: Vector2F, pub ctrl: bool, @@ -53,7 +77,7 @@ pub struct MouseEvent { pub click_count: usize, } -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Copy, Debug, Default)] pub struct MouseMovedEvent { pub position: Vector2F, pub pressed_button: Option, @@ -68,8 +92,8 @@ pub enum Event { KeyDown(KeyDownEvent), KeyUp(KeyUpEvent), ModifiersChanged(ModifiersChangedEvent), - MouseDown(MouseEvent), - MouseUp(MouseEvent), + MouseDown(MouseButtonEvent), + MouseUp(MouseButtonEvent), MouseMoved(MouseMovedEvent), ScrollWheel(ScrollWheelEvent), } diff --git a/crates/gpui/src/platform/mac/event.rs b/crates/gpui/src/platform/mac/event.rs index 5e23859675..209d8de766 100644 --- a/crates/gpui/src/platform/mac/event.rs +++ b/crates/gpui/src/platform/mac/event.rs @@ -2,8 +2,8 @@ use crate::{ geometry::vector::vec2f, keymap::Keystroke, platform::{Event, NavigationDirection}, - KeyDownEvent, KeyUpEvent, ModifiersChangedEvent, MouseButton, MouseEvent, MouseMovedEvent, - ScrollWheelEvent, + KeyDownEvent, KeyUpEvent, ModifiersChangedEvent, MouseButton, MouseButtonEvent, + MouseMovedEvent, ScrollWheelEvent, }; use cocoa::{ appkit::{NSEvent, NSEventModifierFlags, NSEventType}, @@ -126,7 +126,7 @@ impl Event { let modifiers = native_event.modifierFlags(); window_height.map(|window_height| { - Self::MouseDown(MouseEvent { + Self::MouseDown(MouseButtonEvent { button, position: vec2f( native_event.locationInWindow().x as f32, @@ -155,7 +155,7 @@ impl Event { window_height.map(|window_height| { let modifiers = native_event.modifierFlags(); - Self::MouseUp(MouseEvent { + Self::MouseUp(MouseButtonEvent { button, position: vec2f( native_event.locationInWindow().x as f32, diff --git a/crates/gpui/src/platform/mac/window.rs b/crates/gpui/src/platform/mac/window.rs index 43ce09ffff..2680d9aa46 100644 --- a/crates/gpui/src/platform/mac/window.rs +++ b/crates/gpui/src/platform/mac/window.rs @@ -6,7 +6,7 @@ use crate::{ }, keymap::Keystroke, platform::{self, Event, WindowBounds, WindowContext}, - KeyDownEvent, ModifiersChangedEvent, MouseButton, MouseEvent, MouseMovedEvent, Scene, + KeyDownEvent, ModifiersChangedEvent, MouseButton, MouseButtonEvent, MouseMovedEvent, Scene, }; use block::ConcreteBlock; use cocoa::{ @@ -635,7 +635,7 @@ extern "C" fn handle_view_event(this: &Object, _: Sel, native_event: id) { )) .detach(); } - Event::MouseUp(MouseEvent { + Event::MouseUp(MouseButtonEvent { button: MouseButton::Left, .. }) => { diff --git a/crates/gpui/src/presenter.rs b/crates/gpui/src/presenter.rs index 86a8c4cf30..243863149d 100644 --- a/crates/gpui/src/presenter.rs +++ b/crates/gpui/src/presenter.rs @@ -6,10 +6,10 @@ use crate::{ json::{self, ToJson}, keymap::Keystroke, platform::{CursorStyle, Event}, - scene::CursorRegion, + scene::{CursorRegion, MouseRegionEvent}, text_layout::TextLayoutCache, Action, AnyModelHandle, AnyViewHandle, AnyWeakModelHandle, AssetCache, ElementBox, Entity, - FontSystem, ModelHandle, MouseButton, MouseEvent, MouseMovedEvent, MouseRegion, MouseRegionId, + FontSystem, ModelHandle, MouseButtonEvent, MouseMovedEvent, MouseRegion, MouseRegionId, ReadModel, ReadView, RenderContext, RenderParams, Scene, UpgradeModelHandle, UpgradeViewHandle, View, ViewHandle, WeakModelHandle, WeakViewHandle, }; @@ -230,105 +230,58 @@ impl Presenter { let mut mouse_down_out_handlers = Vec::new(); let mut mouse_down_region = None; let mut clicked_region = None; - let mut right_mouse_down_region = None; - let mut right_clicked_region = None; let mut dragged_region = None; - match event { - Event::MouseDown(MouseEvent { - position, - button: MouseButton::Left, - .. - }) => { + match &event { + Event::MouseDown( + e @ MouseButtonEvent { + position, button, .. + }, + ) => { let mut hit = false; for (region, _) in self.mouse_regions.iter().rev() { - if region.bounds.contains_point(position) { + if region.bounds.contains_point(*position) { if !hit { hit = true; invalidated_views.push(region.view_id); - mouse_down_region = Some((region.clone(), position)); + mouse_down_region = + Some((region.clone(), MouseRegionEvent::Down(e.clone()))); self.clicked_region = Some(region.clone()); - self.prev_drag_position = Some(position); + self.prev_drag_position = Some(*position); } - } else if let Some(handler) = region.mouse_down_out.clone() { - mouse_down_out_handlers.push((handler, region.view_id, position)); + } else if let Some(handler) = region + .handlers + .get(&(MouseRegionEvent::down_out_disc(), Some(*button))) + .cloned() + { + mouse_down_out_handlers.push(( + handler, + region.view_id, + MouseRegionEvent::DownOut(e.clone()), + )); } } } - Event::MouseUp(MouseEvent { - position, - click_count, - button: MouseButton::Left, - .. - }) => { + Event::MouseUp(e @ MouseButtonEvent { position, .. }) => { self.prev_drag_position.take(); if let Some(region) = self.clicked_region.take() { invalidated_views.push(region.view_id); - if region.bounds.contains_point(position) { - clicked_region = Some((region, position, click_count)); + if region.bounds.contains_point(*position) { + clicked_region = Some((region, MouseRegionEvent::Click(e.clone()))); } } } - Event::MouseDown(MouseEvent { - position, - button: MouseButton::Right, - .. - }) => { - let mut hit = false; - for (region, _) in self.mouse_regions.iter().rev() { - if region.bounds.contains_point(position) { - if !hit { - hit = true; - invalidated_views.push(region.view_id); - right_mouse_down_region = Some((region.clone(), position)); - self.right_clicked_region = Some(region.clone()); - } - } else if let Some(handler) = region.right_mouse_down_out.clone() { - mouse_down_out_handlers.push((handler, region.view_id, position)); - } - } - } - Event::MouseUp(MouseEvent { - position, - click_count, - button: MouseButton::Right, - .. - }) => { - 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(MouseMovedEvent { - pressed_button, - position, - shift, - ctrl, - alt, - cmd, - .. - }) => { - if let Some(MouseButton::Left) = pressed_button { - if let Some((clicked_region, prev_drag_position)) = self - .clicked_region - .as_ref() - .zip(self.prev_drag_position.as_mut()) - { - dragged_region = - Some((clicked_region.clone(), *prev_drag_position, position)); - *prev_drag_position = position; - } - - self.last_mouse_moved_event = Some(Event::MouseMoved(MouseMovedEvent { - position, - pressed_button: Some(MouseButton::Left), - shift, - ctrl, - alt, - cmd, - })); + Event::MouseMoved(e @ MouseMovedEvent { position, .. }) => { + if let Some((clicked_region, prev_drag_position)) = self + .clicked_region + .as_ref() + .zip(self.prev_drag_position.as_mut()) + { + dragged_region = Some(( + clicked_region.clone(), + MouseRegionEvent::Drag(*prev_drag_position, e.clone()), + )); + *prev_drag_position = *position; } self.last_mouse_moved_event = Some(event.clone()); @@ -339,51 +292,39 @@ impl Presenter { let (mut handled, mut event_cx) = self.handle_hover_events(&event, &mut invalidated_views, cx); - for (handler, view_id, position) in mouse_down_out_handlers { - event_cx.with_current_view(view_id, |event_cx| handler(position, event_cx)) + for (handler, view_id, region_event) in mouse_down_out_handlers { + event_cx.with_current_view(view_id, |event_cx| handler(region_event, event_cx)) } - if let Some((mouse_down_region, position)) = mouse_down_region { + if let Some((mouse_down_region, region_event)) = mouse_down_region { handled = true; - if let Some(mouse_down_callback) = mouse_down_region.mouse_down { + if let Some(mouse_down_callback) = + mouse_down_region.handlers.get(®ion_event.handler_key()) + { event_cx.with_current_view(mouse_down_region.view_id, |event_cx| { - mouse_down_callback(position, event_cx); + mouse_down_callback(region_event, event_cx); }) } } - if let Some((clicked_region, position, click_count)) = clicked_region { + if let Some((clicked_region, region_event)) = clicked_region { handled = true; - if let Some(click_callback) = clicked_region.click { + if let Some(click_callback) = + clicked_region.handlers.get(®ion_event.handler_key()) + { event_cx.with_current_view(clicked_region.view_id, |event_cx| { - click_callback(position, click_count, event_cx); + click_callback(region_event, event_cx); }) } } - if let Some((right_mouse_down_region, position)) = right_mouse_down_region { + if let Some((dragged_region, region_event)) = dragged_region { handled = true; - if let Some(right_mouse_down_callback) = right_mouse_down_region.right_mouse_down { - event_cx.with_current_view(right_mouse_down_region.view_id, |event_cx| { - right_mouse_down_callback(position, event_cx); - }) - } - } - - if let Some((right_clicked_region, position, click_count)) = right_clicked_region { - handled = true; - 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, prev_position, position)) = dragged_region { - handled = true; - if let Some(drag_callback) = dragged_region.drag { + if let Some(drag_callback) = + dragged_region.handlers.get(®ion_event.handler_key()) + { event_cx.with_current_view(dragged_region.view_id, |event_cx| { - drag_callback(prev_position, position, event_cx); + drag_callback(region_event, event_cx); }) } } @@ -420,14 +361,17 @@ impl Presenter { invalidated_views: &mut Vec, cx: &'a mut MutableAppContext, ) -> (bool, EventContext<'a>) { - let mut unhovered_regions = Vec::new(); - let mut hovered_regions = Vec::new(); + let mut hover_regions = Vec::new(); + // let mut unhovered_regions = Vec::new(); + // let mut hovered_regions = Vec::new(); - if let Event::MouseMoved(MouseMovedEvent { - position, - pressed_button, - .. - }) = event + if let Event::MouseMoved( + e @ MouseMovedEvent { + position, + pressed_button, + .. + }, + ) = event { if let None = pressed_button { let mut style_to_assign = CursorStyle::Arrow; @@ -448,7 +392,10 @@ impl Presenter { if let Some(region_id) = region.id() { if !self.hovered_region_ids.contains(®ion_id) { invalidated_views.push(region.view_id); - hovered_regions.push((region.clone(), position)); + hover_regions.push(( + region.clone(), + MouseRegionEvent::Hover(true, e.clone()), + )); self.hovered_region_ids.insert(region_id); } } @@ -456,7 +403,10 @@ impl Presenter { if let Some(region_id) = region.id() { if self.hovered_region_ids.contains(®ion_id) { invalidated_views.push(region.view_id); - unhovered_regions.push((region.clone(), position)); + hover_regions.push(( + region.clone(), + MouseRegionEvent::Hover(false, e.clone()), + )); self.hovered_region_ids.remove(®ion_id); } } @@ -468,20 +418,11 @@ impl Presenter { let mut event_cx = self.build_event_context(cx); let mut handled = false; - for (unhovered_region, position) in unhovered_regions { + for (hover_region, region_event) in hover_regions { handled = true; - if let Some(hover_callback) = unhovered_region.hover { - event_cx.with_current_view(unhovered_region.view_id, |event_cx| { - hover_callback(*position, false, event_cx); - }) - } - } - - for (hovered_region, position) in hovered_regions { - handled = true; - if let Some(hover_callback) = hovered_region.hover { - event_cx.with_current_view(hovered_region.view_id, |event_cx| { - hover_callback(*position, true, event_cx); + if let Some(hover_callback) = hover_region.handlers.get(®ion_event.handler_key()) { + event_cx.with_current_view(hover_region.view_id, |event_cx| { + hover_callback(region_event, event_cx); }) } } diff --git a/crates/gpui/src/scene.rs b/crates/gpui/src/scene.rs index 769eabe7e5..f5577c5e5d 100644 --- a/crates/gpui/src/scene.rs +++ b/crates/gpui/src/scene.rs @@ -1,6 +1,7 @@ +use collections::HashMap; use serde::Deserialize; use serde_json::json; -use std::{any::TypeId, borrow::Cow, rc::Rc, sync::Arc}; +use std::{any::TypeId, borrow::Cow, mem::Discriminant, rc::Rc, sync::Arc}; use crate::{ color::Color, @@ -8,7 +9,7 @@ use crate::{ geometry::{rect::RectF, vector::Vector2F}, json::ToJson, platform::CursorStyle, - EventContext, ImageData, MouseEvent, MouseMovedEvent, ScrollWheelEvent, + EventContext, ImageData, MouseButton, MouseButtonEvent, MouseMovedEvent, ScrollWheelEvent, }; pub struct Scene { @@ -44,30 +45,247 @@ pub struct CursorRegion { pub style: CursorStyle, } +#[derive(Debug)] pub enum MouseRegionEvent { - Moved(MouseMovedEvent), - Hover(MouseEvent), - Down(MouseEvent), - Up(MouseEvent), - Click(MouseEvent), - DownOut(MouseEvent), + Move(MouseMovedEvent), + Drag(Vector2F, MouseMovedEvent), + Hover(bool, MouseMovedEvent), + Down(MouseButtonEvent), + Up(MouseButtonEvent), + Click(MouseButtonEvent), + DownOut(MouseButtonEvent), ScrollWheel(ScrollWheelEvent), } +impl MouseRegionEvent { + pub fn move_disc() -> Discriminant { + std::mem::discriminant(&MouseRegionEvent::Move(Default::default())) + } + pub fn drag_disc() -> Discriminant { + std::mem::discriminant(&MouseRegionEvent::Drag( + Default::default(), + Default::default(), + )) + } + pub fn hover_disc() -> Discriminant { + std::mem::discriminant(&MouseRegionEvent::Hover( + Default::default(), + Default::default(), + )) + } + pub fn down_disc() -> Discriminant { + std::mem::discriminant(&MouseRegionEvent::Down(Default::default())) + } + pub fn up_disc() -> Discriminant { + std::mem::discriminant(&MouseRegionEvent::Up(Default::default())) + } + pub fn click_disc() -> Discriminant { + std::mem::discriminant(&MouseRegionEvent::Click(Default::default())) + } + pub fn down_out_disc() -> Discriminant { + std::mem::discriminant(&MouseRegionEvent::DownOut(Default::default())) + } + pub fn scroll_wheel_disc() -> Discriminant { + std::mem::discriminant(&MouseRegionEvent::ScrollWheel(Default::default())) + } + + pub fn handler_key(&self) -> (Discriminant, Option) { + match self { + MouseRegionEvent::Move(_) => (Self::move_disc(), None), + MouseRegionEvent::Drag(_, MouseMovedEvent { pressed_button, .. }) => { + (Self::drag_disc(), *pressed_button) + } + MouseRegionEvent::Hover(_, _) => (Self::hover_disc(), None), + MouseRegionEvent::Down(MouseButtonEvent { button, .. }) => { + (Self::down_disc(), Some(*button)) + } + MouseRegionEvent::Up(MouseButtonEvent { button, .. }) => { + (Self::up_disc(), Some(*button)) + } + MouseRegionEvent::Click(MouseButtonEvent { button, .. }) => { + (Self::click_disc(), Some(*button)) + } + MouseRegionEvent::DownOut(MouseButtonEvent { button, .. }) => { + (Self::down_out_disc(), Some(*button)) + } + MouseRegionEvent::ScrollWheel(_) => (Self::scroll_wheel_disc(), None), + } + } +} + #[derive(Clone, Default)] pub struct MouseRegion { pub view_id: usize, pub discriminant: Option<(TypeId, usize)>, pub bounds: RectF, + pub handlers: HashMap< + (Discriminant, Option), + Rc, + >, +} - pub hover: Option>, - pub mouse_down: Option>, - pub click: Option>, - pub right_mouse_down: Option>, - pub right_click: Option>, - pub drag: Option>, - pub mouse_down_out: Option>, - pub right_mouse_down_out: Option>, +impl MouseRegion { + pub fn new(view_id: usize, discriminant: Option<(TypeId, usize)>, bounds: RectF) -> Self { + Self { + view_id, + discriminant, + bounds, + handlers: Default::default(), + } + } + + pub fn handle_all( + view_id: usize, + discriminant: Option<(TypeId, usize)>, + bounds: RectF, + ) -> Self { + let mut handlers: HashMap< + (Discriminant, Option), + Rc, + > = Default::default(); + handlers.insert((MouseRegionEvent::move_disc(), None), Rc::new(|_, _| {})); + handlers.insert((MouseRegionEvent::hover_disc(), None), Rc::new(|_, _| {})); + for button in MouseButton::all() { + handlers.insert( + (MouseRegionEvent::drag_disc(), Some(button)), + Rc::new(|_, _| {}), + ); + handlers.insert( + (MouseRegionEvent::down_disc(), Some(button)), + Rc::new(|_, _| {}), + ); + handlers.insert( + (MouseRegionEvent::up_disc(), Some(button)), + Rc::new(|_, _| {}), + ); + handlers.insert( + (MouseRegionEvent::click_disc(), Some(button)), + Rc::new(|_, _| {}), + ); + handlers.insert( + (MouseRegionEvent::down_out_disc(), Some(button)), + Rc::new(|_, _| {}), + ); + } + handlers.insert( + (MouseRegionEvent::scroll_wheel_disc(), None), + Rc::new(|_, _| {}), + ); + + Self { + view_id, + discriminant, + bounds, + handlers, + } + } + + pub fn on_down( + mut self, + button: MouseButton, + handler: impl Fn(MouseButtonEvent, &mut EventContext) + 'static, + ) -> Self { + self.handlers.insert((MouseRegionEvent::down_disc(), Some(button)), + Rc::new(move |region_event, cx| { + if let MouseRegionEvent::Down(mouse_button_event) = region_event { + handler(mouse_button_event, cx); + } else { + panic!( + "Mouse Region Event incorrectly called with mismatched event type. Expected MouseRegionEvent::Down, found {:?}", + region_event); + } + })); + self + } + + pub fn on_up( + mut self, + button: MouseButton, + handler: impl Fn(MouseButtonEvent, &mut EventContext) + 'static, + ) -> Self { + self.handlers.insert((MouseRegionEvent::up_disc(), Some(button)), + Rc::new(move |region_event, cx| { + if let MouseRegionEvent::Up(mouse_button_event) = region_event { + handler(mouse_button_event, cx); + } else { + panic!( + "Mouse Region Event incorrectly called with mismatched event type. Expected MouseRegionEvent::Up, found {:?}", + region_event); + } + })); + self + } + + pub fn on_click( + mut self, + button: MouseButton, + handler: impl Fn(MouseButtonEvent, &mut EventContext) + 'static, + ) -> Self { + self.handlers.insert((MouseRegionEvent::click_disc(), Some(button)), + Rc::new(move |region_event, cx| { + if let MouseRegionEvent::Click(mouse_button_event) = region_event { + handler(mouse_button_event, cx); + } else { + panic!( + "Mouse Region Event incorrectly called with mismatched event type. Expected MouseRegionEvent::Click, found {:?}", + region_event); + } + })); + self + } + + pub fn on_down_out( + mut self, + button: MouseButton, + handler: impl Fn(MouseButtonEvent, &mut EventContext) + 'static, + ) -> Self { + self.handlers.insert((MouseRegionEvent::down_out_disc(), Some(button)), + Rc::new(move |region_event, cx| { + if let MouseRegionEvent::DownOut(mouse_button_event) = region_event { + handler(mouse_button_event, cx); + } else { + panic!( + "Mouse Region Event incorrectly called with mismatched event type. Expected MouseRegionEvent::DownOut, found {:?}", + region_event); + } + })); + self + } + + pub fn on_drag( + mut self, + button: MouseButton, + handler: impl Fn(Vector2F, MouseMovedEvent, &mut EventContext) + 'static, + ) -> Self { + self.handlers.insert((MouseRegionEvent::drag_disc(), Some(button)), + Rc::new(move |region_event, cx| { + if let MouseRegionEvent::Drag(prev_drag_position, mouse_moved_event) = region_event { + handler(prev_drag_position, mouse_moved_event, cx); + } else { + panic!( + "Mouse Region Event incorrectly called with mismatched event type. Expected MouseRegionEvent::Drag, found {:?}", + region_event); + } + })); + self + } + + pub fn on_hover( + mut self, + handler: impl Fn(bool, MouseMovedEvent, &mut EventContext) + 'static, + ) -> Self { + self.handlers.insert((MouseRegionEvent::hover_disc(), None), + Rc::new(move |region_event, cx| { + if let MouseRegionEvent::Hover(hover, mouse_moved_event) = region_event { + handler(hover, mouse_moved_event, cx); + } else { + panic!( + "Mouse Region Event incorrectly called with mismatched event type. Expected MouseRegionEvent::Hover, found {:?}", + region_event); + } + })); + self + } } #[derive(Copy, Clone, Eq, PartialEq, Hash)] diff --git a/crates/gpui/src/views/select.rs b/crates/gpui/src/views/select.rs index 21527a1f2c..1b57caf476 100644 --- a/crates/gpui/src/views/select.rs +++ b/crates/gpui/src/views/select.rs @@ -1,8 +1,8 @@ use serde::Deserialize; use crate::{ - actions, elements::*, impl_actions, AppContext, Entity, MutableAppContext, RenderContext, View, - ViewContext, WeakViewHandle, + actions, elements::*, impl_actions, AppContext, Entity, MouseButton, MutableAppContext, + RenderContext, View, ViewContext, WeakViewHandle, }; pub struct Select { @@ -119,7 +119,9 @@ impl View for Select { .with_style(style.header) .boxed() }) - .on_click(move |_, _, cx| cx.dispatch_action(ToggleSelect)) + .on_click(MouseButton::Left, move |_, cx| { + cx.dispatch_action(ToggleSelect) + }) .boxed(), ); if self.is_open { @@ -151,7 +153,7 @@ impl View for Select { ) }, ) - .on_click(move |_, _, cx| { + .on_click(MouseButton::Left, move |_, cx| { cx.dispatch_action(SelectItem(ix)) }) .boxed() diff --git a/crates/picker/src/picker.rs b/crates/picker/src/picker.rs index 8f8e5d26b9..0b30583053 100644 --- a/crates/picker/src/picker.rs +++ b/crates/picker/src/picker.rs @@ -7,8 +7,8 @@ use gpui::{ geometry::vector::{vec2f, Vector2F}, keymap, platform::CursorStyle, - AppContext, Axis, Element, ElementBox, Entity, MouseState, MutableAppContext, RenderContext, - Task, View, ViewContext, ViewHandle, WeakViewHandle, + AppContext, Axis, Element, ElementBox, Entity, MouseButton, MouseState, MutableAppContext, + RenderContext, Task, View, ViewContext, ViewHandle, WeakViewHandle, }; use menu::{Cancel, Confirm, SelectFirst, SelectIndex, SelectLast, SelectNext, SelectPrev}; use settings::Settings; @@ -90,7 +90,9 @@ impl View for Picker { .read(cx) .render_match(ix, state, ix == selected_ix, cx) }) - .on_mouse_down(move |_, cx| cx.dispatch_action(SelectIndex(ix))) + .on_mouse_down(MouseButton::Left, move |_, cx| { + cx.dispatch_action(SelectIndex(ix)) + }) .with_cursor_style(CursorStyle::PointingHand) .boxed() })); diff --git a/crates/project_panel/src/project_panel.rs b/crates/project_panel/src/project_panel.rs index eaff23a476..8d9443de4f 100644 --- a/crates/project_panel/src/project_panel.rs +++ b/crates/project_panel/src/project_panel.rs @@ -11,8 +11,9 @@ use gpui::{ geometry::vector::Vector2F, impl_internal_actions, keymap, platform::CursorStyle, - AppContext, ClipboardItem, Element, ElementBox, Entity, ModelHandle, MutableAppContext, - PromptLevel, RenderContext, Task, View, ViewContext, ViewHandle, + AppContext, ClipboardItem, Element, ElementBox, Entity, ModelHandle, MouseButton, + MouseButtonEvent, MutableAppContext, PromptLevel, RenderContext, Task, View, ViewContext, + ViewHandle, }; use menu::{Confirm, SelectNext, SelectPrev}; use project::{Entry, EntryKind, Project, ProjectEntryId, ProjectPath, Worktree, WorktreeId}; @@ -1054,19 +1055,25 @@ impl ProjectPanel { .with_padding_left(padding) .boxed() }) - .on_click(move |_, click_count, cx| { - if kind == EntryKind::Dir { - cx.dispatch_action(ToggleExpanded(entry_id)) - } else { - cx.dispatch_action(Open { - entry_id, - change_focus: click_count > 1, - }) - } - }) - .on_right_mouse_down(move |position, cx| { - cx.dispatch_action(DeployContextMenu { entry_id, position }) - }) + .on_click( + MouseButton::Left, + move |MouseButtonEvent { click_count, .. }, cx| { + if kind == EntryKind::Dir { + cx.dispatch_action(ToggleExpanded(entry_id)) + } else { + cx.dispatch_action(Open { + entry_id, + change_focus: click_count > 1, + }) + } + }, + ) + .on_mouse_down( + MouseButton::Right, + move |MouseButtonEvent { position, .. }, cx| { + cx.dispatch_action(DeployContextMenu { entry_id, position }) + }, + ) .with_cursor_style(CursorStyle::PointingHand) .boxed() } @@ -1113,13 +1120,16 @@ impl View for ProjectPanel { .expanded() .boxed() }) - .on_right_mouse_down(move |position, cx| { - // When deploying the context menu anywhere below the last project entry, - // act as if the user clicked the root of the last worktree. - if let Some(entry_id) = last_worktree_root_id { - cx.dispatch_action(DeployContextMenu { entry_id, position }) - } - }) + .on_mouse_down( + MouseButton::Right, + move |MouseButtonEvent { position, .. }, cx| { + // When deploying the context menu anywhere below the last project entry, + // act as if the user clicked the root of the last worktree. + if let Some(entry_id) = last_worktree_root_id { + cx.dispatch_action(DeployContextMenu { entry_id, position }) + } + }, + ) .boxed(), ) .with_child(ChildView::new(&self.context_menu).boxed()) diff --git a/crates/search/src/buffer_search.rs b/crates/search/src/buffer_search.rs index 5303c20e89..529da6f7b6 100644 --- a/crates/search/src/buffer_search.rs +++ b/crates/search/src/buffer_search.rs @@ -7,8 +7,8 @@ use collections::HashMap; use editor::{Anchor, Autoscroll, Editor}; use gpui::{ actions, elements::*, impl_actions, platform::CursorStyle, Action, AppContext, Entity, - MutableAppContext, RenderContext, Subscription, Task, View, ViewContext, ViewHandle, - WeakViewHandle, + MouseButton, MutableAppContext, RenderContext, Subscription, Task, View, ViewContext, + ViewHandle, WeakViewHandle, }; use language::OffsetRangeExt; use project::search::SearchQuery; @@ -285,7 +285,9 @@ impl BufferSearchBar { .with_style(style.container) .boxed() }) - .on_click(move |_, _, cx| cx.dispatch_any_action(option.to_toggle_action())) + .on_click(MouseButton::Left, move |_, cx| { + cx.dispatch_any_action(option.to_toggle_action()) + }) .with_cursor_style(CursorStyle::PointingHand) .with_tooltip::( option as usize, @@ -330,9 +332,9 @@ impl BufferSearchBar { .with_style(style.container) .boxed() }) - .on_click({ + .on_click(MouseButton::Left, { let action = action.boxed_clone(); - move |_, _, cx| cx.dispatch_any_action(action.boxed_clone()) + move |_, cx| cx.dispatch_any_action(action.boxed_clone()) }) .with_cursor_style(CursorStyle::PointingHand) .with_tooltip::( diff --git a/crates/search/src/project_search.rs b/crates/search/src/project_search.rs index 622b84633c..405dd2d334 100644 --- a/crates/search/src/project_search.rs +++ b/crates/search/src/project_search.rs @@ -7,8 +7,8 @@ use collections::HashMap; use editor::{Anchor, Autoscroll, Editor, MultiBuffer, SelectAll, MAX_TAB_TITLE_LEN}; use gpui::{ actions, elements::*, platform::CursorStyle, Action, AppContext, ElementBox, Entity, - ModelContext, ModelHandle, MutableAppContext, RenderContext, Subscription, Task, View, - ViewContext, ViewHandle, WeakModelHandle, WeakViewHandle, + ModelContext, ModelHandle, MouseButton, MutableAppContext, RenderContext, Subscription, Task, + View, ViewContext, ViewHandle, WeakModelHandle, WeakViewHandle, }; use menu::Confirm; use project::{search::SearchQuery, Project}; @@ -735,9 +735,9 @@ impl ProjectSearchBar { .with_style(style.container) .boxed() }) - .on_click({ + .on_click(MouseButton::Left, { let action = action.boxed_clone(); - move |_, _, cx| cx.dispatch_any_action(action.boxed_clone()) + move |_, cx| cx.dispatch_any_action(action.boxed_clone()) }) .with_cursor_style(CursorStyle::PointingHand) .with_tooltip::( @@ -770,7 +770,9 @@ impl ProjectSearchBar { .with_style(style.container) .boxed() }) - .on_click(move |_, _, cx| cx.dispatch_any_action(option.to_toggle_action())) + .on_click(MouseButton::Left, move |_, cx| { + cx.dispatch_any_action(option.to_toggle_action()) + }) .with_cursor_style(CursorStyle::PointingHand) .with_tooltip::( option as usize, diff --git a/crates/terminal/src/terminal_element.rs b/crates/terminal/src/terminal_element.rs index 3406b4b9e1..f1ba70cab9 100644 --- a/crates/terminal/src/terminal_element.rs +++ b/crates/terminal/src/terminal_element.rs @@ -20,8 +20,8 @@ use gpui::{ }, json::json, text_layout::{Line, RunStyle}, - Event, FontCache, KeyDownEvent, MouseRegion, PaintContext, Quad, ScrollWheelEvent, - SizeConstraint, TextLayoutCache, WeakModelHandle, + Event, FontCache, KeyDownEvent, MouseButton, MouseButtonEvent, MouseMovedEvent, MouseRegion, + PaintContext, Quad, ScrollWheelEvent, SizeConstraint, TextLayoutCache, WeakModelHandle, }; use itertools::Itertools; use ordered_float::OrderedFloat; @@ -29,7 +29,7 @@ use settings::Settings; use theme::TerminalStyle; use util::ResultExt; -use std::{cmp::min, ops::Range, rc::Rc, sync::Arc}; +use std::{cmp::min, ops::Range, sync::Arc}; use std::{fmt::Debug, ops::Sub}; use crate::{color_translation::convert_color, connection::TerminalConnection, ZedListener}; @@ -594,63 +594,76 @@ fn attach_mouse_handlers( let drag_mutex = terminal_mutex.clone(); let mouse_down_mutex = terminal_mutex.clone(); - cx.scene.push_mouse_region(MouseRegion { - view_id, - mouse_down: Some(Rc::new(move |pos, _| { - let mut term = mouse_down_mutex.lock(); - let (point, side) = mouse_to_cell_data( - pos, - origin, - cur_size, - term.renderable_content().display_offset, - ); - term.selection = Some(Selection::new(SelectionType::Simple, point, side)) - })), - click: Some(Rc::new(move |pos, click_count, cx| { - let mut term = click_mutex.lock(); + cx.scene.push_mouse_region( + MouseRegion::new(view_id, None, visible_bounds) + .on_down( + MouseButton::Left, + move |MouseButtonEvent { position, .. }, _| { + let mut term = mouse_down_mutex.lock(); - let (point, side) = mouse_to_cell_data( - pos, - origin, - cur_size, - term.renderable_content().display_offset, - ); + let (point, side) = mouse_to_cell_data( + position, + origin, + cur_size, + term.renderable_content().display_offset, + ); + term.selection = Some(Selection::new(SelectionType::Simple, point, side)) + }, + ) + .on_click( + MouseButton::Left, + move |MouseButtonEvent { + position, + click_count, + .. + }, + cx| { + let mut term = click_mutex.lock(); - let selection_type = match click_count { - 0 => return, //This is a release - 1 => Some(SelectionType::Simple), - 2 => Some(SelectionType::Semantic), - 3 => Some(SelectionType::Lines), - _ => None, - }; + let (point, side) = mouse_to_cell_data( + position, + origin, + cur_size, + term.renderable_content().display_offset, + ); - let selection = - selection_type.map(|selection_type| Selection::new(selection_type, point, side)); + let selection_type = match click_count { + 0 => return, //This is a release + 1 => Some(SelectionType::Simple), + 2 => Some(SelectionType::Semantic), + 3 => Some(SelectionType::Lines), + _ => None, + }; - term.selection = selection; - cx.focus_parent_view(); - cx.notify(); - })), - bounds: visible_bounds, - drag: Some(Rc::new(move |_delta, pos, cx| { - let mut term = drag_mutex.lock(); + let selection = selection_type + .map(|selection_type| Selection::new(selection_type, point, side)); - let (point, side) = mouse_to_cell_data( - pos, - origin, - cur_size, - term.renderable_content().display_offset, - ); + term.selection = selection; + cx.focus_parent_view(); + cx.notify(); + }, + ) + .on_drag( + MouseButton::Left, + move |_, MouseMovedEvent { position, .. }, cx| { + let mut term = drag_mutex.lock(); - if let Some(mut selection) = term.selection.take() { - selection.update(point, side); - term.selection = Some(selection); - } + let (point, side) = mouse_to_cell_data( + position, + origin, + cur_size, + term.renderable_content().display_offset, + ); - cx.notify(); - })), - ..Default::default() - }); + if let Some(mut selection) = term.selection.take() { + selection.update(point, side); + term.selection = Some(selection); + } + + cx.notify(); + }, + ), + ); } ///Copied (with modifications) from alacritty/src/input.rs > Processor::cell_side() diff --git a/crates/workspace/src/pane.rs b/crates/workspace/src/pane.rs index 4b231e03e7..657a9f0542 100644 --- a/crates/workspace/src/pane.rs +++ b/crates/workspace/src/pane.rs @@ -13,8 +13,9 @@ use gpui::{ }, impl_actions, impl_internal_actions, platform::{CursorStyle, NavigationDirection}, - AppContext, AsyncAppContext, Entity, ModelHandle, MutableAppContext, PromptLevel, Quad, - RenderContext, Task, View, ViewContext, ViewHandle, WeakViewHandle, + AppContext, AsyncAppContext, Entity, ModelHandle, MouseButton, MouseButtonEvent, + MutableAppContext, PromptLevel, Quad, RenderContext, Task, View, ViewContext, ViewHandle, + WeakViewHandle, }; use project::{Project, ProjectEntryId, ProjectPath}; use serde::Deserialize; @@ -955,9 +956,9 @@ impl Pane { ) .with_padding(Padding::uniform(4.)) .with_cursor_style(CursorStyle::PointingHand) - .on_click({ + .on_click(MouseButton::Left, { let pane = pane.clone(); - move |_, _, cx| { + move |_, cx| { cx.dispatch_action(CloseItem { item_id, pane: pane.clone(), @@ -978,7 +979,7 @@ impl Pane { .with_style(style.container) .boxed() }) - .on_mouse_down(move |_, cx| { + .on_mouse_down(MouseButton::Left, move |_, cx| { cx.dispatch_action(ActivateItem(ix)); }) .boxed() @@ -1079,9 +1080,12 @@ impl View for Pane { }, ) .with_cursor_style(CursorStyle::PointingHand) - .on_mouse_down(|position, cx| { - cx.dispatch_action(DeploySplitMenu { position }); - }) + .on_mouse_down( + MouseButton::Left, + |MouseButtonEvent { position, .. }, cx| { + cx.dispatch_action(DeploySplitMenu { position }); + }, + ) .boxed(), ) .constrained() diff --git a/crates/workspace/src/sidebar.rs b/crates/workspace/src/sidebar.rs index a500f99492..cd4a009f2c 100644 --- a/crates/workspace/src/sidebar.rs +++ b/crates/workspace/src/sidebar.rs @@ -1,7 +1,7 @@ use crate::StatusItemView; use gpui::{ elements::*, impl_actions, platform::CursorStyle, AnyViewHandle, AppContext, Entity, - RenderContext, Subscription, View, ViewContext, ViewHandle, + MouseButton, MouseMovedEvent, RenderContext, Subscription, View, ViewContext, ViewHandle, }; use serde::Deserialize; use settings::Settings; @@ -187,19 +187,27 @@ impl Sidebar { ..Default::default() }) .with_cursor_style(CursorStyle::ResizeLeftRight) - .on_mouse_down(|_, _| {}) // This prevents the mouse down event from being propagated elsewhere - .on_drag(move |old_position, new_position, cx| { - let delta = new_position.x() - old_position.x(); - let prev_width = *actual_width.borrow(); - *custom_width.borrow_mut() = 0f32 - .max(match side { - Side::Left => prev_width + delta, - Side::Right => prev_width - delta, - }) - .round(); + .on_mouse_down(MouseButton::Left, |_, _| {}) // This prevents the mouse down event from being propagated elsewhere + .on_drag( + MouseButton::Left, + move |old_position, + MouseMovedEvent { + position: new_position, + .. + }, + cx| { + let delta = new_position.x() - old_position.x(); + let prev_width = *actual_width.borrow(); + *custom_width.borrow_mut() = 0f32 + .max(match side { + Side::Left => prev_width + delta, + Side::Right => prev_width - delta, + }) + .round(); - cx.notify(); - }) + cx.notify(); + }, + ) .boxed() } } @@ -314,9 +322,9 @@ impl View for SidebarButtons { .boxed() }) .with_cursor_style(CursorStyle::PointingHand) - .on_click({ + .on_click(MouseButton::Left, { let action = action.clone(); - move |_, _, cx| cx.dispatch_action(action.clone()) + move |_, cx| cx.dispatch_action(action.clone()) }) .with_tooltip::( ix, diff --git a/crates/workspace/src/toolbar.rs b/crates/workspace/src/toolbar.rs index 636df9a039..6d8eefcc76 100644 --- a/crates/workspace/src/toolbar.rs +++ b/crates/workspace/src/toolbar.rs @@ -1,7 +1,7 @@ use crate::{ItemHandle, Pane}; use gpui::{ elements::*, platform::CursorStyle, Action, AnyViewHandle, AppContext, ElementBox, Entity, - MutableAppContext, RenderContext, View, ViewContext, ViewHandle, WeakViewHandle, + MouseButton, MutableAppContext, RenderContext, View, ViewContext, ViewHandle, WeakViewHandle, }; use settings::Settings; @@ -191,7 +191,9 @@ fn nav_button( } else { CursorStyle::default() }) - .on_click(move |_, _, cx| cx.dispatch_action(action.clone())) + .on_click(MouseButton::Left, move |_, cx| { + cx.dispatch_action(action.clone()) + }) .with_tooltip::( 0, action_name.to_string(), diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index f6c185a19f..3a30e0cee3 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -21,8 +21,8 @@ use gpui::{ json::{self, ToJson}, platform::{CursorStyle, WindowOptions}, AnyModelHandle, AnyViewHandle, AppContext, AsyncAppContext, Border, Entity, ImageData, - ModelContext, ModelHandle, MutableAppContext, PathPromptOptions, PromptLevel, RenderContext, - Task, View, ViewContext, ViewHandle, WeakViewHandle, + ModelContext, ModelHandle, MouseButton, MutableAppContext, PathPromptOptions, PromptLevel, + RenderContext, Task, View, ViewContext, ViewHandle, WeakViewHandle, }; use language::LanguageRegistry; use log::error; @@ -1980,7 +1980,7 @@ impl Workspace { .with_style(style.container) .boxed() }) - .on_click(|_, _, cx| cx.dispatch_action(Authenticate)) + .on_click(MouseButton::Left, |_, cx| cx.dispatch_action(Authenticate)) .with_cursor_style(CursorStyle::PointingHand) .aligned() .boxed(), @@ -2031,7 +2031,9 @@ impl Workspace { if let Some((peer_id, peer_github_login)) = peer { MouseEventHandler::new::(replica_id.into(), cx, move |_, _| content) .with_cursor_style(CursorStyle::PointingHand) - .on_click(move |_, _, cx| cx.dispatch_action(ToggleFollow(peer_id))) + .on_click(MouseButton::Left, move |_, cx| { + cx.dispatch_action(ToggleFollow(peer_id)) + }) .with_tooltip::( peer_id.0 as usize, if is_followed { diff --git a/crates/zed/src/feedback.rs b/crates/zed/src/feedback.rs index 9e7564f411..f4b67a12bd 100644 --- a/crates/zed/src/feedback.rs +++ b/crates/zed/src/feedback.rs @@ -2,7 +2,7 @@ use crate::OpenBrowser; use gpui::{ elements::{MouseEventHandler, Text}, platform::CursorStyle, - Element, Entity, RenderContext, View, + Element, Entity, MouseButton, RenderContext, View, }; use settings::Settings; use workspace::StatusItemView; @@ -32,7 +32,7 @@ impl View for FeedbackLink { .boxed() }) .with_cursor_style(CursorStyle::PointingHand) - .on_click(|_, _, cx| { + .on_click(MouseButton::Left, |_, cx| { cx.dispatch_action(OpenBrowser { url: NEW_ISSUE_URL.into(), }) diff --git a/styles/package-lock.json b/styles/package-lock.json index 2eb6d3a1bf..49304dc2fa 100644 --- a/styles/package-lock.json +++ b/styles/package-lock.json @@ -5,6 +5,7 @@ "requires": true, "packages": { "": { + "name": "styles", "version": "1.0.0", "license": "ISC", "dependencies": {