flowrs-tui 0.1.15

Flowrs is a Terminal User Interface (TUI) for Apache Airflow
use crossterm::event::{KeyCode, KeyEvent};
use ratatui::{
    buffer::Buffer,
    layout::{Position, Rect},
    style::Styled,
    widgets::{Block, BorderType, Borders, Paragraph, Widget},
};

use crate::ui::constants::DEFAULT_STYLE;

#[derive(Clone)]
pub struct CursorState {
    pub position: Position,
}

pub struct Filter {
    pub enabled: bool,
    pub prefix: Option<String>,
    pub cursor: CursorState,
}

impl Filter {
    pub fn new() -> Filter {
        Filter {
            enabled: false,
            prefix: None,
            cursor: CursorState {
                position: Position::default(),
            },
        }
    }

    pub fn toggle(&mut self) {
        self.enabled = !self.enabled;
    }

    pub fn is_enabled(&self) -> bool {
        self.enabled
    }

    pub fn prefix(&self) -> &Option<String> {
        &self.prefix
    }

    pub fn reset(&mut self) {
        self.enabled = false;
        self.prefix = None;
    }

    pub fn update(&mut self, key_event: &KeyEvent) {
        match key_event.code {
            KeyCode::Esc | KeyCode::Enter => {
                self.toggle();
            }
            KeyCode::Backspace => {
                if let Some(ref mut prefix) = self.prefix {
                    prefix.pop();
                }
            }
            KeyCode::Char(c) => match self.prefix {
                Some(ref mut prefix) => {
                    prefix.push(c);
                }
                None => {
                    self.prefix = Some(c.to_string());
                }
            },
            _ => {}
        }
    }
    pub fn cursor_position(&self) -> &Position {
        &self.cursor.position
    }
}

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

impl Widget for &mut Filter {
    fn render(self, area: Rect, buf: &mut Buffer) {
        let filter = self.prefix().clone();
        let filter_text = filter.unwrap_or_default();

        self.cursor.position = Position {
            x: area.x + 1 + filter_text.len() as u16,
            y: area.y + 1,
        };

        let paragraph = Paragraph::new(filter_text)
            .block(
                Block::default()
                    .border_type(BorderType::Rounded)
                    .borders(Borders::ALL)
                    .title("filter"),
            )
            .set_style(DEFAULT_STYLE);

        Widget::render(paragraph, area, buf);
    }
}