Always pass parent origin when painting elements

This commit is contained in:
Nathan Sobo 2023-09-08 06:32:20 -06:00
parent d311bd04ff
commit 7738867639
11 changed files with 79 additions and 62 deletions

View file

@ -19,6 +19,7 @@ pub trait Element<V: 'static>: 'static + IntoElement<V> {
fn paint( fn paint(
&mut self, &mut self,
view: &mut V, view: &mut V,
parent_origin: Vector2F,
layout: &Layout, layout: &Layout,
state: &mut Self::PaintState, state: &mut Self::PaintState,
cx: &mut PaintContext<V>, cx: &mut PaintContext<V>,
@ -110,9 +111,9 @@ impl<V, E: Element<V>> AnyStatefulElement<V> for StatefulElement<V, E> {
layout_id, layout_id,
mut paint_state, mut paint_state,
} => match cx.computed_layout(layout_id) { } => match cx.computed_layout(layout_id) {
Ok(mut layout) => { Ok(layout) => {
layout.bounds = layout.bounds + parent_origin; self.element
self.element.paint(view, &layout, &mut paint_state, cx); .paint(view, parent_origin, &layout, &mut paint_state, cx);
ElementPhase::PostPaint { ElementPhase::PostPaint {
layout, layout,
paint_state, paint_state,
@ -124,7 +125,8 @@ impl<V, E: Element<V>> AnyStatefulElement<V> for StatefulElement<V, E> {
layout, layout,
mut paint_state, mut paint_state,
} => { } => {
self.element.paint(view, &layout, &mut paint_state, cx); self.element
.paint(view, parent_origin, &layout, &mut paint_state, cx);
ElementPhase::PostPaint { ElementPhase::PostPaint {
layout, layout,
paint_state, paint_state,

View file

@ -10,6 +10,7 @@ use crate::{
}; };
use anyhow::Result; use anyhow::Result;
use gpui::{ use gpui::{
geometry::vector::Vector2F,
platform::{MouseButton, MouseButtonEvent, MouseMovedEvent}, platform::{MouseButton, MouseButtonEvent, MouseMovedEvent},
scene::{self}, scene::{self},
LayoutId, LayoutId,
@ -64,42 +65,45 @@ impl<V: 'static> Element<V> for Div<V> {
fn paint( fn paint(
&mut self, &mut self,
view: &mut V, view: &mut V,
parent_origin: Vector2F,
layout: &Layout, layout: &Layout,
_: &mut Self::PaintState, _: &mut Self::PaintState,
cx: &mut PaintContext<V>, cx: &mut PaintContext<V>,
) where ) where
Self: Sized, Self: Sized,
{ {
let order = layout.order;
let bounds = layout.bounds + parent_origin;
let style = self.computed_style(); let style = self.computed_style();
let pop_text_style = style.text_style(cx).map_or(false, |style| { let pop_text_style = style.text_style(cx).map_or(false, |style| {
cx.push_text_style(&style).log_err().is_some() cx.push_text_style(&style).log_err().is_some()
}); });
style.paint_background(layout.bounds, cx); style.paint_background(bounds, cx);
self.interaction_handlers() self.interaction_handlers().paint(order, bounds, cx);
.paint(layout.order, layout.bounds, cx);
for child in &mut self.children { for child in &mut self.children {
child.paint(view, layout.bounds.origin(), cx); child.paint(view, bounds.origin(), cx);
} }
style.paint_foreground(layout.bounds, cx); style.paint_foreground(bounds, cx);
if pop_text_style { if pop_text_style {
cx.pop_text_style(); cx.pop_text_style();
} }
if cx.is_inspector_enabled() { if cx.is_inspector_enabled() {
self.paint_inspector(layout, cx); self.paint_inspector(parent_origin, layout, cx);
} }
} }
} }
impl<V: 'static> Div<V> { impl<V: 'static> Div<V> {
fn paint_inspector(&self, layout: &Layout, cx: &mut PaintContext<V>) { fn paint_inspector(&self, parent_origin: Vector2F, layout: &Layout, cx: &mut PaintContext<V>) {
let style = self.styles.merged(); let style = self.styles.merged();
let bounds = layout.bounds + parent_origin;
let hovered = layout.bounds.contains_point(cx.mouse_position()); let hovered = bounds.contains_point(cx.mouse_position());
if hovered { if hovered {
let rem_size = cx.rem_size(); let rem_size = cx.rem_size();
cx.scene.push_quad(scene::Quad { cx.scene.push_quad(scene::Quad {
bounds: layout.bounds, bounds,
background: Some(hsla(0., 0., 1., 0.05).into()), background: Some(hsla(0., 0., 1., 0.05).into()),
border: gpui::Border { border: gpui::Border {
color: hsla(0., 0., 1., 0.2).into(), color: hsla(0., 0., 1., 0.2).into(),
@ -110,7 +114,7 @@ impl<V: 'static> Div<V> {
}, },
corner_radii: CornerRadii::default() corner_radii: CornerRadii::default()
.refined(&style.corner_radii) .refined(&style.corner_radii)
.to_gpui(layout.bounds.size(), rem_size), .to_gpui(bounds.size(), rem_size),
}) })
} }

View file

@ -6,7 +6,7 @@ use crate::{
style::{Style, StyleHelpers, Styleable}, style::{Style, StyleHelpers, Styleable},
}; };
use anyhow::Result; use anyhow::Result;
use gpui::{platform::MouseMovedEvent, LayoutId}; use gpui::{geometry::vector::Vector2F, platform::MouseMovedEvent, LayoutId};
use refineable::{CascadeSlot, Refineable, RefinementCascade}; use refineable::{CascadeSlot, Refineable, RefinementCascade};
use smallvec::SmallVec; use smallvec::SmallVec;
use std::{cell::Cell, rc::Rc}; use std::{cell::Cell, rc::Rc};
@ -56,6 +56,7 @@ impl<V: 'static, E: Element<V> + Styleable> Element<V> for Hoverable<E> {
fn paint( fn paint(
&mut self, &mut self,
view: &mut V, view: &mut V,
parent_origin: Vector2F,
layout: &Layout, layout: &Layout,
paint_state: &mut Self::PaintState, paint_state: &mut Self::PaintState,
cx: &mut PaintContext<V>, cx: &mut PaintContext<V>,
@ -78,7 +79,8 @@ impl<V: 'static, E: Element<V> + Styleable> Element<V> for Hoverable<E> {
} }
}); });
self.child.paint(view, layout, paint_state, cx); self.child
.paint(view, parent_origin, layout, paint_state, cx);
} }
} }

View file

@ -2,6 +2,7 @@ use crate as gpui2;
use crate::style::{StyleHelpers, Styleable}; use crate::style::{StyleHelpers, Styleable};
use crate::{style::Style, Element}; use crate::{style::Style, Element};
use futures::FutureExt; use futures::FutureExt;
use gpui::geometry::vector::Vector2F;
use gpui::scene; use gpui::scene;
use gpui2_macros::IntoElement; use gpui2_macros::IntoElement;
use refineable::RefinementCascade; use refineable::RefinementCascade;
@ -47,6 +48,7 @@ impl<V: 'static> Element<V> for Img {
fn paint( fn paint(
&mut self, &mut self,
_: &mut V, _: &mut V,
parent_origin: Vector2F,
layout: &gpui::Layout, layout: &gpui::Layout,
_: &mut Self::PaintState, _: &mut Self::PaintState,
cx: &mut crate::paint_context::PaintContext<V>, cx: &mut crate::paint_context::PaintContext<V>,
@ -54,8 +56,9 @@ impl<V: 'static> Element<V> for Img {
Self: Sized, Self: Sized,
{ {
let style = self.computed_style(); let style = self.computed_style();
let bounds = layout.bounds + parent_origin;
style.paint_background(layout.bounds, cx); style.paint_background(bounds, cx);
if let Some(uri) = &self.uri { if let Some(uri) = &self.uri {
let image_future = cx.image_cache.get(uri.clone()); let image_future = cx.image_cache.get(uri.clone());
@ -66,7 +69,7 @@ impl<V: 'static> Element<V> for Img {
{ {
let rem_size = cx.rem_size(); let rem_size = cx.rem_size();
cx.scene.push_image(scene::Image { cx.scene.push_image(scene::Image {
bounds: layout.bounds, bounds,
border: gpui::Border { border: gpui::Border {
color: style.border_color.unwrap_or_default().into(), color: style.border_color.unwrap_or_default().into(),
top: style.border_widths.top.to_pixels(rem_size), top: style.border_widths.top.to_pixels(rem_size),
@ -74,7 +77,7 @@ impl<V: 'static> Element<V> for Img {
bottom: style.border_widths.bottom.to_pixels(rem_size), bottom: style.border_widths.bottom.to_pixels(rem_size),
left: style.border_widths.left.to_pixels(rem_size), left: style.border_widths.left.to_pixels(rem_size),
}, },
corner_radii: style.corner_radii.to_gpui(layout.bounds.size(), rem_size), corner_radii: style.corner_radii.to_gpui(bounds.size(), rem_size),
grayscale: false, grayscale: false,
data, data,
}) })

View file

@ -6,7 +6,7 @@ use crate::{
style::{Style, StyleHelpers, Styleable}, style::{Style, StyleHelpers, Styleable},
}; };
use anyhow::Result; use anyhow::Result;
use gpui::{platform::MouseButtonEvent, LayoutId}; use gpui::{geometry::vector::Vector2F, platform::MouseButtonEvent, LayoutId};
use refineable::{CascadeSlot, Refineable, RefinementCascade}; use refineable::{CascadeSlot, Refineable, RefinementCascade};
use smallvec::SmallVec; use smallvec::SmallVec;
use std::{cell::Cell, rc::Rc}; use std::{cell::Cell, rc::Rc};
@ -56,6 +56,7 @@ impl<V: 'static, E: Element<V> + Styleable> Element<V> for Pressable<E> {
fn paint( fn paint(
&mut self, &mut self,
view: &mut V, view: &mut V,
parent_origin: Vector2F,
layout: &Layout, layout: &Layout,
paint_state: &mut Self::PaintState, paint_state: &mut Self::PaintState,
cx: &mut PaintContext<V>, cx: &mut PaintContext<V>,
@ -80,7 +81,8 @@ impl<V: 'static, E: Element<V> + Styleable> Element<V> for Pressable<E> {
} }
}); });
self.child.paint(view, layout, paint_state, cx); self.child
.paint(view, parent_origin, layout, paint_state, cx);
} }
} }

View file

@ -3,6 +3,7 @@ use crate::{
style::{Style, StyleHelpers, Styleable}, style::{Style, StyleHelpers, Styleable},
Element, IntoElement, Layout, LayoutId, Rgba, Element, IntoElement, Layout, LayoutId, Rgba,
}; };
use gpui::geometry::vector::Vector2F;
use refineable::RefinementCascade; use refineable::RefinementCascade;
use std::borrow::Cow; use std::borrow::Cow;
use util::ResultExt; use util::ResultExt;
@ -45,6 +46,7 @@ impl<V: 'static> Element<V> for Svg {
fn paint( fn paint(
&mut self, &mut self,
_: &mut V, _: &mut V,
parent_origin: Vector2F,
layout: &Layout, layout: &Layout,
_: &mut Self::PaintState, _: &mut Self::PaintState,
cx: &mut crate::paint_context::PaintContext<V>, cx: &mut crate::paint_context::PaintContext<V>,
@ -55,7 +57,7 @@ impl<V: 'static> Element<V> for Svg {
if let Some((path, fill_color)) = self.path.as_ref().zip(fill_color) { if let Some((path, fill_color)) = self.path.as_ref().zip(fill_color) {
if let Some(svg_tree) = cx.asset_cache.svg(path).log_err() { if let Some(svg_tree) = cx.asset_cache.svg(path).log_err() {
let icon = scene::Icon { let icon = scene::Icon {
bounds: layout.bounds, bounds: layout.bounds + parent_origin,
svg: svg_tree, svg: svg_tree,
path: path.clone(), path: path.clone(),
color: Rgba::from(fill_color).into(), color: Rgba::from(fill_color).into(),

View file

@ -4,7 +4,11 @@ use crate::{
paint_context::PaintContext, paint_context::PaintContext,
}; };
use anyhow::Result; use anyhow::Result;
use gpui::{geometry::Size, text_layout::LineLayout, LayoutId}; use gpui::{
geometry::{vector::Vector2F, Size},
text_layout::LineLayout,
LayoutId,
};
use parking_lot::Mutex; use parking_lot::Mutex;
use std::sync::Arc; use std::sync::Arc;
use util::arc_cow::ArcCow; use util::arc_cow::ArcCow;
@ -64,10 +68,13 @@ impl<V: 'static> Element<V> for Text {
fn paint<'a>( fn paint<'a>(
&mut self, &mut self,
_view: &mut V, _view: &mut V,
parent_origin: Vector2F,
layout: &Layout, layout: &Layout,
paint_state: &mut Self::PaintState, paint_state: &mut Self::PaintState,
cx: &mut PaintContext<V>, cx: &mut PaintContext<V>,
) { ) {
let bounds = layout.bounds + parent_origin;
let line_layout; let line_layout;
let line_height; let line_height;
{ {
@ -83,10 +90,15 @@ impl<V: 'static> Element<V> for Text {
let line = let line =
gpui::text_layout::Line::new(line_layout, &[(self.text.len(), text_style.to_run())]); gpui::text_layout::Line::new(line_layout, &[(self.text.len(), text_style.to_run())]);
let origin = layout.bounds.origin();
// 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 = layout.bounds; let visible_bounds = bounds;
line.paint(cx.scene, origin, visible_bounds, line_height, cx.legacy_cx); line.paint(
cx.scene,
bounds.origin(),
visible_bounds,
line_height,
cx.legacy_cx,
);
} }
} }

View file

@ -77,11 +77,12 @@ pub fn derive_element(input: TokenStream) -> TokenStream {
fn paint( fn paint(
&mut self, &mut self,
view: &mut V, view: &mut V,
layout: &gpui2::element::Layout, parent_origin: gpui2::Vector2F,
_: &gpui2::element::Layout,
rendered_element: &mut Self::PaintState, rendered_element: &mut Self::PaintState,
cx: &mut gpui2::element::PaintContext<V>, cx: &mut gpui2::element::PaintContext<V>,
) { ) {
rendered_element.paint(view, layout.bounds.origin(), cx); rendered_element.paint(view, parent_origin, cx);
} }
} }

View file

@ -33,7 +33,7 @@ impl<V: 'static> CollabPanelElement<V> {
.fill(theme.middle.base.default.background) .fill(theme.middle.base.default.background)
.child( .child(
div() div()
.full() .w_full()
.flex() .flex()
.flex_col() .flex_col()
// List Container // List Container

View file

@ -2,7 +2,7 @@ use gpui2::{
color::Hsla, color::Hsla,
element::{Element, PaintContext}, element::{Element, PaintContext},
layout_context::LayoutContext, layout_context::LayoutContext,
serde_json, AppContext, IntoElement, WindowContext, serde_json, AppContext, IntoElement, Vector2F, WindowContext,
}; };
use serde::{de::Visitor, Deserialize, Deserializer}; use serde::{de::Visitor, Deserialize, Deserializer};
use std::{collections::HashMap, fmt, marker::PhantomData}; use std::{collections::HashMap, fmt, marker::PhantomData};
@ -160,6 +160,7 @@ impl<V: 'static, E: Element<V>> Element<V> for Themed<V, E> {
fn paint( fn paint(
&mut self, &mut self,
view: &mut V, view: &mut V,
parent_origin: Vector2F,
layout: &gpui2::Layout, layout: &gpui2::Layout,
state: &mut Self::PaintState, state: &mut Self::PaintState,
cx: &mut PaintContext<V>, cx: &mut PaintContext<V>,
@ -167,7 +168,7 @@ impl<V: 'static, E: Element<V>> Element<V> for Themed<V, E> {
Self: Sized, Self: Sized,
{ {
cx.push_theme(self.theme.clone()); cx.push_theme(self.theme.clone());
self.child.paint(view, layout, state, cx); self.child.paint(view, parent_origin, layout, state, cx);
cx.pop_theme(); cx.pop_theme();
} }
} }

View file

@ -410,37 +410,25 @@ impl WorkspaceElement {
div() div()
.size_full() .size_full()
.flex() .flex()
.flex_row() .flex_col()
.child(collab_panel()) .font("Zed Sans Extended")
.child(collab_panel()) .gap_0()
.justify_start()
// div() .items_start()
// .size_full() .text_color(theme.lowest.base.default.foreground)
// .flex() // .fill(theme.middle.warning.default.background)
// .flex_col() .child(titlebar())
// .font("Zed Sans Extended") .child(
// .gap_0() div()
// .justify_start() .flex_1()
// .items_start() .flex()
// .text_color(theme.lowest.base.default.foreground) .flex_row()
// // .fill(theme.middle.warning.default.background) .w_full()
// .child(titlebar()) .child(collab_panel())
// .child( .child(div().h_full().flex_1())
// div() .child(collab_panel()),
// .flex_1() )
// .w_full() .child(statusbar())
// .flex()
// .flex_row()
// .child(collab_panel())
// // .child(
// // div()
// // .h_full()
// // .flex_1()
// // .fill(theme.highest.accent.default.background),
// // )
// .child(collab_panel()),
// )
// .child(statusbar())
} }
} }