-
-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
355 additions
and
360 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
use crate::app::{App, AppResult}; | ||
use crate::event::EventHandler; | ||
use crate::tui; | ||
use crossterm::event::{DisableMouseCapture, EnableMouseCapture}; | ||
use crossterm::terminal::{self, EnterAlternateScreen, LeaveAlternateScreen}; | ||
use ratatui::backend::Backend; | ||
use ratatui::Terminal; | ||
use std::io; | ||
use std::panic; | ||
|
||
/// 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<B: Backend> { | ||
/// Interface to the Terminal. | ||
terminal: Terminal<B>, | ||
/// Terminal event handler. | ||
pub events: EventHandler, | ||
} | ||
|
||
impl<B: Backend> Tui<B> { | ||
/// Constructs a new instance of [`Tui`]. | ||
pub fn new(terminal: Terminal<B>, events: EventHandler) -> Self { | ||
Self { terminal, events } | ||
} | ||
|
||
/// Initializes the terminal interface. | ||
/// | ||
/// It enables the raw mode and sets terminal properties. | ||
pub fn init(&mut self) -> AppResult<()> { | ||
terminal::enable_raw_mode()?; | ||
crossterm::execute!(io::stderr(), EnterAlternateScreen, EnableMouseCapture)?; | ||
|
||
// Define a custom panic hook to reset the terminal properties. | ||
// This way, you won't have your terminal messed up if an unexpected error happens. | ||
let panic_hook = panic::take_hook(); | ||
panic::set_hook(Box::new(move |panic| { | ||
Self::reset().expect("failed to reset the terminal"); | ||
panic_hook(panic); | ||
})); | ||
|
||
self.terminal.hide_cursor()?; | ||
self.terminal.clear()?; | ||
Ok(()) | ||
} | ||
|
||
/// [`Draw`] the terminal interface by [`rendering`] the widgets. | ||
/// | ||
/// [`Draw`]: ratatui::Terminal::draw | ||
/// [`rendering`]: crate::tui::render | ||
pub fn draw(&mut self, app: &mut App) -> AppResult<()> { | ||
self.terminal.draw(|frame| tui::render(app, frame))?; | ||
Ok(()) | ||
} | ||
|
||
/// Resets the terminal interface. | ||
/// | ||
/// This function is also used for the panic hook to revert | ||
/// the terminal properties if unexpected errors occur. | ||
fn reset() -> AppResult<()> { | ||
terminal::disable_raw_mode()?; | ||
crossterm::execute!(io::stderr(), LeaveAlternateScreen, DisableMouseCapture)?; | ||
Ok(()) | ||
} | ||
|
||
/// Exits the terminal interface. | ||
/// | ||
/// It disables the raw mode and reverts back the terminal properties. | ||
pub fn exit(&mut self) -> AppResult<()> { | ||
Self::reset()?; | ||
self.terminal.show_cursor()?; | ||
Ok(()) | ||
} | ||
} |
Oops, something went wrong.