Merge pull request #1563 from tarkah/fix/overlay-mutable

Allow &mut self in overlay
This commit is contained in:
Héctor Ramón 2022-11-29 21:50:27 +01:00 committed by GitHub
commit 23da5a3251
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 73 additions and 83 deletions

View file

@ -11,7 +11,7 @@ use iced_native::{
}; };
use ouroboros::self_referencing; use ouroboros::self_referencing;
use std::cell::{Ref, RefCell}; use std::cell::RefCell;
use std::marker::PhantomData; use std::marker::PhantomData;
/// A reusable, custom widget that uses The Elm Architecture. /// A reusable, custom widget that uses The Elm Architecture.
@ -322,25 +322,25 @@ where
} }
fn overlay<'b>( fn overlay<'b>(
&'b self, &'b mut self,
tree: &'b mut Tree, tree: &'b mut Tree,
layout: Layout<'_>, layout: Layout<'_>,
renderer: &Renderer, renderer: &Renderer,
) -> Option<overlay::Element<'b, Message, Renderer>> { ) -> Option<overlay::Element<'b, Message, Renderer>> {
let overlay = OverlayBuilder { let overlay = OverlayBuilder {
instance: self, instance: self,
instance_ref_builder: |instance| instance.state.borrow(),
tree, tree,
types: PhantomData, types: PhantomData,
overlay_builder: |instance, tree| { overlay_builder: |instance, tree| {
instance instance.state.get_mut().as_mut().unwrap().with_element_mut(
.as_ref() move |element| {
.unwrap() element.as_mut().unwrap().as_widget_mut().overlay(
.borrow_element() &mut tree.children[0],
.as_ref() layout,
.unwrap() renderer,
.as_widget() )
.overlay(&mut tree.children[0], layout, renderer) },
)
}, },
} }
.build(); .build();
@ -362,15 +362,11 @@ where
#[self_referencing] #[self_referencing]
struct Overlay<'a, 'b, Message, Renderer, Event, S> { struct Overlay<'a, 'b, Message, Renderer, Event, S> {
instance: &'a Instance<'b, Message, Renderer, Event, S>, instance: &'a mut Instance<'b, Message, Renderer, Event, S>,
tree: &'a mut Tree, tree: &'a mut Tree,
types: PhantomData<(Message, Event, S)>, types: PhantomData<(Message, Event, S)>,
#[borrows(instance)] #[borrows(mut instance, mut tree)]
#[covariant]
instance_ref: Ref<'this, Option<State<'a, Message, Renderer, Event, S>>>,
#[borrows(instance_ref, mut tree)]
#[covariant] #[covariant]
overlay: Option<overlay::Element<'this, Event, Renderer>>, overlay: Option<overlay::Element<'this, Event, Renderer>>,
} }
@ -514,7 +510,6 @@ where
self.overlay = Some( self.overlay = Some(
OverlayBuilder { OverlayBuilder {
instance: overlay.instance, instance: overlay.instance,
instance_ref_builder: |instance| instance.state.borrow(),
tree: overlay.tree, tree: overlay.tree,
types: PhantomData, types: PhantomData,
overlay_builder: |_, _| None, overlay_builder: |_, _| None,

View file

@ -207,7 +207,7 @@ where
} }
fn overlay<'b>( fn overlay<'b>(
&'b self, &'b mut self,
tree: &'b mut Tree, tree: &'b mut Tree,
layout: Layout<'_>, layout: Layout<'_>,
renderer: &Renderer, renderer: &Renderer,
@ -216,12 +216,12 @@ where
cached: self, cached: self,
tree: &mut tree.children[0], tree: &mut tree.children[0],
types: PhantomData, types: PhantomData,
element_ref_builder: |cached| cached.element.borrow(), overlay_builder: |cached, tree| {
element_builder: |element_ref| { Rc::get_mut(cached.element.get_mut().as_mut().unwrap())
element_ref.as_ref().unwrap().borrow() .unwrap()
}, .get_mut()
overlay_builder: |element, tree| { .as_widget_mut()
element.as_widget().overlay(tree, layout, renderer) .overlay(tree, layout, renderer)
}, },
} }
.build(); .build();
@ -237,20 +237,11 @@ where
#[self_referencing] #[self_referencing]
struct Overlay<'a, 'b, Message, Renderer, Dependency, View> { struct Overlay<'a, 'b, Message, Renderer, Dependency, View> {
cached: &'a Lazy<'b, Message, Renderer, Dependency, View>, cached: &'a mut Lazy<'b, Message, Renderer, Dependency, View>,
tree: &'a mut Tree, tree: &'a mut Tree,
types: PhantomData<(Message, Dependency, View)>, types: PhantomData<(Message, Dependency, View)>,
#[borrows(cached)] #[borrows(mut cached, mut tree)]
#[covariant]
element_ref:
Ref<'this, Option<Rc<RefCell<Element<'static, Message, Renderer>>>>>,
#[borrows(element_ref)]
#[covariant]
element: Ref<'this, Element<'static, Message, Renderer>>,
#[borrows(element, mut tree)]
#[covariant] #[covariant]
overlay: Option<overlay::Element<'this, Message, Renderer>>, overlay: Option<overlay::Element<'this, Message, Renderer>>,
} }

View file

@ -235,18 +235,20 @@ where
} }
fn overlay<'b>( fn overlay<'b>(
&'b self, &'b mut self,
tree: &'b mut Tree, tree: &'b mut Tree,
layout: Layout<'_>, layout: Layout<'_>,
renderer: &Renderer, renderer: &Renderer,
) -> Option<overlay::Element<'b, Message, Renderer>> { ) -> Option<overlay::Element<'b, Message, Renderer>> {
use std::ops::DerefMut;
let state = tree.state.downcast_ref::<State>(); let state = tree.state.downcast_ref::<State>();
let overlay = OverlayBuilder { let overlay = OverlayBuilder {
content: self.content.borrow_mut(), content: self.content.borrow_mut(),
tree: state.tree.borrow_mut(), tree: state.tree.borrow_mut(),
types: PhantomData, types: PhantomData,
overlay_builder: |content, tree| { overlay_builder: |content: &mut RefMut<Content<_, _>>, tree| {
content.update( content.update(
tree, tree,
renderer, renderer,
@ -254,16 +256,18 @@ where
&self.view, &self.view,
); );
let Content {
element, layout, ..
} = content.deref_mut();
let content_layout = Layout::with_offset( let content_layout = Layout::with_offset(
layout.position() - Point::ORIGIN, layout.bounds().position() - Point::ORIGIN,
&content.layout, layout,
); );
content.element.as_widget().overlay( element
tree, .as_widget_mut()
content_layout, .overlay(tree, content_layout, renderer)
renderer,
)
}, },
} }
.build(); .build();

View file

@ -405,7 +405,7 @@ where
} }
fn overlay<'b>( fn overlay<'b>(
&'b self, &'b mut self,
tree: &'b mut Tree, tree: &'b mut Tree,
layout: Layout<'_>, layout: Layout<'_>,
renderer: &Renderer, renderer: &Renderer,
@ -560,7 +560,7 @@ where
} }
fn overlay<'b>( fn overlay<'b>(
&'b self, &'b mut self,
state: &'b mut Tree, state: &'b mut Tree,
layout: Layout<'_>, layout: Layout<'_>,
renderer: &Renderer, renderer: &Renderer,

View file

@ -93,7 +93,7 @@ where
/// This method will generally only be used by advanced users that are /// This method will generally only be used by advanced users that are
/// implementing the [`Widget`](crate::Widget) trait. /// implementing the [`Widget`](crate::Widget) trait.
pub fn from_children<'a, Message, Renderer>( pub fn from_children<'a, Message, Renderer>(
children: &'a [crate::Element<'_, Message, Renderer>], children: &'a mut [crate::Element<'_, Message, Renderer>],
tree: &'a mut Tree, tree: &'a mut Tree,
layout: Layout<'_>, layout: Layout<'_>,
renderer: &Renderer, renderer: &Renderer,
@ -102,11 +102,11 @@ where
Renderer: crate::Renderer, Renderer: crate::Renderer,
{ {
children children
.iter() .iter_mut()
.zip(&mut tree.children) .zip(&mut tree.children)
.zip(layout.children()) .zip(layout.children())
.filter_map(|((child, state), layout)| { .filter_map(|((child, state), layout)| {
child.as_widget().overlay(state, layout, renderer) child.as_widget_mut().overlay(state, layout, renderer)
}) })
.next() .next()
} }

View file

@ -190,7 +190,7 @@ where
let mut state = State::Updated; let mut state = State::Updated;
let mut manual_overlay = let mut manual_overlay =
ManuallyDrop::new(self.root.as_widget().overlay( ManuallyDrop::new(self.root.as_widget_mut().overlay(
&mut self.state, &mut self.state,
Layout::new(&self.base), Layout::new(&self.base),
renderer, renderer,
@ -226,7 +226,7 @@ where
); );
manual_overlay = manual_overlay =
ManuallyDrop::new(self.root.as_widget().overlay( ManuallyDrop::new(self.root.as_widget_mut().overlay(
&mut self.state, &mut self.state,
Layout::new(&self.base), Layout::new(&self.base),
renderer, renderer,
@ -395,11 +395,11 @@ where
let viewport = Rectangle::with_size(self.bounds); let viewport = Rectangle::with_size(self.bounds);
let base_cursor = if let Some(overlay) = self.root.as_widget().overlay( let base_cursor = if let Some(overlay) = self
&mut self.state, .root
Layout::new(&self.base), .as_widget_mut()
renderer, .overlay(&mut self.state, Layout::new(&self.base), renderer)
) { {
let overlay_layout = self let overlay_layout = self
.overlay .overlay
.take() .take()
@ -452,7 +452,7 @@ where
overlay overlay
.as_ref() .as_ref()
.and_then(|layout| { .and_then(|layout| {
root.as_widget() root.as_widget_mut()
.overlay(&mut self.state, Layout::new(base), renderer) .overlay(&mut self.state, Layout::new(base), renderer)
.map(|overlay| { .map(|overlay| {
let overlay_interaction = overlay.mouse_interaction( let overlay_interaction = overlay.mouse_interaction(
@ -497,7 +497,7 @@ where
); );
if let Some(layout) = self.overlay.as_ref() { if let Some(layout) = self.overlay.as_ref() {
if let Some(overlay) = self.root.as_widget().overlay( if let Some(overlay) = self.root.as_widget_mut().overlay(
&mut self.state, &mut self.state,
Layout::new(&self.base), Layout::new(&self.base),
renderer, renderer,

View file

@ -208,7 +208,7 @@ where
/// Returns the overlay of the [`Widget`], if there is any. /// Returns the overlay of the [`Widget`], if there is any.
fn overlay<'a>( fn overlay<'a>(
&'a self, &'a mut self,
_state: &'a mut Tree, _state: &'a mut Tree,
_layout: Layout<'_>, _layout: Layout<'_>,
_renderer: &Renderer, _renderer: &Renderer,

View file

@ -260,12 +260,12 @@ where
} }
fn overlay<'b>( fn overlay<'b>(
&'b self, &'b mut self,
tree: &'b mut Tree, tree: &'b mut Tree,
layout: Layout<'_>, layout: Layout<'_>,
renderer: &Renderer, renderer: &Renderer,
) -> Option<overlay::Element<'b, Message, Renderer>> { ) -> Option<overlay::Element<'b, Message, Renderer>> {
self.content.as_widget().overlay( self.content.as_widget_mut().overlay(
&mut tree.children[0], &mut tree.children[0],
layout.children().next().unwrap(), layout.children().next().unwrap(),
renderer, renderer,

View file

@ -242,12 +242,12 @@ where
} }
fn overlay<'b>( fn overlay<'b>(
&'b self, &'b mut self,
tree: &'b mut Tree, tree: &'b mut Tree,
layout: Layout<'_>, layout: Layout<'_>,
renderer: &Renderer, renderer: &Renderer,
) -> Option<overlay::Element<'b, Message, Renderer>> { ) -> Option<overlay::Element<'b, Message, Renderer>> {
overlay::from_children(&self.children, tree, layout, renderer) overlay::from_children(&mut self.children, tree, layout, renderer)
} }
} }

View file

@ -248,12 +248,12 @@ where
} }
fn overlay<'b>( fn overlay<'b>(
&'b self, &'b mut self,
tree: &'b mut Tree, tree: &'b mut Tree,
layout: Layout<'_>, layout: Layout<'_>,
renderer: &Renderer, renderer: &Renderer,
) -> Option<overlay::Element<'b, Message, Renderer>> { ) -> Option<overlay::Element<'b, Message, Renderer>> {
self.content.as_widget().overlay( self.content.as_widget_mut().overlay(
&mut tree.children[0], &mut tree.children[0],
layout.children().next().unwrap(), layout.children().next().unwrap(),
renderer, renderer,

View file

@ -444,13 +444,13 @@ where
} }
fn overlay<'b>( fn overlay<'b>(
&'b self, &'b mut self,
tree: &'b mut Tree, tree: &'b mut Tree,
layout: Layout<'_>, layout: Layout<'_>,
renderer: &Renderer, renderer: &Renderer,
) -> Option<overlay::Element<'_, Message, Renderer>> { ) -> Option<overlay::Element<'_, Message, Renderer>> {
self.contents self.contents
.iter() .iter_mut()
.zip(&mut tree.children) .zip(&mut tree.children)
.zip(layout.children()) .zip(layout.children())
.filter_map(|(((_, pane), tree), layout)| { .filter_map(|(((_, pane), tree), layout)| {

View file

@ -305,12 +305,12 @@ where
} }
pub(crate) fn overlay<'b>( pub(crate) fn overlay<'b>(
&'b self, &'b mut self,
tree: &'b mut Tree, tree: &'b mut Tree,
layout: Layout<'_>, layout: Layout<'_>,
renderer: &Renderer, renderer: &Renderer,
) -> Option<overlay::Element<'b, Message, Renderer>> { ) -> Option<overlay::Element<'b, Message, Renderer>> {
if let Some(title_bar) = self.title_bar.as_ref() { if let Some(title_bar) = self.title_bar.as_mut() {
let mut children = layout.children(); let mut children = layout.children();
let title_bar_layout = children.next()?; let title_bar_layout = children.next()?;
@ -321,14 +321,14 @@ where
match title_bar.overlay(title_bar_state, title_bar_layout, renderer) match title_bar.overlay(title_bar_state, title_bar_layout, renderer)
{ {
Some(overlay) => Some(overlay), Some(overlay) => Some(overlay),
None => self.body.as_widget().overlay( None => self.body.as_widget_mut().overlay(
body_state, body_state,
children.next()?, children.next()?,
renderer, renderer,
), ),
} }
} else { } else {
self.body.as_widget().overlay( self.body.as_widget_mut().overlay(
&mut tree.children[0], &mut tree.children[0],
layout, layout,
renderer, renderer,

View file

@ -395,7 +395,7 @@ where
} }
pub(crate) fn overlay<'b>( pub(crate) fn overlay<'b>(
&'b self, &'b mut self,
tree: &'b mut Tree, tree: &'b mut Tree,
layout: Layout<'_>, layout: Layout<'_>,
renderer: &Renderer, renderer: &Renderer,
@ -415,13 +415,13 @@ where
let controls_state = states.next().unwrap(); let controls_state = states.next().unwrap();
content content
.as_widget() .as_widget_mut()
.overlay(title_state, title_layout, renderer) .overlay(title_state, title_layout, renderer)
.or_else(move || { .or_else(move || {
controls.as_ref().and_then(|controls| { controls.as_mut().and_then(|controls| {
let controls_layout = children.next()?; let controls_layout = children.next()?;
controls.as_widget().overlay( controls.as_widget_mut().overlay(
controls_state, controls_state,
controls_layout, controls_layout,
renderer, renderer,

View file

@ -219,7 +219,7 @@ where
} }
fn overlay<'b>( fn overlay<'b>(
&'b self, &'b mut self,
tree: &'b mut Tree, tree: &'b mut Tree,
layout: Layout<'_>, layout: Layout<'_>,
_renderer: &Renderer, _renderer: &Renderer,

View file

@ -229,12 +229,12 @@ where
} }
fn overlay<'b>( fn overlay<'b>(
&'b self, &'b mut self,
tree: &'b mut Tree, tree: &'b mut Tree,
layout: Layout<'_>, layout: Layout<'_>,
renderer: &Renderer, renderer: &Renderer,
) -> Option<overlay::Element<'b, Message, Renderer>> { ) -> Option<overlay::Element<'b, Message, Renderer>> {
overlay::from_children(&self.children, tree, layout, renderer) overlay::from_children(&mut self.children, tree, layout, renderer)
} }
} }

View file

@ -276,13 +276,13 @@ where
} }
fn overlay<'b>( fn overlay<'b>(
&'b self, &'b mut self,
tree: &'b mut Tree, tree: &'b mut Tree,
layout: Layout<'_>, layout: Layout<'_>,
renderer: &Renderer, renderer: &Renderer,
) -> Option<overlay::Element<'b, Message, Renderer>> { ) -> Option<overlay::Element<'b, Message, Renderer>> {
self.content self.content
.as_widget() .as_widget_mut()
.overlay( .overlay(
&mut tree.children[0], &mut tree.children[0],
layout.children().next().unwrap(), layout.children().next().unwrap(),

View file

@ -221,12 +221,12 @@ where
} }
fn overlay<'b>( fn overlay<'b>(
&'b self, &'b mut self,
tree: &'b mut Tree, tree: &'b mut Tree,
layout: Layout<'_>, layout: Layout<'_>,
renderer: &Renderer, renderer: &Renderer,
) -> Option<overlay::Element<'b, Message, Renderer>> { ) -> Option<overlay::Element<'b, Message, Renderer>> {
self.content.as_widget().overlay( self.content.as_widget_mut().overlay(
&mut tree.children[0], &mut tree.children[0],
layout, layout,
renderer, renderer,