aboutsummaryrefslogtreecommitdiff
path: root/src/cli/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/cli/mod.rs')
-rw-r--r--src/cli/mod.rs94
1 files changed, 56 insertions, 38 deletions
diff --git a/src/cli/mod.rs b/src/cli/mod.rs
index a654e19..370a30b 100644
--- a/src/cli/mod.rs
+++ b/src/cli/mod.rs
@@ -12,81 +12,99 @@ pub mod cmd;
pub use self::cmd::*;
use crate::colours::DEFAULT_COLOURS;
+use crate::input::{Button, Input};
use crate::math::Vec2;
use crate::Editor;
use raylib::drawing::{RaylibDraw, RaylibDrawHandle};
-use raylib::ffi::KeyboardKey;
-use raylib::RaylibHandle;
+use std::sync::mpsc::Receiver;
/// The command line interface. Should be created only once per program instance.
pub struct CLI {
text: String,
- active: bool,
+ char_pipe: Option<Receiver<char>>,
}
impl CLI {
/// Create a CLI for this instance
- #[allow(clippy::new_without_default)]
- pub fn new() -> Self {
+ pub fn new(input: &mut Input) -> Self {
+ input.add_global(Button::Text(':').into());
+
Self {
text: String::new(),
- active: false,
+ char_pipe: None,
}
}
/// Activates the CLI, which will now capture keyboard input and execute commands accordingly.
- pub fn activate(&mut self) {
- if !self.active {
- self.text = ";".to_owned();
- self.active = true;
+ pub fn try_activate(&mut self, input: &mut Input) {
+ if !self.active() {
+ self.char_pipe = input.try_capture_keyboard();
+
+ if self.char_pipe.is_some() {
+ self.text = ":".to_owned();
+ }
}
}
+ /// Deactivate the command line.
+ pub fn deactivate(&mut self) {
+ // Hang up, the input handler will get the message.
+ self.char_pipe = None;
+ }
+
/// Checks if the CLI is currently active. This means input to other things should be ignored.
pub fn active(&self) -> bool {
- self.active
+ self.char_pipe.is_some()
+ }
+
+ fn perform_command(&mut self, editor: &mut Editor) {
+ match cmd::parse_command(&self.text[1..]) {
+ Ok(cmd) => match cmd.process(editor) {
+ Ok(res) => self.text = format!("SUCCESS: {}", res),
+ Err(err) => self.text = format!("ERROR: {}", err),
+ },
+ Err(err) => self.text = format!("SYNTAX ERROR: {}", err),
+ }
}
/// Handle input for the command line and perform any commands the user may want to run.
- pub fn update(&mut self, rl: &mut RaylibHandle, editor: &mut Editor) {
+ pub fn update(&mut self, editor: &mut Editor, input: &mut Input) {
/* Check if the CLI is currently active. If not and it should not be activated according to
* keyboard input, there is nothing to do.
*/
- if !self.active {
- if rl.is_key_pressed(KeyboardKey::KEY_SEMICOLON) {
- // Don't write the keypress again.
- rl.get_key_pressed();
- self.activate();
+ if !self.active() {
+ if input.poll_global(&Button::Text(':').into()) {
+ self.try_activate(input);
+ if !self.active() {
+ return;
+ }
} else {
return;
}
}
- // The CLI is currently active. Handle input to it.
- if let Some(key) = rl.get_key_pressed_number() {
- self.text.push(key as u8 as char);
- } else if rl.is_key_pressed(KeyboardKey::KEY_BACKSPACE) {
- self.text.pop();
- } else if rl.is_key_pressed(KeyboardKey::KEY_ESCAPE) {
- self.text.clear();
+ let rx = self
+ .char_pipe
+ .as_mut()
+ .expect("No character pipe eventhough CLI should be active");
+
+ if let Ok(c) = rx.try_recv() {
+ match c {
+ '\x1B' => self.text.clear(), // Escape
+ '\x7f' => {
+ self.text.pop();
+ } // Backspace
+ '\n' => {
+ self.perform_command(editor);
+ self.deactivate();
+ }
+ c => self.text.push(c),
+ }
}
// When the text is empty, there is also no command marker, so set as inactive and leave.
if self.text.is_empty() {
- self.active = false;
- return;
- }
-
- // Perform the entered command, when the enter-key is pressed.
- if rl.is_key_pressed(KeyboardKey::KEY_ENTER) {
- self.active = false;
- match cmd::parse_command(&self.text[1..]) {
- Ok(cmd) => match cmd.process(editor) {
- Ok(res) => self.text = format!("SUCCESS: {}", res),
- Err(err) => self.text = format!("ERROR: {}", err),
- },
- Err(err) => self.text = format!("SYNTAX ERROR: {}", err),
- }
+ self.deactivate()
}
}