geometry.rs

   1//! The GPUI geometry module is a collection of types and traits that
   2//! can be used to describe common units, concepts, and the relationships
   3//! between them.
   4
   5use core::fmt::Debug;
   6use derive_more::{Add, AddAssign, Div, DivAssign, Mul, Neg, Sub, SubAssign};
   7use refineable::Refineable;
   8use serde_derive::{Deserialize, Serialize};
   9use std::{
  10    cmp::{self, PartialOrd},
  11    fmt,
  12    hash::Hash,
  13    ops::{Add, Div, Mul, MulAssign, Sub},
  14};
  15
  16use crate::AppContext;
  17
  18/// An axis along which a measurement can be made.
  19#[derive(Copy, Clone, PartialEq, Eq, Debug)]
  20pub enum Axis {
  21    /// The y axis, or up and down
  22    Vertical,
  23    /// The x axis, or left and right
  24    Horizontal,
  25}
  26
  27impl Axis {
  28    /// Swap this axis to the opposite axis.
  29    pub fn invert(&self) -> Self {
  30        match self {
  31            Axis::Vertical => Axis::Horizontal,
  32            Axis::Horizontal => Axis::Vertical,
  33        }
  34    }
  35}
  36
  37/// A trait for accessing the given unit along a certain axis.
  38pub trait Along {
  39    /// The unit associated with this type
  40    type Unit;
  41
  42    /// Returns the unit along the given axis.
  43    fn along(&self, axis: Axis) -> Self::Unit;
  44
  45    /// Applies the given function to the unit along the given axis and returns a new value.
  46    fn apply_along(&self, axis: Axis, f: impl FnOnce(Self::Unit) -> Self::Unit) -> Self;
  47}
  48
  49/// Describes a location in a 2D cartesian coordinate space.
  50///
  51/// It holds two public fields, `x` and `y`, which represent the coordinates in the space.
  52/// The type `T` for the coordinates can be any type that implements `Default`, `Clone`, and `Debug`.
  53///
  54/// # Examples
  55///
  56/// ```
  57/// # use zed::Point;
  58/// let point = Point { x: 10, y: 20 };
  59/// println!("{:?}", point); // Outputs: Point { x: 10, y: 20 }
  60/// ```
  61#[derive(Refineable, Default, Add, AddAssign, Sub, SubAssign, Copy, Debug, PartialEq, Eq, Hash)]
  62#[refineable(Debug)]
  63#[repr(C)]
  64pub struct Point<T: Default + Clone + Debug> {
  65    /// The x coordinate of the point.
  66    pub x: T,
  67    /// The y coordinate of the point.
  68    pub y: T,
  69}
  70
  71/// Constructs a new `Point<T>` with the given x and y coordinates.
  72///
  73/// # Arguments
  74///
  75/// * `x` - The x coordinate of the point.
  76/// * `y` - The y coordinate of the point.
  77///
  78/// # Returns
  79///
  80/// Returns a `Point<T>` with the specified coordinates.
  81///
  82/// # Examples
  83///
  84/// ```
  85/// # use zed::Point;
  86/// let p = point(10, 20);
  87/// assert_eq!(p.x, 10);
  88/// assert_eq!(p.y, 20);
  89/// ```
  90pub const fn point<T: Clone + Debug + Default>(x: T, y: T) -> Point<T> {
  91    Point { x, y }
  92}
  93
  94impl<T: Clone + Debug + Default> Point<T> {
  95    /// Creates a new `Point` with the specified `x` and `y` coordinates.
  96    ///
  97    /// # Arguments
  98    ///
  99    /// * `x` - The horizontal coordinate of the point.
 100    /// * `y` - The vertical coordinate of the point.
 101    ///
 102    /// # Examples
 103    ///
 104    /// ```
 105    /// let p = Point::new(10, 20);
 106    /// assert_eq!(p.x, 10);
 107    /// assert_eq!(p.y, 20);
 108    /// ```
 109    pub const fn new(x: T, y: T) -> Self {
 110        Self { x, y }
 111    }
 112
 113    /// Transforms the point to a `Point<U>` by applying the given function to both coordinates.
 114    ///
 115    /// This method allows for converting a `Point<T>` to a `Point<U>` by specifying a closure
 116    /// that defines how to convert between the two types. The closure is applied to both the `x`
 117    /// and `y` coordinates, resulting in a new point of the desired type.
 118    ///
 119    /// # Arguments
 120    ///
 121    /// * `f` - A closure that takes a value of type `T` and returns a value of type `U`.
 122    ///
 123    /// # Examples
 124    ///
 125    /// ```
 126    /// # use zed::Point;
 127    /// let p = Point { x: 3, y: 4 };
 128    /// let p_float = p.map(|coord| coord as f32);
 129    /// assert_eq!(p_float, Point { x: 3.0, y: 4.0 });
 130    /// ```
 131    pub fn map<U: Clone + Default + Debug>(&self, f: impl Fn(T) -> U) -> Point<U> {
 132        Point {
 133            x: f(self.x.clone()),
 134            y: f(self.y.clone()),
 135        }
 136    }
 137}
 138
 139impl<T: Clone + Debug + Default> Along for Point<T> {
 140    type Unit = T;
 141
 142    fn along(&self, axis: Axis) -> T {
 143        match axis {
 144            Axis::Horizontal => self.x.clone(),
 145            Axis::Vertical => self.y.clone(),
 146        }
 147    }
 148
 149    fn apply_along(&self, axis: Axis, f: impl FnOnce(T) -> T) -> Point<T> {
 150        match axis {
 151            Axis::Horizontal => Point {
 152                x: f(self.x.clone()),
 153                y: self.y.clone(),
 154            },
 155            Axis::Vertical => Point {
 156                x: self.x.clone(),
 157                y: f(self.y.clone()),
 158            },
 159        }
 160    }
 161}
 162
 163impl Point<Pixels> {
 164    /// Scales the point by a given factor, which is typically derived from the resolution
 165    /// of a target display to ensure proper sizing of UI elements.
 166    ///
 167    /// # Arguments
 168    ///
 169    /// * `factor` - The scaling factor to apply to both the x and y coordinates.
 170    ///
 171    /// # Examples
 172    ///
 173    /// ```
 174    /// # use zed::{Point, Pixels, ScaledPixels};
 175    /// let p = Point { x: Pixels(10.0), y: Pixels(20.0) };
 176    /// let scaled_p = p.scale(1.5);
 177    /// assert_eq!(scaled_p, Point { x: ScaledPixels(15.0), y: ScaledPixels(30.0) });
 178    /// ```
 179    pub fn scale(&self, factor: f32) -> Point<ScaledPixels> {
 180        Point {
 181            x: self.x.scale(factor),
 182            y: self.y.scale(factor),
 183        }
 184    }
 185
 186    /// Calculates the Euclidean distance from the origin (0, 0) to this point.
 187    ///
 188    /// # Examples
 189    ///
 190    /// ```
 191    /// # use zed::Point;
 192    /// # use zed::Pixels;
 193    /// let p = Point { x: Pixels(3.0), y: Pixels(4.0) };
 194    /// assert_eq!(p.magnitude(), 5.0);
 195    /// ```
 196    pub fn magnitude(&self) -> f64 {
 197        ((self.x.0.powi(2) + self.y.0.powi(2)) as f64).sqrt()
 198    }
 199}
 200
 201impl<T, Rhs> Mul<Rhs> for Point<T>
 202where
 203    T: Mul<Rhs, Output = T> + Clone + Default + Debug,
 204    Rhs: Clone + Debug,
 205{
 206    type Output = Point<T>;
 207
 208    fn mul(self, rhs: Rhs) -> Self::Output {
 209        Point {
 210            x: self.x * rhs.clone(),
 211            y: self.y * rhs,
 212        }
 213    }
 214}
 215
 216impl<T, S> MulAssign<S> for Point<T>
 217where
 218    T: Clone + Mul<S, Output = T> + Default + Debug,
 219    S: Clone,
 220{
 221    fn mul_assign(&mut self, rhs: S) {
 222        self.x = self.x.clone() * rhs.clone();
 223        self.y = self.y.clone() * rhs;
 224    }
 225}
 226
 227impl<T, S> Div<S> for Point<T>
 228where
 229    T: Div<S, Output = T> + Clone + Default + Debug,
 230    S: Clone,
 231{
 232    type Output = Self;
 233
 234    fn div(self, rhs: S) -> Self::Output {
 235        Self {
 236            x: self.x / rhs.clone(),
 237            y: self.y / rhs,
 238        }
 239    }
 240}
 241
 242impl<T> Point<T>
 243where
 244    T: PartialOrd + Clone + Default + Debug,
 245{
 246    /// Returns a new point with the maximum values of each dimension from `self` and `other`.
 247    ///
 248    /// # Arguments
 249    ///
 250    /// * `other` - A reference to another `Point` to compare with `self`.
 251    ///
 252    /// # Examples
 253    ///
 254    /// ```
 255    /// # use zed::Point;
 256    /// let p1 = Point { x: 3, y: 7 };
 257    /// let p2 = Point { x: 5, y: 2 };
 258    /// let max_point = p1.max(&p2);
 259    /// assert_eq!(max_point, Point { x: 5, y: 7 });
 260    /// ```
 261    pub fn max(&self, other: &Self) -> Self {
 262        Point {
 263            x: if self.x > other.x {
 264                self.x.clone()
 265            } else {
 266                other.x.clone()
 267            },
 268            y: if self.y > other.y {
 269                self.y.clone()
 270            } else {
 271                other.y.clone()
 272            },
 273        }
 274    }
 275
 276    /// Returns a new point with the minimum values of each dimension from `self` and `other`.
 277    ///
 278    /// # Arguments
 279    ///
 280    /// * `other` - A reference to another `Point` to compare with `self`.
 281    ///
 282    /// # Examples
 283    ///
 284    /// ```
 285    /// # use zed::Point;
 286    /// let p1 = Point { x: 3, y: 7 };
 287    /// let p2 = Point { x: 5, y: 2 };
 288    /// let min_point = p1.min(&p2);
 289    /// assert_eq!(min_point, Point { x: 3, y: 2 });
 290    /// ```
 291    pub fn min(&self, other: &Self) -> Self {
 292        Point {
 293            x: if self.x <= other.x {
 294                self.x.clone()
 295            } else {
 296                other.x.clone()
 297            },
 298            y: if self.y <= other.y {
 299                self.y.clone()
 300            } else {
 301                other.y.clone()
 302            },
 303        }
 304    }
 305
 306    /// Clamps the point to a specified range.
 307    ///
 308    /// Given a minimum point and a maximum point, this method constrains the current point
 309    /// such that its coordinates do not exceed the range defined by the minimum and maximum points.
 310    /// If the current point's coordinates are less than the minimum, they are set to the minimum.
 311    /// If they are greater than the maximum, they are set to the maximum.
 312    ///
 313    /// # Arguments
 314    ///
 315    /// * `min` - A reference to a `Point` representing the minimum allowable coordinates.
 316    /// * `max` - A reference to a `Point` representing the maximum allowable coordinates.
 317    ///
 318    /// # Examples
 319    ///
 320    /// ```
 321    /// # use zed::Point;
 322    /// let p = Point { x: 10, y: 20 };
 323    /// let min = Point { x: 0, y: 5 };
 324    /// let max = Point { x: 15, y: 25 };
 325    /// let clamped_p = p.clamp(&min, &max);
 326    /// assert_eq!(clamped_p, Point { x: 10, y: 20 });
 327    ///
 328    /// let p_out_of_bounds = Point { x: -5, y: 30 };
 329    /// let clamped_p_out_of_bounds = p_out_of_bounds.clamp(&min, &max);
 330    /// assert_eq!(clamped_p_out_of_bounds, Point { x: 0, y: 25 });
 331    /// ```
 332    pub fn clamp(&self, min: &Self, max: &Self) -> Self {
 333        self.max(min).min(max)
 334    }
 335}
 336
 337impl<T: Clone + Default + Debug> Clone for Point<T> {
 338    fn clone(&self) -> Self {
 339        Self {
 340            x: self.x.clone(),
 341            y: self.y.clone(),
 342        }
 343    }
 344}
 345
 346/// A structure representing a two-dimensional size with width and height in a given unit.
 347///
 348/// This struct is generic over the type `T`, which can be any type that implements `Clone`, `Default`, and `Debug`.
 349/// It is commonly used to specify dimensions for elements in a UI, such as a window or element.
 350#[derive(Refineable, Default, Clone, Copy, PartialEq, Div, Hash, Serialize, Deserialize)]
 351#[refineable(Debug)]
 352#[repr(C)]
 353pub struct Size<T: Clone + Default + Debug> {
 354    /// The width component of the size.
 355    pub width: T,
 356    /// The height component of the size.
 357    pub height: T,
 358}
 359
 360impl From<Size<GlobalPixels>> for Size<Pixels> {
 361    fn from(size: Size<GlobalPixels>) -> Self {
 362        Size {
 363            width: Pixels(size.width.0),
 364            height: Pixels(size.height.0),
 365        }
 366    }
 367}
 368
 369/// Constructs a new `Size<T>` with the provided width and height.
 370///
 371/// # Arguments
 372///
 373/// * `width` - The width component of the `Size`.
 374/// * `height` - The height component of the `Size`.
 375///
 376/// # Examples
 377///
 378/// ```
 379/// # use zed::Size;
 380/// let my_size = size(10, 20);
 381/// assert_eq!(my_size.width, 10);
 382/// assert_eq!(my_size.height, 20);
 383/// ```
 384pub const fn size<T>(width: T, height: T) -> Size<T>
 385where
 386    T: Clone + Default + Debug,
 387{
 388    Size { width, height }
 389}
 390
 391impl<T> Size<T>
 392where
 393    T: Clone + Default + Debug,
 394{
 395    /// Applies a function to the width and height of the size, producing a new `Size<U>`.
 396    ///
 397    /// This method allows for converting a `Size<T>` to a `Size<U>` by specifying a closure
 398    /// that defines how to convert between the two types. The closure is applied to both the `width`
 399    /// and `height`, resulting in a new size of the desired type.
 400    ///
 401    /// # Arguments
 402    ///
 403    /// * `f` - A closure that takes a value of type `T` and returns a value of type `U`.
 404    ///
 405    /// # Examples
 406    ///
 407    /// ```
 408    /// # use zed::Size;
 409    /// let my_size = Size { width: 10, height: 20 };
 410    /// let my_new_size = my_size.map(|dimension| dimension as f32 * 1.5);
 411    /// assert_eq!(my_new_size, Size { width: 15.0, height: 30.0 });
 412    /// ```
 413    pub fn map<U>(&self, f: impl Fn(T) -> U) -> Size<U>
 414    where
 415        U: Clone + Default + Debug,
 416    {
 417        Size {
 418            width: f(self.width.clone()),
 419            height: f(self.height.clone()),
 420        }
 421    }
 422}
 423
 424impl Size<Pixels> {
 425    /// Scales the size by a given factor.
 426    ///
 427    /// This method multiplies both the width and height by the provided scaling factor,
 428    /// resulting in a new `Size<ScaledPixels>` that is proportionally larger or smaller
 429    /// depending on the factor.
 430    ///
 431    /// # Arguments
 432    ///
 433    /// * `factor` - The scaling factor to apply to the width and height.
 434    ///
 435    /// # Examples
 436    ///
 437    /// ```
 438    /// # use zed::{Size, Pixels, ScaledPixels};
 439    /// let size = Size { width: Pixels(100.0), height: Pixels(50.0) };
 440    /// let scaled_size = size.scale(2.0);
 441    /// assert_eq!(scaled_size, Size { width: ScaledPixels(200.0), height: ScaledPixels(100.0) });
 442    /// ```
 443    pub fn scale(&self, factor: f32) -> Size<ScaledPixels> {
 444        Size {
 445            width: self.width.scale(factor),
 446            height: self.height.scale(factor),
 447        }
 448    }
 449}
 450
 451impl<T> Along for Size<T>
 452where
 453    T: Clone + Default + Debug,
 454{
 455    type Unit = T;
 456
 457    fn along(&self, axis: Axis) -> T {
 458        match axis {
 459            Axis::Horizontal => self.width.clone(),
 460            Axis::Vertical => self.height.clone(),
 461        }
 462    }
 463
 464    /// Returns the value of this size along the given axis.
 465    fn apply_along(&self, axis: Axis, f: impl FnOnce(T) -> T) -> Self {
 466        match axis {
 467            Axis::Horizontal => Size {
 468                width: f(self.width.clone()),
 469                height: self.height.clone(),
 470            },
 471            Axis::Vertical => Size {
 472                width: self.width.clone(),
 473                height: f(self.height.clone()),
 474            },
 475        }
 476    }
 477}
 478
 479impl<T> Size<T>
 480where
 481    T: PartialOrd + Clone + Default + Debug,
 482{
 483    /// Returns a new `Size` with the maximum width and height from `self` and `other`.
 484    ///
 485    /// # Arguments
 486    ///
 487    /// * `other` - A reference to another `Size` to compare with `self`.
 488    ///
 489    /// # Examples
 490    ///
 491    /// ```
 492    /// # use zed::Size;
 493    /// let size1 = Size { width: 30, height: 40 };
 494    /// let size2 = Size { width: 50, height: 20 };
 495    /// let max_size = size1.max(&size2);
 496    /// assert_eq!(max_size, Size { width: 50, height: 40 });
 497    /// ```
 498    pub fn max(&self, other: &Self) -> Self {
 499        Size {
 500            width: if self.width >= other.width {
 501                self.width.clone()
 502            } else {
 503                other.width.clone()
 504            },
 505            height: if self.height >= other.height {
 506                self.height.clone()
 507            } else {
 508                other.height.clone()
 509            },
 510        }
 511    }
 512}
 513
 514impl<T> Sub for Size<T>
 515where
 516    T: Sub<Output = T> + Clone + Default + Debug,
 517{
 518    type Output = Size<T>;
 519
 520    fn sub(self, rhs: Self) -> Self::Output {
 521        Size {
 522            width: self.width - rhs.width,
 523            height: self.height - rhs.height,
 524        }
 525    }
 526}
 527
 528impl<T> Add for Size<T>
 529where
 530    T: Add<Output = T> + Clone + Default + Debug,
 531{
 532    type Output = Size<T>;
 533
 534    fn add(self, rhs: Self) -> Self::Output {
 535        Size {
 536            width: self.width + rhs.width,
 537            height: self.height + rhs.height,
 538        }
 539    }
 540}
 541
 542impl<T, Rhs> Mul<Rhs> for Size<T>
 543where
 544    T: Mul<Rhs, Output = Rhs> + Clone + Default + Debug,
 545    Rhs: Clone + Default + Debug,
 546{
 547    type Output = Size<Rhs>;
 548
 549    fn mul(self, rhs: Rhs) -> Self::Output {
 550        Size {
 551            width: self.width * rhs.clone(),
 552            height: self.height * rhs,
 553        }
 554    }
 555}
 556
 557impl<T, S> MulAssign<S> for Size<T>
 558where
 559    T: Mul<S, Output = T> + Clone + Default + Debug,
 560    S: Clone,
 561{
 562    fn mul_assign(&mut self, rhs: S) {
 563        self.width = self.width.clone() * rhs.clone();
 564        self.height = self.height.clone() * rhs;
 565    }
 566}
 567
 568impl<T> Eq for Size<T> where T: Eq + Default + Debug + Clone {}
 569
 570impl<T> Debug for Size<T>
 571where
 572    T: Clone + Default + Debug,
 573{
 574    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 575        write!(f, "Size {{ {:?} × {:?} }}", self.width, self.height)
 576    }
 577}
 578
 579impl<T: Clone + Default + Debug> From<Point<T>> for Size<T> {
 580    fn from(point: Point<T>) -> Self {
 581        Self {
 582            width: point.x,
 583            height: point.y,
 584        }
 585    }
 586}
 587
 588impl From<Size<Pixels>> for Size<GlobalPixels> {
 589    fn from(size: Size<Pixels>) -> Self {
 590        Size {
 591            width: GlobalPixels(size.width.0),
 592            height: GlobalPixels(size.height.0),
 593        }
 594    }
 595}
 596
 597impl From<Size<Pixels>> for Size<DefiniteLength> {
 598    fn from(size: Size<Pixels>) -> Self {
 599        Size {
 600            width: size.width.into(),
 601            height: size.height.into(),
 602        }
 603    }
 604}
 605
 606impl From<Size<Pixels>> for Size<AbsoluteLength> {
 607    fn from(size: Size<Pixels>) -> Self {
 608        Size {
 609            width: size.width.into(),
 610            height: size.height.into(),
 611        }
 612    }
 613}
 614
 615impl Size<Length> {
 616    /// Returns a `Size` with both width and height set to fill the available space.
 617    ///
 618    /// This function creates a `Size` instance where both the width and height are set to `Length::Definite(DefiniteLength::Fraction(1.0))`,
 619    /// which represents 100% of the available space in both dimensions.
 620    ///
 621    /// # Returns
 622    ///
 623    /// A `Size<Length>` that will fill the available space when used in a layout.
 624    pub fn full() -> Self {
 625        Self {
 626            width: relative(1.).into(),
 627            height: relative(1.).into(),
 628        }
 629    }
 630}
 631
 632impl Size<Length> {
 633    /// Returns a `Size` with both width and height set to `auto`, which allows the layout engine to determine the size.
 634    ///
 635    /// This function creates a `Size` instance where both the width and height are set to `Length::Auto`,
 636    /// indicating that their size should be computed based on the layout context, such as the content size or
 637    /// available space.
 638    ///
 639    /// # Returns
 640    ///
 641    /// A `Size<Length>` with width and height set to `Length::Auto`.
 642    pub fn auto() -> Self {
 643        Self {
 644            width: Length::Auto,
 645            height: Length::Auto,
 646        }
 647    }
 648}
 649
 650/// Represents a rectangular area in a 2D space with an origin point and a size.
 651///
 652/// The `Bounds` struct is generic over a type `T` which represents the type of the coordinate system.
 653/// The origin is represented as a `Point<T>` which defines the upper-left corner of the rectangle,
 654/// and the size is represented as a `Size<T>` which defines the width and height of the rectangle.
 655///
 656/// # Examples
 657///
 658/// ```
 659/// # use zed::{Bounds, Point, Size};
 660/// let origin = Point { x: 0, y: 0 };
 661/// let size = Size { width: 10, height: 20 };
 662/// let bounds = Bounds::new(origin, size);
 663///
 664/// assert_eq!(bounds.origin, origin);
 665/// assert_eq!(bounds.size, size);
 666/// ```
 667#[derive(Refineable, Clone, Default, Debug, Eq, PartialEq)]
 668#[refineable(Debug)]
 669#[repr(C)]
 670pub struct Bounds<T: Clone + Default + Debug> {
 671    /// The origin point of this area.
 672    pub origin: Point<T>,
 673    /// The size of the rectangle.
 674    pub size: Size<T>,
 675}
 676
 677impl Bounds<GlobalPixels> {
 678    /// Generate a centered bounds for the primary display
 679    pub fn centered(size: impl Into<Size<GlobalPixels>>, cx: &mut AppContext) -> Self {
 680        let size = size.into();
 681        cx.primary_display()
 682            .map(|display| {
 683                let center = display.bounds().center();
 684                Bounds {
 685                    origin: point(center.x - size.width / 2.0, center.y - size.height / 2.0),
 686                    size,
 687                }
 688            })
 689            .unwrap_or_else(|| Bounds {
 690                origin: point(GlobalPixels(0.0), GlobalPixels(0.0)),
 691                size,
 692            })
 693    }
 694
 695    /// Generate maximized bounds for the primary display
 696    pub fn maximized(cx: &mut AppContext) -> Self {
 697        cx.primary_display()
 698            .map(|display| display.bounds())
 699            .unwrap_or_else(|| Bounds {
 700                origin: point(GlobalPixels(0.0), GlobalPixels(0.0)),
 701                size: size(GlobalPixels(1024.0), GlobalPixels(768.0)),
 702            })
 703    }
 704}
 705
 706impl<T> Bounds<T>
 707where
 708    T: Clone + Debug + Sub<Output = T> + Default,
 709{
 710    /// Constructs a `Bounds` from two corner points: the upper-left and lower-right corners.
 711    ///
 712    /// This function calculates the origin and size of the `Bounds` based on the provided corner points.
 713    /// The origin is set to the upper-left corner, and the size is determined by the difference between
 714    /// the x and y coordinates of the lower-right and upper-left points.
 715    ///
 716    /// # Arguments
 717    ///
 718    /// * `upper_left` - A `Point<T>` representing the upper-left corner of the rectangle.
 719    /// * `lower_right` - A `Point<T>` representing the lower-right corner of the rectangle.
 720    ///
 721    /// # Returns
 722    ///
 723    /// Returns a `Bounds<T>` that encompasses the area defined by the two corner points.
 724    ///
 725    /// # Examples
 726    ///
 727    /// ```
 728    /// # use zed::{Bounds, Point};
 729    /// let upper_left = Point { x: 0, y: 0 };
 730    /// let lower_right = Point { x: 10, y: 10 };
 731    /// let bounds = Bounds::from_corners(upper_left, lower_right);
 732    ///
 733    /// assert_eq!(bounds.origin, upper_left);
 734    /// assert_eq!(bounds.size.width, 10);
 735    /// assert_eq!(bounds.size.height, 10);
 736    /// ```
 737    pub fn from_corners(upper_left: Point<T>, lower_right: Point<T>) -> Self {
 738        let origin = Point {
 739            x: upper_left.x.clone(),
 740            y: upper_left.y.clone(),
 741        };
 742        let size = Size {
 743            width: lower_right.x - upper_left.x,
 744            height: lower_right.y - upper_left.y,
 745        };
 746        Bounds { origin, size }
 747    }
 748
 749    /// Creates a new `Bounds` with the specified origin and size.
 750    ///
 751    /// # Arguments
 752    ///
 753    /// * `origin` - A `Point<T>` representing the origin of the bounds.
 754    /// * `size` - A `Size<T>` representing the size of the bounds.
 755    ///
 756    /// # Returns
 757    ///
 758    /// Returns a `Bounds<T>` that has the given origin and size.
 759    pub fn new(origin: Point<T>, size: Size<T>) -> Self {
 760        Bounds { origin, size }
 761    }
 762}
 763
 764impl<T> Bounds<T>
 765where
 766    T: Clone + Debug + PartialOrd + Add<T, Output = T> + Sub<Output = T> + Default + Half,
 767{
 768    /// Checks if this `Bounds` intersects with another `Bounds`.
 769    ///
 770    /// Two `Bounds` instances intersect if they overlap in the 2D space they occupy.
 771    /// This method checks if there is any overlapping area between the two bounds.
 772    ///
 773    /// # Arguments
 774    ///
 775    /// * `other` - A reference to another `Bounds` to check for intersection with.
 776    ///
 777    /// # Returns
 778    ///
 779    /// Returns `true` if there is any intersection between the two bounds, `false` otherwise.
 780    ///
 781    /// # Examples
 782    ///
 783    /// ```
 784    /// # use zed::{Bounds, Point, Size};
 785    /// let bounds1 = Bounds {
 786    ///     origin: Point { x: 0, y: 0 },
 787    ///     size: Size { width: 10, height: 10 },
 788    /// };
 789    /// let bounds2 = Bounds {
 790    ///     origin: Point { x: 5, y: 5 },
 791    ///     size: Size { width: 10, height: 10 },
 792    /// };
 793    /// let bounds3 = Bounds {
 794    ///     origin: Point { x: 20, y: 20 },
 795    ///     size: Size { width: 10, height: 10 },
 796    /// };
 797    ///
 798    /// assert_eq!(bounds1.intersects(&bounds2), true); // Overlapping bounds
 799    /// assert_eq!(bounds1.intersects(&bounds3), false); // Non-overlapping bounds
 800    /// ```
 801    pub fn intersects(&self, other: &Bounds<T>) -> bool {
 802        let my_lower_right = self.lower_right();
 803        let their_lower_right = other.lower_right();
 804
 805        self.origin.x < their_lower_right.x
 806            && my_lower_right.x > other.origin.x
 807            && self.origin.y < their_lower_right.y
 808            && my_lower_right.y > other.origin.y
 809    }
 810
 811    /// Dilates the bounds by a specified amount in all directions.
 812    ///
 813    /// This method expands the bounds by the given `amount`, increasing the size
 814    /// and adjusting the origin so that the bounds grow outwards equally in all directions.
 815    /// The resulting bounds will have its width and height increased by twice the `amount`
 816    /// (since it grows in both directions), and the origin will be moved by `-amount`
 817    /// in both the x and y directions.
 818    ///
 819    /// # Arguments
 820    ///
 821    /// * `amount` - The amount by which to dilate the bounds.
 822    ///
 823    /// # Examples
 824    ///
 825    /// ```
 826    /// # use zed::{Bounds, Point, Size};
 827    /// let mut bounds = Bounds {
 828    ///     origin: Point { x: 10, y: 10 },
 829    ///     size: Size { width: 10, height: 10 },
 830    /// };
 831    /// bounds.dilate(5);
 832    /// assert_eq!(bounds, Bounds {
 833    ///     origin: Point { x: 5, y: 5 },
 834    ///     size: Size { width: 20, height: 20 },
 835    /// });
 836    /// ```
 837    pub fn dilate(&mut self, amount: T) {
 838        self.origin.x = self.origin.x.clone() - amount.clone();
 839        self.origin.y = self.origin.y.clone() - amount.clone();
 840        let double_amount = amount.clone() + amount;
 841        self.size.width = self.size.width.clone() + double_amount.clone();
 842        self.size.height = self.size.height.clone() + double_amount;
 843    }
 844
 845    /// Returns the center point of the bounds.
 846    ///
 847    /// Calculates the center by taking the origin's x and y coordinates and adding half the width and height
 848    /// of the bounds, respectively. The center is represented as a `Point<T>` where `T` is the type of the
 849    /// coordinate system.
 850    ///
 851    /// # Returns
 852    ///
 853    /// A `Point<T>` representing the center of the bounds.
 854    ///
 855    /// # Examples
 856    ///
 857    /// ```
 858    /// # use zed::{Bounds, Point, Size};
 859    /// let bounds = Bounds {
 860    ///     origin: Point { x: 0, y: 0 },
 861    ///     size: Size { width: 10, height: 20 },
 862    /// };
 863    /// let center = bounds.center();
 864    /// assert_eq!(center, Point { x: 5, y: 10 });
 865    /// ```
 866    pub fn center(&self) -> Point<T> {
 867        Point {
 868            x: self.origin.x.clone() + self.size.width.clone().half(),
 869            y: self.origin.y.clone() + self.size.height.clone().half(),
 870        }
 871    }
 872
 873    /// Calculates the half perimeter of a rectangle defined by the bounds.
 874    ///
 875    /// The half perimeter is calculated as the sum of the width and the height of the rectangle.
 876    /// This method is generic over the type `T` which must implement the `Sub` trait to allow
 877    /// calculation of the width and height from the bounds' origin and size, as well as the `Add` trait
 878    /// to sum the width and height for the half perimeter.
 879    ///
 880    /// # Examples
 881    ///
 882    /// ```
 883    /// # use zed::{Bounds, Point, Size};
 884    /// let bounds = Bounds {
 885    ///     origin: Point { x: 0, y: 0 },
 886    ///     size: Size { width: 10, height: 20 },
 887    /// };
 888    /// let half_perimeter = bounds.half_perimeter();
 889    /// assert_eq!(half_perimeter, 30);
 890    /// ```
 891    pub fn half_perimeter(&self) -> T {
 892        self.size.width.clone() + self.size.height.clone()
 893    }
 894}
 895
 896impl<T: Clone + Default + Debug + PartialOrd + Add<T, Output = T> + Sub<Output = T>> Bounds<T> {
 897    /// Calculates the intersection of two `Bounds` objects.
 898    ///
 899    /// This method computes the overlapping region of two `Bounds`. If the bounds do not intersect,
 900    /// the resulting `Bounds` will have a size with width and height of zero.
 901    ///
 902    /// # Arguments
 903    ///
 904    /// * `other` - A reference to another `Bounds` to intersect with.
 905    ///
 906    /// # Returns
 907    ///
 908    /// Returns a `Bounds` representing the intersection area. If there is no intersection,
 909    /// the returned `Bounds` will have a size with width and height of zero.
 910    ///
 911    /// # Examples
 912    ///
 913    /// ```
 914    /// # use zed::{Bounds, Point, Size};
 915    /// let bounds1 = Bounds {
 916    ///     origin: Point { x: 0, y: 0 },
 917    ///     size: Size { width: 10, height: 10 },
 918    /// };
 919    /// let bounds2 = Bounds {
 920    ///     origin: Point { x: 5, y: 5 },
 921    ///     size: Size { width: 10, height: 10 },
 922    /// };
 923    /// let intersection = bounds1.intersect(&bounds2);
 924    ///
 925    /// assert_eq!(intersection, Bounds {
 926    ///     origin: Point { x: 5, y: 5 },
 927    ///     size: Size { width: 5, height: 5 },
 928    /// });
 929    /// ```
 930    pub fn intersect(&self, other: &Self) -> Self {
 931        let upper_left = self.origin.max(&other.origin);
 932        let lower_right = self.lower_right().min(&other.lower_right());
 933        Self::from_corners(upper_left, lower_right)
 934    }
 935
 936    /// Computes the union of two `Bounds`.
 937    ///
 938    /// This method calculates the smallest `Bounds` that contains both the current `Bounds` and the `other` `Bounds`.
 939    /// The resulting `Bounds` will have an origin that is the minimum of the origins of the two `Bounds`,
 940    /// and a size that encompasses the furthest extents of both `Bounds`.
 941    ///
 942    /// # Arguments
 943    ///
 944    /// * `other` - A reference to another `Bounds` to create a union with.
 945    ///
 946    /// # Returns
 947    ///
 948    /// Returns a `Bounds` representing the union of the two `Bounds`.
 949    ///
 950    /// # Examples
 951    ///
 952    /// ```
 953    /// # use zed::{Bounds, Point, Size};
 954    /// let bounds1 = Bounds {
 955    ///     origin: Point { x: 0, y: 0 },
 956    ///     size: Size { width: 10, height: 10 },
 957    /// };
 958    /// let bounds2 = Bounds {
 959    ///     origin: Point { x: 5, y: 5 },
 960    ///     size: Size { width: 15, height: 15 },
 961    /// };
 962    /// let union_bounds = bounds1.union(&bounds2);
 963    ///
 964    /// assert_eq!(union_bounds, Bounds {
 965    ///     origin: Point { x: 0, y: 0 },
 966    ///     size: Size { width: 20, height: 20 },
 967    /// });
 968    /// ```
 969    pub fn union(&self, other: &Self) -> Self {
 970        let top_left = self.origin.min(&other.origin);
 971        let bottom_right = self.lower_right().max(&other.lower_right());
 972        Bounds::from_corners(top_left, bottom_right)
 973    }
 974}
 975
 976impl<T, Rhs> Mul<Rhs> for Bounds<T>
 977where
 978    T: Mul<Rhs, Output = Rhs> + Clone + Default + Debug,
 979    Point<T>: Mul<Rhs, Output = Point<Rhs>>,
 980    Rhs: Clone + Default + Debug,
 981{
 982    type Output = Bounds<Rhs>;
 983
 984    fn mul(self, rhs: Rhs) -> Self::Output {
 985        Bounds {
 986            origin: self.origin * rhs.clone(),
 987            size: self.size * rhs,
 988        }
 989    }
 990}
 991
 992impl<T, S> MulAssign<S> for Bounds<T>
 993where
 994    T: Mul<S, Output = T> + Clone + Default + Debug,
 995    S: Clone,
 996{
 997    fn mul_assign(&mut self, rhs: S) {
 998        self.origin *= rhs.clone();
 999        self.size *= rhs;
1000    }
1001}
1002
1003impl<T, S> Div<S> for Bounds<T>
1004where
1005    Size<T>: Div<S, Output = Size<T>>,
1006    T: Div<S, Output = T> + Default + Clone + Debug,
1007    S: Clone,
1008{
1009    type Output = Self;
1010
1011    fn div(self, rhs: S) -> Self {
1012        Self {
1013            origin: self.origin / rhs.clone(),
1014            size: self.size / rhs,
1015        }
1016    }
1017}
1018
1019impl<T> Bounds<T>
1020where
1021    T: Add<T, Output = T> + Clone + Default + Debug,
1022{
1023    /// Returns the top edge of the bounds.
1024    ///
1025    /// # Returns
1026    ///
1027    /// A value of type `T` representing the y-coordinate of the top edge of the bounds.
1028    pub fn top(&self) -> T {
1029        self.origin.y.clone()
1030    }
1031
1032    /// Returns the bottom edge of the bounds.
1033    ///
1034    /// # Returns
1035    ///
1036    /// A value of type `T` representing the y-coordinate of the bottom edge of the bounds.
1037    pub fn bottom(&self) -> T {
1038        self.origin.y.clone() + self.size.height.clone()
1039    }
1040
1041    /// Returns the left edge of the bounds.
1042    ///
1043    /// # Returns
1044    ///
1045    /// A value of type `T` representing the x-coordinate of the left edge of the bounds.
1046    pub fn left(&self) -> T {
1047        self.origin.x.clone()
1048    }
1049
1050    /// Returns the right edge of the bounds.
1051    ///
1052    /// # Returns
1053    ///
1054    /// A value of type `T` representing the x-coordinate of the right edge of the bounds.
1055    pub fn right(&self) -> T {
1056        self.origin.x.clone() + self.size.width.clone()
1057    }
1058
1059    /// Returns the upper-right corner point of the bounds.
1060    ///
1061    /// # Returns
1062    ///
1063    /// A `Point<T>` representing the upper-right corner of the bounds.
1064    ///
1065    /// # Examples
1066    ///
1067    /// ```
1068    /// # use zed::{Bounds, Point, Size};
1069    /// let bounds = Bounds {
1070    ///     origin: Point { x: 0, y: 0 },
1071    ///     size: Size { width: 10, height: 20 },
1072    /// };
1073    /// let upper_right = bounds.upper_right();
1074    /// assert_eq!(upper_right, Point { x: 10, y: 0 });
1075    /// ```
1076    pub fn upper_right(&self) -> Point<T> {
1077        Point {
1078            x: self.origin.x.clone() + self.size.width.clone(),
1079            y: self.origin.y.clone(),
1080        }
1081    }
1082
1083    /// Returns the lower-right corner point of the bounds.
1084    ///
1085    /// # Returns
1086    ///
1087    /// A `Point<T>` representing the lower-right corner of the bounds.
1088    ///
1089    /// # Examples
1090    ///
1091    /// ```
1092    /// # use zed::{Bounds, Point, Size};
1093    /// let bounds = Bounds {
1094    ///     origin: Point { x: 0, y: 0 },
1095    ///     size: Size { width: 10, height: 20 },
1096    /// };
1097    /// let lower_right = bounds.lower_right();
1098    /// assert_eq!(lower_right, Point { x: 10, y: 20 });
1099    /// ```
1100    pub fn lower_right(&self) -> Point<T> {
1101        Point {
1102            x: self.origin.x.clone() + self.size.width.clone(),
1103            y: self.origin.y.clone() + self.size.height.clone(),
1104        }
1105    }
1106
1107    /// Returns the lower-left corner point of the bounds.
1108    ///
1109    /// # Returns
1110    ///
1111    /// A `Point<T>` representing the lower-left corner of the bounds.
1112    ///
1113    /// # Examples
1114    ///
1115    /// ```
1116    /// # use zed::{Bounds, Point, Size};
1117    /// let bounds = Bounds {
1118    ///     origin: Point { x: 0, y: 0 },
1119    ///     size: Size { width: 10, height: 20 },
1120    /// };
1121    /// let lower_left = bounds.lower_left();
1122    /// assert_eq!(lower_left, Point { x: 0, y: 20 });
1123    /// ```
1124    pub fn lower_left(&self) -> Point<T> {
1125        Point {
1126            x: self.origin.x.clone(),
1127            y: self.origin.y.clone() + self.size.height.clone(),
1128        }
1129    }
1130}
1131
1132impl<T> Bounds<T>
1133where
1134    T: Add<T, Output = T> + PartialOrd + Clone + Default + Debug,
1135{
1136    /// Checks if the given point is within the bounds.
1137    ///
1138    /// This method determines whether a point lies inside the rectangle defined by the bounds,
1139    /// including the edges. The point is considered inside if its x-coordinate is greater than
1140    /// or equal to the left edge and less than or equal to the right edge, and its y-coordinate
1141    /// is greater than or equal to the top edge and less than or equal to the bottom edge of the bounds.
1142    ///
1143    /// # Arguments
1144    ///
1145    /// * `point` - A reference to a `Point<T>` that represents the point to check.
1146    ///
1147    /// # Returns
1148    ///
1149    /// Returns `true` if the point is within the bounds, `false` otherwise.
1150    ///
1151    /// # Examples
1152    ///
1153    /// ```
1154    /// # use zed::{Point, Bounds};
1155    /// let bounds = Bounds {
1156    ///     origin: Point { x: 0, y: 0 },
1157    ///     size: Size { width: 10, height: 10 },
1158    /// };
1159    /// let inside_point = Point { x: 5, y: 5 };
1160    /// let outside_point = Point { x: 15, y: 15 };
1161    ///
1162    /// assert!(bounds.contains_point(&inside_point));
1163    /// assert!(!bounds.contains_point(&outside_point));
1164    /// ```
1165    pub fn contains(&self, point: &Point<T>) -> bool {
1166        point.x >= self.origin.x
1167            && point.x <= self.origin.x.clone() + self.size.width.clone()
1168            && point.y >= self.origin.y
1169            && point.y <= self.origin.y.clone() + self.size.height.clone()
1170    }
1171
1172    /// Applies a function to the origin and size of the bounds, producing a new `Bounds<U>`.
1173    ///
1174    /// This method allows for converting a `Bounds<T>` to a `Bounds<U>` by specifying a closure
1175    /// that defines how to convert between the two types. The closure is applied to the `origin` and
1176    /// `size` fields, resulting in new bounds of the desired type.
1177    ///
1178    /// # Arguments
1179    ///
1180    /// * `f` - A closure that takes a value of type `T` and returns a value of type `U`.
1181    ///
1182    /// # Returns
1183    ///
1184    /// Returns a new `Bounds<U>` with the origin and size mapped by the provided function.
1185    ///
1186    /// # Examples
1187    ///
1188    /// ```
1189    /// # use zed::{Bounds, Point, Size};
1190    /// let bounds = Bounds {
1191    ///     origin: Point { x: 10.0, y: 10.0 },
1192    ///     size: Size { width: 10.0, height: 20.0 },
1193    /// };
1194    /// let new_bounds = bounds.map(|value| value as f64 * 1.5);
1195    ///
1196    /// assert_eq!(new_bounds, Bounds {
1197    ///     origin: Point { x: 15.0, y: 15.0 },
1198    ///     size: Size { width: 15.0, height: 30.0 },
1199    /// });
1200    pub fn map<U>(&self, f: impl Fn(T) -> U) -> Bounds<U>
1201    where
1202        U: Clone + Default + Debug,
1203    {
1204        Bounds {
1205            origin: self.origin.map(&f),
1206            size: self.size.map(f),
1207        }
1208    }
1209
1210    /// Applies a function to the origin  of the bounds, producing a new `Bounds` with the new origin
1211    ///
1212    /// # Examples
1213    ///
1214    /// ```
1215    /// # use zed::{Bounds, Point, Size};
1216    /// let bounds = Bounds {
1217    ///     origin: Point { x: 10.0, y: 10.0 },
1218    ///     size: Size { width: 10.0, height: 20.0 },
1219    /// };
1220    /// let new_bounds = bounds.map_origin(|value| value * 1.5);
1221    ///
1222    /// assert_eq!(new_bounds, Bounds {
1223    ///     origin: Point { x: 15.0, y: 15.0 },
1224    ///     size: Size { width: 10.0, height: 20.0 },
1225    /// });
1226    pub fn map_origin(self, f: impl Fn(Point<T>) -> Point<T>) -> Bounds<T> {
1227        Bounds {
1228            origin: f(self.origin),
1229            size: self.size,
1230        }
1231    }
1232}
1233
1234/// Checks if the bounds represent an empty area.
1235///
1236/// # Returns
1237///
1238/// Returns `true` if either the width or the height of the bounds is less than or equal to zero, indicating an empty area.
1239impl<T: PartialOrd + Default + Debug + Clone> Bounds<T> {
1240    /// Checks if the bounds represent an empty area.
1241    ///
1242    /// # Returns
1243    ///
1244    /// Returns `true` if either the width or the height of the bounds is less than or equal to zero, indicating an empty area.
1245    pub fn is_empty(&self) -> bool {
1246        self.size.width <= T::default() || self.size.height <= T::default()
1247    }
1248}
1249
1250impl Bounds<Pixels> {
1251    /// Scales the bounds by a given factor, typically used to adjust for display scaling.
1252    ///
1253    /// This method multiplies the origin and size of the bounds by the provided scaling factor,
1254    /// resulting in a new `Bounds<ScaledPixels>` that is proportionally larger or smaller
1255    /// depending on the scaling factor. This can be used to ensure that the bounds are properly
1256    /// scaled for different display densities.
1257    ///
1258    /// # Arguments
1259    ///
1260    /// * `factor` - The scaling factor to apply to the origin and size, typically the display's scaling factor.
1261    ///
1262    /// # Returns
1263    ///
1264    /// Returns a new `Bounds<ScaledPixels>` that represents the scaled bounds.
1265    ///
1266    /// # Examples
1267    ///
1268    /// ```
1269    /// # use zed::{Bounds, Point, Size, Pixels};
1270    /// let bounds = Bounds {
1271    ///     origin: Point { x: Pixels(10.0), y: Pixels(20.0) },
1272    ///     size: Size { width: Pixels(30.0), height: Pixels(40.0) },
1273    /// };
1274    /// let display_scale_factor = 2.0;
1275    /// let scaled_bounds = bounds.scale(display_scale_factor);
1276    /// assert_eq!(scaled_bounds, Bounds {
1277    ///     origin: Point { x: ScaledPixels(20.0), y: ScaledPixels(40.0) },
1278    ///     size: Size { width: ScaledPixels(60.0), height: ScaledPixels(80.0) },
1279    /// });
1280    /// ```
1281    pub fn scale(&self, factor: f32) -> Bounds<ScaledPixels> {
1282        Bounds {
1283            origin: self.origin.scale(factor),
1284            size: self.size.scale(factor),
1285        }
1286    }
1287}
1288
1289impl<T: Clone + Debug + Copy + Default> Copy for Bounds<T> {}
1290
1291/// Represents the edges of a box in a 2D space, such as padding or margin.
1292///
1293/// Each field represents the size of the edge on one side of the box: `top`, `right`, `bottom`, and `left`.
1294///
1295/// # Examples
1296///
1297/// ```
1298/// # use zed::Edges;
1299/// let edges = Edges {
1300///     top: 10.0,
1301///     right: 20.0,
1302///     bottom: 30.0,
1303///     left: 40.0,
1304/// };
1305///
1306/// assert_eq!(edges.top, 10.0);
1307/// assert_eq!(edges.right, 20.0);
1308/// assert_eq!(edges.bottom, 30.0);
1309/// assert_eq!(edges.left, 40.0);
1310/// ```
1311#[derive(Refineable, Clone, Default, Debug, Eq, PartialEq)]
1312#[refineable(Debug)]
1313#[repr(C)]
1314pub struct Edges<T: Clone + Default + Debug> {
1315    /// The size of the top edge.
1316    pub top: T,
1317    /// The size of the right edge.
1318    pub right: T,
1319    /// The size of the bottom edge.
1320    pub bottom: T,
1321    /// The size of the left edge.
1322    pub left: T,
1323}
1324
1325impl<T> Mul for Edges<T>
1326where
1327    T: Mul<Output = T> + Clone + Default + Debug,
1328{
1329    type Output = Self;
1330
1331    fn mul(self, rhs: Self) -> Self::Output {
1332        Self {
1333            top: self.top.clone() * rhs.top,
1334            right: self.right.clone() * rhs.right,
1335            bottom: self.bottom.clone() * rhs.bottom,
1336            left: self.left.clone() * rhs.left,
1337        }
1338    }
1339}
1340
1341impl<T, S> MulAssign<S> for Edges<T>
1342where
1343    T: Mul<S, Output = T> + Clone + Default + Debug,
1344    S: Clone,
1345{
1346    fn mul_assign(&mut self, rhs: S) {
1347        self.top = self.top.clone() * rhs.clone();
1348        self.right = self.right.clone() * rhs.clone();
1349        self.bottom = self.bottom.clone() * rhs.clone();
1350        self.left = self.left.clone() * rhs;
1351    }
1352}
1353
1354impl<T: Clone + Default + Debug + Copy> Copy for Edges<T> {}
1355
1356impl<T: Clone + Default + Debug> Edges<T> {
1357    /// Constructs `Edges` where all sides are set to the same specified value.
1358    ///
1359    /// This function creates an `Edges` instance with the `top`, `right`, `bottom`, and `left` fields all initialized
1360    /// to the same value provided as an argument. This is useful when you want to have uniform edges around a box,
1361    /// such as padding or margin with the same size on all sides.
1362    ///
1363    /// # Arguments
1364    ///
1365    /// * `value` - The value to set for all four sides of the edges.
1366    ///
1367    /// # Returns
1368    ///
1369    /// An `Edges` instance with all sides set to the given value.
1370    ///
1371    /// # Examples
1372    ///
1373    /// ```
1374    /// # use zed::Edges;
1375    /// let uniform_edges = Edges::all(10.0);
1376    /// assert_eq!(uniform_edges.top, 10.0);
1377    /// assert_eq!(uniform_edges.right, 10.0);
1378    /// assert_eq!(uniform_edges.bottom, 10.0);
1379    /// assert_eq!(uniform_edges.left, 10.0);
1380    /// ```
1381    pub fn all(value: T) -> Self {
1382        Self {
1383            top: value.clone(),
1384            right: value.clone(),
1385            bottom: value.clone(),
1386            left: value,
1387        }
1388    }
1389
1390    /// Applies a function to each field of the `Edges`, producing a new `Edges<U>`.
1391    ///
1392    /// This method allows for converting an `Edges<T>` to an `Edges<U>` by specifying a closure
1393    /// that defines how to convert between the two types. The closure is applied to each field
1394    /// (`top`, `right`, `bottom`, `left`), resulting in new edges of the desired type.
1395    ///
1396    /// # Arguments
1397    ///
1398    /// * `f` - A closure that takes a reference to a value of type `T` and returns a value of type `U`.
1399    ///
1400    /// # Returns
1401    ///
1402    /// Returns a new `Edges<U>` with each field mapped by the provided function.
1403    ///
1404    /// # Examples
1405    ///
1406    /// ```
1407    /// # use zed::Edges;
1408    /// let edges = Edges { top: 10, right: 20, bottom: 30, left: 40 };
1409    /// let edges_float = edges.map(|&value| value as f32 * 1.1);
1410    /// assert_eq!(edges_float, Edges { top: 11.0, right: 22.0, bottom: 33.0, left: 44.0 });
1411    /// ```
1412    pub fn map<U>(&self, f: impl Fn(&T) -> U) -> Edges<U>
1413    where
1414        U: Clone + Default + Debug,
1415    {
1416        Edges {
1417            top: f(&self.top),
1418            right: f(&self.right),
1419            bottom: f(&self.bottom),
1420            left: f(&self.left),
1421        }
1422    }
1423
1424    /// Checks if any of the edges satisfy a given predicate.
1425    ///
1426    /// This method applies a predicate function to each field of the `Edges` and returns `true` if any field satisfies the predicate.
1427    ///
1428    /// # Arguments
1429    ///
1430    /// * `predicate` - A closure that takes a reference to a value of type `T` and returns a `bool`.
1431    ///
1432    /// # Returns
1433    ///
1434    /// Returns `true` if the predicate returns `true` for any of the edge values, `false` otherwise.
1435    ///
1436    /// # Examples
1437    ///
1438    /// ```
1439    /// # use zed::Edges;
1440    /// let edges = Edges {
1441    ///     top: 10,
1442    ///     right: 0,
1443    ///     bottom: 5,
1444    ///     left: 0,
1445    /// };
1446    ///
1447    /// assert!(edges.any(|value| *value == 0));
1448    /// assert!(edges.any(|value| *value > 0));
1449    /// assert!(!edges.any(|value| *value > 10));
1450    /// ```
1451    pub fn any<F: Fn(&T) -> bool>(&self, predicate: F) -> bool {
1452        predicate(&self.top)
1453            || predicate(&self.right)
1454            || predicate(&self.bottom)
1455            || predicate(&self.left)
1456    }
1457}
1458
1459impl Edges<Length> {
1460    /// Sets the edges of the `Edges` struct to `auto`, which is a special value that allows the layout engine to automatically determine the size of the edges.
1461    ///
1462    /// This is typically used in layout contexts where the exact size of the edges is not important, or when the size should be calculated based on the content or container.
1463    ///
1464    /// # Returns
1465    ///
1466    /// Returns an `Edges<Length>` with all edges set to `Length::Auto`.
1467    ///
1468    /// # Examples
1469    ///
1470    /// ```
1471    /// # use zed::Edges;
1472    /// let auto_edges = Edges::auto();
1473    /// assert_eq!(auto_edges.top, Length::Auto);
1474    /// assert_eq!(auto_edges.right, Length::Auto);
1475    /// assert_eq!(auto_edges.bottom, Length::Auto);
1476    /// assert_eq!(auto_edges.left, Length::Auto);
1477    /// ```
1478    pub fn auto() -> Self {
1479        Self {
1480            top: Length::Auto,
1481            right: Length::Auto,
1482            bottom: Length::Auto,
1483            left: Length::Auto,
1484        }
1485    }
1486
1487    /// Sets the edges of the `Edges` struct to zero, which means no size or thickness.
1488    ///
1489    /// This is typically used when you want to specify that a box (like a padding or margin area)
1490    /// should have no edges, effectively making it non-existent or invisible in layout calculations.
1491    ///
1492    /// # Returns
1493    ///
1494    /// Returns an `Edges<Length>` with all edges set to zero length.
1495    ///
1496    /// # Examples
1497    ///
1498    /// ```
1499    /// # use zed::Edges;
1500    /// let no_edges = Edges::zero();
1501    /// assert_eq!(no_edges.top, Length::Definite(DefiniteLength::from(Pixels(0.))));
1502    /// assert_eq!(no_edges.right, Length::Definite(DefiniteLength::from(Pixels(0.))));
1503    /// assert_eq!(no_edges.bottom, Length::Definite(DefiniteLength::from(Pixels(0.))));
1504    /// assert_eq!(no_edges.left, Length::Definite(DefiniteLength::from(Pixels(0.))));
1505    /// ```
1506    pub fn zero() -> Self {
1507        Self {
1508            top: px(0.).into(),
1509            right: px(0.).into(),
1510            bottom: px(0.).into(),
1511            left: px(0.).into(),
1512        }
1513    }
1514}
1515
1516impl Edges<DefiniteLength> {
1517    /// Sets the edges of the `Edges` struct to zero, which means no size or thickness.
1518    ///
1519    /// This is typically used when you want to specify that a box (like a padding or margin area)
1520    /// should have no edges, effectively making it non-existent or invisible in layout calculations.
1521    ///
1522    /// # Returns
1523    ///
1524    /// Returns an `Edges<DefiniteLength>` with all edges set to zero length.
1525    ///
1526    /// # Examples
1527    ///
1528    /// ```
1529    /// # use zed::Edges;
1530    /// let no_edges = Edges::zero();
1531    /// assert_eq!(no_edges.top, DefiniteLength::from(zed::px(0.)));
1532    /// assert_eq!(no_edges.right, DefiniteLength::from(zed::px(0.)));
1533    /// assert_eq!(no_edges.bottom, DefiniteLength::from(zed::px(0.)));
1534    /// assert_eq!(no_edges.left, DefiniteLength::from(zed::px(0.)));
1535    /// ```
1536    pub fn zero() -> Self {
1537        Self {
1538            top: px(0.).into(),
1539            right: px(0.).into(),
1540            bottom: px(0.).into(),
1541            left: px(0.).into(),
1542        }
1543    }
1544
1545    /// Converts the `DefiniteLength` to `Pixels` based on the parent size and the REM size.
1546    ///
1547    /// This method allows for a `DefiniteLength` value to be converted into pixels, taking into account
1548    /// the size of the parent element (for percentage-based lengths) and the size of a rem unit (for rem-based lengths).
1549    ///
1550    /// # Arguments
1551    ///
1552    /// * `parent_size` - `Size<AbsoluteLength>` representing the size of the parent element.
1553    /// * `rem_size` - `Pixels` representing the size of one REM unit.
1554    ///
1555    /// # Returns
1556    ///
1557    /// Returns an `Edges<Pixels>` representing the edges with lengths converted to pixels.
1558    ///
1559    /// # Examples
1560    ///
1561    /// ```
1562    /// # use zed::{Edges, DefiniteLength, px, AbsoluteLength, Size};
1563    /// let edges = Edges {
1564    ///     top: DefiniteLength::Absolute(AbsoluteLength::Pixels(px(10.0))),
1565    ///     right: DefiniteLength::Fraction(0.5),
1566    ///     bottom: DefiniteLength::Absolute(AbsoluteLength::Rems(rems(2.0))),
1567    ///     left: DefiniteLength::Fraction(0.25),
1568    /// };
1569    /// let parent_size = Size {
1570    ///     width: AbsoluteLength::Pixels(px(200.0)),
1571    ///     height: AbsoluteLength::Pixels(px(100.0)),
1572    /// };
1573    /// let rem_size = px(16.0);
1574    /// let edges_in_pixels = edges.to_pixels(parent_size, rem_size);
1575    ///
1576    /// assert_eq!(edges_in_pixels.top, px(10.0)); // Absolute length in pixels
1577    /// assert_eq!(edges_in_pixels.right, px(100.0)); // 50% of parent width
1578    /// assert_eq!(edges_in_pixels.bottom, px(32.0)); // 2 rems
1579    /// assert_eq!(edges_in_pixels.left, px(50.0)); // 25% of parent width
1580    /// ```
1581    pub fn to_pixels(&self, parent_size: Size<AbsoluteLength>, rem_size: Pixels) -> Edges<Pixels> {
1582        Edges {
1583            top: self.top.to_pixels(parent_size.height, rem_size),
1584            right: self.right.to_pixels(parent_size.width, rem_size),
1585            bottom: self.bottom.to_pixels(parent_size.height, rem_size),
1586            left: self.left.to_pixels(parent_size.width, rem_size),
1587        }
1588    }
1589}
1590
1591impl Edges<AbsoluteLength> {
1592    /// Sets the edges of the `Edges` struct to zero, which means no size or thickness.
1593    ///
1594    /// This is typically used when you want to specify that a box (like a padding or margin area)
1595    /// should have no edges, effectively making it non-existent or invisible in layout calculations.
1596    ///
1597    /// # Returns
1598    ///
1599    /// Returns an `Edges<AbsoluteLength>` with all edges set to zero length.
1600    ///
1601    /// # Examples
1602    ///
1603    /// ```
1604    /// # use zed::Edges;
1605    /// let no_edges = Edges::zero();
1606    /// assert_eq!(no_edges.top, AbsoluteLength::Pixels(Pixels(0.0)));
1607    /// assert_eq!(no_edges.right, AbsoluteLength::Pixels(Pixels(0.0)));
1608    /// assert_eq!(no_edges.bottom, AbsoluteLength::Pixels(Pixels(0.0)));
1609    /// assert_eq!(no_edges.left, AbsoluteLength::Pixels(Pixels(0.0)));
1610    /// ```
1611    pub fn zero() -> Self {
1612        Self {
1613            top: px(0.).into(),
1614            right: px(0.).into(),
1615            bottom: px(0.).into(),
1616            left: px(0.).into(),
1617        }
1618    }
1619
1620    /// Converts the `AbsoluteLength` to `Pixels` based on the `rem_size`.
1621    ///
1622    /// If the `AbsoluteLength` is already in pixels, it simply returns the corresponding `Pixels` value.
1623    /// If the `AbsoluteLength` is in rems, it multiplies the number of rems by the `rem_size` to convert it to pixels.
1624    ///
1625    /// # Arguments
1626    ///
1627    /// * `rem_size` - The size of one rem unit in pixels.
1628    ///
1629    /// # Returns
1630    ///
1631    /// Returns an `Edges<Pixels>` representing the edges with lengths converted to pixels.
1632    ///
1633    /// # Examples
1634    ///
1635    /// ```
1636    /// # use zed::{Edges, AbsoluteLength, Pixels, px};
1637    /// let edges = Edges {
1638    ///     top: AbsoluteLength::Pixels(px(10.0)),
1639    ///     right: AbsoluteLength::Rems(rems(1.0)),
1640    ///     bottom: AbsoluteLength::Pixels(px(20.0)),
1641    ///     left: AbsoluteLength::Rems(rems(2.0)),
1642    /// };
1643    /// let rem_size = px(16.0);
1644    /// let edges_in_pixels = edges.to_pixels(rem_size);
1645    ///
1646    /// assert_eq!(edges_in_pixels.top, px(10.0)); // Already in pixels
1647    /// assert_eq!(edges_in_pixels.right, px(16.0)); // 1 rem converted to pixels
1648    /// assert_eq!(edges_in_pixels.bottom, px(20.0)); // Already in pixels
1649    /// assert_eq!(edges_in_pixels.left, px(32.0)); // 2 rems converted to pixels
1650    /// ```
1651    pub fn to_pixels(&self, rem_size: Pixels) -> Edges<Pixels> {
1652        Edges {
1653            top: self.top.to_pixels(rem_size),
1654            right: self.right.to_pixels(rem_size),
1655            bottom: self.bottom.to_pixels(rem_size),
1656            left: self.left.to_pixels(rem_size),
1657        }
1658    }
1659}
1660
1661impl Edges<Pixels> {
1662    /// Scales the `Edges<Pixels>` by a given factor, returning `Edges<ScaledPixels>`.
1663    ///
1664    /// This method is typically used for adjusting the edge sizes for different display densities or scaling factors.
1665    ///
1666    /// # Arguments
1667    ///
1668    /// * `factor` - The scaling factor to apply to each edge.
1669    ///
1670    /// # Returns
1671    ///
1672    /// Returns a new `Edges<ScaledPixels>` where each edge is the result of scaling the original edge by the given factor.
1673    ///
1674    /// # Examples
1675    ///
1676    /// ```
1677    /// # use zed::{Edges, Pixels};
1678    /// let edges = Edges {
1679    ///     top: Pixels(10.0),
1680    ///     right: Pixels(20.0),
1681    ///     bottom: Pixels(30.0),
1682    ///     left: Pixels(40.0),
1683    /// };
1684    /// let scaled_edges = edges.scale(2.0);
1685    /// assert_eq!(scaled_edges.top, ScaledPixels(20.0));
1686    /// assert_eq!(scaled_edges.right, ScaledPixels(40.0));
1687    /// assert_eq!(scaled_edges.bottom, ScaledPixels(60.0));
1688    /// assert_eq!(scaled_edges.left, ScaledPixels(80.0));
1689    /// ```
1690    pub fn scale(&self, factor: f32) -> Edges<ScaledPixels> {
1691        Edges {
1692            top: self.top.scale(factor),
1693            right: self.right.scale(factor),
1694            bottom: self.bottom.scale(factor),
1695            left: self.left.scale(factor),
1696        }
1697    }
1698
1699    /// Returns the maximum value of any edge.
1700    ///
1701    /// # Returns
1702    ///
1703    /// The maximum `Pixels` value among all four edges.
1704    pub fn max(&self) -> Pixels {
1705        self.top.max(self.right).max(self.bottom).max(self.left)
1706    }
1707}
1708
1709impl From<f32> for Edges<Pixels> {
1710    fn from(val: f32) -> Self {
1711        Edges {
1712            top: val.into(),
1713            right: val.into(),
1714            bottom: val.into(),
1715            left: val.into(),
1716        }
1717    }
1718}
1719
1720/// Represents the corners of a box in a 2D space, such as border radius.
1721///
1722/// Each field represents the size of the corner on one side of the box: `top_left`, `top_right`, `bottom_right`, and `bottom_left`.
1723#[derive(Refineable, Clone, Default, Debug, Eq, PartialEq)]
1724#[refineable(Debug)]
1725#[repr(C)]
1726pub struct Corners<T: Clone + Default + Debug> {
1727    /// The value associated with the top left corner.
1728    pub top_left: T,
1729    /// The value associated with the top right corner.
1730    pub top_right: T,
1731    /// The value associated with the bottom right corner.
1732    pub bottom_right: T,
1733    /// The value associated with the bottom left corner.
1734    pub bottom_left: T,
1735}
1736
1737impl<T> Corners<T>
1738where
1739    T: Clone + Default + Debug,
1740{
1741    /// Constructs `Corners` where all sides are set to the same specified value.
1742    ///
1743    /// This function creates a `Corners` instance with the `top_left`, `top_right`, `bottom_right`, and `bottom_left` fields all initialized
1744    /// to the same value provided as an argument. This is useful when you want to have uniform corners around a box,
1745    /// such as a uniform border radius on a rectangle.
1746    ///
1747    /// # Arguments
1748    ///
1749    /// * `value` - The value to set for all four corners.
1750    ///
1751    /// # Returns
1752    ///
1753    /// An `Corners` instance with all corners set to the given value.
1754    ///
1755    /// # Examples
1756    ///
1757    /// ```
1758    /// # use zed::Corners;
1759    /// let uniform_corners = Corners::all(5.0);
1760    /// assert_eq!(uniform_corners.top_left, 5.0);
1761    /// assert_eq!(uniform_corners.top_right, 5.0);
1762    /// assert_eq!(uniform_corners.bottom_right, 5.0);
1763    /// assert_eq!(uniform_corners.bottom_left, 5.0);
1764    /// ```
1765    pub fn all(value: T) -> Self {
1766        Self {
1767            top_left: value.clone(),
1768            top_right: value.clone(),
1769            bottom_right: value.clone(),
1770            bottom_left: value,
1771        }
1772    }
1773}
1774
1775impl Corners<AbsoluteLength> {
1776    /// Converts the `AbsoluteLength` to `Pixels` based on the provided size and rem size, ensuring the resulting
1777    /// `Pixels` do not exceed half of the maximum of the provided size's width and height.
1778    ///
1779    /// This method is particularly useful when dealing with corner radii, where the radius in pixels should not
1780    /// exceed half the size of the box it applies to, to avoid the corners overlapping.
1781    ///
1782    /// # Arguments
1783    ///
1784    /// * `size` - The `Size<Pixels>` against which the maximum allowable radius is determined.
1785    /// * `rem_size` - The size of one REM unit in pixels, used for conversion if the `AbsoluteLength` is in REMs.
1786    ///
1787    /// # Returns
1788    ///
1789    /// Returns a `Corners<Pixels>` instance with each corner's length converted to pixels and clamped to the
1790    /// maximum allowable radius based on the provided size.
1791    ///
1792    /// # Examples
1793    ///
1794    /// ```
1795    /// # use zed::{Corners, AbsoluteLength, Pixels, Size};
1796    /// let corners = Corners {
1797    ///     top_left: AbsoluteLength::Pixels(Pixels(15.0)),
1798    ///     top_right: AbsoluteLength::Rems(Rems(1.0)),
1799    ///     bottom_right: AbsoluteLength::Pixels(Pixels(20.0)),
1800    ///     bottom_left: AbsoluteLength::Rems(Rems(2.0)),
1801    /// };
1802    /// let size = Size { width: Pixels(100.0), height: Pixels(50.0) };
1803    /// let rem_size = Pixels(16.0);
1804    /// let corners_in_pixels = corners.to_pixels(size, rem_size);
1805    ///
1806    /// // The resulting corners should not exceed half the size of the smallest dimension (50.0 / 2.0 = 25.0).
1807    /// assert_eq!(corners_in_pixels.top_left, Pixels(15.0));
1808    /// assert_eq!(corners_in_pixels.top_right, Pixels(16.0)); // 1 rem converted to pixels
1809    /// assert_eq!(corners_in_pixels.bottom_right, Pixels(20.0).min(Pixels(25.0))); // Clamped to 25.0
1810    /// assert_eq!(corners_in_pixels.bottom_left, Pixels(32.0).min(Pixels(25.0))); // 2 rems converted to pixels and clamped
1811    /// ```
1812    pub fn to_pixels(&self, size: Size<Pixels>, rem_size: Pixels) -> Corners<Pixels> {
1813        let max = size.width.max(size.height) / 2.;
1814        Corners {
1815            top_left: self.top_left.to_pixels(rem_size).min(max),
1816            top_right: self.top_right.to_pixels(rem_size).min(max),
1817            bottom_right: self.bottom_right.to_pixels(rem_size).min(max),
1818            bottom_left: self.bottom_left.to_pixels(rem_size).min(max),
1819        }
1820    }
1821}
1822
1823impl Corners<Pixels> {
1824    /// Scales the `Corners<Pixels>` by a given factor, returning `Corners<ScaledPixels>`.
1825    ///
1826    /// This method is typically used for adjusting the corner sizes for different display densities or scaling factors.
1827    ///
1828    /// # Arguments
1829    ///
1830    /// * `factor` - The scaling factor to apply to each corner.
1831    ///
1832    /// # Returns
1833    ///
1834    /// Returns a new `Corners<ScaledPixels>` where each corner is the result of scaling the original corner by the given factor.
1835    ///
1836    /// # Examples
1837    ///
1838    /// ```
1839    /// # use zed::{Corners, Pixels};
1840    /// let corners = Corners {
1841    ///     top_left: Pixels(10.0),
1842    ///     top_right: Pixels(20.0),
1843    ///     bottom_right: Pixels(30.0),
1844    ///     bottom_left: Pixels(40.0),
1845    /// };
1846    /// let scaled_corners = corners.scale(2.0);
1847    /// assert_eq!(scaled_corners.top_left, ScaledPixels(20.0));
1848    /// assert_eq!(scaled_corners.top_right, ScaledPixels(40.0));
1849    /// assert_eq!(scaled_corners.bottom_right, ScaledPixels(60.0));
1850    /// assert_eq!(scaled_corners.bottom_left, ScaledPixels(80.0));
1851    /// ```
1852    pub fn scale(&self, factor: f32) -> Corners<ScaledPixels> {
1853        Corners {
1854            top_left: self.top_left.scale(factor),
1855            top_right: self.top_right.scale(factor),
1856            bottom_right: self.bottom_right.scale(factor),
1857            bottom_left: self.bottom_left.scale(factor),
1858        }
1859    }
1860
1861    /// Returns the maximum value of any corner.
1862    ///
1863    /// # Returns
1864    ///
1865    /// The maximum `Pixels` value among all four corners.
1866    pub fn max(&self) -> Pixels {
1867        self.top_left
1868            .max(self.top_right)
1869            .max(self.bottom_right)
1870            .max(self.bottom_left)
1871    }
1872}
1873
1874impl<T: Clone + Default + Debug> Corners<T> {
1875    /// Applies a function to each field of the `Corners`, producing a new `Corners<U>`.
1876    ///
1877    /// This method allows for converting a `Corners<T>` to a `Corners<U>` by specifying a closure
1878    /// that defines how to convert between the two types. The closure is applied to each field
1879    /// (`top_left`, `top_right`, `bottom_right`, `bottom_left`), resulting in new corners of the desired type.
1880    ///
1881    /// # Arguments
1882    ///
1883    /// * `f` - A closure that takes a reference to a value of type `T` and returns a value of type `U`.
1884    ///
1885    /// # Returns
1886    ///
1887    /// Returns a new `Corners<U>` with each field mapped by the provided function.
1888    ///
1889    /// # Examples
1890    ///
1891    /// ```
1892    /// # use zed::{Corners, Pixels};
1893    /// let corners = Corners {
1894    ///     top_left: Pixels(10.0),
1895    ///     top_right: Pixels(20.0),
1896    ///     bottom_right: Pixels(30.0),
1897    ///     bottom_left: Pixels(40.0),
1898    /// };
1899    /// let corners_in_rems = corners.map(|&px| Rems(px.0 / 16.0));
1900    /// assert_eq!(corners_in_rems, Corners {
1901    ///     top_left: Rems(0.625),
1902    ///     top_right: Rems(1.25),
1903    ///     bottom_right: Rems(1.875),
1904    ///     bottom_left: Rems(2.5),
1905    /// });
1906    /// ```
1907    pub fn map<U>(&self, f: impl Fn(&T) -> U) -> Corners<U>
1908    where
1909        U: Clone + Default + Debug,
1910    {
1911        Corners {
1912            top_left: f(&self.top_left),
1913            top_right: f(&self.top_right),
1914            bottom_right: f(&self.bottom_right),
1915            bottom_left: f(&self.bottom_left),
1916        }
1917    }
1918}
1919
1920impl<T> Mul for Corners<T>
1921where
1922    T: Mul<Output = T> + Clone + Default + Debug,
1923{
1924    type Output = Self;
1925
1926    fn mul(self, rhs: Self) -> Self::Output {
1927        Self {
1928            top_left: self.top_left.clone() * rhs.top_left,
1929            top_right: self.top_right.clone() * rhs.top_right,
1930            bottom_right: self.bottom_right.clone() * rhs.bottom_right,
1931            bottom_left: self.bottom_left.clone() * rhs.bottom_left,
1932        }
1933    }
1934}
1935
1936impl<T, S> MulAssign<S> for Corners<T>
1937where
1938    T: Mul<S, Output = T> + Clone + Default + Debug,
1939    S: Clone,
1940{
1941    fn mul_assign(&mut self, rhs: S) {
1942        self.top_left = self.top_left.clone() * rhs.clone();
1943        self.top_right = self.top_right.clone() * rhs.clone();
1944        self.bottom_right = self.bottom_right.clone() * rhs.clone();
1945        self.bottom_left = self.bottom_left.clone() * rhs;
1946    }
1947}
1948
1949impl<T> Copy for Corners<T> where T: Copy + Clone + Default + Debug {}
1950
1951impl From<f32> for Corners<Pixels> {
1952    fn from(val: f32) -> Self {
1953        Corners {
1954            top_left: val.into(),
1955            top_right: val.into(),
1956            bottom_right: val.into(),
1957            bottom_left: val.into(),
1958        }
1959    }
1960}
1961
1962impl From<Pixels> for Corners<Pixels> {
1963    fn from(val: Pixels) -> Self {
1964        Corners {
1965            top_left: val,
1966            top_right: val,
1967            bottom_right: val,
1968            bottom_left: val,
1969        }
1970    }
1971}
1972
1973/// Represents a length in pixels, the base unit of measurement in the UI framework.
1974///
1975/// `Pixels` is a value type that represents an absolute length in pixels, which is used
1976/// for specifying sizes, positions, and distances in the UI. It is the fundamental unit
1977/// of measurement for all visual elements and layout calculations.
1978///
1979/// The inner value is an `f32`, allowing for sub-pixel precision which can be useful for
1980/// anti-aliasing and animations. However, when applied to actual pixel grids, the value
1981/// is typically rounded to the nearest integer.
1982///
1983/// # Examples
1984///
1985/// ```
1986/// use zed::Pixels;
1987///
1988/// // Define a length of 10 pixels
1989/// let length = Pixels(10.0);
1990///
1991/// // Define a length and scale it by a factor of 2
1992/// let scaled_length = length.scale(2.0);
1993/// assert_eq!(scaled_length, Pixels(20.0));
1994/// ```
1995#[derive(
1996    Clone,
1997    Copy,
1998    Default,
1999    Add,
2000    AddAssign,
2001    Sub,
2002    SubAssign,
2003    Neg,
2004    Div,
2005    DivAssign,
2006    PartialEq,
2007    Serialize,
2008    Deserialize,
2009)]
2010#[repr(transparent)]
2011pub struct Pixels(pub f32);
2012
2013impl std::ops::Div for Pixels {
2014    type Output = f32;
2015
2016    fn div(self, rhs: Self) -> Self::Output {
2017        self.0 / rhs.0
2018    }
2019}
2020
2021impl std::ops::DivAssign for Pixels {
2022    fn div_assign(&mut self, rhs: Self) {
2023        *self = Self(self.0 / rhs.0);
2024    }
2025}
2026
2027impl std::ops::RemAssign for Pixels {
2028    fn rem_assign(&mut self, rhs: Self) {
2029        self.0 %= rhs.0;
2030    }
2031}
2032
2033impl std::ops::Rem for Pixels {
2034    type Output = Self;
2035
2036    fn rem(self, rhs: Self) -> Self {
2037        Self(self.0 % rhs.0)
2038    }
2039}
2040
2041impl Mul<f32> for Pixels {
2042    type Output = Pixels;
2043
2044    fn mul(self, other: f32) -> Pixels {
2045        Pixels(self.0 * other)
2046    }
2047}
2048
2049impl Mul<usize> for Pixels {
2050    type Output = Pixels;
2051
2052    fn mul(self, other: usize) -> Pixels {
2053        Pixels(self.0 * other as f32)
2054    }
2055}
2056
2057impl Mul<Pixels> for f32 {
2058    type Output = Pixels;
2059
2060    fn mul(self, rhs: Pixels) -> Self::Output {
2061        Pixels(self * rhs.0)
2062    }
2063}
2064
2065impl MulAssign<f32> for Pixels {
2066    fn mul_assign(&mut self, other: f32) {
2067        self.0 *= other;
2068    }
2069}
2070
2071impl Pixels {
2072    /// Represents zero pixels.
2073    pub const ZERO: Pixels = Pixels(0.0);
2074    /// The maximum value that can be represented by `Pixels`.
2075    pub const MAX: Pixels = Pixels(f32::MAX);
2076
2077    /// Floors the `Pixels` value to the nearest whole number.
2078    ///
2079    /// # Returns
2080    ///
2081    /// Returns a new `Pixels` instance with the floored value.
2082    pub fn floor(&self) -> Self {
2083        Self(self.0.floor())
2084    }
2085
2086    /// Rounds the `Pixels` value to the nearest whole number.
2087    ///
2088    /// # Returns
2089    ///
2090    /// Returns a new `Pixels` instance with the rounded value.
2091    pub fn round(&self) -> Self {
2092        Self(self.0.round())
2093    }
2094
2095    /// Returns the ceiling of the `Pixels` value to the nearest whole number.
2096    ///
2097    /// # Returns
2098    ///
2099    /// Returns a new `Pixels` instance with the ceiling value.
2100    pub fn ceil(&self) -> Self {
2101        Self(self.0.ceil())
2102    }
2103
2104    /// Scales the `Pixels` value by a given factor, producing `ScaledPixels`.
2105    ///
2106    /// This method is used when adjusting pixel values for display scaling factors,
2107    /// such as high DPI (dots per inch) or Retina displays, where the pixel density is higher and
2108    /// thus requires scaling to maintain visual consistency and readability.
2109    ///
2110    /// The resulting `ScaledPixels` represent the scaled value which can be used for rendering
2111    /// calculations where display scaling is considered.
2112    pub fn scale(&self, factor: f32) -> ScaledPixels {
2113        ScaledPixels(self.0 * factor)
2114    }
2115
2116    /// Raises the `Pixels` value to a given power.
2117    ///
2118    /// # Arguments
2119    ///
2120    /// * `exponent` - The exponent to raise the `Pixels` value by.
2121    ///
2122    /// # Returns
2123    ///
2124    /// Returns a new `Pixels` instance with the value raised to the given exponent.
2125    pub fn pow(&self, exponent: f32) -> Self {
2126        Self(self.0.powf(exponent))
2127    }
2128
2129    /// Returns the absolute value of the `Pixels`.
2130    ///
2131    /// # Returns
2132    ///
2133    /// A new `Pixels` instance with the absolute value of the original `Pixels`.
2134    pub fn abs(&self) -> Self {
2135        Self(self.0.abs())
2136    }
2137}
2138
2139impl Mul<Pixels> for Pixels {
2140    type Output = Pixels;
2141
2142    fn mul(self, rhs: Pixels) -> Self::Output {
2143        Pixels(self.0 * rhs.0)
2144    }
2145}
2146
2147impl Eq for Pixels {}
2148
2149impl PartialOrd for Pixels {
2150    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
2151        Some(self.cmp(other))
2152    }
2153}
2154
2155impl Ord for Pixels {
2156    fn cmp(&self, other: &Self) -> cmp::Ordering {
2157        self.0.total_cmp(&other.0)
2158    }
2159}
2160
2161impl std::hash::Hash for Pixels {
2162    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
2163        self.0.to_bits().hash(state);
2164    }
2165}
2166
2167impl From<f64> for Pixels {
2168    fn from(pixels: f64) -> Self {
2169        Pixels(pixels as f32)
2170    }
2171}
2172
2173impl From<f32> for Pixels {
2174    fn from(pixels: f32) -> Self {
2175        Pixels(pixels)
2176    }
2177}
2178
2179impl Debug for Pixels {
2180    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2181        write!(f, "{} px", self.0)
2182    }
2183}
2184
2185impl From<Pixels> for f32 {
2186    fn from(pixels: Pixels) -> Self {
2187        pixels.0
2188    }
2189}
2190
2191impl From<&Pixels> for f32 {
2192    fn from(pixels: &Pixels) -> Self {
2193        pixels.0
2194    }
2195}
2196
2197impl From<Pixels> for f64 {
2198    fn from(pixels: Pixels) -> Self {
2199        pixels.0 as f64
2200    }
2201}
2202
2203impl From<Pixels> for u32 {
2204    fn from(pixels: Pixels) -> Self {
2205        pixels.0 as u32
2206    }
2207}
2208
2209impl From<u32> for Pixels {
2210    fn from(pixels: u32) -> Self {
2211        Pixels(pixels as f32)
2212    }
2213}
2214
2215impl From<Pixels> for usize {
2216    fn from(pixels: Pixels) -> Self {
2217        pixels.0 as usize
2218    }
2219}
2220
2221impl From<usize> for Pixels {
2222    fn from(pixels: usize) -> Self {
2223        Pixels(pixels as f32)
2224    }
2225}
2226
2227/// Represents physical pixels on the display.
2228///
2229/// `DevicePixels` is a unit of measurement that refers to the actual pixels on a device's screen.
2230/// This type is used when precise pixel manipulation is required, such as rendering graphics or
2231/// interfacing with hardware that operates on the pixel level. Unlike logical pixels that may be
2232/// affected by the device's scale factor, `DevicePixels` always correspond to real pixels on the
2233/// display.
2234#[derive(
2235    Add, AddAssign, Clone, Copy, Default, Div, Eq, Hash, Ord, PartialEq, PartialOrd, Sub, SubAssign,
2236)]
2237#[repr(transparent)]
2238pub struct DevicePixels(pub(crate) i32);
2239
2240impl DevicePixels {
2241    /// Converts the `DevicePixels` value to the number of bytes needed to represent it in memory.
2242    ///
2243    /// This function is useful when working with graphical data that needs to be stored in a buffer,
2244    /// such as images or framebuffers, where each pixel may be represented by a specific number of bytes.
2245    ///
2246    /// # Arguments
2247    ///
2248    /// * `bytes_per_pixel` - The number of bytes used to represent a single pixel.
2249    ///
2250    /// # Returns
2251    ///
2252    /// The number of bytes required to represent the `DevicePixels` value in memory.
2253    ///
2254    /// # Examples
2255    ///
2256    /// ```
2257    /// # use zed::DevicePixels;
2258    /// let pixels = DevicePixels(10); // 10 device pixels
2259    /// let bytes_per_pixel = 4; // Assume each pixel is represented by 4 bytes (e.g., RGBA)
2260    /// let total_bytes = pixels.to_bytes(bytes_per_pixel);
2261    /// assert_eq!(total_bytes, 40); // 10 pixels * 4 bytes/pixel = 40 bytes
2262    /// ```
2263    pub fn to_bytes(&self, bytes_per_pixel: u8) -> u32 {
2264        self.0 as u32 * bytes_per_pixel as u32
2265    }
2266}
2267
2268impl fmt::Debug for DevicePixels {
2269    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2270        write!(f, "{} px (device)", self.0)
2271    }
2272}
2273
2274impl From<DevicePixels> for i32 {
2275    fn from(device_pixels: DevicePixels) -> Self {
2276        device_pixels.0
2277    }
2278}
2279
2280impl From<i32> for DevicePixels {
2281    fn from(device_pixels: i32) -> Self {
2282        DevicePixels(device_pixels)
2283    }
2284}
2285
2286impl From<u32> for DevicePixels {
2287    fn from(device_pixels: u32) -> Self {
2288        DevicePixels(device_pixels as i32)
2289    }
2290}
2291
2292impl From<DevicePixels> for u32 {
2293    fn from(device_pixels: DevicePixels) -> Self {
2294        device_pixels.0 as u32
2295    }
2296}
2297
2298impl From<DevicePixels> for u64 {
2299    fn from(device_pixels: DevicePixels) -> Self {
2300        device_pixels.0 as u64
2301    }
2302}
2303
2304impl From<u64> for DevicePixels {
2305    fn from(device_pixels: u64) -> Self {
2306        DevicePixels(device_pixels as i32)
2307    }
2308}
2309
2310impl From<DevicePixels> for usize {
2311    fn from(device_pixels: DevicePixels) -> Self {
2312        device_pixels.0 as usize
2313    }
2314}
2315
2316impl From<usize> for DevicePixels {
2317    fn from(device_pixels: usize) -> Self {
2318        DevicePixels(device_pixels as i32)
2319    }
2320}
2321
2322/// Represents scaled pixels that take into account the device's scale factor.
2323///
2324/// `ScaledPixels` are used to ensure that UI elements appear at the correct size on devices
2325/// with different pixel densities. When a device has a higher scale factor (such as Retina displays),
2326/// a single logical pixel may correspond to multiple physical pixels. By using `ScaledPixels`,
2327/// dimensions and positions can be specified in a way that scales appropriately across different
2328/// display resolutions.
2329#[derive(Clone, Copy, Default, Add, AddAssign, Sub, SubAssign, Div, PartialEq, PartialOrd)]
2330#[repr(transparent)]
2331pub struct ScaledPixels(pub(crate) f32);
2332
2333impl ScaledPixels {
2334    /// Floors the `ScaledPixels` value to the nearest whole number.
2335    ///
2336    /// # Returns
2337    ///
2338    /// Returns a new `ScaledPixels` instance with the floored value.
2339    pub fn floor(&self) -> Self {
2340        Self(self.0.floor())
2341    }
2342
2343    /// Rounds the `ScaledPixels` value to the nearest whole number.
2344    ///
2345    /// # Returns
2346    ///
2347    /// Returns a new `ScaledPixels` instance with the rounded value.
2348    pub fn ceil(&self) -> Self {
2349        Self(self.0.ceil())
2350    }
2351}
2352
2353impl Eq for ScaledPixels {}
2354
2355impl Debug for ScaledPixels {
2356    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2357        write!(f, "{} px (scaled)", self.0)
2358    }
2359}
2360
2361impl From<ScaledPixels> for DevicePixels {
2362    fn from(scaled: ScaledPixels) -> Self {
2363        DevicePixels(scaled.0.ceil() as i32)
2364    }
2365}
2366
2367impl From<DevicePixels> for ScaledPixels {
2368    fn from(device: DevicePixels) -> Self {
2369        ScaledPixels(device.0 as f32)
2370    }
2371}
2372
2373impl From<ScaledPixels> for f64 {
2374    fn from(scaled_pixels: ScaledPixels) -> Self {
2375        scaled_pixels.0 as f64
2376    }
2377}
2378
2379/// Represents pixels in a global coordinate space, which can span across multiple displays.
2380///
2381/// `GlobalPixels` is used when dealing with a coordinate system that is not limited to a single
2382/// display's boundaries. This type is particularly useful in multi-monitor setups where
2383/// positioning and measurements need to be consistent and relative to a "global" origin point
2384/// rather than being relative to any individual display.
2385#[derive(Clone, Copy, Default, Add, AddAssign, Sub, SubAssign, Div, PartialEq, PartialOrd)]
2386#[repr(transparent)]
2387pub struct GlobalPixels(pub(crate) f32);
2388
2389impl Debug for GlobalPixels {
2390    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2391        write!(f, "{} px (global coordinate space)", self.0)
2392    }
2393}
2394
2395impl From<GlobalPixels> for f64 {
2396    fn from(global_pixels: GlobalPixels) -> Self {
2397        global_pixels.0 as f64
2398    }
2399}
2400
2401impl From<f64> for GlobalPixels {
2402    fn from(global_pixels: f64) -> Self {
2403        GlobalPixels(global_pixels as f32)
2404    }
2405}
2406
2407/// Represents a length in rems, a unit based on the font-size of the window, which can be assigned with [`WindowContext::set_rem_size`][set_rem_size].
2408///
2409/// Rems are used for defining lengths that are scalable and consistent across different UI elements.
2410/// The value of `1rem` is typically equal to the font-size of the root element (often the `<html>` element in browsers),
2411/// making it a flexible unit that adapts to the user's text size preferences. In this framework, `rems` serve a similar
2412/// purpose, allowing for scalable and accessible design that can adjust to different display settings or user preferences.
2413///
2414/// For example, if the root element's font-size is `16px`, then `1rem` equals `16px`. A length of `2rems` would then be `32px`.
2415///
2416/// [set_rem_size]: crate::WindowContext::set_rem_size
2417#[derive(Clone, Copy, Default, Add, Sub, Mul, Div, Neg, PartialEq)]
2418pub struct Rems(pub f32);
2419
2420impl Mul<Pixels> for Rems {
2421    type Output = Pixels;
2422
2423    fn mul(self, other: Pixels) -> Pixels {
2424        Pixels(self.0 * other.0)
2425    }
2426}
2427
2428impl Debug for Rems {
2429    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2430        write!(f, "{} rem", self.0)
2431    }
2432}
2433
2434/// Represents an absolute length in pixels or rems.
2435///
2436/// `AbsoluteLength` can be either a fixed number of pixels, which is an absolute measurement not
2437/// affected by the current font size, or a number of rems, which is relative to the font size of
2438/// the root element. It is used for specifying dimensions that are either independent of or
2439/// related to the typographic scale.
2440#[derive(Clone, Copy, Debug, Neg, PartialEq)]
2441pub enum AbsoluteLength {
2442    /// A length in pixels.
2443    Pixels(Pixels),
2444    /// A length in rems.
2445    Rems(Rems),
2446}
2447
2448impl AbsoluteLength {
2449    /// Checks if the absolute length is zero.
2450    pub fn is_zero(&self) -> bool {
2451        match self {
2452            AbsoluteLength::Pixels(px) => px.0 == 0.0,
2453            AbsoluteLength::Rems(rems) => rems.0 == 0.0,
2454        }
2455    }
2456}
2457
2458impl From<Pixels> for AbsoluteLength {
2459    fn from(pixels: Pixels) -> Self {
2460        AbsoluteLength::Pixels(pixels)
2461    }
2462}
2463
2464impl From<Rems> for AbsoluteLength {
2465    fn from(rems: Rems) -> Self {
2466        AbsoluteLength::Rems(rems)
2467    }
2468}
2469
2470impl AbsoluteLength {
2471    /// Converts an `AbsoluteLength` to `Pixels` based on a given `rem_size`.
2472    ///
2473    /// # Arguments
2474    ///
2475    /// * `rem_size` - The size of one rem in pixels.
2476    ///
2477    /// # Returns
2478    ///
2479    /// Returns the `AbsoluteLength` as `Pixels`.
2480    ///
2481    /// # Examples
2482    ///
2483    /// ```
2484    /// # use zed::{AbsoluteLength, Pixels};
2485    /// let length_in_pixels = AbsoluteLength::Pixels(Pixels(42.0));
2486    /// let length_in_rems = AbsoluteLength::Rems(Rems(2.0));
2487    /// let rem_size = Pixels(16.0);
2488    ///
2489    /// assert_eq!(length_in_pixels.to_pixels(rem_size), Pixels(42.0));
2490    /// assert_eq!(length_in_rems.to_pixels(rem_size), Pixels(32.0));
2491    /// ```
2492    pub fn to_pixels(&self, rem_size: Pixels) -> Pixels {
2493        match self {
2494            AbsoluteLength::Pixels(pixels) => *pixels,
2495            AbsoluteLength::Rems(rems) => *rems * rem_size,
2496        }
2497    }
2498}
2499
2500impl Default for AbsoluteLength {
2501    fn default() -> Self {
2502        px(0.).into()
2503    }
2504}
2505
2506/// A non-auto length that can be defined in pixels, rems, or percent of parent.
2507///
2508/// This enum represents lengths that have a specific value, as opposed to lengths that are automatically
2509/// determined by the context. It includes absolute lengths in pixels or rems, and relative lengths as a
2510/// fraction of the parent's size.
2511#[derive(Clone, Copy, Neg, PartialEq)]
2512pub enum DefiniteLength {
2513    /// An absolute length specified in pixels or rems.
2514    Absolute(AbsoluteLength),
2515    /// A relative length specified as a fraction of the parent's size, between 0 and 1.
2516    Fraction(f32),
2517}
2518
2519impl DefiniteLength {
2520    /// Converts the `DefiniteLength` to `Pixels` based on a given `base_size` and `rem_size`.
2521    ///
2522    /// If the `DefiniteLength` is an absolute length, it will be directly converted to `Pixels`.
2523    /// If it is a fraction, the fraction will be multiplied by the `base_size` to get the length in pixels.
2524    ///
2525    /// # Arguments
2526    ///
2527    /// * `base_size` - The base size in `AbsoluteLength` to which the fraction will be applied.
2528    /// * `rem_size` - The size of one rem in pixels, used to convert rems to pixels.
2529    ///
2530    /// # Returns
2531    ///
2532    /// Returns the `DefiniteLength` as `Pixels`.
2533    ///
2534    /// # Examples
2535    ///
2536    /// ```
2537    /// # use zed::{DefiniteLength, AbsoluteLength, Pixels, px, rems};
2538    /// let length_in_pixels = DefiniteLength::Absolute(AbsoluteLength::Pixels(px(42.0)));
2539    /// let length_in_rems = DefiniteLength::Absolute(AbsoluteLength::Rems(rems(2.0)));
2540    /// let length_as_fraction = DefiniteLength::Fraction(0.5);
2541    /// let base_size = AbsoluteLength::Pixels(px(100.0));
2542    /// let rem_size = px(16.0);
2543    ///
2544    /// assert_eq!(length_in_pixels.to_pixels(base_size, rem_size), Pixels(42.0));
2545    /// assert_eq!(length_in_rems.to_pixels(base_size, rem_size), Pixels(32.0));
2546    /// assert_eq!(length_as_fraction.to_pixels(base_size, rem_size), Pixels(50.0));
2547    /// ```
2548    pub fn to_pixels(&self, base_size: AbsoluteLength, rem_size: Pixels) -> Pixels {
2549        match self {
2550            DefiniteLength::Absolute(size) => size.to_pixels(rem_size),
2551            DefiniteLength::Fraction(fraction) => match base_size {
2552                AbsoluteLength::Pixels(px) => px * *fraction,
2553                AbsoluteLength::Rems(rems) => rems * rem_size * *fraction,
2554            },
2555        }
2556    }
2557}
2558
2559impl Debug for DefiniteLength {
2560    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2561        match self {
2562            DefiniteLength::Absolute(length) => Debug::fmt(length, f),
2563            DefiniteLength::Fraction(fract) => write!(f, "{}%", (fract * 100.0) as i32),
2564        }
2565    }
2566}
2567
2568impl From<Pixels> for DefiniteLength {
2569    fn from(pixels: Pixels) -> Self {
2570        Self::Absolute(pixels.into())
2571    }
2572}
2573
2574impl From<Rems> for DefiniteLength {
2575    fn from(rems: Rems) -> Self {
2576        Self::Absolute(rems.into())
2577    }
2578}
2579
2580impl From<AbsoluteLength> for DefiniteLength {
2581    fn from(length: AbsoluteLength) -> Self {
2582        Self::Absolute(length)
2583    }
2584}
2585
2586impl Default for DefiniteLength {
2587    fn default() -> Self {
2588        Self::Absolute(AbsoluteLength::default())
2589    }
2590}
2591
2592/// A length that can be defined in pixels, rems, percent of parent, or auto.
2593#[derive(Clone, Copy)]
2594pub enum Length {
2595    /// A definite length specified either in pixels, rems, or as a fraction of the parent's size.
2596    Definite(DefiniteLength),
2597    /// An automatic length that is determined by the context in which it is used.
2598    Auto,
2599}
2600
2601impl Debug for Length {
2602    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2603        match self {
2604            Length::Definite(definite_length) => write!(f, "{:?}", definite_length),
2605            Length::Auto => write!(f, "auto"),
2606        }
2607    }
2608}
2609
2610/// Constructs a `DefiniteLength` representing a relative fraction of a parent size.
2611///
2612/// This function creates a `DefiniteLength` that is a specified fraction of a parent's dimension.
2613/// The fraction should be a floating-point number between 0.0 and 1.0, where 1.0 represents 100% of the parent's size.
2614///
2615/// # Arguments
2616///
2617/// * `fraction` - The fraction of the parent's size, between 0.0 and 1.0.
2618///
2619/// # Returns
2620///
2621/// A `DefiniteLength` representing the relative length as a fraction of the parent's size.
2622pub fn relative(fraction: f32) -> DefiniteLength {
2623    DefiniteLength::Fraction(fraction)
2624}
2625
2626/// Returns the Golden Ratio, i.e. `~(1.0 + sqrt(5.0)) / 2.0`.
2627pub fn phi() -> DefiniteLength {
2628    relative(1.618_034)
2629}
2630
2631/// Constructs a `Rems` value representing a length in rems.
2632///
2633/// # Arguments
2634///
2635/// * `rems` - The number of rems for the length.
2636///
2637/// # Returns
2638///
2639/// A `Rems` representing the specified number of rems.
2640pub fn rems(rems: f32) -> Rems {
2641    Rems(rems)
2642}
2643
2644/// Constructs a `Pixels` value representing a length in pixels.
2645///
2646/// # Arguments
2647///
2648/// * `pixels` - The number of pixels for the length.
2649///
2650/// # Returns
2651///
2652/// A `Pixels` representing the specified number of pixels.
2653pub const fn px(pixels: f32) -> Pixels {
2654    Pixels(pixels)
2655}
2656
2657/// Returns a `Length` representing an automatic length.
2658///
2659/// The `auto` length is often used in layout calculations where the length should be determined
2660/// by the layout context itself rather than being explicitly set. This is commonly used in CSS
2661/// for properties like `width`, `height`, `margin`, `padding`, etc., where `auto` can be used
2662/// to instruct the layout engine to calculate the size based on other factors like the size of the
2663/// container or the intrinsic size of the content.
2664///
2665/// # Returns
2666///
2667/// A `Length` variant set to `Auto`.
2668pub fn auto() -> Length {
2669    Length::Auto
2670}
2671
2672impl From<Pixels> for Length {
2673    fn from(pixels: Pixels) -> Self {
2674        Self::Definite(pixels.into())
2675    }
2676}
2677
2678impl From<Rems> for Length {
2679    fn from(rems: Rems) -> Self {
2680        Self::Definite(rems.into())
2681    }
2682}
2683
2684impl From<DefiniteLength> for Length {
2685    fn from(length: DefiniteLength) -> Self {
2686        Self::Definite(length)
2687    }
2688}
2689
2690impl From<AbsoluteLength> for Length {
2691    fn from(length: AbsoluteLength) -> Self {
2692        Self::Definite(length.into())
2693    }
2694}
2695
2696impl Default for Length {
2697    fn default() -> Self {
2698        Self::Definite(DefiniteLength::default())
2699    }
2700}
2701
2702impl From<()> for Length {
2703    fn from(_: ()) -> Self {
2704        Self::Definite(DefiniteLength::default())
2705    }
2706}
2707
2708/// Provides a trait for types that can calculate half of their value.
2709///
2710/// The `Half` trait is used for types that can be evenly divided, returning a new instance of the same type
2711/// representing half of the original value. This is commonly used for types that represent measurements or sizes,
2712/// such as lengths or pixels, where halving is a frequent operation during layout calculations or animations.
2713pub trait Half {
2714    /// Returns half of the current value.
2715    ///
2716    /// # Returns
2717    ///
2718    /// A new instance of the implementing type, representing half of the original value.
2719    fn half(&self) -> Self;
2720}
2721
2722impl Half for i32 {
2723    fn half(&self) -> Self {
2724        self / 2
2725    }
2726}
2727
2728impl Half for f32 {
2729    fn half(&self) -> Self {
2730        self / 2.
2731    }
2732}
2733
2734impl Half for DevicePixels {
2735    fn half(&self) -> Self {
2736        Self(self.0 / 2)
2737    }
2738}
2739
2740impl Half for ScaledPixels {
2741    fn half(&self) -> Self {
2742        Self(self.0 / 2.)
2743    }
2744}
2745
2746impl Half for Pixels {
2747    fn half(&self) -> Self {
2748        Self(self.0 / 2.)
2749    }
2750}
2751
2752impl Half for Rems {
2753    fn half(&self) -> Self {
2754        Self(self.0 / 2.)
2755    }
2756}
2757
2758impl Half for GlobalPixels {
2759    fn half(&self) -> Self {
2760        Self(self.0 / 2.)
2761    }
2762}
2763
2764/// A trait for checking if a value is zero.
2765///
2766/// This trait provides a method to determine if a value is considered to be zero.
2767/// It is implemented for various numeric and length-related types where the concept
2768/// of zero is applicable. This can be useful for comparisons, optimizations, or
2769/// determining if an operation has a neutral effect.
2770pub trait IsZero {
2771    /// Determines if the value is zero.
2772    ///
2773    /// # Returns
2774    ///
2775    /// Returns `true` if the value is zero, `false` otherwise.
2776    fn is_zero(&self) -> bool;
2777}
2778
2779impl IsZero for DevicePixels {
2780    fn is_zero(&self) -> bool {
2781        self.0 == 0
2782    }
2783}
2784
2785impl IsZero for ScaledPixels {
2786    fn is_zero(&self) -> bool {
2787        self.0 == 0.
2788    }
2789}
2790
2791impl IsZero for Pixels {
2792    fn is_zero(&self) -> bool {
2793        self.0 == 0.
2794    }
2795}
2796
2797impl IsZero for Rems {
2798    fn is_zero(&self) -> bool {
2799        self.0 == 0.
2800    }
2801}
2802
2803impl IsZero for AbsoluteLength {
2804    fn is_zero(&self) -> bool {
2805        match self {
2806            AbsoluteLength::Pixels(pixels) => pixels.is_zero(),
2807            AbsoluteLength::Rems(rems) => rems.is_zero(),
2808        }
2809    }
2810}
2811
2812impl IsZero for DefiniteLength {
2813    fn is_zero(&self) -> bool {
2814        match self {
2815            DefiniteLength::Absolute(length) => length.is_zero(),
2816            DefiniteLength::Fraction(fraction) => *fraction == 0.,
2817        }
2818    }
2819}
2820
2821impl IsZero for Length {
2822    fn is_zero(&self) -> bool {
2823        match self {
2824            Length::Definite(length) => length.is_zero(),
2825            Length::Auto => false,
2826        }
2827    }
2828}
2829
2830impl<T: IsZero + Debug + Clone + Default> IsZero for Point<T> {
2831    fn is_zero(&self) -> bool {
2832        self.x.is_zero() && self.y.is_zero()
2833    }
2834}
2835
2836impl<T> IsZero for Size<T>
2837where
2838    T: IsZero + Default + Debug + Clone,
2839{
2840    fn is_zero(&self) -> bool {
2841        self.width.is_zero() || self.height.is_zero()
2842    }
2843}
2844
2845impl<T: IsZero + Debug + Clone + Default> IsZero for Bounds<T> {
2846    fn is_zero(&self) -> bool {
2847        self.size.is_zero()
2848    }
2849}
2850
2851impl<T> IsZero for Corners<T>
2852where
2853    T: IsZero + Clone + Default + Debug,
2854{
2855    fn is_zero(&self) -> bool {
2856        self.top_left.is_zero()
2857            && self.top_right.is_zero()
2858            && self.bottom_right.is_zero()
2859            && self.bottom_left.is_zero()
2860    }
2861}
2862
2863#[cfg(test)]
2864mod tests {
2865    use super::*;
2866
2867    #[test]
2868    fn test_bounds_intersects() {
2869        let bounds1 = Bounds {
2870            origin: Point { x: 0.0, y: 0.0 },
2871            size: Size {
2872                width: 5.0,
2873                height: 5.0,
2874            },
2875        };
2876        let bounds2 = Bounds {
2877            origin: Point { x: 4.0, y: 4.0 },
2878            size: Size {
2879                width: 5.0,
2880                height: 5.0,
2881            },
2882        };
2883        let bounds3 = Bounds {
2884            origin: Point { x: 10.0, y: 10.0 },
2885            size: Size {
2886                width: 5.0,
2887                height: 5.0,
2888            },
2889        };
2890
2891        // Test Case 1: Intersecting bounds
2892        assert_eq!(bounds1.intersects(&bounds2), true);
2893
2894        // Test Case 2: Non-Intersecting bounds
2895        assert_eq!(bounds1.intersects(&bounds3), false);
2896
2897        // Test Case 3: Bounds intersecting with themselves
2898        assert_eq!(bounds1.intersects(&bounds1), true);
2899    }
2900}