Compare commits
1 Commits
fix-git-ht
...
wet-paint
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2e72b162a4 |
@@ -60,8 +60,19 @@ pub trait Element: 'static + IntoElement {
|
||||
) -> (LayoutId, Self::State);
|
||||
|
||||
/// Once layout has been completed, this method will be called to paint the element to the screen.
|
||||
/// If `wet` is false, this is a dry run, which is used to determine which geometry will be closest
|
||||
/// to the user in the painted scene for purposes of hover state calculations. Avoid unnecessary
|
||||
/// computation in the dry phase, but be sure to push opaque layers at a Z-index that matches what
|
||||
/// you'll draw in the final scene.
|
||||
///
|
||||
/// The state argument is the same state that was returned from [`Element::request_layout()`].
|
||||
fn paint(&mut self, bounds: Bounds<Pixels>, state: &mut Self::State, cx: &mut ElementContext);
|
||||
fn paint(
|
||||
&mut self,
|
||||
bounds: Bounds<Pixels>,
|
||||
wet: bool,
|
||||
state: &mut Self::State,
|
||||
cx: &mut ElementContext,
|
||||
);
|
||||
|
||||
/// Convert this element into a dynamically-typed [`AnyElement`].
|
||||
fn into_any(self) -> AnyElement {
|
||||
@@ -108,10 +119,9 @@ pub trait IntoElement: Sized {
|
||||
phase: ElementDrawPhase::Start,
|
||||
};
|
||||
|
||||
let frame_state =
|
||||
DrawableElement::draw(element, origin, available_space.map(Into::into), cx);
|
||||
element.draw(origin, available_space.map(Into::into), cx);
|
||||
|
||||
if let Some(mut frame_state) = frame_state {
|
||||
if let Some(mut frame_state) = element.into_frame_state() {
|
||||
f(&mut frame_state, cx)
|
||||
} else {
|
||||
cx.with_element_state(element_id.unwrap(), |element_state, cx| {
|
||||
@@ -203,8 +213,14 @@ impl<C: RenderOnce> Element for Component<C> {
|
||||
(layout_id, element)
|
||||
}
|
||||
|
||||
fn paint(&mut self, _: Bounds<Pixels>, element: &mut Self::State, cx: &mut ElementContext) {
|
||||
element.paint(cx)
|
||||
fn paint(
|
||||
&mut self,
|
||||
_: Bounds<Pixels>,
|
||||
wet: bool,
|
||||
element: &mut Self::State,
|
||||
cx: &mut ElementContext,
|
||||
) {
|
||||
element.paint(wet, cx)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -229,7 +245,7 @@ trait ElementObject {
|
||||
|
||||
fn request_layout(&mut self, cx: &mut ElementContext) -> LayoutId;
|
||||
|
||||
fn paint(&mut self, cx: &mut ElementContext);
|
||||
fn paint(&mut self, wet: bool, cx: &mut ElementContext);
|
||||
|
||||
fn measure(
|
||||
&mut self,
|
||||
@@ -301,7 +317,7 @@ impl<E: Element> DrawableElement<E> {
|
||||
layout_id
|
||||
}
|
||||
|
||||
fn paint(mut self, cx: &mut ElementContext) -> Option<E::State> {
|
||||
fn paint(&mut self, wet: bool, cx: &mut ElementContext) {
|
||||
match self.phase {
|
||||
ElementDrawPhase::LayoutRequested {
|
||||
layout_id,
|
||||
@@ -315,11 +331,8 @@ impl<E: Element> DrawableElement<E> {
|
||||
let bounds = cx.layout_bounds(layout_id);
|
||||
|
||||
if let Some(mut frame_state) = frame_state {
|
||||
self.element
|
||||
.take()
|
||||
.unwrap()
|
||||
.paint(bounds, &mut frame_state, cx);
|
||||
Some(frame_state)
|
||||
let mut element = self.element.as_mut().unwrap();
|
||||
element.paint(bounds, wet, &mut frame_state, cx);
|
||||
} else {
|
||||
let element_id = self
|
||||
.element
|
||||
@@ -329,13 +342,10 @@ impl<E: Element> DrawableElement<E> {
|
||||
.expect("if we don't have frame state, we should have element state");
|
||||
cx.with_element_state(element_id, |element_state, cx| {
|
||||
let mut element_state = element_state.unwrap();
|
||||
self.element
|
||||
.take()
|
||||
.unwrap()
|
||||
.paint(bounds, &mut element_state, cx);
|
||||
let mut element = self.element.as_mut().unwrap();
|
||||
element.paint(bounds, wet, &mut element_state, cx);
|
||||
((), element_state)
|
||||
});
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
@@ -343,6 +353,14 @@ impl<E: Element> DrawableElement<E> {
|
||||
}
|
||||
}
|
||||
|
||||
fn into_frame_state(self) -> Option<E::State> {
|
||||
match self.phase {
|
||||
ElementDrawPhase::Start => None,
|
||||
ElementDrawPhase::LayoutRequested { frame_state, .. }
|
||||
| ElementDrawPhase::LayoutComputed { frame_state, .. } => frame_state,
|
||||
}
|
||||
}
|
||||
|
||||
fn measure(
|
||||
&mut self,
|
||||
available_space: Size<AvailableSpace>,
|
||||
@@ -384,13 +402,16 @@ impl<E: Element> DrawableElement<E> {
|
||||
}
|
||||
|
||||
fn draw(
|
||||
mut self,
|
||||
&mut self,
|
||||
origin: Point<Pixels>,
|
||||
available_space: Size<AvailableSpace>,
|
||||
cx: &mut ElementContext,
|
||||
) -> Option<E::State> {
|
||||
) {
|
||||
self.measure(available_space, cx);
|
||||
cx.with_absolute_element_offset(origin, |cx| self.paint(cx))
|
||||
cx.with_absolute_element_offset(origin, |cx| {
|
||||
self.paint(false, cx);
|
||||
self.paint(true, cx);
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -407,8 +428,8 @@ where
|
||||
DrawableElement::request_layout(self.as_mut().unwrap(), cx)
|
||||
}
|
||||
|
||||
fn paint(&mut self, cx: &mut ElementContext) {
|
||||
DrawableElement::paint(self.take().unwrap(), cx);
|
||||
fn paint(&mut self, wet: bool, cx: &mut ElementContext) {
|
||||
DrawableElement::paint(self.as_mut().unwrap(), wet, cx);
|
||||
}
|
||||
|
||||
fn measure(
|
||||
@@ -425,7 +446,7 @@ where
|
||||
available_space: Size<AvailableSpace>,
|
||||
cx: &mut ElementContext,
|
||||
) {
|
||||
DrawableElement::draw(self.take().unwrap(), origin, available_space, cx);
|
||||
DrawableElement::draw(self.as_mut().unwrap(), origin, available_space, cx);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -451,8 +472,8 @@ impl AnyElement {
|
||||
}
|
||||
|
||||
/// Paints the element stored in this `AnyElement`.
|
||||
pub fn paint(&mut self, cx: &mut ElementContext) {
|
||||
self.0.paint(cx)
|
||||
pub fn paint(&mut self, wet: bool, cx: &mut ElementContext) {
|
||||
self.0.paint(wet, cx)
|
||||
}
|
||||
|
||||
/// Initializes this element and performs layout within the given available space to determine its size.
|
||||
@@ -492,8 +513,14 @@ impl Element for AnyElement {
|
||||
(layout_id, ())
|
||||
}
|
||||
|
||||
fn paint(&mut self, _: Bounds<Pixels>, _: &mut Self::State, cx: &mut ElementContext) {
|
||||
self.paint(cx)
|
||||
fn paint(
|
||||
&mut self,
|
||||
_: Bounds<Pixels>,
|
||||
wet: bool,
|
||||
_: &mut Self::State,
|
||||
cx: &mut ElementContext,
|
||||
) {
|
||||
self.paint(wet, cx)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -542,6 +569,7 @@ impl Element for () {
|
||||
fn paint(
|
||||
&mut self,
|
||||
_bounds: Bounds<Pixels>,
|
||||
_wet: bool,
|
||||
_state: &mut Self::State,
|
||||
_cx: &mut ElementContext,
|
||||
) {
|
||||
|
||||
@@ -4,7 +4,9 @@ use crate::{Bounds, Element, ElementContext, IntoElement, Pixels, Style, StyleRe
|
||||
|
||||
/// Construct a canvas element with the given paint callback.
|
||||
/// Useful for adding short term custom drawing to a view.
|
||||
pub fn canvas(callback: impl 'static + FnOnce(&Bounds<Pixels>, &mut ElementContext)) -> Canvas {
|
||||
pub fn canvas(
|
||||
callback: impl 'static + FnOnce(&Bounds<Pixels>, bool, &mut ElementContext),
|
||||
) -> Canvas {
|
||||
Canvas {
|
||||
paint_callback: Some(Box::new(callback)),
|
||||
style: StyleRefinement::default(),
|
||||
@@ -14,7 +16,7 @@ pub fn canvas(callback: impl 'static + FnOnce(&Bounds<Pixels>, &mut ElementConte
|
||||
/// A canvas element, meant for accessing the low level paint API without defining a whole
|
||||
/// custom element
|
||||
pub struct Canvas {
|
||||
paint_callback: Option<Box<dyn FnOnce(&Bounds<Pixels>, &mut ElementContext)>>,
|
||||
paint_callback: Option<Box<dyn FnOnce(&Bounds<Pixels>, bool, &mut ElementContext)>>,
|
||||
style: StyleRefinement,
|
||||
}
|
||||
|
||||
@@ -44,9 +46,15 @@ impl Element for Canvas {
|
||||
(layout_id, style)
|
||||
}
|
||||
|
||||
fn paint(&mut self, bounds: Bounds<Pixels>, style: &mut Style, cx: &mut ElementContext) {
|
||||
fn paint(
|
||||
&mut self,
|
||||
bounds: Bounds<Pixels>,
|
||||
wet: bool,
|
||||
style: &mut Style,
|
||||
cx: &mut ElementContext,
|
||||
) {
|
||||
style.paint(bounds, cx, |cx| {
|
||||
(self.paint_callback.take().unwrap())(&bounds, cx)
|
||||
(self.paint_callback.take().unwrap())(&bounds, wet, cx)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1084,6 +1084,7 @@ impl Element for Div {
|
||||
fn paint(
|
||||
&mut self,
|
||||
bounds: Bounds<Pixels>,
|
||||
wet: bool,
|
||||
element_state: &mut Self::State,
|
||||
cx: &mut ElementContext,
|
||||
) {
|
||||
@@ -1128,7 +1129,7 @@ impl Element for Div {
|
||||
|_style, scroll_offset, cx| {
|
||||
cx.with_element_offset(scroll_offset, |cx| {
|
||||
for child in &mut self.children {
|
||||
child.paint(cx);
|
||||
child.paint(wet, cx);
|
||||
}
|
||||
})
|
||||
},
|
||||
@@ -2136,8 +2137,14 @@ where
|
||||
self.element.request_layout(state, cx)
|
||||
}
|
||||
|
||||
fn paint(&mut self, bounds: Bounds<Pixels>, state: &mut Self::State, cx: &mut ElementContext) {
|
||||
self.element.paint(bounds, state, cx)
|
||||
fn paint(
|
||||
&mut self,
|
||||
bounds: Bounds<Pixels>,
|
||||
wet: bool,
|
||||
state: &mut Self::State,
|
||||
cx: &mut ElementContext,
|
||||
) {
|
||||
self.element.paint(bounds, wet, state, cx)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2211,8 +2218,14 @@ where
|
||||
self.element.request_layout(state, cx)
|
||||
}
|
||||
|
||||
fn paint(&mut self, bounds: Bounds<Pixels>, state: &mut Self::State, cx: &mut ElementContext) {
|
||||
self.element.paint(bounds, state, cx)
|
||||
fn paint(
|
||||
&mut self,
|
||||
bounds: Bounds<Pixels>,
|
||||
wet: bool,
|
||||
state: &mut Self::State,
|
||||
cx: &mut ElementContext,
|
||||
) {
|
||||
self.element.paint(bounds, wet, state, cx)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -102,6 +102,7 @@ impl Element for Img {
|
||||
fn paint(
|
||||
&mut self,
|
||||
bounds: Bounds<Pixels>,
|
||||
wet: bool,
|
||||
element_state: &mut Self::State,
|
||||
cx: &mut ElementContext,
|
||||
) {
|
||||
|
||||
@@ -372,6 +372,7 @@ impl Element for List {
|
||||
fn paint(
|
||||
&mut self,
|
||||
bounds: Bounds<crate::Pixels>,
|
||||
wet: bool,
|
||||
_state: &mut Self::State,
|
||||
cx: &mut crate::ElementContext,
|
||||
) {
|
||||
|
||||
@@ -96,6 +96,7 @@ impl Element for Overlay {
|
||||
fn paint(
|
||||
&mut self,
|
||||
bounds: crate::Bounds<crate::Pixels>,
|
||||
wet: bool,
|
||||
element_state: &mut Self::State,
|
||||
cx: &mut ElementContext,
|
||||
) {
|
||||
@@ -170,7 +171,7 @@ impl Element for Overlay {
|
||||
cx.with_absolute_element_offset(offset, |cx| {
|
||||
cx.break_content_mask(|cx| {
|
||||
for child in &mut self.children {
|
||||
child.paint(cx);
|
||||
child.paint(wet, cx);
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
@@ -42,6 +42,7 @@ impl Element for Svg {
|
||||
fn paint(
|
||||
&mut self,
|
||||
bounds: Bounds<Pixels>,
|
||||
wet: bool,
|
||||
element_state: &mut Self::State,
|
||||
cx: &mut ElementContext,
|
||||
) where
|
||||
|
||||
@@ -29,7 +29,13 @@ impl Element for &'static str {
|
||||
(layout_id, state)
|
||||
}
|
||||
|
||||
fn paint(&mut self, bounds: Bounds<Pixels>, state: &mut TextState, cx: &mut ElementContext) {
|
||||
fn paint(
|
||||
&mut self,
|
||||
bounds: Bounds<Pixels>,
|
||||
wet: bool,
|
||||
state: &mut TextState,
|
||||
cx: &mut ElementContext,
|
||||
) {
|
||||
state.paint(bounds, self, cx)
|
||||
}
|
||||
}
|
||||
@@ -71,7 +77,13 @@ impl Element for SharedString {
|
||||
(layout_id, state)
|
||||
}
|
||||
|
||||
fn paint(&mut self, bounds: Bounds<Pixels>, state: &mut TextState, cx: &mut ElementContext) {
|
||||
fn paint(
|
||||
&mut self,
|
||||
bounds: Bounds<Pixels>,
|
||||
wet: bool,
|
||||
state: &mut TextState,
|
||||
cx: &mut ElementContext,
|
||||
) {
|
||||
let text_str: &str = self.as_ref();
|
||||
state.paint(bounds, text_str, cx)
|
||||
}
|
||||
@@ -150,7 +162,13 @@ impl Element for StyledText {
|
||||
(layout_id, state)
|
||||
}
|
||||
|
||||
fn paint(&mut self, bounds: Bounds<Pixels>, state: &mut Self::State, cx: &mut ElementContext) {
|
||||
fn paint(
|
||||
&mut self,
|
||||
bounds: Bounds<Pixels>,
|
||||
wet: bool,
|
||||
state: &mut Self::State,
|
||||
cx: &mut ElementContext,
|
||||
) {
|
||||
state.paint(bounds, &self.text, cx)
|
||||
}
|
||||
}
|
||||
@@ -419,7 +437,13 @@ impl Element for InteractiveText {
|
||||
}
|
||||
}
|
||||
|
||||
fn paint(&mut self, bounds: Bounds<Pixels>, state: &mut Self::State, cx: &mut ElementContext) {
|
||||
fn paint(
|
||||
&mut self,
|
||||
bounds: Bounds<Pixels>,
|
||||
wet: bool,
|
||||
state: &mut Self::State,
|
||||
cx: &mut ElementContext,
|
||||
) {
|
||||
if let Some(click_listener) = self.click_listener.take() {
|
||||
let mouse_position = cx.mouse_position();
|
||||
if let Some(ix) = state.text_state.index_for_position(bounds, mouse_position) {
|
||||
@@ -547,7 +571,7 @@ impl Element for InteractiveText {
|
||||
}
|
||||
}
|
||||
|
||||
self.text.paint(bounds, &mut state.text_state, cx)
|
||||
self.text.paint(bounds, wet, &mut state.text_state, cx)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -157,6 +157,7 @@ impl Element for UniformList {
|
||||
fn paint(
|
||||
&mut self,
|
||||
bounds: Bounds<crate::Pixels>,
|
||||
wet: bool,
|
||||
element_state: &mut Self::State,
|
||||
cx: &mut ElementContext,
|
||||
) {
|
||||
|
||||
@@ -104,8 +104,16 @@ impl<V: Render> Element for View<V> {
|
||||
})
|
||||
}
|
||||
|
||||
fn paint(&mut self, _: Bounds<Pixels>, element: &mut Self::State, cx: &mut ElementContext) {
|
||||
cx.paint_view(self.entity_id(), |cx| element.take().unwrap().paint(cx));
|
||||
fn paint(
|
||||
&mut self,
|
||||
_: Bounds<Pixels>,
|
||||
wet: bool,
|
||||
element: &mut Self::State,
|
||||
cx: &mut ElementContext,
|
||||
) {
|
||||
cx.paint_view(self.entity_id(), |cx| {
|
||||
element.as_mut().unwrap().paint(wet, cx)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -247,6 +255,7 @@ impl AnyView {
|
||||
self.model.entity_id()
|
||||
}
|
||||
|
||||
/// Draws this view at the given origin, with its sizing based on the `available_space`.
|
||||
pub(crate) fn draw(
|
||||
&self,
|
||||
origin: Point<Pixels>,
|
||||
@@ -257,7 +266,8 @@ impl AnyView {
|
||||
cx.with_absolute_element_offset(origin, |cx| {
|
||||
let (layout_id, mut rendered_element) = (self.request_layout)(self, cx);
|
||||
cx.compute_layout(layout_id, available_space);
|
||||
rendered_element.paint(cx)
|
||||
rendered_element.paint(false, cx);
|
||||
rendered_element.paint(true, cx);
|
||||
});
|
||||
})
|
||||
}
|
||||
@@ -301,10 +311,16 @@ impl Element for AnyView {
|
||||
})
|
||||
}
|
||||
|
||||
fn paint(&mut self, bounds: Bounds<Pixels>, state: &mut Self::State, cx: &mut ElementContext) {
|
||||
fn paint(
|
||||
&mut self,
|
||||
bounds: Bounds<Pixels>,
|
||||
wet: bool,
|
||||
state: &mut Self::State,
|
||||
cx: &mut ElementContext,
|
||||
) {
|
||||
cx.paint_view(self.entity_id(), |cx| {
|
||||
if !self.cache {
|
||||
state.element.take().unwrap().paint(cx);
|
||||
state.element.as_mut().unwrap().paint(wet, cx);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -321,7 +337,7 @@ impl Element for AnyView {
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(mut element) = state.element.take() {
|
||||
if let Some(mut element) = state.element.as_mut() {
|
||||
element.paint(cx);
|
||||
} else {
|
||||
let mut element = (self.request_layout)(self, cx).1;
|
||||
|
||||
@@ -191,7 +191,7 @@ impl<M: ManagedView> Element for PopoverMenu<M> {
|
||||
element_state: &mut Self::State,
|
||||
cx: &mut ElementContext,
|
||||
) {
|
||||
if let Some(mut child) = element_state.child_element.take() {
|
||||
if let Some(mut child) = element_state.child_element.as_mut() {
|
||||
child.paint(cx);
|
||||
}
|
||||
|
||||
@@ -199,7 +199,7 @@ impl<M: ManagedView> Element for PopoverMenu<M> {
|
||||
element_state.child_bounds = Some(cx.layout_bounds(child_layout_id));
|
||||
}
|
||||
|
||||
if let Some(mut menu) = element_state.menu_element.take() {
|
||||
if let Some(mut menu) = element_state.menu_element.as_mut() {
|
||||
menu.paint(cx);
|
||||
|
||||
if let Some(child_bounds) = element_state.child_bounds {
|
||||
|
||||
@@ -118,11 +118,11 @@ impl<M: ManagedView> Element for RightClickMenu<M> {
|
||||
element_state: &mut Self::State,
|
||||
cx: &mut ElementContext,
|
||||
) {
|
||||
if let Some(mut child) = element_state.child_element.take() {
|
||||
if let Some(mut child) = element_state.child_element.as_mut() {
|
||||
child.paint(cx);
|
||||
}
|
||||
|
||||
if let Some(mut menu) = element_state.menu_element.take() {
|
||||
if let Some(mut menu) = element_state.menu_element.as_mut() {
|
||||
menu.paint(cx);
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user