diff options
author | DLFW <daniel@llin.info> | 2022-01-04 00:05:15 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-01-03 18:05:15 -0500 |
commit | a420d6ae3dbc53da4e614b21c96d7b78b364dabb (patch) | |
tree | c07b5e7fb059181b376b7e4a4b2388f990ddee40 /src/ui | |
parent | 7791f93d95d350bdbb8dbdde4a9ec6fcbd32df41 (diff) |
Continuous scrolling (#118)
* Continuous scrolling
The scrolling behavior is changed from “paging” to a continuous
scrolling. Joshuto keeps a buffer from the cursor to each end of the
list, which is configured by `[display] scroll_offset`. If the terminal
height is too small to keep the distance, the buffer is set to a value
that assures that the cursor is at least as close to the end the user is
scrolling towards as to the other end of the visible list.
If the window is resized and the cursor jumps out of scope, the viewport
is adjusted when changing the index next time.
Possible improvements:
* Issue a viewport update on terminal geometry change
* When scrolling down to the bottom, don't allow an empty section
beneath the last entry
* Update documentation for scroll_offset
* remove unused variable
* keep viewport index when replacing dirlist
* Don't keep copy of scroll_offset in JoshutoDirList
* sanity: remove obsolete parameter
Diffstat (limited to 'src/ui')
-rw-r--r-- | src/ui/widgets/tui_dirlist.rs | 33 | ||||
-rw-r--r-- | src/ui/widgets/tui_dirlist_detailed.rs | 64 | ||||
-rw-r--r-- | src/ui/widgets/tui_footer.rs | 2 |
3 files changed, 45 insertions, 54 deletions
diff --git a/src/ui/widgets/tui_dirlist.rs b/src/ui/widgets/tui_dirlist.rs index 9a14e6a..946834b 100644 --- a/src/ui/widgets/tui_dirlist.rs +++ b/src/ui/widgets/tui_dirlist.rs @@ -32,8 +32,8 @@ impl<'a> Widget for TuiDirList<'a> { return; } - let curr_index = self.dirlist.index.unwrap(); - let skip_dist = self.dirlist.first_index_for_viewport(area.height as usize); + let curr_index = self.dirlist.get_index().unwrap(); + let skip_dist = self.dirlist.first_index_for_viewport(); let drawing_width = area.width as usize; @@ -43,26 +43,21 @@ impl<'a> Widget for TuiDirList<'a> { .enumerate() .take(area.height as usize) .for_each(|(i, entry)| { - let style = style::entry_style(entry); - print_entry(buf, entry, style, (x + 1, y + i as u16), drawing_width - 1); - }); - - // draw selected entry in a different style - let screen_index = curr_index % area.height as usize; + let ix = skip_dist + i; - let entry = self.dirlist.curr_entry_ref().unwrap(); - let style = style::entry_style(entry).add_modifier(Modifier::REVERSED); + let style = if ix == curr_index { + style::entry_style(entry).add_modifier(Modifier::REVERSED) + } else { + style::entry_style(entry) + }; - let space_fill = " ".repeat(drawing_width); - buf.set_string(x, y + screen_index as u16, space_fill.as_str(), style); + if ix == curr_index { + let space_fill = " ".repeat(drawing_width); + buf.set_string(x, y + i as u16, space_fill.as_str(), style); + } - print_entry( - buf, - entry, - style, - (x + 1, y + screen_index as u16), - drawing_width - 1, - ); + print_entry(buf, entry, style, (x + 1, y + i as u16), drawing_width - 1); + }); } } diff --git a/src/ui/widgets/tui_dirlist_detailed.rs b/src/ui/widgets/tui_dirlist_detailed.rs index 7cb0693..f5d07be 100644 --- a/src/ui/widgets/tui_dirlist_detailed.rs +++ b/src/ui/widgets/tui_dirlist_detailed.rs @@ -37,7 +37,7 @@ impl<'a> Widget for TuiDirListDetailed<'a> { let x = area.left(); let y = area.top(); - let curr_index = match self.dirlist.index { + let curr_index = match self.dirlist.get_index() { Some(i) => i, None => { let style = Style::default().bg(Color::Red).fg(Color::White); @@ -47,8 +47,7 @@ impl<'a> Widget for TuiDirListDetailed<'a> { }; let drawing_width = area.width as usize; - let skip_dist = self.dirlist.first_index_for_viewport(area.height as usize); - let screen_index = curr_index % area.height as usize; + let skip_dist = self.dirlist.first_index_for_viewport(); let line_num_style = self.display_options.line_nums(); // Length (In chars) of the last entry's index on current page. // Using this to align all elements @@ -64,20 +63,38 @@ impl<'a> Widget for TuiDirListDetailed<'a> { .enumerate() .take(area.height as usize) .for_each(|(i, entry)| { - let style = style::entry_style(entry); + let ix = skip_dist + i; - let line_number_string = match line_num_style { - LineNumberStyle::Absolute => { - format!("{:1$} ", skip_dist + i + 1, max_index_length) + let style = if ix == curr_index { + style::entry_style(entry).add_modifier(Modifier::REVERSED) + } else { + style::entry_style(entry) + }; + + let line_number_string = if ix == curr_index { + match line_num_style { + LineNumberStyle::None => "".to_string(), + _ => format!("{:<1$} ", curr_index + 1, max_index_length), + } + } else { + match line_num_style { + LineNumberStyle::Absolute => { + format!("{:1$} ", ix + 1, max_index_length) + } + LineNumberStyle::Relative => format!( + "{:1$} ", + (curr_index as i16 - ix as i16).abs(), + max_index_length + ), + LineNumberStyle::None => String::new(), } - LineNumberStyle::Relative => format!( - "{:1$} ", - (screen_index as i16 - i as i16).abs(), - max_index_length - ), - LineNumberStyle::None => String::new(), }; + if ix == curr_index { + let space_fill = " ".repeat(drawing_width); + buf.set_string(x, y + i as u16, space_fill.as_str(), style); + } + print_entry( buf, entry, @@ -87,27 +104,6 @@ impl<'a> Widget for TuiDirListDetailed<'a> { line_number_string, ); }); - - // draw selected entry in a different style - let entry = self.dirlist.curr_entry_ref().unwrap(); - let style = style::entry_style(entry).add_modifier(Modifier::REVERSED); - - let space_fill = " ".repeat(drawing_width); - buf.set_string(x, y + screen_index as u16, space_fill.as_str(), style); - - let line_number_string = match line_num_style { - LineNumberStyle::None => "".to_string(), - _ => format!("{:<1$} ", curr_index + 1, max_index_length), - }; - - print_entry( - buf, - entry, - style, - (x + 1, y + screen_index as u16), - drawing_width - 1, - line_number_string, - ); } } diff --git a/src/ui/widgets/tui_footer.rs b/src/ui/widgets/tui_footer.rs index d340983..1cc0995 100644 --- a/src/ui/widgets/tui_footer.rs +++ b/src/ui/widgets/tui_footer.rs @@ -22,7 +22,7 @@ impl<'a> TuiFooter<'a> { impl<'a> Widget for TuiFooter<'a> { fn render(self, area: Rect, buf: &mut Buffer) { use std::os::unix::fs::PermissionsExt; - match self.dirlist.index { + match self.dirlist.get_index() { Some(i) if i < self.dirlist.len() => { let entry = &self.dirlist.contents[i]; |