// src/tui/terminal/core.rs use crossterm::{ execute, terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen}, cursor::{SetCursorStyle, EnableBlinking, Show, Hide, MoveTo}, }; use ratatui::{backend::CrosstermBackend, Terminal}; use std::io::{self, stdout, Write}; pub struct TerminalCore { terminal: Terminal>, } impl TerminalCore { pub fn new() -> Result> { enable_raw_mode()?; let mut stdout = stdout(); execute!( stdout, EnterAlternateScreen, SetCursorStyle::SteadyBlock, EnableBlinking )?; let backend = CrosstermBackend::new(stdout); let terminal = Terminal::new(backend)?; Ok(Self { terminal }) } pub fn draw(&mut self, f: F) -> Result<(), Box> where F: FnOnce(&mut ratatui::Frame), { self.terminal.draw(f)?; Ok(()) } pub fn cleanup(&mut self) -> Result<(), Box> { let backend = self.terminal.backend_mut(); execute!( backend, Show, SetCursorStyle::DefaultUserShape, LeaveAlternateScreen )?; disable_raw_mode()?; backend.flush()?; execute!( backend, crossterm::terminal::Clear(crossterm::terminal::ClearType::All), MoveTo(0, 0) )?; Ok(()) } pub fn set_cursor_style( &mut self, style: SetCursorStyle, ) -> Result<(), Box> { execute!( self.terminal.backend_mut(), style, EnableBlinking, )?; Ok(()) } pub fn show_cursor(&mut self) -> Result<(), Box> { execute!( self.terminal.backend_mut(), Show )?; Ok(()) } pub fn hide_cursor(&mut self) -> Result<(), Box> { execute!( self.terminal.backend_mut(), Hide )?; Ok(()) } } impl Drop for TerminalCore { fn drop(&mut self) { let _ = self.cleanup(); } }