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