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