mirror of
https://github.com/gitui-org/gitui
synced 2026-05-24 09:28:21 +00:00
76 lines
1.6 KiB
Rust
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);
|
|
}
|
|
}
|