Skip to main content

gpui_core/
geometry.rs

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