use derive_more::{From, TryInto};
use crate::math::NormalSigned;
use super::{size, Alignment};
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub struct Offset {
pub horizontal : Signed,
pub vertical : Signed
}
#[derive(Clone, Copy, Debug, Eq, PartialEq, From, TryInto)]
pub enum Signed {
Absolute (i32),
Relative (NormalSigned <f32>)
}
impl Offset {
#[inline]
pub fn default_absolute() -> Self {
Offset { horizontal: 0.into(), vertical: 0.into() }
}
#[inline]
pub fn default_relative() -> Self {
Offset {
horizontal: NormalSigned::<f32>::zero().into(),
vertical: NormalSigned::<f32>::zero().into()
}
}
#[inline]
pub fn move_right (mut self, alignment : Alignment, count : u32) -> Self {
let count = count as i32;
let sign = count * alignment.horizontal.right_sign();
match self.horizontal {
Signed::Absolute (ref mut horizontal) => *horizontal += sign,
Signed::Relative (ref mut horizontal) => *horizontal =
NormalSigned::clamp ((sign as f32).mul_add (1.0/60.0, **horizontal))
}
self
}
#[inline]
pub fn move_left (mut self, alignment : Alignment, count : u32) -> Self {
let count = count as i32;
let sign = count * alignment.horizontal.left_sign();
match self.horizontal {
Signed::Absolute (ref mut horizontal) => *horizontal += sign,
Signed::Relative (ref mut horizontal) => *horizontal =
NormalSigned::clamp ((sign as f32).mul_add (1.0/60.0, **horizontal))
}
self
}
#[inline]
pub fn move_up (mut self, alignment : Alignment, count : u32) -> Self {
let count = count as i32;
let sign = count * alignment.vertical.up_sign();
match self.vertical {
Signed::Absolute (ref mut vertical) => *vertical += sign,
Signed::Relative (ref mut vertical) => *vertical =
NormalSigned::clamp ((sign as f32).mul_add (1.0/60.0, **vertical))
}
self
}
#[inline]
pub fn move_down (mut self, alignment : Alignment, count : u32) -> Self {
let count = count as i32;
let sign = count * alignment.vertical.down_sign();
match self.vertical {
Signed::Absolute (ref mut vertical) => *vertical += sign,
Signed::Relative (ref mut vertical) => *vertical =
NormalSigned::clamp ((sign as f32).mul_add (1.0/60.0, **vertical))
}
self
}
}
impl Default for Offset {
fn default() -> Self {
Offset::default_absolute()
}
}
impl Signed {
#[inline]
pub fn half (self) -> Self {
match self {
Signed::Absolute (x) => Signed::Absolute (x / 2),
Signed::Relative (x) => Signed::Relative (x * NormalSigned::clamp (0.5))
}
}
}
impl std::ops::Neg for Signed {
type Output = Self;
fn neg (self) -> Self {
match self {
Signed::Absolute (x) => Signed::Absolute (-x),
Signed::Relative (x) => Signed::Relative (-x)
}
}
}
impl From <size::Unsigned> for Signed {
fn from (unsigned : size::Unsigned) -> Self {
match unsigned {
size::Unsigned::Absolute (x) => {
assert!(x <= i32::MAX as u32);
Signed::Absolute (x as i32)
}
size::Unsigned::Relative (x) => Signed::Relative (x.into())
}
}
}