Detailed changes
@@ -1,131 +1,131 @@
-use crate::{
- element::{Element, ElementMetadata, ParentElement},
- frame,
- text::ArcCow,
- themes::rose_pine,
-};
-use gpui::{platform::MouseButton, ViewContext};
-use playground_macros::Element;
-use std::{marker::PhantomData, rc::Rc};
-
-struct ButtonHandlers<V, D> {
- click: Option<Rc<dyn Fn(&mut V, &D, &mut ViewContext<V>)>>,
-}
-
-impl<V, D> Default for ButtonHandlers<V, D> {
- fn default() -> Self {
- Self { click: None }
- }
-}
-
-#[derive(Element)]
-#[element_crate = "crate"]
-pub struct Button<V: 'static, D: 'static> {
- metadata: ElementMetadata<V>,
- handlers: ButtonHandlers<V, D>,
- label: Option<ArcCow<'static, str>>,
- icon: Option<ArcCow<'static, str>>,
- data: Rc<D>,
- view_type: PhantomData<V>,
-}
-
-// Impl block for buttons without data.
-// See below for an impl block for any button.
-impl<V: 'static> Button<V, ()> {
- fn new() -> Self {
- Self {
- metadata: Default::default(),
- handlers: ButtonHandlers::default(),
- label: None,
- icon: None,
- data: Rc::new(()),
- view_type: PhantomData,
- }
- }
-
- pub fn data<D: 'static>(self, data: D) -> Button<V, D> {
- Button {
- metadata: Default::default(),
- handlers: ButtonHandlers::default(),
- label: self.label,
- icon: self.icon,
- data: Rc::new(data),
- view_type: PhantomData,
- }
- }
-}
-
-// Impl block for *any* button.
-impl<V: 'static, D: 'static> Button<V, D> {
- pub fn label(mut self, label: impl Into<ArcCow<'static, str>>) -> Self {
- self.label = Some(label.into());
- self
- }
-
- pub fn icon(mut self, icon: impl Into<ArcCow<'static, str>>) -> Self {
- self.icon = Some(icon.into());
- self
- }
-
- pub fn click(self, handler: impl Fn(&mut V, &D, &mut ViewContext<V>) + 'static) -> Self {
- let data = self.data.clone();
- Element::click(self, MouseButton::Left, move |view, _, cx| {
- handler(view, data.as_ref(), cx);
- })
- }
-}
-
-pub fn button<V>() -> Button<V, ()> {
- Button::new()
-}
-
-impl<V: 'static, D: 'static> Button<V, D> {
- fn render(&mut self, view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
- // TODO: Drive theme from the context
- let button = frame()
- .fill(rose_pine::dawn().error(0.5))
- .h_4()
- .children(self.label.clone());
-
- if let Some(handler) = self.handlers.click.clone() {
- let data = self.data.clone();
- button.mouse_down(MouseButton::Left, move |view, event, cx| {
- handler(view, data.as_ref(), cx)
- })
- } else {
- button
- }
- }
-}
-
-// impl<V: 'static, D> Element<V> for Button<V, D> {
-// type Layout = AnyElement<V>;
-
-// fn style_mut(&mut self) -> &mut crate::style::ElementStyle {
-// &mut self.metadata.style
+// use crate::{
+// element::{Element, ElementMetadata, ParentElement},
+// frame,
+// text::ArcCow,
+// themes::rose_pine,
+// };
+// use gpui::{platform::MouseButton, ViewContext};
+// use playground_macros::Element;
+// use std::{marker::PhantomData, rc::Rc};
+
+// struct ButtonHandlers<V, D> {
+// click: Option<Rc<dyn Fn(&mut V, &D, &mut ViewContext<V>)>>,
+// }
+
+// impl<V, D> Default for ButtonHandlers<V, D> {
+// fn default() -> Self {
+// Self { click: None }
+// }
+// }
+
+// #[derive(Element)]
+// #[element_crate = "crate"]
+// pub struct Button<V: 'static, D: 'static> {
+// metadata: ElementMetadata<V>,
+// handlers: ButtonHandlers<V, D>,
+// label: Option<ArcCow<'static, str>>,
+// icon: Option<ArcCow<'static, str>>,
+// data: Rc<D>,
+// view_type: PhantomData<V>,
+// }
+
+// // Impl block for buttons without data.
+// // See below for an impl block for any button.
+// impl<V: 'static> Button<V, ()> {
+// fn new() -> Self {
+// Self {
+// metadata: Default::default(),
+// handlers: ButtonHandlers::default(),
+// label: None,
+// icon: None,
+// data: Rc::new(()),
+// view_type: PhantomData,
+// }
+// }
+
+// pub fn data<D: 'static>(self, data: D) -> Button<V, D> {
+// Button {
+// metadata: Default::default(),
+// handlers: ButtonHandlers::default(),
+// label: self.label,
+// icon: self.icon,
+// data: Rc::new(data),
+// view_type: PhantomData,
+// }
+// }
+// }
+
+// // Impl block for *any* button.
+// impl<V: 'static, D: 'static> Button<V, D> {
+// pub fn label(mut self, label: impl Into<ArcCow<'static, str>>) -> Self {
+// self.label = Some(label.into());
+// self
// }
-// fn handlers_mut(&mut self) -> &mut crate::element::ElementHandlers<V> {
-// &mut self.metadata.handlers
+// pub fn icon(mut self, icon: impl Into<ArcCow<'static, str>>) -> Self {
+// self.icon = Some(icon.into());
+// self
// }
-// fn layout(
-// &mut self,
-// view: &mut V,
-// cx: &mut crate::element::LayoutContext<V>,
-// ) -> anyhow::Result<(taffy::tree::NodeId, Self::Layout)> {
-// let mut element = self.render(view, cx).into_any();
-// let node_id = element.layout(view, cx)?;
-// Ok((node_id, element))
+// pub fn click(self, handler: impl Fn(&mut V, &D, &mut ViewContext<V>) + 'static) -> Self {
+// let data = self.data.clone();
+// Element::click(self, MouseButton::Left, move |view, _, cx| {
+// handler(view, data.as_ref(), cx);
+// })
// }
+// }
+
+// pub fn button<V>() -> Button<V, ()> {
+// Button::new()
+// }
-// fn paint<'a>(
-// &mut self,
-// layout: crate::element::Layout<'a, Self::Layout>,
-// view: &mut V,
-// cx: &mut crate::element::PaintContext<V>,
-// ) -> anyhow::Result<()> {
-// layout.from_element.paint(view, cx)?;
-// Ok(())
+// impl<V: 'static, D: 'static> Button<V, D> {
+// fn render(&mut self, view: &mut V, cx: &mut ViewContext<V>) -> impl Element<V> {
+// // TODO: Drive theme from the context
+// let button = frame()
+// .fill(rose_pine::dawn().error(0.5))
+// .h_4()
+// .children(self.label.clone());
+
+// if let Some(handler) = self.handlers.click.clone() {
+// let data = self.data.clone();
+// button.mouse_down(MouseButton::Left, move |view, event, cx| {
+// handler(view, data.as_ref(), cx)
+// })
+// } else {
+// button
+// }
// }
// }
+
+// // impl<V: 'static, D> Element<V> for Button<V, D> {
+// // type Layout = AnyElement<V>;
+
+// // fn style_mut(&mut self) -> &mut crate::style::ElementStyle {
+// // &mut self.metadata.style
+// // }
+
+// // fn handlers_mut(&mut self) -> &mut crate::element::ElementHandlers<V> {
+// // &mut self.metadata.handlers
+// // }
+
+// // fn layout(
+// // &mut self,
+// // view: &mut V,
+// // cx: &mut crate::element::LayoutContext<V>,
+// // ) -> anyhow::Result<(taffy::tree::NodeId, Self::Layout)> {
+// // let mut element = self.render(view, cx).into_any();
+// // let node_id = element.layout(view, cx)?;
+// // Ok((node_id, element))
+// // }
+
+// // fn paint<'a>(
+// // &mut self,
+// // layout: crate::element::Layout<'a, Self::Layout>,
+// // view: &mut V,
+// // cx: &mut crate::element::PaintContext<V>,
+// // ) -> anyhow::Result<()> {
+// // layout.from_element.paint(view, cx)?;
+// // Ok(())
+// // }
+// // }
@@ -78,7 +78,6 @@ pub trait Element<V> {
}
}
-use crate as playground; // Macro invocation below references this crate as playground.
pub trait Styleable {
type Style: refineable::Refineable;
@@ -89,12 +88,15 @@ pub trait Styleable {
style.refine(self.declared_style());
style
}
+}
- // Tailwind-style helpers methods that take and return mut self
- //
- // Example:
- // // Sets the padding to 0.5rem, just like class="p-2" in Tailwind.
- // fn p_2(mut self) -> Self where Self: Sized;
+// Tailwind-style helpers methods that take and return mut self
+//
+// Example:
+// // Sets the padding to 0.5rem, just like class="p-2" in Tailwind.
+// fn p_2(mut self) -> Self where Self: Sized;
+use crate as playground; // Macro invocation references this crate as playground.
+pub trait StyleHelpers: Styleable<Style = Style> {
styleable_helpers!();
}
@@ -139,6 +141,8 @@ impl<V: 'static> Element<V> for Div<V> {
Self: Sized,
{
let style = self.style();
+
+ style.paint_background::<V, Self>(layout, cx);
}
}
@@ -1,17 +1,15 @@
use crate::{
adapter::Adapter,
color::Hsla,
- hoverable::Hoverable,
style::{Display, Fill, Overflow, Position, StyleRefinement},
};
use anyhow::Result;
pub use gpui::LayoutContext;
use gpui::{
- geometry::{DefinedLength, Length, PointRefinement},
+ geometry::PointRefinement,
platform::{MouseButton, MouseButtonEvent},
EngineLayout, EventContext, RenderContext, ViewContext,
};
-use playground_macros::tailwind_lengths;
use refineable::Refineable;
use std::{
any::{Any, TypeId},
@@ -338,94 +336,6 @@ pub trait Element<V: 'static>: 'static {
self
}
- #[tailwind_lengths]
- fn inset_(mut self, length: DefinedLength) -> Self
- where
- Self: Sized,
- {
- let inset = &mut self.declared_style().inset;
- inset.top = Some(length);
- inset.right = Some(length);
- inset.bottom = Some(length);
- inset.left = Some(length);
- self
- }
-
- fn w(mut self, width: impl Into<Length>) -> Self
- where
- Self: Sized,
- {
- self.declared_style().size.width = Some(width.into());
- self
- }
-
- fn w_auto(mut self) -> Self
- where
- Self: Sized,
- {
- self.declared_style().size.width = Some(Length::Auto);
- self
- }
-
- #[tailwind_lengths]
- fn w_(mut self, length: DefinedLength) -> Self
- where
- Self: Sized,
- {
- self.declared_style().size.width = Some(length);
- self
- }
-
- #[tailwind_lengths]
- fn min_w_(mut self, length: DefinedLength) -> Self
- where
- Self: Sized,
- {
- self.declared_style().min_size.width = Some(length);
- self
- }
-
- fn h(mut self, height: impl Into<Length>) -> Self
- where
- Self: Sized,
- {
- self.declared_style().size.height = Some(height.into());
- self
- }
-
- fn h_auto(mut self) -> Self
- where
- Self: Sized,
- {
- self.declared_style().size.height = Some(Length::Auto);
- self
- }
-
- #[tailwind_lengths]
- fn h_(mut self, height: DefinedLength) -> Self
- where
- Self: Sized,
- {
- self.declared_style().size.height = Some(height);
- self
- }
-
- #[tailwind_lengths]
- fn min_h_(mut self, length: DefinedLength) -> Self
- where
- Self: Sized,
- {
- self.declared_style().min_size.height = Some(length);
- self
- }
-
- fn hover(self) -> Hoverable<V, Self>
- where
- Self: Sized,
- {
- Hoverable::new(self)
- }
-
fn fill(mut self, fill: impl Into<Fill>) -> Self
where
Self: Sized,
@@ -1,17 +1,8 @@
#![allow(dead_code, unused_variables)]
-use color::black;
-use components::button;
-use element::{Element, ParentElement};
-use frame::frame;
-use gpui::{
- geometry::{rect::RectF, vector::vec2f},
- platform::WindowOptions,
-};
use log::LevelFilter;
use simplelog::SimpleLogger;
-use themes::{rose_pine, ThemeColors};
-use view::view;
+use themes::ThemeColors;
mod adapter;
mod color;
@@ -31,31 +22,32 @@ fn main() {
SimpleLogger::init(LevelFilter::Info, Default::default()).expect("could not initialize logger");
gpui::App::new(()).unwrap().run(|cx| {
- cx.add_window(
- WindowOptions {
- bounds: gpui::platform::WindowBounds::Fixed(RectF::new(
- vec2f(0., 0.),
- vec2f(400., 300.),
- )),
- center: true,
- ..Default::default()
- },
- |_| view(|_| playground(&rose_pine::moon())),
- );
+ // cx.add_window(
+ // WindowOptions {
+ // bounds: gpui::platform::WindowBounds::Fixed(RectF::new(
+ // vec2f(0., 0.),
+ // vec2f(400., 300.),
+ // )),
+ // center: true,
+ // ..Default::default()
+ // },
+ // |_| view(|_| playground(&rose_pine::moon())),
+ // );
cx.platform().activate(true);
});
}
-fn playground<V: 'static>(theme: &ThemeColors) -> impl Element<V> {
- frame()
- .text_color(black())
- .h_full()
- .w_half()
- .fill(theme.success(0.5))
- .hover()
- .fill(theme.error(0.5))
- .child(button().label("Hello").click(|_, _, _| println!("click!")))
-}
+// fn playground<V: 'static>(theme: &ThemeColors) -> impl Element<V> {
+// todo!()
+// // frame()
+// // .text_color(black())
+// // .h_full()
+// // .w_half()
+// // .fill(theme.success(0.5))
+// // .hover()
+// // .fill(theme.error(0.5))
+// // .child(button().label("Hello").click(|_, _, _| println!("click!")))
+// }
// todo!()
// // column()
@@ -1,8 +1,13 @@
-use crate::color::Hsla;
+use crate::{
+ color::Hsla,
+ div::{Element, Layout},
+ element::PaintContext,
+};
use gpui::{
fonts::TextStyleRefinement,
geometry::{
- DefinedLength, Edges, EdgesRefinement, Length, Point, PointRefinement, Size, SizeRefinement,
+ AbsoluteLength, DefiniteLength, Edges, EdgesRefinement, Length, Point, PointRefinement,
+ Size, SizeRefinement,
},
};
use refineable::Refineable;
@@ -49,10 +54,10 @@ pub struct Style {
pub margin: Edges<Length>,
/// How large should the padding be on each side?
#[refineable]
- pub padding: Edges<DefinedLength>,
+ pub padding: Edges<DefiniteLength>,
/// How large should the border be on each side?
#[refineable]
- pub border: Edges<DefinedLength>,
+ pub border: Edges<DefiniteLength>,
// Alignment properties
/// How this node's children aligned in the cross/block axis?
@@ -65,7 +70,7 @@ pub struct Style {
pub justify_content: Option<JustifyContent>,
/// How large should the gaps between items in a flex container be?
#[refineable]
- pub gap: Size<DefinedLength>,
+ pub gap: Size<DefiniteLength>,
// Flexbox properies
/// Which direction does the main axis flow in?
@@ -81,47 +86,14 @@ pub struct Style {
/// The fill color of this element
pub fill: Option<Fill>,
+ /// The radius of the corners of this element
+ #[refineable]
+ pub corner_radii: CornerRadii,
/// The color of text within this element. Cascades to children unless overridden.
pub text_color: Option<Hsla>,
}
impl Style {
- pub const DEFAULT: Style = Style {
- display: Display::DEFAULT,
- overflow: Point {
- x: Overflow::Visible,
- y: Overflow::Visible,
- },
- scrollbar_width: 0.0,
- position: Position::Relative,
- inset: Edges::auto(),
- margin: Edges::<Length>::zero(),
- padding: Edges::<DefinedLength>::zero(),
- border: Edges::<DefinedLength>::zero(),
- size: Size::auto(),
- min_size: Size::auto(),
- max_size: Size::auto(),
- aspect_ratio: None,
- gap: Size::zero(),
- // Aligment
- align_items: None,
- align_self: None,
- align_content: None,
- justify_content: None,
- // Flexbox
- flex_direction: FlexDirection::Row,
- flex_wrap: FlexWrap::NoWrap,
- flex_grow: 0.0,
- flex_shrink: 1.0,
- flex_basis: Length::Auto,
- fill: None,
- text_color: None,
- };
-
- pub fn new() -> Self {
- Self::DEFAULT.clone()
- }
-
pub fn to_taffy(&self, rem_size: f32) -> taffy::style::Style {
taffy::style::Style {
display: self.display,
@@ -149,11 +121,61 @@ impl Style {
..Default::default() // Ignore grid properties for now
}
}
+
+ /// Paints the background of an element styled with this style.
+ /// Return the bounds in which to paint the content.
+ pub fn paint_background<V: 'static, E: Element<V>>(
+ &self,
+ layout: &mut Layout<V, E::Layout>,
+ cx: &mut PaintContext<V>,
+ ) {
+ let bounds = layout.bounds(cx);
+ let rem_size = cx.rem_pixels();
+ 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(rem_size),
+ border: Default::default(),
+ });
+ }
+ }
}
impl Default for Style {
fn default() -> Self {
- Self::DEFAULT.clone()
+ Style {
+ display: Display::DEFAULT,
+ overflow: Point {
+ x: Overflow::Visible,
+ y: Overflow::Visible,
+ },
+ scrollbar_width: 0.0,
+ position: Position::Relative,
+ inset: Edges::auto(),
+ margin: Edges::<Length>::zero(),
+ padding: Edges::<DefiniteLength>::zero(),
+ border: Edges::<DefiniteLength>::zero(),
+ size: Size::auto(),
+ min_size: Size::auto(),
+ max_size: Size::auto(),
+ aspect_ratio: None,
+ gap: Size::zero(),
+ // Aligment
+ align_items: None,
+ align_self: None,
+ align_content: None,
+ justify_content: None,
+ // Flexbox
+ flex_direction: FlexDirection::Row,
+ flex_wrap: FlexWrap::NoWrap,
+ flex_grow: 0.0,
+ flex_shrink: 1.0,
+ flex_basis: Length::Auto,
+ fill: None,
+ text_color: None,
+ corner_radii: CornerRadii::default(),
+ }
}
}
@@ -202,3 +224,22 @@ impl From<Hsla> for Fill {
Self::Color(color)
}
}
+
+#[derive(Clone, Refineable, Default)]
+pub struct CornerRadii {
+ top_left: AbsoluteLength,
+ top_right: AbsoluteLength,
+ bottom_left: AbsoluteLength,
+ bottom_right: AbsoluteLength,
+}
+
+impl CornerRadii {
+ pub fn to_gpui(&self, rem_size: f32) -> gpui::scene::CornerRadii {
+ gpui::scene::CornerRadii {
+ top_left: self.top_left.to_pixels(rem_size),
+ top_right: self.top_right.to_pixels(rem_size),
+ bottom_left: self.bottom_left.to_pixels(rem_size),
+ bottom_right: self.bottom_right.to_pixels(rem_size),
+ }
+ }
+}
@@ -38,7 +38,7 @@ fn generate_methods() -> Vec<TokenStream2> {
.iter()
.map(|field_tokens| {
quote! {
- style.#field_tokens = Some(gpui::geometry::#length_tokens.into());
+ style.#field_tokens = Some(gpui::geometry::#length_tokens);
}
})
.collect::<Vec<_>>();
@@ -60,30 +60,30 @@ fn generate_methods() -> Vec<TokenStream2> {
fn tailwind_lengths() -> Vec<(&'static str, TokenStream2)> {
vec![
- ("0", quote! { DefinedLength::Pixels(0.) }),
- ("1", quote! { DefinedLength::Rems(0.25) }),
- ("2", quote! { DefinedLength::Rems(0.5) }),
- ("3", quote! { DefinedLength::Rems(0.75) }),
- ("4", quote! { DefinedLength::Rems(1.0) }),
- ("5", quote! { DefinedLength::Rems(1.25) }),
- ("6", quote! { DefinedLength::Rems(1.5) }),
- ("8", quote! { DefinedLength::Rems(2.0) }),
- ("10", quote! { DefinedLength::Rems(2.5) }),
- ("12", quote! { DefinedLength::Rems(3.0) }),
- ("16", quote! { DefinedLength::Rems(4.0) }),
- ("20", quote! { DefinedLength::Rems(5.0) }),
- ("24", quote! { DefinedLength::Rems(6.0) }),
- ("32", quote! { DefinedLength::Rems(8.0) }),
- ("40", quote! { DefinedLength::Rems(10.0) }),
- ("48", quote! { DefinedLength::Rems(12.0) }),
- ("56", quote! { DefinedLength::Rems(14.0) }),
- ("64", quote! { DefinedLength::Rems(16.0) }),
- ("auto", quote! { Length::Auto }),
- ("px", quote! { DefinedLength::Pixels(1.0) }),
- ("full", quote! { DefinedLength::Percent(100.0) }),
- // ("screen_50", quote! { DefinedLength::Vh(50.0) }),
- // ("screen_75", quote! { DefinedLength::Vh(75.0) }),
- // ("screen", quote! { DefinedLength::Vh(100.0) }),
+ ("0", quote! { pixels(0.) }),
+ ("1", quote! { rems(0.25) }),
+ ("2", quote! { rems(0.5) }),
+ ("3", quote! { rems(0.75) }),
+ ("4", quote! { rems(1.) }),
+ ("5", quote! { rems(1.25) }),
+ ("6", quote! { rems(1.5) }),
+ ("8", quote! { rems(2.0) }),
+ ("10", quote! { rems(2.5) }),
+ ("12", quote! { rems(3.) }),
+ ("16", quote! { rems(4.) }),
+ ("20", quote! { rems(5.) }),
+ ("24", quote! { rems(6.) }),
+ ("32", quote! { rems(8.) }),
+ ("40", quote! { rems(10.) }),
+ ("48", quote! { rems(12.) }),
+ ("56", quote! { rems(14.) }),
+ ("64", quote! { rems(16.) }),
+ ("auto", quote! { auto() }),
+ ("px", quote! { pixels(1.) }),
+ ("full", quote! { relative(1.) }),
+ // ("screen_50", quote! { DefiniteLength::Vh(50.0) }),
+ // ("screen_75", quote! { DefiniteLength::Vh(75.0) }),
+ // ("screen", quote! { DefiniteLength::Vh(100.0) }),
]
}
@@ -187,11 +187,11 @@ where
}
}
-impl Size<DefinedLength> {
- pub const fn zero() -> Self {
+impl Size<DefiniteLength> {
+ pub fn zero() -> Self {
Self {
- width: DefinedLength::Pixels(0.),
- height: DefinedLength::Pixels(0.),
+ width: pixels(0.),
+ height: pixels(0.),
}
}
@@ -204,7 +204,7 @@ impl Size<DefinedLength> {
}
impl Size<Length> {
- pub const fn auto() -> Self {
+ pub fn auto() -> Self {
Self {
width: Length::Auto,
height: Length::Auto,
@@ -230,13 +230,13 @@ pub struct Edges<T: Clone + Default> {
pub left: T,
}
-impl Edges<DefinedLength> {
- pub const fn zero() -> Self {
+impl Edges<DefiniteLength> {
+ pub fn zero() -> Self {
Self {
- top: DefinedLength::Pixels(0.0),
- right: DefinedLength::Pixels(0.0),
- bottom: DefinedLength::Pixels(0.0),
- left: DefinedLength::Pixels(0.0),
+ top: pixels(0.),
+ right: pixels(0.),
+ bottom: pixels(0.),
+ left: pixels(0.),
}
}
@@ -251,7 +251,7 @@ impl Edges<DefinedLength> {
}
impl Edges<Length> {
- pub const fn auto() -> Self {
+ pub fn auto() -> Self {
Self {
top: Length::Auto,
right: Length::Auto,
@@ -260,12 +260,12 @@ impl Edges<Length> {
}
}
- pub const fn zero() -> Self {
+ pub fn zero() -> Self {
Self {
- top: Length::Defined(DefinedLength::Pixels(0.0)),
- right: Length::Defined(DefinedLength::Pixels(0.0)),
- bottom: Length::Defined(DefinedLength::Pixels(0.0)),
- left: Length::Defined(DefinedLength::Pixels(0.0)),
+ top: pixels(0.),
+ right: pixels(0.),
+ bottom: pixels(0.),
+ left: pixels(0.),
}
}
@@ -282,72 +282,108 @@ impl Edges<Length> {
}
}
-/// A non-auto length that can be defined in pixels, rems, or percent of parent.
#[derive(Clone, Copy)]
-pub enum DefinedLength {
+pub enum AbsoluteLength {
Pixels(f32),
Rems(f32),
- Percent(f32), // 0. - 100.
}
-impl DefinedLength {
+impl AbsoluteLength {
+ pub fn to_pixels(&self, rem_size: f32) -> f32 {
+ match self {
+ AbsoluteLength::Pixels(pixels) => *pixels,
+ AbsoluteLength::Rems(rems) => rems * rem_size,
+ }
+ }
+}
+
+impl Default for AbsoluteLength {
+ fn default() -> Self {
+ Self::Pixels(0.0)
+ }
+}
+
+/// A non-auto length that can be defined in pixels, rems, or percent of parent.
+#[derive(Clone, Copy)]
+pub enum DefiniteLength {
+ Absolute(AbsoluteLength),
+ Relative(f32), // Percent, from 0 to 100.
+}
+
+impl DefiniteLength {
fn to_taffy(&self, rem_size: f32) -> taffy::style::LengthPercentage {
match self {
- DefinedLength::Pixels(pixels) => taffy::style::LengthPercentage::Length(*pixels),
- DefinedLength::Rems(rems) => taffy::style::LengthPercentage::Length(rems * rem_size),
- DefinedLength::Percent(percent) => {
- taffy::style::LengthPercentage::Percent(*percent / 100.)
+ DefiniteLength::Absolute(length) => match length {
+ AbsoluteLength::Pixels(pixels) => taffy::style::LengthPercentage::Length(*pixels),
+ AbsoluteLength::Rems(rems) => {
+ taffy::style::LengthPercentage::Length(rems * rem_size)
+ }
+ },
+ DefiniteLength::Relative(fraction) => {
+ taffy::style::LengthPercentage::Percent(*fraction)
}
}
}
}
-impl Default for DefinedLength {
+impl From<AbsoluteLength> for DefiniteLength {
+ fn from(length: AbsoluteLength) -> Self {
+ Self::Absolute(length)
+ }
+}
+
+impl Default for DefiniteLength {
fn default() -> Self {
- Self::Pixels(0.)
+ Self::Absolute(AbsoluteLength::default())
}
}
/// A length that can be defined in pixels, rems, percent of parent, or auto.
#[derive(Clone, Copy)]
pub enum Length {
- Defined(DefinedLength),
+ Definite(DefiniteLength),
Auto,
}
-pub fn auto() -> Length {
- Length::Auto
+pub fn relative<T: From<DefiniteLength>>(fraction: f32) -> T {
+ DefiniteLength::Relative(fraction).into()
}
-pub fn percent(percent: f32) -> DefinedLength {
- DefinedLength::Percent(percent)
+pub fn rems<T: From<AbsoluteLength>>(rems: f32) -> T {
+ AbsoluteLength::Rems(rems).into()
}
-pub fn rems(rems: f32) -> DefinedLength {
- DefinedLength::Rems(rems)
+pub fn pixels<T: From<AbsoluteLength>>(pixels: f32) -> T {
+ AbsoluteLength::Pixels(pixels).into()
}
-pub fn pixels(pixels: f32) -> DefinedLength {
- DefinedLength::Pixels(pixels)
+pub fn auto() -> Length {
+ Length::Auto
}
impl Length {
pub fn to_taffy(&self, rem_size: f32) -> taffy::prelude::LengthPercentageAuto {
match self {
- Length::Defined(length) => length.to_taffy(rem_size).into(),
+ Length::Definite(length) => length.to_taffy(rem_size).into(),
Length::Auto => taffy::prelude::LengthPercentageAuto::Auto,
}
}
}
-impl From<DefinedLength> for Length {
- fn from(value: DefinedLength) -> Self {
- Length::Defined(value)
+impl From<DefiniteLength> for Length {
+ fn from(length: DefiniteLength) -> Self {
+ Self::Definite(length)
+ }
+}
+
+impl From<AbsoluteLength> for Length {
+ fn from(length: AbsoluteLength) -> Self {
+ Self::Definite(length.into())
}
}
impl Default for Length {
fn default() -> Self {
- Self::Defined(DefinedLength::default())
+ Self::Definite(DefiniteLength::default())
}
}