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    let mut out = steps.mul_add (self.step, number);
27    self.min.map (|min| out = min.max (out));
28    self.max.map (|max| out = max.min (out));
29    out
30  }
31}
32
33impl Default for Numeral {
34  fn default() -> Self {
35    Numeral {
36      min:       None,
37      max:       None,
38      step:      1.0,
39      format:    Format::Integer,
40      alignment: alignment::Horizontal::Right
41    }
42  }
43}
44
45impl Format {
46  pub fn format_number (&self, number : f64) -> String {
47    let integer_out_of_range =
48      || log::warn!("integer format number out of range: {number}");
49    match self {
50      Format::Integer => {
51        let integer = if number > f64::from (i32::MAX) {
52          integer_out_of_range();
53          i32::MAX
54        } else if number < f64::from (i32::MIN) {
55          integer_out_of_range();
56          i32::MIN
57        } else {
58          number.trunc() as i32
59        };
60        integer.to_string()
61      }
62      Format::Float (None) => number.to_string(),
63      Format::Float (Some (decimals)) =>
64        format!("{:.1$}", number, *decimals as usize)
65    }
66  }
67}