use crossterm::{ event::{self, DisableMouseCapture, EnableMouseCapture, Event, KeyCode}, execute, terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen}, }; use std::{error::Error, io}; use tui::{ backend::{Backend, CrosstermBackend}, buffer::Buffer, layout::Rect, style::Style, widgets::Widget, Frame, Terminal, }; #[derive(Default)] struct Label<'a> { text: &'a str, } impl<'a> Widget for Label<'a> { fn render(self, area: Rect, buf: &mut Buffer) { buf.set_string(area.left(), area.top(), self.text, Style::default()); } } impl<'a> Label<'a> { fn text(mut self, text: &'a str) -> Label<'a> { self.text = text; self } } fn main() -> Result<(), Box> { // 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 res = run_app(&mut terminal); // restore terminal disable_raw_mode()?; execute!( terminal.backend_mut(), LeaveAlternateScreen, DisableMouseCapture )?; terminal.show_cursor()?; if let Err(err) = res { println!("{:?}", err) } Ok(()) } fn run_app(terminal: &mut Terminal) -> io::Result<()> { loop { terminal.draw(ui)?; if let Event::Key(key) = event::read()? { if let KeyCode::Char('q') = key.code { return Ok(()); } } } } fn ui(f: &mut Frame) { let size = f.size(); let label = Label::default().text("Test"); f.render_widget(label, size); }