From 68a6bf78cfe6d0a46f15f2e80e917ffb69b8c963 Mon Sep 17 00:00:00 2001 From: DLFW Date: Mon, 21 Jun 2021 02:40:44 +0200 Subject: Fix selecting an entry by mouse click when show_borders=true (#77) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * encapsulate paging strategy This commit introduces one central place where the “paging” (first entry of a dir list shown in the UI) strategy is implemented. This decreases the risk for copy-paste mistakes, makes it easier to change it, and would make the implementation of a configurable paging strategy easier. * fix: correct new index on click for parent column And a little refactoring of the code that handles the left click. * fix: consider borders on left click When selecting a dir entry with a left click of the mouse, the borders were not considered, which led to 1. a faulty, constant y offset of 1 row 2. a faulty offset, which increased with each page scrolled down, due to a wrong calculation of the content height --- src/fs/dirlist.rs | 11 +++++++ src/ui/widgets/tui_dirlist.rs | 2 +- src/ui/widgets/tui_dirlist_detailed.rs | 2 +- src/util/input.rs | 52 +++++++++++++++++++--------------- 4 files changed, 42 insertions(+), 25 deletions(-) diff --git a/src/fs/dirlist.rs b/src/fs/dirlist.rs index b80e05b..e8dc90b 100644 --- a/src/fs/dirlist.rs +++ b/src/fs/dirlist.rs @@ -143,6 +143,17 @@ impl JoshutoDirList { self.get_curr_mut_(self.index?) } + /// For a given number of entries, visible in a UI, this method returns the index of the entry + /// with which the UI should start to list the entries. + /// + /// This method assures that the cursor is always in the viewport of the UI. + pub fn first_index_for_viewport(&self, viewport_height: usize) -> usize { + match self.index { + Some(index) => index / viewport_height as usize * viewport_height as usize, + None => 0, + } + } + fn get_curr_mut_(&mut self, index: usize) -> Option<&mut JoshutoDirEntry> { if index < self.contents.len() { Some(&mut self.contents[index]) diff --git a/src/ui/widgets/tui_dirlist.rs b/src/ui/widgets/tui_dirlist.rs index 7d9f888..f66c9f0 100644 --- a/src/ui/widgets/tui_dirlist.rs +++ b/src/ui/widgets/tui_dirlist.rs @@ -36,7 +36,7 @@ impl<'a> Widget for TuiDirList<'a> { } let curr_index = self.dirlist.index.unwrap(); - let skip_dist = curr_index / area.height as usize * area.height as usize; + let skip_dist = self.dirlist.first_index_for_viewport(area.height as usize); let drawing_width = area.width as usize; diff --git a/src/ui/widgets/tui_dirlist_detailed.rs b/src/ui/widgets/tui_dirlist_detailed.rs index 796ead4..2c0337d 100644 --- a/src/ui/widgets/tui_dirlist_detailed.rs +++ b/src/ui/widgets/tui_dirlist_detailed.rs @@ -41,7 +41,7 @@ impl<'a> Widget for TuiDirListDetailed<'a> { }; let drawing_width = area.width as usize; - let skip_dist = curr_index / area.height as usize * area.height as usize; + let skip_dist = self.dirlist.first_index_for_viewport(area.height as usize); // draw every entry self.dirlist diff --git a/src/util/input.rs b/src/util/input.rs index 1d4b469..7a6d9ad 100644 --- a/src/util/input.rs +++ b/src/util/input.rs @@ -16,7 +16,13 @@ pub fn process_mouse(event: MouseEvent, context: &mut AppContext, backend: &mut let constraints: &[Constraint; 3] = &context.config_ref().display_options_ref().default_layout; let layout_rect = Layout::default() .direction(Direction::Horizontal) - .vertical_margin(1) + .vertical_margin( + if context.config_ref().display_options_ref().show_borders() { + 2 + } else { + 1 + }, + ) .constraints(constraints.as_ref()) .split(f_size); @@ -54,28 +60,28 @@ pub fn process_mouse(event: MouseEvent, context: &mut AppContext, backend: &mut MouseEvent::Press(MouseButton::Left, x, y) if y > layout_rect[1].y && y <= layout_rect[1].y + layout_rect[1].height => { - if x < layout_rect[1].x { - if let Some(dirlist) = context.tab_context_ref().curr_tab_ref().curr_list_ref() { - if let Some(curr_index) = dirlist.index { - let skip_dist = curr_index / layout_rect[1].height as usize - * layout_rect[1].height as usize; - - let new_index = skip_dist + (y - layout_rect[1].y - 1) as usize; - if let Err(e) = parent_cursor_move::parent_cursor_move(new_index, context) { - context.push_msg(e.to_string()); - } - } - } - } else if x < layout_rect[2].x { - if let Some(dirlist) = context.tab_context_ref().curr_tab_ref().curr_list_ref() { - if let Some(curr_index) = dirlist.index { - let skip_dist = curr_index / layout_rect[1].height as usize - * layout_rect[1].height as usize; - - let new_index = skip_dist + (y - layout_rect[1].y - 1) as usize; - if let Err(e) = cursor_move::cursor_move(new_index, context) { - context.push_msg(e.to_string()); - } + if x < layout_rect[2].x { + let (dirlist, is_parent) = if x < layout_rect[1].x { + ( + context.tab_context_ref().curr_tab_ref().parent_list_ref(), + true, + ) + } else { + ( + context.tab_context_ref().curr_tab_ref().curr_list_ref(), + false, + ) + }; + if let Some(dirlist) = dirlist { + let skip_dist = + dirlist.first_index_for_viewport(layout_rect[1].height as usize); + let new_index = skip_dist + (y - layout_rect[1].y - 1) as usize; + if let Err(e) = if is_parent { + parent_cursor_move::parent_cursor_move(new_index, context) + } else { + cursor_move::cursor_move(new_index, context) + } { + context.push_msg(e.to_string()); } } } else { -- cgit v1.2.3