diff options
| author | Arne Dußin | 2021-01-27 14:01:50 +0100 |
|---|---|---|
| committer | Arne Dußin | 2021-02-02 22:16:15 +0100 |
| commit | f92e9f6f07b1e3834c2ca58ce3510734819d08e4 (patch) | |
| tree | 20e3d3afce342a56ae98f6c20491482ccd2b5c6b /src/gui/decimal_num_box.rs | |
| parent | c60a6d07efb120724b308e29e8e70f27c87c952d (diff) | |
| download | graf_karto-f92e9f6f07b1e3834c2ca58ce3510734819d08e4.tar.gz graf_karto-f92e9f6f07b1e3834c2ca58ce3510734819d08e4.zip | |
Rework graf karto to fit the client/server structure
Diffstat (limited to 'src/gui/decimal_num_box.rs')
| -rw-r--r-- | src/gui/decimal_num_box.rs | 173 |
1 files changed, 0 insertions, 173 deletions
diff --git a/src/gui/decimal_num_box.rs b/src/gui/decimal_num_box.rs deleted file mode 100644 index e9395f7..0000000 --- a/src/gui/decimal_num_box.rs +++ /dev/null @@ -1,173 +0,0 @@ -//! Functions similarly to a text-bux, but only accepts floating point (decimal) numbers -//! -//! Since a lot of functions require the user to input measurements in meters, it is useful to have a -//! singular entity that reads these in an intuitive way. Inputting of such numbers is handled in -//! this module. - -use crate::math::{self, Vec2}; -use nalgebra::RealField; -use num_traits::Pow; -use raylib::drawing::RaylibDraw; -use raylib::ffi::{Color, KeyboardKey}; -use raylib::text; -use raylib::RaylibHandle; -use std::str::FromStr; - -/// The number of decimal places that can be edited and will be shown by a decimal text field. -pub const DECIMAL_PLACES: u16 = 4; - -/// The decimal num box can handle any decimal number, like f32 or f64. Currently has a hard limit -/// of four decimal places, but that may change in the future. -pub struct DecimalNumBox<F: RealField + Pow<u16, Output = F> + FromStr> { - input: String, - last_value: F, - active: bool, -} - -impl<F: RealField + Pow<u16, Output = F> + FromStr> DecimalNumBox<F> { - /// Create a new Number box showing the value specified. Should the value have more then the - /// maximum number of decimal places, it will be rounded. - pub fn new(value: F) -> Self { - let value = math::round_nth_decimal(value, DECIMAL_PLACES); - let input = format!("{:.4}", value); - - Self { - input, - last_value: value, - active: false, - } - } - - /// Get the value entered by the user. If the user has something that cannot be parsed into a - /// decimal value, this differs from the string that is shown and is instead the last value - /// entered by the user that is still a valid decimal number. - pub fn value(&self) -> F { - self.last_value - } - - /// Set the value directly. This may only be done, if the box is currently not active, to protect - /// user input. Returns true if the value could be set, otherwise false. - pub fn set_value(&mut self, value: F) -> bool { - if !self.active { - self.last_value = math::round_nth_decimal(value, DECIMAL_PLACES); - // XXX: Don't use the magical 4 - self.input = format!("{:.4}", self.last_value); - true - } else { - false - } - } - - /// Check if this number box is currently active. Active means, it's capturing keyboard input. - /// If it's not active, it does not attempt to capture any keystrokes. - pub fn active(&self) -> bool { - self.active - } - - /// Set if the box is active (capturing keyboard input and adjusting it's value accordingly) or - /// not. - pub fn set_active(&mut self, active: bool) { - self.active = active - } - - /// Update this decimal box. If it is inactive, this doesn't do anything, but if it is active, it - /// captures the keyboard input, if available. Returns `true`, if the value changed, otherwise - /// `false`. Note that the string that is displayed may change, but the value does not have to. - /// This happens, if the user types something invalid. In this case, `false` is returned as well. - pub fn update(&mut self, rl: &mut RaylibHandle) -> bool { - /* If the box is currently inactive, nothing must be changed, and this function will do - * nothing. - */ - if !self.active { - return false; - } - - // TODO: Check for movement keys. - - // Delete the last character when pressing backspace. - let string_changed = if rl.is_key_pressed(KeyboardKey::KEY_BACKSPACE) { - self.input.pop().is_some() - } - // Check the entered numbers or decimal point. - else if let Some(key) = rl.get_key_pressed() { - match key { - // Add (at most one) decimal point to the input when entering a dot. - KeyboardKey::KEY_PERIOD => { - if !self.input.contains('.') { - self.input.push('.'); - true - } else { - false - } - } - _ => { - if key as u16 >= KeyboardKey::KEY_ZERO as u16 - && key as u16 <= KeyboardKey::KEY_NINE as u16 - { - self.input.push(key as u8 as char); - true - } else { - false - } - } - } - } else { - false - }; - - if string_changed { - // Try to parse the new string. If it doesn't work, keep the old one. - match self.input.parse::<F>() { - Ok(value) => { - let value = math::round_nth_decimal(value, DECIMAL_PLACES); - if value != self.last_value { - self.last_value = value; - true - } else { - false - } - } - Err(_) => false, - } - } else { - false - } - } - - /// Draw the number box at the given position. the `unit` parameter is used to append this text, - /// let's say for instance 'm' for meters to the text drawn to screen. Most of the time, a unit - /// makes sense to show on this number box, otherwise it can be left as an empty string. The unit - /// has no relevance to internal processes and cannot be edited by the user. - pub fn draw(&self, rld: &mut impl RaylibDraw, unit: &str, pos: &Vec2<f64>) { - let text = format!("{}{}", self.input, unit); - let width = text::measure_text(&text, 20); - - // Draw background to highlight this box if it's active. - if self.active { - rld.draw_rectangle_v( - *pos - Vec2::new(5., 5.), - Vec2::new(width as f32 + 10., 20. + 10.), - Color { - r: 120, - g: 120, - b: 120, - a: 180, - }, - ); - } - - // Draw the text of the box. - rld.draw_text( - &text, - pos.x as i32, - pos.y as i32, - 20, - Color { - r: 255, - g: 255, - b: 255, - a: 255, - }, - ) - } -} |
