ratatui/examples/crossterm_demo.rs
Florian Dehau 3747ddbefb feat(backend): Refactor crossterm backend
* Remove compilation warnings
* Fix rendering artifacts in the crossterm demo. In particular, the bold modifier
was leaking on most of the terminal screen because the old logic was not
properly unsetting the bold modifier after use (took inspiration of the termion
backend implementation)
2019-10-31 09:17:47 +01:00

98 lines
2.4 KiB
Rust

#[allow(dead_code)]
mod demo;
#[allow(dead_code)]
mod util;
use std::sync::mpsc;
use std::thread;
use std::time::Duration;
use crossterm::{input, AlternateScreen, InputEvent, KeyEvent};
use structopt::StructOpt;
use tui::backend::CrosstermBackend;
use tui::Terminal;
use crate::demo::{ui, App};
use std::io::stdout;
enum Event<I> {
Input(I),
Tick,
}
#[derive(Debug, StructOpt)]
struct Cli {
#[structopt(long = "tick-rate", default_value = "250")]
tick_rate: u64,
#[structopt(long = "log")]
log: bool,
}
fn main() -> Result<(), failure::Error> {
let cli = Cli::from_args();
stderrlog::new().quiet(!cli.log).verbosity(4).init()?;
let screen = AlternateScreen::to_alternate(true)?;
let backend = CrosstermBackend::with_alternate_screen(stdout(), screen)?;
let mut terminal = Terminal::new(backend)?;
terminal.hide_cursor()?;
// Setup input handling
let (tx, rx) = mpsc::channel();
{
let tx = tx.clone();
thread::spawn(move || {
let input = input();
let reader = input.read_sync();
for event in reader {
match event {
InputEvent::Keyboard(key) => {
if let Err(_) = tx.send(Event::Input(key.clone())) {
return;
}
if key == KeyEvent::Char('q') {
return;
}
}
_ => {}
}
}
});
}
{
let tx = tx.clone();
thread::spawn(move || {
let tx = tx.clone();
loop {
tx.send(Event::Tick).unwrap();
thread::sleep(Duration::from_millis(cli.tick_rate));
}
});
}
let mut app = App::new("Crossterm Demo");
terminal.clear()?;
loop {
ui::draw(&mut terminal, &app)?;
match rx.recv()? {
Event::Input(event) => match event {
KeyEvent::Char(c) => app.on_key(c),
KeyEvent::Left => app.on_left(),
KeyEvent::Up => app.on_up(),
KeyEvent::Right => app.on_right(),
KeyEvent::Down => app.on_down(),
_ => {}
},
Event::Tick => {
app.on_tick();
}
}
if app.should_quit {
break;
}
}
Ok(())
}