Skip to main content

gpui/
geometry.rs

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