diff --git a/crates/drag_and_drop/src/drag_and_drop.rs b/crates/drag_and_drop/src/drag_and_drop.rs index 5e4dbb4684e6b7c6eccc5c7daf36bbcab7cc8dcc..cb5c019c9f55aa72edd3c754a9e21fbc7b26dc6f 100644 --- a/crates/drag_and_drop/src/drag_and_drop.rs +++ b/crates/drag_and_drop/src/drag_and_drop.rs @@ -1,11 +1,12 @@ use std::{any::Any, rc::Rc}; +use collections::HashSet; use gpui::{ elements::{Container, MouseEventHandler}, geometry::vector::Vector2F, scene::DragRegionEvent, - CursorStyle, Element, ElementBox, EventContext, MouseButton, RenderContext, View, ViewContext, - WeakViewHandle, + CursorStyle, Element, ElementBox, EventContext, MouseButton, MutableAppContext, RenderContext, + View, WeakViewHandle, }; struct State { @@ -29,24 +30,23 @@ impl Clone for State { } pub struct DragAndDrop { - parent: WeakViewHandle, + containers: HashSet>, currently_dragged: Option>, } -impl DragAndDrop { - pub fn new(parent: WeakViewHandle, cx: &mut ViewContext) -> Self { - cx.observe_global::(|cx| { - if let Some(parent) = cx.global::().parent.upgrade(cx) { - parent.update(cx, |_, cx| cx.notify()) - } - }) - .detach(); - +impl Default for DragAndDrop { + fn default() -> Self { Self { - parent, - currently_dragged: None, + containers: Default::default(), + currently_dragged: Default::default(), } } +} + +impl DragAndDrop { + pub fn register_container(&mut self, handle: WeakViewHandle) { + self.containers.insert(handle); + } pub fn currently_dragged(&self, window_id: usize) -> Option<(Vector2F, Rc)> { self.currently_dragged.as_ref().and_then( @@ -93,9 +93,7 @@ impl DragAndDrop { }), }); - if let Some(parent) = this.parent.upgrade(cx) { - parent.update(cx, |_, cx| cx.notify()) - } + this.notify_containers_for_window(window_id, cx); }); } @@ -129,13 +127,13 @@ impl DragAndDrop { .with_cursor_style(CursorStyle::Arrow) .on_up(MouseButton::Left, |_, cx| { cx.defer(|cx| { - cx.update_global::(|this, _| this.currently_dragged.take()); + cx.update_global::(|this, cx| this.stop_dragging(cx)); }); cx.propogate_event(); }) .on_up_out(MouseButton::Left, |_, cx| { cx.defer(|cx| { - cx.update_global::(|this, _| this.currently_dragged.take()); + cx.update_global::(|this, cx| this.stop_dragging(cx)); }); }) // Don't block hover events or invalidations @@ -145,6 +143,25 @@ impl DragAndDrop { }, ) } + + fn stop_dragging(&mut self, cx: &mut MutableAppContext) { + if let Some(State { window_id, .. }) = self.currently_dragged.take() { + self.notify_containers_for_window(window_id, cx); + } + } + + fn notify_containers_for_window(&mut self, window_id: usize, cx: &mut MutableAppContext) { + self.containers.retain(|container| { + if let Some(container) = container.upgrade(cx) { + if container.window_id() == window_id { + container.update(cx, |_, cx| cx.notify()); + } + true + } else { + false + } + }); + } } pub trait Draggable { diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index 8f903f2b6540798ed99f725876879b2ce7d94fe0..ac24467343165e67db2a2ac105b48fb03674bac6 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -949,8 +949,9 @@ impl Workspace { status_bar }); - let drag_and_drop = DragAndDrop::new(cx.weak_handle(), cx); - cx.set_global(drag_and_drop); + cx.update_default_global::, _, _>(|drag_and_drop, _| { + drag_and_drop.register_container(weak_self.clone()); + }); let mut this = Workspace { modal: None, diff --git a/styles/package-lock.json b/styles/package-lock.json index 5499f1852cb4330467268dee6436b53589a90e9b..582f1c84968a5c1a25ddac5fd3c21ba907353c6d 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": {