diff --git a/crates/gpui2/src/app.rs b/crates/gpui2/src/app.rs index 800c86d569ff6f612b3ad9b49976d2858a89a26a..9293302938c13b8948fab22dd4fc092e69da6c80 100644 --- a/crates/gpui2/src/app.rs +++ b/crates/gpui2/src/app.rs @@ -188,7 +188,7 @@ pub struct AppContext { flushing_effects: bool, pending_updates: usize, pub(crate) actions: Rc, - pub(crate) active_drag: Option, + pub(crate) active_drag: Option, pub(crate) active_tooltip: Option, pub(crate) next_frame_callbacks: HashMap>, pub(crate) frame_consumers: HashMap>, @@ -1264,34 +1264,6 @@ pub struct AnyDrag { pub cursor_offset: Point, } -pub enum AnyDragState { - EventListener, - AnyDrag(AnyDrag), -} - -impl AnyDragState { - pub fn any_drag(&self) -> Option<&AnyDrag> { - match self { - AnyDragState::EventListener => None, - AnyDragState::AnyDrag(any_drag) => Some(any_drag), - } - } - - pub fn entity_id(&self) -> Option { - match self { - AnyDragState::EventListener => None, - AnyDragState::AnyDrag(any_drag) => Some(any_drag.view.entity_id()), - } - } - - pub fn entity_type(&self) -> Option { - match self { - AnyDragState::EventListener => None, - AnyDragState::AnyDrag(any_drag) => Some(any_drag.view.entity_type()), - } - } -} - #[derive(Clone)] pub(crate) struct AnyTooltip { pub view: AnyView, diff --git a/crates/gpui2/src/elements/div.rs b/crates/gpui2/src/elements/div.rs index ab2124314308e8e2572cbdc6c612c1cbf94c8c02..10fd7dda0a4d710c1751333dcbf197793761f088 100644 --- a/crates/gpui2/src/elements/div.rs +++ b/crates/gpui2/src/elements/div.rs @@ -1,10 +1,10 @@ use crate::{ - point, px, Action, AnyDrag, AnyDragState, AnyElement, AnyTooltip, AnyView, AppContext, - BorrowAppContext, BorrowWindow, Bounds, ClickEvent, DispatchPhase, Element, ElementId, - FocusEvent, FocusHandle, IntoElement, KeyContext, KeyDownEvent, KeyUpEvent, LayoutId, - MouseButton, MouseDownEvent, MouseMoveEvent, MouseUpEvent, ParentElement, Pixels, Point, - Render, ScrollWheelEvent, SharedString, Size, StackingOrder, Style, StyleRefinement, Styled, - Task, View, Visibility, WindowContext, + point, px, Action, AnyDrag, AnyElement, AnyTooltip, AnyView, AppContext, BorrowAppContext, + BorrowWindow, Bounds, ClickEvent, DispatchPhase, Element, ElementId, FocusEvent, FocusHandle, + IntoElement, KeyContext, KeyDownEvent, KeyUpEvent, LayoutId, MouseButton, MouseDownEvent, + MouseMoveEvent, MouseUpEvent, ParentElement, Pixels, Point, Render, ScrollWheelEvent, + SharedString, Size, StackingOrder, Style, StyleRefinement, Styled, Task, View, Visibility, + WindowContext, }; use collections::HashMap; use refineable::Refineable; @@ -415,19 +415,6 @@ pub trait StatefulInteractiveElement: InteractiveElement { self } - fn on_drag_event( - mut self, - listener: impl Fn(&MouseMoveEvent, &mut WindowContext) + 'static, - ) -> Self - where - Self: Sized, - { - self.interactivity() - .drag_event_listeners - .push(Box::new(listener)); - self - } - fn on_hover(mut self, listener: impl Fn(&bool, &mut WindowContext) + 'static) -> Self where Self: Sized, @@ -761,7 +748,6 @@ pub struct Interactivity { pub action_listeners: SmallVec<[(TypeId, ActionListener); 8]>, pub drop_listeners: SmallVec<[(TypeId, Box); 2]>, pub click_listeners: SmallVec<[ClickListener; 2]>, - pub drag_event_listeners: SmallVec<[DragEventListener; 1]>, pub drag_listener: Option, pub hover_listener: Option>, pub tooltip_builder: Option, @@ -906,11 +892,8 @@ impl Interactivity { if phase == DispatchPhase::Bubble && interactive_bounds.visibly_contains(&event.position, &cx) { - if let Some(drag_state_type) = cx - .active_drag - .as_ref() - .and_then(|drag| drag.any_drag()) - .map(|drag| drag.view.entity_type()) + if let Some(drag_state_type) = + cx.active_drag.as_ref().map(|drag| drag.view.entity_type()) { for (drop_state_type, listener) in &drop_listeners { if *drop_state_type == drag_state_type { @@ -918,7 +901,7 @@ impl Interactivity { .active_drag .take() .expect("checked for type drag state type above"); - let drag = drag.any_drag().expect("checked for any drag above"); + listener(drag.view.clone(), cx); cx.notify(); cx.stop_propagation(); @@ -933,16 +916,12 @@ impl Interactivity { let click_listeners = mem::take(&mut self.click_listeners); let drag_listener = mem::take(&mut self.drag_listener); - let drag_event_listeners = mem::take(&mut self.drag_event_listeners); - if !click_listeners.is_empty() - || drag_listener.is_some() - || !drag_event_listeners.is_empty() - { + if !click_listeners.is_empty() || drag_listener.is_some() { let pending_mouse_down = element_state.pending_mouse_down.clone(); let mouse_down = pending_mouse_down.borrow().clone(); if let Some(mouse_down) = mouse_down { - if !drag_event_listeners.is_empty() || drag_listener.is_some() { + if let Some(drag_listener) = drag_listener { let active_state = element_state.clicked_state.clone(); let interactive_bounds = interactive_bounds.clone(); @@ -950,29 +929,17 @@ impl Interactivity { if cx.active_drag.is_some() { if phase == DispatchPhase::Capture { cx.notify(); - } else if interactive_bounds.visibly_contains(&event.position, cx) - && (event.position - mouse_down.position).magnitude() - > DRAG_THRESHOLD - { - for listener in &drag_event_listeners { - listener(event, cx); - } } } else if phase == DispatchPhase::Bubble && interactive_bounds.visibly_contains(&event.position, cx) && (event.position - mouse_down.position).magnitude() > DRAG_THRESHOLD { *active_state.borrow_mut() = ElementClickedState::default(); - if let Some(drag_listener) = &drag_listener { - let cursor_offset = event.position - bounds.origin; - let drag = drag_listener(cursor_offset, cx); - cx.active_drag = Some(AnyDragState::AnyDrag(drag)); - cx.notify(); - cx.stop_propagation(); - } - for listener in &drag_event_listeners { - listener(event, cx); - } + let cursor_offset = event.position - bounds.origin; + let drag = drag_listener(cursor_offset, cx); + cx.active_drag = Some(drag); + cx.notify(); + cx.stop_propagation(); } }); } @@ -1235,7 +1202,7 @@ impl Interactivity { if let Some(drag) = cx.active_drag.take() { for (state_type, group_drag_style) in &self.group_drag_over_styles { if let Some(group_bounds) = GroupBounds::get(&group_drag_style.group, cx) { - if Some(*state_type) == drag.entity_type() + if *state_type == drag.view.entity_type() && group_bounds.contains_point(&mouse_position) { style.refine(&group_drag_style.style); @@ -1244,7 +1211,7 @@ impl Interactivity { } for (state_type, drag_over_style) in &self.drag_over_styles { - if Some(*state_type) == drag.entity_type() + if *state_type == drag.view.entity_type() && bounds .intersect(&cx.content_mask().bounds) .contains_point(&mouse_position) @@ -1301,7 +1268,6 @@ impl Default for Interactivity { action_listeners: SmallVec::new(), drop_listeners: SmallVec::new(), click_listeners: SmallVec::new(), - drag_event_listeners: SmallVec::new(), drag_listener: None, hover_listener: None, tooltip_builder: None, diff --git a/crates/gpui2/src/window.rs b/crates/gpui2/src/window.rs index 3a966871fc13091a5d77709ca3a0e4dc67282efd..455472a349449dfa5e84d7a285a789a3402d35f6 100644 --- a/crates/gpui2/src/window.rs +++ b/crates/gpui2/src/window.rs @@ -1188,14 +1188,11 @@ impl<'a> WindowContext<'a> { }); if let Some(active_drag) = self.app.active_drag.take() { - if let Some(active_drag) = active_drag.any_drag() { - self.with_z_index(1, |cx| { - let offset = cx.mouse_position() - active_drag.cursor_offset; - let available_space = - size(AvailableSpace::MinContent, AvailableSpace::MinContent); - active_drag.view.draw(offset, available_space, cx); - }); - } + self.with_z_index(1, |cx| { + let offset = cx.mouse_position() - active_drag.cursor_offset; + let available_space = size(AvailableSpace::MinContent, AvailableSpace::MinContent); + active_drag.view.draw(offset, available_space, cx); + }); self.active_drag = Some(active_drag); } else if let Some(active_tooltip) = self.app.active_tooltip.take() { self.with_z_index(1, |cx| { @@ -1273,10 +1270,10 @@ impl<'a> WindowContext<'a> { FileDropEvent::Entered { position, files } => { self.window.mouse_position = position; if self.active_drag.is_none() { - self.active_drag = Some(crate::AnyDragState::AnyDrag(AnyDrag { + self.active_drag = Some(AnyDrag { view: self.build_view(|_| files).into(), cursor_offset: position, - })); + }); } InputEvent::MouseDown(MouseDownEvent { position,