3383 lines · 98.1 KB · Rust
RawDownload
//! The GPUI geometry module is a collection of types and traits that//! can be used to describe common units, concepts, and the relationships//! between them. use core::fmt::Debug;use derive_more::{Add, AddAssign, Div, DivAssign, Mul, Neg, Sub, SubAssign};use refineable::Refineable;use serde_derive::{Deserialize, Serialize};use std::{    cmp::{self, PartialOrd},    fmt,    hash::Hash,    ops::{Add, Div, Mul, MulAssign, Neg, Sub},}; use crate::{AppContext, DisplayId}; /// Axis in a 2D cartesian space.#[derive(Copy, Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]pub enum Axis {    /// The y axis, or up and down    Vertical,    /// The x axis, or left and right    Horizontal,} impl Axis {    /// Swap this axis to the opposite axis.    pub fn invert(self) -> Self {        match self {            Axis::Vertical => Axis::Horizontal,            Axis::Horizontal => Axis::Vertical,        }    }} /// A trait for accessing the given unit along a certain axis.pub trait Along {    /// The unit associated with this type    type Unit;     /// Returns the unit along the given axis.    fn along(&self, axis: Axis) -> Self::Unit;     /// Applies the given function to the unit along the given axis and returns a new value.    fn apply_along(&self, axis: Axis, f: impl FnOnce(Self::Unit) -> Self::Unit) -> Self;} /// Describes a location in a 2D cartesian space.////// It holds two public fields, `x` and `y`, which represent the coordinates in the space./// The type `T` for the coordinates can be any type that implements `Default`, `Clone`, and `Debug`.////// # Examples////// ```/// # use gpui::Point;/// let point = Point { x: 10, y: 20 };/// println!("{:?}", point); // Outputs: Point { x: 10, y: 20 }/// ```#[derive(    Refineable,    Default,    Add,    AddAssign,    Sub,    SubAssign,    Copy,    Debug,    PartialEq,    Eq,    Serialize,    Deserialize,    Hash,)]#[refineable(Debug)]#[repr(C)]pub struct Point<T: Default + Clone + Debug> {    /// The x coordinate of the point.    pub x: T,    /// The y coordinate of the point.    pub y: T,} /// Constructs a new `Point<T>` with the given x and y coordinates.////// # Arguments////// * `x` - The x coordinate of the point./// * `y` - The y coordinate of the point.////// # Returns////// Returns a `Point<T>` with the specified coordinates.////// # Examples////// ```/// # use gpui::Point;/// let p = point(10, 20);/// assert_eq!(p.x, 10);/// assert_eq!(p.y, 20);/// ```pub const fn point<T: Clone + Debug + Default>(x: T, y: T) -> Point<T> {    Point { x, y }} impl<T: Clone + Debug + Default> Point<T> {    /// Creates a new `Point` with the specified `x` and `y` coordinates.    ///    /// # Arguments    ///    /// * `x` - The horizontal coordinate of the point.    /// * `y` - The vertical coordinate of the point.    ///    /// # Examples    ///    /// ```    /// let p = Point::new(10, 20);    /// assert_eq!(p.x, 10);    /// assert_eq!(p.y, 20);    /// ```    pub const fn new(x: T, y: T) -> Self {        Self { x, y }    }     /// Transforms the point to a `Point<U>` by applying the given function to both coordinates.    ///    /// This method allows for converting a `Point<T>` to a `Point<U>` by specifying a closure    /// that defines how to convert between the two types. The closure is applied to both the `x`    /// and `y` coordinates, resulting in a new point of the desired type.    ///    /// # Arguments    ///    /// * `f` - A closure that takes a value of type `T` and returns a value of type `U`.    ///    /// # Examples    ///    /// ```    /// # use gpui::Point;    /// let p = Point { x: 3, y: 4 };    /// let p_float = p.map(|coord| coord as f32);    /// assert_eq!(p_float, Point { x: 3.0, y: 4.0 });    /// ```    pub fn map<U: Clone + Default + Debug>(&self, f: impl Fn(T) -> U) -> Point<U> {        Point {            x: f(self.x.clone()),            y: f(self.y.clone()),        }    }} impl<T: Clone + Debug + Default> Along for Point<T> {    type Unit = T;     fn along(&self, axis: Axis) -> T {        match axis {            Axis::Horizontal => self.x.clone(),            Axis::Vertical => self.y.clone(),        }    }     fn apply_along(&self, axis: Axis, f: impl FnOnce(T) -> T) -> Point<T> {        match axis {            Axis::Horizontal => Point {                x: f(self.x.clone()),                y: self.y.clone(),            },            Axis::Vertical => Point {                x: self.x.clone(),                y: f(self.y.clone()),            },        }    }} impl<T: Clone + Debug + Default + Negate> Negate for Point<T> {    fn negate(self) -> Self {        self.map(Negate::negate)    }} impl Point<Pixels> {    /// Scales the point by a given factor, which is typically derived from the resolution    /// of a target display to ensure proper sizing of UI elements.    ///    /// # Arguments    ///    /// * `factor` - The scaling factor to apply to both the x and y coordinates.    ///    /// # Examples    ///    /// ```    /// # use gpui::{Point, Pixels, ScaledPixels};    /// let p = Point { x: Pixels(10.0), y: Pixels(20.0) };    /// let scaled_p = p.scale(1.5);    /// assert_eq!(scaled_p, Point { x: ScaledPixels(15.0), y: ScaledPixels(30.0) });    /// ```    pub fn scale(&self, factor: f32) -> Point<ScaledPixels> {        Point {            x: self.x.scale(factor),            y: self.y.scale(factor),        }    }     /// Calculates the Euclidean distance from the origin (0, 0) to this point.    ///    /// # Examples    ///    /// ```    /// # use gpui::{Pixels, Point};    /// let p = Point { x: Pixels(3.0), y: Pixels(4.0) };    /// assert_eq!(p.magnitude(), 5.0);    /// ```    pub fn magnitude(&self) -> f64 {        ((self.x.0.powi(2) + self.y.0.powi(2)) as f64).sqrt()    }} impl<T, Rhs> Mul<Rhs> for Point<T>where    T: Mul<Rhs, Output = T> + Clone + Default + Debug,    Rhs: Clone + Debug,{    type Output = Point<T>;     fn mul(self, rhs: Rhs) -> Self::Output {        Point {            x: self.x * rhs.clone(),            y: self.y * rhs,        }    }} impl<T, S> MulAssign<S> for Point<T>where    T: Clone + Mul<S, Output = T> + Default + Debug,    S: Clone,{    fn mul_assign(&mut self, rhs: S) {        self.x = self.x.clone() * rhs.clone();        self.y = self.y.clone() * rhs;    }} impl<T, S> Div<S> for Point<T>where    T: Div<S, Output = T> + Clone + Default + Debug,    S: Clone,{    type Output = Self;     fn div(self, rhs: S) -> Self::Output {        Self {            x: self.x / rhs.clone(),            y: self.y / rhs,        }    }} impl<T> Point<T>where    T: PartialOrd + Clone + Default + Debug,{    /// Returns a new point with the maximum values of each dimension from `self` and `other`.    ///    /// # Arguments    ///    /// * `other` - A reference to another `Point` to compare with `self`.    ///    /// # Examples    ///    /// ```    /// # use gpui::Point;    /// let p1 = Point { x: 3, y: 7 };    /// let p2 = Point { x: 5, y: 2 };    /// let max_point = p1.max(&p2);    /// assert_eq!(max_point, Point { x: 5, y: 7 });    /// ```    pub fn max(&self, other: &Self) -> Self {        Point {            x: if self.x > other.x {                self.x.clone()            } else {                other.x.clone()            },            y: if self.y > other.y {                self.y.clone()            } else {                other.y.clone()            },        }    }     /// Returns a new point with the minimum values of each dimension from `self` and `other`.    ///    /// # Arguments    ///    /// * `other` - A reference to another `Point` to compare with `self`.    ///    /// # Examples    ///    /// ```    /// # use gpui::Point;    /// let p1 = Point { x: 3, y: 7 };    /// let p2 = Point { x: 5, y: 2 };    /// let min_point = p1.min(&p2);    /// assert_eq!(min_point, Point { x: 3, y: 2 });    /// ```    pub fn min(&self, other: &Self) -> Self {        Point {            x: if self.x <= other.x {                self.x.clone()            } else {                other.x.clone()            },            y: if self.y <= other.y {                self.y.clone()            } else {                other.y.clone()            },        }    }     /// Clamps the point to a specified range.    ///    /// Given a minimum point and a maximum point, this method constrains the current point    /// such that its coordinates do not exceed the range defined by the minimum and maximum points.    /// If the current point's coordinates are less than the minimum, they are set to the minimum.    /// If they are greater than the maximum, they are set to the maximum.    ///    /// # Arguments    ///    /// * `min` - A reference to a `Point` representing the minimum allowable coordinates.    /// * `max` - A reference to a `Point` representing the maximum allowable coordinates.    ///    /// # Examples    ///    /// ```    /// # use gpui::Point;    /// let p = Point { x: 10, y: 20 };    /// let min = Point { x: 0, y: 5 };    /// let max = Point { x: 15, y: 25 };    /// let clamped_p = p.clamp(&min, &max);    /// assert_eq!(clamped_p, Point { x: 10, y: 20 });    ///    /// let p_out_of_bounds = Point { x: -5, y: 30 };    /// let clamped_p_out_of_bounds = p_out_of_bounds.clamp(&min, &max);    /// assert_eq!(clamped_p_out_of_bounds, Point { x: 0, y: 25 });    /// ```    pub fn clamp(&self, min: &Self, max: &Self) -> Self {        self.max(min).min(max)    }} impl<T: Clone + Default + Debug> Clone for Point<T> {    fn clone(&self) -> Self {        Self {            x: self.x.clone(),            y: self.y.clone(),        }    }} /// A structure representing a two-dimensional size with width and height in a given unit.////// This struct is generic over the type `T`, which can be any type that implements `Clone`, `Default`, and `Debug`./// It is commonly used to specify dimensions for elements in a UI, such as a window or element.#[derive(Refineable, Default, Clone, Copy, PartialEq, Div, Hash, Serialize, Deserialize)]#[refineable(Debug)]#[repr(C)]pub struct Size<T: Clone + Default + Debug> {    /// The width component of the size.    pub width: T,    /// The height component of the size.    pub height: T,} /// Constructs a new `Size<T>` with the provided width and height.////// # Arguments////// * `width` - The width component of the `Size`./// * `height` - The height component of the `Size`.////// # Examples////// ```/// # use gpui::Size;/// let my_size = size(10, 20);/// assert_eq!(my_size.width, 10);/// assert_eq!(my_size.height, 20);/// ```pub const fn size<T>(width: T, height: T) -> Size<T>where    T: Clone + Default + Debug,{    Size { width, height }} impl<T> Size<T>where    T: Clone + Default + Debug,{    /// Applies a function to the width and height of the size, producing a new `Size<U>`.    ///    /// This method allows for converting a `Size<T>` to a `Size<U>` by specifying a closure    /// that defines how to convert between the two types. The closure is applied to both the `width`    /// and `height`, resulting in a new size of the desired type.    ///    /// # Arguments    ///    /// * `f` - A closure that takes a value of type `T` and returns a value of type `U`.    ///    /// # Examples    ///    /// ```    /// # use gpui::Size;    /// let my_size = Size { width: 10, height: 20 };    /// let my_new_size = my_size.map(|dimension| dimension as f32 * 1.5);    /// assert_eq!(my_new_size, Size { width: 15.0, height: 30.0 });    /// ```    pub fn map<U>(&self, f: impl Fn(T) -> U) -> Size<U>    where        U: Clone + Default + Debug,    {        Size {            width: f(self.width.clone()),            height: f(self.height.clone()),        }    }} impl<T> Size<T>where    T: Clone + Default + Debug + Half,{    /// Compute the center point of the size.g    pub fn center(&self) -> Point<T> {        Point {            x: self.width.half(),            y: self.height.half(),        }    }} impl Size<Pixels> {    /// Scales the size by a given factor.    ///    /// This method multiplies both the width and height by the provided scaling factor,    /// resulting in a new `Size<ScaledPixels>` that is proportionally larger or smaller    /// depending on the factor.    ///    /// # Arguments    ///    /// * `factor` - The scaling factor to apply to the width and height.    ///    /// # Examples    ///    /// ```    /// # use gpui::{Size, Pixels, ScaledPixels};    /// let size = Size { width: Pixels(100.0), height: Pixels(50.0) };    /// let scaled_size = size.scale(2.0);    /// assert_eq!(scaled_size, Size { width: ScaledPixels(200.0), height: ScaledPixels(100.0) });    /// ```    pub fn scale(&self, factor: f32) -> Size<ScaledPixels> {        Size {            width: self.width.scale(factor),            height: self.height.scale(factor),        }    }} impl<T> Along for Size<T>where    T: Clone + Default + Debug,{    type Unit = T;     fn along(&self, axis: Axis) -> T {        match axis {            Axis::Horizontal => self.width.clone(),            Axis::Vertical => self.height.clone(),        }    }     /// Returns the value of this size along the given axis.    fn apply_along(&self, axis: Axis, f: impl FnOnce(T) -> T) -> Self {        match axis {            Axis::Horizontal => Size {                width: f(self.width.clone()),                height: self.height.clone(),            },            Axis::Vertical => Size {                width: self.width.clone(),                height: f(self.height.clone()),            },        }    }}

Lines 1–500 of 3383.