From b82736912d8b367d68a71257d81019b51ac4a062 Mon Sep 17 00:00:00 2001 From: Timon Date: Wed, 21 Nov 2018 22:57:39 +0100 Subject: [PATCH] Added the ability to pause the terminal (#47) --- examples/color/mod.rs | 2 +- examples/examples.rs | 7 +++++- examples/input/keyboard/input.rs | 7 +++++- src/modules/input/input.rs | 38 ++++++++++++++++++++++++++++++++ src/modules/input/mod.rs | 10 +++++++++ 5 files changed, 61 insertions(+), 3 deletions(-) diff --git a/examples/color/mod.rs b/examples/color/mod.rs index 67fe69a..223bd5e 100644 --- a/examples/color/mod.rs +++ b/examples/color/mod.rs @@ -109,7 +109,7 @@ pub fn print_all_foreground_colors() { ); #[cfg(unix)] - println!("{}", style("RGB color (10,10,10) ")).with(Color::AnsiValue(50)); + println!("{}", style("RGB color (10,10,10) ").with(Color::AnsiValue(50))); } /// Print all available foreground colors | demonstration. diff --git a/examples/examples.rs b/examples/examples.rs index 35240a3..c2c1b11 100644 --- a/examples/examples.rs +++ b/examples/examples.rs @@ -14,4 +14,9 @@ mod input; mod some_types; mod terminal; -fn main() {} +use crossterm::input::{TerminalInput, KeyEvent}; + +fn main() { + println!("Press 'x' to quit..."); + TerminalInput::wait_until(KeyEvent::OnKeyPress(b'x')); +} \ No newline at end of file diff --git a/examples/input/keyboard/input.rs b/examples/input/keyboard/input.rs index fda3670..c391ced 100644 --- a/examples/input/keyboard/input.rs +++ b/examples/input/keyboard/input.rs @@ -1,6 +1,6 @@ extern crate crossterm; -use self::crossterm::input::input; +use self::crossterm::input::{input, TerminalInput, KeyEvent}; use self::crossterm::Screen; pub fn read_char() { @@ -20,3 +20,8 @@ pub fn read_line() { Err(e) => println!("error: {}", e), } } + +pub fn pause_terminal() { + println!("Press 'x' to quit..."); + TerminalInput::wait_until(KeyEvent::OnKeyPress(b'x')); +} diff --git a/src/modules/input/input.rs b/src/modules/input/input.rs index db816ef..75ed305 100644 --- a/src/modules/input/input.rs +++ b/src/modules/input/input.rs @@ -3,6 +3,7 @@ use super::*; use Screen; +use std::{thread, time::Duration}; /// Struct that stores an specific platform implementation for input related actions. /// @@ -158,6 +159,43 @@ impl<'stdout> TerminalInput<'stdout> { self.terminal_input .read_until_async(delimiter, &self.stdout) } + + /// This will prevent the current thread from continuing until the passed `KeyEvent` has happened. + /// + /// ``` + /// use crossterm::input::{TerminalInput, KeyEvent}; + /// + /// fn main() { + /// println!("Press 'x' to quit..."); + /// TerminalInput::wait_until(KeyEvent::OnKeyPress(b'x')); + /// } + /// ``` + pub fn wait_until(key_event: KeyEvent) { + let screen = Screen::new(true); + let input = from_screen(&screen); + + let mut stdin = input.read_async().bytes(); + + loop { + let pressed_key: Option> = stdin.next(); + + match pressed_key { + Some(Ok(value)) => { + match key_event { + KeyEvent::OnKeyPress(ascii_code) => if value == ascii_code { break; }, + KeyEvent::OnEnter => if value == b'\r' { break; }, + KeyEvent::OnAnyKeyPress => { + break; + } + } + } + _ => {} + } + + // some sleeping time so that we don't 'dos' our cpu. + thread::sleep(Duration::from_millis(10)); + } + } } /// Get an Terminal Input implementation whereon input related actions can be performed. diff --git a/src/modules/input/mod.rs b/src/modules/input/mod.rs index b53cf30..01ab7c3 100644 --- a/src/modules/input/mod.rs +++ b/src/modules/input/mod.rs @@ -47,6 +47,16 @@ pub struct AsyncReader { recv: mpsc::Receiver>, } +// This enum represents a key event that from the user. +pub enum KeyEvent { + /// Represents a specific key press. + OnKeyPress(u8), + /// Represents a key press from any key. + OnAnyKeyPress, + /// Represents a key press from enter. + OnEnter, +} + impl Read for AsyncReader { /// Read from the byte stream. ///