Checkpoint

This commit is contained in:
Nathan Sobo 2023-09-14 18:51:03 -06:00
parent 378b2fbd9e
commit 4fd4f44bb7
5 changed files with 144 additions and 123 deletions

View file

@ -4,12 +4,13 @@ use refineable::Refineable;
use std::ops::Mul;
#[derive(Refineable, Default, Add, AddAssign, Sub, Mul, Div, Copy, Debug, PartialEq, Eq, Hash)]
pub struct Point<T: Clone> {
#[refineable(debug)]
pub struct Point<T: Clone + Debug> {
pub x: T,
pub y: T,
}
impl<T: Clone> Clone for Point<T> {
impl<T: Clone + Debug> Clone for Point<T> {
fn clone(&self) -> Self {
Self {
x: self.x.clone(),
@ -18,8 +19,9 @@ impl<T: Clone> Clone for Point<T> {
}
}
#[derive(Default, Clone, Refineable, Debug)]
pub struct Size<T: Clone> {
#[derive(Refineable, Default, Clone, Debug)]
#[refineable(debug)]
pub struct Size<T: Clone + Debug> {
pub width: T,
pub height: T,
}
@ -52,13 +54,15 @@ impl Size<Length> {
}
#[derive(Refineable, Clone, Default, Debug)]
pub struct Bounds<F: Clone> {
pub origin: Point<F>,
pub size: Size<F>,
#[refineable(debug)]
pub struct Bounds<T: Clone + Debug> {
pub origin: Point<T>,
pub size: Size<T>,
}
#[derive(Refineable, Clone, Default, Debug)]
pub struct Edges<T: Clone> {
#[refineable(debug)]
pub struct Edges<T: Clone + Debug> {
pub top: T,
pub right: T,
pub bottom: T,

View file

@ -38,8 +38,15 @@ pub trait Context {
) -> R;
}
#[derive(Clone, Eq, PartialEq)]
pub struct SharedString(ArcCow<'static, str>);
impl std::fmt::Debug for SharedString {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.0.fmt(f)
}
}
impl<T: Into<ArcCow<'static, str>>> From<T> for SharedString {
fn from(value: T) -> Self {
Self(value.into())

View file

@ -1,14 +1,12 @@
use gpui2::fonts::TextStyleRefinement;
use refineable::Refineable;
use std::sync::Arc;
pub use super::taffy::style::{
AlignContent, AlignItems, AlignSelf, Display, FlexDirection, FlexWrap, JustifyContent,
Overflow, Position,
};
use super::{
AbsoluteLength, DefiniteLength, Edges, EdgesRefinement, Hsla, Length, Point, PointRefinement,
SharedString, Size, SizeRefinement, WindowContext,
rems, AbsoluteLength, Bounds, DefiniteLength, Edges, EdgesRefinement, Hsla, Length, Pixels,
Point, PointRefinement, Rems, SharedString, Size, SizeRefinement, ViewContext, WindowContext,
};
pub use gpui2::style::{FontStyle, FontWeight};
@ -98,30 +96,33 @@ pub struct Style {
pub text_color: Option<Hsla>,
/// The font size in rems.
pub font_size: Option<f32>,
pub font_size: Option<Rems>,
pub font_family: Option<Arc<str>>,
pub font_family: Option<SharedString>,
pub font_weight: Option<FontWeight>,
pub font_style: Option<FontStyle>,
}
#[derive(Clone, Debug)]
#[derive(Refineable, Clone, Debug)]
#[refineable(debug)]
pub struct TextStyle {
pub color: Color,
pub font_family_name: SharedString,
pub font_size: FontSize,
pub color: Hsla,
pub font_family: SharedString,
pub font_size: Rems,
pub font_weight: FontWeight,
pub font_style: FontStyle,
pub underline: Underline,
pub soft_wrap: bool,
}
#[derive(Clone, Default, Debug)]
#[derive(Refineable, Clone, Default, Debug)]
#[refineable(debug)]
pub struct Underline {
pub origin: Vector2F,
pub width: f32,
pub thickness: f32,
pub color: Color,
pub origin: Point<Pixels>,
pub width: Pixels,
pub thickness: Pixels,
pub color: Hsla,
pub squiggly: bool,
}
@ -137,75 +138,31 @@ impl Style {
}
Some(TextStyleRefinement {
color: self.text_color.map(Into::into),
color: self.text_color,
font_family: self.font_family.clone(),
font_size: self.font_size.map(|size| size * cx.rem_size()),
font_weight: self.font_weight.map(Into::into),
font_size: self.font_size,
font_weight: self.font_weight,
font_style: self.font_style,
underline: None,
})
}
pub fn to_taffy(&self, rem_size: f32) -> taffy::style::Style {
taffy::style::Style {
display: self.display,
overflow: self.overflow.clone().into(),
scrollbar_width: self.scrollbar_width,
position: self.position,
inset: self.inset.to_taffy(rem_size),
size: self.size.to_taffy(rem_size),
min_size: self.min_size.to_taffy(rem_size),
max_size: self.max_size.to_taffy(rem_size),
aspect_ratio: self.aspect_ratio,
margin: self.margin.to_taffy(rem_size),
padding: self.padding.to_taffy(rem_size),
border: self.border_widths.to_taffy(rem_size),
align_items: self.align_items,
align_self: self.align_self,
align_content: self.align_content,
justify_content: self.justify_content,
gap: self.gap.to_taffy(rem_size),
flex_direction: self.flex_direction,
flex_wrap: self.flex_wrap,
flex_basis: self.flex_basis.to_taffy(rem_size).into(),
flex_grow: self.flex_grow,
flex_shrink: self.flex_shrink,
..Default::default() // Ignore grid properties for now
}
}
/// Paints the background of an element styled with this style.
pub fn paint_background<V: 'static>(&self, bounds: RectF, cx: &mut ViewContext<V>) {
pub fn paint_background<V: 'static>(&self, bounds: Bounds<Pixels>, cx: &mut ViewContext<V>) {
let rem_size = cx.rem_size();
if let Some(color) = self.fill.as_ref().and_then(Fill::color) {
cx.scene().push_quad(gpui::Quad {
bounds,
background: Some(color.into()),
corner_radii: self.corner_radii.to_gpui(bounds.size(), rem_size),
border: Default::default(),
});
todo!();
}
}
/// Paints the foreground of an element styled with this style.
pub fn paint_foreground<V: 'static>(&self, bounds: RectF, cx: &mut ViewContext<V>) {
pub fn paint_foreground<V: 'static>(&self, bounds: Bounds<Pixels>, cx: &mut ViewContext<V>) {
let rem_size = cx.rem_size();
if let Some(color) = self.border_color {
let border = self.border_widths.to_pixels(rem_size);
if !border.is_empty() {
cx.scene().push_quad(gpui::Quad {
bounds,
background: None,
corner_radii: self.corner_radii.to_gpui(bounds.size(), rem_size),
border: scene::Border {
color: color.into(),
top: border.top,
right: border.right,
bottom: border.bottom,
left: border.left,
},
});
todo!();
}
}
}
@ -245,7 +202,7 @@ impl Default for Style {
border_color: None,
corner_radii: CornerRadii::default(),
text_color: None,
font_size: Some(1.),
font_size: Some(rems(1.)),
font_family: None,
font_weight: None,
font_style: None,
@ -286,16 +243,3 @@ pub struct CornerRadii {
bottom_left: AbsoluteLength,
bottom_right: AbsoluteLength,
}
impl CornerRadii {
pub fn to_gpui(&self, box_size: Vector2F, rem_size: f32) -> gpui::scene::CornerRadii {
let max_radius = box_size.x().min(box_size.y()) / 2.;
gpui::scene::CornerRadii {
top_left: self.top_left.to_pixels(rem_size).min(max_radius),
top_right: self.top_right.to_pixels(rem_size).min(max_radius),
bottom_left: self.bottom_left.to_pixels(rem_size).min(max_radius),
bottom_right: self.bottom_right.to_pixels(rem_size).min(max_radius),
}
}
}

View file

@ -33,17 +33,37 @@ impl TaffyLayoutEngine {
}
}
trait ToTaffy {
type Output;
fn to_taffy(&self, rem_size: Pixels) -> Self::Output;
trait ToTaffy<Output> {
fn to_taffy(&self, rem_size: Pixels) -> Output;
}
impl ToTaffy for Style {
type Output = taffy::style::Style;
fn to_taffy(&self, rem_size: Pixels) -> Self::Output {
todo!()
impl ToTaffy<taffy::style::Style> for Style {
fn to_taffy(&self, rem_size: Pixels) -> taffy::style::Style {
taffy::style::Style {
display: self.display,
overflow: self.overflow.clone().into(),
scrollbar_width: self.scrollbar_width,
position: self.position,
inset: self.inset.to_taffy(rem_size),
size: self.size.to_taffy(rem_size),
min_size: self.min_size.to_taffy(rem_size),
max_size: self.max_size.to_taffy(rem_size),
aspect_ratio: self.aspect_ratio,
margin: self.margin.to_taffy(rem_size),
padding: self.padding.to_taffy(rem_size),
border: self.border_widths.to_taffy(rem_size),
align_items: self.align_items,
align_self: self.align_self,
align_content: self.align_content,
justify_content: self.justify_content,
gap: self.gap.to_taffy(rem_size),
flex_direction: self.flex_direction,
flex_wrap: self.flex_wrap,
flex_basis: self.flex_basis.to_taffy(rem_size),
flex_grow: self.flex_grow,
flex_shrink: self.flex_shrink,
..Default::default() // Ignore grid properties for now
}
}
}
@ -61,20 +81,25 @@ impl ToTaffy for Style {
// }
// }
impl ToTaffy for Length {
type Output = taffy::style::LengthPercentageAuto;
impl ToTaffy<taffy::style::LengthPercentageAuto> for Length {
fn to_taffy(&self, rem_size: Pixels) -> taffy::prelude::LengthPercentageAuto {
match self {
Length::Definite(length) => length.to_taffy(rem_size).into(),
Length::Definite(length) => length.to_taffy(rem_size),
Length::Auto => taffy::prelude::LengthPercentageAuto::Auto,
}
}
}
impl ToTaffy for DefiniteLength {
type Output = taffy::style::LengthPercentage;
impl ToTaffy<taffy::style::Dimension> for Length {
fn to_taffy(&self, rem_size: Pixels) -> taffy::prelude::Dimension {
match self {
Length::Definite(length) => length.to_taffy(rem_size),
Length::Auto => taffy::prelude::Dimension::Auto,
}
}
}
impl ToTaffy<taffy::style::LengthPercentage> for DefiniteLength {
fn to_taffy(&self, rem_size: Pixels) -> taffy::style::LengthPercentage {
match self {
DefiniteLength::Absolute(length) => match length {
@ -92,10 +117,40 @@ impl ToTaffy for DefiniteLength {
}
}
impl ToTaffy for AbsoluteLength {
type Output = taffy::style::LengthPercentage;
impl ToTaffy<taffy::style::LengthPercentageAuto> for DefiniteLength {
fn to_taffy(&self, rem_size: Pixels) -> taffy::style::LengthPercentageAuto {
match self {
DefiniteLength::Absolute(length) => match length {
AbsoluteLength::Pixels(pixels) => {
taffy::style::LengthPercentageAuto::Length(pixels.into())
}
AbsoluteLength::Rems(rems) => {
taffy::style::LengthPercentageAuto::Length((*rems * rem_size).into())
}
},
DefiniteLength::Fraction(fraction) => {
taffy::style::LengthPercentageAuto::Percent(*fraction)
}
}
}
}
fn to_taffy(&self, rem_size: Pixels) -> Self::Output {
impl ToTaffy<taffy::style::Dimension> for DefiniteLength {
fn to_taffy(&self, rem_size: Pixels) -> taffy::style::Dimension {
match self {
DefiniteLength::Absolute(length) => match length {
AbsoluteLength::Pixels(pixels) => taffy::style::Dimension::Length(pixels.into()),
AbsoluteLength::Rems(rems) => {
taffy::style::Dimension::Length((*rems * rem_size).into())
}
},
DefiniteLength::Fraction(fraction) => taffy::style::Dimension::Percent(*fraction),
}
}
}
impl ToTaffy<taffy::style::LengthPercentage> for AbsoluteLength {
fn to_taffy(&self, rem_size: Pixels) -> taffy::style::LengthPercentage {
match self {
AbsoluteLength::Pixels(pixels) => taffy::style::LengthPercentage::Length(pixels.into()),
AbsoluteLength::Rems(rems) => {
@ -105,7 +160,7 @@ impl ToTaffy for AbsoluteLength {
}
}
impl<T, T2> From<taffy::geometry::Point<T>> for Point<T2>
impl<T, T2: Clone + Debug> From<taffy::geometry::Point<T>> for Point<T2>
where
T: Into<T2>,
{
@ -117,7 +172,7 @@ where
}
}
impl<T, T2> Into<taffy::geometry::Point<T2>> for Point<T>
impl<T: Clone + Debug, T2> Into<taffy::geometry::Point<T2>> for Point<T>
where
T: Into<T2>,
{
@ -129,10 +184,8 @@ where
}
}
impl<T: ToTaffy + Clone> ToTaffy for Size<T> {
type Output = taffy::geometry::Size<T::Output>;
fn to_taffy(&self, rem_size: Pixels) -> Self::Output {
impl<T: ToTaffy<U> + Clone + Debug, U> ToTaffy<taffy::geometry::Size<U>> for Size<T> {
fn to_taffy(&self, rem_size: Pixels) -> taffy::geometry::Size<U> {
taffy::geometry::Size {
width: self.width.to_taffy(rem_size).into(),
height: self.height.to_taffy(rem_size).into(),
@ -140,15 +193,16 @@ impl<T: ToTaffy + Clone> ToTaffy for Size<T> {
}
}
impl<T: ToTaffy + Clone> ToTaffy for Edges<T> {
type Output = taffy::geometry::Rect<T::Output>;
fn to_taffy(&self, rem_size: Pixels) -> Self::Output {
impl<T, U> ToTaffy<taffy::geometry::Rect<U>> for Edges<T>
where
T: ToTaffy<U> + Clone + Debug,
{
fn to_taffy(&self, rem_size: Pixels) -> taffy::geometry::Rect<U> {
taffy::geometry::Rect {
top: self.top.to_taffy(rem_size),
right: self.right.to_taffy(rem_size),
bottom: self.bottom.to_taffy(rem_size),
left: self.left.to_taffy(rem_size),
top: self.top.to_taffy(rem_size).into(),
right: self.right.to_taffy(rem_size).into(),
bottom: self.bottom.to_taffy(rem_size).into(),
left: self.left.to_taffy(rem_size).into(),
}
}
}
@ -179,6 +233,6 @@ impl From<&taffy::tree::Layout> for Layout {
impl From<f32> for Pixels {
fn from(pixels: f32) -> Self {
Self(pixels)
Pixels(pixels)
}
}

View file

@ -1,4 +1,7 @@
use std::sync::Arc;
use std::{
fmt::{self, Debug},
sync::Arc,
};
#[derive(PartialEq, Eq)]
pub enum ArcCow<'a, T: ?Sized> {
@ -72,3 +75,12 @@ impl<T: ?Sized> AsRef<T> for ArcCow<'_, T> {
}
}
}
impl<'a, T: ?Sized + Debug> Debug for ArcCow<'a, T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
ArcCow::Borrowed(borrowed) => Debug::fmt(borrowed, f),
ArcCow::Owned(owned) => Debug::fmt(&**owned, f),
}
}
}