Detailed changes
@@ -49,6 +49,7 @@ impl gpui::Element for TextElement {
fn paint(
&mut self,
bounds: RectF,
+ _: RectF,
_: &mut Self::LayoutState,
cx: &mut gpui::PaintContext,
) -> Self::PaintState {
@@ -50,7 +50,7 @@ use std::{
trait AnyElement {
fn layout(&mut self, constraint: SizeConstraint, cx: &mut LayoutContext) -> Vector2F;
- fn paint(&mut self, origin: Vector2F, cx: &mut PaintContext);
+ fn paint(&mut self, origin: Vector2F, visible_bounds: RectF, cx: &mut PaintContext);
fn dispatch_event(&mut self, event: &Event, cx: &mut EventContext) -> bool;
fn debug(&self, cx: &DebugContext) -> serde_json::Value;
@@ -71,6 +71,7 @@ pub trait Element {
fn paint(
&mut self,
bounds: RectF,
+ visible_bounds: RectF,
layout: &mut Self::LayoutState,
cx: &mut PaintContext,
) -> Self::PaintState;
@@ -168,7 +169,7 @@ impl<T: Element> AnyElement for Lifecycle<T> {
result
}
- fn paint(&mut self, origin: Vector2F, cx: &mut PaintContext) {
+ fn paint(&mut self, origin: Vector2F, visible_bounds: RectF, cx: &mut PaintContext) {
*self = match mem::take(self) {
Lifecycle::PostLayout {
mut element,
@@ -177,7 +178,10 @@ impl<T: Element> AnyElement for Lifecycle<T> {
mut layout,
} => {
let bounds = RectF::new(origin, size);
- let paint = element.paint(bounds, &mut layout, cx);
+ let visible_bounds = visible_bounds
+ .intersection(bounds)
+ .unwrap_or_else(|| RectF::new(bounds.origin(), Vector2F::default()));
+ let paint = element.paint(bounds, visible_bounds, &mut layout, cx);
Lifecycle::PostPaint {
element,
constraint,
@@ -194,7 +198,10 @@ impl<T: Element> AnyElement for Lifecycle<T> {
..
} => {
let bounds = RectF::new(origin, bounds.size());
- let paint = element.paint(bounds, &mut layout, cx);
+ let visible_bounds = visible_bounds
+ .intersection(bounds)
+ .unwrap_or_else(|| RectF::new(bounds.origin(), Vector2F::default()));
+ let paint = element.paint(bounds, visible_bounds, &mut layout, cx);
Lifecycle::PostPaint {
element,
constraint,
@@ -305,8 +312,8 @@ impl ElementRc {
self.element.borrow_mut().layout(constraint, cx)
}
- pub fn paint(&mut self, origin: Vector2F, cx: &mut PaintContext) {
- self.element.borrow_mut().paint(origin, cx);
+ pub fn paint(&mut self, origin: Vector2F, visible_bounds: RectF, cx: &mut PaintContext) {
+ self.element.borrow_mut().paint(origin, visible_bounds, cx);
}
pub fn dispatch_event(&mut self, event: &Event, cx: &mut EventContext) -> bool {
@@ -1,9 +1,10 @@
use crate::{
+ geometry::{rect::RectF, vector::Vector2F},
json, DebugContext, Element, ElementBox, Event, EventContext, LayoutContext, PaintContext,
SizeConstraint,
};
use json::ToJson;
-use pathfinder_geometry::vector::Vector2F;
+
use serde_json::json;
pub struct Align {
@@ -53,7 +54,8 @@ impl Element for Align {
fn paint(
&mut self,
- bounds: pathfinder_geometry::rect::RectF,
+ bounds: RectF,
+ visible_bounds: RectF,
_: &mut Self::LayoutState,
cx: &mut PaintContext,
) -> Self::PaintState {
@@ -63,8 +65,11 @@ impl Element for Align {
let child_center = self.child.size() / 2.;
let child_target = child_center + child_center * self.alignment;
- self.child
- .paint(bounds.origin() - (child_target - my_target), cx);
+ self.child.paint(
+ bounds.origin() - (child_target - my_target),
+ visible_bounds,
+ cx,
+ );
}
fn dispatch_event(
@@ -9,13 +9,11 @@ use pathfinder_geometry::{
vector::{vec2f, Vector2F},
};
-pub struct Canvas<F>(F)
-where
- F: FnMut(RectF, &mut PaintContext);
+pub struct Canvas<F>(F);
impl<F> Canvas<F>
where
- F: FnMut(RectF, &mut PaintContext),
+ F: FnMut(RectF, RectF, &mut PaintContext),
{
pub fn new(f: F) -> Self {
Self(f)
@@ -24,7 +22,7 @@ where
impl<F> Element for Canvas<F>
where
- F: FnMut(RectF, &mut PaintContext),
+ F: FnMut(RectF, RectF, &mut PaintContext),
{
type LayoutState = ();
type PaintState = ();
@@ -50,10 +48,11 @@ where
fn paint(
&mut self,
bounds: RectF,
+ visible_bounds: RectF,
_: &mut Self::LayoutState,
cx: &mut PaintContext,
) -> Self::PaintState {
- self.0(bounds, cx)
+ self.0(bounds, visible_bounds, cx)
}
fn dispatch_event(
@@ -70,10 +70,11 @@ impl Element for ConstrainedBox {
fn paint(
&mut self,
bounds: RectF,
+ visible_bounds: RectF,
_: &mut Self::LayoutState,
cx: &mut PaintContext,
) -> Self::PaintState {
- self.child.paint(bounds.origin(), cx);
+ self.child.paint(bounds.origin(), visible_bounds, cx);
}
fn dispatch_event(
@@ -169,6 +169,7 @@ impl Element for Container {
fn paint(
&mut self,
bounds: RectF,
+ visible_bounds: RectF,
_: &mut Self::LayoutState,
cx: &mut PaintContext,
) -> Self::PaintState {
@@ -198,7 +199,7 @@ impl Element for Container {
self.style.border.left_width(),
self.style.border.top_width(),
);
- self.child.paint(child_origin, cx);
+ self.child.paint(child_origin, visible_bounds, cx);
}
fn dispatch_event(
@@ -42,6 +42,7 @@ impl Element for Empty {
fn paint(
&mut self,
_: RectF,
+ _: RectF,
_: &mut Self::LayoutState,
_: &mut PaintContext,
) -> Self::PaintState {
@@ -44,10 +44,11 @@ impl Element for EventHandler {
fn paint(
&mut self,
bounds: RectF,
+ visible_bounds: RectF,
_: &mut Self::LayoutState,
cx: &mut PaintContext,
) -> Self::PaintState {
- self.child.paint(bounds.origin(), cx);
+ self.child.paint(bounds.origin(), visible_bounds, cx);
}
fn dispatch_event(
@@ -134,12 +134,13 @@ impl Element for Flex {
fn paint(
&mut self,
bounds: RectF,
+ visible_bounds: RectF,
_: &mut Self::LayoutState,
cx: &mut PaintContext,
) -> Self::PaintState {
let mut child_origin = bounds.origin();
for child in &mut self.children {
- child.paint(child_origin, cx);
+ child.paint(child_origin, visible_bounds, cx);
match self.axis {
Axis::Horizontal => child_origin += vec2f(child.size().x(), 0.0),
Axis::Vertical => child_origin += vec2f(0.0, child.size().y()),
@@ -212,10 +213,11 @@ impl Element for Expanded {
fn paint(
&mut self,
bounds: RectF,
+ visible_bounds: RectF,
_: &mut Self::LayoutState,
cx: &mut PaintContext,
) -> Self::PaintState {
- self.child.paint(bounds.origin(), cx)
+ self.child.paint(bounds.origin(), visible_bounds, cx)
}
fn dispatch_event(
@@ -128,6 +128,7 @@ impl Element for Label {
fn paint(
&mut self,
bounds: RectF,
+ visible_bounds: RectF,
line: &mut Self::LayoutState,
cx: &mut PaintContext,
) -> Self::PaintState {
@@ -48,18 +48,22 @@ impl Element for LineBox {
fn paint(
&mut self,
- bounds: pathfinder_geometry::rect::RectF,
+ bounds: RectF,
+ visible_bounds: RectF,
padding_top: &mut f32,
cx: &mut PaintContext,
) -> Self::PaintState {
- self.child
- .paint(bounds.origin() + vec2f(0., *padding_top), cx);
+ self.child.paint(
+ bounds.origin() + vec2f(0., *padding_top),
+ visible_bounds,
+ cx,
+ );
}
fn dispatch_event(
&mut self,
event: &Event,
- _: pathfinder_geometry::rect::RectF,
+ _: RectF,
_: &mut Self::LayoutState,
_: &mut Self::PaintState,
cx: &mut EventContext,
@@ -230,12 +230,18 @@ impl Element for List {
(size, scroll_top)
}
- fn paint(&mut self, bounds: RectF, scroll_top: &mut ListOffset, cx: &mut PaintContext) {
+ fn paint(
+ &mut self,
+ bounds: RectF,
+ visible_bounds: RectF,
+ scroll_top: &mut ListOffset,
+ cx: &mut PaintContext,
+ ) {
cx.scene.push_layer(Some(bounds));
let state = &mut *self.state.0.borrow_mut();
for (mut element, origin) in state.visible_elements(bounds, scroll_top) {
- element.paint(origin, cx);
+ element.paint(origin, visible_bounds, cx);
}
cx.scene.pop_layer();
@@ -832,7 +838,7 @@ mod tests {
(self.size, ())
}
- fn paint(&mut self, _: RectF, _: &mut (), _: &mut PaintContext) {
+ fn paint(&mut self, _: RectF, _: RectF, _: &mut (), _: &mut PaintContext) {
todo!()
}
@@ -81,10 +81,11 @@ impl Element for MouseEventHandler {
fn paint(
&mut self,
bounds: RectF,
+ visible_bounds: RectF,
_: &mut Self::LayoutState,
cx: &mut PaintContext,
) -> Self::PaintState {
- self.child.paint(bounds.origin(), cx);
+ self.child.paint(bounds.origin(), visible_bounds, cx);
}
fn dispatch_event(
@@ -27,10 +27,16 @@ impl Element for Overlay {
(Vector2F::zero(), size)
}
- fn paint(&mut self, bounds: RectF, size: &mut Self::LayoutState, cx: &mut PaintContext) {
+ fn paint(
+ &mut self,
+ bounds: RectF,
+ visible_bounds: RectF,
+ size: &mut Self::LayoutState,
+ cx: &mut PaintContext,
+ ) {
let bounds = RectF::new(bounds.origin(), *size);
cx.scene.push_stacking_context(None);
- self.child.paint(bounds.origin(), cx);
+ self.child.paint(bounds.origin(), visible_bounds, cx);
cx.scene.pop_stacking_context();
}
@@ -36,12 +36,13 @@ impl Element for Stack {
fn paint(
&mut self,
bounds: RectF,
+ visible_bounds: RectF,
_: &mut Self::LayoutState,
cx: &mut PaintContext,
) -> Self::PaintState {
for child in &mut self.children {
cx.scene.push_layer(None);
- child.paint(bounds.origin(), cx);
+ child.paint(bounds.origin(), visible_bounds, cx);
cx.scene.pop_layer();
}
}
@@ -65,7 +65,13 @@ impl Element for Svg {
}
}
- fn paint(&mut self, bounds: RectF, svg: &mut Self::LayoutState, cx: &mut PaintContext) {
+ fn paint(
+ &mut self,
+ bounds: RectF,
+ _visible_bounds: RectF,
+ svg: &mut Self::LayoutState,
+ cx: &mut PaintContext,
+ ) {
if let Some(svg) = svg.clone() {
cx.scene.push_icon(scene::Icon {
bounds,
@@ -76,6 +76,7 @@ impl Element for Text {
fn paint(
&mut self,
bounds: RectF,
+ visible_bounds: RectF,
layout: &mut Self::LayoutState,
cx: &mut PaintContext,
) -> Self::PaintState {
@@ -165,6 +165,7 @@ where
fn paint(
&mut self,
bounds: RectF,
+ visible_bounds: RectF,
layout: &mut Self::LayoutState,
cx: &mut PaintContext,
) -> Self::PaintState {
@@ -174,7 +175,7 @@ where
bounds.origin() - vec2f(0.0, self.state.scroll_top() % layout.item_height);
for item in &mut layout.items {
- item.paint(item_origin, cx);
+ item.paint(item_origin, visible_bounds, cx);
item_origin += vec2f(0.0, layout.item_height);
}
@@ -2,6 +2,7 @@ use crate::{
app::{AppContext, MutableAppContext, WindowInvalidation},
elements::Element,
font_cache::FontCache,
+ geometry::rect::RectF,
json::{self, ToJson},
platform::Event,
text_layout::TextLayoutCache,
@@ -111,7 +112,11 @@ impl Presenter {
rendered_views: &mut self.rendered_views,
app: cx.as_ref(),
};
- paint_cx.paint(root_view_id, Vector2F::zero());
+ paint_cx.paint(
+ root_view_id,
+ Vector2F::zero(),
+ RectF::new(Vector2F::zero(), window_size),
+ );
self.text_layout_cache.finish_frame();
if let Some(event) = self.last_mouse_moved_event.clone() {
@@ -273,9 +278,9 @@ pub struct PaintContext<'a> {
}
impl<'a> PaintContext<'a> {
- fn paint(&mut self, view_id: usize, origin: Vector2F) {
+ fn paint(&mut self, view_id: usize, origin: Vector2F, visible_bounds: RectF) {
if let Some(mut tree) = self.rendered_views.remove(&view_id) {
- tree.paint(origin, self);
+ tree.paint(origin, visible_bounds, self);
self.rendered_views.insert(view_id, tree);
}
}
@@ -455,17 +460,18 @@ impl Element for ChildView {
fn paint(
&mut self,
- bounds: pathfinder_geometry::rect::RectF,
+ bounds: RectF,
+ visible_bounds: RectF,
_: &mut Self::LayoutState,
cx: &mut PaintContext,
) -> Self::PaintState {
- cx.paint(self.view_id, bounds.origin());
+ cx.paint(self.view_id, bounds.origin(), visible_bounds);
}
fn dispatch_event(
&mut self,
event: &Event,
- _: pathfinder_geometry::rect::RectF,
+ _: RectF,
_: &mut Self::LayoutState,
_: &mut Self::PaintState,
cx: &mut EventContext,
@@ -475,7 +481,7 @@ impl Element for ChildView {
fn debug(
&self,
- bounds: pathfinder_geometry::rect::RectF,
+ bounds: RectF,
_: &Self::LayoutState,
_: &Self::PaintState,
cx: &DebugContext,
@@ -559,6 +559,7 @@ impl Element for EditorElement {
fn paint(
&mut self,
bounds: RectF,
+ _: RectF,
layout: &mut Self::LayoutState,
cx: &mut PaintContext,
) -> Self::PaintState {
@@ -336,7 +336,7 @@ impl Pane {
} else {
let diameter = 8.;
ConstrainedBox::new(
- Canvas::new(move |bounds, cx| {
+ Canvas::new(move |bounds, _, cx| {
if let Some(current_color) = current_color {
let square = RectF::new(bounds.origin(), vec2f(diameter, diameter));
cx.scene.push_quad(Quad {