Skip to main content

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` * 1/60th
29  #[inline]
30  pub fn move_right (mut self, alignment : Alignment, count : u32) -> Self {
31    let count = count as i32;
32    let sign  = count * alignment.horizontal.right_sign();
33    match self.horizontal {
34      Signed::Absolute (ref mut horizontal) => *horizontal += sign,
35      Signed::Relative (ref mut horizontal) => *horizontal =
36        //NormalSigned::clamp (**horizontal + (sign as f32) * (1.0/60.0))
37        NormalSigned::clamp ((sign as f32).mul_add (1.0/60.0, **horizontal))
38    }
39    self
40  }
41  /// Moves absolute offset by `count` units or relative offset by `count` * 1/60th
42  #[inline]
43  pub fn move_left (mut self, alignment : Alignment, count : u32) -> Self {
44    let count = count as i32;
45    let sign  = count * alignment.horizontal.left_sign();
46    match self.horizontal {
47      Signed::Absolute (ref mut horizontal) => *horizontal += sign,
48      Signed::Relative (ref mut horizontal) => *horizontal =
49        //NormalSigned::clamp (**horizontal + (sign as f32) * (1.0/60.0))
50        NormalSigned::clamp ((sign as f32).mul_add (1.0/60.0, **horizontal))
51    }
52    self
53  }
54  /// Moves absolute offset by `count` units or relative offset by `count` * 1/60th
55  #[inline]
56  pub fn move_up (mut self, alignment : Alignment, count : u32) -> Self {
57    let count = count as i32;
58    let sign  = count * alignment.vertical.up_sign();
59    match self.vertical {
60      Signed::Absolute (ref mut vertical) => *vertical += sign,
61      Signed::Relative (ref mut vertical) => *vertical =
62        //NormalSigned::clamp (**vertical + (sign as f32) * (1.0/60.0))
63        NormalSigned::clamp ((sign as f32).mul_add (1.0/60.0, **vertical))
64    }
65    self
66  }
67  /// Moves absolute offset by `count` units or relative offset by `count` * 1/60th
68  #[inline]
69  pub fn move_down (mut self, alignment : Alignment, count : u32) -> Self {
70    let count = count as i32;
71    let sign  = count * alignment.vertical.down_sign();
72    match self.vertical {
73      Signed::Absolute (ref mut vertical) => *vertical += sign,
74      Signed::Relative (ref mut vertical) => *vertical =
75        //NormalSigned::clamp (**vertical + (sign as f32) * (1.0/60.0))
76        NormalSigned::clamp ((sign as f32).mul_add (1.0/60.0, **vertical))
77    }
78    self
79  }
80}
81
82impl Default for Offset {
83  fn default() -> Self {
84    Offset::default_absolute()
85  }
86}
87
88impl Signed {
89  #[inline]
90  pub fn half (self) -> Self {
91    match self {
92      Signed::Absolute (x) => Signed::Absolute (x / 2),
93      Signed::Relative (x) => Signed::Relative (x * NormalSigned::clamp (0.5))
94    }
95  }
96}
97impl std::ops::Neg for Signed {
98  type Output = Self;
99  fn neg (self) -> Self {
100    match self {
101      Signed::Absolute (x) => Signed::Absolute (-x),
102      Signed::Relative (x) => Signed::Relative (-x)
103    }
104  }
105}
106impl From <size::Unsigned> for Signed {
107  /// Panics if absolute unsigned size is greater than `i32::MAX`
108  fn from (unsigned : size::Unsigned) -> Self {
109    match unsigned {
110      size::Unsigned::Absolute (x) => {
111        assert!(x <= i32::MAX as u32);
112        Signed::Absolute (x as i32)
113      }
114      size::Unsigned::Relative (x) => Signed::Relative (x.into())
115    }
116  }
117}