project_panel: Holding alt
or shift
to copy the file should adds a green (+) icon to the mouse cursor (#32040)
Part of https://github.com/zed-industries/zed/issues/14496 Depends on new API https://github.com/zed-industries/zed/pull/32028 Holding `alt` or `shift` to copy the file should add a green (+) icon to the mouse cursor to indicate this is a copy operation. 1. Press `option` first, then drag: https://github.com/user-attachments/assets/ae58c441-f1ab-423e-be59-a8ec5cba33b0 2. Drag first, then press `option`: https://github.com/user-attachments/assets/5136329f-9396-4ab9-a799-07d69cec89e2 Release Notes: - Added copy-drag cursor when pressing Alt or Shift to copy the file in Project Panel.
This commit is contained in:
parent
10df7b5eb9
commit
030d4d2631
1 changed files with 46 additions and 8 deletions
|
@ -18,11 +18,12 @@ use file_icons::FileIcons;
|
||||||
use git::status::GitSummary;
|
use git::status::GitSummary;
|
||||||
use gpui::{
|
use gpui::{
|
||||||
Action, AnyElement, App, ArcCow, AsyncWindowContext, Bounds, ClipboardItem, Context,
|
Action, AnyElement, App, ArcCow, AsyncWindowContext, Bounds, ClipboardItem, Context,
|
||||||
DismissEvent, Div, DragMoveEvent, Entity, EventEmitter, ExternalPaths, FocusHandle, Focusable,
|
CursorStyle, DismissEvent, Div, DragMoveEvent, Entity, EventEmitter, ExternalPaths,
|
||||||
Hsla, InteractiveElement, KeyContext, ListHorizontalSizingBehavior, ListSizingBehavior,
|
FocusHandle, Focusable, Hsla, InteractiveElement, KeyContext, ListHorizontalSizingBehavior,
|
||||||
MouseButton, MouseDownEvent, ParentElement, Pixels, Point, PromptLevel, Render, ScrollStrategy,
|
ListSizingBehavior, Modifiers, ModifiersChangedEvent, MouseButton, MouseDownEvent,
|
||||||
Stateful, Styled, Subscription, Task, UniformListScrollHandle, WeakEntity, Window, actions,
|
ParentElement, Pixels, Point, PromptLevel, Render, ScrollStrategy, Stateful, Styled,
|
||||||
anchored, deferred, div, impl_actions, point, px, size, transparent_white, uniform_list,
|
Subscription, Task, UniformListScrollHandle, WeakEntity, Window, actions, anchored, deferred,
|
||||||
|
div, impl_actions, point, px, size, transparent_white, uniform_list,
|
||||||
};
|
};
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
use language::DiagnosticSeverity;
|
use language::DiagnosticSeverity;
|
||||||
|
@ -109,6 +110,7 @@ pub struct ProjectPanel {
|
||||||
// in case a user clicks to open a file.
|
// in case a user clicks to open a file.
|
||||||
mouse_down: bool,
|
mouse_down: bool,
|
||||||
hover_expand_task: Option<Task<()>>,
|
hover_expand_task: Option<Task<()>>,
|
||||||
|
previous_drag_position: Option<Point<Pixels>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct DragTargetEntry {
|
struct DragTargetEntry {
|
||||||
|
@ -503,6 +505,7 @@ impl ProjectPanel {
|
||||||
scroll_handle,
|
scroll_handle,
|
||||||
mouse_down: false,
|
mouse_down: false,
|
||||||
hover_expand_task: None,
|
hover_expand_task: None,
|
||||||
|
previous_drag_position: None,
|
||||||
};
|
};
|
||||||
this.update_visible_entries(None, cx);
|
this.update_visible_entries(None, cx);
|
||||||
|
|
||||||
|
@ -3106,6 +3109,29 @@ impl ProjectPanel {
|
||||||
.detach();
|
.detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn refresh_drag_cursor_style(
|
||||||
|
&self,
|
||||||
|
modifiers: &Modifiers,
|
||||||
|
window: &mut Window,
|
||||||
|
cx: &mut Context<Self>,
|
||||||
|
) {
|
||||||
|
if let Some(existing_cursor) = cx.active_drag_cursor_style() {
|
||||||
|
let new_cursor = if Self::is_copy_modifier_set(modifiers) {
|
||||||
|
CursorStyle::DragCopy
|
||||||
|
} else {
|
||||||
|
CursorStyle::PointingHand
|
||||||
|
};
|
||||||
|
if existing_cursor != new_cursor {
|
||||||
|
cx.set_active_drag_cursor_style(new_cursor, window);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_copy_modifier_set(modifiers: &Modifiers) -> bool {
|
||||||
|
cfg!(target_os = "macos") && modifiers.alt
|
||||||
|
|| cfg!(not(target_os = "macos")) && modifiers.control
|
||||||
|
}
|
||||||
|
|
||||||
fn drag_onto(
|
fn drag_onto(
|
||||||
&mut self,
|
&mut self,
|
||||||
selections: &DraggedSelection,
|
selections: &DraggedSelection,
|
||||||
|
@ -3114,9 +3140,7 @@ impl ProjectPanel {
|
||||||
window: &mut Window,
|
window: &mut Window,
|
||||||
cx: &mut Context<Self>,
|
cx: &mut Context<Self>,
|
||||||
) {
|
) {
|
||||||
let should_copy = cfg!(target_os = "macos") && window.modifiers().alt
|
if Self::is_copy_modifier_set(&window.modifiers()) {
|
||||||
|| cfg!(not(target_os = "macos")) && window.modifiers().control;
|
|
||||||
if should_copy {
|
|
||||||
let _ = maybe!({
|
let _ = maybe!({
|
||||||
let project = self.project.read(cx);
|
let project = self.project.read(cx);
|
||||||
let target_worktree = project.worktree_for_entry(target_entry_id, cx)?;
|
let target_worktree = project.worktree_for_entry(target_entry_id, cx)?;
|
||||||
|
@ -4682,6 +4706,15 @@ impl Render for ProjectPanel {
|
||||||
window: &mut Window,
|
window: &mut Window,
|
||||||
cx: &mut Context<ProjectPanel>,
|
cx: &mut Context<ProjectPanel>,
|
||||||
) {
|
) {
|
||||||
|
if let Some(previous_position) = this.previous_drag_position {
|
||||||
|
// Refresh cursor only when an actual drag happens,
|
||||||
|
// because modifiers are not updated when the cursor is not moved.
|
||||||
|
if e.event.position != previous_position {
|
||||||
|
this.refresh_drag_cursor_style(&e.event.modifiers, window, cx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.previous_drag_position = Some(e.event.position);
|
||||||
|
|
||||||
if !e.bounds.contains(&e.event.position) {
|
if !e.bounds.contains(&e.event.position) {
|
||||||
this.drag_target_entry = None;
|
this.drag_target_entry = None;
|
||||||
return;
|
return;
|
||||||
|
@ -4741,6 +4774,11 @@ impl Render for ProjectPanel {
|
||||||
.on_drag_move(cx.listener(handle_drag_move::<DraggedSelection>))
|
.on_drag_move(cx.listener(handle_drag_move::<DraggedSelection>))
|
||||||
.size_full()
|
.size_full()
|
||||||
.relative()
|
.relative()
|
||||||
|
.on_modifiers_changed(cx.listener(
|
||||||
|
|this, event: &ModifiersChangedEvent, window, cx| {
|
||||||
|
this.refresh_drag_cursor_style(&event.modifiers, window, cx);
|
||||||
|
},
|
||||||
|
))
|
||||||
.on_hover(cx.listener(|this, hovered, window, cx| {
|
.on_hover(cx.listener(|this, hovered, window, cx| {
|
||||||
if *hovered {
|
if *hovered {
|
||||||
this.show_scrollbar = true;
|
this.show_scrollbar = true;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue