WIP
This commit is contained in:
parent
44608517c1
commit
a8bb3dd9a3
8 changed files with 107 additions and 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> {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue