Introduce a visible_bounds parameter to Element::paint
We're not using this yet but this will be useful to avoid rendering unnecessary portions of text.
This commit is contained in:
@@ -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 {
|
||||
|
||||
+13
-6
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
+13
-7
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user