diff --git a/src/app.rs b/src/app.rs index 1165b3671..c7c940cd1 100644 --- a/src/app.rs +++ b/src/app.rs @@ -244,16 +244,14 @@ where let state = if let Some(element) = self.root_pod.as_mut().and_then(|pod| pod.downcast_mut()) { let mut state = response.state.unwrap(); - let changed = response.view.rebuild( + let changes = response.view.rebuild( &mut self.cx, response.prev.as_ref().unwrap(), self.id.as_mut().unwrap(), &mut state, element, ); - if changed { - self.root_pod.as_mut().unwrap().request_update(); - } + self.root_pod.as_mut().unwrap().mark(changes); assert!(self.cx.is_empty(), "id path imbalance on rebuild"); state } else { diff --git a/src/view.rs b/src/view.rs index cd4ebd42e..33da1e2b6 100644 --- a/src/view.rs +++ b/src/view.rs @@ -35,7 +35,7 @@ use futures_task::{ArcWake, Waker}; use crate::{ event::EventResult, id::{Id, IdPath}, - widget::Widget, + widget::{ChangeFlags, Widget}, }; /// A view object representing a node in the UI. @@ -73,7 +73,7 @@ pub trait View: Send { id: &mut Id, state: &mut Self::State, element: &mut Self::Element, - ) -> bool; + ) -> ChangeFlags; /// Propagate an event. /// diff --git a/src/view/button.rs b/src/view/button.rs index 4a26b78a7..8c2230032 100644 --- a/src/view/button.rs +++ b/src/view/button.rs @@ -14,7 +14,7 @@ use std::any::Any; -use crate::{event::EventResult, id::Id}; +use crate::{event::EventResult, id::Id, widget::ChangeFlags}; use super::{Cx, View}; @@ -58,12 +58,11 @@ impl View for Button { _id: &mut crate::id::Id, _state: &mut Self::State, element: &mut Self::Element, - ) -> bool { + ) -> ChangeFlags { if prev.label != self.label { - element.set_label(self.label.clone()); - true + element.set_label(self.label.clone()) } else { - false + ChangeFlags::empty() } } diff --git a/src/view/text.rs b/src/view/text.rs index ed901e89b..2d39840c6 100644 --- a/src/view/text.rs +++ b/src/view/text.rs @@ -14,7 +14,7 @@ use std::any::Any; -use crate::{event::EventResult, id::Id}; +use crate::{event::EventResult, id::Id, widget::ChangeFlags}; use super::{Cx, View}; @@ -35,12 +35,11 @@ impl View for String { _id: &mut crate::id::Id, _state: &mut Self::State, element: &mut Self::Element, - ) -> bool { + ) -> ChangeFlags { if prev != self { - element.set_text(self.clone()); - true + element.set_text(self.clone()) } else { - false + ChangeFlags::empty() } } diff --git a/src/widget.rs b/src/widget.rs index 7594e8f1b..ce0b42eb8 100644 --- a/src/widget.rs +++ b/src/widget.rs @@ -33,7 +33,7 @@ use piet_scene::SceneBuilder; use self::contexts::LifeCycleCx; pub use self::contexts::{AlignCx, CxState, EventCx, LayoutCx, PaintCx, PreparePaintCx, UpdateCx}; pub use self::core::Pod; -pub(crate) use self::core::{PodFlags, WidgetState}; +pub(crate) use self::core::{ChangeFlags, PodFlags, WidgetState}; pub use self::raw_event::{LifeCycle, RawEvent}; use self::align::SingleAlignment; diff --git a/src/widget/button.rs b/src/widget/button.rs index b986621f0..de91acc33 100644 --- a/src/widget/button.rs +++ b/src/widget/button.rs @@ -22,7 +22,7 @@ use super::{ align::{FirstBaseline, LastBaseline, SingleAlignment}, contexts::LifeCycleCx, piet_scene_helpers::{self, UnitPoint}, - AlignCx, EventCx, LayoutCx, LifeCycle, PaintCx, RawEvent, UpdateCx, Widget, + AlignCx, ChangeFlags, EventCx, LayoutCx, LifeCycle, PaintCx, RawEvent, UpdateCx, Widget, }; pub struct Button { @@ -40,9 +40,10 @@ impl Button { } } - pub fn set_label(&mut self, label: String) { + pub fn set_label(&mut self, label: String) -> ChangeFlags { self.label = label; self.layout = None; + ChangeFlags::LAYOUT | ChangeFlags::PAINT } } diff --git a/src/widget/core.rs b/src/widget/core.rs index c77698e60..18be6a4a4 100644 --- a/src/widget/core.rs +++ b/src/widget/core.rs @@ -49,6 +49,16 @@ bitflags! { } } +bitflags! { + #[derive(Default)] + #[must_use] + pub struct ChangeFlags: u8 { + const UPDATE = 1; + const LAYOUT = 2; + const PAINT = 4; + } +} + /// A pod that contains a widget (in a container). pub struct Pod { pub(crate) state: WidgetState, @@ -127,6 +137,11 @@ impl Pod { (*self.widget).as_any_mut().downcast_mut() } + pub fn mark(&mut self, flags: ChangeFlags) { + self.state + .request(PodFlags::from_bits(flags.bits().into()).unwrap()); + } + pub fn request_update(&mut self) { self.state.request(PodFlags::REQUEST_UPDATE); } diff --git a/src/widget/text.rs b/src/widget/text.rs index db1585f21..4bb8163a1 100644 --- a/src/widget/text.rs +++ b/src/widget/text.rs @@ -21,7 +21,7 @@ use crate::text::ParleyBrush; use super::{ align::{FirstBaseline, LastBaseline, SingleAlignment, VertAlignment}, contexts::LifeCycleCx, - AlignCx, EventCx, LayoutCx, LifeCycle, PaintCx, RawEvent, UpdateCx, Widget, + AlignCx, ChangeFlags, EventCx, LayoutCx, LifeCycle, PaintCx, RawEvent, UpdateCx, Widget, }; pub struct TextWidget { @@ -39,8 +39,9 @@ impl TextWidget { } } - pub fn set_text(&mut self, text: String) { + pub fn set_text(&mut self, text: String) -> ChangeFlags { self.text = text; + ChangeFlags::LAYOUT | ChangeFlags::PAINT } }