From 716c7722cda29bf612508bb96f51822a86e0f69e Mon Sep 17 00:00:00 2001 From: Ellie Huxtable Date: Sat, 20 Mar 2021 00:50:31 +0000 Subject: Add TUI, resolve #19, #17, #16 (#21) --- src/command/event.rs | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 src/command/event.rs (limited to 'src/command/event.rs') diff --git a/src/command/event.rs b/src/command/event.rs new file mode 100644 index 00000000..b205be70 --- /dev/null +++ b/src/command/event.rs @@ -0,0 +1,68 @@ +use std::sync::mpsc; +use std::thread; +use std::time::Duration; + +use termion::event::Key; +use termion::input::TermRead; + +pub enum Event { + Input(I), + Tick, +} + +/// A small event handler that wrap termion input and tick events. Each event +/// type is handled in its own thread and returned to a common `Receiver` +pub struct Events { + rx: mpsc::Receiver>, +} + +#[derive(Debug, Clone, Copy)] +pub struct Config { + pub exit_key: Key, + pub tick_rate: Duration, +} + +impl Default for Config { + fn default() -> Config { + Config { + exit_key: Key::Char('q'), + tick_rate: Duration::from_millis(250), + } + } +} + +impl Events { + pub fn new() -> Events { + Events::with_config(Config::default()) + } + + pub fn with_config(config: Config) -> Events { + let (tx, rx) = mpsc::channel(); + + { + let tx = tx.clone(); + thread::spawn(move || { + let tty = termion::get_tty().expect("Could not find tty"); + for key in tty.keys().flatten() { + if let Err(err) = tx.send(Event::Input(key)) { + eprintln!("{}", err); + return; + } + } + }) + }; + + thread::spawn(move || loop { + if tx.send(Event::Tick).is_err() { + break; + } + thread::sleep(config.tick_rate); + }); + + Events { rx } + } + + pub fn next(&self) -> Result, mpsc::RecvError> { + self.rx.recv() + } +} -- cgit v1.3.1