2019-02-10 21:35:44 +00:00
|
|
|
#[allow(dead_code)]
|
|
|
|
mod demo;
|
|
|
|
#[allow(dead_code)]
|
|
|
|
mod util;
|
|
|
|
|
|
|
|
use std::sync::mpsc;
|
|
|
|
use std::thread;
|
|
|
|
use std::time::Duration;
|
|
|
|
|
2019-06-16 21:03:36 +00:00
|
|
|
use crossterm::{input, AlternateScreen, InputEvent, KeyEvent};
|
2019-02-10 21:35:44 +00:00
|
|
|
use structopt::StructOpt;
|
|
|
|
use tui::backend::CrosstermBackend;
|
|
|
|
use tui::Terminal;
|
|
|
|
|
|
|
|
use crate::demo::{ui, App};
|
|
|
|
|
|
|
|
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()?;
|
|
|
|
|
2019-06-16 21:03:36 +00:00
|
|
|
let screen = AlternateScreen::to_alternate(true)?;
|
|
|
|
let backend = CrosstermBackend::with_alternate_screen(screen)?;
|
2019-02-10 21:35:44 +00:00
|
|
|
let mut terminal = Terminal::new(backend)?;
|
|
|
|
terminal.hide_cursor()?;
|
|
|
|
|
|
|
|
// Setup input handling
|
|
|
|
let (tx, rx) = mpsc::channel();
|
|
|
|
{
|
|
|
|
let tx = tx.clone();
|
|
|
|
thread::spawn(move || {
|
2019-06-16 21:03:36 +00:00
|
|
|
let input = input();
|
|
|
|
let reader = input.read_sync();
|
|
|
|
for event in reader {
|
|
|
|
match event {
|
|
|
|
InputEvent::Keyboard(key) => {
|
2019-02-10 21:35:44 +00:00
|
|
|
if let Err(_) = tx.send(Event::Input(key)) {
|
|
|
|
return;
|
|
|
|
}
|
2019-06-16 21:03:36 +00:00
|
|
|
if key == KeyEvent::Char('q') {
|
2019-02-10 21:35:44 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2019-06-16 21:03:36 +00:00
|
|
|
_ => {}
|
2019-02-10 21:35:44 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
{
|
|
|
|
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()? {
|
2019-06-16 21:03:36 +00:00
|
|
|
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(),
|
|
|
|
_ => {}
|
|
|
|
},
|
2019-02-10 21:35:44 +00:00
|
|
|
Event::Tick => {
|
|
|
|
app.on_tick();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if app.should_quit {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|