Add Corner to geometry and make names of corner methods consistent (#22119)

Release Notes:

- N/A
This commit is contained in:
Michael Sloan 2024-12-16 22:57:15 -07:00 committed by GitHub
parent 3052fc2565
commit fc5a810408
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
39 changed files with 325 additions and 254 deletions

View file

@ -694,7 +694,7 @@ impl Size<Length> {
/// Represents a rectangular area in a 2D space with an origin point and a size.
///
/// The `Bounds` struct is generic over a type `T` which represents the type of the coordinate system.
/// The origin is represented as a `Point<T>` which defines the upper-left corner of the rectangle,
/// The origin is represented as a `Point<T>` which defines the top left corner of the rectangle,
/// and the size is represented as a `Size<T>` which defines the width and height of the rectangle.
///
/// # Examples
@ -757,16 +757,16 @@ impl<T> Bounds<T>
where
T: Clone + Debug + Sub<Output = T> + Default,
{
/// Constructs a `Bounds` from two corner points: the upper-left and lower-right corners.
/// Constructs a `Bounds` from two corner points: the top left and bottom right corners.
///
/// This function calculates the origin and size of the `Bounds` based on the provided corner points.
/// The origin is set to the upper-left corner, and the size is determined by the difference between
/// the x and y coordinates of the lower-right and upper-left points.
/// The origin is set to the top left corner, and the size is determined by the difference between
/// the x and y coordinates of the bottom right and top left points.
///
/// # Arguments
///
/// * `upper_left` - A `Point<T>` representing the upper-left corner of the rectangle.
/// * `lower_right` - A `Point<T>` representing the lower-right corner of the rectangle.
/// * `upper_left` - A `Point<T>` representing the top left corner of the rectangle.
/// * `bottom_right` - A `Point<T>` representing the bottom right corner of the rectangle.
///
/// # Returns
///
@ -777,25 +777,53 @@ where
/// ```
/// # use gpui::{Bounds, Point};
/// let upper_left = Point { x: 0, y: 0 };
/// let lower_right = Point { x: 10, y: 10 };
/// let bounds = Bounds::from_corners(upper_left, lower_right);
/// let bottom_right = Point { x: 10, y: 10 };
/// let bounds = Bounds::from_corners(upper_left, bottom_right);
///
/// assert_eq!(bounds.origin, upper_left);
/// assert_eq!(bounds.size.width, 10);
/// assert_eq!(bounds.size.height, 10);
/// ```
pub fn from_corners(upper_left: Point<T>, lower_right: Point<T>) -> Self {
pub fn from_corners(upper_left: Point<T>, bottom_right: Point<T>) -> Self {
let origin = Point {
x: upper_left.x.clone(),
y: upper_left.y.clone(),
};
let size = Size {
width: lower_right.x - upper_left.x,
height: lower_right.y - upper_left.y,
width: bottom_right.x - upper_left.x,
height: bottom_right.y - upper_left.y,
};
Bounds { origin, size }
}
/// Constructs a `Bounds` from a corner point and size.
///
/// # Examples
///
/// ```
/// # use zed::{Bounds, Corner, Point};
/// todo!
/// ```
pub fn from_corner_and_size(corner: Corner, origin: Point<T>, size: Size<T>) -> Bounds<T> {
let origin = match corner {
Corner::TopLeft => origin,
Corner::TopRight => Point {
x: origin.x - size.width.clone(),
y: origin.y,
},
Corner::BottomLeft => Point {
x: origin.x,
y: origin.y - size.height.clone(),
},
Corner::BottomRight => Point {
x: origin.x - size.width.clone(),
y: origin.y - size.height.clone(),
},
};
Bounds { origin, size }
}
/// Creates a new `Bounds` with the specified origin and size.
///
/// # Arguments
@ -849,8 +877,8 @@ where
/// assert_eq!(bounds1.intersects(&bounds3), false); // Non-overlapping bounds
/// ```
pub fn intersects(&self, other: &Bounds<T>) -> bool {
let my_lower_right = self.lower_right();
let their_lower_right = other.lower_right();
let my_lower_right = self.bottom_right();
let their_lower_right = other.bottom_right();
self.origin.x < their_lower_right.x
&& my_lower_right.x > other.origin.x
@ -996,8 +1024,8 @@ impl<T: Clone + Default + Debug + PartialOrd + Add<T, Output = T> + Sub<Output =
/// ```
pub fn intersect(&self, other: &Self) -> Self {
let upper_left = self.origin.max(&other.origin);
let lower_right = self.lower_right().min(&other.lower_right());
Self::from_corners(upper_left, lower_right)
let bottom_right = self.bottom_right().min(&other.bottom_right());
Self::from_corners(upper_left, bottom_right)
}
/// Computes the union of two `Bounds`.
@ -1035,7 +1063,7 @@ impl<T: Clone + Default + Debug + PartialOrd + Add<T, Output = T> + Sub<Output =
/// ```
pub fn union(&self, other: &Self) -> Self {
let top_left = self.origin.min(&other.origin);
let bottom_right = self.lower_right().max(&other.lower_right());
let bottom_right = self.bottom_right().max(&other.bottom_right());
Bounds::from_corners(top_left, bottom_right)
}
}
@ -1123,11 +1151,11 @@ where
self.origin.x.clone() + self.size.width.clone()
}
/// Returns the upper-right corner point of the bounds.
/// Returns the top right corner point of the bounds.
///
/// # Returns
///
/// A `Point<T>` representing the upper-right corner of the bounds.
/// A `Point<T>` representing the top right corner of the bounds.
///
/// # Examples
///
@ -1137,21 +1165,21 @@ where
/// origin: Point { x: 0, y: 0 },
/// size: Size { width: 10, height: 20 },
/// };
/// let upper_right = bounds.upper_right();
/// assert_eq!(upper_right, Point { x: 10, y: 0 });
/// let top_right = bounds.top_right();
/// assert_eq!(top_right, Point { x: 10, y: 0 });
/// ```
pub fn upper_right(&self) -> Point<T> {
pub fn top_right(&self) -> Point<T> {
Point {
x: self.origin.x.clone() + self.size.width.clone(),
y: self.origin.y.clone(),
}
}
/// Returns the lower-right corner point of the bounds.
/// Returns the bottom right corner point of the bounds.
///
/// # Returns
///
/// A `Point<T>` representing the lower-right corner of the bounds.
/// A `Point<T>` representing the bottom right corner of the bounds.
///
/// # Examples
///
@ -1161,21 +1189,21 @@ where
/// origin: Point { x: 0, y: 0 },
/// size: Size { width: 10, height: 20 },
/// };
/// let lower_right = bounds.lower_right();
/// assert_eq!(lower_right, Point { x: 10, y: 20 });
/// let bottom_right = bounds.bottom_right();
/// assert_eq!(bottom_right, Point { x: 10, y: 20 });
/// ```
pub fn lower_right(&self) -> Point<T> {
pub fn bottom_right(&self) -> Point<T> {
Point {
x: self.origin.x.clone() + self.size.width.clone(),
y: self.origin.y.clone() + self.size.height.clone(),
}
}
/// Returns the lower-left corner point of the bounds.
/// Returns the bottom left corner point of the bounds.
///
/// # Returns
///
/// A `Point<T>` representing the lower-left corner of the bounds.
/// A `Point<T>` representing the bottom left corner of the bounds.
///
/// # Examples
///
@ -1185,15 +1213,41 @@ where
/// origin: Point { x: 0, y: 0 },
/// size: Size { width: 10, height: 20 },
/// };
/// let lower_left = bounds.lower_left();
/// assert_eq!(lower_left, Point { x: 0, y: 20 });
/// let bottom_left = bounds.bottom_left();
/// assert_eq!(bottom_left, Point { x: 0, y: 20 });
/// ```
pub fn lower_left(&self) -> Point<T> {
pub fn bottom_left(&self) -> Point<T> {
Point {
x: self.origin.x.clone(),
y: self.origin.y.clone() + self.size.height.clone(),
}
}
/// Returns the requested corner point of the bounds.
///
/// # Returns
///
/// A `Point<T>` representing the corner of the bounds requested by the parameter.
///
/// # Examples
///
/// ```
/// # use zed::{Bounds, Corner, Point, Size};
/// let bounds = Bounds {
/// origin: Point { x: 0, y: 0 },
/// size: Size { width: 10, height: 20 },
/// };
/// let bottom_left = bounds.corner(Corner::BottomLeft);
/// assert_eq!(bottom_left, Point { x: 0, y: 20 });
/// ```
pub fn corner(&self, corner: Corner) -> Point<T> {
match corner {
Corner::TopLeft => self.origin.clone(),
Corner::TopRight => self.top_right(),
Corner::BottomLeft => self.bottom_left(),
Corner::BottomRight => self.bottom_right(),
}
}
}
impl<T> Bounds<T>
@ -1861,6 +1915,64 @@ impl From<Pixels> for Edges<Pixels> {
}
}
/// Identifies a corner of a 2d box.
#[derive(Clone, Copy, PartialEq, Eq)]
pub enum Corner {
/// The top left corner
TopLeft,
/// The top right corner
TopRight,
/// The bottom left corner
BottomLeft,
/// The bottom right corner
BottomRight,
}
impl Corner {
/// Returns the directly opposite corner.
///
/// # Examples
///
/// ```
/// # use zed::Corner;
/// assert_eq!(Corner::TopLeft.opposite_corner(), Corner::BottomRight);
/// ```
pub fn opposite_corner(self) -> Self {
match self {
Corner::TopLeft => Corner::BottomRight,
Corner::TopRight => Corner::BottomLeft,
Corner::BottomLeft => Corner::TopRight,
Corner::BottomRight => Corner::TopLeft,
}
}
/// Returns the corner across from this corner, moving along the specified axis.
///
/// # Examples
///
/// ```
/// # use zed::Corner;
/// let result = Corner::TopLeft.other_side_corner_along(Axis::Horizontal);
/// assert_eq!(result, Corner::TopRight);
/// ```
pub fn other_side_corner_along(self, axis: Axis) -> Self {
match axis {
Axis::Vertical => match self {
Corner::TopLeft => Corner::BottomLeft,
Corner::TopRight => Corner::BottomRight,
Corner::BottomLeft => Corner::TopLeft,
Corner::BottomRight => Corner::TopRight,
},
Axis::Horizontal => match self {
Corner::TopLeft => Corner::TopRight,
Corner::TopRight => Corner::TopLeft,
Corner::BottomLeft => Corner::BottomRight,
Corner::BottomRight => Corner::BottomLeft,
},
}
}
}
/// Represents the corners of a box in a 2D space, such as border radius.
///
/// Each field represents the size of the corner on one side of the box: `top_left`, `top_right`, `bottom_right`, and `bottom_left`.
@ -1914,6 +2026,33 @@ where
bottom_left: value,
}
}
/// Returns the requested corner.
///
/// # Returns
///
/// A `Point<T>` representing the corner requested by the parameter.
///
/// # Examples
///
/// ```
/// # use zed::{Corner, Corners};
/// let corners = Corners {
/// top_left: 1,
/// top_right: 2,
/// bottom_left: 3,
/// bottom_right: 4
/// };
/// assert_eq!(corners.corner(Corner::BottomLeft), 3);
/// ```
pub fn corner(&self, corner: Corner) -> T {
match corner {
Corner::TopLeft => self.top_left.clone(),
Corner::TopRight => self.top_right.clone(),
Corner::BottomLeft => self.bottom_left.clone(),
Corner::BottomRight => self.bottom_right.clone(),
}
}
}
impl Corners<AbsoluteLength> {