From 8ff05c6a7227544cd36c208da8be1996e04c41dd Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Sun, 7 Jan 2024 01:17:49 +0200 Subject: [PATCH] Prepare for external file drop in pane --- crates/gpui/src/app.rs | 6 --- crates/gpui/src/interactive.rs | 2 +- crates/gpui/src/platform/mac/window.rs | 5 +- crates/gpui/src/window.rs | 6 +-- crates/terminal_view/src/terminal_element.rs | 2 +- crates/terminal_view/src/terminal_panel.rs | 5 +- crates/workspace/src/pane.rs | 49 ++++++++++++++++++-- crates/workspace/src/workspace.rs | 16 ++++--- 8 files changed, 63 insertions(+), 28 deletions(-) diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index 4ad9540043e1058ee9ab9f5e9df9ef9bbce92057..2a0ff545e92ee6ea43a580a3a5c39e648b6c947f 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -1099,12 +1099,6 @@ impl AppContext { pub fn has_active_drag(&self) -> bool { self.active_drag.is_some() } - - pub fn active_drag(&self) -> Option<&T> { - self.active_drag - .as_ref() - .and_then(|drag| drag.value.downcast_ref()) - } } impl Context for AppContext { diff --git a/crates/gpui/src/interactive.rs b/crates/gpui/src/interactive.rs index 0be917350df812ce07de2e95d1dac52cd59637ad..6f396d31aa481571d3331e816f30dbf788d47816 100644 --- a/crates/gpui/src/interactive.rs +++ b/crates/gpui/src/interactive.rs @@ -214,7 +214,7 @@ impl Render for ExternalPaths { pub enum FileDropEvent { Entered { position: Point, - files: ExternalPaths, + paths: ExternalPaths, }, Pending { position: Point, diff --git a/crates/gpui/src/platform/mac/window.rs b/crates/gpui/src/platform/mac/window.rs index 12ffc36afc08f5da22d244b7a3c14bebfb527acd..2beac528c18f53cfa9a39b008dbebf3825502b30 100644 --- a/crates/gpui/src/platform/mac/window.rs +++ b/crates/gpui/src/platform/mac/window.rs @@ -1673,10 +1673,7 @@ extern "C" fn dragging_entered(this: &Object, _: Sel, dragging_info: id) -> NSDr if send_new_event(&window_state, { let position = drag_event_position(&window_state, dragging_info); let paths = external_paths_from_event(dragging_info); - InputEvent::FileDrop(FileDropEvent::Entered { - position, - files: paths, - }) + InputEvent::FileDrop(FileDropEvent::Entered { position, paths }) }) { NSDragOperationCopy } else { diff --git a/crates/gpui/src/window.rs b/crates/gpui/src/window.rs index 71e6cb9e559a97634ee7d2df8610569838c32a5d..a0d3d0f886bbb7aeed136196740272c2da3e4f43 100644 --- a/crates/gpui/src/window.rs +++ b/crates/gpui/src/window.rs @@ -1462,12 +1462,12 @@ impl<'a> WindowContext<'a> { // Translate dragging and dropping of external files from the operating system // to internal drag and drop events. InputEvent::FileDrop(file_drop) => match file_drop { - FileDropEvent::Entered { position, files } => { + FileDropEvent::Entered { position, paths } => { self.window.mouse_position = position; if self.active_drag.is_none() { self.active_drag = Some(AnyDrag { - value: Box::new(files.clone()), - view: self.new_view(|_| files).into(), + value: Box::new(paths.clone()), + view: self.new_view(|_| paths).into(), cursor_offset: position, }); } diff --git a/crates/terminal_view/src/terminal_element.rs b/crates/terminal_view/src/terminal_element.rs index ffdca7d8135d2702a3cbc9b4d42070e8ec4e41a4..4eb26bf50745dece3bb8e7c27b3b15bfbab8d624 100644 --- a/crates/terminal_view/src/terminal_element.rs +++ b/crates/terminal_view/src/terminal_element.rs @@ -693,9 +693,9 @@ impl TerminalElement { .join(""); new_text.push(' '); terminal.update(cx, |terminal, _| { - // todo!() long paths are not displayed properly albeit the text is there terminal.paste(&new_text); }); + cx.stop_propagation(); } }); diff --git a/crates/terminal_view/src/terminal_panel.rs b/crates/terminal_view/src/terminal_panel.rs index 5e3e4c3c23d27ab3f59f31b759573c9d1c2203d3..86ac4a9818e688edcd2838c9dc2d5526485686c8 100644 --- a/crates/terminal_view/src/terminal_panel.rs +++ b/crates/terminal_view/src/terminal_panel.rs @@ -65,11 +65,8 @@ impl TerminalPanel { return item.downcast::().is_some(); } } - if a.downcast_ref::().is_some() { - return true; - } - false + a.downcast_ref::().is_some() })), cx, ); diff --git a/crates/workspace/src/pane.rs b/crates/workspace/src/pane.rs index 21c5962bebb92904935b2a2c2207cda622e29dda..1798112fcc1f28655225d86fb349bb0446463170 100644 --- a/crates/workspace/src/pane.rs +++ b/crates/workspace/src/pane.rs @@ -8,9 +8,10 @@ use anyhow::Result; use collections::{HashMap, HashSet, VecDeque}; use gpui::{ actions, impl_actions, overlay, prelude::*, Action, AnchorCorner, AnyElement, AppContext, - AsyncWindowContext, DismissEvent, Div, DragMoveEvent, EntityId, EventEmitter, FocusHandle, - FocusableView, Model, MouseButton, NavigationDirection, Pixels, Point, PromptLevel, Render, - ScrollHandle, Subscription, Task, View, ViewContext, VisualContext, WeakView, WindowContext, + AsyncWindowContext, DismissEvent, Div, DragMoveEvent, EntityId, EventEmitter, ExternalPaths, + FocusHandle, FocusableView, Model, MouseButton, NavigationDirection, Pixels, Point, + PromptLevel, Render, ScrollHandle, Subscription, Task, View, ViewContext, VisualContext, + WeakView, WindowContext, }; use parking_lot::Mutex; use project::{Project, ProjectEntryId, ProjectPath}; @@ -1555,6 +1556,10 @@ impl Pane { this.drag_split_direction = None; this.handle_project_entry_drop(entry_id, cx) })) + .on_drop(cx.listener(move |this, paths, cx| { + this.drag_split_direction = None; + this.handle_external_paths_drop(paths, cx) + })) .when_some(item.tab_tooltip_text(cx), |tab, text| { tab.tooltip(move |cx| Tooltip::text(text.clone(), cx)) }) @@ -1721,6 +1726,10 @@ impl Pane { .on_drop(cx.listener(move |this, entry_id: &ProjectEntryId, cx| { this.drag_split_direction = None; this.handle_project_entry_drop(entry_id, cx) + })) + .on_drop(cx.listener(move |this, paths, cx| { + this.drag_split_direction = None; + this.handle_external_paths_drop(paths, cx) })), ) } @@ -1855,6 +1864,35 @@ impl Pane { .log_err(); } + fn handle_external_paths_drop( + &mut self, + paths: &ExternalPaths, + cx: &mut ViewContext<'_, Pane>, + ) { + // let mut to_pane = cx.view().clone(); + // let split_direction = self.drag_split_direction; + // let project_entry_id = *project_entry_id; + // self.workspace + // .update(cx, |_, cx| { + // cx.defer(move |workspace, cx| { + // if let Some(path) = workspace + // .project() + // .read(cx) + // .path_for_entry(project_entry_id, cx) + // { + // if let Some(split_direction) = split_direction { + // to_pane = workspace.split_pane(to_pane, split_direction, cx); + // } + // workspace + // .open_path(path, Some(to_pane.downgrade()), true, cx) + // .detach_and_log_err(cx); + // } + // }); + // }) + // .log_err(); + dbg!("@@@@@@@@@@@@@@", paths); + } + pub fn display_nav_history_buttons(&mut self, display: bool) { self.display_nav_history_buttons = display; } @@ -1956,6 +1994,7 @@ impl Render for Pane { .group("") .on_drag_move::(cx.listener(Self::handle_drag_move)) .on_drag_move::(cx.listener(Self::handle_drag_move)) + .on_drag_move::(cx.listener(Self::handle_drag_move)) .map(|div| { if let Some(item) = self.active_item() { div.v_flex() @@ -1985,6 +2024,7 @@ impl Render for Pane { )) .group_drag_over::("", |style| style.visible()) .group_drag_over::("", |style| style.visible()) + .group_drag_over::("", |style| style.visible()) .when_some(self.can_drop_predicate.clone(), |this, p| { this.can_drop(move |a, cx| p(a, cx)) }) @@ -1994,6 +2034,9 @@ impl Render for Pane { .on_drop(cx.listener(move |this, entry_id, cx| { this.handle_project_entry_drop(entry_id, cx) })) + .on_drop(cx.listener(move |this, paths, cx| { + this.handle_external_paths_drop(paths, cx) + })) .map(|div| match self.drag_split_direction { None => div.top_0().left_0().right_0().bottom_0(), Some(SplitDirection::Up) => div.top_0().left_0().right_0().h_32(), diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index 6b29496f2cfd919a60e4947adb2f989fbb425486..78595d2c3126845cc06d5c14cc5e51084334d65e 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -27,11 +27,11 @@ use futures::{ use gpui::{ actions, canvas, div, impl_actions, point, size, Action, AnyElement, AnyModel, AnyView, AnyWeakView, AnyWindowHandle, AppContext, AsyncAppContext, AsyncWindowContext, BorrowWindow, - Bounds, Context, Div, DragMoveEvent, Element, Entity, EntityId, EventEmitter, FocusHandle, - FocusableView, GlobalPixels, InteractiveElement, IntoElement, KeyContext, LayoutId, - ManagedView, Model, ModelContext, ParentElement, PathPromptOptions, Pixels, Point, PromptLevel, - Render, Size, Styled, Subscription, Task, View, ViewContext, VisualContext, WeakView, - WindowBounds, WindowContext, WindowHandle, WindowOptions, + Bounds, Context, Div, DragMoveEvent, Element, Entity, EntityId, EventEmitter, ExternalPaths, + FocusHandle, FocusableView, GlobalPixels, InteractiveElement, IntoElement, KeyContext, + LayoutId, ManagedView, Model, ModelContext, ParentElement, PathPromptOptions, Pixels, Point, + PromptLevel, Render, Size, Styled, Subscription, Task, View, ViewContext, VisualContext, + WeakView, WindowBounds, WindowContext, WindowHandle, WindowOptions, }; use item::{FollowableItem, FollowableItemHandle, Item, ItemHandle, ItemSettings, ProjectItem}; use itertools::Itertools; @@ -544,7 +544,11 @@ impl Workspace { weak_handle.clone(), project.clone(), pane_history_timestamp.clone(), - None, + Some(Arc::new(|a, _| { + a.downcast_ref::().is_some() + || a.downcast_ref::().is_some() + || a.downcast_ref::().is_some() + })), cx, ) });