diff --git a/xilem/src/view/button.rs b/xilem/src/view/button.rs index f0df8ddb4..85a27ef9e 100644 --- a/xilem/src/view/button.rs +++ b/xilem/src/view/button.rs @@ -2,10 +2,8 @@ // SPDX-License-Identifier: Apache-2.0 use crate::{core::View, Pod}; -use masonry::{ - widget::{self, WidgetMut}, - ArcStr, WidgetPod, -}; +use masonry::{widget, ArcStr, WidgetPod}; +use xilem_core::ViewElement; use crate::{MessageResult, ViewCtx, ViewId}; @@ -37,17 +35,18 @@ where }) } - fn rebuild( + fn rebuild<'a>( &self, prev: &Self, _: &mut Self::ViewState, ctx: &mut ViewCtx, - mut element: WidgetMut, - ) { + mut element: ::Mut<'a>, + ) -> ::Mut<'a> { if prev.label != self.label { element.set_text(self.label.clone()); ctx.mark_changed(); } + element } fn teardown( diff --git a/xilem/src/view/checkbox.rs b/xilem/src/view/checkbox.rs index ecbfcdce5..1257862eb 100644 --- a/xilem/src/view/checkbox.rs +++ b/xilem/src/view/checkbox.rs @@ -5,6 +5,7 @@ use masonry::{ widget::{self, WidgetMut}, ArcStr, WidgetPod, }; +use xilem_core::ViewElement; use crate::{MessageResult, Pod, View, ViewCtx, ViewId}; @@ -46,13 +47,13 @@ where }) } - fn rebuild( + fn rebuild<'a>( &self, prev: &Self, (): &mut Self::ViewState, ctx: &mut ViewCtx, - mut element: WidgetMut<'_, widget::Checkbox>, - ) { + mut element: ::Mut<'a>, + ) -> ::Mut<'a> { if prev.label != self.label { element.set_text(self.label.clone()); ctx.mark_changed(); @@ -61,6 +62,7 @@ where element.set_checked(self.checked); ctx.mark_changed(); } + element } fn teardown( diff --git a/xilem/src/view/flex.rs b/xilem/src/view/flex.rs index fe66f2681..b92f9117b 100644 --- a/xilem/src/view/flex.rs +++ b/xilem/src/view/flex.rs @@ -7,7 +7,7 @@ use masonry::{ widget::{self, Axis, CrossAxisAlignment, MainAxisAlignment, WidgetMut}, Widget, WidgetPod, }; -use xilem_core::{AppendVec, ElementSplice, View, ViewSequence}; +use xilem_core::{AppendVec, ElementSplice, View, ViewElement, ViewSequence}; use crate::{Pod, ViewCtx}; @@ -75,13 +75,13 @@ where (WidgetPod::new(widget).into(), seq_state) } - fn rebuild( + fn rebuild<'a>( &self, prev: &Self, view_state: &mut Self::ViewState, ctx: &mut ViewCtx, - mut element: WidgetMut, - ) { + mut element: ::Mut<'a>, + ) -> ::Mut<'a> { if prev.axis != self.axis { element.set_direction(self.axis); ctx.mark_changed(); @@ -102,24 +102,25 @@ where let mut splice = FlexSplice { // Skip the initial spacer which is always present ix: 1, - element, + element: &mut element, scratch: AppendVec::default(), }; self.sequence .seq_rebuild(&prev.sequence, view_state, ctx, &mut splice); debug_assert!(splice.scratch.into_inner().is_empty()); + element } fn teardown( &self, view_state: &mut Self::ViewState, ctx: &mut ViewCtx, - element: ::Mut<'_>, + mut element: ::Mut<'_>, ) { let mut splice = FlexSplice { // Skip the initial spacer which is always present ix: 1, - element, + element: &mut element, scratch: AppendVec::default(), }; self.sequence.seq_teardown(view_state, ctx, &mut splice); @@ -138,13 +139,13 @@ where } } -struct FlexSplice<'w> { +struct FlexSplice<'f, 'w> { ix: usize, - element: WidgetMut<'w, widget::Flex>, + element: &'f mut WidgetMut<'w, widget::Flex>, scratch: AppendVec>>, } -impl ElementSplice>> for FlexSplice<'_> { +impl<'f> ElementSplice>> for FlexSplice<'f, '_> { fn push(&mut self, element: Pod>) { self.element.insert_child_pod(self.ix, element.inner); // Insert a spacer after the child diff --git a/xilem/src/view/label.rs b/xilem/src/view/label.rs index 52c473f67..5dcbed319 100644 --- a/xilem/src/view/label.rs +++ b/xilem/src/view/label.rs @@ -5,6 +5,7 @@ use masonry::{ widget::{self, WidgetMut}, ArcStr, WidgetPod, }; +use xilem_core::ViewElement; use crate::{Color, MessageResult, Pod, TextAlignment, View, ViewCtx, ViewId}; @@ -55,13 +56,13 @@ impl View for Label { (widget_pod.into(), ()) } - fn rebuild( + fn rebuild<'a>( &self, prev: &Self, (): &mut Self::ViewState, ctx: &mut ViewCtx, - mut element: WidgetMut<'_, widget::Label>, - ) { + mut element: ::Mut<'a>, + ) -> ::Mut<'a> { if prev.label != self.label { element.set_text(self.label.clone()); ctx.mark_changed(); @@ -78,6 +79,7 @@ impl View for Label { element.set_alignment(self.alignment); ctx.mark_changed(); } + element } fn teardown(&self, (): &mut Self::ViewState, _: &mut ViewCtx, _: WidgetMut<'_, widget::Label>) { diff --git a/xilem/src/view/prose.rs b/xilem/src/view/prose.rs index ea521e840..d88941d27 100644 --- a/xilem/src/view/prose.rs +++ b/xilem/src/view/prose.rs @@ -6,6 +6,7 @@ use masonry::{ widget::{self, WidgetMut}, ArcStr, WidgetPod, }; +use xilem_core::ViewElement; use crate::{Color, MessageResult, Pod, TextAlignment, View, ViewCtx, ViewId}; @@ -57,13 +58,13 @@ impl View for Prose { (widget_pod.into(), ()) } - fn rebuild( + fn rebuild<'a>( &self, prev: &Self, (): &mut Self::ViewState, ctx: &mut ViewCtx, - mut element: WidgetMut<'_, widget::Prose>, - ) { + mut element: ::Mut<'a>, + ) -> ::Mut<'a> { if prev.label != self.label { element.set_text(self.label.clone()); ctx.mark_changed(); @@ -76,6 +77,7 @@ impl View for Prose { element.set_alignment(self.alignment); ctx.mark_changed(); } + element } fn teardown(&self, (): &mut Self::ViewState, _: &mut ViewCtx, _: WidgetMut<'_, widget::Prose>) { diff --git a/xilem/src/view/textbox.rs b/xilem/src/view/textbox.rs index 1ec50e6b8..de0834d41 100644 --- a/xilem/src/view/textbox.rs +++ b/xilem/src/view/textbox.rs @@ -1,12 +1,8 @@ // Copyright 2024 the Xilem Authors // SPDX-License-Identifier: Apache-2.0 -use masonry::{ - text2::TextBrush, - widget::{self, WidgetMut}, - WidgetPod, -}; -use xilem_core::View; +use masonry::{text2::TextBrush, widget, WidgetPod}; +use xilem_core::{View, ViewElement}; use crate::{Color, MessageResult, Pod, TextAlignment, ViewCtx, ViewId}; @@ -82,13 +78,13 @@ impl View for Textbox( &self, prev: &Self, _: &mut Self::ViewState, ctx: &mut ViewCtx, - mut element: WidgetMut, - ) { + mut element: ::Mut<'a>, + ) -> ::Mut<'a> { // Unlike the other properties, we don't compare to the previous value; // instead, we compare directly to the element's text. This is to handle // cases like "Previous data says contents is 'fooba', user presses 'r', @@ -109,6 +105,7 @@ impl View for Textbox View for File { (path.into(), ()) } - fn rebuild( + fn rebuild<'a>( &self, prev: &Self, _view_state: &mut Self::ViewState, ctx: &mut ViewCtx, - element: ::Mut<'_>, - ) { + element: ::Mut<'a>, + ) -> ::Mut<'a> { if prev.name != self.name { let new_path = ctx.current_folder_path.join(&*self.name); let _ = std::fs::rename(&element, &new_path); *element = new_path; } if self.contents != prev.contents { - let _ = std::fs::write(element, self.contents.as_bytes()); + let _ = std::fs::write(&element, self.contents.as_bytes()); } + element } fn teardown( diff --git a/xilem_core/examples/user_interface.rs b/xilem_core/examples/user_interface.rs index 1c3ff27bd..3efed20b6 100644 --- a/xilem_core/examples/user_interface.rs +++ b/xilem_core/examples/user_interface.rs @@ -68,14 +68,15 @@ impl View for Button { ) } - fn rebuild( + fn rebuild<'a>( &self, _prev: &Self, _view_state: &mut Self::ViewState, _ctx: &mut ViewCtx, - _element: ::Mut<'_>, - ) { + element: ::Mut<'a>, + ) -> ::Mut<'a> { // Nothing to do + element } fn teardown( diff --git a/xilem_core/src/any_view.rs b/xilem_core/src/any_view.rs index 0a0e606b8..c2fdb53a6 100644 --- a/xilem_core/src/any_view.rs +++ b/xilem_core/src/any_view.rs @@ -28,13 +28,13 @@ pub trait AnyView { fn dyn_build(&self, ctx: &mut Context) -> (Element, AnyViewState); - fn dyn_rebuild( + fn dyn_rebuild<'a>( &self, dyn_state: &mut AnyViewState, ctx: &mut Context, prev: &dyn AnyView, - element: Element::Mut<'_>, - ); + element: Element::Mut<'a>, + ) -> Element::Mut<'a>; /// Returns `Element::Mut<'el>` so that the element can be /// returned and replaced in `dyn_rebuild`, if needed @@ -78,13 +78,13 @@ where ) } - fn dyn_rebuild( + fn dyn_rebuild<'a>( &self, dyn_state: &mut AnyViewState, ctx: &mut Context, prev: &dyn AnyView, - mut element: ::Mut<'_>, - ) { + mut element: ::Mut<'a>, + ) -> ::Mut<'a> { if let Some(prev) = prev.as_any().downcast_ref() { // If we were previously of this type, then do a normal rebuild DynamicElement::with_downcast(element, |element| { @@ -96,7 +96,7 @@ where ctx.with_id(ViewId::new(dyn_state.generation), move |ctx| { self.rebuild(prev, state, ctx, element); }); - }); + }) } else { // Otherwise, teardown the old element, then replace the value element = prev.dyn_teardown(dyn_state, ctx, element); @@ -108,7 +108,7 @@ where let (new_element, view_state) = ctx.with_id(ViewId::new(dyn_state.generation), |ctx| self.build(ctx)); dyn_state.inner_state = Box::new(view_state); - DynamicElement::replace_inner(element, new_element); + DynamicElement::replace_inner(element, new_element) } } fn dyn_teardown<'el>( @@ -175,14 +175,14 @@ where self.dyn_build(ctx) } - fn rebuild( + fn rebuild<'a>( &self, prev: &Self, view_state: &mut Self::ViewState, ctx: &mut Context, - element: ::Mut<'_>, - ) { - self.dyn_rebuild(view_state, ctx, prev, element); + element: ::Mut<'a>, + ) -> ::Mut<'a> { + self.dyn_rebuild(view_state, ctx, prev, element) } fn teardown( @@ -221,14 +221,14 @@ where self.dyn_build(ctx) } - fn rebuild( + fn rebuild<'a>( &self, prev: &Self, view_state: &mut Self::ViewState, ctx: &mut Context, - element: ::Mut<'_>, - ) { - self.dyn_rebuild(view_state, ctx, prev, element); + element: ::Mut<'a>, + ) -> ::Mut<'a> { + self.dyn_rebuild(view_state, ctx, prev, element) } fn teardown( @@ -266,14 +266,14 @@ where self.dyn_build(ctx) } - fn rebuild( + fn rebuild<'a>( &self, prev: &Self, view_state: &mut Self::ViewState, ctx: &mut Context, - element: ::Mut<'_>, - ) { - self.dyn_rebuild(view_state, ctx, prev, element); + element: ::Mut<'a>, + ) -> ::Mut<'a> { + self.dyn_rebuild(view_state, ctx, prev, element) } fn teardown( @@ -311,14 +311,14 @@ where self.dyn_build(ctx) } - fn rebuild( + fn rebuild<'a>( &self, prev: &Self, view_state: &mut Self::ViewState, ctx: &mut Context, - element: ::Mut<'_>, - ) { - self.dyn_rebuild(view_state, ctx, prev, element); + element: ::Mut<'a>, + ) -> ::Mut<'a> { + self.dyn_rebuild(view_state, ctx, prev, element) } fn teardown( diff --git a/xilem_core/src/view.rs b/xilem_core/src/view.rs index 0bb9e4705..802b2c16c 100644 --- a/xilem_core/src/view.rs +++ b/xilem_core/src/view.rs @@ -46,13 +46,13 @@ pub trait View: 'static { fn build(&self, ctx: &mut Context) -> (Self::Element, Self::ViewState); /// Update `element` based on the difference between `self` and `prev`. - fn rebuild( + fn rebuild<'a>( &self, prev: &Self, view_state: &mut Self::ViewState, ctx: &mut Context, - element: ::Mut<'_>, - ); + element: ::Mut<'a>, + ) -> ::Mut<'a>; /// Handle `element` being removed from the tree. /// @@ -129,14 +129,14 @@ impl + fn build(&self, ctx: &mut Context) -> (Self::Element, Self::ViewState) { self.deref().build(ctx) } - fn rebuild( + fn rebuild<'a>( &self, prev: &Self, view_state: &mut Self::ViewState, ctx: &mut Context, - element: ::Mut<'_>, - ) { - self.deref().rebuild(prev, view_state, ctx, element); + element: ::Mut<'a>, + ) -> ::Mut<'a> { + self.deref().rebuild(prev, view_state, ctx, element) } fn teardown( &self, @@ -168,15 +168,18 @@ impl + fn build(&self, ctx: &mut Context) -> (Self::Element, Self::ViewState) { self.deref().build(ctx) } - fn rebuild( + + fn rebuild<'a>( &self, prev: &Self, view_state: &mut Self::ViewState, ctx: &mut Context, - element: ::Mut<'_>, - ) { + element: ::Mut<'a>, + ) -> ::Mut<'a> { if !Arc::ptr_eq(self, prev) { - self.deref().rebuild(prev, view_state, ctx, element); + self.deref().rebuild(prev, view_state, ctx, element) + } else { + element } } fn teardown( diff --git a/xilem_core/src/views/memoize.rs b/xilem_core/src/views/memoize.rs index 185a2e20c..6e14c65a5 100644 --- a/xilem_core/src/views/memoize.rs +++ b/xilem_core/src/views/memoize.rs @@ -64,17 +64,20 @@ where (element, memoize_state) } - fn rebuild( + fn rebuild<'a>( &self, prev: &Self, view_state: &mut Self::ViewState, cx: &mut Context, - element: ::Mut<'_>, - ) { + element: ::Mut<'a>, + ) -> ::Mut<'a> { if std::mem::take(&mut view_state.dirty) || prev.data != self.data { let view = (self.child_cb)(&self.data); - view.rebuild(&view_state.view, &mut view_state.view_state, cx, element); + let el = view.rebuild(&view_state.view, &mut view_state.view_state, cx, element); view_state.view = view; + el + } else { + element } }