use bevy_reflect::Reflect; use glam::Vec2; use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Sub, SubAssign}; /// A two dimensional "size" as defined by a width and height #[derive(Copy, Clone, PartialEq, Debug, Reflect)] #[reflect(PartialEq)] pub struct Size { pub width: T, pub height: T, } impl Size { pub fn new(width: T, height: T) -> Self { Size { width, height } } } impl Default for Size { fn default() -> Self { Self { width: Default::default(), height: Default::default(), } } } /// A rect, as defined by its "side" locations #[derive(Copy, Clone, PartialEq, Debug, Reflect)] #[reflect(PartialEq)] pub struct Rect { pub left: T, pub right: T, pub top: T, pub bottom: T, } impl Rect { pub fn all(value: T) -> Self where T: Clone, { Rect { left: value.clone(), right: value.clone(), top: value.clone(), bottom: value, } } } impl Default for Rect { fn default() -> Self { Self { left: Default::default(), right: Default::default(), top: Default::default(), bottom: Default::default(), } } } impl Add for Size where T: Add, { type Output = Size; fn add(self, rhs: Vec2) -> Self::Output { Self { width: self.width + rhs.x, height: self.height + rhs.y, } } } impl AddAssign for Size where T: AddAssign, { fn add_assign(&mut self, rhs: Vec2) { self.width += rhs.x; self.height += rhs.y; } } impl Sub for Size where T: Sub, { type Output = Size; fn sub(self, rhs: Vec2) -> Self::Output { Self { width: self.width - rhs.x, height: self.height - rhs.y, } } } impl SubAssign for Size where T: SubAssign, { fn sub_assign(&mut self, rhs: Vec2) { self.width -= rhs.x; self.height -= rhs.y; } } impl Mul for Size where T: Mul, { type Output = Size; fn mul(self, rhs: f32) -> Self::Output { Self::Output { width: self.width * rhs, height: self.height * rhs, } } } impl MulAssign for Size where T: MulAssign, { fn mul_assign(&mut self, rhs: f32) { self.width *= rhs; self.height *= rhs; } } impl Div for Size where T: Div, { type Output = Size; fn div(self, rhs: f32) -> Self::Output { Self::Output { width: self.width / rhs, height: self.height / rhs, } } } impl DivAssign for Size where T: DivAssign, { fn div_assign(&mut self, rhs: f32) { self.width /= rhs; self.height /= rhs; } } #[cfg(test)] mod tests { use super::*; #[test] fn size_ops() { type SizeF = Size; assert_eq!( SizeF::new(10., 10.) + Vec2::new(10., 10.), SizeF::new(20., 20.) ); assert_eq!( SizeF::new(20., 20.) - Vec2::new(10., 10.), SizeF::new(10., 10.) ); assert_eq!(SizeF::new(10., 10.) * 2., SizeF::new(20., 20.)); assert_eq!(SizeF::new(20., 20.) / 2., SizeF::new(10., 10.)); let mut size = SizeF::new(10., 10.); size += Vec2::new(10., 10.); assert_eq!(size, SizeF::new(20., 20.)); } }