rtlibs-tui 0.1.4

rtools library: ratatui widgets
Documentation
use ratatui::buffer::Buffer;
use ratatui::layout::Constraint;
use ratatui::layout::Layout;
use ratatui::layout::Rect;
use ratatui::style::Color;
use ratatui::style::Style;
use ratatui::text::Text;
use ratatui::widgets::Clear;
use ratatui::widgets::StatefulWidget;
use ratatui::widgets::Widget;

use crate::widgets::InputNumberWidget;

use super::InputCurrencyState;

pub struct InputCurrencyWidget
{
    style: Style,
}

impl std::default::Default for InputCurrencyWidget
{
    fn default() -> Self
    {
        Self::new()
    }
}

impl InputCurrencyWidget
{
    pub fn new() -> Self
    {
        Self {
            style: Style::default(),
        }
    }

    pub fn style<S: Into<Style>>(
        mut self,
        style: S,
    ) -> Self
    {
        self.style = style.into();
        self
    }
}

impl StatefulWidget for InputCurrencyWidget
{
    type State = InputCurrencyState;

    fn render(
        self,
        area: Rect,
        buf: &mut Buffer,
        state: &mut Self::State,
    )
    {
        Clear.render(
            area, buf,
        );

        let style = if state
            .input()
            .is_some()
        {
            Style::new().bg(Color::DarkGray)
        }
        else
        {
            Style::new().bg(Color::Red)
        };

        let label_length: u16 = state
            .label
            .clone()
            .and_then(
                |s| {
                    s.chars()
                        .count()
                        .try_into()
                        .ok()
                },
            )
            .unwrap_or(0);

        let [label_area, sign_area, integral_area, sep_area, decimal_area, currency_area, _] =
            Layout::horizontal([
                Constraint::Length(label_length),
                Constraint::Length(1),
                Constraint::Length(8),
                Constraint::Length(1),
                Constraint::Length(2),
                Constraint::Length(1),
                Constraint::Fill(1),
            ])
            .areas(area);

        if let Some(label) = state
            .label
            .as_ref()
        {
            Text::raw(label).render(
                label_area, buf,
            );
        }

        Text::raw(".").render(
            sep_area, buf,
        );
        Text::raw("").render(
            currency_area,
            buf,
        );

        let sign = if state.is_negative { "-" } else { "+" };
        Text::raw(sign).render(
            sign_area, buf,
        );

        InputNumberWidget::new()
            .style(style)
            .render(
                integral_area,
                buf,
                &mut state.input_integral,
            );
        InputNumberWidget::new()
            .style(style)
            .render(
                decimal_area,
                buf,
                &mut state.input_decimal,
            );
    }
}