diff options
author | 2022-08-06 00:32:57 +0200 | |
---|---|---|
committer | 2022-08-06 00:32:57 +0200 | |
commit | 1923dbf7f0769d55e5283f572fde0ce752e28b86 (patch) | |
tree | 7be9b36f941f6e13ddc8884f715c04555b1e77db /native/src/widget/action.rs | |
parent | 1b4f38c71f6e05e26599ee75ea9c91dde96e71ae (diff) | |
parent | c23ed7e4a0a2b62a0d7cabe6e35d7323eac543d2 (diff) | |
download | iced-1923dbf7f0769d55e5283f572fde0ce752e28b86.tar.gz iced-1923dbf7f0769d55e5283f572fde0ce752e28b86.tar.bz2 iced-1923dbf7f0769d55e5283f572fde0ce752e28b86.zip |
Merge pull request #1393 from iced-rs/deprecate-stateful-widgets
Replace stateful widgets with the new `iced_pure` API
Diffstat (limited to 'native/src/widget/action.rs')
-rw-r--r-- | native/src/widget/action.rs | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/native/src/widget/action.rs b/native/src/widget/action.rs new file mode 100644 index 00000000..766e902b --- /dev/null +++ b/native/src/widget/action.rs @@ -0,0 +1,88 @@ +use crate::widget::operation::{self, Operation}; +use crate::widget::Id; + +use iced_futures::MaybeSend; + +/// An operation to be performed on the widget tree. +#[allow(missing_debug_implementations)] +pub struct Action<T>(Box<dyn Operation<T>>); + +impl<T> Action<T> { + /// Creates a new [`Action`] with the given [`Operation`]. + pub fn new(operation: impl Operation<T> + 'static) -> Self { + Self(Box::new(operation)) + } + + /// Maps the output of an [`Action`] using the given function. + pub fn map<A>( + self, + f: impl Fn(T) -> A + 'static + MaybeSend + Sync, + ) -> Action<A> + where + T: 'static, + A: 'static, + { + Action(Box::new(Map { + operation: self.0, + f: Box::new(f), + })) + } + + /// Consumes the [`Action`] and returns the internal [`Operation`]. + pub fn into_operation(self) -> Box<dyn Operation<T>> { + self.0 + } +} + +#[allow(missing_debug_implementations)] +struct Map<A, B> { + operation: Box<dyn Operation<A>>, + f: Box<dyn Fn(A) -> B>, +} + +impl<A, B> Operation<B> for Map<A, B> +where + A: 'static, + B: 'static, +{ + fn container( + &mut self, + id: Option<&Id>, + operate_on_children: &mut dyn FnMut(&mut dyn Operation<B>), + ) { + struct MapRef<'a, A, B> { + operation: &'a mut dyn Operation<A>, + f: &'a dyn Fn(A) -> B, + } + + impl<'a, A, B> Operation<B> for MapRef<'a, A, B> { + fn container( + &mut self, + id: Option<&Id>, + operate_on_children: &mut dyn FnMut(&mut dyn Operation<B>), + ) { + let Self { operation, f } = self; + + operation.container(id, &mut |operation| { + operate_on_children(&mut MapRef { operation, f }); + }); + } + } + + let Self { operation, f } = self; + + MapRef { + operation: operation.as_mut(), + f, + } + .container(id, operate_on_children); + } + + fn focusable( + &mut self, + state: &mut dyn operation::Focusable, + id: Option<&Id>, + ) { + self.operation.focusable(state, id); + } +} |