use crossterm::event::{DisableMouseCapture, EnableMouseCapture}; use crossterm::terminal::{self, EnterAlternateScreen, LeaveAlternateScreen}; use musichoard::collection; use ratatui::backend::Backend; use ratatui::Terminal; use std::io; pub mod app; pub mod event; pub mod handler; pub mod ui; use self::app::App; use self::event::EventListener; use self::handler::EventHandler; use self::ui::Ui; #[derive(Debug)] pub enum Error { CollectionError(String), } impl From for Error { fn from(err: collection::Error) -> Error { Error::CollectionError(err.to_string()) } } pub struct Tui { terminal: Terminal, listener: EventListener, handler: EventHandler, ui: Ui, app: App, } impl Tui { pub fn new( terminal: Terminal, listener: EventListener, handler: EventHandler, ui: Ui, app: App, ) -> Self { Self { terminal, listener, handler, ui, app, } } fn init(&mut self) { terminal::enable_raw_mode().unwrap(); crossterm::execute!(io::stdout(), EnterAlternateScreen, EnableMouseCapture).unwrap(); self.terminal.hide_cursor().unwrap(); self.terminal.clear().unwrap(); } pub fn run(&mut self) { self.init(); self.listener.spawn(); while self.app.is_running() { self.terminal .draw(|frame| self.ui.render(&mut self.app, frame)) .unwrap(); self.handler.handle_next_event(&mut self.app); } self.exit(); } fn exit(&mut self) { terminal::disable_raw_mode().unwrap(); crossterm::execute!(io::stdout(), LeaveAlternateScreen, DisableMouseCapture).unwrap(); self.terminal.show_cursor().unwrap(); } }