Skip to content

Commit

Permalink
Merge pull request #1337 from iced-rs/generic-widget-tree
Browse files Browse the repository at this point in the history
Take `Borrow<dyn Widget>` instead of `Element` in `Tree` API
  • Loading branch information
hecrj committed May 31, 2022
1 parent e11331d commit fb01625
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 13 deletions.
18 changes: 18 additions & 0 deletions pure/src/element.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ use iced_native::mouse;
use iced_native::renderer;
use iced_native::{Clipboard, Length, Point, Rectangle, Shell};

use std::borrow::Borrow;

/// A generic [`Widget`].
///
/// It is useful to build composable user interfaces that do not leak
Expand Down Expand Up @@ -321,3 +323,19 @@ where
.map(move |overlay| overlay.map(mapper))
}
}

impl<'a, Message, Renderer> Borrow<dyn Widget<Message, Renderer> + 'a>
for Element<'a, Message, Renderer>
{
fn borrow(&self) -> &(dyn Widget<Message, Renderer> + 'a) {
self.widget.borrow()
}
}

impl<'a, Message, Renderer> Borrow<dyn Widget<Message, Renderer> + 'a>
for &Element<'a, Message, Renderer>
{
fn borrow(&self) -> &(dyn Widget<Message, Renderer> + 'a) {
self.widget.borrow()
}
}
33 changes: 20 additions & 13 deletions pure/src/widget/tree.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
//! Store internal widget state in a state tree to ensure continuity.
use crate::Element;
use crate::Widget;

use std::any::{self, Any};
use std::borrow::Borrow;

/// A persistent state widget tree.
///
Expand All @@ -28,13 +29,15 @@ impl Tree {
}

/// Creates a new [`Tree`] for the provided [`Element`].
pub fn new<Message, Renderer>(
element: &Element<'_, Message, Renderer>,
pub fn new<'a, Message, Renderer>(
widget: impl Borrow<dyn Widget<Message, Renderer> + 'a>,
) -> Self {
let widget = widget.borrow();

Self {
tag: element.as_widget().tag(),
state: element.as_widget().state(),
children: element.as_widget().children(),
tag: widget.tag(),
state: widget.state(),
children: widget.children(),
}
}

Expand All @@ -46,23 +49,27 @@ impl Tree {
/// Otherwise, the whole [`Tree`] is recreated.
///
/// [`Widget::diff`]: crate::Widget::diff
pub fn diff<Message, Renderer>(
pub fn diff<'a, Message, Renderer>(
&mut self,
new: &Element<'_, Message, Renderer>,
new: impl Borrow<dyn Widget<Message, Renderer> + 'a>,
) {
if self.tag == new.as_widget().tag() {
new.as_widget().diff(self)
if self.tag == new.borrow().tag() {
new.borrow().diff(self)
} else {
*self = Self::new(new);
}
}

/// Reconciliates the children of the tree with the provided list of [`Element`].
pub fn diff_children<Message, Renderer>(
pub fn diff_children<'a, Message, Renderer>(
&mut self,
new_children: &[Element<'_, Message, Renderer>],
new_children: &[impl Borrow<dyn Widget<Message, Renderer> + 'a>],
) {
self.diff_children_custom(new_children, Self::diff, Self::new)
self.diff_children_custom(
new_children,
|tree, widget| tree.diff(widget.borrow()),
|widget| Self::new(widget.borrow()),
)
}

/// Reconciliates the children of the tree with the provided list of [`Element`] using custom
Expand Down

0 comments on commit fb01625

Please sign in to comment.