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