gitui/src/ui/scrolllist.rs
2020-03-23 14:27:49 +01:00

76 lines
1.6 KiB
Rust

use std::iter::Iterator;
use tui::{
buffer::Buffer,
layout::Rect,
style::Style,
widgets::{Block, List, Text, Widget},
};
///
pub struct ScrollableList<'b, L>
where
L: Iterator<Item = Text<'b>>,
{
block: Option<Block<'b>>,
/// Items to be displayed
items: L,
/// Index of the scroll position
scroll: usize,
/// Base style of the widget
style: Style,
}
impl<'b, L> ScrollableList<'b, L>
where
L: Iterator<Item = Text<'b>>,
{
pub fn new(items: L) -> Self {
Self {
block: None,
items,
scroll: 0,
style: Default::default(),
}
}
pub fn block(mut self, block: Block<'b>) -> Self {
self.block = Some(block);
self
}
pub fn style(mut self, style: Style) -> Self {
self.style = style;
self
}
pub fn scroll(mut self, index: usize) -> Self {
self.scroll = index;
self
}
}
impl<'b, L> Widget for ScrollableList<'b, L>
where
L: Iterator<Item = Text<'b>>,
{
fn draw(&mut self, area: Rect, buf: &mut Buffer) {
let list_area = match self.block {
Some(ref mut b) => b.inner(area),
None => area,
};
let list_height = list_area.height as usize;
let offset = if self.scroll >= list_height {
self.scroll - list_height + 1
} else {
0
};
// Render items
List::new(self.items.by_ref().skip(offset as usize))
.block(self.block.unwrap_or_default())
.style(self.style)
.draw(area, buf);
}
}