Skip to main content

gpui/
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    pub(crate) fn to_pixels(self, scale_factor: f32) -> Size<Pixels> {
1606        size(
1607            px(self.width.0 as f32 / scale_factor),
1608            px(self.height.0 as f32 / scale_factor),
1609        )
1610    }
1611}
1612
1613impl Size<Pixels> {
1614    /// Converts the size from logical to physical pixels.
1615    pub(crate) fn to_device_pixels(self, scale_factor: f32) -> Size<DevicePixels> {
1616        size(
1617            DevicePixels((self.width.0 * scale_factor).round() as i32),
1618            DevicePixels((self.height.0 * scale_factor).round() as i32),
1619        )
1620    }
1621}
1622
1623impl Bounds<Pixels> {
1624    /// Scales the bounds by a given factor, typically used to adjust for display scaling.
1625    ///
1626    /// This method multiplies the origin and size of the bounds by the provided scaling factor,
1627    /// resulting in a new `Bounds<ScaledPixels>` that is proportionally larger or smaller
1628    /// depending on the scaling factor. This can be used to ensure that the bounds are properly
1629    /// scaled for different display densities.
1630    ///
1631    /// # Arguments
1632    ///
1633    /// * `factor` - The scaling factor to apply to the origin and size, typically the display's scaling factor.
1634    ///
1635    /// # Returns
1636    ///
1637    /// Returns a new `Bounds<ScaledPixels>` that represents the scaled bounds.
1638    ///
1639    /// # Examples
1640    ///
1641    /// ```
1642    /// # use gpui::{Bounds, Point, Size, Pixels, ScaledPixels, DevicePixels};
1643    /// let bounds = Bounds {
1644    ///     origin: Point { x: Pixels::from(10.0), y: Pixels::from(20.0) },
1645    ///     size: Size { width: Pixels::from(30.0), height: Pixels::from(40.0) },
1646    /// };
1647    /// let display_scale_factor = 2.0;
1648    /// let scaled_bounds = bounds.scale(display_scale_factor);
1649    /// assert_eq!(scaled_bounds, Bounds {
1650    ///     origin: Point {
1651    ///         x: ScaledPixels::from(20.0),
1652    ///         y: ScaledPixels::from(40.0),
1653    ///     },
1654    ///     size: Size {
1655    ///         width: ScaledPixels::from(60.0),
1656    ///         height: ScaledPixels::from(80.0)
1657    ///     },
1658    /// });
1659    /// ```
1660    pub fn scale(&self, factor: f32) -> Bounds<ScaledPixels> {
1661        Bounds {
1662            origin: self.origin.scale(factor),
1663            size: self.size.scale(factor),
1664        }
1665    }
1666
1667    /// Convert the bounds from logical pixels to physical pixels
1668    pub fn to_device_pixels(self, factor: f32) -> Bounds<DevicePixels> {
1669        Bounds {
1670            origin: point(
1671                DevicePixels((self.origin.x.0 * factor).round() as i32),
1672                DevicePixels((self.origin.y.0 * factor).round() as i32),
1673            ),
1674            size: self.size.to_device_pixels(factor),
1675        }
1676    }
1677}
1678
1679impl Bounds<DevicePixels> {
1680    /// Convert the bounds from physical pixels to logical pixels
1681    pub fn to_pixels(self, scale_factor: f32) -> Bounds<Pixels> {
1682        Bounds {
1683            origin: point(
1684                px(self.origin.x.0 as f32 / scale_factor),
1685                px(self.origin.y.0 as f32 / scale_factor),
1686            ),
1687            size: self.size.to_pixels(scale_factor),
1688        }
1689    }
1690}
1691
1692impl<T: Copy + Clone + Debug + Default + PartialEq> Copy for Bounds<T> {}
1693
1694/// Represents the edges of a box in a 2D space, such as padding or margin.
1695///
1696/// Each field represents the size of the edge on one side of the box: `top`, `right`, `bottom`, and `left`.
1697///
1698/// # Examples
1699///
1700/// ```
1701/// # use gpui::Edges;
1702/// let edges = Edges {
1703///     top: 10.0,
1704///     right: 20.0,
1705///     bottom: 30.0,
1706///     left: 40.0,
1707/// };
1708///
1709/// assert_eq!(edges.top, 10.0);
1710/// assert_eq!(edges.right, 20.0);
1711/// assert_eq!(edges.bottom, 30.0);
1712/// assert_eq!(edges.left, 40.0);
1713/// ```
1714#[derive(Refineable, Clone, Default, Debug, Eq, PartialEq)]
1715#[refineable(Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
1716#[repr(C)]
1717pub struct Edges<T: Clone + Debug + Default + PartialEq> {
1718    /// The size of the top edge.
1719    pub top: T,
1720    /// The size of the right edge.
1721    pub right: T,
1722    /// The size of the bottom edge.
1723    pub bottom: T,
1724    /// The size of the left edge.
1725    pub left: T,
1726}
1727
1728impl<T> Mul for Edges<T>
1729where
1730    T: Mul<Output = T> + Clone + Debug + Default + PartialEq,
1731{
1732    type Output = Self;
1733
1734    fn mul(self, rhs: Self) -> Self::Output {
1735        Self {
1736            top: self.top.clone() * rhs.top,
1737            right: self.right.clone() * rhs.right,
1738            bottom: self.bottom.clone() * rhs.bottom,
1739            left: self.left * rhs.left,
1740        }
1741    }
1742}
1743
1744impl<T, S> MulAssign<S> for Edges<T>
1745where
1746    T: Mul<S, Output = T> + Clone + Debug + Default + PartialEq,
1747    S: Clone,
1748{
1749    fn mul_assign(&mut self, rhs: S) {
1750        self.top = self.top.clone() * rhs.clone();
1751        self.right = self.right.clone() * rhs.clone();
1752        self.bottom = self.bottom.clone() * rhs.clone();
1753        self.left = self.left.clone() * rhs;
1754    }
1755}
1756
1757impl<T: Clone + Debug + Default + PartialEq + Copy> Copy for Edges<T> {}
1758
1759impl<T: Clone + Debug + Default + PartialEq> Edges<T> {
1760    /// Constructs `Edges` where all sides are set to the same specified value.
1761    ///
1762    /// This function creates an `Edges` instance with the `top`, `right`, `bottom`, and `left` fields all initialized
1763    /// to the same value provided as an argument. This is useful when you want to have uniform edges around a box,
1764    /// such as padding or margin with the same size on all sides.
1765    ///
1766    /// # Arguments
1767    ///
1768    /// * `value` - The value to set for all four sides of the edges.
1769    ///
1770    /// # Returns
1771    ///
1772    /// An `Edges` instance with all sides set to the given value.
1773    ///
1774    /// # Examples
1775    ///
1776    /// ```
1777    /// # use gpui::Edges;
1778    /// let uniform_edges = Edges::all(10.0);
1779    /// assert_eq!(uniform_edges.top, 10.0);
1780    /// assert_eq!(uniform_edges.right, 10.0);
1781    /// assert_eq!(uniform_edges.bottom, 10.0);
1782    /// assert_eq!(uniform_edges.left, 10.0);
1783    /// ```
1784    pub fn all(value: T) -> Self {
1785        Self {
1786            top: value.clone(),
1787            right: value.clone(),
1788            bottom: value.clone(),
1789            left: value,
1790        }
1791    }
1792
1793    /// Applies a function to each field of the `Edges`, producing a new `Edges<U>`.
1794    ///
1795    /// This method allows for converting an `Edges<T>` to an `Edges<U>` by specifying a closure
1796    /// that defines how to convert between the two types. The closure is applied to each field
1797    /// (`top`, `right`, `bottom`, `left`), resulting in new edges of the desired type.
1798    ///
1799    /// # Arguments
1800    ///
1801    /// * `f` - A closure that takes a reference to a value of type `T` and returns a value of type `U`.
1802    ///
1803    /// # Returns
1804    ///
1805    /// Returns a new `Edges<U>` with each field mapped by the provided function.
1806    ///
1807    /// # Examples
1808    ///
1809    /// ```
1810    /// # use gpui::Edges;
1811    /// let edges = Edges { top: 10, right: 20, bottom: 30, left: 40 };
1812    /// let edges_float = edges.map(|&value| value as f32 * 1.1);
1813    /// assert_eq!(edges_float, Edges { top: 11.0, right: 22.0, bottom: 33.0, left: 44.0 });
1814    /// ```
1815    pub fn map<U>(&self, f: impl Fn(&T) -> U) -> Edges<U>
1816    where
1817        U: Clone + Debug + Default + PartialEq,
1818    {
1819        Edges {
1820            top: f(&self.top),
1821            right: f(&self.right),
1822            bottom: f(&self.bottom),
1823            left: f(&self.left),
1824        }
1825    }
1826
1827    /// Checks if any of the edges satisfy a given predicate.
1828    ///
1829    /// This method applies a predicate function to each field of the `Edges` and returns `true` if any field satisfies the predicate.
1830    ///
1831    /// # Arguments
1832    ///
1833    /// * `predicate` - A closure that takes a reference to a value of type `T` and returns a `bool`.
1834    ///
1835    /// # Returns
1836    ///
1837    /// Returns `true` if the predicate returns `true` for any of the edge values, `false` otherwise.
1838    ///
1839    /// # Examples
1840    ///
1841    /// ```
1842    /// # use gpui::Edges;
1843    /// let edges = Edges {
1844    ///     top: 10,
1845    ///     right: 0,
1846    ///     bottom: 5,
1847    ///     left: 0,
1848    /// };
1849    ///
1850    /// assert!(edges.any(|value| *value == 0));
1851    /// assert!(edges.any(|value| *value > 0));
1852    /// assert!(!edges.any(|value| *value > 10));
1853    /// ```
1854    pub fn any<F: Fn(&T) -> bool>(&self, predicate: F) -> bool {
1855        predicate(&self.top)
1856            || predicate(&self.right)
1857            || predicate(&self.bottom)
1858            || predicate(&self.left)
1859    }
1860}
1861
1862impl Edges<Length> {
1863    /// 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.
1864    ///
1865    /// 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.
1866    ///
1867    /// # Returns
1868    ///
1869    /// Returns an `Edges<Length>` with all edges set to `Length::Auto`.
1870    ///
1871    /// # Examples
1872    ///
1873    /// ```
1874    /// # use gpui::{Edges, Length};
1875    /// let auto_edges = Edges::auto();
1876    /// assert_eq!(auto_edges.top, Length::Auto);
1877    /// assert_eq!(auto_edges.right, Length::Auto);
1878    /// assert_eq!(auto_edges.bottom, Length::Auto);
1879    /// assert_eq!(auto_edges.left, Length::Auto);
1880    /// ```
1881    pub fn auto() -> Self {
1882        Self {
1883            top: Length::Auto,
1884            right: Length::Auto,
1885            bottom: Length::Auto,
1886            left: Length::Auto,
1887        }
1888    }
1889
1890    /// Sets the edges of the `Edges` struct to zero, which means no size or thickness.
1891    ///
1892    /// This is typically used when you want to specify that a box (like a padding or margin area)
1893    /// should have no edges, effectively making it non-existent or invisible in layout calculations.
1894    ///
1895    /// # Returns
1896    ///
1897    /// Returns an `Edges<Length>` with all edges set to zero length.
1898    ///
1899    /// # Examples
1900    ///
1901    /// ```
1902    /// # use gpui::{DefiniteLength, Edges, Length, Pixels};
1903    /// let no_edges = Edges::<Length>::zero();
1904    /// assert_eq!(no_edges.top, Length::Definite(DefiniteLength::from(Pixels::ZERO)));
1905    /// assert_eq!(no_edges.right, Length::Definite(DefiniteLength::from(Pixels::ZERO)));
1906    /// assert_eq!(no_edges.bottom, Length::Definite(DefiniteLength::from(Pixels::ZERO)));
1907    /// assert_eq!(no_edges.left, Length::Definite(DefiniteLength::from(Pixels::ZERO)));
1908    /// ```
1909    pub fn zero() -> Self {
1910        Self {
1911            top: px(0.).into(),
1912            right: px(0.).into(),
1913            bottom: px(0.).into(),
1914            left: px(0.).into(),
1915        }
1916    }
1917}
1918
1919impl Edges<DefiniteLength> {
1920    /// Sets the edges of the `Edges` struct to zero, which means no size or thickness.
1921    ///
1922    /// This is typically used when you want to specify that a box (like a padding or margin area)
1923    /// should have no edges, effectively making it non-existent or invisible in layout calculations.
1924    ///
1925    /// # Returns
1926    ///
1927    /// Returns an `Edges<DefiniteLength>` with all edges set to zero length.
1928    ///
1929    /// # Examples
1930    ///
1931    /// ```
1932    /// # use gpui::{px, DefiniteLength, Edges};
1933    /// let no_edges = Edges::<DefiniteLength>::zero();
1934    /// assert_eq!(no_edges.top, DefiniteLength::from(px(0.)));
1935    /// assert_eq!(no_edges.right, DefiniteLength::from(px(0.)));
1936    /// assert_eq!(no_edges.bottom, DefiniteLength::from(px(0.)));
1937    /// assert_eq!(no_edges.left, DefiniteLength::from(px(0.)));
1938    /// ```
1939    pub fn zero() -> Self {
1940        Self {
1941            top: px(0.).into(),
1942            right: px(0.).into(),
1943            bottom: px(0.).into(),
1944            left: px(0.).into(),
1945        }
1946    }
1947
1948    /// Converts the `DefiniteLength` to `Pixels` based on the parent size and the REM size.
1949    ///
1950    /// This method allows for a `DefiniteLength` value to be converted into pixels, taking into account
1951    /// the size of the parent element (for percentage-based lengths) and the size of a rem unit (for rem-based lengths).
1952    ///
1953    /// # Arguments
1954    ///
1955    /// * `parent_size` - `Size<AbsoluteLength>` representing the size of the parent element.
1956    /// * `rem_size` - `Pixels` representing the size of one REM unit.
1957    ///
1958    /// # Returns
1959    ///
1960    /// Returns an `Edges<Pixels>` representing the edges with lengths converted to pixels.
1961    ///
1962    /// # Examples
1963    ///
1964    /// ```
1965    /// # use gpui::{Edges, DefiniteLength, px, AbsoluteLength, rems, Size};
1966    /// let edges = Edges {
1967    ///     top: DefiniteLength::Absolute(AbsoluteLength::Pixels(px(10.0))),
1968    ///     right: DefiniteLength::Fraction(0.5),
1969    ///     bottom: DefiniteLength::Absolute(AbsoluteLength::Rems(rems(2.0))),
1970    ///     left: DefiniteLength::Fraction(0.25),
1971    /// };
1972    /// let parent_size = Size {
1973    ///     width: AbsoluteLength::Pixels(px(200.0)),
1974    ///     height: AbsoluteLength::Pixels(px(100.0)),
1975    /// };
1976    /// let rem_size = px(16.0);
1977    /// let edges_in_pixels = edges.to_pixels(parent_size, rem_size);
1978    ///
1979    /// assert_eq!(edges_in_pixels.top, px(10.0)); // Absolute length in pixels
1980    /// assert_eq!(edges_in_pixels.right, px(100.0)); // 50% of parent width
1981    /// assert_eq!(edges_in_pixels.bottom, px(32.0)); // 2 rems
1982    /// assert_eq!(edges_in_pixels.left, px(50.0)); // 25% of parent width
1983    /// ```
1984    pub fn to_pixels(self, parent_size: Size<AbsoluteLength>, rem_size: Pixels) -> Edges<Pixels> {
1985        Edges {
1986            top: self.top.to_pixels(parent_size.height, rem_size),
1987            right: self.right.to_pixels(parent_size.width, rem_size),
1988            bottom: self.bottom.to_pixels(parent_size.height, rem_size),
1989            left: self.left.to_pixels(parent_size.width, rem_size),
1990        }
1991    }
1992}
1993
1994impl Edges<AbsoluteLength> {
1995    /// Sets the edges of the `Edges` struct to zero, which means no size or thickness.
1996    ///
1997    /// This is typically used when you want to specify that a box (like a padding or margin area)
1998    /// should have no edges, effectively making it non-existent or invisible in layout calculations.
1999    ///
2000    /// # Returns
2001    ///
2002    /// Returns an `Edges<AbsoluteLength>` with all edges set to zero length.
2003    ///
2004    /// # Examples
2005    ///
2006    /// ```
2007    /// # use gpui::{AbsoluteLength, Edges, Pixels};
2008    /// let no_edges = Edges::<AbsoluteLength>::zero();
2009    /// assert_eq!(no_edges.top, AbsoluteLength::Pixels(Pixels::ZERO));
2010    /// assert_eq!(no_edges.right, AbsoluteLength::Pixels(Pixels::ZERO));
2011    /// assert_eq!(no_edges.bottom, AbsoluteLength::Pixels(Pixels::ZERO));
2012    /// assert_eq!(no_edges.left, AbsoluteLength::Pixels(Pixels::ZERO));
2013    /// ```
2014    pub fn zero() -> Self {
2015        Self {
2016            top: px(0.).into(),
2017            right: px(0.).into(),
2018            bottom: px(0.).into(),
2019            left: px(0.).into(),
2020        }
2021    }
2022
2023    /// Converts the `AbsoluteLength` to `Pixels` based on the `rem_size`.
2024    ///
2025    /// If the `AbsoluteLength` is already in pixels, it simply returns the corresponding `Pixels` value.
2026    /// If the `AbsoluteLength` is in rems, it multiplies the number of rems by the `rem_size` to convert it to pixels.
2027    ///
2028    /// # Arguments
2029    ///
2030    /// * `rem_size` - The size of one rem unit in pixels.
2031    ///
2032    /// # Returns
2033    ///
2034    /// Returns an `Edges<Pixels>` representing the edges with lengths converted to pixels.
2035    ///
2036    /// # Examples
2037    ///
2038    /// ```
2039    /// # use gpui::{Edges, AbsoluteLength, Pixels, px, rems};
2040    /// let edges = Edges {
2041    ///     top: AbsoluteLength::Pixels(px(10.0)),
2042    ///     right: AbsoluteLength::Rems(rems(1.0)),
2043    ///     bottom: AbsoluteLength::Pixels(px(20.0)),
2044    ///     left: AbsoluteLength::Rems(rems(2.0)),
2045    /// };
2046    /// let rem_size = px(16.0);
2047    /// let edges_in_pixels = edges.to_pixels(rem_size);
2048    ///
2049    /// assert_eq!(edges_in_pixels.top, px(10.0)); // Already in pixels
2050    /// assert_eq!(edges_in_pixels.right, px(16.0)); // 1 rem converted to pixels
2051    /// assert_eq!(edges_in_pixels.bottom, px(20.0)); // Already in pixels
2052    /// assert_eq!(edges_in_pixels.left, px(32.0)); // 2 rems converted to pixels
2053    /// ```
2054    pub fn to_pixels(self, rem_size: Pixels) -> Edges<Pixels> {
2055        Edges {
2056            top: self.top.to_pixels(rem_size),
2057            right: self.right.to_pixels(rem_size),
2058            bottom: self.bottom.to_pixels(rem_size),
2059            left: self.left.to_pixels(rem_size),
2060        }
2061    }
2062}
2063
2064impl Edges<Pixels> {
2065    /// Scales the `Edges<Pixels>` by a given factor, returning `Edges<ScaledPixels>`.
2066    ///
2067    /// This method is typically used for adjusting the edge sizes for different display densities or scaling factors.
2068    ///
2069    /// # Arguments
2070    ///
2071    /// * `factor` - The scaling factor to apply to each edge.
2072    ///
2073    /// # Returns
2074    ///
2075    /// Returns a new `Edges<ScaledPixels>` where each edge is the result of scaling the original edge by the given factor.
2076    ///
2077    /// # Examples
2078    ///
2079    /// ```
2080    /// # use gpui::{Edges, Pixels, ScaledPixels};
2081    /// let edges = Edges {
2082    ///     top: Pixels::from(10.0),
2083    ///     right: Pixels::from(20.0),
2084    ///     bottom: Pixels::from(30.0),
2085    ///     left: Pixels::from(40.0),
2086    /// };
2087    /// let scaled_edges = edges.scale(2.0);
2088    /// assert_eq!(scaled_edges.top, ScaledPixels::from(20.0));
2089    /// assert_eq!(scaled_edges.right, ScaledPixels::from(40.0));
2090    /// assert_eq!(scaled_edges.bottom, ScaledPixels::from(60.0));
2091    /// assert_eq!(scaled_edges.left, ScaledPixels::from(80.0));
2092    /// ```
2093    pub fn scale(&self, factor: f32) -> Edges<ScaledPixels> {
2094        Edges {
2095            top: self.top.scale(factor),
2096            right: self.right.scale(factor),
2097            bottom: self.bottom.scale(factor),
2098            left: self.left.scale(factor),
2099        }
2100    }
2101
2102    /// Returns the maximum value of any edge.
2103    ///
2104    /// # Returns
2105    ///
2106    /// The maximum `Pixels` value among all four edges.
2107    pub fn max(&self) -> Pixels {
2108        self.top.max(self.right).max(self.bottom).max(self.left)
2109    }
2110}
2111
2112impl From<f32> for Edges<Pixels> {
2113    fn from(val: f32) -> Self {
2114        let val: Pixels = val.into();
2115        val.into()
2116    }
2117}
2118
2119impl From<Pixels> for Edges<Pixels> {
2120    fn from(val: Pixels) -> Self {
2121        Edges {
2122            top: val,
2123            right: val,
2124            bottom: val,
2125            left: val,
2126        }
2127    }
2128}
2129
2130/// Identifies a corner of a 2d box.
2131#[derive(Clone, Copy, Debug, PartialEq, Eq)]
2132pub enum Corner {
2133    /// The top left corner
2134    TopLeft,
2135    /// The top right corner
2136    TopRight,
2137    /// The bottom left corner
2138    BottomLeft,
2139    /// The bottom right corner
2140    BottomRight,
2141}
2142
2143impl Corner {
2144    /// Returns the directly opposite corner.
2145    ///
2146    /// # Examples
2147    ///
2148    /// ```
2149    /// # use gpui::Corner;
2150    /// assert_eq!(Corner::TopLeft.opposite_corner(), Corner::BottomRight);
2151    /// ```
2152    #[must_use]
2153    pub fn opposite_corner(self) -> Self {
2154        match self {
2155            Corner::TopLeft => Corner::BottomRight,
2156            Corner::TopRight => Corner::BottomLeft,
2157            Corner::BottomLeft => Corner::TopRight,
2158            Corner::BottomRight => Corner::TopLeft,
2159        }
2160    }
2161
2162    /// Returns the corner across from this corner, moving along the specified axis.
2163    ///
2164    /// # Examples
2165    ///
2166    /// ```
2167    /// # use gpui::{Axis, Corner};
2168    /// let result = Corner::TopLeft.other_side_corner_along(Axis::Horizontal);
2169    /// assert_eq!(result, Corner::TopRight);
2170    /// ```
2171    #[must_use]
2172    pub fn other_side_corner_along(self, axis: Axis) -> Self {
2173        match axis {
2174            Axis::Vertical => match self {
2175                Corner::TopLeft => Corner::BottomLeft,
2176                Corner::TopRight => Corner::BottomRight,
2177                Corner::BottomLeft => Corner::TopLeft,
2178                Corner::BottomRight => Corner::TopRight,
2179            },
2180            Axis::Horizontal => match self {
2181                Corner::TopLeft => Corner::TopRight,
2182                Corner::TopRight => Corner::TopLeft,
2183                Corner::BottomLeft => Corner::BottomRight,
2184                Corner::BottomRight => Corner::BottomLeft,
2185            },
2186        }
2187    }
2188}
2189
2190/// Represents the corners of a box in a 2D space, such as border radius.
2191///
2192/// Each field represents the size of the corner on one side of the box: `top_left`, `top_right`, `bottom_right`, and `bottom_left`.
2193#[derive(Refineable, Clone, Default, Debug, Eq, PartialEq)]
2194#[refineable(Debug, PartialEq, Serialize, Deserialize, JsonSchema)]
2195#[repr(C)]
2196pub struct Corners<T: Clone + Debug + Default + PartialEq> {
2197    /// The value associated with the top left corner.
2198    pub top_left: T,
2199    /// The value associated with the top right corner.
2200    pub top_right: T,
2201    /// The value associated with the bottom right corner.
2202    pub bottom_right: T,
2203    /// The value associated with the bottom left corner.
2204    pub bottom_left: T,
2205}
2206
2207impl<T> Corners<T>
2208where
2209    T: Clone + Debug + Default + PartialEq,
2210{
2211    /// Constructs `Corners` where all sides are set to the same specified value.
2212    ///
2213    /// This function creates a `Corners` instance with the `top_left`, `top_right`, `bottom_right`, and `bottom_left` fields all initialized
2214    /// to the same value provided as an argument. This is useful when you want to have uniform corners around a box,
2215    /// such as a uniform border radius on a rectangle.
2216    ///
2217    /// # Arguments
2218    ///
2219    /// * `value` - The value to set for all four corners.
2220    ///
2221    /// # Returns
2222    ///
2223    /// An `Corners` instance with all corners set to the given value.
2224    ///
2225    /// # Examples
2226    ///
2227    /// ```
2228    /// # use gpui::Corners;
2229    /// let uniform_corners = Corners::all(5.0);
2230    /// assert_eq!(uniform_corners.top_left, 5.0);
2231    /// assert_eq!(uniform_corners.top_right, 5.0);
2232    /// assert_eq!(uniform_corners.bottom_right, 5.0);
2233    /// assert_eq!(uniform_corners.bottom_left, 5.0);
2234    /// ```
2235    pub fn all(value: T) -> Self {
2236        Self {
2237            top_left: value.clone(),
2238            top_right: value.clone(),
2239            bottom_right: value.clone(),
2240            bottom_left: value,
2241        }
2242    }
2243
2244    /// Returns the requested corner.
2245    ///
2246    /// # Returns
2247    ///
2248    /// A `Point<T>` representing the corner requested by the parameter.
2249    ///
2250    /// # Examples
2251    ///
2252    /// ```
2253    /// # use gpui::{Corner, Corners};
2254    /// let corners = Corners {
2255    ///     top_left: 1,
2256    ///     top_right: 2,
2257    ///     bottom_left: 3,
2258    ///     bottom_right: 4
2259    /// };
2260    /// assert_eq!(corners.corner(Corner::BottomLeft), 3);
2261    /// ```
2262    #[must_use]
2263    pub fn corner(&self, corner: Corner) -> T {
2264        match corner {
2265            Corner::TopLeft => self.top_left.clone(),
2266            Corner::TopRight => self.top_right.clone(),
2267            Corner::BottomLeft => self.bottom_left.clone(),
2268            Corner::BottomRight => self.bottom_right.clone(),
2269        }
2270    }
2271}
2272
2273impl Corners<AbsoluteLength> {
2274    /// Converts the `AbsoluteLength` to `Pixels` based on the provided rem size.
2275    ///
2276    /// # Arguments
2277    ///
2278    /// * `rem_size` - The size of one REM unit in pixels, used for conversion if the `AbsoluteLength` is in REMs.
2279    ///
2280    /// # Returns
2281    ///
2282    /// Returns a `Corners<Pixels>` instance with each corner's length converted to pixels.
2283    ///
2284    /// # Examples
2285    ///
2286    /// ```
2287    /// # use gpui::{Corners, AbsoluteLength, Pixels, Rems, Size};
2288    /// let corners = Corners {
2289    ///     top_left: AbsoluteLength::Pixels(Pixels::from(15.0)),
2290    ///     top_right: AbsoluteLength::Rems(Rems(1.0)),
2291    ///     bottom_right: AbsoluteLength::Pixels(Pixels::from(30.0)),
2292    ///     bottom_left: AbsoluteLength::Rems(Rems(2.0)),
2293    /// };
2294    /// let rem_size = Pixels::from(16.0);
2295    /// let corners_in_pixels = corners.to_pixels(rem_size);
2296    ///
2297    /// assert_eq!(corners_in_pixels.top_left, Pixels::from(15.0));
2298    /// assert_eq!(corners_in_pixels.top_right, Pixels::from(16.0)); // 1 rem converted to pixels
2299    /// assert_eq!(corners_in_pixels.bottom_right, Pixels::from(30.0));
2300    /// assert_eq!(corners_in_pixels.bottom_left, Pixels::from(32.0)); // 2 rems converted to pixels
2301    /// ```
2302    pub fn to_pixels(self, rem_size: Pixels) -> Corners<Pixels> {
2303        Corners {
2304            top_left: self.top_left.to_pixels(rem_size),
2305            top_right: self.top_right.to_pixels(rem_size),
2306            bottom_right: self.bottom_right.to_pixels(rem_size),
2307            bottom_left: self.bottom_left.to_pixels(rem_size),
2308        }
2309    }
2310}
2311
2312impl Corners<Pixels> {
2313    /// Scales the `Corners<Pixels>` by a given factor, returning `Corners<ScaledPixels>`.
2314    ///
2315    /// This method is typically used for adjusting the corner sizes for different display densities or scaling factors.
2316    ///
2317    /// # Arguments
2318    ///
2319    /// * `factor` - The scaling factor to apply to each corner.
2320    ///
2321    /// # Returns
2322    ///
2323    /// Returns a new `Corners<ScaledPixels>` where each corner is the result of scaling the original corner by the given factor.
2324    ///
2325    /// # Examples
2326    ///
2327    /// ```
2328    /// # use gpui::{Corners, Pixels, ScaledPixels};
2329    /// let corners = Corners {
2330    ///     top_left: Pixels::from(10.0),
2331    ///     top_right: Pixels::from(20.0),
2332    ///     bottom_right: Pixels::from(30.0),
2333    ///     bottom_left: Pixels::from(40.0),
2334    /// };
2335    /// let scaled_corners = corners.scale(2.0);
2336    /// assert_eq!(scaled_corners.top_left, ScaledPixels::from(20.0));
2337    /// assert_eq!(scaled_corners.top_right, ScaledPixels::from(40.0));
2338    /// assert_eq!(scaled_corners.bottom_right, ScaledPixels::from(60.0));
2339    /// assert_eq!(scaled_corners.bottom_left, ScaledPixels::from(80.0));
2340    /// ```
2341    #[must_use]
2342    pub fn scale(&self, factor: f32) -> Corners<ScaledPixels> {
2343        Corners {
2344            top_left: self.top_left.scale(factor),
2345            top_right: self.top_right.scale(factor),
2346            bottom_right: self.bottom_right.scale(factor),
2347            bottom_left: self.bottom_left.scale(factor),
2348        }
2349    }
2350
2351    /// Returns the maximum value of any corner.
2352    ///
2353    /// # Returns
2354    ///
2355    /// The maximum `Pixels` value among all four corners.
2356    #[must_use]
2357    pub fn max(&self) -> Pixels {
2358        self.top_left
2359            .max(self.top_right)
2360            .max(self.bottom_right)
2361            .max(self.bottom_left)
2362    }
2363}
2364
2365impl<T: Div<f32, Output = T> + Ord + Clone + Debug + Default + PartialEq> Corners<T> {
2366    /// Clamps corner radii to be less than or equal to half the shortest side of a quad.
2367    ///
2368    /// # Arguments
2369    ///
2370    /// * `size` - The size of the quad which limits the size of the corner radii.
2371    ///
2372    /// # Returns
2373    ///
2374    /// Corner radii values clamped to fit.
2375    #[must_use]
2376    pub fn clamp_radii_for_quad_size(self, size: Size<T>) -> Corners<T> {
2377        let max = cmp::min(size.width, size.height) / 2.;
2378        Corners {
2379            top_left: cmp::min(self.top_left, max.clone()),
2380            top_right: cmp::min(self.top_right, max.clone()),
2381            bottom_right: cmp::min(self.bottom_right, max.clone()),
2382            bottom_left: cmp::min(self.bottom_left, max),
2383        }
2384    }
2385}
2386
2387impl<T: Clone + Debug + Default + PartialEq> Corners<T> {
2388    /// Applies a function to each field of the `Corners`, producing a new `Corners<U>`.
2389    ///
2390    /// This method allows for converting a `Corners<T>` to a `Corners<U>` by specifying a closure
2391    /// that defines how to convert between the two types. The closure is applied to each field
2392    /// (`top_left`, `top_right`, `bottom_right`, `bottom_left`), resulting in new corners of the desired type.
2393    ///
2394    /// # Arguments
2395    ///
2396    /// * `f` - A closure that takes a reference to a value of type `T` and returns a value of type `U`.
2397    ///
2398    /// # Returns
2399    ///
2400    /// Returns a new `Corners<U>` with each field mapped by the provided function.
2401    ///
2402    /// # Examples
2403    ///
2404    /// ```
2405    /// # use gpui::{Corners, Pixels, Rems};
2406    /// let corners = Corners {
2407    ///     top_left: Pixels::from(10.0),
2408    ///     top_right: Pixels::from(20.0),
2409    ///     bottom_right: Pixels::from(30.0),
2410    ///     bottom_left: Pixels::from(40.0),
2411    /// };
2412    /// let corners_in_rems = corners.map(|&px| Rems(f32::from(px) / 16.0));
2413    /// assert_eq!(corners_in_rems, Corners {
2414    ///     top_left: Rems(0.625),
2415    ///     top_right: Rems(1.25),
2416    ///     bottom_right: Rems(1.875),
2417    ///     bottom_left: Rems(2.5),
2418    /// });
2419    /// ```
2420    #[must_use]
2421    pub fn map<U>(&self, f: impl Fn(&T) -> U) -> Corners<U>
2422    where
2423        U: Clone + Debug + Default + PartialEq,
2424    {
2425        Corners {
2426            top_left: f(&self.top_left),
2427            top_right: f(&self.top_right),
2428            bottom_right: f(&self.bottom_right),
2429            bottom_left: f(&self.bottom_left),
2430        }
2431    }
2432}
2433
2434impl<T> Mul for Corners<T>
2435where
2436    T: Mul<Output = T> + Clone + Debug + Default + PartialEq,
2437{
2438    type Output = Self;
2439
2440    fn mul(self, rhs: Self) -> Self::Output {
2441        Self {
2442            top_left: self.top_left.clone() * rhs.top_left,
2443            top_right: self.top_right.clone() * rhs.top_right,
2444            bottom_right: self.bottom_right.clone() * rhs.bottom_right,
2445            bottom_left: self.bottom_left * rhs.bottom_left,
2446        }
2447    }
2448}
2449
2450impl<T, S> MulAssign<S> for Corners<T>
2451where
2452    T: Mul<S, Output = T> + Clone + Debug + Default + PartialEq,
2453    S: Clone,
2454{
2455    fn mul_assign(&mut self, rhs: S) {
2456        self.top_left = self.top_left.clone() * rhs.clone();
2457        self.top_right = self.top_right.clone() * rhs.clone();
2458        self.bottom_right = self.bottom_right.clone() * rhs.clone();
2459        self.bottom_left = self.bottom_left.clone() * rhs;
2460    }
2461}
2462
2463impl<T> Copy for Corners<T> where T: Copy + Clone + Debug + Default + PartialEq {}
2464
2465impl From<f32> for Corners<Pixels> {
2466    fn from(val: f32) -> Self {
2467        Corners {
2468            top_left: val.into(),
2469            top_right: val.into(),
2470            bottom_right: val.into(),
2471            bottom_left: val.into(),
2472        }
2473    }
2474}
2475
2476impl From<Pixels> for Corners<Pixels> {
2477    fn from(val: Pixels) -> Self {
2478        Corners {
2479            top_left: val,
2480            top_right: val,
2481            bottom_right: val,
2482            bottom_left: val,
2483        }
2484    }
2485}
2486
2487/// Represents an angle in Radians
2488#[derive(
2489    Clone,
2490    Copy,
2491    Default,
2492    Add,
2493    AddAssign,
2494    Sub,
2495    SubAssign,
2496    Neg,
2497    Div,
2498    DivAssign,
2499    PartialEq,
2500    Serialize,
2501    Deserialize,
2502    Debug,
2503)]
2504#[repr(transparent)]
2505pub struct Radians(pub f32);
2506
2507/// Create a `Radian` from a raw value
2508pub fn radians(value: f32) -> Radians {
2509    Radians(value)
2510}
2511
2512/// A type representing a percentage value.
2513#[derive(
2514    Clone,
2515    Copy,
2516    Default,
2517    Add,
2518    AddAssign,
2519    Sub,
2520    SubAssign,
2521    Neg,
2522    Div,
2523    DivAssign,
2524    PartialEq,
2525    Serialize,
2526    Deserialize,
2527    Debug,
2528)]
2529#[repr(transparent)]
2530pub struct Percentage(pub f32);
2531
2532/// Generate a `Radian` from a percentage of a full circle.
2533pub fn percentage(value: f32) -> Percentage {
2534    debug_assert!(
2535        (0.0..=1.0).contains(&value),
2536        "Percentage must be between 0 and 1"
2537    );
2538    Percentage(value)
2539}
2540
2541impl From<Percentage> for Radians {
2542    fn from(value: Percentage) -> Self {
2543        radians(value.0 * std::f32::consts::PI * 2.0)
2544    }
2545}
2546
2547/// Represents a length in pixels, the base unit of measurement in the UI framework.
2548///
2549/// `Pixels` is a value type that represents an absolute length in pixels, which is used
2550/// for specifying sizes, positions, and distances in the UI. It is the fundamental unit
2551/// of measurement for all visual elements and layout calculations.
2552///
2553/// The inner value is an `f32`, allowing for sub-pixel precision which can be useful for
2554/// anti-aliasing and animations. However, when applied to actual pixel grids, the value
2555/// is typically rounded to the nearest integer.
2556///
2557/// # Examples
2558///
2559/// ```
2560/// use gpui::{Pixels, ScaledPixels};
2561///
2562/// // Define a length of 10 pixels
2563/// let length = Pixels::from(10.0);
2564///
2565/// // Define a length and scale it by a factor of 2
2566/// let scaled_length = length.scale(2.0);
2567/// assert_eq!(scaled_length, ScaledPixels::from(20.0));
2568/// ```
2569#[derive(
2570    Clone,
2571    Copy,
2572    Default,
2573    Add,
2574    AddAssign,
2575    Sub,
2576    SubAssign,
2577    Neg,
2578    Div,
2579    DivAssign,
2580    PartialEq,
2581    Serialize,
2582    Deserialize,
2583    JsonSchema,
2584)]
2585#[repr(transparent)]
2586pub struct Pixels(pub(crate) f32);
2587
2588impl Div for Pixels {
2589    type Output = f32;
2590
2591    fn div(self, rhs: Self) -> Self::Output {
2592        self.0 / rhs.0
2593    }
2594}
2595
2596impl std::ops::DivAssign for Pixels {
2597    fn div_assign(&mut self, rhs: Self) {
2598        *self = Self(self.0 / rhs.0);
2599    }
2600}
2601
2602impl std::ops::RemAssign for Pixels {
2603    fn rem_assign(&mut self, rhs: Self) {
2604        self.0 %= rhs.0;
2605    }
2606}
2607
2608impl std::ops::Rem for Pixels {
2609    type Output = Self;
2610
2611    fn rem(self, rhs: Self) -> Self {
2612        Self(self.0 % rhs.0)
2613    }
2614}
2615
2616impl Mul<f32> for Pixels {
2617    type Output = Self;
2618
2619    fn mul(self, rhs: f32) -> Self {
2620        Self(self.0 * rhs)
2621    }
2622}
2623
2624impl Mul<Pixels> for f32 {
2625    type Output = Pixels;
2626
2627    fn mul(self, rhs: Pixels) -> Self::Output {
2628        rhs * self
2629    }
2630}
2631
2632impl Mul<usize> for Pixels {
2633    type Output = Self;
2634
2635    fn mul(self, rhs: usize) -> Self {
2636        self * (rhs as f32)
2637    }
2638}
2639
2640impl Mul<Pixels> for usize {
2641    type Output = Pixels;
2642
2643    fn mul(self, rhs: Pixels) -> Pixels {
2644        rhs * self
2645    }
2646}
2647
2648impl MulAssign<f32> for Pixels {
2649    fn mul_assign(&mut self, rhs: f32) {
2650        self.0 *= rhs;
2651    }
2652}
2653
2654impl Display for Pixels {
2655    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2656        write!(f, "{}px", self.0)
2657    }
2658}
2659
2660impl Debug for Pixels {
2661    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2662        Display::fmt(self, f)
2663    }
2664}
2665
2666impl TryFrom<&'_ str> for Pixels {
2667    type Error = anyhow::Error;
2668
2669    fn try_from(value: &'_ str) -> Result<Self, Self::Error> {
2670        value
2671            .strip_suffix("px")
2672            .context("expected 'px' suffix")
2673            .and_then(|number| Ok(number.parse()?))
2674            .map(Self)
2675    }
2676}
2677
2678impl Pixels {
2679    /// Represents zero pixels.
2680    pub const ZERO: Pixels = Pixels(0.0);
2681    /// The maximum value that can be represented by `Pixels`.
2682    pub const MAX: Pixels = Pixels(f32::MAX);
2683    /// The minimum value that can be represented by `Pixels`.
2684    pub const MIN: Pixels = Pixels(f32::MIN);
2685
2686    /// Floors the `Pixels` value to the nearest whole number.
2687    ///
2688    /// # Returns
2689    ///
2690    /// Returns a new `Pixels` instance with the floored value.
2691    pub fn floor(&self) -> Self {
2692        Self(self.0.floor())
2693    }
2694
2695    /// Rounds the `Pixels` value to the nearest whole number.
2696    ///
2697    /// # Returns
2698    ///
2699    /// Returns a new `Pixels` instance with the rounded value.
2700    pub fn round(&self) -> Self {
2701        Self(self.0.round())
2702    }
2703
2704    /// Returns the ceiling of the `Pixels` value to the nearest whole number.
2705    ///
2706    /// # Returns
2707    ///
2708    /// Returns a new `Pixels` instance with the ceiling value.
2709    pub fn ceil(&self) -> Self {
2710        Self(self.0.ceil())
2711    }
2712
2713    /// Scales the `Pixels` value by a given factor, producing `ScaledPixels`.
2714    ///
2715    /// This method is used when adjusting pixel values for display scaling factors,
2716    /// such as high DPI (dots per inch) or Retina displays, where the pixel density is higher and
2717    /// thus requires scaling to maintain visual consistency and readability.
2718    ///
2719    /// The resulting `ScaledPixels` represent the scaled value which can be used for rendering
2720    /// calculations where display scaling is considered.
2721    #[must_use]
2722    pub fn scale(&self, factor: f32) -> ScaledPixels {
2723        ScaledPixels(self.0 * factor)
2724    }
2725
2726    /// Raises the `Pixels` value to a given power.
2727    ///
2728    /// # Arguments
2729    ///
2730    /// * `exponent` - The exponent to raise the `Pixels` value by.
2731    ///
2732    /// # Returns
2733    ///
2734    /// Returns a new `Pixels` instance with the value raised to the given exponent.
2735    pub fn pow(&self, exponent: f32) -> Self {
2736        Self(self.0.powf(exponent))
2737    }
2738
2739    /// Returns the absolute value of the `Pixels`.
2740    ///
2741    /// # Returns
2742    ///
2743    /// A new `Pixels` instance with the absolute value of the original `Pixels`.
2744    pub fn abs(&self) -> Self {
2745        Self(self.0.abs())
2746    }
2747
2748    /// Returns the sign of the `Pixels` value.
2749    ///
2750    /// # Returns
2751    ///
2752    /// Returns:
2753    /// * `1.0` if the value is positive
2754    /// * `-1.0` if the value is negative
2755    pub fn signum(&self) -> f32 {
2756        self.0.signum()
2757    }
2758
2759    /// Returns the f64 value of `Pixels`.
2760    ///
2761    /// # Returns
2762    ///
2763    /// A f64 value of the `Pixels`.
2764    pub fn to_f64(self) -> f64 {
2765        self.0 as f64
2766    }
2767}
2768
2769impl Eq for Pixels {}
2770
2771impl PartialOrd for Pixels {
2772    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
2773        Some(self.cmp(other))
2774    }
2775}
2776
2777impl Ord for Pixels {
2778    fn cmp(&self, other: &Self) -> cmp::Ordering {
2779        self.0.total_cmp(&other.0)
2780    }
2781}
2782
2783impl std::hash::Hash for Pixels {
2784    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
2785        self.0.to_bits().hash(state);
2786    }
2787}
2788
2789impl From<f64> for Pixels {
2790    fn from(pixels: f64) -> Self {
2791        Pixels(pixels as f32)
2792    }
2793}
2794
2795impl From<f32> for Pixels {
2796    fn from(pixels: f32) -> Self {
2797        Pixels(pixels)
2798    }
2799}
2800
2801impl From<Pixels> for f32 {
2802    fn from(pixels: Pixels) -> Self {
2803        pixels.0
2804    }
2805}
2806
2807impl From<&Pixels> for f32 {
2808    fn from(pixels: &Pixels) -> Self {
2809        pixels.0
2810    }
2811}
2812
2813impl From<Pixels> for f64 {
2814    fn from(pixels: Pixels) -> Self {
2815        pixels.0 as f64
2816    }
2817}
2818
2819impl From<Pixels> for u32 {
2820    fn from(pixels: Pixels) -> Self {
2821        pixels.0 as u32
2822    }
2823}
2824
2825impl From<&Pixels> for u32 {
2826    fn from(pixels: &Pixels) -> Self {
2827        pixels.0 as u32
2828    }
2829}
2830
2831impl From<u32> for Pixels {
2832    fn from(pixels: u32) -> Self {
2833        Pixels(pixels as f32)
2834    }
2835}
2836
2837impl From<Pixels> for usize {
2838    fn from(pixels: Pixels) -> Self {
2839        pixels.0 as usize
2840    }
2841}
2842
2843impl From<usize> for Pixels {
2844    fn from(pixels: usize) -> Self {
2845        Pixels(pixels as f32)
2846    }
2847}
2848
2849/// Represents physical pixels on the display.
2850///
2851/// `DevicePixels` is a unit of measurement that refers to the actual pixels on a device's screen.
2852/// This type is used when precise pixel manipulation is required, such as rendering graphics or
2853/// interfacing with hardware that operates on the pixel level. Unlike logical pixels that may be
2854/// affected by the device's scale factor, `DevicePixels` always correspond to real pixels on the
2855/// display.
2856#[derive(
2857    Add,
2858    AddAssign,
2859    Clone,
2860    Copy,
2861    Default,
2862    Div,
2863    Eq,
2864    Hash,
2865    Ord,
2866    PartialEq,
2867    PartialOrd,
2868    Sub,
2869    SubAssign,
2870    Serialize,
2871    Deserialize,
2872)]
2873#[repr(transparent)]
2874pub struct DevicePixels(pub i32);
2875
2876impl DevicePixels {
2877    /// Converts the `DevicePixels` value to the number of bytes needed to represent it in memory.
2878    ///
2879    /// This function is useful when working with graphical data that needs to be stored in a buffer,
2880    /// such as images or framebuffers, where each pixel may be represented by a specific number of bytes.
2881    ///
2882    /// # Arguments
2883    ///
2884    /// * `bytes_per_pixel` - The number of bytes used to represent a single pixel.
2885    ///
2886    /// # Returns
2887    ///
2888    /// The number of bytes required to represent the `DevicePixels` value in memory.
2889    ///
2890    /// # Examples
2891    ///
2892    /// ```
2893    /// # use gpui::DevicePixels;
2894    /// let pixels = DevicePixels(10); // 10 device pixels
2895    /// let bytes_per_pixel = 4; // Assume each pixel is represented by 4 bytes (e.g., RGBA)
2896    /// let total_bytes = pixels.to_bytes(bytes_per_pixel);
2897    /// assert_eq!(total_bytes, 40); // 10 pixels * 4 bytes/pixel = 40 bytes
2898    /// ```
2899    pub fn to_bytes(self, bytes_per_pixel: u8) -> u32 {
2900        self.0 as u32 * bytes_per_pixel as u32
2901    }
2902}
2903
2904impl fmt::Debug for DevicePixels {
2905    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2906        write!(f, "{} px (device)", self.0)
2907    }
2908}
2909
2910impl From<DevicePixels> for i32 {
2911    fn from(device_pixels: DevicePixels) -> Self {
2912        device_pixels.0
2913    }
2914}
2915
2916impl From<i32> for DevicePixels {
2917    fn from(device_pixels: i32) -> Self {
2918        DevicePixels(device_pixels)
2919    }
2920}
2921
2922impl From<u32> for DevicePixels {
2923    fn from(device_pixels: u32) -> Self {
2924        DevicePixels(device_pixels as i32)
2925    }
2926}
2927
2928impl From<DevicePixels> for u32 {
2929    fn from(device_pixels: DevicePixels) -> Self {
2930        device_pixels.0 as u32
2931    }
2932}
2933
2934impl From<DevicePixels> for u64 {
2935    fn from(device_pixels: DevicePixels) -> Self {
2936        device_pixels.0 as u64
2937    }
2938}
2939
2940impl From<u64> for DevicePixels {
2941    fn from(device_pixels: u64) -> Self {
2942        DevicePixels(device_pixels as i32)
2943    }
2944}
2945
2946impl From<DevicePixels> for usize {
2947    fn from(device_pixels: DevicePixels) -> Self {
2948        device_pixels.0 as usize
2949    }
2950}
2951
2952impl From<usize> for DevicePixels {
2953    fn from(device_pixels: usize) -> Self {
2954        DevicePixels(device_pixels as i32)
2955    }
2956}
2957
2958/// Represents scaled pixels that take into account the device's scale factor.
2959///
2960/// `ScaledPixels` are used to ensure that UI elements appear at the correct size on devices
2961/// with different pixel densities. When a device has a higher scale factor (such as Retina displays),
2962/// a single logical pixel may correspond to multiple physical pixels. By using `ScaledPixels`,
2963/// dimensions and positions can be specified in a way that scales appropriately across different
2964/// display resolutions.
2965#[derive(Clone, Copy, Default, Add, AddAssign, Sub, SubAssign, Div, DivAssign, PartialEq)]
2966#[repr(transparent)]
2967pub struct ScaledPixels(pub(crate) f32);
2968
2969impl ScaledPixels {
2970    /// Floors the `ScaledPixels` value to the nearest whole number.
2971    ///
2972    /// # Returns
2973    ///
2974    /// Returns a new `ScaledPixels` instance with the floored value.
2975    pub fn floor(&self) -> Self {
2976        Self(self.0.floor())
2977    }
2978
2979    /// Rounds the `ScaledPixels` value to the nearest whole number.
2980    ///
2981    /// # Returns
2982    ///
2983    /// Returns a new `ScaledPixels` instance with the rounded value.
2984    pub fn round(&self) -> Self {
2985        Self(self.0.round())
2986    }
2987
2988    /// Ceils the `ScaledPixels` value to the nearest whole number.
2989    ///
2990    /// # Returns
2991    ///
2992    /// Returns a new `ScaledPixels` instance with the ceiled value.
2993    pub fn ceil(&self) -> Self {
2994        Self(self.0.ceil())
2995    }
2996}
2997
2998impl Eq for ScaledPixels {}
2999
3000impl PartialOrd for ScaledPixels {
3001    fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
3002        Some(self.cmp(other))
3003    }
3004}
3005
3006impl Ord for ScaledPixels {
3007    fn cmp(&self, other: &Self) -> cmp::Ordering {
3008        self.0.total_cmp(&other.0)
3009    }
3010}
3011
3012impl Debug for ScaledPixels {
3013    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3014        write!(f, "{}px (scaled)", self.0)
3015    }
3016}
3017
3018impl From<ScaledPixels> for DevicePixels {
3019    fn from(scaled: ScaledPixels) -> Self {
3020        DevicePixels(scaled.0.ceil() as i32)
3021    }
3022}
3023
3024impl From<DevicePixels> for ScaledPixels {
3025    fn from(device: DevicePixels) -> Self {
3026        ScaledPixels(device.0 as f32)
3027    }
3028}
3029
3030impl From<ScaledPixels> for f64 {
3031    fn from(scaled_pixels: ScaledPixels) -> Self {
3032        scaled_pixels.0 as f64
3033    }
3034}
3035
3036impl From<ScaledPixels> for u32 {
3037    fn from(pixels: ScaledPixels) -> Self {
3038        pixels.0 as u32
3039    }
3040}
3041
3042impl From<f32> for ScaledPixels {
3043    fn from(pixels: f32) -> Self {
3044        Self(pixels)
3045    }
3046}
3047
3048impl Div for ScaledPixels {
3049    type Output = f32;
3050
3051    fn div(self, rhs: Self) -> Self::Output {
3052        self.0 / rhs.0
3053    }
3054}
3055
3056impl std::ops::DivAssign for ScaledPixels {
3057    fn div_assign(&mut self, rhs: Self) {
3058        *self = Self(self.0 / rhs.0);
3059    }
3060}
3061
3062impl std::ops::RemAssign for ScaledPixels {
3063    fn rem_assign(&mut self, rhs: Self) {
3064        self.0 %= rhs.0;
3065    }
3066}
3067
3068impl std::ops::Rem for ScaledPixels {
3069    type Output = Self;
3070
3071    fn rem(self, rhs: Self) -> Self {
3072        Self(self.0 % rhs.0)
3073    }
3074}
3075
3076impl Mul<f32> for ScaledPixels {
3077    type Output = Self;
3078
3079    fn mul(self, rhs: f32) -> Self {
3080        Self(self.0 * rhs)
3081    }
3082}
3083
3084impl Mul<ScaledPixels> for f32 {
3085    type Output = ScaledPixels;
3086
3087    fn mul(self, rhs: ScaledPixels) -> Self::Output {
3088        rhs * self
3089    }
3090}
3091
3092impl Mul<usize> for ScaledPixels {
3093    type Output = Self;
3094
3095    fn mul(self, rhs: usize) -> Self {
3096        self * (rhs as f32)
3097    }
3098}
3099
3100impl Mul<ScaledPixels> for usize {
3101    type Output = ScaledPixels;
3102
3103    fn mul(self, rhs: ScaledPixels) -> ScaledPixels {
3104        rhs * self
3105    }
3106}
3107
3108impl MulAssign<f32> for ScaledPixels {
3109    fn mul_assign(&mut self, rhs: f32) {
3110        self.0 *= rhs;
3111    }
3112}
3113
3114/// 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].
3115///
3116/// Rems are used for defining lengths that are scalable and consistent across different UI elements.
3117/// The value of `1rem` is typically equal to the font-size of the root element (often the `<html>` element in browsers),
3118/// making it a flexible unit that adapts to the user's text size preferences. In this framework, `rems` serve a similar
3119/// purpose, allowing for scalable and accessible design that can adjust to different display settings or user preferences.
3120///
3121/// For example, if the root element's font-size is `16px`, then `1rem` equals `16px`. A length of `2rems` would then be `32px`.
3122///
3123/// [set_rem_size]: crate::Window::set_rem_size
3124#[derive(Clone, Copy, Default, Add, Sub, Mul, Div, Neg, PartialEq)]
3125pub struct Rems(pub f32);
3126
3127impl Rems {
3128    /// Convert this Rem value to pixels.
3129    pub fn to_pixels(self, rem_size: Pixels) -> Pixels {
3130        self * rem_size
3131    }
3132}
3133
3134impl Mul<Pixels> for Rems {
3135    type Output = Pixels;
3136
3137    fn mul(self, other: Pixels) -> Pixels {
3138        Pixels(self.0 * other.0)
3139    }
3140}
3141
3142impl Display for Rems {
3143    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3144        write!(f, "{}rem", self.0)
3145    }
3146}
3147
3148impl Debug for Rems {
3149    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3150        Display::fmt(self, f)
3151    }
3152}
3153
3154impl TryFrom<&'_ str> for Rems {
3155    type Error = anyhow::Error;
3156
3157    fn try_from(value: &'_ str) -> Result<Self, Self::Error> {
3158        value
3159            .strip_suffix("rem")
3160            .context("expected 'rem' suffix")
3161            .and_then(|number| Ok(number.parse()?))
3162            .map(Self)
3163    }
3164}
3165
3166/// Represents an absolute length in pixels or rems.
3167///
3168/// `AbsoluteLength` can be either a fixed number of pixels, which is an absolute measurement not
3169/// affected by the current font size, or a number of rems, which is relative to the font size of
3170/// the root element. It is used for specifying dimensions that are either independent of or
3171/// related to the typographic scale.
3172#[derive(Clone, Copy, Neg, PartialEq)]
3173pub enum AbsoluteLength {
3174    /// A length in pixels.
3175    Pixels(Pixels),
3176    /// A length in rems.
3177    Rems(Rems),
3178}
3179
3180impl AbsoluteLength {
3181    /// Checks if the absolute length is zero.
3182    pub fn is_zero(&self) -> bool {
3183        match self {
3184            AbsoluteLength::Pixels(px) => px.0 == 0.0,
3185            AbsoluteLength::Rems(rems) => rems.0 == 0.0,
3186        }
3187    }
3188}
3189
3190impl From<Pixels> for AbsoluteLength {
3191    fn from(pixels: Pixels) -> Self {
3192        AbsoluteLength::Pixels(pixels)
3193    }
3194}
3195
3196impl From<Rems> for AbsoluteLength {
3197    fn from(rems: Rems) -> Self {
3198        AbsoluteLength::Rems(rems)
3199    }
3200}
3201
3202impl AbsoluteLength {
3203    /// Converts an `AbsoluteLength` to `Pixels` based on a given `rem_size`.
3204    ///
3205    /// # Arguments
3206    ///
3207    /// * `rem_size` - The size of one rem in pixels.
3208    ///
3209    /// # Returns
3210    ///
3211    /// Returns the `AbsoluteLength` as `Pixels`.
3212    ///
3213    /// # Examples
3214    ///
3215    /// ```
3216    /// # use gpui::{AbsoluteLength, Pixels, Rems};
3217    /// let length_in_pixels = AbsoluteLength::Pixels(Pixels::from(42.0));
3218    /// let length_in_rems = AbsoluteLength::Rems(Rems(2.0));
3219    /// let rem_size = Pixels::from(16.0);
3220    ///
3221    /// assert_eq!(length_in_pixels.to_pixels(rem_size), Pixels::from(42.0));
3222    /// assert_eq!(length_in_rems.to_pixels(rem_size), Pixels::from(32.0));
3223    /// ```
3224    pub fn to_pixels(self, rem_size: Pixels) -> Pixels {
3225        match self {
3226            AbsoluteLength::Pixels(pixels) => pixels,
3227            AbsoluteLength::Rems(rems) => rems.to_pixels(rem_size),
3228        }
3229    }
3230
3231    /// Converts an `AbsoluteLength` to `Rems` based on a given `rem_size`.
3232    ///
3233    /// # Arguments
3234    ///
3235    /// * `rem_size` - The size of one rem in pixels.
3236    ///
3237    /// # Returns
3238    ///
3239    /// Returns the `AbsoluteLength` as `Pixels`.
3240    pub fn to_rems(self, rem_size: Pixels) -> Rems {
3241        match self {
3242            AbsoluteLength::Pixels(pixels) => Rems(pixels.0 / rem_size.0),
3243            AbsoluteLength::Rems(rems) => rems,
3244        }
3245    }
3246}
3247
3248impl Default for AbsoluteLength {
3249    fn default() -> Self {
3250        px(0.).into()
3251    }
3252}
3253
3254impl Display for AbsoluteLength {
3255    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3256        match self {
3257            Self::Pixels(pixels) => write!(f, "{pixels}"),
3258            Self::Rems(rems) => write!(f, "{rems}"),
3259        }
3260    }
3261}
3262
3263impl Debug for AbsoluteLength {
3264    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3265        Display::fmt(self, f)
3266    }
3267}
3268
3269const EXPECTED_ABSOLUTE_LENGTH: &str = "number with 'px' or 'rem' suffix";
3270
3271impl TryFrom<&'_ str> for AbsoluteLength {
3272    type Error = anyhow::Error;
3273
3274    fn try_from(value: &'_ str) -> Result<Self, Self::Error> {
3275        if let Ok(pixels) = value.try_into() {
3276            Ok(Self::Pixels(pixels))
3277        } else if let Ok(rems) = value.try_into() {
3278            Ok(Self::Rems(rems))
3279        } else {
3280            Err(anyhow!(
3281                "invalid AbsoluteLength '{value}', expected {EXPECTED_ABSOLUTE_LENGTH}"
3282            ))
3283        }
3284    }
3285}
3286
3287impl JsonSchema for AbsoluteLength {
3288    fn schema_name() -> Cow<'static, str> {
3289        "AbsoluteLength".into()
3290    }
3291
3292    fn json_schema(_generator: &mut schemars::SchemaGenerator) -> schemars::Schema {
3293        json_schema!({
3294            "type": "string",
3295            "pattern": r"^-?\d+(\.\d+)?(px|rem)$"
3296        })
3297    }
3298}
3299
3300impl<'de> Deserialize<'de> for AbsoluteLength {
3301    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
3302        struct StringVisitor;
3303
3304        impl de::Visitor<'_> for StringVisitor {
3305            type Value = AbsoluteLength;
3306
3307            fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
3308                write!(f, "{EXPECTED_ABSOLUTE_LENGTH}")
3309            }
3310
3311            fn visit_str<E: de::Error>(self, value: &str) -> Result<Self::Value, E> {
3312                AbsoluteLength::try_from(value).map_err(E::custom)
3313            }
3314        }
3315
3316        deserializer.deserialize_str(StringVisitor)
3317    }
3318}
3319
3320impl Serialize for AbsoluteLength {
3321    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
3322    where
3323        S: Serializer,
3324    {
3325        serializer.serialize_str(&format!("{self}"))
3326    }
3327}
3328
3329/// A non-auto length that can be defined in pixels, rems, or percent of parent.
3330///
3331/// This enum represents lengths that have a specific value, as opposed to lengths that are automatically
3332/// determined by the context. It includes absolute lengths in pixels or rems, and relative lengths as a
3333/// fraction of the parent's size.
3334#[derive(Clone, Copy, Neg, PartialEq)]
3335pub enum DefiniteLength {
3336    /// An absolute length specified in pixels or rems.
3337    Absolute(AbsoluteLength),
3338    /// A relative length specified as a fraction of the parent's size, between 0 and 1.
3339    Fraction(f32),
3340}
3341
3342impl DefiniteLength {
3343    /// Converts the `DefiniteLength` to `Pixels` based on a given `base_size` and `rem_size`.
3344    ///
3345    /// If the `DefiniteLength` is an absolute length, it will be directly converted to `Pixels`.
3346    /// If it is a fraction, the fraction will be multiplied by the `base_size` to get the length in pixels.
3347    ///
3348    /// # Arguments
3349    ///
3350    /// * `base_size` - The base size in `AbsoluteLength` to which the fraction will be applied.
3351    /// * `rem_size` - The size of one rem in pixels, used to convert rems to pixels.
3352    ///
3353    /// # Returns
3354    ///
3355    /// Returns the `DefiniteLength` as `Pixels`.
3356    ///
3357    /// # Examples
3358    ///
3359    /// ```
3360    /// # use gpui::{DefiniteLength, AbsoluteLength, Pixels, px, rems};
3361    /// let length_in_pixels = DefiniteLength::Absolute(AbsoluteLength::Pixels(px(42.0)));
3362    /// let length_in_rems = DefiniteLength::Absolute(AbsoluteLength::Rems(rems(2.0)));
3363    /// let length_as_fraction = DefiniteLength::Fraction(0.5);
3364    /// let base_size = AbsoluteLength::Pixels(px(100.0));
3365    /// let rem_size = px(16.0);
3366    ///
3367    /// assert_eq!(length_in_pixels.to_pixels(base_size, rem_size), Pixels::from(42.0));
3368    /// assert_eq!(length_in_rems.to_pixels(base_size, rem_size), Pixels::from(32.0));
3369    /// assert_eq!(length_as_fraction.to_pixels(base_size, rem_size), Pixels::from(50.0));
3370    /// ```
3371    pub fn to_pixels(self, base_size: AbsoluteLength, rem_size: Pixels) -> Pixels {
3372        match self {
3373            DefiniteLength::Absolute(size) => size.to_pixels(rem_size),
3374            DefiniteLength::Fraction(fraction) => match base_size {
3375                AbsoluteLength::Pixels(px) => px * fraction,
3376                AbsoluteLength::Rems(rems) => rems * rem_size * fraction,
3377            },
3378        }
3379    }
3380}
3381
3382impl Debug for DefiniteLength {
3383    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3384        Display::fmt(self, f)
3385    }
3386}
3387
3388impl Display for DefiniteLength {
3389    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3390        match self {
3391            DefiniteLength::Absolute(length) => write!(f, "{length}"),
3392            DefiniteLength::Fraction(fraction) => write!(f, "{}%", (fraction * 100.0) as i32),
3393        }
3394    }
3395}
3396
3397const EXPECTED_DEFINITE_LENGTH: &str = "expected number with 'px', 'rem', or '%' suffix";
3398
3399impl TryFrom<&'_ str> for DefiniteLength {
3400    type Error = anyhow::Error;
3401
3402    fn try_from(value: &'_ str) -> Result<Self, Self::Error> {
3403        if let Some(percentage) = value.strip_suffix('%') {
3404            let fraction: f32 = percentage.parse::<f32>().with_context(|| {
3405                format!("invalid DefiniteLength '{value}', expected {EXPECTED_DEFINITE_LENGTH}")
3406            })?;
3407            Ok(DefiniteLength::Fraction(fraction / 100.0))
3408        } else if let Ok(absolute_length) = value.try_into() {
3409            Ok(DefiniteLength::Absolute(absolute_length))
3410        } else {
3411            Err(anyhow!(
3412                "invalid DefiniteLength '{value}', expected {EXPECTED_DEFINITE_LENGTH}"
3413            ))
3414        }
3415    }
3416}
3417
3418impl JsonSchema for DefiniteLength {
3419    fn schema_name() -> Cow<'static, str> {
3420        "DefiniteLength".into()
3421    }
3422
3423    fn json_schema(_generator: &mut schemars::SchemaGenerator) -> schemars::Schema {
3424        json_schema!({
3425            "type": "string",
3426            "pattern": r"^-?\d+(\.\d+)?(px|rem|%)$"
3427        })
3428    }
3429}
3430
3431impl<'de> Deserialize<'de> for DefiniteLength {
3432    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
3433        struct StringVisitor;
3434
3435        impl de::Visitor<'_> for StringVisitor {
3436            type Value = DefiniteLength;
3437
3438            fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
3439                write!(f, "{EXPECTED_DEFINITE_LENGTH}")
3440            }
3441
3442            fn visit_str<E: de::Error>(self, value: &str) -> Result<Self::Value, E> {
3443                DefiniteLength::try_from(value).map_err(E::custom)
3444            }
3445        }
3446
3447        deserializer.deserialize_str(StringVisitor)
3448    }
3449}
3450
3451impl Serialize for DefiniteLength {
3452    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
3453    where
3454        S: Serializer,
3455    {
3456        serializer.serialize_str(&format!("{self}"))
3457    }
3458}
3459
3460impl From<Pixels> for DefiniteLength {
3461    fn from(pixels: Pixels) -> Self {
3462        Self::Absolute(pixels.into())
3463    }
3464}
3465
3466impl From<Rems> for DefiniteLength {
3467    fn from(rems: Rems) -> Self {
3468        Self::Absolute(rems.into())
3469    }
3470}
3471
3472impl From<AbsoluteLength> for DefiniteLength {
3473    fn from(length: AbsoluteLength) -> Self {
3474        Self::Absolute(length)
3475    }
3476}
3477
3478impl Default for DefiniteLength {
3479    fn default() -> Self {
3480        Self::Absolute(AbsoluteLength::default())
3481    }
3482}
3483
3484/// A length that can be defined in pixels, rems, percent of parent, or auto.
3485#[derive(Clone, Copy, PartialEq)]
3486pub enum Length {
3487    /// A definite length specified either in pixels, rems, or as a fraction of the parent's size.
3488    Definite(DefiniteLength),
3489    /// An automatic length that is determined by the context in which it is used.
3490    Auto,
3491}
3492
3493impl Debug for Length {
3494    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3495        Display::fmt(self, f)
3496    }
3497}
3498
3499impl Display for Length {
3500    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
3501        match self {
3502            Length::Definite(definite_length) => write!(f, "{}", definite_length),
3503            Length::Auto => write!(f, "auto"),
3504        }
3505    }
3506}
3507
3508const EXPECTED_LENGTH: &str = "expected 'auto' or number with 'px', 'rem', or '%' suffix";
3509
3510impl TryFrom<&'_ str> for Length {
3511    type Error = anyhow::Error;
3512
3513    fn try_from(value: &'_ str) -> Result<Self, Self::Error> {
3514        if value == "auto" {
3515            Ok(Length::Auto)
3516        } else if let Ok(definite_length) = value.try_into() {
3517            Ok(Length::Definite(definite_length))
3518        } else {
3519            Err(anyhow!(
3520                "invalid Length '{value}', expected {EXPECTED_LENGTH}"
3521            ))
3522        }
3523    }
3524}
3525
3526impl JsonSchema for Length {
3527    fn schema_name() -> Cow<'static, str> {
3528        "Length".into()
3529    }
3530
3531    fn json_schema(_generator: &mut schemars::SchemaGenerator) -> schemars::Schema {
3532        json_schema!({
3533            "type": "string",
3534            "pattern": r"^(auto|-?\d+(\.\d+)?(px|rem|%))$"
3535        })
3536    }
3537}
3538
3539impl<'de> Deserialize<'de> for Length {
3540    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
3541        struct StringVisitor;
3542
3543        impl de::Visitor<'_> for StringVisitor {
3544            type Value = Length;
3545
3546            fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
3547                write!(f, "{EXPECTED_LENGTH}")
3548            }
3549
3550            fn visit_str<E: de::Error>(self, value: &str) -> Result<Self::Value, E> {
3551                Length::try_from(value).map_err(E::custom)
3552            }
3553        }
3554
3555        deserializer.deserialize_str(StringVisitor)
3556    }
3557}
3558
3559impl Serialize for Length {
3560    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
3561    where
3562        S: Serializer,
3563    {
3564        serializer.serialize_str(&format!("{self}"))
3565    }
3566}
3567
3568/// Constructs a `DefiniteLength` representing a relative fraction of a parent size.
3569///
3570/// This function creates a `DefiniteLength` that is a specified fraction of a parent's dimension.
3571/// The fraction should be a floating-point number between 0.0 and 1.0, where 1.0 represents 100% of the parent's size.
3572///
3573/// # Arguments
3574///
3575/// * `fraction` - The fraction of the parent's size, between 0.0 and 1.0.
3576///
3577/// # Returns
3578///
3579/// A `DefiniteLength` representing the relative length as a fraction of the parent's size.
3580pub const fn relative(fraction: f32) -> DefiniteLength {
3581    DefiniteLength::Fraction(fraction)
3582}
3583
3584/// Returns the Golden Ratio, i.e. `~(1.0 + sqrt(5.0)) / 2.0`.
3585pub fn phi() -> DefiniteLength {
3586    relative(1.618_034)
3587}
3588
3589/// Constructs a `Rems` value representing a length in rems.
3590///
3591/// # Arguments
3592///
3593/// * `rems` - The number of rems for the length.
3594///
3595/// # Returns
3596///
3597/// A `Rems` representing the specified number of rems.
3598pub fn rems(rems: f32) -> Rems {
3599    Rems(rems)
3600}
3601
3602/// Constructs a `Pixels` value representing a length in pixels.
3603///
3604/// # Arguments
3605///
3606/// * `pixels` - The number of pixels for the length.
3607///
3608/// # Returns
3609///
3610/// A `Pixels` representing the specified number of pixels.
3611pub const fn px(pixels: f32) -> Pixels {
3612    Pixels(pixels)
3613}
3614
3615/// Returns a `Length` representing an automatic length.
3616///
3617/// The `auto` length is often used in layout calculations where the length should be determined
3618/// by the layout context itself rather than being explicitly set. This is commonly used in CSS
3619/// for properties like `width`, `height`, `margin`, `padding`, etc., where `auto` can be used
3620/// to instruct the layout engine to calculate the size based on other factors like the size of the
3621/// container or the intrinsic size of the content.
3622///
3623/// # Returns
3624///
3625/// A `Length` variant set to `Auto`.
3626pub fn auto() -> Length {
3627    Length::Auto
3628}
3629
3630impl From<Pixels> for Length {
3631    fn from(pixels: Pixels) -> Self {
3632        Self::Definite(pixels.into())
3633    }
3634}
3635
3636impl From<Rems> for Length {
3637    fn from(rems: Rems) -> Self {
3638        Self::Definite(rems.into())
3639    }
3640}
3641
3642impl From<DefiniteLength> for Length {
3643    fn from(length: DefiniteLength) -> Self {
3644        Self::Definite(length)
3645    }
3646}
3647
3648impl From<AbsoluteLength> for Length {
3649    fn from(length: AbsoluteLength) -> Self {
3650        Self::Definite(length.into())
3651    }
3652}
3653
3654impl Default for Length {
3655    fn default() -> Self {
3656        Self::Definite(DefiniteLength::default())
3657    }
3658}
3659
3660impl From<()> for Length {
3661    fn from(_: ()) -> Self {
3662        Self::Definite(DefiniteLength::default())
3663    }
3664}
3665
3666/// A location in a grid layout.
3667#[derive(Clone, PartialEq, Debug, Serialize, Deserialize, JsonSchema, Default)]
3668pub struct GridLocation {
3669    /// The rows this item uses within the grid.
3670    pub row: Range<GridPlacement>,
3671    /// The columns this item uses within the grid.
3672    pub column: Range<GridPlacement>,
3673}
3674
3675/// The placement of an item within a grid layout's column or row.
3676#[derive(Clone, Copy, PartialEq, Debug, Serialize, Deserialize, JsonSchema, Default)]
3677pub enum GridPlacement {
3678    /// The grid line index to place this item.
3679    Line(i16),
3680    /// The number of grid lines to span.
3681    Span(u16),
3682    /// Automatically determine the placement, equivalent to Span(1)
3683    #[default]
3684    Auto,
3685}
3686
3687impl From<GridPlacement> for taffy::GridPlacement {
3688    fn from(placement: GridPlacement) -> Self {
3689        match placement {
3690            GridPlacement::Line(index) => taffy::GridPlacement::from_line_index(index),
3691            GridPlacement::Span(span) => taffy::GridPlacement::from_span(span),
3692            GridPlacement::Auto => taffy::GridPlacement::Auto,
3693        }
3694    }
3695}
3696
3697/// Provides a trait for types that can calculate half of their value.
3698///
3699/// The `Half` trait is used for types that can be evenly divided, returning a new instance of the same type
3700/// representing half of the original value. This is commonly used for types that represent measurements or sizes,
3701/// such as lengths or pixels, where halving is a frequent operation during layout calculations or animations.
3702pub trait Half {
3703    /// Returns half of the current value.
3704    ///
3705    /// # Returns
3706    ///
3707    /// A new instance of the implementing type, representing half of the original value.
3708    fn half(&self) -> Self;
3709}
3710
3711impl Half for i32 {
3712    fn half(&self) -> Self {
3713        self / 2
3714    }
3715}
3716
3717impl Half for f32 {
3718    fn half(&self) -> Self {
3719        self / 2.
3720    }
3721}
3722
3723impl Half for DevicePixels {
3724    fn half(&self) -> Self {
3725        Self(self.0 / 2)
3726    }
3727}
3728
3729impl Half for ScaledPixels {
3730    fn half(&self) -> Self {
3731        Self(self.0 / 2.)
3732    }
3733}
3734
3735impl Half for Pixels {
3736    fn half(&self) -> Self {
3737        Self(self.0 / 2.)
3738    }
3739}
3740
3741impl Half for Rems {
3742    fn half(&self) -> Self {
3743        Self(self.0 / 2.)
3744    }
3745}
3746
3747/// Provides a trait for types that can negate their values.
3748pub trait Negate {
3749    /// Returns the negation of the given value
3750    fn negate(self) -> Self;
3751}
3752
3753impl Negate for i32 {
3754    fn negate(self) -> Self {
3755        -self
3756    }
3757}
3758
3759impl Negate for f32 {
3760    fn negate(self) -> Self {
3761        -self
3762    }
3763}
3764
3765impl Negate for DevicePixels {
3766    fn negate(self) -> Self {
3767        Self(-self.0)
3768    }
3769}
3770
3771impl Negate for ScaledPixels {
3772    fn negate(self) -> Self {
3773        Self(-self.0)
3774    }
3775}
3776
3777impl Negate for Pixels {
3778    fn negate(self) -> Self {
3779        Self(-self.0)
3780    }
3781}
3782
3783impl Negate for Rems {
3784    fn negate(self) -> Self {
3785        Self(-self.0)
3786    }
3787}
3788
3789/// A trait for checking if a value is zero.
3790///
3791/// This trait provides a method to determine if a value is considered to be zero.
3792/// It is implemented for various numeric and length-related types where the concept
3793/// of zero is applicable. This can be useful for comparisons, optimizations, or
3794/// determining if an operation has a neutral effect.
3795pub trait IsZero {
3796    /// Determines if the value is zero.
3797    ///
3798    /// # Returns
3799    ///
3800    /// Returns `true` if the value is zero, `false` otherwise.
3801    fn is_zero(&self) -> bool;
3802}
3803
3804impl IsZero for DevicePixels {
3805    fn is_zero(&self) -> bool {
3806        self.0 == 0
3807    }
3808}
3809
3810impl IsZero for ScaledPixels {
3811    fn is_zero(&self) -> bool {
3812        self.0 == 0.
3813    }
3814}
3815
3816impl IsZero for Pixels {
3817    fn is_zero(&self) -> bool {
3818        self.0 == 0.
3819    }
3820}
3821
3822impl IsZero for Rems {
3823    fn is_zero(&self) -> bool {
3824        self.0 == 0.
3825    }
3826}
3827
3828impl IsZero for AbsoluteLength {
3829    fn is_zero(&self) -> bool {
3830        match self {
3831            AbsoluteLength::Pixels(pixels) => pixels.is_zero(),
3832            AbsoluteLength::Rems(rems) => rems.is_zero(),
3833        }
3834    }
3835}
3836
3837impl IsZero for DefiniteLength {
3838    fn is_zero(&self) -> bool {
3839        match self {
3840            DefiniteLength::Absolute(length) => length.is_zero(),
3841            DefiniteLength::Fraction(fraction) => *fraction == 0.,
3842        }
3843    }
3844}
3845
3846impl IsZero for Length {
3847    fn is_zero(&self) -> bool {
3848        match self {
3849            Length::Definite(length) => length.is_zero(),
3850            Length::Auto => false,
3851        }
3852    }
3853}
3854
3855impl<T: IsZero + Clone + Debug + Default + PartialEq> IsZero for Point<T> {
3856    fn is_zero(&self) -> bool {
3857        self.x.is_zero() && self.y.is_zero()
3858    }
3859}
3860
3861impl<T> IsZero for Size<T>
3862where
3863    T: IsZero + Clone + Debug + Default + PartialEq,
3864{
3865    fn is_zero(&self) -> bool {
3866        self.width.is_zero() || self.height.is_zero()
3867    }
3868}
3869
3870impl<T: IsZero + Clone + Debug + Default + PartialEq> IsZero for Bounds<T> {
3871    fn is_zero(&self) -> bool {
3872        self.size.is_zero()
3873    }
3874}
3875
3876impl<T> IsZero for Corners<T>
3877where
3878    T: IsZero + Clone + Debug + Default + PartialEq,
3879{
3880    fn is_zero(&self) -> bool {
3881        self.top_left.is_zero()
3882            && self.top_right.is_zero()
3883            && self.bottom_right.is_zero()
3884            && self.bottom_left.is_zero()
3885    }
3886}
3887
3888#[cfg(test)]
3889mod tests {
3890    use super::*;
3891
3892    #[test]
3893    fn test_bounds_intersects() {
3894        let bounds1 = Bounds {
3895            origin: Point { x: 0.0, y: 0.0 },
3896            size: Size {
3897                width: 5.0,
3898                height: 5.0,
3899            },
3900        };
3901        let bounds2 = Bounds {
3902            origin: Point { x: 4.0, y: 4.0 },
3903            size: Size {
3904                width: 5.0,
3905                height: 5.0,
3906            },
3907        };
3908        let bounds3 = Bounds {
3909            origin: Point { x: 10.0, y: 10.0 },
3910            size: Size {
3911                width: 5.0,
3912                height: 5.0,
3913            },
3914        };
3915
3916        // Test Case 1: Intersecting bounds
3917        assert!(bounds1.intersects(&bounds2));
3918
3919        // Test Case 2: Non-Intersecting bounds
3920        assert!(!bounds1.intersects(&bounds3));
3921
3922        // Test Case 3: Bounds intersecting with themselves
3923        assert!(bounds1.intersects(&bounds1));
3924    }
3925}