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