gooey/interface/controller/
offset.rs

1use derive_more::{From, TryInto};
2use crate::math::NormalSigned;
3use super::{size, Alignment};
4
5#[derive(Clone, Copy, Debug, Eq, PartialEq)]
6pub struct Offset {
7  pub horizontal : Signed,
8  pub vertical   : Signed
9}
10#[derive(Clone, Copy, Debug, Eq, PartialEq, From, TryInto)]
11pub enum Signed {
12  Absolute (i32),
13  Relative (NormalSigned <f32>)
14}
15
16impl Offset {
17  #[inline]
18  pub fn default_absolute() -> Self {
19    Offset { horizontal: 0.into(), vertical: 0.into() }
20  }
21  #[inline]
22  pub fn default_relative() -> Self {
23    Offset {
24      horizontal: NormalSigned::<f32>::zero().into(),
25      vertical:   NormalSigned::<f32>::zero().into()
26    }
27  }
28  /// Moves absolute offset by `count` units or relative offset by `count` *
29  /// 1/60th
30  #[inline]
31  pub fn move_right (mut self, alignment : Alignment, count : u32) -> Self {
32    let count = count as i32;
33    let sign = count * alignment.horizontal.right_sign();
34    match self.horizontal {
35      Signed::Absolute (ref mut horizontal) => *horizontal += sign,
36      Signed::Relative (ref mut horizontal) => *horizontal =
37        //NormalSigned::clamp (**horizontal + (sign as f32) * (1.0/60.0))
38        NormalSigned::clamp ((sign as f32).mul_add (1.0/60.0, **horizontal))
39    }
40    self
41  }
42  /// Moves absolute offset by `count` units or relative offset by `count` *
43  /// 1/60th
44  #[inline]
45  pub fn move_left (mut self, alignment : Alignment, count : u32) -> Self {
46    let count = count as i32;
47    let sign = count * alignment.horizontal.left_sign();
48    match self.horizontal {
49      Signed::Absolute (ref mut horizontal) => *horizontal += sign,
50      Signed::Relative (ref mut horizontal) => *horizontal =
51        //NormalSigned::clamp (**horizontal + (sign as f32) * (1.0/60.0))
52        NormalSigned::clamp ((sign as f32).mul_add (1.0/60.0, **horizontal))
53    }
54    self
55  }
56  /// Moves absolute offset by `count` units or relative offset by `count` *
57  /// 1/60th
58  #[inline]
59  pub fn move_up (mut self, alignment : Alignment, count : u32) -> Self {
60    let count = count as i32;
61    let sign = count * alignment.vertical.up_sign();
62    match self.vertical {
63      Signed::Absolute (ref mut vertical) => *vertical += sign,
64      Signed::Relative (ref mut vertical) => *vertical =
65        //NormalSigned::clamp (**vertical + (sign as f32) * (1.0/60.0))
66        NormalSigned::clamp ((sign as f32).mul_add (1.0/60.0, **vertical))
67    }
68    self
69  }
70  /// Moves absolute offset by `count` units or relative offset by `count` *
71  /// 1/60th
72  #[inline]
73  pub fn move_down (mut self, alignment : Alignment, count : u32) -> Self {
74    let count = count as i32;
75    let sign = count * alignment.vertical.down_sign();
76    match self.vertical {
77      Signed::Absolute (ref mut vertical) => *vertical += sign,
78      Signed::Relative (ref mut vertical) => *vertical =
79        //NormalSigned::clamp (**vertical + (sign as f32) * (1.0/60.0))
80        NormalSigned::clamp ((sign as f32).mul_add (1.0/60.0, **vertical))
81    }
82    self
83  }
84}
85
86impl Default for Offset {
87  fn default() -> Self {
88    Offset::default_absolute()
89  }
90}
91
92impl Signed {
93  #[inline]
94  pub fn half (self) -> Self {
95    match self {
96      Signed::Absolute (x) => Signed::Absolute (x / 2),
97      Signed::Relative (x) => Signed::Relative (x * NormalSigned::clamp (0.5))
98    }
99  }
100}
101impl std::ops::Neg for Signed {
102  type Output = Self;
103  fn neg (self) -> Self {
104    match self {
105      Signed::Absolute (x) => Signed::Absolute (-x),
106      Signed::Relative (x) => Signed::Relative (-x)
107    }
108  }
109}
110impl From <size::Unsigned> for Signed {
111  /// Panics if absolute unsigned size is greater than `i32::MAX`
112  fn from (unsigned : size::Unsigned) -> Self {
113    match unsigned {
114      size::Unsigned::Absolute (x) => {
115        assert!(x <= i32::MAX as u32);
116        Signed::Absolute (x as i32)
117      }
118      size::Unsigned::Relative (x) => Signed::Relative (x.into())
119    }
120  }
121}