editor: Add support for drag_and_drop_selection
(#30671)
Closes #4958 Release Notes: - Added support for drag and drop text selection. It can be disabled by setting `drag_and_drop_selection` to `false`. --------- Co-authored-by: Smit Barmase <heysmitbarmase@gmail.com>
This commit is contained in:
parent
b15aef4310
commit
4fe05530b0
6 changed files with 214 additions and 16 deletions
|
@ -906,6 +906,18 @@ struct InlineBlamePopover {
|
|||
popover_state: InlineBlamePopoverState,
|
||||
}
|
||||
|
||||
enum SelectionDragState {
|
||||
/// State when no drag related activity is detected.
|
||||
None,
|
||||
/// State when the mouse is down on a selection that is about to be dragged.
|
||||
ReadyToDrag { selection: Selection<Anchor> },
|
||||
/// State when the mouse is dragging the selection in the editor.
|
||||
Dragging {
|
||||
selection: Selection<Anchor>,
|
||||
drop_cursor: Selection<Anchor>,
|
||||
},
|
||||
}
|
||||
|
||||
/// Represents a breakpoint indicator that shows up when hovering over lines in the gutter that don't have
|
||||
/// a breakpoint on them.
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
|
@ -1091,6 +1103,8 @@ pub struct Editor {
|
|||
hide_mouse_mode: HideMouseMode,
|
||||
pub change_list: ChangeList,
|
||||
inline_value_cache: InlineValueCache,
|
||||
selection_drag_state: SelectionDragState,
|
||||
drag_and_drop_selection_enabled: bool,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Default)]
|
||||
|
@ -1985,6 +1999,8 @@ impl Editor {
|
|||
.unwrap_or_default(),
|
||||
change_list: ChangeList::new(),
|
||||
mode,
|
||||
selection_drag_state: SelectionDragState::None,
|
||||
drag_and_drop_selection_enabled: EditorSettings::get_global(cx).drag_and_drop_selection,
|
||||
};
|
||||
if let Some(breakpoints) = editor.breakpoint_store.as_ref() {
|
||||
editor
|
||||
|
@ -3530,6 +3546,7 @@ impl Editor {
|
|||
|
||||
pub fn cancel(&mut self, _: &Cancel, window: &mut Window, cx: &mut Context<Self>) {
|
||||
self.selection_mark_mode = false;
|
||||
self.selection_drag_state = SelectionDragState::None;
|
||||
|
||||
if self.clear_expanded_diff_hunks(cx) {
|
||||
cx.notify();
|
||||
|
@ -10584,6 +10601,56 @@ impl Editor {
|
|||
});
|
||||
}
|
||||
|
||||
pub fn drop_selection(
|
||||
&mut self,
|
||||
point_for_position: Option<PointForPosition>,
|
||||
is_cut: bool,
|
||||
window: &mut Window,
|
||||
cx: &mut Context<Self>,
|
||||
) -> bool {
|
||||
if let Some(point_for_position) = point_for_position {
|
||||
match self.selection_drag_state {
|
||||
SelectionDragState::Dragging { ref selection, .. } => {
|
||||
let snapshot = self.snapshot(window, cx);
|
||||
let selection_display =
|
||||
selection.map(|anchor| anchor.to_display_point(&snapshot));
|
||||
if !point_for_position.intersects_selection(&selection_display) {
|
||||
let point = point_for_position.previous_valid;
|
||||
let display_map = self.display_map.update(cx, |map, cx| map.snapshot(cx));
|
||||
let buffer = &display_map.buffer_snapshot;
|
||||
let mut edits = Vec::new();
|
||||
let insert_point = display_map
|
||||
.clip_point(point, Bias::Left)
|
||||
.to_point(&display_map);
|
||||
let text = buffer
|
||||
.text_for_range(selection.start..selection.end)
|
||||
.collect::<String>();
|
||||
if is_cut {
|
||||
edits.push(((selection.start..selection.end), String::new()));
|
||||
}
|
||||
let insert_anchor = buffer.anchor_before(insert_point);
|
||||
edits.push(((insert_anchor..insert_anchor), text));
|
||||
let last_edit_start = insert_anchor.bias_left(buffer);
|
||||
let last_edit_end = insert_anchor.bias_right(buffer);
|
||||
self.transact(window, cx, |this, window, cx| {
|
||||
this.buffer.update(cx, |buffer, cx| {
|
||||
buffer.edit(edits, None, cx);
|
||||
});
|
||||
this.change_selections(Some(Autoscroll::fit()), window, cx, |s| {
|
||||
s.select_anchor_ranges([last_edit_start..last_edit_end]);
|
||||
});
|
||||
});
|
||||
self.selection_drag_state = SelectionDragState::None;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
self.selection_drag_state = SelectionDragState::None;
|
||||
false
|
||||
}
|
||||
|
||||
pub fn duplicate(
|
||||
&mut self,
|
||||
upwards: bool,
|
||||
|
@ -18987,6 +19054,7 @@ impl Editor {
|
|||
self.show_breadcrumbs = editor_settings.toolbar.breadcrumbs;
|
||||
self.cursor_shape = editor_settings.cursor_shape.unwrap_or_default();
|
||||
self.hide_mouse_mode = editor_settings.hide_mouse.unwrap_or_default();
|
||||
self.drag_and_drop_selection_enabled = editor_settings.drag_and_drop_selection;
|
||||
}
|
||||
|
||||
if old_cursor_shape != self.cursor_shape {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue