crates/gpui3/src/elements.rs 🔗
@@ -3,6 +3,4 @@ mod img;
mod svg;
mod text;
-use super::*;
-
pub use div::*;
Nathan Sobo created
crates/gpui3/src/elements.rs | 2
crates/gpui3/src/elements/img.rs | 2
crates/gpui3/src/elements/text.rs | 17 +++--
crates/gpui3/src/geometry.rs | 9 +++
crates/gpui3/src/gpui3.rs | 8 ++
crates/gpui3/src/style.rs | 1
crates/gpui3/src/taffy.rs | 92 ++++++++++++++++++++++++++------
crates/gpui3/src/window.rs | 10 +-
8 files changed, 107 insertions(+), 34 deletions(-)
@@ -3,6 +3,4 @@ mod img;
mod svg;
mod text;
-use super::*;
-
pub use div::*;
@@ -1,7 +1,7 @@
use crate::{Element, Layout, LayoutId, Result, Style, Styled};
use refineable::RefinementCascade;
use std::marker::PhantomData;
-use util::{arc_cow::ArcCow, ResultExt};
+use util::arc_cow::ArcCow;
pub struct Img<S> {
style: RefinementCascade<Style>,
@@ -1,6 +1,5 @@
use crate::{
- AnyElement, Element, IntoAnyElement, Layout, LayoutId, Line, LineLayout, Pixels, Result, Size,
- ViewContext,
+ AnyElement, Element, IntoAnyElement, Layout, LayoutId, Line, Pixels, Result, Size, ViewContext,
};
use parking_lot::Mutex;
use std::{marker::PhantomData, sync::Arc};
@@ -42,16 +41,18 @@ impl<S: 'static> Element for Text<S> {
) -> Result<(LayoutId, Self::FrameState)> {
let text_system = cx.text_system().clone();
let text_style = cx.text_style();
- let line_height = cx.text_system().line_height(text_style.font_size);
+ let font_size = text_style.font_size * cx.rem_size();
+ let line_height = cx.text_system().line_height(font_size);
let text = self.text.clone();
let paint_state = Arc::new(Mutex::new(None));
- let layout_id = cx.request_measured_layout(Default::default(), cx.rem_size(), {
+ let rem_size = cx.rem_size();
+ let layout_id = cx.request_measured_layout(Default::default(), rem_size, {
let frame_state = paint_state.clone();
move |_, _| {
let line_layout = text_system.layout_str(
text.as_ref(),
- text_style.font_size,
+ font_size,
&[(text.len(), text_style.to_run())],
);
@@ -78,7 +79,7 @@ impl<S: 'static> Element for Text<S> {
_: &mut Self::State,
paint_state: &mut Self::FrameState,
cx: &mut ViewContext<S>,
- ) {
+ ) -> Result<()> {
let bounds = layout.bounds;
let line;
@@ -96,7 +97,9 @@ impl<S: 'static> Element for Text<S> {
// todo!("We haven't added visible bounds to the new element system yet, so this is a placeholder.");
let visible_bounds = bounds;
- line.paint(bounds.origin, visible_bounds, line_height, cx.legacy_cx);
+ line.paint(bounds.origin, visible_bounds, line_height, cx);
+
+ Ok(())
}
}
@@ -79,6 +79,15 @@ pub fn size<T: Clone + Debug>(width: T, height: T) -> Size<T> {
Size { width, height }
}
+impl<T: Clone + Debug> Size<T> {
+ pub fn map<U: Clone + Debug, F: Fn(T) -> U>(&self, f: F) -> Size<U> {
+ Size {
+ width: f(self.width.clone()),
+ height: f(self.height.clone()),
+ }
+ }
+}
+
impl From<Size<Option<Pixels>>> for Size<Option<f32>> {
fn from(val: Size<Option<Pixels>>) -> Self {
Size {
@@ -31,8 +31,8 @@ pub use smol::Timer;
use std::ops::{Deref, DerefMut};
pub use style::*;
pub use styled::*;
-pub use taffy::LayoutId;
use taffy::TaffyLayoutEngine;
+pub use taffy::{AvailableSpace, LayoutId};
pub use text_system::*;
pub use util::arc_cow::ArcCow;
pub use window::*;
@@ -55,6 +55,12 @@ pub trait Context {
#[derive(Clone, Eq, PartialEq)]
pub struct SharedString(ArcCow<'static, str>);
+impl Default for SharedString {
+ fn default() -> Self {
+ Self(ArcCow::Owned("".into()))
+ }
+}
+
impl AsRef<str> for SharedString {
fn as_ref(&self) -> &str {
&self.0
@@ -3,7 +3,6 @@ use super::{
Hsla, Length, Pixels, Point, PointRefinement, Rems, Result, RunStyle, SharedString, Size,
SizeRefinement, ViewContext, WindowContext,
};
-use crate::{FontCache, TextSystem};
use refineable::Refineable;
pub use taffy::style::{
AlignContent, AlignItems, AlignSelf, Display, FlexDirection, FlexWrap, JustifyContent,
@@ -4,9 +4,24 @@ use super::{
};
use std::fmt::Debug;
pub use taffy::tree::NodeId as LayoutId;
-use taffy::{style::AvailableSpace, tree::MeasureFunc, *};
+use taffy::{
+ geometry::Size as TaffySize,
+ style::AvailableSpace as TaffyAvailableSpace,
+ tree::{Measurable, MeasureFunc},
+ Taffy,
+};
pub struct TaffyLayoutEngine(Taffy);
+#[derive(Copy, Clone, 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
+ MinContent,
+ /// The amount of space available is indefinite and the node should be laid out under a max-content constraint
+ MaxContent,
+}
+
impl TaffyLayoutEngine {
pub fn new() -> Self {
TaffyLayoutEngine(Taffy::new())
@@ -30,12 +45,17 @@ impl TaffyLayoutEngine {
&mut self,
style: Style,
rem_size: Pixels,
- measure: impl FnOnce(Size<Option<Pixels>>, Size<AvailableSpace>) + 'static,
+ measure: impl Fn(Size<Option<Pixels>>, Size<AvailableSpace>) -> Size<Pixels>
+ + Send
+ + Sync
+ + 'static,
) -> Result<LayoutId> {
let style = style.to_taffy(rem_size);
- self.0
- .new_leaf_with_measure(style, Box::new(Measureable(measure)))
+ let measurable = Box::new(Measureable(measure)) as Box<dyn Measurable>;
+ Ok(self
+ .0
+ .new_leaf_with_measure(style, MeasureFunc::Boxed(measurable))?)
}
pub fn layout(&mut self, id: LayoutId) -> Result<Layout> {
@@ -47,14 +67,18 @@ struct Measureable<F>(F);
impl<F> taffy::tree::Measurable for Measureable<F>
where
- F: Send + Sync + FnOnce(Size<Option<Pixels>>, Size<AvailableSpace>) -> Size<Pixels>,
+ F: Send + Sync + Fn(Size<Option<Pixels>>, Size<AvailableSpace>) -> Size<Pixels>,
{
fn measure(
&self,
- known_dimensions: taffy::prelude::Size<Option<f32>>,
- available_space: taffy::prelude::Size<AvailableSpace>,
- ) -> taffy::prelude::Size<f32> {
- (self.0)(known_dimensions.into(), available_space.into()).into()
+ known_dimensions: TaffySize<Option<f32>>,
+ available_space: TaffySize<TaffyAvailableSpace>,
+ ) -> TaffySize<f32> {
+ let known_dimensions: Size<Option<f32>> = known_dimensions.into();
+ let known_dimensions: Size<Option<Pixels>> = known_dimensions.map(|d| d.map(Into::into));
+ let available_space = available_space.into();
+ let size = (self.0)(known_dimensions, available_space);
+ size.into()
}
}
@@ -232,14 +256,48 @@ where
}
}
-impl<S, T: Clone + Default + Debug> From<taffy::geometry::Size<S>> for Size<T>
-where
- S: Into<T>,
-{
- fn from(value: taffy::geometry::Size<S>) -> Self {
- Self {
- width: value.width.into(),
- height: value.height.into(),
+impl<T: Into<U>, U: Clone + Debug> From<TaffySize<T>> for Size<U> {
+ fn from(taffy_size: taffy::geometry::Size<T>) -> Self {
+ Size {
+ width: taffy_size.width.into(),
+ height: taffy_size.height.into(),
+ }
+ }
+}
+
+impl<T: Into<U> + Clone + Debug, U> From<Size<T>> for taffy::geometry::Size<U> {
+ fn from(size: Size<T>) -> Self {
+ taffy::geometry::Size {
+ width: size.width.into(),
+ height: size.height.into(),
+ }
+ }
+}
+
+// impl From<TaffySize<Option<f32>>> for Size<Option<Pixels>> {
+// fn from(value: TaffySize<Option<f32>>) -> Self {
+// Self {
+// width: value.width.map(Into::into),
+// height: value.height.map(Into::into),
+// }
+// }
+// }
+
+// impl From<TaffySize<TaffyAvailableSpace>> for Size<AvailableSpace> {
+// fn from(taffy_size: TaffySize<TaffyAvailableSpace>) -> Self {
+// Size {
+// width: From::from(taffy_size.width),
+// height: From::from(taffy_size.height),
+// }
+// }
+// }
+
+impl From<TaffyAvailableSpace> for AvailableSpace {
+ fn from(space: TaffyAvailableSpace) -> Self {
+ match space {
+ TaffyAvailableSpace::Definite(value) => AvailableSpace::Definite(Pixels(value)),
+ TaffyAvailableSpace::MinContent => AvailableSpace::MinContent,
+ TaffyAvailableSpace::MaxContent => AvailableSpace::MaxContent,
}
}
}
@@ -1,4 +1,4 @@
-use crate::{PlatformWindow, Point, Size, Style, TextStyle, TextStyleRefinement};
+use crate::{AvailableSpace, PlatformWindow, Point, Size, Style, TextStyle, TextStyleRefinement};
use super::{
px, taffy::LayoutId, AppContext, Bounds, Context, EntityId, Handle, Pixels, Reference,
@@ -11,7 +11,6 @@ use std::{
any::{Any, TypeId},
marker::PhantomData,
};
-use taffy::style::AvailableSpace;
pub struct AnyWindow {}
@@ -75,7 +74,7 @@ impl<'a, 'w> WindowContext<'a, 'w> {
}
pub fn request_measured_layout<
- F: FnOnce(Size<Option<Pixels>>, Size<AvailableSpace>) + 'static,
+ F: Fn(Size<Option<Pixels>>, Size<AvailableSpace>) -> Size<Pixels> + Send + Sync + 'static,
>(
&mut self,
style: Style,
@@ -107,11 +106,12 @@ impl<'a, 'w> WindowContext<'a, 'w> {
self.window.text_style_stack.pop();
}
- pub fn text_style(&self) -> &Vec<TextStyle> {
- let style = TextStyleRefinement::default();
+ pub fn text_style(&self) -> TextStyle {
+ let mut style = TextStyle::default();
for refinement in &self.window.text_style_stack {
style.refine(refinement);
}
+ style
}
pub fn mouse_position(&self) -> Point<Pixels> {