rtlibs-tui 0.1.5

rtools library: ratatui widgets
Documentation
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,
        );
    }
}