mirror of
https://github.com/zellij-org/zellij.git
synced 2024-12-24 17:53:36 +03:00
refactor(tab): simplify mouse hold and release (#1185)
This commit is contained in:
parent
87e44ed9a6
commit
7de77536ab
@ -58,14 +58,12 @@ impl ZellijPlugin for State {
|
||||
Mouse::ScrollUp(_) => {
|
||||
*self.selected_mut() = self.selected().saturating_sub(1);
|
||||
}
|
||||
Mouse::Release(Some((line, _))) => {
|
||||
Mouse::Release(line, _) => {
|
||||
if line < 0 {
|
||||
return;
|
||||
}
|
||||
let mut should_select = true;
|
||||
if let Some((Event::Mouse(Mouse::Release(Some((prev_line, _)))), t)) =
|
||||
prev_event
|
||||
{
|
||||
if let Some((Event::Mouse(Mouse::Release(prev_line, _)), t)) = prev_event {
|
||||
if prev_line == line
|
||||
&& Instant::now().saturating_duration_since(t).as_millis() < 400
|
||||
{
|
||||
|
@ -1303,9 +1303,9 @@ impl Grid {
|
||||
self.mark_for_rerender();
|
||||
}
|
||||
|
||||
pub fn end_selection(&mut self, end: Option<&Position>) {
|
||||
pub fn end_selection(&mut self, end: &Position) {
|
||||
let old_selection = self.selection;
|
||||
self.selection.end(end);
|
||||
self.selection.end(*end);
|
||||
self.update_selected_lines(&old_selection, &self.selection.clone());
|
||||
self.mark_for_rerender();
|
||||
}
|
||||
@ -1391,7 +1391,11 @@ impl Grid {
|
||||
// for now trim after building the selection to handle whitespace in wrapped lines
|
||||
let selection: Vec<_> = selection.iter().map(|l| l.trim_end()).collect();
|
||||
|
||||
Some(selection.join("\n"))
|
||||
if selection.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(selection.join("\n"))
|
||||
}
|
||||
}
|
||||
|
||||
fn update_selected_lines(&mut self, old_selection: &Selection, new_selection: &Selection) {
|
||||
|
@ -360,14 +360,12 @@ impl Pane for PluginPane {
|
||||
))
|
||||
.unwrap();
|
||||
}
|
||||
fn end_selection(&mut self, end: Option<&Position>, client_id: ClientId) {
|
||||
fn end_selection(&mut self, end: &Position, client_id: ClientId) {
|
||||
self.send_plugin_instructions
|
||||
.send(PluginInstruction::Update(
|
||||
Some(self.pid),
|
||||
Some(client_id),
|
||||
Event::Mouse(Mouse::Release(
|
||||
end.map(|Position { line, column }| (line.0, column.0)),
|
||||
)),
|
||||
Event::Mouse(Mouse::Release(end.line(), end.column())),
|
||||
))
|
||||
.unwrap();
|
||||
}
|
||||
|
@ -32,11 +32,9 @@ impl Selection {
|
||||
self.end = to
|
||||
}
|
||||
|
||||
pub fn end(&mut self, to: Option<&Position>) {
|
||||
pub fn end(&mut self, end: Position) {
|
||||
self.active = false;
|
||||
if let Some(to) = to {
|
||||
self.end = *to
|
||||
}
|
||||
self.end = end;
|
||||
}
|
||||
|
||||
pub fn contains(&self, row: usize, col: usize) -> bool {
|
||||
|
@ -431,7 +431,7 @@ impl Pane for TerminalPane {
|
||||
self.set_should_render(true);
|
||||
}
|
||||
|
||||
fn end_selection(&mut self, end: Option<&Position>, _client_id: ClientId) {
|
||||
fn end_selection(&mut self, end: &Position, _client_id: ClientId) {
|
||||
self.grid.end_selection(end);
|
||||
self.set_should_render(true);
|
||||
}
|
||||
|
@ -851,7 +851,7 @@ fn copy_selected_text_from_viewport() {
|
||||
|
||||
grid.start_selection(&Position::new(23, 6));
|
||||
// check for widechar, 📦 occupies columns 34, 35, and gets selected even if only the first column is selected
|
||||
grid.end_selection(Some(&Position::new(25, 35)));
|
||||
grid.end_selection(&Position::new(25, 35));
|
||||
let text = grid.get_selected_text();
|
||||
assert_eq!(
|
||||
text.unwrap(),
|
||||
@ -875,7 +875,7 @@ fn copy_wrapped_selected_text_from_viewport() {
|
||||
}
|
||||
|
||||
grid.start_selection(&Position::new(5, 0));
|
||||
grid.end_selection(Some(&Position::new(8, 42)));
|
||||
grid.end_selection(&Position::new(8, 42));
|
||||
let text = grid.get_selected_text();
|
||||
assert_eq!(
|
||||
text.unwrap(),
|
||||
@ -900,7 +900,7 @@ fn copy_selected_text_from_lines_above() {
|
||||
|
||||
grid.start_selection(&Position::new(-2, 10));
|
||||
// check for widechar, 📦 occupies columns 34, 35, and gets selected even if only the first column is selected
|
||||
grid.end_selection(Some(&Position::new(2, 8)));
|
||||
grid.end_selection(&Position::new(2, 8));
|
||||
let text = grid.get_selected_text();
|
||||
assert_eq!(
|
||||
text.unwrap(),
|
||||
@ -927,7 +927,7 @@ fn copy_selected_text_from_lines_below() {
|
||||
|
||||
grid.start_selection(&Position::new(63, 6));
|
||||
// check for widechar, 📦 occupies columns 34, 35, and gets selected even if only the first column is selected
|
||||
grid.end_selection(Some(&Position::new(65, 35)));
|
||||
grid.end_selection(&Position::new(65, 35));
|
||||
let text = grid.get_selected_text();
|
||||
assert_eq!(
|
||||
text.unwrap(),
|
||||
|
@ -22,26 +22,15 @@ fn selection_to() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn selection_end_with_position() {
|
||||
fn selection_end() {
|
||||
let mut selection = Selection::default();
|
||||
selection.start(Position::new(10, 10));
|
||||
selection.end(Some(&Position::new(20, 30)));
|
||||
selection.end(Position::new(20, 30));
|
||||
|
||||
assert!(!selection.active);
|
||||
assert_eq!(selection.end, Position::new(20, 30));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn selection_end_without_position() {
|
||||
let mut selection = Selection::default();
|
||||
selection.start(Position::new(10, 10));
|
||||
selection.to(Position::new(15, 100));
|
||||
selection.end(None);
|
||||
|
||||
assert!(!selection.active);
|
||||
assert_eq!(selection.end, Position::new(15, 100));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn contains() {
|
||||
struct TestCase<'a> {
|
||||
|
@ -199,7 +199,7 @@ pub trait Pane {
|
||||
}
|
||||
fn start_selection(&mut self, _start: &Position, _client_id: ClientId) {}
|
||||
fn update_selection(&mut self, _position: &Position, _client_id: ClientId) {}
|
||||
fn end_selection(&mut self, _end: Option<&Position>, _client_id: ClientId) {}
|
||||
fn end_selection(&mut self, _end: &Position, _client_id: ClientId) {}
|
||||
fn reset_selection(&mut self) {}
|
||||
fn get_selected_text(&self) -> Option<String> {
|
||||
None
|
||||
@ -2336,17 +2336,16 @@ impl Tab {
|
||||
pub fn handle_left_click(&mut self, position: &Position, client_id: ClientId) {
|
||||
self.focus_pane_at(position, client_id);
|
||||
|
||||
let show_floating_panes = self.floating_panes.panes_are_visible();
|
||||
if show_floating_panes {
|
||||
let search_selectable = false;
|
||||
if self
|
||||
let search_selectable = false;
|
||||
if self.floating_panes.panes_are_visible()
|
||||
&& self
|
||||
.floating_panes
|
||||
.move_pane_with_mouse(*position, search_selectable)
|
||||
{
|
||||
self.set_force_render();
|
||||
return;
|
||||
}
|
||||
{
|
||||
self.set_force_render();
|
||||
return;
|
||||
}
|
||||
|
||||
if let Some(pane) = self.get_pane_at(position, false) {
|
||||
let relative_position = pane.relative_position(position);
|
||||
pane.start_selection(&relative_position, client_id);
|
||||
@ -2393,97 +2392,38 @@ impl Tab {
|
||||
}
|
||||
}
|
||||
pub fn handle_mouse_release(&mut self, position: &Position, client_id: ClientId) {
|
||||
if self.floating_panes.panes_are_visible() {
|
||||
if self.selecting_with_mouse {
|
||||
let mut selected_text = None;
|
||||
let active_pane = self.get_active_pane_or_floating_pane_mut(client_id);
|
||||
if let Some(active_pane) = active_pane {
|
||||
let relative_position = active_pane.relative_position(position);
|
||||
active_pane.end_selection(&relative_position, client_id);
|
||||
selected_text = active_pane.get_selected_text();
|
||||
active_pane.reset_selection();
|
||||
}
|
||||
|
||||
if let Some(selected_text) = selected_text {
|
||||
self.write_selection_to_clipboard(&selected_text);
|
||||
}
|
||||
self.selecting_with_mouse = false;
|
||||
} else if self.floating_panes.panes_are_visible() {
|
||||
self.floating_panes.stop_moving_pane_with_mouse(*position);
|
||||
}
|
||||
if !self.selecting_with_mouse {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut selected_text = None;
|
||||
if self.floating_panes.panes_are_visible() {
|
||||
let active_pane_id = self
|
||||
.floating_panes
|
||||
.active_pane_id(client_id)
|
||||
.or_else(|| self.active_panes.get(&client_id).copied());
|
||||
// on release, get the selected text from the active pane, and reset it's selection
|
||||
let pane_id_at_position = self
|
||||
.floating_panes
|
||||
.get_pane_id_at(position, true)
|
||||
.or_else(|| self.get_pane_id_at(position, true));
|
||||
if active_pane_id != pane_id_at_position {
|
||||
// release happened outside of pane
|
||||
if let Some(active_pane_id) = active_pane_id {
|
||||
if let Some(active_pane) = self
|
||||
.floating_panes
|
||||
.get_mut(&active_pane_id)
|
||||
.or_else(|| self.panes.get_mut(&active_pane_id))
|
||||
{
|
||||
active_pane.end_selection(None, client_id);
|
||||
selected_text = active_pane.get_selected_text();
|
||||
active_pane.reset_selection();
|
||||
}
|
||||
}
|
||||
} else if let Some(pane) = pane_id_at_position.and_then(|pane_id_at_position| {
|
||||
self.floating_panes
|
||||
.get_mut(&pane_id_at_position)
|
||||
.or_else(|| self.panes.get_mut(&pane_id_at_position))
|
||||
}) {
|
||||
// release happened inside of pane
|
||||
let relative_position = pane.relative_position(position);
|
||||
pane.end_selection(Some(&relative_position), client_id);
|
||||
selected_text = pane.get_selected_text();
|
||||
pane.reset_selection();
|
||||
}
|
||||
} else {
|
||||
let active_pane_id = self.active_panes.get(&client_id);
|
||||
// on release, get the selected text from the active pane, and reset it's selection
|
||||
if active_pane_id != self.get_pane_id_at(position, true).as_ref() {
|
||||
if let Some(active_pane_id) = active_pane_id {
|
||||
if let Some(active_pane) = self.panes.get_mut(&active_pane_id) {
|
||||
active_pane.end_selection(None, client_id);
|
||||
selected_text = active_pane.get_selected_text();
|
||||
active_pane.reset_selection();
|
||||
}
|
||||
}
|
||||
} else if let Some(pane) = self.get_pane_at(position, true) {
|
||||
let relative_position = pane.relative_position(position);
|
||||
pane.end_selection(Some(&relative_position), client_id);
|
||||
selected_text = pane.get_selected_text();
|
||||
pane.reset_selection();
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(selected_text) = selected_text {
|
||||
self.write_selection_to_clipboard(&selected_text);
|
||||
}
|
||||
self.selecting_with_mouse = false;
|
||||
}
|
||||
pub fn handle_mouse_hold(&mut self, position_on_screen: &Position, client_id: ClientId) {
|
||||
let search_selectable = true;
|
||||
if self
|
||||
.floating_panes
|
||||
.move_pane_with_mouse(*position_on_screen, search_selectable)
|
||||
{
|
||||
self.set_force_render();
|
||||
} else if self.floating_panes.panes_are_visible() {
|
||||
let active_pane = self
|
||||
.floating_panes
|
||||
.get_active_pane_mut(client_id)
|
||||
.or_else(|| {
|
||||
self.active_panes
|
||||
.get(&client_id)
|
||||
.and_then(|pane_id| self.panes.get_mut(pane_id))
|
||||
});
|
||||
active_pane.map(|active_pane| {
|
||||
let relative_position = active_pane.relative_position(position_on_screen);
|
||||
active_pane.update_selection(&relative_position, client_id);
|
||||
});
|
||||
} else if let Some(active_pane_id) = self.get_active_pane_id(client_id) {
|
||||
if let Some(active_pane) = self.panes.get_mut(&active_pane_id) {
|
||||
if self.selecting_with_mouse {
|
||||
let active_pane = self.get_active_pane_or_floating_pane_mut(client_id);
|
||||
if let Some(active_pane) = active_pane {
|
||||
let relative_position = active_pane.relative_position(position_on_screen);
|
||||
active_pane.update_selection(&relative_position, client_id);
|
||||
}
|
||||
} else if self.floating_panes.panes_are_visible()
|
||||
&& self
|
||||
.floating_panes
|
||||
.move_pane_with_mouse(*position_on_screen, search_selectable)
|
||||
{
|
||||
self.set_force_render();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -58,12 +58,12 @@ pub enum Key {
|
||||
// left click) and the `ScrollUp` and `ScrollDown` events could probably be
|
||||
// merged into a single `Scroll(isize)` event.
|
||||
pub enum Mouse {
|
||||
ScrollUp(usize), // number of lines
|
||||
ScrollDown(usize), // number of lines
|
||||
LeftClick(isize, usize), // line and column
|
||||
RightClick(isize, usize), // line and column
|
||||
Hold(isize, usize), // line and column
|
||||
Release(Option<(isize, usize)>), // line and column
|
||||
ScrollUp(usize), // number of lines
|
||||
ScrollDown(usize), // number of lines
|
||||
LeftClick(isize, usize), // line and column
|
||||
RightClick(isize, usize), // line and column
|
||||
Hold(isize, usize), // line and column
|
||||
Release(isize, usize), // line and column
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, EnumDiscriminants, ToString, Serialize, Deserialize)]
|
||||
|
Loading…
Reference in New Issue
Block a user