diff options
Diffstat (limited to 'src/app/input/selection.rs')
| -rw-r--r-- | src/app/input/selection.rs | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/src/app/input/selection.rs b/src/app/input/selection.rs new file mode 100644 index 00000000..953e9b26 --- /dev/null +++ b/src/app/input/selection.rs @@ -0,0 +1,68 @@ +use crossterm::event::{MouseEvent, MouseEventKind}; + +use crate::app::state::AppState; + +impl AppState { + fn update_selection_cursor( + &mut self, + pane_id: crate::layout::PaneId, + screen_col: u16, + screen_row: u16, + ) { + let Some(info) = self.pane_info_by_id(pane_id).cloned() else { + return; + }; + let metrics = self.pane_scroll_metrics(pane_id); + if let Some(selection) = self.selection.as_mut() { + selection.drag(screen_col, screen_row, info.inner_rect, metrics); + } + } + + fn selection_edge_scroll_lines(distance: u16) -> usize { + usize::from(distance).saturating_mul(3).clamp(3, 15) + } + + pub(super) fn update_selection_drag(&mut self, screen_col: u16, screen_row: u16) { + let Some(pane_id) = self.selection.as_ref().map(|selection| selection.pane_id) else { + return; + }; + let Some(info) = self.pane_info_by_id(pane_id).cloned() else { + return; + }; + + let bottom = info.inner_rect.y + info.inner_rect.height.saturating_sub(1); + if screen_row < info.inner_rect.y { + self.scroll_pane_up( + pane_id, + Self::selection_edge_scroll_lines(info.inner_rect.y - screen_row), + ); + } else if screen_row > bottom { + self.scroll_pane_down( + pane_id, + Self::selection_edge_scroll_lines(screen_row - bottom), + ); + } + + self.update_selection_cursor(pane_id, screen_col, screen_row); + } + + pub(super) fn scroll_selection_with_wheel(&mut self, mouse: MouseEvent) -> bool { + const LINES_PER_NOTCH: usize = 3; + + let Some(selection) = self.selection.as_ref() else { + return false; + }; + if !selection.is_in_progress() { + return false; + } + let pane_id = selection.pane_id; + self.focus_pane(pane_id); + match mouse.kind { + MouseEventKind::ScrollUp => self.scroll_pane_up(pane_id, LINES_PER_NOTCH), + MouseEventKind::ScrollDown => self.scroll_pane_down(pane_id, LINES_PER_NOTCH), + _ => return false, + } + self.update_selection_cursor(pane_id, mouse.column, mouse.row); + true + } +} |
