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