From 297b6b282c094093e3bcc6b4fc9627c2d35bdb6d Mon Sep 17 00:00:00 2001 From: Nathan Sobo Date: Fri, 13 Oct 2023 12:41:00 -0600 Subject: [PATCH] Make all geometry types Default to support movement-based refinement --- crates/gpui3/src/geometry.rs | 188 +++++++++++++++++++++++++---------- crates/gpui3/src/scene.rs | 4 +- crates/gpui3/src/taffy.rs | 59 +++++------ crates/gpui3/src/window.rs | 2 +- 4 files changed, 170 insertions(+), 83 deletions(-) diff --git a/crates/gpui3/src/geometry.rs b/crates/gpui3/src/geometry.rs index aace043b926ce6fefa6b62497a5044148beb4f66..33d6809044812f5a0eac700ff85697d7e7169840 100644 --- a/crates/gpui3/src/geometry.rs +++ b/crates/gpui3/src/geometry.rs @@ -2,28 +2,29 @@ use core::fmt::Debug; use derive_more::{Add, AddAssign, Div, Mul, Neg, Sub, SubAssign}; use refineable::Refineable; use std::{ - cmp, fmt, + cmp::{self, PartialOrd}, + fmt, ops::{Add, AddAssign, Div, Mul, MulAssign, Sub, SubAssign}, }; #[derive(Refineable, Default, Add, AddAssign, Sub, SubAssign, Copy, Debug, PartialEq, Eq, Hash)] #[refineable(debug)] #[repr(C)] -pub struct Point { +pub struct Point { pub x: T, pub y: T, } -pub fn point(x: T, y: T) -> Point { +pub fn point(x: T, y: T) -> Point { Point { x, y } } -impl Point { +impl Point { pub fn new(x: T, y: T) -> Self { Self { x, y } } - pub fn map U>(&self, f: F) -> Point { + pub fn map(&self, f: impl Fn(T) -> U) -> Point { Point { x: f(self.x.clone()), y: f(self.y.clone()), @@ -42,7 +43,7 @@ impl Point { impl Mul for Point where - T: Mul + Clone + Debug, + T: Mul + Clone + Default + Debug, Rhs: Clone + Debug, { type Output = Point; @@ -55,28 +56,42 @@ where } } -impl, S: Clone> MulAssign for Point { +impl MulAssign for Point +where + T: Clone + Mul + 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> SubAssign> for Point { +impl SubAssign> for Point +where + T: Sub + Clone + Debug + Default, +{ fn sub_assign(&mut self, rhs: Size) { self.x = self.x.clone() - rhs.width; self.y = self.y.clone() - rhs.height; } } -impl + Copy> AddAssign for Point { +impl AddAssign for Point +where + T: Add + Clone + Default + Debug, +{ fn add_assign(&mut self, rhs: T) { - self.x = self.x.clone() + rhs; + self.x = self.x.clone() + rhs.clone(); self.y = self.y.clone() + rhs; } } -impl, S: Clone> Div for Point { +impl Div for Point +where + T: Div + Clone + Default + Debug, + S: Clone, +{ type Output = Self; fn div(self, rhs: S) -> Self::Output { @@ -87,7 +102,10 @@ impl, S: Clone> Div for Point { } } -impl Point { +impl Point +where + T: PartialOrd + Clone + Default + Debug, +{ pub fn max(&self, other: &Self) -> Self { Point { x: if self.x >= other.x { @@ -119,7 +137,7 @@ impl Point { } } -impl Clone for Point { +impl Clone for Point { fn clone(&self) -> Self { Self { x: self.x.clone(), @@ -131,17 +149,26 @@ impl Clone for Point { #[derive(Refineable, Default, Clone, Copy, PartialEq, Div, Hash)] #[refineable(debug)] #[repr(C)] -pub struct Size { +pub struct Size { pub width: T, pub height: T, } -pub fn size(width: T, height: T) -> Size { +pub fn size(width: T, height: T) -> Size +where + T: Clone + Default + Debug, +{ Size { width, height } } -impl Size { - pub fn map U>(&self, f: F) -> Size { +impl Size +where + T: Clone + Default + Debug, +{ + pub fn map(&self, f: impl Fn(T) -> U) -> Size + where + U: Clone + Default + Debug, + { Size { width: f(self.width.clone()), height: f(self.height.clone()), @@ -158,7 +185,10 @@ impl Size { } } -impl Size { +impl Size +where + T: Ord + Clone + Default + Debug, +{ pub fn max(&self, other: &Self) -> Self { Size { width: if self.width >= other.width { @@ -177,8 +207,8 @@ impl Size { impl Mul for Size where - T: Mul + Debug + Clone, - Rhs: Debug + Clone, + T: Mul + Clone + Default + Debug, + Rhs: Clone + Default + Debug, { type Output = Size; @@ -190,16 +220,23 @@ where } } -impl, S: Clone> MulAssign for Size { +impl MulAssign for Size +where + T: Mul + Clone + Default + Debug, + S: Clone, +{ fn mul_assign(&mut self, rhs: S) { self.width = self.width.clone() * rhs.clone(); self.height = self.height.clone() * rhs; } } -impl Eq for Size {} +impl Eq for Size where T: Eq + Default + Debug + Clone {} -impl Debug for Size { +impl Debug for Size +where + T: Clone + Default + Debug, +{ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Size {{ {:?} × {:?} }}", self.width, self.height) } @@ -244,12 +281,15 @@ impl Size { #[derive(Refineable, Clone, Default, Debug, Eq, PartialEq)] #[refineable(debug)] #[repr(C)] -pub struct Bounds { +pub struct Bounds { pub origin: Point, pub size: Size, } -impl + Default> Bounds { +impl Bounds +where + T: Clone + Debug + Sub + Default, +{ pub fn from_corners(upper_left: Point, lower_right: Point) -> Self { let origin = Point { x: upper_left.x.clone(), @@ -263,7 +303,10 @@ impl + Default> Bounds { } } -impl + Sub + Default> Bounds { +impl Bounds +where + T: Clone + Debug + PartialOrd + Add + Sub + Default, +{ pub fn intersects(&self, other: &Bounds) -> bool { let my_lower_right = self.lower_right(); let their_lower_right = other.lower_right(); @@ -283,7 +326,7 @@ impl + Sub + Defa } } -impl + Sub> Bounds { +impl + Sub> Bounds { 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()); @@ -299,9 +342,9 @@ impl + Sub> Bound impl Mul for Bounds where - T: Mul + Clone + Debug, + T: Mul + Clone + Default + Debug, Point: Mul>, - Rhs: Clone + Debug, + Rhs: Clone + Default + Debug, { type Output = Bounds; @@ -313,16 +356,22 @@ where } } -impl, S: Clone> MulAssign for Bounds { +impl MulAssign for Bounds +where + T: Mul + Clone + Default + Debug, + S: Clone, +{ fn mul_assign(&mut self, rhs: S) { self.origin *= rhs.clone(); self.size *= rhs; } } -impl, S: Clone> Div for Bounds +impl Div for Bounds where Size: Div>, + T: Div + Default + Clone + Debug, + S: Clone, { type Output = Self; @@ -334,7 +383,10 @@ where } } -impl> Bounds { +impl Bounds +where + T: Add + Clone + Default + Debug, +{ pub fn upper_right(&self) -> Point { Point { x: self.origin.x.clone() + self.size.width.clone(), @@ -357,7 +409,10 @@ impl> Bounds { } } -impl> Bounds { +impl Bounds +where + T: Add + PartialOrd + Clone + Default + Debug, +{ pub fn contains_point(&self, point: Point) -> bool { point.x >= self.origin.x && point.x <= self.origin.x.clone() + self.size.width.clone() @@ -365,7 +420,10 @@ impl> Bounds { && point.y <= self.origin.y.clone() + self.size.height.clone() } - pub fn map U>(&self, f: F) -> Bounds { + pub fn map(&self, f: impl Fn(T) -> U) -> Bounds + where + U: Clone + Default + Debug, + { Bounds { origin: self.origin.map(&f), size: self.size.map(f), @@ -382,19 +440,22 @@ impl Bounds { } } -impl Copy for Bounds {} +impl Copy for Bounds {} #[derive(Refineable, Clone, Default, Debug, Eq, PartialEq)] #[refineable(debug)] #[repr(C)] -pub struct Edges { +pub struct Edges { pub top: T, pub right: T, pub bottom: T, pub left: T, } -impl> Mul for Edges { +impl Mul for Edges +where + T: Mul + Clone + Default + Debug, +{ type Output = Self; fn mul(self, rhs: Self) -> Self::Output { @@ -407,19 +468,26 @@ impl> Mul for Edges { } } -impl, S: Clone> MulAssign for Edges { +impl MulAssign for Edges +where + T: Mul + Clone + Default + Debug, + S: Clone, +{ fn mul_assign(&mut self, rhs: S) { self.top = self.top.clone() * rhs.clone(); self.right = self.right.clone() * rhs.clone(); self.bottom = self.bottom.clone() * rhs.clone(); - self.left = self.left.clone() * rhs.clone(); + self.left = self.left.clone() * rhs; } } -impl Copy for Edges {} +impl Copy for Edges {} -impl Edges { - pub fn map U>(&self, f: F) -> Edges { +impl Edges { + pub fn map(&self, f: impl Fn(&T) -> U) -> Edges + where + U: Clone + Default + Debug, + { Edges { top: f(&self.top), right: f(&self.right), @@ -501,7 +569,7 @@ impl Edges { #[derive(Refineable, Clone, Default, Debug, Eq, PartialEq)] #[refineable(debug)] #[repr(C)] -pub struct Corners { +pub struct Corners { pub top_left: T, pub top_right: T, pub bottom_right: T, @@ -531,8 +599,11 @@ impl Corners { } } -impl Corners { - pub fn map U>(&self, f: F) -> Corners { +impl Corners { + pub fn map(&self, f: impl Fn(&T) -> U) -> Corners + where + U: Clone + Default + Debug, + { Corners { top_left: f(&self.top_left), top_right: f(&self.top_right), @@ -542,7 +613,10 @@ impl Corners { } } -impl> Mul for Corners { +impl Mul for Corners +where + T: Mul + Clone + Default + Debug, +{ type Output = Self; fn mul(self, rhs: Self) -> Self::Output { @@ -555,7 +629,11 @@ impl> Mul for Corners { } } -impl, S: Clone> MulAssign for Corners { +impl MulAssign for Corners +where + T: Mul + Clone + Default + Debug, + S: Clone, +{ fn mul_assign(&mut self, rhs: S) { self.top_left = self.top_left.clone() * rhs.clone(); self.top_right = self.top_right.clone() * rhs.clone(); @@ -564,7 +642,7 @@ impl, S: Clone> MulAssign for Corners Copy for Corners {} +impl Copy for Corners where T: Copy + Clone + Default + Debug {} #[derive(Clone, Copy, Default, Add, AddAssign, Sub, SubAssign, Div, Neg, PartialEq, PartialOrd)] #[repr(transparent)] @@ -1016,25 +1094,31 @@ impl IsZero for Length { } } -impl IsZero for Point { +impl IsZero for Point { fn is_zero(&self) -> bool { self.x.is_zero() && self.y.is_zero() } } -impl IsZero for Size { +impl IsZero for Size +where + T: IsZero + Default + Debug + Clone, +{ fn is_zero(&self) -> bool { self.width.is_zero() || self.height.is_zero() } } -impl IsZero for Bounds { +impl IsZero for Bounds { fn is_zero(&self) -> bool { self.size.is_zero() } } -impl IsZero for Corners { +impl IsZero for Corners +where + T: IsZero + Clone + Default + Debug, +{ fn is_zero(&self) -> bool { self.top_left.is_zero() && self.top_right.is_zero() diff --git a/crates/gpui3/src/scene.rs b/crates/gpui3/src/scene.rs index 5406b024d64ec878e46abb2179eb86efd870d953..f4404218b05d5e67a3df02f8c051f0a17cade27c 100644 --- a/crates/gpui3/src/scene.rs +++ b/crates/gpui3/src/scene.rs @@ -595,7 +595,7 @@ impl From for Primitive { pub(crate) struct PathId(pub(crate) usize); #[derive(Debug)] -pub struct Path { +pub struct Path { pub(crate) id: PathId, order: u32, pub(crate) bounds: Bounds

, @@ -736,7 +736,7 @@ impl From> for Primitive { #[derive(Clone, Debug)] #[repr(C)] -pub struct PathVertex { +pub struct PathVertex { pub(crate) xy_position: Point

, pub(crate) st_position: Point, pub(crate) content_mask: ContentMask

, diff --git a/crates/gpui3/src/taffy.rs b/crates/gpui3/src/taffy.rs index 154cb071ddde35710bd8b8732cbfc26eb87dbd1a..cadb7e1b57bff164c2e63ea41b5d5aa2edb05fe4 100644 --- a/crates/gpui3/src/taffy.rs +++ b/crates/gpui3/src/taffy.rs @@ -2,7 +2,7 @@ use super::{AbsoluteLength, Bounds, DefiniteLength, Edges, Length, Pixels, Point use collections::HashMap; use std::fmt::Debug; use taffy::{ - geometry::Size as TaffySize, + geometry::{Point as TaffyPoint, Rect as TaffyRect, Size as TaffySize}, style::AvailableSpace as TaffyAvailableSpace, tree::{Measurable, MeasureFunc, NodeId}, Taffy, @@ -321,11 +321,12 @@ impl ToTaffy for AbsoluteLength { } } -impl From> for Point +impl From> for Point where T: Into, + T2: Clone + Default + Debug, { - fn from(point: taffy::geometry::Point) -> Point { + fn from(point: TaffyPoint) -> Point { Point { x: point.x.into(), y: point.y.into(), @@ -333,33 +334,36 @@ where } } -impl Into> for Point +impl Into> for Point where - T: Into, + T: Into + Clone + Default + Debug, { - fn into(self) -> taffy::geometry::Point { - taffy::geometry::Point { + fn into(self) -> TaffyPoint { + TaffyPoint { x: self.x.into(), y: self.y.into(), } } } -impl + Clone + Debug, U> ToTaffy> for Size { - fn to_taffy(&self, rem_size: Pixels) -> taffy::geometry::Size { - taffy::geometry::Size { +impl ToTaffy> for Size +where + T: ToTaffy + Clone + Default + Debug, +{ + fn to_taffy(&self, rem_size: Pixels) -> TaffySize { + TaffySize { width: self.width.to_taffy(rem_size).into(), height: self.height.to_taffy(rem_size).into(), } } } -impl ToTaffy> for Edges +impl ToTaffy> for Edges where - T: ToTaffy + Clone + Debug, + T: ToTaffy + Clone + Default + Debug, { - fn to_taffy(&self, rem_size: Pixels) -> taffy::geometry::Rect { - taffy::geometry::Rect { + fn to_taffy(&self, rem_size: Pixels) -> TaffyRect { + TaffyRect { top: self.top.to_taffy(rem_size).into(), right: self.right.to_taffy(rem_size).into(), bottom: self.bottom.to_taffy(rem_size).into(), @@ -368,8 +372,12 @@ where } } -impl, U: Clone + Debug> From> for Size { - fn from(taffy_size: taffy::geometry::Size) -> Self { +impl From> for Size +where + T: Into, + U: Clone + Default + Debug, +{ + fn from(taffy_size: TaffySize) -> Self { Size { width: taffy_size.width.into(), height: taffy_size.height.into(), @@ -377,29 +385,24 @@ impl, U: Clone + Debug> From> for Size { } } -impl + Clone + Debug, U> From> for taffy::geometry::Size { +impl From> for TaffySize +where + T: Into + Clone + Default + Debug, +{ fn from(size: Size) -> Self { - taffy::geometry::Size { + TaffySize { width: size.width.into(), height: size.height.into(), } } } -// impl From>> for Size> { -// fn from(value: TaffySize>) -> Self { -// Self { -// width: value.width.map(Into::into), -// height: value.height.map(Into::into), -// } -// } -// } - -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone, Default, Debug)] pub enum AvailableSpace { /// The amount of space available is the specified number of pixels Definite(Pixels), /// The amount of space available is indefinite and the node should be laid out under a min-content constraint + #[default] MinContent, /// The amount of space available is indefinite and the node should be laid out under a max-content constraint MaxContent, diff --git a/crates/gpui3/src/window.rs b/crates/gpui3/src/window.rs index 0af65f476c902eb02554c7a1c40b5082d2fa0947..2861664b51e43ba6aa0fe0d9cd08205354ebc1a3 100644 --- a/crates/gpui3/src/window.rs +++ b/crates/gpui3/src/window.rs @@ -132,7 +132,7 @@ impl Window { #[derive(Clone, Debug, Default, PartialEq, Eq)] #[repr(C)] -pub struct ContentMask { +pub struct ContentMask { pub bounds: Bounds

, }