Skip to main content

gpui/
geometry.rs

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