use crate::Rect;
#[derive(Clone, Copy, Debug, Default, PartialEq)]
pub struct Insets {
pub top: f32,
pub right: f32,
pub bottom: f32,
pub left: f32,
}
impl Insets {
pub const ZERO: Self = Self {
top: 0.0,
right: 0.0,
bottom: 0.0,
left: 0.0,
};
#[must_use]
pub const fn new(top: f32, right: f32, bottom: f32, left: f32) -> Self {
Self {
top,
right,
bottom,
left,
}
}
#[must_use]
pub fn try_from_physical_rects(window: Rect, safe: Rect, scale_factor: f32) -> Option<Self> {
let coordinates = [
window.origin.x,
window.origin.y,
window.size.width,
window.size.height,
safe.origin.x,
safe.origin.y,
safe.size.width,
safe.size.height,
];
if coordinates.iter().any(|value| !value.is_finite())
|| window.size.width <= 0.0
|| window.size.height <= 0.0
|| safe.size.width <= 0.0
|| safe.size.height <= 0.0
{
return None;
}
let safe = window.intersection(safe)?;
Some(Self::from_physical_rects(window, safe, scale_factor))
}
#[must_use]
pub fn from_physical_rects(window: Rect, safe: Rect, scale_factor: f32) -> Self {
let scale_factor = if scale_factor.is_finite() && scale_factor > 0.0 {
scale_factor
} else {
1.0
};
let width = window.size.width.max(0.0);
let height = window.size.height.max(0.0);
let safe_width = safe.size.width.max(0.0);
let safe_height = safe.size.height.max(0.0);
let left = (safe.origin.x - window.origin.x).clamp(0.0, width);
let right = (safe.origin.x + safe_width - window.origin.x).clamp(left, width);
let top = (safe.origin.y - window.origin.y).clamp(0.0, height);
let bottom = (safe.origin.y + safe_height - window.origin.y).clamp(top, height);
Self::new(
top / scale_factor,
(width - right) / scale_factor,
(height - bottom) / scale_factor,
left / scale_factor,
)
}
#[must_use]
pub const fn horizontal(self) -> f32 {
self.left + self.right
}
#[must_use]
pub const fn vertical(self) -> f32 {
self.top + self.bottom
}
}