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