tabiew 0.14.2

A lightweight TUI application to view and query tabular data files, such as CSV, TSV, and parquet.
use crossterm::event::{KeyCode, KeyModifiers};
use ratatui::layout::Rect;

use crate::{
    handler::message::Message,
    tui::{component::Component, pickers::list_picker::ListPicker},
};

#[derive(Debug)]
pub struct TabSwitcher {
    picker: ListPicker<String>,
    rollback: usize,
}

impl TabSwitcher {
    pub fn new(title: impl Into<String>, tabs: Vec<String>, idx: usize) -> TabSwitcher {
        let title = title.into();
        let mut picker = ListPicker::new(tabs.clone()).with_title(title.clone());
        picker.select(idx);
        Self {
            picker,
            rollback: idx,
        }
    }

    pub fn selected(&self) -> Option<usize> {
        self.picker.selected()
    }

    pub fn select(&mut self, idx: impl Into<Option<usize>>) {
        self.picker.select(idx);
    }

    pub fn select_prev(&mut self) {
        self.picker.select_up();
    }

    pub fn select_next(&mut self) {
        let idx = self
            .picker
            .selected()
            .unwrap_or_default()
            .saturating_add(1)
            .min(self.picker.len().saturating_sub(1));
        self.picker.select(Some(idx));
    }

    pub fn select_first(&mut self) {
        self.picker.select(Some(0));
    }
    pub fn select_last(&mut self) {
        self.picker
            .select(Some(self.picker.len().saturating_sub(1)));
    }
}

impl Component for TabSwitcher {
    fn render(
        &mut self,
        area: Rect,
        buf: &mut ratatui::prelude::Buffer,
        focus_state: super::component::FocusState,
    ) {
        self.picker.render(area, buf, focus_state);
    }

    fn handle(&mut self, event: crossterm::event::KeyEvent) -> bool {
        if self.picker.handle(event) {
            if let Some(select) = self.picker.selected() {
                Message::TabsSelect(select).enqueue();
            }
            true
        } else {
            match (event.code, event.modifiers) {
                (KeyCode::Enter, KeyModifiers::NONE) => {
                    Message::TabsDismissSwitcher.enqueue();
                    true
                }
                (KeyCode::Esc, KeyModifiers::NONE)
                | (KeyCode::Char('q'), KeyModifiers::NONE)
                | (KeyCode::Char('t'), KeyModifiers::NONE) => {
                    Message::TabsDismissSwitcher.enqueue();
                    Message::TabsSelect(self.rollback).enqueue();
                    true
                }
                _ => false,
            }
        }
    }
}