Skip to content

Commit

Permalink
xilem_core: return element in View::rebuild
Browse files Browse the repository at this point in the history
Otherwise it's not possible to modify the element anymore after child `View` has used the element in `View::rebuild`
  • Loading branch information
Philipp-M committed Jun 1, 2024
1 parent 824112c commit 7f4faff
Show file tree
Hide file tree
Showing 11 changed files with 92 additions and 81 deletions.
13 changes: 6 additions & 7 deletions xilem/src/view/button.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};

Expand Down Expand Up @@ -37,17 +35,18 @@ where
})
}

fn rebuild(
fn rebuild<'a>(
&self,
prev: &Self,
_: &mut Self::ViewState,
ctx: &mut ViewCtx,
mut element: WidgetMut<widget::Button>,
) {
mut element: <Self::Element as ViewElement>::Mut<'a>,
) -> <Self::Element as ViewElement>::Mut<'a> {
if prev.label != self.label {
element.set_text(self.label.clone());
ctx.mark_changed();
}
element
}

fn teardown(
Expand Down
8 changes: 5 additions & 3 deletions xilem/src/view/checkbox.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use masonry::{
widget::{self, WidgetMut},
ArcStr, WidgetPod,
};
use xilem_core::ViewElement;

use crate::{MessageResult, Pod, View, ViewCtx, ViewId};

Expand Down Expand Up @@ -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: <Self::Element as ViewElement>::Mut<'a>,
) -> <Self::Element as ViewElement>::Mut<'a> {
if prev.label != self.label {
element.set_text(self.label.clone());
ctx.mark_changed();
Expand All @@ -61,6 +62,7 @@ where
element.set_checked(self.checked);
ctx.mark_changed();
}
element
}

fn teardown(
Expand Down
21 changes: 11 additions & 10 deletions xilem/src/view/flex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};

Expand Down Expand Up @@ -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<widget::Flex>,
) {
mut element: <Self::Element as ViewElement>::Mut<'a>,
) -> <Self::Element as ViewElement>::Mut<'a> {
if prev.axis != self.axis {
element.set_direction(self.axis);
ctx.mark_changed();
Expand All @@ -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: <Self::Element as xilem_core::ViewElement>::Mut<'_>,
mut element: <Self::Element as xilem_core::ViewElement>::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);
Expand All @@ -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<Pod<Box<dyn Widget>>>,
}

impl ElementSplice<Pod<Box<dyn Widget>>> for FlexSplice<'_> {
impl<'f> ElementSplice<Pod<Box<dyn Widget>>> for FlexSplice<'f, '_> {
fn push(&mut self, element: Pod<Box<dyn masonry::Widget>>) {
self.element.insert_child_pod(self.ix, element.inner);
// Insert a spacer after the child
Expand Down
8 changes: 5 additions & 3 deletions xilem/src/view/label.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use masonry::{
widget::{self, WidgetMut},
ArcStr, WidgetPod,
};
use xilem_core::ViewElement;

use crate::{Color, MessageResult, Pod, TextAlignment, View, ViewCtx, ViewId};

Expand Down Expand Up @@ -55,13 +56,13 @@ impl<State, Action> View<State, Action, ViewCtx> 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: <Self::Element as ViewElement>::Mut<'a>,
) -> <Self::Element as ViewElement>::Mut<'a> {
if prev.label != self.label {
element.set_text(self.label.clone());
ctx.mark_changed();
Expand All @@ -78,6 +79,7 @@ impl<State, Action> View<State, Action, ViewCtx> for Label {
element.set_alignment(self.alignment);
ctx.mark_changed();
}
element
}

fn teardown(&self, (): &mut Self::ViewState, _: &mut ViewCtx, _: WidgetMut<'_, widget::Label>) {
Expand Down
8 changes: 5 additions & 3 deletions xilem/src/view/prose.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use masonry::{
widget::{self, WidgetMut},
ArcStr, WidgetPod,
};
use xilem_core::ViewElement;

use crate::{Color, MessageResult, Pod, TextAlignment, View, ViewCtx, ViewId};

Expand Down Expand Up @@ -57,13 +58,13 @@ impl<State, Action> View<State, Action, ViewCtx> 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: <Self::Element as ViewElement>::Mut<'a>,
) -> <Self::Element as ViewElement>::Mut<'a> {
if prev.label != self.label {
element.set_text(self.label.clone());
ctx.mark_changed();
Expand All @@ -76,6 +77,7 @@ impl<State, Action> View<State, Action, ViewCtx> for Prose {
element.set_alignment(self.alignment);
ctx.mark_changed();
}
element
}

fn teardown(&self, (): &mut Self::ViewState, _: &mut ViewCtx, _: WidgetMut<'_, widget::Prose>) {
Expand Down
15 changes: 6 additions & 9 deletions xilem/src/view/textbox.rs
Original file line number Diff line number Diff line change
@@ -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};

Expand Down Expand Up @@ -82,13 +78,13 @@ impl<State: 'static, Action: 'static> View<State, Action, ViewCtx> for Textbox<S
})
}

fn rebuild(
fn rebuild<'a>(
&self,
prev: &Self,
_: &mut Self::ViewState,
ctx: &mut ViewCtx,
mut element: WidgetMut<widget::Textbox>,
) {
mut element: <Self::Element as ViewElement>::Mut<'a>,
) -> <Self::Element as ViewElement>::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',
Expand All @@ -109,6 +105,7 @@ impl<State: 'static, Action: 'static> View<State, Action, ViewCtx> for Textbox<S
element.set_alignment(self.alignment);
ctx.mark_changed();
}
element
}

fn teardown(
Expand Down
9 changes: 5 additions & 4 deletions xilem_core/examples/filesystem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,21 +163,22 @@ impl<State, Action> View<State, Action, ViewCtx> for File {
(path.into(), ())
}

fn rebuild(
fn rebuild<'a>(
&self,
prev: &Self,
_view_state: &mut Self::ViewState,
ctx: &mut ViewCtx,
element: <Self::Element as xilem_core::ViewElement>::Mut<'_>,
) {
element: <Self::Element as ViewElement>::Mut<'a>,
) -> <Self::Element as ViewElement>::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(
Expand Down
7 changes: 4 additions & 3 deletions xilem_core/examples/user_interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,14 +68,15 @@ impl<State, Action> View<State, Action, ViewCtx> for Button {
)
}

fn rebuild(
fn rebuild<'a>(
&self,
_prev: &Self,
_view_state: &mut Self::ViewState,
_ctx: &mut ViewCtx,
_element: <Self::Element as ViewElement>::Mut<'_>,
) {
element: <Self::Element as ViewElement>::Mut<'a>,
) -> <Self::Element as ViewElement>::Mut<'a> {
// Nothing to do
element
}

fn teardown(
Expand Down
Loading

0 comments on commit 7f4faff

Please sign in to comment.