Skip to main content

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