Skip to main content

gpui_core/
geometry.rs

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