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 svg;
|
||||||
mod text;
|
mod text;
|
||||||
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
pub use div::*;
|
pub use div::*;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use crate::{Element, Layout, LayoutId, Result, Style, Styled};
|
use crate::{Element, Layout, LayoutId, Result, Style, Styled};
|
||||||
use refineable::RefinementCascade;
|
use refineable::RefinementCascade;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use util::{arc_cow::ArcCow, ResultExt};
|
use util::arc_cow::ArcCow;
|
||||||
|
|
||||||
pub struct Img<S> {
|
pub struct Img<S> {
|
||||||
style: RefinementCascade<Style>,
|
style: RefinementCascade<Style>,
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
AnyElement, Element, IntoAnyElement, Layout, LayoutId, Line, LineLayout, Pixels, Result, Size,
|
AnyElement, Element, IntoAnyElement, Layout, LayoutId, Line, Pixels, Result, Size, ViewContext,
|
||||||
ViewContext,
|
|
||||||
};
|
};
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
use std::{marker::PhantomData, sync::Arc};
|
use std::{marker::PhantomData, sync::Arc};
|
||||||
|
@ -42,16 +41,18 @@ impl<S: 'static> Element for Text<S> {
|
||||||
) -> Result<(LayoutId, Self::FrameState)> {
|
) -> Result<(LayoutId, Self::FrameState)> {
|
||||||
let text_system = cx.text_system().clone();
|
let text_system = cx.text_system().clone();
|
||||||
let text_style = cx.text_style();
|
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 text = self.text.clone();
|
||||||
let paint_state = Arc::new(Mutex::new(None));
|
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();
|
let frame_state = paint_state.clone();
|
||||||
move |_, _| {
|
move |_, _| {
|
||||||
let line_layout = text_system.layout_str(
|
let line_layout = text_system.layout_str(
|
||||||
text.as_ref(),
|
text.as_ref(),
|
||||||
text_style.font_size,
|
font_size,
|
||||||
&[(text.len(), text_style.to_run())],
|
&[(text.len(), text_style.to_run())],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -78,7 +79,7 @@ impl<S: 'static> Element for Text<S> {
|
||||||
_: &mut Self::State,
|
_: &mut Self::State,
|
||||||
paint_state: &mut Self::FrameState,
|
paint_state: &mut Self::FrameState,
|
||||||
cx: &mut ViewContext<S>,
|
cx: &mut ViewContext<S>,
|
||||||
) {
|
) -> Result<()> {
|
||||||
let bounds = layout.bounds;
|
let bounds = layout.bounds;
|
||||||
|
|
||||||
let line;
|
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.");
|
// todo!("We haven't added visible bounds to the new element system yet, so this is a placeholder.");
|
||||||
let visible_bounds = bounds;
|
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 }
|
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>> {
|
impl From<Size<Option<Pixels>>> for Size<Option<f32>> {
|
||||||
fn from(val: Size<Option<Pixels>>) -> Self {
|
fn from(val: Size<Option<Pixels>>) -> Self {
|
||||||
Size {
|
Size {
|
||||||
|
|
|
@ -31,8 +31,8 @@ pub use smol::Timer;
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
pub use style::*;
|
pub use style::*;
|
||||||
pub use styled::*;
|
pub use styled::*;
|
||||||
pub use taffy::LayoutId;
|
|
||||||
use taffy::TaffyLayoutEngine;
|
use taffy::TaffyLayoutEngine;
|
||||||
|
pub use taffy::{AvailableSpace, LayoutId};
|
||||||
pub use text_system::*;
|
pub use text_system::*;
|
||||||
pub use util::arc_cow::ArcCow;
|
pub use util::arc_cow::ArcCow;
|
||||||
pub use window::*;
|
pub use window::*;
|
||||||
|
@ -55,6 +55,12 @@ pub trait Context {
|
||||||
#[derive(Clone, Eq, PartialEq)]
|
#[derive(Clone, Eq, PartialEq)]
|
||||||
pub struct SharedString(ArcCow<'static, str>);
|
pub struct SharedString(ArcCow<'static, str>);
|
||||||
|
|
||||||
|
impl Default for SharedString {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self(ArcCow::Owned("".into()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl AsRef<str> for SharedString {
|
impl AsRef<str> for SharedString {
|
||||||
fn as_ref(&self) -> &str {
|
fn as_ref(&self) -> &str {
|
||||||
&self.0
|
&self.0
|
||||||
|
|
|
@ -3,7 +3,6 @@ use super::{
|
||||||
Hsla, Length, Pixels, Point, PointRefinement, Rems, Result, RunStyle, SharedString, Size,
|
Hsla, Length, Pixels, Point, PointRefinement, Rems, Result, RunStyle, SharedString, Size,
|
||||||
SizeRefinement, ViewContext, WindowContext,
|
SizeRefinement, ViewContext, WindowContext,
|
||||||
};
|
};
|
||||||
use crate::{FontCache, TextSystem};
|
|
||||||
use refineable::Refineable;
|
use refineable::Refineable;
|
||||||
pub use taffy::style::{
|
pub use taffy::style::{
|
||||||
AlignContent, AlignItems, AlignSelf, Display, FlexDirection, FlexWrap, JustifyContent,
|
AlignContent, AlignItems, AlignSelf, Display, FlexDirection, FlexWrap, JustifyContent,
|
||||||
|
|
|
@ -4,9 +4,24 @@ use super::{
|
||||||
};
|
};
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
pub use taffy::tree::NodeId as LayoutId;
|
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);
|
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 {
|
impl TaffyLayoutEngine {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
TaffyLayoutEngine(Taffy::new())
|
TaffyLayoutEngine(Taffy::new())
|
||||||
|
@ -30,12 +45,17 @@ impl TaffyLayoutEngine {
|
||||||
&mut self,
|
&mut self,
|
||||||
style: Style,
|
style: Style,
|
||||||
rem_size: Pixels,
|
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> {
|
) -> Result<LayoutId> {
|
||||||
let style = style.to_taffy(rem_size);
|
let style = style.to_taffy(rem_size);
|
||||||
|
|
||||||
self.0
|
let measurable = Box::new(Measureable(measure)) as Box<dyn Measurable>;
|
||||||
.new_leaf_with_measure(style, Box::new(Measureable(measure)))
|
Ok(self
|
||||||
|
.0
|
||||||
|
.new_leaf_with_measure(style, MeasureFunc::Boxed(measurable))?)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn layout(&mut self, id: LayoutId) -> Result<Layout> {
|
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>
|
impl<F> taffy::tree::Measurable for Measureable<F>
|
||||||
where
|
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(
|
fn measure(
|
||||||
&self,
|
&self,
|
||||||
known_dimensions: taffy::prelude::Size<Option<f32>>,
|
known_dimensions: TaffySize<Option<f32>>,
|
||||||
available_space: taffy::prelude::Size<AvailableSpace>,
|
available_space: TaffySize<TaffyAvailableSpace>,
|
||||||
) -> taffy::prelude::Size<f32> {
|
) -> TaffySize<f32> {
|
||||||
(self.0)(known_dimensions.into(), available_space.into()).into()
|
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>
|
impl<T: Into<U>, U: Clone + Debug> From<TaffySize<T>> for Size<U> {
|
||||||
where
|
fn from(taffy_size: taffy::geometry::Size<T>) -> Self {
|
||||||
S: Into<T>,
|
Size {
|
||||||
{
|
width: taffy_size.width.into(),
|
||||||
fn from(value: taffy::geometry::Size<S>) -> Self {
|
height: taffy_size.height.into(),
|
||||||
Self {
|
}
|
||||||
width: value.width.into(),
|
}
|
||||||
height: value.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::{
|
use super::{
|
||||||
px, taffy::LayoutId, AppContext, Bounds, Context, EntityId, Handle, Pixels, Reference,
|
px, taffy::LayoutId, AppContext, Bounds, Context, EntityId, Handle, Pixels, Reference,
|
||||||
|
@ -11,7 +11,6 @@ use std::{
|
||||||
any::{Any, TypeId},
|
any::{Any, TypeId},
|
||||||
marker::PhantomData,
|
marker::PhantomData,
|
||||||
};
|
};
|
||||||
use taffy::style::AvailableSpace;
|
|
||||||
|
|
||||||
pub struct AnyWindow {}
|
pub struct AnyWindow {}
|
||||||
|
|
||||||
|
@ -75,7 +74,7 @@ impl<'a, 'w> WindowContext<'a, 'w> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn request_measured_layout<
|
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,
|
&mut self,
|
||||||
style: Style,
|
style: Style,
|
||||||
|
@ -107,11 +106,12 @@ impl<'a, 'w> WindowContext<'a, 'w> {
|
||||||
self.window.text_style_stack.pop();
|
self.window.text_style_stack.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn text_style(&self) -> &Vec<TextStyle> {
|
pub fn text_style(&self) -> TextStyle {
|
||||||
let style = TextStyleRefinement::default();
|
let mut style = TextStyle::default();
|
||||||
for refinement in &self.window.text_style_stack {
|
for refinement in &self.window.text_style_stack {
|
||||||
style.refine(refinement);
|
style.refine(refinement);
|
||||||
}
|
}
|
||||||
|
style
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mouse_position(&self) -> Point<Pixels> {
|
pub fn mouse_position(&self) -> Point<Pixels> {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue