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