rtlibs-tui 0.1.4

rtools library: ratatui widgets
Documentation
use ratatui::layout::Position;

use crate::widgets::InputState;
use crate::widgets::ListState;

use super::InputSelectOption;

#[derive(Debug)]
pub struct InputSelectState
{
    pub(crate) label: Option<String>,
    pub(crate) input: InputState,
    pub(crate) input_options: ListState<InputSelectOption>,
    pub(crate) options: Vec<String>,
    pub(crate) items_shown: u16,
    // pub(crate) selected: Option<usize>,
    pub(crate) filter: String,
    pub(crate) allow_new_option: bool,
}

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

impl InputSelectState
{
    pub fn new() -> Self
    {
        Self {
            label: None,
            input: InputState::new(),
            input_options: ListState::new().with_scrollbar(),
            options: Vec::new(),
            items_shown: 3,
            // selected: None,
            filter: String::new(),
            allow_new_option: false,
        }
    }

    pub fn is_valid(&self) -> bool
    {
        self.options
            .contains(
                &self
                    .input
                    .input(),
            )
            || self.allow_new_option
    }

    pub fn allow_new_option(mut self) -> Self
    {
        self.allow_new_option = true;
        self
    }

    pub fn with_items_shown(
        mut self,
        count: u16,
    ) -> Self
    {
        self.items_shown = count;
        self
    }

    pub fn with_option<S>(
        mut self,
        option: S,
    ) -> Self
    where
        S: AsRef<str>,
    {
        // self.input_options
        //     .add_item(InputSelectOption::new(option.as_ref()));
        self.options
            .push(
                option
                    .as_ref()
                    .to_string(),
            );
        self.set_filter("");
        self
    }

    pub fn with_options<S>(
        mut self,
        options: &[S],
    ) -> Self
    where
        S: AsRef<str>,
    {
        // let temp_options = options
        //     .iter()
        //     .map(
        //         |s| {
        //             InputSelectOption::new(s)
        //             // s.as_ref()
        //             //     .to_string()
        //         },
        //     )
        //     .collect::<Vec<_>>();
        // self.input_options
        //     .add_items(temp_options);
        let mut options = options
            .iter()
            .map(
                |s| {
                    s.as_ref()
                        .to_string()
                },
            )
            .collect::<Vec<_>>();
        self.options
            .append(&mut options);
        self.set_filter("");
        self
    }

    pub fn input(&self) -> Option<String>
    {
        let value = self
            .input
            .input();
        Some(value.clone())
    }

    pub fn set_label<S>(
        &mut self,
        label: S,
    ) where
        S: AsRef<str>,
    {
        self.label = Some(
            label
                .as_ref()
                .to_string(),
        );
    }

    pub fn remove_label(&mut self)
    {
        self.label
            .take();
    }

    pub fn with_label<S>(
        mut self,
        label: S,
    ) -> Self
    where
        S: AsRef<str>,
    {
        self.set_label(label);
        self
    }

    pub fn set<S>(
        &mut self,
        value: S,
    ) where
        S: AsRef<str>,
    {
        self.input
            .set(value);
        self.set_filter("");
    }

    pub fn reset_cursor(&mut self)
    {
        self.input
            .reset_cursor();
    }

    pub fn with_default<S>(
        mut self,
        value: S,
    ) -> Self
    where
        S: AsRef<str>,
    {
        self.set(value);
        self
    }

    pub fn cursor(&self) -> Position
    {
        self.input
            .cursor()
    }

    pub fn clear(&mut self)
    {
        self.input
            .clear();
    }

    pub fn set_filter<S>(
        &mut self,
        filter: S,
    ) where
        S: AsRef<str>,
    {
        self.filter = filter
            .as_ref()
            .to_string();
        self.input_options
            .clear();
        let filtered = self
            .options
            .iter()
            .filter(|o| o.starts_with(filter.as_ref()));
        for item in filtered
        {
            self.input_options
                .add_item(InputSelectOption::new(item));
        }
    }
}