Checkpoint
This commit is contained in:
@@ -28,6 +28,7 @@ use collections::{hash_map::Entry, BTreeMap, HashMap, HashSet, VecDeque};
|
||||
use derive_more::Deref;
|
||||
pub use menu::*;
|
||||
use parking_lot::Mutex;
|
||||
use pathfinder_geometry::rect::RectF;
|
||||
use platform::Event;
|
||||
use postage::oneshot;
|
||||
#[cfg(any(test, feature = "test-support"))]
|
||||
@@ -3571,6 +3572,16 @@ impl<'a, 'b, 'c, V> PaintContext<'a, 'b, 'c, V> {
|
||||
pub fn new(view_context: &'c mut ViewContext<'a, 'b, V>) -> Self {
|
||||
Self { view_context }
|
||||
}
|
||||
|
||||
pub fn paint_layer<F, R>(&mut self, clip_bounds: Option<RectF>, f: F) -> R
|
||||
where
|
||||
F: FnOnce(&mut Self) -> R,
|
||||
{
|
||||
self.scene().push_layer(clip_bounds);
|
||||
let result = f(self);
|
||||
self.scene().pop_layer();
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b, 'c, V> Deref for PaintContext<'a, 'b, 'c, V> {
|
||||
|
||||
@@ -55,6 +55,7 @@ pub struct Window {
|
||||
pub(crate) invalidation: Option<WindowInvalidation>,
|
||||
pub(crate) platform_window: Box<dyn platform::Window>,
|
||||
pub(crate) rendered_views: HashMap<usize, Box<dyn AnyRootElement>>,
|
||||
scene: SceneBuilder,
|
||||
pub(crate) text_style_stack: Vec<TextStyle>,
|
||||
pub(crate) theme_stack: Vec<Box<dyn Any>>,
|
||||
pub(crate) new_parents: HashMap<usize, usize>,
|
||||
@@ -98,6 +99,7 @@ impl Window {
|
||||
inspector_enabled: false,
|
||||
platform_window,
|
||||
rendered_views: Default::default(),
|
||||
scene: SceneBuilder::new(),
|
||||
text_style_stack: Vec::new(),
|
||||
theme_stack: Vec::new(),
|
||||
new_parents: HashMap::default(),
|
||||
@@ -241,6 +243,10 @@ impl<'a> WindowContext<'a> {
|
||||
.push_back(Effect::RepaintWindow { window });
|
||||
}
|
||||
|
||||
pub fn scene(&mut self) -> &mut SceneBuilder {
|
||||
&mut self.window.scene
|
||||
}
|
||||
|
||||
pub fn enable_inspector(&mut self) {
|
||||
self.window.inspector_enabled = true;
|
||||
}
|
||||
@@ -1080,9 +1086,7 @@ impl<'a> WindowContext<'a> {
|
||||
let root_view_id = self.window.root_view().id();
|
||||
let mut rendered_root = self.window.rendered_views.remove(&root_view_id).unwrap();
|
||||
|
||||
let mut scene_builder = SceneBuilder::new(scale_factor);
|
||||
rendered_root.paint(
|
||||
&mut scene_builder,
|
||||
Vector2F::zero(),
|
||||
RectF::from_points(Vector2F::zero(), window_size),
|
||||
self,
|
||||
@@ -1092,7 +1096,7 @@ impl<'a> WindowContext<'a> {
|
||||
.insert(root_view_id, rendered_root);
|
||||
|
||||
self.window.text_layout_cache.finish_frame();
|
||||
let mut scene = scene_builder.build();
|
||||
let mut scene = self.window.scene.build(scale_factor);
|
||||
self.window.cursor_regions = scene.cursor_regions();
|
||||
self.window.mouse_regions = scene.mouse_regions();
|
||||
self.window.event_handlers = scene.take_event_handlers();
|
||||
@@ -1696,7 +1700,6 @@ impl<V: 'static> Element<V> for ChildView {
|
||||
|
||||
fn paint(
|
||||
&mut self,
|
||||
scene: &mut SceneBuilder,
|
||||
bounds: RectF,
|
||||
visible_bounds: RectF,
|
||||
_: &mut Self::LayoutState,
|
||||
@@ -1705,7 +1708,7 @@ impl<V: 'static> Element<V> for ChildView {
|
||||
) {
|
||||
if let Some(mut rendered_view) = cx.window.rendered_views.remove(&self.view_id) {
|
||||
rendered_view
|
||||
.paint(scene, bounds.origin(), visible_bounds, cx)
|
||||
.paint(bounds.origin(), visible_bounds, cx)
|
||||
.log_err();
|
||||
cx.window.rendered_views.insert(self.view_id, rendered_view);
|
||||
} else {
|
||||
|
||||
@@ -34,8 +34,8 @@ use crate::{
|
||||
rect::RectF,
|
||||
vector::{vec2f, Vector2F},
|
||||
},
|
||||
json, Action, Entity, LayoutContext, PaintContext, SceneBuilder, SizeConstraint, TypeTag, View,
|
||||
ViewContext, WeakViewHandle, WindowContext,
|
||||
json, Action, Entity, LayoutContext, PaintContext, SizeConstraint, TypeTag, View, ViewContext,
|
||||
WeakViewHandle, WindowContext,
|
||||
};
|
||||
use anyhow::{anyhow, Result};
|
||||
use core::panic;
|
||||
@@ -64,7 +64,6 @@ pub trait Element<V: 'static>: 'static {
|
||||
|
||||
fn paint(
|
||||
&mut self,
|
||||
scene: &mut SceneBuilder,
|
||||
bounds: RectF,
|
||||
visible_bounds: RectF,
|
||||
layout: &mut Self::LayoutState,
|
||||
@@ -265,7 +264,6 @@ trait AnyElementState<V> {
|
||||
|
||||
fn paint(
|
||||
&mut self,
|
||||
scene: &mut SceneBuilder,
|
||||
origin: Vector2F,
|
||||
visible_bounds: RectF,
|
||||
view: &mut V,
|
||||
@@ -346,7 +344,6 @@ impl<V, E: Element<V>> AnyElementState<V> for ElementState<V, E> {
|
||||
|
||||
fn paint(
|
||||
&mut self,
|
||||
scene: &mut SceneBuilder,
|
||||
origin: Vector2F,
|
||||
visible_bounds: RectF,
|
||||
view: &mut V,
|
||||
@@ -361,7 +358,6 @@ impl<V, E: Element<V>> AnyElementState<V> for ElementState<V, E> {
|
||||
} => {
|
||||
let bounds = RectF::new(origin, size);
|
||||
let paint = element.paint(
|
||||
scene,
|
||||
bounds,
|
||||
visible_bounds,
|
||||
&mut layout,
|
||||
@@ -386,7 +382,6 @@ impl<V, E: Element<V>> AnyElementState<V> for ElementState<V, E> {
|
||||
} => {
|
||||
let bounds = RectF::new(origin, bounds.size());
|
||||
let paint = element.paint(
|
||||
scene,
|
||||
bounds,
|
||||
visible_bounds,
|
||||
&mut layout,
|
||||
@@ -522,13 +517,12 @@ impl<V> AnyElement<V> {
|
||||
|
||||
pub fn paint(
|
||||
&mut self,
|
||||
scene: &mut SceneBuilder,
|
||||
origin: Vector2F,
|
||||
visible_bounds: RectF,
|
||||
view: &mut V,
|
||||
cx: &mut PaintContext<V>,
|
||||
) {
|
||||
self.state.paint(scene, origin, visible_bounds, view, cx);
|
||||
self.state.paint(origin, visible_bounds, view, cx);
|
||||
}
|
||||
|
||||
pub fn rect_for_text_range(
|
||||
@@ -584,14 +578,13 @@ impl<V: 'static> Element<V> for AnyElement<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.paint(scene, bounds.origin(), visible_bounds, view, cx);
|
||||
self.paint(bounds.origin(), visible_bounds, view, cx);
|
||||
}
|
||||
|
||||
fn rect_for_text_range(
|
||||
@@ -647,7 +640,6 @@ pub trait AnyRootElement {
|
||||
fn layout(&mut self, constraint: SizeConstraint, cx: &mut WindowContext) -> Result<Vector2F>;
|
||||
fn paint(
|
||||
&mut self,
|
||||
scene: &mut SceneBuilder,
|
||||
origin: Vector2F,
|
||||
visible_bounds: RectF,
|
||||
cx: &mut WindowContext,
|
||||
@@ -675,7 +667,6 @@ impl<V: View> AnyRootElement for RootElement<V> {
|
||||
|
||||
fn paint(
|
||||
&mut self,
|
||||
scene: &mut SceneBuilder,
|
||||
origin: Vector2F,
|
||||
visible_bounds: RectF,
|
||||
cx: &mut WindowContext,
|
||||
@@ -687,8 +678,7 @@ impl<V: View> AnyRootElement for RootElement<V> {
|
||||
|
||||
view.update(cx, |view, cx| {
|
||||
let mut cx = PaintContext::new(cx);
|
||||
self.element
|
||||
.paint(scene, origin, visible_bounds, view, &mut cx);
|
||||
self.element.paint(origin, visible_bounds, view, &mut cx);
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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,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(
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,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(
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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,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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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(
|
||||
|
||||
+26
-41
@@ -26,7 +26,6 @@ pub use mouse_event::*;
|
||||
pub use mouse_region::*;
|
||||
|
||||
pub struct SceneBuilder {
|
||||
scale_factor: f32,
|
||||
stacking_contexts: Vec<StackingContext>,
|
||||
active_stacking_context_stack: Vec<usize>,
|
||||
/// Used by the gpui2 crate.
|
||||
@@ -245,45 +244,40 @@ impl Scene {
|
||||
}
|
||||
|
||||
impl SceneBuilder {
|
||||
pub fn new(scale_factor: f32) -> Self {
|
||||
let stacking_context = StackingContext::new(None, 0);
|
||||
SceneBuilder {
|
||||
scale_factor,
|
||||
stacking_contexts: vec![stacking_context],
|
||||
active_stacking_context_stack: vec![0],
|
||||
pub fn new() -> Self {
|
||||
let mut this = SceneBuilder {
|
||||
stacking_contexts: Vec::new(),
|
||||
active_stacking_context_stack: Vec::new(),
|
||||
#[cfg(debug_assertions)]
|
||||
mouse_region_ids: Default::default(),
|
||||
mouse_region_ids: HashSet::default(),
|
||||
event_handlers: Vec::new(),
|
||||
}
|
||||
};
|
||||
this.clear();
|
||||
this
|
||||
}
|
||||
|
||||
pub fn build(mut self) -> Scene {
|
||||
self.stacking_contexts
|
||||
.sort_by_key(|context| context.z_index);
|
||||
pub fn clear(&mut self) {
|
||||
self.stacking_contexts.clear();
|
||||
self.stacking_contexts.push(StackingContext::new(None, 0));
|
||||
self.active_stacking_context_stack.clear();
|
||||
self.active_stacking_context_stack.push(0);
|
||||
#[cfg(debug_assertions)]
|
||||
self.mouse_region_ids.clear();
|
||||
}
|
||||
|
||||
pub fn build(&mut self, scale_factor: f32) -> Scene {
|
||||
let mut stacking_contexts = std::mem::take(&mut self.stacking_contexts);
|
||||
stacking_contexts.sort_by_key(|context| context.z_index);
|
||||
let event_handlers = std::mem::take(&mut self.event_handlers);
|
||||
self.clear();
|
||||
|
||||
Scene {
|
||||
scale_factor: self.scale_factor,
|
||||
stacking_contexts: self.stacking_contexts,
|
||||
event_handlers: self.event_handlers,
|
||||
scale_factor,
|
||||
stacking_contexts,
|
||||
event_handlers,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn scale_factor(&self) -> f32 {
|
||||
self.scale_factor
|
||||
}
|
||||
|
||||
pub fn paint_stacking_context<F>(
|
||||
&mut self,
|
||||
clip_bounds: Option<RectF>,
|
||||
z_index: Option<usize>,
|
||||
f: F,
|
||||
) where
|
||||
F: FnOnce(&mut Self),
|
||||
{
|
||||
self.push_stacking_context(clip_bounds, z_index);
|
||||
f(self);
|
||||
self.pop_stacking_context();
|
||||
}
|
||||
|
||||
pub fn push_stacking_context(&mut self, clip_bounds: Option<RectF>, z_index: Option<usize>) {
|
||||
let z_index = z_index.unwrap_or_else(|| self.active_stacking_context().z_index + 1);
|
||||
self.active_stacking_context_stack
|
||||
@@ -297,15 +291,6 @@ impl SceneBuilder {
|
||||
assert!(!self.active_stacking_context_stack.is_empty());
|
||||
}
|
||||
|
||||
pub fn paint_layer<F>(&mut self, clip_bounds: Option<RectF>, f: F)
|
||||
where
|
||||
F: FnOnce(&mut Self),
|
||||
{
|
||||
self.push_layer(clip_bounds);
|
||||
f(self);
|
||||
self.pop_layer();
|
||||
}
|
||||
|
||||
pub fn push_layer(&mut self, clip_bounds: Option<RectF>) {
|
||||
self.active_stacking_context().push_layer(clip_bounds);
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ use crate::{
|
||||
platform::FontSystem,
|
||||
scene,
|
||||
window::WindowContext,
|
||||
SceneBuilder,
|
||||
};
|
||||
use ordered_float::OrderedFloat;
|
||||
use parking_lot::{Mutex, RwLock, RwLockUpgradableReadGuard};
|
||||
@@ -284,7 +283,6 @@ impl Line {
|
||||
|
||||
pub fn paint(
|
||||
&self,
|
||||
scene: &mut SceneBuilder,
|
||||
origin: Vector2F,
|
||||
visible_bounds: RectF,
|
||||
line_height: f32,
|
||||
@@ -347,7 +345,7 @@ impl Line {
|
||||
}
|
||||
|
||||
if let Some((underline_origin, underline_style)) = finished_underline {
|
||||
scene.push_underline(scene::Underline {
|
||||
cx.scene().push_underline(scene::Underline {
|
||||
origin: underline_origin,
|
||||
width: glyph_origin.x() - underline_origin.x(),
|
||||
thickness: underline_style.thickness.into(),
|
||||
@@ -357,14 +355,14 @@ impl Line {
|
||||
}
|
||||
|
||||
if glyph.is_emoji {
|
||||
scene.push_image_glyph(scene::ImageGlyph {
|
||||
cx.scene().push_image_glyph(scene::ImageGlyph {
|
||||
font_id: run.font_id,
|
||||
font_size: self.layout.font_size,
|
||||
id: glyph.id,
|
||||
origin: glyph_origin,
|
||||
});
|
||||
} else {
|
||||
scene.push_glyph(scene::Glyph {
|
||||
cx.scene().push_glyph(scene::Glyph {
|
||||
font_id: run.font_id,
|
||||
font_size: self.layout.font_size,
|
||||
id: glyph.id,
|
||||
@@ -377,7 +375,7 @@ impl Line {
|
||||
|
||||
if let Some((underline_start, underline_style)) = underline.take() {
|
||||
let line_end_x = origin.x() + self.layout.width;
|
||||
scene.push_underline(scene::Underline {
|
||||
cx.scene().push_underline(scene::Underline {
|
||||
origin: underline_start,
|
||||
width: line_end_x - underline_start.x(),
|
||||
color: underline_style.color.unwrap(),
|
||||
@@ -389,7 +387,6 @@ impl Line {
|
||||
|
||||
pub fn paint_wrapped(
|
||||
&self,
|
||||
scene: &mut SceneBuilder,
|
||||
origin: Vector2F,
|
||||
visible_bounds: RectF,
|
||||
line_height: f32,
|
||||
@@ -417,7 +414,7 @@ impl Line {
|
||||
{
|
||||
boundaries.next();
|
||||
if let Some((underline_origin, underline_style)) = underline {
|
||||
scene.push_underline(scene::Underline {
|
||||
cx.scene().push_underline(scene::Underline {
|
||||
origin: underline_origin,
|
||||
width: glyph_origin.x() - underline_origin.x(),
|
||||
thickness: underline_style.thickness.into(),
|
||||
@@ -461,7 +458,7 @@ impl Line {
|
||||
}
|
||||
|
||||
if let Some((underline_origin, underline_style)) = finished_underline {
|
||||
scene.push_underline(scene::Underline {
|
||||
cx.scene().push_underline(scene::Underline {
|
||||
origin: underline_origin,
|
||||
width: glyph_origin.x() - underline_origin.x(),
|
||||
thickness: underline_style.thickness.into(),
|
||||
@@ -477,14 +474,14 @@ impl Line {
|
||||
);
|
||||
if glyph_bounds.intersects(visible_bounds) {
|
||||
if glyph.is_emoji {
|
||||
scene.push_image_glyph(scene::ImageGlyph {
|
||||
cx.scene().push_image_glyph(scene::ImageGlyph {
|
||||
font_id: run.font_id,
|
||||
font_size: self.layout.font_size,
|
||||
id: glyph.id,
|
||||
origin: glyph_bounds.origin() + baseline_offset,
|
||||
});
|
||||
} else {
|
||||
scene.push_glyph(scene::Glyph {
|
||||
cx.scene().push_glyph(scene::Glyph {
|
||||
font_id: run.font_id,
|
||||
font_size: self.layout.font_size,
|
||||
id: glyph.id,
|
||||
@@ -498,7 +495,7 @@ impl Line {
|
||||
|
||||
if let Some((underline_origin, underline_style)) = underline.take() {
|
||||
let line_end_x = glyph_origin.x() + self.layout.width - prev_position;
|
||||
scene.push_underline(scene::Underline {
|
||||
cx.scene().push_underline(scene::Underline {
|
||||
origin: underline_origin,
|
||||
width: line_end_x - underline_origin.x(),
|
||||
thickness: underline_style.thickness.into(),
|
||||
|
||||
Reference in New Issue
Block a user