use std::{io, panic};
use anyhow::Result;
use crossterm::{
event::DisableMouseCapture,
terminal::{self, EnterAlternateScreen, LeaveAlternateScreen},
};
use ratatui::widgets::{Row, TableState};
use crate::{app::App, inputs::events::EventHandler, ui::render};
pub type CrosstermTerminal = ratatui::Terminal<ratatui::backend::CrosstermBackend<std::io::Stdout>>;
pub struct Tui {
terminal: CrosstermTerminal,
events: EventHandler,
}
impl Tui {
pub fn new(terminal: CrosstermTerminal, events: EventHandler) -> Self {
Self { terminal, events }
}
pub fn enter(&mut self) -> Result<()> {
terminal::enable_raw_mode()?;
crossterm::execute!(io::stdout(), EnterAlternateScreen, DisableMouseCapture)?;
let panic_hook = panic::take_hook();
panic::set_hook(Box::new(move |panic| {
Self::reset().expect("Failed to reset terminal");
panic_hook(panic);
}));
self.terminal.hide_cursor()?;
self.terminal.clear()?;
Ok(())
}
pub fn draw<'a>(
&mut self,
app: &mut App,
body_left_state: &mut TableState,
body_right_state: &mut TableState,
diff_one_rows: &Vec<Row<'a>>,
diff_two_rows: &Vec<Row<'a>>,
) -> Result<()> {
self.terminal.draw(|rect| {
render(
rect,
app,
body_left_state,
body_right_state,
diff_one_rows,
diff_two_rows,
)
})?;
Ok(())
}
fn reset() -> Result<()> {
terminal::disable_raw_mode()?;
crossterm::execute!(io::stdout(), LeaveAlternateScreen)?;
Ok(())
}
pub fn exit(&mut self) -> Result<()> {
Self::reset()?;
self.terminal.show_cursor()?;
Ok(())
}
}