Checkpoint

This commit is contained in:
Nathan Sobo 2023-10-05 21:02:26 -06:00
parent e99f6c03c1
commit 65c7765c07
12 changed files with 80 additions and 107 deletions

View file

@ -1,4 +1,6 @@
use super::{Layout, LayoutId, Pixels, Point, Result, ViewContext};
use crate::Bounds;
use super::{LayoutId, Pixels, Point, Result, ViewContext};
pub(crate) use smallvec::SmallVec;
pub trait Element: 'static {
@ -13,7 +15,7 @@ pub trait Element: 'static {
fn paint(
&mut self,
layout: Layout,
bounds: Bounds<Pixels>,
state: &mut Self::State,
frame_state: &mut Self::FrameState,
cx: &mut ViewContext<Self::State>,
@ -65,7 +67,7 @@ enum ElementRenderPhase<S> {
frame_state: S,
},
Painted {
layout: Layout,
bounds: Bounds<Pixels>,
frame_state: S,
},
}
@ -105,24 +107,23 @@ impl<E: Element> ElementObject<E::State> for RenderedElement<E> {
layout_id,
mut frame_state,
} => {
let mut layout = cx.layout(layout_id)?.clone();
offset.map(|offset| layout.bounds.origin += offset);
self.element
.paint(layout.clone(), state, &mut frame_state, cx)?;
let mut bounds = cx.layout_bounds(layout_id)?.clone();
offset.map(|offset| bounds.origin += offset);
self.element.paint(bounds, state, &mut frame_state, cx)?;
ElementRenderPhase::Painted {
layout,
bounds,
frame_state,
}
}
ElementRenderPhase::Painted {
layout,
bounds,
mut frame_state,
} => {
self.element
.paint(layout.clone(), state, &mut frame_state, cx)?;
.paint(bounds.clone(), state, &mut frame_state, cx)?;
ElementRenderPhase::Painted {
layout,
bounds,
frame_state,
}
}

View file

@ -1,6 +1,6 @@
use crate::{
AnyElement, Bounds, Element, Layout, LayoutId, Overflow, ParentElement, Pixels, Point,
Refineable, RefinementCascade, Result, Style, StyleHelpers, Styled, ViewContext,
AnyElement, Bounds, Element, LayoutId, Overflow, ParentElement, Pixels, Point, Refineable,
RefinementCascade, Result, Style, StyleHelpers, Styled, ViewContext,
};
use parking_lot::Mutex;
use smallvec::SmallVec;
@ -40,31 +40,28 @@ impl<S: 'static + Send + Sync> Element for Div<S> {
fn paint(
&mut self,
layout: Layout,
bounds: Bounds<Pixels>,
state: &mut S,
child_layouts: &mut Self::FrameState,
cx: &mut ViewContext<S>,
) -> Result<()> {
let Layout { order, bounds } = layout;
let style = self.computed_style();
cx.stack(0, |cx| style.paint(order, bounds, cx));
cx.stack(0, |cx| style.paint(bounds, cx));
let overflow = &style.overflow;
style.apply_text_style(cx, |cx| {
cx.stack(1, |cx| {
style.apply_overflow(layout.bounds, cx, |cx| {
self.paint_children(overflow, state, cx)
})
style.apply_overflow(bounds, cx, |cx| self.paint_children(overflow, state, cx))
})
})?;
self.handle_scroll(order, bounds, style.overflow.clone(), child_layouts, cx);
self.handle_scroll(bounds, style.overflow.clone(), child_layouts, cx);
// todo!("enable inspector")
// if cx.is_inspector_enabled() {
// self.paint_inspector(parent_origin, layout, cx);
// }
//
Ok(())
}
}
@ -139,7 +136,6 @@ impl<S: 'static> Div<S> {
fn handle_scroll(
&mut self,
_order: u32,
bounds: Bounds<Pixels>,
overflow: Point<Overflow>,
child_layout_ids: &[LayoutId],
@ -148,8 +144,8 @@ impl<S: 'static> Div<S> {
if overflow.y == Overflow::Scroll || overflow.x == Overflow::Scroll {
let mut scroll_max = Point::default();
for child_layout_id in child_layout_ids {
if let Some(child_layout) = cx.layout(*child_layout_id).log_err() {
scroll_max = scroll_max.max(&child_layout.bounds.lower_right());
if let Some(child_bounds) = cx.layout_bounds(*child_layout_id).log_err() {
scroll_max = scroll_max.max(&child_bounds.lower_right());
}
}
scroll_max -= bounds.size;

View file

@ -1,6 +1,6 @@
use crate::{
BorrowWindow, Element, Layout, LayoutId, Result, SharedString, Style, StyleHelpers, Styled,
ViewContext,
BorrowWindow, Bounds, Element, LayoutId, Pixels, Result, SharedString, Style, StyleHelpers,
Styled, ViewContext,
};
use futures::FutureExt;
use refineable::RefinementCascade;
@ -54,16 +54,14 @@ impl<S: Send + Sync + 'static> Element for Img<S> {
fn paint(
&mut self,
layout: Layout,
bounds: Bounds<Pixels>,
_: &mut Self::State,
_: &mut Self::FrameState,
cx: &mut ViewContext<Self::State>,
) -> Result<()> {
let style = self.computed_style();
let order = layout.order;
let bounds = layout.bounds;
style.paint(order, bounds, cx);
style.paint(bounds, cx);
if let Some(uri) = self.uri.clone() {
let image_future = cx.image_cache.get(uri);
@ -74,7 +72,7 @@ impl<S: Send + Sync + 'static> Element for Img<S> {
{
let corner_radii = style.corner_radii.to_pixels(bounds.size, cx.rem_size());
cx.stack(1, |cx| {
cx.paint_image(bounds, corner_radii, order, data, self.grayscale)
cx.paint_image(bounds, corner_radii, data, self.grayscale)
})?;
} else {
cx.spawn(|_, mut cx| async move {

View file

@ -1,4 +1,4 @@
use crate::Element;
use crate::{Bounds, Element, Pixels};
use std::marker::PhantomData;
pub struct Stateless<E: Element<State = ()>, S> {
@ -20,11 +20,11 @@ impl<E: Element<State = ()>, S: Send + Sync + 'static> Element for Stateless<E,
fn paint(
&mut self,
layout: crate::Layout,
bounds: Bounds<Pixels>,
_: &mut Self::State,
frame_state: &mut Self::FrameState,
cx: &mut crate::ViewContext<Self::State>,
) -> anyhow::Result<()> {
cx.erase_state(|cx| self.element.paint(layout, &mut (), frame_state, cx))
cx.erase_state(|cx| self.element.paint(bounds, &mut (), frame_state, cx))
}
}

View file

@ -1,4 +1,4 @@
use crate::{Element, Layout, LayoutId, Result, SharedString, Style, StyleHelpers, Styled};
use crate::{Bounds, Element, LayoutId, Pixels, Result, SharedString, Style, StyleHelpers, Styled};
use refineable::RefinementCascade;
use std::marker::PhantomData;
@ -41,7 +41,7 @@ impl<S: 'static> Element for Svg<S> {
fn paint(
&mut self,
layout: Layout,
bounds: Bounds<Pixels>,
_: &mut Self::State,
_: &mut Self::FrameState,
cx: &mut crate::ViewContext<S>,
@ -51,7 +51,7 @@ impl<S: 'static> Element for Svg<S> {
{
let fill_color = self.computed_style().fill.and_then(|fill| fill.color());
if let Some((path, fill_color)) = self.path.as_ref().zip(fill_color) {
cx.paint_svg(layout.bounds, layout.order, path.clone(), fill_color)?;
cx.paint_svg(bounds, path.clone(), fill_color)?;
}
Ok(())
}

View file

@ -1,5 +1,5 @@
use crate::{
AnyElement, Element, IntoAnyElement, Layout, LayoutId, Line, Pixels, Result, Size, ViewContext,
AnyElement, Bounds, Element, IntoAnyElement, LayoutId, Line, Pixels, Result, Size, ViewContext,
};
use parking_lot::Mutex;
use std::{marker::PhantomData, sync::Arc};
@ -82,7 +82,7 @@ impl<S: 'static> Element for Text<S> {
fn paint<'a>(
&mut self,
layout: Layout,
bounds: Bounds<Pixels>,
_: &mut Self::State,
frame_state: &mut Self::FrameState,
cx: &mut ViewContext<S>,
@ -99,8 +99,7 @@ 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 = layout.bounds;
line.paint(&layout, visible_bounds, line_height, cx)?;
line.paint(bounds, bounds, line_height, cx)?;
Ok(())
}

View file

@ -241,7 +241,7 @@ impl Style {
}
/// Paints the background of an element styled with this style.
pub fn paint<V: 'static>(&self, order: u32, bounds: Bounds<Pixels>, cx: &mut ViewContext<V>) {
pub fn paint<V: 'static>(&self, bounds: Bounds<Pixels>, cx: &mut ViewContext<V>) {
let rem_size = cx.rem_size();
let scale = cx.scale_factor();

View file

@ -1,6 +1,5 @@
use super::{
AbsoluteLength, Bounds, DefiniteLength, Edges, Layout, Length, Pixels, Point, Result, Size,
Style,
AbsoluteLength, Bounds, DefiniteLength, Edges, Length, Pixels, Point, Result, Size, Style,
};
use collections::HashMap;
use std::fmt::Debug;
@ -14,7 +13,7 @@ use taffy::{
pub struct TaffyLayoutEngine {
taffy: Taffy,
children_to_parents: HashMap<LayoutId, LayoutId>,
absolute_layouts: HashMap<LayoutId, Layout>,
absolute_layout_bounds: HashMap<LayoutId, Bounds<Pixels>>,
}
impl TaffyLayoutEngine {
@ -22,7 +21,7 @@ impl TaffyLayoutEngine {
TaffyLayoutEngine {
taffy: Taffy::new(),
children_to_parents: HashMap::default(),
absolute_layouts: HashMap::default(),
absolute_layout_bounds: HashMap::default(),
}
}
@ -76,19 +75,24 @@ impl TaffyLayoutEngine {
Ok(())
}
pub fn layout(&mut self, id: LayoutId) -> Result<Layout> {
if let Some(layout) = self.absolute_layouts.get(&id).cloned() {
pub fn layout_bounds(&mut self, id: LayoutId) -> Result<Bounds<Pixels>> {
if let Some(layout) = self.absolute_layout_bounds.get(&id).cloned() {
return Ok(layout);
}
let mut relative_layout: Layout = self.taffy.layout(id.into()).map(Into::into)?;
if let Some(parent_id) = self.children_to_parents.get(&id).copied() {
let parent_layout = self.layout(parent_id)?;
relative_layout.bounds.origin += parent_layout.bounds.origin;
}
self.absolute_layouts.insert(id, relative_layout.clone());
let layout = self.taffy.layout(id.into())?;
let mut bounds = Bounds {
origin: layout.location.into(),
size: layout.size.into(),
};
Ok(relative_layout)
if let Some(parent_id) = self.children_to_parents.get(&id).copied() {
let parent_bounds = self.layout_bounds(parent_id)?;
bounds.origin += parent_bounds.origin;
}
self.absolute_layout_bounds.insert(id, bounds);
Ok(bounds)
}
}
@ -369,15 +373,3 @@ impl From<Pixels> for AvailableSpace {
AvailableSpace::Definite(pixels)
}
}
impl From<&taffy::tree::Layout> for Layout {
fn from(layout: &taffy::tree::Layout) -> Self {
Layout {
order: layout.order,
bounds: Bounds {
origin: layout.location.into(),
size: layout.size.into(),
},
}
}
}

View file

@ -1,6 +1,6 @@
use crate::{
black, point, px, Bounds, FontId, Hsla, Layout, Pixels, Point, RunStyle, ShapedBoundary,
ShapedLine, ShapedRun, UnderlineStyle, WindowContext,
black, point, px, Bounds, FontId, Hsla, Pixels, Point, RunStyle, ShapedBoundary, ShapedLine,
ShapedRun, UnderlineStyle, WindowContext,
};
use anyhow::Result;
use smallvec::SmallVec;
@ -90,15 +90,14 @@ impl Line {
}
}
// todo!
pub fn paint(
&self,
layout: &Layout,
visible_bounds: Bounds<Pixels>,
bounds: Bounds<Pixels>,
visible_bounds: Bounds<Pixels>, // todo!("use clipping")
line_height: Pixels,
cx: &mut WindowContext,
) -> Result<()> {
let origin = layout.bounds.origin;
let origin = bounds.origin;
let padding_top = (line_height - self.layout.ascent - self.layout.descent) / 2.;
let baseline_offset = point(px(0.), padding_top + self.layout.ascent);
@ -159,17 +158,10 @@ impl Line {
}
if glyph.is_emoji {
cx.paint_emoji(
glyph_origin,
layout.order,
run.font_id,
glyph.id,
self.layout.font_size,
)?;
cx.paint_emoji(glyph_origin, run.font_id, glyph.id, self.layout.font_size)?;
} else {
cx.paint_glyph(
glyph_origin,
layout.order,
run.font_id,
glyph.id,
self.layout.font_size,

View file

@ -1,7 +1,7 @@
use parking_lot::Mutex;
use crate::{
AnyElement, Element, Handle, IntoAnyElement, Layout, LayoutId, Result, ViewContext,
AnyElement, Bounds, Element, Handle, IntoAnyElement, LayoutId, Pixels, Result, ViewContext,
WindowContext,
};
use std::{any::Any, marker::PhantomData, sync::Arc};
@ -67,7 +67,7 @@ impl<S: Send + Sync + 'static, P: Send + 'static> Element for View<S, P> {
fn paint(
&mut self,
_: Layout,
_: Bounds<Pixels>,
_: &mut Self::State,
element: &mut Self::FrameState,
cx: &mut ViewContext<Self::State>,
@ -81,7 +81,7 @@ trait ViewObject: Send + 'static {
fn layout(&mut self, cx: &mut WindowContext) -> Result<(LayoutId, Box<dyn Any>)>;
fn paint(
&mut self,
layout: Layout,
bounds: Bounds<Pixels>,
element: &mut dyn Any,
cx: &mut WindowContext,
) -> Result<()>;
@ -97,7 +97,12 @@ impl<S: Send + Sync + 'static, P: Send + 'static> ViewObject for View<S, P> {
})
}
fn paint(&mut self, _: Layout, element: &mut dyn Any, cx: &mut WindowContext) -> Result<()> {
fn paint(
&mut self,
_: Bounds<Pixels>,
element: &mut dyn Any,
cx: &mut WindowContext,
) -> Result<()> {
self.state.update(cx, |state, cx| {
let element = element.downcast_mut::<AnyElement<S>>().unwrap();
element.paint(state, None, cx)
@ -124,12 +129,12 @@ impl<S: 'static> Element for AnyView<S> {
fn paint(
&mut self,
layout: Layout,
bounds: Bounds<Pixels>,
_: &mut (),
element: &mut Box<dyn Any>,
cx: &mut ViewContext<Self::State>,
) -> Result<()> {
self.view.lock().paint(layout, element.as_mut(), cx)
self.view.lock().paint(bounds, element.as_mut(), cx)
}
}

View file

@ -224,11 +224,11 @@ impl<'a, 'w> WindowContext<'a, 'w> {
.request_measured_layout(style, rem_size, measure)
}
pub fn layout(&mut self, layout_id: LayoutId) -> Result<Layout> {
pub fn layout_bounds(&mut self, layout_id: LayoutId) -> Result<Bounds<Pixels>> {
Ok(self
.window
.layout_engine
.layout(layout_id)
.layout_bounds(layout_id)
.map(Into::into)?)
}
@ -262,7 +262,6 @@ impl<'a, 'w> WindowContext<'a, 'w> {
pub fn paint_glyph(
&mut self,
origin: Point<Pixels>,
order: u32,
font_id: FontId,
glyph_id: GlyphId,
font_size: Pixels,
@ -302,7 +301,7 @@ impl<'a, 'w> WindowContext<'a, 'w> {
self.window.scene.insert(
layer_id,
MonochromeSprite {
order,
order: 0,
bounds,
content_mask,
color,
@ -316,7 +315,6 @@ impl<'a, 'w> WindowContext<'a, 'w> {
pub fn paint_emoji(
&mut self,
origin: Point<Pixels>,
order: u32,
font_id: FontId,
glyph_id: GlyphId,
font_size: Pixels,
@ -352,7 +350,7 @@ impl<'a, 'w> WindowContext<'a, 'w> {
self.window.scene.insert(
layer_id,
PolychromeSprite {
order,
order: 0,
bounds,
corner_radii: Default::default(),
content_mask,
@ -367,7 +365,6 @@ impl<'a, 'w> WindowContext<'a, 'w> {
pub fn paint_svg(
&mut self,
bounds: Bounds<Pixels>,
order: u32,
path: SharedString,
color: Hsla,
) -> Result<()> {
@ -394,7 +391,7 @@ impl<'a, 'w> WindowContext<'a, 'w> {
self.window.scene.insert(
layer_id,
MonochromeSprite {
order,
order: 0,
bounds,
content_mask,
color,
@ -409,7 +406,6 @@ impl<'a, 'w> WindowContext<'a, 'w> {
&mut self,
bounds: Bounds<Pixels>,
corner_radii: Corners<Pixels>,
order: u32,
data: Arc<ImageData>,
grayscale: bool,
) -> Result<()> {
@ -430,7 +426,7 @@ impl<'a, 'w> WindowContext<'a, 'w> {
self.window.scene.insert(
order,
PolychromeSprite {
order: 0, // Used in in Scene::batches. 0 has no meaning.
order: 0,
bounds,
content_mask,
corner_radii,
@ -452,7 +448,7 @@ impl<'a, 'w> WindowContext<'a, 'w> {
cx.window
.layout_engine
.compute_layout(root_layout_id, available_space)?;
let layout = cx.window.layout_engine.layout(root_layout_id)?;
let layout = cx.window.layout_engine.layout_bounds(root_layout_id)?;
root_view.paint(layout, &mut (), &mut frame_state, cx)?;
cx.window.root_view = Some(root_view);
@ -786,9 +782,3 @@ pub struct AnyWindowHandle {
pub(crate) id: WindowId,
state_type: TypeId,
}
#[derive(Clone)]
pub struct Layout {
pub order: u32,
pub bounds: Bounds<Pixels>,
}

View file

@ -1,5 +1,5 @@
use gpui3::{
BorrowAppContext, Element, Hsla, Layout, LayoutId, Result, ViewContext, WindowContext,
BorrowAppContext, Bounds, Element, Hsla, LayoutId, Pixels, Result, ViewContext, WindowContext,
};
use serde::{de::Visitor, Deserialize, Deserializer};
use std::{collections::HashMap, fmt};
@ -160,7 +160,7 @@ impl<E: Element> Element for Themed<E> {
fn paint(
&mut self,
layout: Layout,
bounds: Bounds<Pixels>,
state: &mut Self::State,
frame_state: &mut Self::FrameState,
cx: &mut ViewContext<Self::State>,
@ -169,7 +169,7 @@ impl<E: Element> Element for Themed<E> {
Self: Sized,
{
cx.with_state(self.theme.clone(), |cx| {
self.child.paint(layout, state, frame_state, cx)
self.child.paint(bounds, state, frame_state, cx)
})
}
}