aboutsummaryrefslogtreecommitdiff
path: root/src/tui.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/tui.rs')
-rwxr-xr-xsrc/tui.rs66
1 files changed, 66 insertions, 0 deletions
diff --git a/src/tui.rs b/src/tui.rs
new file mode 100755
index 0000000..5c94b3b
--- /dev/null
+++ b/src/tui.rs
@@ -0,0 +1,66 @@
+use crate::connection::Connection;
+use crate::ui;
+use crossterm::event::{DisableMouseCapture, EnableMouseCapture};
+use crossterm::{
+ terminal::{self, *},
+};
+use ratatui::prelude::*;
+use std::io::{self, stdout, Stdout};
+use std::panic;
+
+use crate::app::{App, AppResult};
+use crate::event::EventHandler;
+
+pub type CrosstermTerminal = ratatui::Terminal<ratatui::backend::CrosstermBackend<std::io::Stderr>>;
+
+#[derive(Debug)]
+pub struct Tui {
+ terminal: CrosstermTerminal,
+ pub events: EventHandler,
+}
+
+impl Tui {
+ pub fn new(terminal: CrosstermTerminal, events: EventHandler) -> Self {
+ Self { terminal, events }
+ }
+
+ pub fn init(&mut self) -> AppResult<()> {
+ terminal::enable_raw_mode()?;
+ crossterm::execute!(io::stdout(), EnterAlternateScreen, EnableMouseCapture)?;
+
+ let panic_hook = panic::take_hook();
+ panic::set_hook(Box::new(move |panic| {
+ Self::reset().expect("failed to reset the terminal");
+ panic_hook(panic);
+ }));
+ Ok(())
+ }
+
+ /// [`Draw`] the terminal interface by [`rendering`] the widgets.
+ ///
+ /// [`Draw`]: ratatui::Terminal::draw
+ /// [`rendering`]: crate::ui::render
+ pub fn draw(&mut self, app: &mut App) -> AppResult<()> {
+ self.terminal.draw(|frame| ui::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(())
+ }
+}