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