aboutsummaryrefslogtreecommitdiff
path: root/src/app/input/selection.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/app/input/selection.rs')
-rw-r--r--src/app/input/selection.rs68
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
+ }
+}