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; mod ui; use event::EventHandler; use self::app::App; /// Error type for the TUI. #[derive(Debug)] pub enum Error { /// The collection manager failed. CollectionError(String), } impl From for Error { fn from(err: collection::Error) -> Error { Error::CollectionError(err.to_string()) } } /// Representation of a terminal user interface. /// /// It is responsible for setting up the terminal, /// initializing the interface and handling the draw events. #[derive(Debug)] pub struct Tui { /// Interface to the Terminal. terminal: Terminal, /// Terminal event handler. pub events: EventHandler, } impl Tui { /// Constructs a new instance of [`Tui`]. pub fn new(terminal: Terminal, events: EventHandler) -> Self { Self { terminal, events } } /// Initializes the terminal interface. /// /// It enables the raw mode and sets terminal properties. pub 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(); } /// [`Draw`] the terminal interface by [`rendering`] the widgets. /// /// [`Draw`]: tui::Terminal::draw /// [`rendering`]: crate::ui:render pub fn draw(&mut self, app: &mut App) { self.terminal.draw(|frame| ui::render(app, frame)).unwrap(); } /// Exits the terminal interface. /// /// It disables the raw mode and reverts back the terminal properties. pub fn exit(&mut self) { terminal::disable_raw_mode().unwrap(); crossterm::execute!(io::stdout(), LeaveAlternateScreen, DisableMouseCapture).unwrap(); self.terminal.show_cursor().unwrap(); } }