From f322894e50a17870e940706aec19f66db1221ca5 Mon Sep 17 00:00:00 2001 From: Olivier FAURE Date: Tue, 22 Oct 2024 15:36:48 +0200 Subject: [PATCH] Replace WidgetMut methods with free functions. (#705) See discussion here https://github.com/linebender/xilem/pull/663 and [on zulip](https://xi.zulipchat.com/#narrow/channel/317477-masonry/topic/Improving.20docs.20for.20WidgetMut). Basically, previous code was using `WidgetMut` as a receiver. This can be done when WidgetMut is a local type, but external users wouldn't be able to do it. The result would be that users importing Masonry as a dependency but copy-pasting code from one of our widgets would get compile errors. This PR switches to a syntax that external crates will be able to use when declaring widgets. It's a more verbose, less readable syntax, but it's unambiguous and doesn't require clever tricks. We can consider switching back to WidgetMut-as-a-receiver when `#![feature(arbitrary_self_types)]` or some equivalent gets stabilized. See https://github.com/rust-lang/rust/issues/44874#issuecomment-2122179688 for current progress. --- masonry/README.md | 6 +- masonry/examples/calc_masonry.rs | 19 +- masonry/examples/grid_masonry.rs | 6 +- masonry/examples/to_do_list.rs | 12 +- masonry/src/lib.rs | 6 +- masonry/src/widget/button.rs | 16 +- masonry/src/widget/checkbox.rs | 31 +-- masonry/src/widget/flex.rs | 253 +++++++++++++----------- masonry/src/widget/grid.rs | 135 ++++++++----- masonry/src/widget/image.rs | 16 +- masonry/src/widget/label.rs | 73 ++++--- masonry/src/widget/portal.rs | 76 +++---- masonry/src/widget/progress_bar.rs | 16 +- masonry/src/widget/prose.rs | 54 +++-- masonry/src/widget/root_widget.rs | 6 +- masonry/src/widget/scroll_bar.rs | 16 +- masonry/src/widget/sized_box.rs | 90 +++++---- masonry/src/widget/spinner.rs | 15 +- masonry/src/widget/split.rs | 48 ++--- masonry/src/widget/tests/widget_tree.rs | 2 +- masonry/src/widget/textbox.rs | 56 +++--- masonry/src/widget/variable_label.rs | 70 +++---- xilem/src/driver.rs | 2 +- xilem/src/view/button.rs | 2 +- xilem/src/view/checkbox.rs | 4 +- xilem/src/view/flex.rs | 91 +++++---- xilem/src/view/grid.rs | 44 +++-- xilem/src/view/image.rs | 4 +- xilem/src/view/label.rs | 10 +- xilem/src/view/portal.rs | 4 +- xilem/src/view/progress_bar.rs | 2 +- xilem/src/view/prose.rs | 8 +- xilem/src/view/sized_box.rs | 28 +-- xilem/src/view/spinner.rs | 4 +- xilem/src/view/textbox.rs | 8 +- xilem/src/view/variable_label.rs | 16 +- 36 files changed, 672 insertions(+), 577 deletions(-) diff --git a/masonry/README.md b/masonry/README.md index a0d2b7f2d..4e9e2b190 100644 --- a/masonry/README.md +++ b/masonry/README.md @@ -50,9 +50,9 @@ impl AppDriver for Driver { match action { Action::ButtonPressed(_) => { let mut root: WidgetMut>> = ctx.get_root(); - let mut root = root.child_mut(); - let mut flex = root.child_mut(); - flex.add_child(Label::new(self.next_task.clone())); + let mut portal = RootWidget::child_mut(&mut root); + let mut flex = Portal::child_mut(&mut portal); + Flex::add_child(&mut flex, Label::new(self.next_task.clone())); } Action::TextChanged(new_text) => { self.next_task = new_text.clone(); diff --git a/masonry/examples/calc_masonry.rs b/masonry/examples/calc_masonry.rs index 60b3b165c..6c9cb541e 100644 --- a/masonry/examples/calc_masonry.rs +++ b/masonry/examples/calc_masonry.rs @@ -147,7 +147,7 @@ impl Widget for CalcButton { let color = self.active_color; // See on_status_change for why we use `mutate_later` here. ctx.mutate_later(&mut self.inner, move |mut inner| { - inner.set_background(color); + SizedBox::set_background(&mut inner, color); }); ctx.capture_pointer(); trace!("CalcButton {:?} pressed", ctx.widget_id()); @@ -158,7 +158,7 @@ impl Widget for CalcButton { let color = self.base_color; // See on_status_change for why we use `mutate_later` here. ctx.mutate_later(&mut self.inner, move |mut inner| { - inner.set_background(color); + SizedBox::set_background(&mut inner, color); }); ctx.submit_action(Action::Other(Box::new(self.action))); trace!("CalcButton {:?} released", ctx.widget_id()); @@ -190,7 +190,7 @@ impl Widget for CalcButton { match event { Update::HoveredChanged(true) => { ctx.mutate_later(&mut self.inner, move |mut inner| { - inner.set_border(Color::WHITE, 3.0); + SizedBox::set_border(&mut inner, Color::WHITE, 3.0); }); // FIXME - This is a monkey-patch for a problem where the mutate pass isn't run after this. // Should be fixed once the pass spec RFC is implemented. @@ -198,7 +198,7 @@ impl Widget for CalcButton { } Update::HoveredChanged(false) => { ctx.mutate_later(&mut self.inner, move |mut inner| { - inner.set_border(Color::TRANSPARENT, 3.0); + SizedBox::set_border(&mut inner, Color::TRANSPARENT, 3.0); }); // FIXME - This is a monkey-patch for a problem where the mutate pass isn't run after this. // Should be fixed once the pass spec RFC is implemented. @@ -254,12 +254,11 @@ impl AppDriver for CalcState { _ => unreachable!(), } - ctx.get_root::>() - .child_mut() - .child_mut(1) - .unwrap() - .downcast::