diff options
Diffstat (limited to 'src/client/gui/dimension_indicator.rs')
| -rw-r--r-- | src/client/gui/dimension_indicator.rs | 141 |
1 files changed, 72 insertions, 69 deletions
diff --git a/src/client/gui/dimension_indicator.rs b/src/client/gui/dimension_indicator.rs index fb6394a..ebad78b 100644 --- a/src/client/gui/dimension_indicator.rs +++ b/src/client/gui/dimension_indicator.rs @@ -2,6 +2,7 @@ //! manually change the size of them in a precise manner should need be. use crate::client::colours::DEFAULT_COLOURS; +use crate::client::input::{Button, Input, Scancode}; use crate::client::map::Map; use crate::client::transform::Transform; use crate::client::Editor; @@ -11,6 +12,7 @@ use nalgebra::{Matrix3, Vector2}; use raylib::drawing::RaylibDraw; use raylib::ffi::KeyboardKey; use raylib::RaylibHandle; +use std::sync::mpsc::Receiver; /// A state the [DimensionIndicator] is currently in. This determines the behaviour of it and what /// inputs it might be waiting for. @@ -25,6 +27,7 @@ enum State { dim_x: String, dim_y: String, editing_x: bool, + text_pipe: Receiver<char>, }, } @@ -37,38 +40,28 @@ pub struct DimensionIndicator { bounds: Rect<f64>, } -impl Default for State { - fn default() -> Self { - Self::Watching - } -} +impl DimensionIndicator { + /// Create a new dimension indicator. While it is possible to have multiple instances, this is + /// not generally recommended, since they will need to be managed carefully or otherwise steal + /// keystrokes from each other. + pub fn new(input: &mut Input) -> Self { + input.add_global(Button::Scancode(Scancode::Tab).into()); -impl Default for DimensionIndicator { - fn default() -> Self { Self { state: State::default(), bounds: Rect::new(0., 0., 0., 0.), } } -} - -impl DimensionIndicator { - /// Create a new dimension indicator. While it is possible to have multiple instances, this is - /// not generally recommended, since they will need to be managed carefully or otherwise steal - /// keystrokes from each other. - pub fn new() -> Self { - Self::default() - } /// Update whatever is selected on the map according to the dimension indicator rules and rulers. - pub fn update(&mut self, editor: &Editor, rl: &mut RaylibHandle) { + pub fn update(&mut self, editor: &Editor, input: &mut Input) { match self.state { - State::Watching => self.update_watching(editor.map(), rl), - State::Ruling { .. } => self.update_ruling(editor, rl), + State::Watching => self.update_watching(editor.map(), input), + State::Ruling { .. } => self.update_ruling(editor, input), }; } - fn update_watching(&mut self, map: &Map, rl: &RaylibHandle) { + fn update_watching(&mut self, map: &Map, input: &mut Input) { let mut min: Vec2<f64> = Vec2::default(); let mut max: Vec2<f64> = Vec2::default(); @@ -105,75 +98,79 @@ impl DimensionIndicator { // Check if the user wants to change into editing mode, which the user can only do if there // is a selection to begin with. - if selection_exists && rl.is_key_pressed(KeyboardKey::KEY_TAB) { - self.state = State::Ruling { - dim_x: self.bounds.w.to_string(), - dim_y: self.bounds.h.to_string(), - editing_x: true, - }; + if selection_exists && input.poll_global(&Button::Scancode(Scancode::Tab).into()) { + // Try to capture the keyboard and go into the ruling state. + if let Some(text_pipe) = input.try_capture_keyboard() { + self.state = State::Ruling { + dim_x: self.bounds.w.to_string(), + dim_y: self.bounds.h.to_string(), + editing_x: true, + text_pipe, + }; + } } } - fn update_ruling(&mut self, editor: &Editor, rl: &mut RaylibHandle) { + fn update_ruling(&mut self, editor: &Editor, input: &mut Input) { // Get the currently edited dimension for processing. - let (edited_dim, editing_x) = match &mut self.state { + let (edited_dim, editing_x, text_pipe) = match &mut self.state { State::Watching => panic!("Called ruler update when in watching state"), State::Ruling { dim_x, dim_y, editing_x, + text_pipe, } => { if *editing_x { - (dim_x, editing_x) + (dim_x, editing_x, text_pipe) } else { - (dim_y, editing_x) + (dim_y, editing_x, text_pipe) } } }; - // Switch the currently edited dimension when pressing tab. - if rl.is_key_pressed(KeyboardKey::KEY_TAB) { - *editing_x = !*editing_x; - return; - } - // Finish editing mode on enter. - if rl.is_key_pressed(KeyboardKey::KEY_ENTER) { - self.state = State::Watching; - return; - } + let next_char = match text_pipe.try_recv() { + Ok(c) => c, + Err(_) => return, + }; - // Marker to see if the dimensions will have to be checked for an update. - let mut dimension_changed = false; - // Delete the last character of the dimension on backspace. - if rl.is_key_pressed(KeyboardKey::KEY_BACKSPACE) { - edited_dim.pop(); - dimension_changed = true; - } - /* Capture the current key and try to add it to the string of the current dimension, - * if possible. - */ - else if let Some(key) = rl.get_key_pressed() { - match key { - // Add a decimal point to the dimension if possible. - KeyboardKey::KEY_PERIOD => { - if !edited_dim.contains('.') { - edited_dim.push('.'); + let update_bounds = match next_char { + '\t' => { + // Switch the currently edited dimension when pressing tab. + *editing_x = !*editing_x; + return; + } + '\n' => { + // Finish editing mode on enter. + self.state = State::Watching; + return; + } + '\x7f' => { + // Delete last char on backspace + edited_dim.pop(); + true + } + key => { + match key { + // Add a decimal point to the dimension if possible. + '.' => { + if !edited_dim.contains('.') { + edited_dim.push('.'); + } + // Nothing changed here, since there is an implicit .0 at the end. + false } - // Nothing changed here, since there is an implicit .0 at the end. - } - // Handle the entered key if it is a number to append it to the currently edited dimension. - _ => { - if key as u16 >= KeyboardKey::KEY_ZERO as u16 - && key as u16 <= KeyboardKey::KEY_NINE as u16 - { - edited_dim.push(key as u8 as char); - dimension_changed = true; + // Handle the entered key if it is a number to append it to the currently edited dimension. + '0'..='9' => { + edited_dim.push(key); + true } + _ => false, } - }; - } + } + }; - if dimension_changed { + if update_bounds { /* Try to parse the dimension from the currently edited string. If it * is valid, change the dimensions of the currently selected items. If * not, ignore the change and wait for a valid dimension. @@ -185,7 +182,7 @@ impl DimensionIndicator { Rect::new(self.bounds.x, self.bounds.y, self.bounds.h, dim) }; - self.set_bounds(editor, new_bounds); + self.set_bounds(editor, dbg!(new_bounds)); } } } @@ -306,3 +303,9 @@ impl DimensionIndicator { } } } + +impl Default for State { + fn default() -> Self { + Self::Watching + } +} |
