Prepare for external file drop in pane

This commit is contained in:
Kirill Bulatov 2024-01-07 01:17:49 +02:00
parent dc7f9bbc54
commit 8ff05c6a72
8 changed files with 63 additions and 28 deletions

View file

@ -1099,12 +1099,6 @@ impl AppContext {
pub fn has_active_drag(&self) -> bool {
self.active_drag.is_some()
}
pub fn active_drag<T: 'static>(&self) -> Option<&T> {
self.active_drag
.as_ref()
.and_then(|drag| drag.value.downcast_ref())
}
}
impl Context for AppContext {

View file

@ -214,7 +214,7 @@ impl Render for ExternalPaths {
pub enum FileDropEvent {
Entered {
position: Point<Pixels>,
files: ExternalPaths,
paths: ExternalPaths,
},
Pending {
position: Point<Pixels>,

View file

@ -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 {

View file

@ -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,
});
}

View file

@ -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();
}
});

View file

@ -65,11 +65,8 @@ impl TerminalPanel {
return item.downcast::<TerminalView>().is_some();
}
}
if a.downcast_ref::<ExternalPaths>().is_some() {
return true;
}
false
a.downcast_ref::<ExternalPaths>().is_some()
})),
cx,
);

View file

@ -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::<DraggedTab>(cx.listener(Self::handle_drag_move))
.on_drag_move::<ProjectEntryId>(cx.listener(Self::handle_drag_move))
.on_drag_move::<ExternalPaths>(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::<DraggedTab>("", |style| style.visible())
.group_drag_over::<ProjectEntryId>("", |style| style.visible())
.group_drag_over::<ExternalPaths>("", |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(),

View file

@ -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::<ExternalPaths>().is_some()
|| a.downcast_ref::<DraggedTab>().is_some()
|| a.downcast_ref::<ProjectEntryId>().is_some()
})),
cx,
)
});