From 120a08aefeed9581f5d9110861b15ee0cbcd5831 Mon Sep 17 00:00:00 2001 From: Cyandev Date: Sat, 9 Mar 2024 13:16:33 +0800 Subject: Add scrollbar for main list --- src/interactive/widgets/entries.rs | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/interactive/widgets/entries.rs b/src/interactive/widgets/entries.rs index c4794f4..e3b6cea 100644 --- a/src/interactive/widgets/entries.rs +++ b/src/interactive/widgets/entries.rs @@ -11,10 +11,10 @@ use std::collections::HashSet; use std::time::SystemTime; use tui::{ buffer::Buffer, - layout::Rect, + layout::{Margin, Rect}, style::{Color, Modifier, Style}, text::Span, - widgets::{Block, Borders}, + widgets::{Block, Borders, Scrollbar, ScrollbarOrientation, ScrollbarState, StatefulWidget}, }; use tui_react::util::rect::line_bound; use tui_react::{ @@ -132,8 +132,25 @@ impl Entries { columns_with_separators(columns, percentage_style, false) }); + let line_count = lines.len(); list.render(props, lines, area, buf); + let scrollbar = Scrollbar::default() + .orientation(ScrollbarOrientation::VerticalRight) + .begin_symbol(None) + .end_symbol(None); + let scroll_offset = selected + .and_then(|selected_idx| { + entries + .iter() + .find_position(|bundle| bundle.index == selected_idx) + .map(|(pos, _)| pos) + }) + .unwrap_or(list.offset); + let mut scrollbar_state = ScrollbarState::new(line_count).position(scroll_offset); + + scrollbar.render(area.inner(&Margin::new(0, 1)), buf, &mut scrollbar_state); + if *is_focussed { let bound = draw_top_right_help(area, &title, buf); draw_bottom_right_help(bound, buf); -- cgit v1.2.3 From fd797e86787ca1675e0f0406828c06506b4b1a11 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Sat, 9 Mar 2024 08:59:42 +0100 Subject: avoid iterating a potentially long list doubly --- src/interactive/widgets/entries.rs | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/interactive/widgets/entries.rs b/src/interactive/widgets/entries.rs index e3b6cea..78171c7 100644 --- a/src/interactive/widgets/entries.rs +++ b/src/interactive/widgets/entries.rs @@ -83,7 +83,8 @@ impl Entries { block: Some(title_block), entry_in_view, }; - let lines = entries.iter().map(|bundle| { + let mut scroll_offset = None; + let lines = entries.iter().enumerate().map(|(idx, bundle)| { let node_idx = &bundle.index; let is_dir = &bundle.is_dir; let exists = &bundle.exists; @@ -91,6 +92,9 @@ impl Entries { let is_marked = marked.map(|m| m.contains_key(node_idx)).unwrap_or(false); let is_selected = selected.map_or(false, |idx| idx == *node_idx); + if is_selected { + scroll_offset = Some(idx); + } let fraction = bundle.size as f32 / total as f32; let text_style = style(is_selected, *is_focussed); let percentage_style = percentage_style(fraction, text_style); @@ -139,15 +143,8 @@ impl Entries { .orientation(ScrollbarOrientation::VerticalRight) .begin_symbol(None) .end_symbol(None); - let scroll_offset = selected - .and_then(|selected_idx| { - entries - .iter() - .find_position(|bundle| bundle.index == selected_idx) - .map(|(pos, _)| pos) - }) - .unwrap_or(list.offset); - let mut scrollbar_state = ScrollbarState::new(line_count).position(scroll_offset); + let mut scrollbar_state = + ScrollbarState::new(line_count).position(scroll_offset.unwrap_or(list.offset)); scrollbar.render(area.inner(&Margin::new(0, 1)), buf, &mut scrollbar_state); -- cgit v1.2.3