use crossterm::event::{Event, EventStream, KeyCode, KeyEvent, KeyEventKind, KeyModifiers}; use futures::{FutureExt, StreamExt}; use ratatui::{ DefaultTerminal, Frame, prelude::*, style::Stylize, text::Line, widgets::{Block, Paragraph}, }; fn main() { smol::block_on(async { color_eyre::install().unwrap(); let terminal = ratatui::init(); let result = App::new().run(terminal).await; ratatui::restore(); }); } #[derive(Debug, Default)] pub struct App { /// Is the application running? running: bool, // Event stream. event_stream: EventStream, state: AppState, } #[derive(Debug, Default)] pub enum screen { #[default] Dashboard, Battery, } #[derive(Debug, Default)] pub struct AppState { active_screen: screen, } impl App { /// Construct a new instance of [`App`]. pub fn new() -> Self { Self::default() } /// Run the application's main loop. pub async fn run(mut self, mut terminal: DefaultTerminal) -> color_eyre::Result<()> { self.running = true; while self.running { terminal.draw(|frame| self.draw(frame))?; self.handle_crossterm_events().await?; } Ok(()) } /// Renders the user interface. /// /// This is where you add new widgets. See the following resources for more information: /// - /// - fn draw(&mut self, frame: &mut Frame) { let title = Line::from("Ratatui Simple Template") .bold() .blue() .centered(); let text = "Hello, Ratatui!\n\n\ Created using https://github.com/ratatui/templates\n\ Press `Esc`, `Ctrl-C` or `q` to stop running."; let layout = Layout::default() .direction(Direction::Vertical) .constraints(vec![ Constraint::Percentage(33), Constraint::Percentage(33), Constraint::Percentage(33), ]) .split(frame.area()); frame.render_widget( Paragraph::new(text) .block(Block::bordered().title(title)) .centered(), layout[1], ) } /// Reads the crossterm events and updates the state of [`App`]. async fn handle_crossterm_events(&mut self) -> color_eyre::Result<()> { let event = self.event_stream.next().fuse().await; match event { Some(Ok(evt)) => match evt { Event::Key(key) if key.kind == KeyEventKind::Press => self.on_key_event(key), Event::Mouse(_) => {} Event::Resize(_, _) => {} _ => {} }, _ => {} } Ok(()) } /// Handles the key events and updates the state of [`App`]. fn on_key_event(&mut self, key: KeyEvent) { match (key.modifiers, key.code) { (_, KeyCode::Esc | KeyCode::Char('q')) | (KeyModifiers::CONTROL, KeyCode::Char('c') | KeyCode::Char('C')) => self.quit(), // Add other key handlers here. _ => {} } } /// Set running to false to quit the application. fn quit(&mut self) { self.running = false; } }