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    }
39    self
40  }
41  /// Moves absolute offset by `count` units or relative offset by `count` *
42  /// 1/60th
43  #[inline]
44  pub fn move_left (mut self, alignment : Alignment, count : u32) -> Self {
45    let count = count as i32;
46    let sign = count * alignment.horizontal.left_sign();
47    match self.horizontal {
48      Signed::Absolute (ref mut horizontal) => *horizontal += sign,
49      Signed::Relative (ref mut horizontal) => *horizontal =
50        NormalSigned::clamp (**horizontal + (sign as f32) * (1.0/60.0))
51    }
52    self
53  }
54  /// Moves absolute offset by `count` units or relative offset by `count` *
55  /// 1/60th
56  #[inline]
57  pub fn move_up (mut self, alignment : Alignment, count : u32) -> Self {
58    let count = count as i32;
59    let sign = count * alignment.vertical.up_sign();
60    match self.vertical {
61      Signed::Absolute (ref mut vertical) => *vertical += sign,
62      Signed::Relative (ref mut vertical) => *vertical =
63        NormalSigned::clamp (**vertical + (sign as f32) * (1.0/60.0))
64    }
65    self
66  }
67  /// Moves absolute offset by `count` units or relative offset by `count` *
68  /// 1/60th
69  #[inline]
70  pub fn move_down (mut self, alignment : Alignment, count : u32) -> Self {
71    let count = count as i32;
72    let sign = count * alignment.vertical.down_sign();
73    match self.vertical {
74      Signed::Absolute (ref mut vertical) => *vertical += sign,
75      Signed::Relative (ref mut vertical) => *vertical =
76        NormalSigned::clamp (**vertical + (sign as f32) * (1.0/60.0))
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}