Checkpoint

This commit is contained in:
Nathan Sobo
2023-09-08 16:25:10 -06:00
parent 362b1a44be
commit ebf8b32811
49 changed files with 491 additions and 627 deletions
+1 -4
View File
@@ -1,7 +1,6 @@
use crate::{
geometry::{rect::RectF, vector::Vector2F},
json, AnyElement, Element, LayoutContext, PaintContext, SceneBuilder, SizeConstraint,
ViewContext,
json, AnyElement, Element, LayoutContext, PaintContext, SizeConstraint, ViewContext,
};
use json::ToJson;
@@ -65,7 +64,6 @@ impl<V: 'static> Element<V> for Align<V> {
fn paint(
&mut self,
scene: &mut SceneBuilder,
bounds: RectF,
visible_bounds: RectF,
_: &mut Self::LayoutState,
@@ -79,7 +77,6 @@ impl<V: 'static> Element<V> for Align<V> {
let child_target = child_center + child_center * self.alignment;
self.child.paint(
scene,
bounds.origin() - (child_target - my_target),
visible_bounds,
view,
+4 -5
View File
@@ -3,7 +3,7 @@ use std::marker::PhantomData;
use super::Element;
use crate::{
json::{self, json},
PaintContext, SceneBuilder, ViewContext,
PaintContext, ViewContext,
};
use json::ToJson;
use pathfinder_geometry::{
@@ -15,7 +15,7 @@ pub struct Canvas<V, F>(F, PhantomData<V>);
impl<V, F> Canvas<V, F>
where
F: FnMut(&mut SceneBuilder, RectF, RectF, &mut V, &mut ViewContext<V>),
F: FnMut(RectF, RectF, &mut V, &mut PaintContext<V>),
{
pub fn new(f: F) -> Self {
Self(f, PhantomData)
@@ -24,7 +24,7 @@ where
impl<V: 'static, F> Element<V> for Canvas<V, F>
where
F: 'static + FnMut(&mut SceneBuilder, RectF, RectF, &mut V, &mut ViewContext<V>),
F: 'static + FnMut(RectF, RectF, &mut V, &mut PaintContext<V>),
{
type LayoutState = ();
type PaintState = ();
@@ -50,14 +50,13 @@ where
fn paint(
&mut self,
scene: &mut SceneBuilder,
bounds: RectF,
visible_bounds: RectF,
_: &mut Self::LayoutState,
view: &mut V,
cx: &mut PaintContext<V>,
) -> Self::PaintState {
self.0(scene, bounds, visible_bounds, view, cx)
self.0(bounds, visible_bounds, view, cx)
}
fn rect_for_text_range(
+5 -9
View File
@@ -3,10 +3,7 @@ use std::ops::Range;
use pathfinder_geometry::{rect::RectF, vector::Vector2F};
use serde_json::json;
use crate::{
json, AnyElement, Element, LayoutContext, PaintContext, SceneBuilder, SizeConstraint,
ViewContext,
};
use crate::{json, AnyElement, Element, LayoutContext, PaintContext, SizeConstraint, ViewContext};
pub struct Clipped<V> {
child: AnyElement<V>,
@@ -33,17 +30,16 @@ impl<V: 'static> Element<V> for Clipped<V> {
fn paint(
&mut self,
scene: &mut SceneBuilder,
bounds: RectF,
visible_bounds: RectF,
_: &mut Self::LayoutState,
view: &mut V,
cx: &mut PaintContext<V>,
) -> Self::PaintState {
scene.paint_layer(Some(bounds), |scene| {
self.child
.paint(scene, bounds.origin(), visible_bounds, view, cx)
})
cx.scene().push_layer(Some(bounds));
let state = self.child.paint(bounds.origin(), visible_bounds, view, cx);
cx.scene().pop_layer();
state
}
fn rect_for_text_range(
+2 -5
View File
@@ -2,9 +2,7 @@ use std::{any::Any, marker::PhantomData};
use pathfinder_geometry::{rect::RectF, vector::Vector2F};
use crate::{
AnyElement, Element, LayoutContext, PaintContext, SceneBuilder, SizeConstraint, ViewContext,
};
use crate::{AnyElement, Element, LayoutContext, PaintContext, SizeConstraint, ViewContext};
use super::Empty;
@@ -300,7 +298,6 @@ impl<V: 'static, C: StatefulComponent<V> + 'static> Element<V> for ComponentAdap
fn paint(
&mut self,
scene: &mut SceneBuilder,
bounds: RectF,
visible_bounds: RectF,
_: &mut Self::LayoutState,
@@ -310,7 +307,7 @@ impl<V: 'static, C: StatefulComponent<V> + 'static> Element<V> for ComponentAdap
self.element
.as_mut()
.expect("Layout should always be called before paint")
.paint(scene, bounds.origin(), visible_bounds, view, cx)
.paint(bounds.origin(), visible_bounds, view, cx)
}
fn rect_for_text_range(
+4 -7
View File
@@ -5,8 +5,7 @@ use serde_json::json;
use crate::{
geometry::{rect::RectF, vector::Vector2F},
json, AnyElement, Element, LayoutContext, PaintContext, SceneBuilder, SizeConstraint,
ViewContext,
json, AnyElement, Element, LayoutContext, PaintContext, SizeConstraint, ViewContext,
};
pub struct ConstrainedBox<V> {
@@ -152,17 +151,15 @@ impl<V: 'static> Element<V> for ConstrainedBox<V> {
fn paint(
&mut self,
scene: &mut SceneBuilder,
bounds: RectF,
visible_bounds: RectF,
_: &mut Self::LayoutState,
view: &mut V,
cx: &mut PaintContext<V>,
) -> Self::PaintState {
scene.paint_layer(Some(visible_bounds), |scene| {
self.child
.paint(scene, bounds.origin(), visible_bounds, view, cx);
})
cx.scene().push_layer(Some(visible_bounds));
self.child.paint(bounds.origin(), visible_bounds, view, cx);
cx.scene().pop_layer();
}
fn rect_for_text_range(
+13 -16
View File
@@ -10,7 +10,7 @@ use crate::{
json::ToJson,
platform::CursorStyle,
scene::{self, CornerRadii, CursorRegion, Quad},
AnyElement, Element, LayoutContext, PaintContext, SceneBuilder, SizeConstraint, ViewContext,
AnyElement, Element, LayoutContext, PaintContext, SizeConstraint, ViewContext,
};
use schemars::JsonSchema;
use serde::Deserialize;
@@ -387,7 +387,6 @@ impl<V: 'static> Element<V> for Container<V> {
fn paint(
&mut self,
scene: &mut SceneBuilder,
bounds: RectF,
visible_bounds: RectF,
_: &mut Self::LayoutState,
@@ -400,7 +399,7 @@ impl<V: 'static> Element<V> for Container<V> {
);
if let Some(shadow) = self.style.shadow.as_ref() {
scene.push_shadow(scene::Shadow {
cx.scene().push_shadow(scene::Shadow {
bounds: quad_bounds + shadow.offset,
corner_radii: self.style.corner_radii,
sigma: shadow.blur,
@@ -410,7 +409,7 @@ impl<V: 'static> Element<V> for Container<V> {
if let Some(hit_bounds) = quad_bounds.intersection(visible_bounds) {
if let Some(style) = self.style.cursor {
scene.push_cursor_region(CursorRegion {
cx.scene().push_cursor_region(CursorRegion {
bounds: hit_bounds,
style,
});
@@ -421,26 +420,25 @@ impl<V: 'static> Element<V> for Container<V> {
quad_bounds.origin() + vec2f(self.style.padding.left, self.style.padding.top);
if self.style.border.overlay {
scene.push_quad(Quad {
cx.scene().push_quad(Quad {
bounds: quad_bounds,
background: self.style.background_color,
border: Default::default(),
corner_radii: self.style.corner_radii.into(),
});
self.child
.paint(scene, child_origin, visible_bounds, view, cx);
self.child.paint(child_origin, visible_bounds, view, cx);
scene.push_layer(None);
scene.push_quad(Quad {
cx.scene().push_layer(None);
cx.scene().push_quad(Quad {
bounds: quad_bounds,
background: self.style.overlay_color,
border: self.style.border.into(),
corner_radii: self.style.corner_radii.into(),
});
scene.pop_layer();
cx.scene().pop_layer();
} else {
scene.push_quad(Quad {
cx.scene().push_quad(Quad {
bounds: quad_bounds,
background: self.style.background_color,
border: self.style.border.into(),
@@ -452,18 +450,17 @@ impl<V: 'static> Element<V> for Container<V> {
self.style.border.left_width(),
self.style.border.top_width(),
);
self.child
.paint(scene, child_origin, visible_bounds, view, cx);
self.child.paint(child_origin, visible_bounds, view, cx);
if self.style.overlay_color.is_some() {
scene.push_layer(None);
scene.push_quad(Quad {
cx.scene().push_layer(None);
cx.scene().push_quad(Quad {
bounds: quad_bounds,
background: self.style.overlay_color,
border: Default::default(),
corner_radii: self.style.corner_radii.into(),
});
scene.pop_layer();
cx.scene().pop_layer();
}
}
}
+1 -2
View File
@@ -6,7 +6,7 @@ use crate::{
vector::{vec2f, Vector2F},
},
json::{json, ToJson},
LayoutContext, PaintContext, SceneBuilder, ViewContext,
LayoutContext, PaintContext, ViewContext,
};
use crate::{Element, SizeConstraint};
@@ -52,7 +52,6 @@ impl<V: 'static> Element<V> for Empty {
fn paint(
&mut self,
_: &mut SceneBuilder,
_: RectF,
_: RectF,
_: &mut Self::LayoutState,
+2 -5
View File
@@ -2,8 +2,7 @@ use std::ops::Range;
use crate::{
geometry::{rect::RectF, vector::Vector2F},
json, AnyElement, Element, LayoutContext, PaintContext, SceneBuilder, SizeConstraint,
ViewContext,
json, AnyElement, Element, LayoutContext, PaintContext, SizeConstraint, ViewContext,
};
use serde_json::json;
@@ -57,15 +56,13 @@ impl<V: 'static> Element<V> for Expanded<V> {
fn paint(
&mut self,
scene: &mut SceneBuilder,
bounds: RectF,
visible_bounds: RectF,
_: &mut Self::LayoutState,
view: &mut V,
cx: &mut PaintContext<V>,
) -> Self::PaintState {
self.child
.paint(scene, bounds.origin(), visible_bounds, view, cx);
self.child.paint(bounds.origin(), visible_bounds, view, cx);
}
fn rect_for_text_range(
+10 -13
View File
@@ -2,8 +2,8 @@ use std::{any::Any, cell::Cell, f32::INFINITY, ops::Range, rc::Rc};
use crate::{
json::{self, ToJson, Value},
AnyElement, Axis, Element, ElementStateHandle, LayoutContext, PaintContext, SceneBuilder,
SizeConstraint, Vector2FExt, ViewContext,
AnyElement, Axis, Element, ElementStateHandle, LayoutContext, PaintContext, SizeConstraint,
Vector2FExt, ViewContext,
};
use pathfinder_geometry::{
rect::RectF,
@@ -260,7 +260,6 @@ impl<V: 'static> Element<V> for Flex<V> {
fn paint(
&mut self,
scene: &mut SceneBuilder,
bounds: RectF,
visible_bounds: RectF,
remaining_space: &mut Self::LayoutState,
@@ -272,14 +271,14 @@ impl<V: 'static> Element<V> for Flex<V> {
let mut remaining_space = *remaining_space;
let overflowing = remaining_space < 0.;
if overflowing {
scene.push_layer(Some(visible_bounds));
cx.scene().push_layer(Some(visible_bounds));
}
if let Some(scroll_state) = &self.scroll_state {
scene.push_mouse_region(
crate::MouseRegion::new::<Self>(scroll_state.1, 0, bounds)
if let Some((scroll_state, id)) = &self.scroll_state {
let scroll_state = scroll_state.read(cx).clone();
cx.scene().push_mouse_region(
crate::MouseRegion::new::<Self>(*id, 0, bounds)
.on_scroll({
let scroll_state = scroll_state.0.read(cx).clone();
let axis = self.axis;
move |e, _: &mut V, cx| {
if remaining_space < 0. {
@@ -358,7 +357,7 @@ impl<V: 'static> Element<V> for Flex<V> {
aligned_child_origin
};
child.paint(scene, aligned_child_origin, visible_bounds, view, cx);
child.paint(aligned_child_origin, visible_bounds, view, cx);
match self.axis {
Axis::Horizontal => child_origin += vec2f(child.size().x() + self.spacing, 0.0),
@@ -367,7 +366,7 @@ impl<V: 'static> Element<V> for Flex<V> {
}
if overflowing {
scene.pop_layer();
cx.scene().pop_layer();
}
}
@@ -451,15 +450,13 @@ impl<V: 'static> Element<V> for FlexItem<V> {
fn paint(
&mut self,
scene: &mut SceneBuilder,
bounds: RectF,
visible_bounds: RectF,
_: &mut Self::LayoutState,
view: &mut V,
cx: &mut PaintContext<V>,
) -> Self::PaintState {
self.child
.paint(scene, bounds.origin(), visible_bounds, view, cx)
self.child.paint(bounds.origin(), visible_bounds, view, cx)
}
fn rect_for_text_range(
+2 -4
View File
@@ -3,7 +3,7 @@ use std::ops::Range;
use crate::{
geometry::{rect::RectF, vector::Vector2F},
json::json,
AnyElement, Element, LayoutContext, PaintContext, SceneBuilder, SizeConstraint, ViewContext,
AnyElement, Element, LayoutContext, PaintContext, SizeConstraint, ViewContext,
};
pub struct Hook<V> {
@@ -47,15 +47,13 @@ impl<V: 'static> Element<V> for Hook<V> {
fn paint(
&mut self,
scene: &mut SceneBuilder,
bounds: RectF,
visible_bounds: RectF,
_: &mut Self::LayoutState,
view: &mut V,
cx: &mut PaintContext<V>,
) {
self.child
.paint(scene, bounds.origin(), visible_bounds, view, cx);
self.child.paint(bounds.origin(), visible_bounds, view, cx);
}
fn rect_for_text_range(
+3 -5
View File
@@ -5,8 +5,7 @@ use crate::{
vector::{vec2f, Vector2F},
},
json::{json, ToJson},
scene, Element, ImageData, LayoutContext, PaintContext, SceneBuilder, SizeConstraint,
ViewContext,
scene, Element, ImageData, LayoutContext, PaintContext, SizeConstraint, ViewContext,
};
use schemars::JsonSchema;
use serde::Deserialize;
@@ -92,15 +91,14 @@ impl<V: 'static> Element<V> for Image {
fn paint(
&mut self,
scene: &mut SceneBuilder,
bounds: RectF,
_: RectF,
layout: &mut Self::LayoutState,
_: &mut V,
_: &mut PaintContext<V>,
cx: &mut PaintContext<V>,
) -> Self::PaintState {
if let Some(data) = layout {
scene.push_image(scene::Image {
cx.scene().push_image(scene::Image {
bounds,
border: self.style.border.into(),
corner_radii: self.style.corner_radius.into(),
+1 -2
View File
@@ -61,14 +61,13 @@ impl<V: 'static> Element<V> for KeystrokeLabel {
fn paint(
&mut self,
scene: &mut SceneBuilder,
bounds: RectF,
visible_bounds: RectF,
element: &mut AnyElement<V>,
view: &mut V,
cx: &mut PaintContext<V>,
) {
element.paint(scene, bounds.origin(), visible_bounds, view, cx);
element.paint(bounds.origin(), visible_bounds, view, cx);
}
fn rect_for_text_range(
+2 -9
View File
@@ -8,7 +8,7 @@ use crate::{
},
json::{ToJson, Value},
text_layout::{Line, RunStyle},
Element, LayoutContext, PaintContext, SceneBuilder, SizeConstraint, ViewContext,
Element, LayoutContext, PaintContext, SizeConstraint, ViewContext,
};
use schemars::JsonSchema;
use serde::Deserialize;
@@ -158,7 +158,6 @@ impl<V: 'static> Element<V> for Label {
fn paint(
&mut self,
scene: &mut SceneBuilder,
bounds: RectF,
visible_bounds: RectF,
line: &mut Self::LayoutState,
@@ -166,13 +165,7 @@ impl<V: 'static> Element<V> for Label {
cx: &mut PaintContext<V>,
) -> Self::PaintState {
let visible_bounds = bounds.intersection(visible_bounds).unwrap_or_default();
line.paint(
scene,
bounds.origin(),
visible_bounds,
bounds.size().y(),
cx,
)
line.paint(bounds.origin(), visible_bounds, bounds.size().y(), cx)
}
fn rect_for_text_range(
+9 -21
View File
@@ -4,8 +4,7 @@ use crate::{
vector::{vec2f, Vector2F},
},
json::json,
AnyElement, Element, LayoutContext, MouseRegion, PaintContext, SceneBuilder, SizeConstraint,
ViewContext,
AnyElement, Element, LayoutContext, MouseRegion, PaintContext, SizeConstraint, ViewContext,
};
use std::{cell::RefCell, collections::VecDeque, fmt::Debug, ops::Range, rc::Rc};
use sum_tree::{Bias, SumTree};
@@ -250,7 +249,6 @@ impl<V: 'static> Element<V> for List<V> {
fn paint(
&mut self,
scene: &mut SceneBuilder,
bounds: RectF,
visible_bounds: RectF,
scroll_top: &mut ListOffset,
@@ -258,9 +256,10 @@ impl<V: 'static> Element<V> for List<V> {
cx: &mut PaintContext<V>,
) {
let visible_bounds = visible_bounds.intersection(bounds).unwrap_or_default();
scene.push_layer(Some(visible_bounds));
scene.push_mouse_region(
MouseRegion::new::<Self>(cx.view_id(), 0, bounds).on_scroll({
cx.scene().push_layer(Some(visible_bounds));
let view_id = cx.view_id();
cx.scene()
.push_mouse_region(MouseRegion::new::<Self>(view_id, 0, bounds).on_scroll({
let state = self.state.clone();
let height = bounds.height();
let scroll_top = scroll_top.clone();
@@ -274,17 +273,14 @@ impl<V: 'static> Element<V> for List<V> {
cx,
)
}
}),
);
}));
let state = &mut *self.state.0.borrow_mut();
for (element, origin) in state.visible_elements(bounds, scroll_top) {
element
.borrow_mut()
.paint(scene, origin, visible_bounds, view, cx);
element.borrow_mut().paint(origin, visible_bounds, view, cx);
}
scene.pop_layer();
cx.scene().pop_layer();
}
fn rect_for_text_range(
@@ -957,15 +953,7 @@ mod tests {
(self.size, ())
}
fn paint(
&mut self,
_: &mut SceneBuilder,
_: RectF,
_: RectF,
_: &mut (),
_: &mut V,
_: &mut PaintContext<V>,
) {
fn paint(&mut self, _: RectF, _: RectF, _: &mut (), _: &mut V, _: &mut PaintContext<V>) {
unimplemented!()
}
+11 -20
View File
@@ -11,7 +11,7 @@ use crate::{
MouseHover, MouseMove, MouseMoveOut, MouseScrollWheel, MouseUp, MouseUpOut,
},
AnyElement, Element, EventContext, LayoutContext, MouseRegion, MouseState, PaintContext,
SceneBuilder, SizeConstraint, TypeTag, ViewContext,
SizeConstraint, TypeTag, ViewContext,
};
use serde_json::json;
use std::ops::Range;
@@ -236,26 +236,21 @@ impl<V: 'static> MouseEventHandler<V> {
.round_out()
}
fn paint_regions(
&self,
scene: &mut SceneBuilder,
bounds: RectF,
visible_bounds: RectF,
cx: &mut ViewContext<V>,
) {
fn paint_regions(&self, bounds: RectF, visible_bounds: RectF, cx: &mut ViewContext<V>) {
let visible_bounds = visible_bounds.intersection(bounds).unwrap_or_default();
let hit_bounds = self.hit_bounds(visible_bounds);
if let Some(style) = self.cursor_style {
scene.push_cursor_region(CursorRegion {
cx.scene().push_cursor_region(CursorRegion {
bounds: hit_bounds,
style,
});
}
scene.push_mouse_region(
let view_id = cx.view_id();
cx.scene().push_mouse_region(
MouseRegion::from_handlers(
self.tag,
cx.view_id(),
view_id,
self.region_id,
hit_bounds,
self.handlers.clone(),
@@ -282,7 +277,6 @@ impl<V: 'static> Element<V> for MouseEventHandler<V> {
fn paint(
&mut self,
scene: &mut SceneBuilder,
bounds: RectF,
visible_bounds: RectF,
_: &mut Self::LayoutState,
@@ -290,16 +284,13 @@ impl<V: 'static> Element<V> for MouseEventHandler<V> {
cx: &mut PaintContext<V>,
) -> Self::PaintState {
if self.above {
self.child
.paint(scene, bounds.origin(), visible_bounds, view, cx);
scene.paint_layer(None, |scene| {
self.paint_regions(scene, bounds, visible_bounds, cx);
self.child.paint(bounds.origin(), visible_bounds, view, cx);
cx.paint_layer(None, |cx| {
self.paint_regions(bounds, visible_bounds, cx);
});
} else {
self.paint_regions(scene, bounds, visible_bounds, cx);
self.child
.paint(scene, bounds.origin(), visible_bounds, view, cx);
self.paint_regions(bounds, visible_bounds, cx);
self.child.paint(bounds.origin(), visible_bounds, view, cx);
}
}
+18 -21
View File
@@ -3,8 +3,8 @@ use std::ops::Range;
use crate::{
geometry::{rect::RectF, vector::Vector2F},
json::ToJson,
AnyElement, Axis, Element, LayoutContext, MouseRegion, PaintContext, SceneBuilder,
SizeConstraint, ViewContext,
AnyElement, Axis, Element, LayoutContext, MouseRegion, PaintContext, SizeConstraint,
ViewContext,
};
use serde_json::json;
@@ -138,7 +138,6 @@ impl<V: 'static> Element<V> for Overlay<V> {
fn paint(
&mut self,
scene: &mut SceneBuilder,
bounds: RectF,
_: RectF,
size: &mut Self::LayoutState,
@@ -213,25 +212,23 @@ impl<V: 'static> Element<V> for Overlay<V> {
OverlayFitMode::None => {}
}
scene.paint_stacking_context(None, self.z_index, |scene| {
if self.hoverable {
enum OverlayHoverCapture {}
// Block hovers in lower stacking contexts
scene.push_mouse_region(MouseRegion::new::<OverlayHoverCapture>(
cx.view_id(),
cx.view_id(),
bounds,
cx.scene().push_stacking_context(None, self.z_index);
if self.hoverable {
enum OverlayHoverCapture {}
// Block hovers in lower stacking contexts
let view_id = cx.view_id();
cx.scene()
.push_mouse_region(MouseRegion::new::<OverlayHoverCapture>(
view_id, view_id, bounds,
));
}
self.child.paint(
scene,
bounds.origin(),
RectF::new(Vector2F::zero(), cx.window_size()),
view,
cx,
);
});
}
self.child.paint(
bounds.origin(),
RectF::new(Vector2F::zero(), cx.window_size()),
view,
cx,
);
cx.scene().pop_stacking_context();
}
fn rect_for_text_range(
+54 -57
View File
@@ -7,7 +7,7 @@ use serde_json::json;
use crate::{
geometry::rect::RectF,
platform::{CursorStyle, MouseButton},
AnyElement, AppContext, Axis, Element, LayoutContext, MouseRegion, PaintContext, SceneBuilder,
AnyElement, AppContext, Axis, Element, LayoutContext, MouseRegion, PaintContext,
SizeConstraint, TypeTag, View, ViewContext,
};
@@ -112,70 +112,70 @@ impl<V: 'static> Element<V> for Resizable<V> {
fn paint(
&mut self,
scene: &mut SceneBuilder,
bounds: pathfinder_geometry::rect::RectF,
visible_bounds: pathfinder_geometry::rect::RectF,
constraint: &mut SizeConstraint,
view: &mut V,
cx: &mut PaintContext<V>,
) -> Self::PaintState {
scene.push_stacking_context(None, None);
cx.scene().push_stacking_context(None, None);
let handle_region = self.handle_side.of_rect(bounds, self.handle_size);
enum ResizeHandle {}
scene.push_mouse_region(
MouseRegion::new::<ResizeHandle>(
cx.view_id(),
self.handle_side as usize,
handle_region,
)
.on_down(MouseButton::Left, |_, _: &mut V, _| {}) // This prevents the mouse down event from being propagated elsewhere
.on_click(MouseButton::Left, {
let on_resize = self.on_resize.clone();
move |click, v, cx| {
if click.click_count == 2 {
on_resize.borrow_mut()(v, None, cx);
let view_id = cx.view_id();
cx.scene().push_mouse_region(
MouseRegion::new::<ResizeHandle>(view_id, self.handle_side as usize, handle_region)
.on_down(MouseButton::Left, |_, _: &mut V, _| {}) // This prevents the mouse down event from being propagated elsewhere
.on_click(MouseButton::Left, {
let on_resize = self.on_resize.clone();
move |click, v, cx| {
if click.click_count == 2 {
on_resize.borrow_mut()(v, None, cx);
}
}
}
})
.on_drag(MouseButton::Left, {
let bounds = bounds.clone();
let side = self.handle_side;
let prev_size = side.relevant_component(bounds.size());
let min_size = side.relevant_component(constraint.min);
let max_size = side.relevant_component(constraint.max);
let on_resize = self.on_resize.clone();
let tag = self.tag;
move |event, view: &mut V, cx| {
if event.end {
return;
})
.on_drag(MouseButton::Left, {
let bounds = bounds.clone();
let side = self.handle_side;
let prev_size = side.relevant_component(bounds.size());
let min_size = side.relevant_component(constraint.min);
let max_size = side.relevant_component(constraint.max);
let on_resize = self.on_resize.clone();
let tag = self.tag;
move |event, view: &mut V, cx| {
if event.end {
return;
}
let Some((bounds, _)) = get_bounds(tag, cx) else {
return;
};
let new_size_raw = match side {
// Handle on top side of element => Element is on bottom
HandleSide::Top => {
bounds.height() + bounds.origin_y() - event.position.y()
}
// Handle on right side of element => Element is on left
HandleSide::Right => event.position.x() - bounds.lower_left().x(),
// Handle on left side of element => Element is on the right
HandleSide::Left => {
bounds.width() + bounds.origin_x() - event.position.x()
}
// Handle on bottom side of element => Element is on the top
HandleSide::Bottom => event.position.y() - bounds.lower_left().y(),
};
let new_size = min_size.max(new_size_raw).min(max_size).round();
if new_size != prev_size {
on_resize.borrow_mut()(view, Some(new_size), cx);
}
}
let Some((bounds, _)) = get_bounds(tag, cx) else {
return;
};
let new_size_raw = match side {
// Handle on top side of element => Element is on bottom
HandleSide::Top => bounds.height() + bounds.origin_y() - event.position.y(),
// Handle on right side of element => Element is on left
HandleSide::Right => event.position.x() - bounds.lower_left().x(),
// Handle on left side of element => Element is on the right
HandleSide::Left => bounds.width() + bounds.origin_x() - event.position.x(),
// Handle on bottom side of element => Element is on the top
HandleSide::Bottom => event.position.y() - bounds.lower_left().y(),
};
let new_size = min_size.max(new_size_raw).min(max_size).round();
if new_size != prev_size {
on_resize.borrow_mut()(view, Some(new_size), cx);
}
}
}),
}),
);
scene.push_cursor_region(crate::CursorRegion {
cx.scene().push_cursor_region(crate::CursorRegion {
bounds: handle_region,
style: match self.handle_side.axis() {
Axis::Horizontal => CursorStyle::ResizeLeftRight,
@@ -183,10 +183,9 @@ impl<V: 'static> Element<V> for Resizable<V> {
},
});
scene.pop_stacking_context();
cx.scene().pop_stacking_context();
self.child
.paint(scene, bounds.origin(), visible_bounds, view, cx);
self.child.paint(bounds.origin(), visible_bounds, view, cx);
}
fn rect_for_text_range(
@@ -249,7 +248,6 @@ impl<V: View, P: 'static> Element<V> for BoundsProvider<V, P> {
fn paint(
&mut self,
scene: &mut crate::SceneBuilder,
bounds: pathfinder_geometry::rect::RectF,
visible_bounds: pathfinder_geometry::rect::RectF,
_: &mut Self::LayoutState,
@@ -260,8 +258,7 @@ impl<V: View, P: 'static> Element<V> for BoundsProvider<V, P> {
map.0.insert(TypeTag::new::<P>(), (bounds, visible_bounds));
});
self.child
.paint(scene, bounds.origin(), visible_bounds, view, cx)
self.child.paint(bounds.origin(), visible_bounds, view, cx)
}
fn rect_for_text_range(
+4 -5
View File
@@ -3,7 +3,7 @@ use std::ops::Range;
use crate::{
geometry::{rect::RectF, vector::Vector2F},
json::{self, json, ToJson},
AnyElement, Element, LayoutContext, PaintContext, SceneBuilder, SizeConstraint, ViewContext,
AnyElement, Element, LayoutContext, PaintContext, SizeConstraint, ViewContext,
};
/// Element which renders it's children in a stack on top of each other.
@@ -52,7 +52,6 @@ impl<V: 'static> Element<V> for Stack<V> {
fn paint(
&mut self,
scene: &mut SceneBuilder,
bounds: RectF,
visible_bounds: RectF,
_: &mut Self::LayoutState,
@@ -60,9 +59,9 @@ impl<V: 'static> Element<V> for Stack<V> {
cx: &mut PaintContext<V>,
) -> Self::PaintState {
for child in &mut self.children {
scene.paint_layer(None, |scene| {
child.paint(scene, bounds.origin(), visible_bounds, view, cx);
});
cx.scene().push_layer(None);
child.paint(bounds.origin(), visible_bounds, view, cx);
cx.scene().pop_layer();
}
}
+3 -4
View File
@@ -7,7 +7,7 @@ use crate::{
rect::RectF,
vector::{vec2f, Vector2F},
},
scene, Element, LayoutContext, SceneBuilder, SizeConstraint, ViewContext,
scene, Element, LayoutContext, SizeConstraint, ViewContext,
};
use schemars::JsonSchema;
use serde_derive::Deserialize;
@@ -69,15 +69,14 @@ impl<V: 'static> Element<V> for Svg {
fn paint(
&mut self,
scene: &mut SceneBuilder,
bounds: RectF,
_visible_bounds: RectF,
svg: &mut Self::LayoutState,
_: &mut V,
_: &mut PaintContext<V>,
cx: &mut PaintContext<V>,
) {
if let Some(svg) = svg.clone() {
scene.push_icon(scene::Icon {
cx.scene().push_icon(scene::Icon {
bounds,
svg,
path: self.path.clone(),
+9 -11
View File
@@ -7,8 +7,8 @@ use crate::{
},
json::{ToJson, Value},
text_layout::{Line, RunStyle, ShapedBoundary},
AppContext, Element, FontCache, LayoutContext, PaintContext, SceneBuilder, SizeConstraint,
TextLayoutCache, ViewContext,
Element, FontCache, LayoutContext, PaintContext, SizeConstraint, TextLayoutCache, ViewContext,
WindowContext,
};
use log::warn;
use serde_json::json;
@@ -21,7 +21,7 @@ pub struct Text {
highlights: Option<Box<[(Range<usize>, HighlightStyle)]>>,
custom_runs: Option<(
Box<[Range<usize>]>,
Box<dyn FnMut(usize, RectF, &mut SceneBuilder, &mut AppContext)>,
Box<dyn FnMut(usize, RectF, &mut WindowContext)>,
)>,
}
@@ -58,7 +58,7 @@ impl Text {
pub fn with_custom_runs(
mut self,
runs: impl Into<Box<[Range<usize>]>>,
callback: impl 'static + FnMut(usize, RectF, &mut SceneBuilder, &mut AppContext),
callback: impl 'static + FnMut(usize, RectF, &mut WindowContext),
) -> Self {
self.custom_runs = Some((runs.into(), Box::new(callback)));
self
@@ -166,7 +166,6 @@ impl<V: 'static> Element<V> for Text {
fn paint(
&mut self,
scene: &mut SceneBuilder,
bounds: RectF,
visible_bounds: RectF,
layout: &mut Self::LayoutState,
@@ -175,7 +174,7 @@ impl<V: 'static> Element<V> for Text {
) -> Self::PaintState {
let mut origin = bounds.origin();
let empty = Vec::new();
let mut callback = |_, _, _: &mut SceneBuilder, _: &mut AppContext| {};
let mut callback = |_, _, _: &mut WindowContext| {};
let mouse_runs;
let custom_run_callback;
@@ -202,7 +201,6 @@ impl<V: 'static> Element<V> for Text {
if boundaries.intersects(visible_bounds) {
if self.soft_wrap {
line.paint_wrapped(
scene,
origin,
visible_bounds,
layout.line_height,
@@ -210,7 +208,7 @@ impl<V: 'static> Element<V> for Text {
cx,
);
} else {
line.paint(scene, origin, visible_bounds, layout.line_height, cx);
line.paint(origin, visible_bounds, layout.line_height, cx);
}
}
@@ -248,7 +246,7 @@ impl<V: 'static> Element<V> for Text {
*run_origin,
glyph_origin + vec2f(0., layout.line_height),
);
custom_run_callback(*run_ix, bounds, scene, cx);
custom_run_callback(*run_ix, bounds, cx);
*run_origin =
vec2f(origin.x(), glyph_origin.y() + layout.line_height);
}
@@ -264,7 +262,7 @@ impl<V: 'static> Element<V> for Text {
run_origin,
glyph_origin + vec2f(0., layout.line_height),
);
custom_run_callback(run_ix, bounds, scene, cx);
custom_run_callback(run_ix, bounds, cx);
custom_runs.next();
}
@@ -294,7 +292,7 @@ impl<V: 'static> Element<V> for Text {
run_origin,
line_end + vec2f(0., layout.line_height),
);
custom_run_callback(run_ix, bounds, scene, cx);
custom_run_callback(run_ix, bounds, cx);
if end_offset == run_end_offset {
custom_runs.next();
}
+4 -6
View File
@@ -6,8 +6,8 @@ use crate::{
fonts::TextStyle,
geometry::{rect::RectF, vector::Vector2F},
json::json,
Action, Axis, ElementStateHandle, LayoutContext, PaintContext, SceneBuilder, SizeConstraint,
Task, TypeTag, ViewContext,
Action, Axis, ElementStateHandle, LayoutContext, PaintContext, SizeConstraint, Task, TypeTag,
ViewContext,
};
use schemars::JsonSchema;
use serde::Deserialize;
@@ -204,17 +204,15 @@ impl<V: 'static> Element<V> for Tooltip<V> {
fn paint(
&mut self,
scene: &mut SceneBuilder,
bounds: RectF,
visible_bounds: RectF,
_: &mut Self::LayoutState,
view: &mut V,
cx: &mut PaintContext<V>,
) {
self.child
.paint(scene, bounds.origin(), visible_bounds, view, cx);
self.child.paint(bounds.origin(), visible_bounds, view, cx);
if let Some(tooltip) = self.tooltip.as_mut() {
tooltip.paint(scene, bounds.origin(), visible_bounds, view, cx);
tooltip.paint(bounds.origin(), visible_bounds, view, cx);
}
}
+5 -6
View File
@@ -6,7 +6,7 @@ use crate::{
},
json::{self, json},
platform::ScrollWheelEvent,
AnyElement, LayoutContext, MouseRegion, PaintContext, SceneBuilder, ViewContext,
AnyElement, LayoutContext, MouseRegion, PaintContext, ViewContext,
};
use json::ToJson;
use std::{cell::RefCell, cmp, ops::Range, rc::Rc};
@@ -272,7 +272,6 @@ impl<V: 'static> Element<V> for UniformList<V> {
fn paint(
&mut self,
scene: &mut SceneBuilder,
bounds: RectF,
visible_bounds: RectF,
layout: &mut Self::LayoutState,
@@ -281,9 +280,9 @@ impl<V: 'static> Element<V> for UniformList<V> {
) -> Self::PaintState {
let visible_bounds = visible_bounds.intersection(bounds).unwrap_or_default();
scene.push_layer(Some(visible_bounds));
cx.scene().push_layer(Some(visible_bounds));
scene.push_mouse_region(
cx.scene().push_mouse_region(
MouseRegion::new::<Self>(self.view_id, 0, visible_bounds).on_scroll({
let scroll_max = layout.scroll_max;
let state = self.state.clone();
@@ -312,11 +311,11 @@ impl<V: 'static> Element<V> for UniformList<V> {
);
for item in &mut layout.items {
item.paint(scene, item_origin, visible_bounds, view, cx);
item.paint(item_origin, visible_bounds, view, cx);
item_origin += vec2f(0.0, layout.item_height);
}
scene.pop_layer();
cx.scene().pop_layer();
}
fn rect_for_text_range(