use zng_unit::FactorUnits;
use super::{
DipPoint, DipRect, DipSideOffsets, DipSize, DipVector, Factor, FactorPercent, PxPoint, PxRect, PxSideOffsets, PxSize, PxVector, Size,
};
use std::{fmt, ops};
use zng_var::impl_from_and_into_var;
impl ops::Mul<Factor> for Factor2d {
type Output = Factor2d;
fn mul(self, rhs: Factor) -> Factor2d {
Factor2d::new(self.x * rhs, self.y * rhs)
}
}
impl ops::Div<Factor> for Factor2d {
type Output = Factor2d;
fn div(self, rhs: Factor) -> Factor2d {
Factor2d::new(self.x / rhs, self.y / rhs)
}
}
impl ops::MulAssign<Factor> for Factor2d {
fn mul_assign(&mut self, rhs: Factor) {
*self = *self * rhs;
}
}
impl ops::DivAssign<Factor> for Factor2d {
fn div_assign(&mut self, rhs: Factor) {
*self = *self / rhs;
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Factor2d {
pub x: Factor,
pub y: Factor,
}
impl_from_and_into_var! {
fn from<X: Into<Factor>, Y: Into<Factor>>((x, y): (X, Y)) -> Factor2d {
Factor2d { x: x.into(), y: y.into() }
}
fn from(xy: Factor) -> Factor2d {
Factor2d { x: xy, y: xy }
}
fn from(xy: FactorPercent) -> Factor2d {
xy.fct().into()
}
fn from(scale: Factor2d) -> Size {
Size {
width: scale.x.into(),
height: scale.y.into(),
}
}
}
impl Factor2d {
pub fn new(x: impl Into<Factor>, y: impl Into<Factor>) -> Self {
Factor2d { x: x.into(), y: y.into() }
}
pub fn uniform(xy: impl Into<Factor>) -> Self {
let xy = xy.into();
xy.into()
}
pub fn identity() -> Self {
Self::uniform(1.0)
}
pub fn is_uniform(self) -> bool {
self.x == self.y
}
pub fn abs(mut self) -> Self {
self.x = self.x.abs();
self.y = self.y.abs();
self
}
pub fn yx(self) -> Self {
Self::new(self.y, self.x)
}
}
impl fmt::Display for Factor2d {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if self.is_uniform() {
write!(f, "{}", FactorPercent::from(self.x))
} else {
write!(f, "({}, {})", FactorPercent::from(self.x), FactorPercent::from(self.y))
}
}
}
impl ops::Mul<Factor2d> for PxSize {
type Output = PxSize;
fn mul(self, rhs: Factor2d) -> PxSize {
PxSize::new(self.width * rhs.x, self.height * rhs.y)
}
}
impl ops::Mul<Factor2d> for DipSize {
type Output = DipSize;
fn mul(self, rhs: Factor2d) -> DipSize {
DipSize::new(self.width * rhs.x, self.height * rhs.y)
}
}
impl ops::Div<Factor2d> for PxSize {
type Output = PxSize;
fn div(self, rhs: Factor2d) -> PxSize {
PxSize::new(self.width / rhs.x, self.height / rhs.y)
}
}
impl ops::Div<Factor2d> for DipSize {
type Output = DipSize;
fn div(self, rhs: Factor2d) -> DipSize {
DipSize::new(self.width / rhs.x, self.height / rhs.y)
}
}
impl ops::MulAssign<Factor2d> for PxSize {
fn mul_assign(&mut self, rhs: Factor2d) {
*self = *self * rhs;
}
}
impl ops::MulAssign<Factor2d> for DipSize {
fn mul_assign(&mut self, rhs: Factor2d) {
*self = *self * rhs;
}
}
impl ops::DivAssign<Factor2d> for PxSize {
fn div_assign(&mut self, rhs: Factor2d) {
*self = *self / rhs;
}
}
impl ops::DivAssign<Factor2d> for DipSize {
fn div_assign(&mut self, rhs: Factor2d) {
*self = *self / rhs;
}
}
impl ops::Mul<Factor2d> for PxPoint {
type Output = PxPoint;
fn mul(self, rhs: Factor2d) -> PxPoint {
PxPoint::new(self.x * rhs.x, self.y * rhs.y)
}
}
impl ops::Div<Factor2d> for PxPoint {
type Output = PxPoint;
fn div(self, rhs: Factor2d) -> PxPoint {
PxPoint::new(self.x / rhs.x, self.y / rhs.y)
}
}
impl ops::MulAssign<Factor2d> for PxPoint {
fn mul_assign(&mut self, rhs: Factor2d) {
*self = *self * rhs;
}
}
impl ops::DivAssign<Factor2d> for PxPoint {
fn div_assign(&mut self, rhs: Factor2d) {
*self = *self / rhs;
}
}
impl ops::Mul<Factor2d> for DipPoint {
type Output = DipPoint;
fn mul(self, rhs: Factor2d) -> DipPoint {
DipPoint::new(self.x * rhs.x, self.y * rhs.y)
}
}
impl ops::Div<Factor2d> for DipPoint {
type Output = DipPoint;
fn div(self, rhs: Factor2d) -> DipPoint {
DipPoint::new(self.x / rhs.x, self.y / rhs.y)
}
}
impl ops::MulAssign<Factor2d> for DipPoint {
fn mul_assign(&mut self, rhs: Factor2d) {
*self = *self * rhs;
}
}
impl ops::DivAssign<Factor2d> for DipPoint {
fn div_assign(&mut self, rhs: Factor2d) {
*self = *self / rhs;
}
}
impl ops::Mul<Factor2d> for PxVector {
type Output = PxVector;
fn mul(self, rhs: Factor2d) -> PxVector {
PxVector::new(self.x * rhs.x, self.y * rhs.y)
}
}
impl ops::Div<Factor2d> for PxVector {
type Output = PxVector;
fn div(self, rhs: Factor2d) -> PxVector {
PxVector::new(self.x / rhs.x, self.y / rhs.y)
}
}
impl ops::MulAssign<Factor2d> for PxVector {
fn mul_assign(&mut self, rhs: Factor2d) {
*self = *self * rhs;
}
}
impl ops::DivAssign<Factor2d> for PxVector {
fn div_assign(&mut self, rhs: Factor2d) {
*self = *self / rhs;
}
}
impl ops::Mul<Factor2d> for DipVector {
type Output = DipVector;
fn mul(self, rhs: Factor2d) -> DipVector {
DipVector::new(self.x * rhs.x, self.y * rhs.y)
}
}
impl ops::Div<Factor2d> for DipVector {
type Output = DipVector;
fn div(self, rhs: Factor2d) -> DipVector {
DipVector::new(self.x / rhs.x, self.y / rhs.y)
}
}
impl ops::MulAssign<Factor2d> for DipVector {
fn mul_assign(&mut self, rhs: Factor2d) {
*self = *self * rhs;
}
}
impl ops::DivAssign<Factor2d> for DipVector {
fn div_assign(&mut self, rhs: Factor2d) {
*self = *self / rhs;
}
}
impl ops::Mul<Factor2d> for Factor2d {
type Output = Factor2d;
fn mul(self, rhs: Factor2d) -> Factor2d {
Factor2d::new(self.x * rhs.x, self.y * rhs.y)
}
}
impl ops::Div<Factor2d> for Factor2d {
type Output = Factor2d;
fn div(self, rhs: Factor2d) -> Factor2d {
Factor2d::new(self.x / rhs.x, self.y / rhs.y)
}
}
impl ops::MulAssign<Factor2d> for Factor2d {
fn mul_assign(&mut self, rhs: Factor2d) {
*self = *self * rhs;
}
}
impl ops::DivAssign<Factor2d> for Factor2d {
fn div_assign(&mut self, rhs: Factor2d) {
*self = *self / rhs;
}
}
impl ops::Mul<Factor2d> for PxRect {
type Output = PxRect;
fn mul(self, rhs: Factor2d) -> PxRect {
PxRect::new(self.origin * rhs, self.size * rhs)
}
}
impl ops::Div<Factor2d> for PxRect {
type Output = PxRect;
fn div(self, rhs: Factor2d) -> PxRect {
PxRect::new(self.origin / rhs, self.size / rhs)
}
}
impl ops::MulAssign<Factor2d> for PxRect {
fn mul_assign(&mut self, rhs: Factor2d) {
*self = *self * rhs;
}
}
impl ops::DivAssign<Factor2d> for PxRect {
fn div_assign(&mut self, rhs: Factor2d) {
*self = *self / rhs;
}
}
impl ops::Mul<Factor2d> for DipRect {
type Output = DipRect;
fn mul(self, rhs: Factor2d) -> DipRect {
DipRect::new(self.origin * rhs, self.size * rhs)
}
}
impl ops::Div<Factor2d> for DipRect {
type Output = DipRect;
fn div(self, rhs: Factor2d) -> DipRect {
DipRect::new(self.origin / rhs, self.size / rhs)
}
}
impl ops::MulAssign<Factor2d> for DipRect {
fn mul_assign(&mut self, rhs: Factor2d) {
*self = *self * rhs;
}
}
impl ops::DivAssign<Factor2d> for DipRect {
fn div_assign(&mut self, rhs: Factor2d) {
*self = *self / rhs;
}
}
impl ops::Neg for Factor2d {
type Output = Self;
fn neg(mut self) -> Self::Output {
self.x = -self.x;
self.y = -self.y;
self
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct FactorSideOffsets {
pub top: Factor,
pub right: Factor,
pub bottom: Factor,
pub left: Factor,
}
impl FactorSideOffsets {
pub fn new(top: impl Into<Factor>, right: impl Into<Factor>, bottom: impl Into<Factor>, left: impl Into<Factor>) -> Self {
Self {
top: top.into(),
right: right.into(),
bottom: bottom.into(),
left: left.into(),
}
}
pub fn new_vh(top_bottom: impl Into<Factor>, left_right: impl Into<Factor>) -> Self {
let tb = top_bottom.into();
let lr = left_right.into();
Self::new(tb, lr, tb, lr)
}
pub fn new_all(uniform: impl Into<Factor>) -> Self {
let u = uniform.into();
Self::new(u, u, u, u)
}
pub fn zero() -> Self {
Self::new_all(0.fct())
}
pub fn one() -> Self {
Self::new_all(1.fct())
}
}
impl ops::Mul<FactorSideOffsets> for FactorSideOffsets {
type Output = FactorSideOffsets;
fn mul(self, rhs: FactorSideOffsets) -> FactorSideOffsets {
FactorSideOffsets::new(
self.top * rhs.top,
self.right * rhs.right,
self.bottom * rhs.bottom,
self.left * rhs.left,
)
}
}
impl ops::Div<FactorSideOffsets> for FactorSideOffsets {
type Output = FactorSideOffsets;
fn div(self, rhs: FactorSideOffsets) -> FactorSideOffsets {
FactorSideOffsets::new(
self.top / rhs.top,
self.right / rhs.right,
self.bottom / rhs.bottom,
self.left / rhs.left,
)
}
}
impl ops::MulAssign<FactorSideOffsets> for FactorSideOffsets {
fn mul_assign(&mut self, rhs: FactorSideOffsets) {
*self = *self * rhs;
}
}
impl ops::DivAssign<FactorSideOffsets> for FactorSideOffsets {
fn div_assign(&mut self, rhs: FactorSideOffsets) {
*self = *self / rhs;
}
}
impl ops::Mul<FactorSideOffsets> for PxSideOffsets {
type Output = PxSideOffsets;
fn mul(self, rhs: FactorSideOffsets) -> PxSideOffsets {
PxSideOffsets::new(
self.top * rhs.top,
self.right * rhs.right,
self.bottom * rhs.bottom,
self.left * rhs.left,
)
}
}
impl ops::Div<FactorSideOffsets> for PxSideOffsets {
type Output = PxSideOffsets;
fn div(self, rhs: FactorSideOffsets) -> PxSideOffsets {
PxSideOffsets::new(
self.top / rhs.top,
self.right / rhs.right,
self.bottom / rhs.bottom,
self.left / rhs.left,
)
}
}
impl ops::MulAssign<FactorSideOffsets> for PxSideOffsets {
fn mul_assign(&mut self, rhs: FactorSideOffsets) {
*self = *self * rhs;
}
}
impl ops::DivAssign<FactorSideOffsets> for PxSideOffsets {
fn div_assign(&mut self, rhs: FactorSideOffsets) {
*self = *self / rhs;
}
}
impl ops::Mul<FactorSideOffsets> for DipSideOffsets {
type Output = DipSideOffsets;
fn mul(self, rhs: FactorSideOffsets) -> DipSideOffsets {
DipSideOffsets::new(
self.top * rhs.top,
self.right * rhs.right,
self.bottom * rhs.bottom,
self.left * rhs.left,
)
}
}
impl ops::Div<FactorSideOffsets> for DipSideOffsets {
type Output = DipSideOffsets;
fn div(self, rhs: FactorSideOffsets) -> DipSideOffsets {
DipSideOffsets::new(
self.top / rhs.top,
self.right / rhs.right,
self.bottom / rhs.bottom,
self.left / rhs.left,
)
}
}
impl ops::MulAssign<FactorSideOffsets> for DipSideOffsets {
fn mul_assign(&mut self, rhs: FactorSideOffsets) {
*self = *self * rhs;
}
}
impl ops::DivAssign<FactorSideOffsets> for DipSideOffsets {
fn div_assign(&mut self, rhs: FactorSideOffsets) {
*self = *self / rhs;
}
}
impl_from_and_into_var! {
fn from(all: Factor) -> FactorSideOffsets {
FactorSideOffsets::new_all(all)
}
fn from(percent: FactorPercent) -> FactorSideOffsets {
FactorSideOffsets::new_all(percent)
}
fn from<TB: Into<Factor>, LR: Into<Factor>>((top_bottom, left_right): (TB, LR)) -> FactorSideOffsets {
FactorSideOffsets::new_vh(top_bottom, left_right)
}
fn from<T: Into<Factor>, R: Into<Factor>, B: Into<Factor>, L: Into<Factor>>(
(top, right, bottom, left): (T, R, B, L),
) -> FactorSideOffsets {
FactorSideOffsets::new(top, right, bottom, left)
}
}