gooey/interface/controller/component/
numeral.rs

1//! Numeric value controller
2
3use super::impl_kind;
4use crate::interface::controller::alignment;
5
6#[derive(Clone, Debug, PartialEq)]
7pub struct Numeral {
8  pub min       : Option <f64>,
9  pub max       : Option <f64>,
10  pub step      : f64,
11  pub format    : Format,
12  pub alignment : alignment::Horizontal
13}
14impl_kind!(Numeral);
15
16#[derive(Clone, Debug, Eq, PartialEq)]
17pub enum Format {
18  Integer,
19  Float (Option <u8>)
20}
21
22impl Numeral {
23  /// Modify the given number by the given number of steps and clamp
24  pub fn modify (&self, number : f64, steps : f64) -> f64 {
25    let mut out = number + steps * self.step;
26    self.min.map (|min| out = min.max (out));
27    self.max.map (|max| out = max.min (out));
28    out
29  }
30}
31
32impl Default for Numeral {
33  fn default() -> Self {
34    Numeral {
35      min:       None,
36      max:       None,
37      step:      1.0,
38      format:    Format::Integer,
39      alignment: alignment::Horizontal::Right
40    }
41  }
42}
43
44impl Format {
45  pub fn format_number (&self, number : f64) -> String {
46    let integer_out_of_range =
47      || log::warn!("integer format number out of range: {}", number);
48    match self {
49      Format::Integer => {
50        let integer = if number > f64::from (i32::max_value()) {
51          integer_out_of_range();
52          i32::max_value()
53        } else if number < f64::from (i32::min_value()) {
54          integer_out_of_range();
55          i32::min_value()
56        } else {
57          number.trunc() as i32
58        };
59        integer.to_string()
60      }
61      Format::Float (None) => number.to_string(),
62      Format::Float (Some (decimals)) =>
63        format!("{:.1$}", number, *decimals as usize)
64    }
65  }
66}