use ratatui::buffer::Buffer;
use ratatui::layout::Rect;
use ratatui::layout::Size;
use ratatui::style::Style;
use ratatui::text::Line;
use ratatui::widgets::Paragraph;
use ratatui::widgets::StatefulWidget;
use tui_scrollview::ScrollView;
use super::ScrollState;
#[derive(Debug)]
pub struct ScrollWidget
{
style: Style,
}
impl std::default::Default for ScrollWidget
{
fn default() -> Self
{
Self::new()
}
}
impl ScrollWidget
{
pub fn new() -> Self
{
Self {
style: Style::default(),
}
}
pub fn style<S: Into<Style>>(
mut self,
style: S,
) -> Self
{
self.style = style.into();
self
}
fn build_from_text<'r>(
&'r self,
state: &'r mut ScrollState,
) -> Vec<Line<'r>>
{
state
.text
.as_ref()
.map(|a| a.lines())
.map(
|lines| {
lines
.map(Line::raw)
.collect::<Vec<_>>()
},
)
.unwrap_or_default()
}
fn build<'r>(
&'r self,
state: &'r mut ScrollState,
) -> Vec<Line<'r>>
{
self.build_from_text(state)
}
}
impl StatefulWidget for ScrollWidget
{
type State = ScrollState;
fn render(
self,
area: Rect,
buf: &mut Buffer,
state: &mut Self::State,
)
{
let lines = self.build(state);
let height = u16::try_from(lines.len()).unwrap_or_default();
let scrollbar_width = if height <= area.height { 0 } else { 1 };
let content_size = Size::new(
area.width - scrollbar_width,
height,
);
let content_area = Rect::new(
0,
0,
content_size.width,
content_size.height,
);
let mut scrollview = ScrollView::new(content_size);
scrollview.render_widget(
Paragraph::new(lines).style(self.style),
content_area,
);
scrollview.render(
area,
buf,
&mut state.scrollview,
);
}
}