diff options
| author | srdusr <trevorgray@srdusr.com> | 2025-09-26 13:39:28 +0200 |
|---|---|---|
| committer | srdusr <trevorgray@srdusr.com> | 2025-09-26 13:39:28 +0200 |
| commit | 8d60c7f93407988ee0232ea90980028f299cb0f3 (patch) | |
| tree | b343b691d1bce64fb3bc9b40324857486f2be244 /crates/tui/src/main.rs | |
| parent | 76f0d0e902e6ed164704572bd81faa5e5e560cf3 (diff) | |
| download | typerpunk-8d60c7f93407988ee0232ea90980028f299cb0f3.tar.gz typerpunk-8d60c7f93407988ee0232ea90980028f299cb0f3.zip | |
Initial Commit
Diffstat (limited to 'crates/tui/src/main.rs')
| -rw-r--r-- | crates/tui/src/main.rs | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/crates/tui/src/main.rs b/crates/tui/src/main.rs new file mode 100644 index 0000000..1819103 --- /dev/null +++ b/crates/tui/src/main.rs @@ -0,0 +1,90 @@ +use crossterm::{ + event::{self, DisableMouseCapture, EnableMouseCapture, Event}, + execute, + terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen}, +}; +use ratatui::{ + backend::CrosstermBackend, + Terminal, +}; +use std::{io, error::Error as StdError}; +use typerpunk_core::{ + app::App, + input::InputHandler, + ui::draw, +}; + +fn main() -> Result<(), Box<dyn StdError>> { + // Setup terminal + enable_raw_mode()?; + let mut stdout = io::stdout(); + execute!(stdout, EnterAlternateScreen, EnableMouseCapture)?; + let backend = CrosstermBackend::new(stdout); + let mut terminal = Terminal::new(backend)?; + + // Create app and run it + let app = match App::new() { + Ok(app) => app, + Err(e) => { + cleanup_terminal(&mut terminal)?; + return Err(e); + } + }; + + let mut input_handler = InputHandler::new(app); + let res = run_app(&mut terminal, &mut input_handler); + + // Restore terminal + cleanup_terminal(&mut terminal)?; + + if let Err(err) = res { + println!("Error: {:?}", err); + } + + Ok(()) +} + +fn cleanup_terminal<B: ratatui::backend::Backend + std::io::Write>(terminal: &mut Terminal<B>) -> io::Result<()> { + disable_raw_mode()?; + execute!( + terminal.backend_mut(), + LeaveAlternateScreen, + DisableMouseCapture + )?; + terminal.show_cursor()?; + Ok(()) +} + +fn run_app<B: ratatui::backend::Backend>( + terminal: &mut Terminal<B>, + input_handler: &mut InputHandler, +) -> io::Result<()> { + let mut last_render = std::time::Instant::now(); + let render_interval = std::time::Duration::from_millis(16); // ~60 FPS + + loop { + // Update app state to refresh timers and stats + input_handler.app.update(); + terminal.draw(|f| draw(f, &input_handler.app))?; + + if event::poll(std::time::Duration::from_millis(0))? { + if let Event::Key(key) = event::read()? { + input_handler.app.handle_input(key); + if input_handler.app.should_exit { + return Ok(()); + } + } + } + + // Limit render rate + let now = std::time::Instant::now(); + if now.duration_since(last_render) < render_interval { + std::thread::sleep(render_interval - now.duration_since(last_render)); + } + last_render = now; + + if input_handler.app.should_exit { + return Ok(()); + } + } +}
\ No newline at end of file |
