use std::ops::{Add, Neg, Sub};
use crate::{Rect, Size};
#[derive(Clone, Copy, Default, Debug, PartialEq)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Insets {
pub x0: f64,
pub y0: f64,
pub x1: f64,
pub y1: f64,
}
impl Insets {
pub const ZERO: Insets = Insets::uniform(0.);
#[inline]
pub const fn uniform(d: f64) -> Insets {
Insets {
x0: d,
y0: d,
x1: d,
y1: d,
}
}
#[inline]
pub const fn uniform_xy(x: f64, y: f64) -> Insets {
Insets {
x0: x,
y0: y,
x1: x,
y1: y,
}
}
#[inline]
pub const fn new(x0: f64, y0: f64, x1: f64, y1: f64) -> Insets {
Insets { x0, y0, x1, y1 }
}
#[inline]
pub fn x_value(self) -> f64 {
self.x0 + self.x1
}
#[inline]
pub fn y_value(self) -> f64 {
self.y0 + self.y1
}
pub fn size(self) -> Size {
Size::new(self.x_value(), self.y_value())
}
pub fn are_nonnegative(self) -> bool {
let Insets { x0, y0, x1, y1 } = self;
x0 >= 0.0 && y0 >= 0.0 && x1 >= 0.0 && y1 >= 0.0
}
pub fn nonnegative(self) -> Insets {
let Insets { x0, y0, x1, y1 } = self;
Insets {
x0: x0.max(0.0),
y0: y0.max(0.0),
x1: x1.max(0.0),
y1: y1.max(0.0),
}
}
#[inline]
pub fn is_finite(&self) -> bool {
self.x0.is_finite() && self.y0.is_finite() && self.x1.is_finite() && self.y1.is_finite()
}
#[inline]
pub fn is_nan(&self) -> bool {
self.x0.is_nan() || self.y0.is_nan() || self.x1.is_nan() || self.y1.is_nan()
}
}
impl Neg for Insets {
type Output = Insets;
#[inline]
fn neg(self) -> Insets {
Insets::new(-self.x0, -self.y0, -self.x1, -self.y1)
}
}
impl Add<Rect> for Insets {
type Output = Rect;
#[inline]
#[allow(clippy::suspicious_arithmetic_impl)]
fn add(self, other: Rect) -> Rect {
let other = other.abs();
Rect::new(
other.x0 - self.x0,
other.y0 - self.y0,
other.x1 + self.x1,
other.y1 + self.y1,
)
}
}
impl Add<Insets> for Rect {
type Output = Rect;
#[inline]
fn add(self, other: Insets) -> Rect {
other + self
}
}
impl Sub<Rect> for Insets {
type Output = Rect;
#[inline]
fn sub(self, other: Rect) -> Rect {
other + -self
}
}
impl Sub<Insets> for Rect {
type Output = Rect;
#[inline]
fn sub(self, other: Insets) -> Rect {
other - self
}
}
impl From<f64> for Insets {
fn from(src: f64) -> Insets {
Insets::uniform(src)
}
}
impl From<(f64, f64)> for Insets {
fn from(src: (f64, f64)) -> Insets {
Insets::uniform_xy(src.0, src.1)
}
}
impl From<(f64, f64, f64, f64)> for Insets {
fn from(src: (f64, f64, f64, f64)) -> Insets {
Insets::new(src.0, src.1, src.2, src.3)
}
}