gooey-rs 0.12.1

Tile-based UI library with audio support
Documentation
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()
    }
  }
  /// Moves absolute offset by `count` units or relative offset by `count` * 1/60th
  #[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 (**horizontal + (sign as f32) * (1.0/60.0))
        NormalSigned::clamp ((sign as f32).mul_add (1.0/60.0, **horizontal))
    }
    self
  }
  /// Moves absolute offset by `count` units or relative offset by `count` * 1/60th
  #[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 (**horizontal + (sign as f32) * (1.0/60.0))
        NormalSigned::clamp ((sign as f32).mul_add (1.0/60.0, **horizontal))
    }
    self
  }
  /// Moves absolute offset by `count` units or relative offset by `count` * 1/60th
  #[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 (**vertical + (sign as f32) * (1.0/60.0))
        NormalSigned::clamp ((sign as f32).mul_add (1.0/60.0, **vertical))
    }
    self
  }
  /// Moves absolute offset by `count` units or relative offset by `count` * 1/60th
  #[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 (**vertical + (sign as f32) * (1.0/60.0))
        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 {
  /// Panics if absolute unsigned size is greater than `i32::MAX`
  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())
    }
  }
}