diff options
| author | 2023-03-05 06:23:40 +0100 | |
|---|---|---|
| committer | 2023-03-05 06:23:40 +0100 | |
| commit | 8af69be47e88896b3c5f70174db609eee0c67971 (patch) | |
| tree | bf9b04335def215c2c3bacda2afe4c2125346dc8 /native | |
| parent | 43414bbdfb080b7aa3c702d944cc9d0c9c0fd14b (diff) | |
| download | iced-8af69be47e88896b3c5f70174db609eee0c67971.tar.gz iced-8af69be47e88896b3c5f70174db609eee0c67971.tar.bz2 iced-8af69be47e88896b3c5f70174db609eee0c67971.zip | |
Converge `Command` types from `iced_futures` and `iced_native`
Diffstat (limited to 'native')
| -rw-r--r-- | native/src/command.rs | 59 | ||||
| -rw-r--r-- | native/src/command/action.rs | 8 | ||||
| -rw-r--r-- | native/src/lib.rs | 1 | ||||
| -rw-r--r-- | native/src/widget.rs | 16 | ||||
| -rw-r--r-- | native/src/widget/action.rs | 153 | 
5 files changed, 45 insertions, 192 deletions
| diff --git a/native/src/command.rs b/native/src/command.rs index 39bee8f6..cd4c51ff 100644 --- a/native/src/command.rs +++ b/native/src/command.rs @@ -3,37 +3,39 @@ mod action;  pub use action::Action; -use crate::widget; - -use iced_futures::MaybeSend; +use crate::core::widget; +use crate::futures::MaybeSend;  use std::fmt;  use std::future::Future;  /// A set of asynchronous actions to be performed by some runtime.  #[must_use = "`Command` must be returned to runtime to take effect"] -pub struct Command<T>(iced_futures::Command<Action<T>>); +pub struct Command<T>(Internal<Action<T>>); + +#[derive(Debug)] +enum Internal<T> { +    None, +    Single(T), +    Batch(Vec<T>), +}  impl<T> Command<T> {      /// Creates an empty [`Command`].      ///      /// In other words, a [`Command`] that does nothing.      pub const fn none() -> Self { -        Self(iced_futures::Command::none()) +        Self(Internal::None)      }      /// Creates a [`Command`] that performs a single [`Action`].      pub const fn single(action: Action<T>) -> Self { -        Self(iced_futures::Command::single(action)) +        Self(Internal::Single(action))      }      /// Creates a [`Command`] that performs a [`widget::Operation`]. -    pub fn widget( -        operation: impl iced_core::widget::Operation<T> + 'static, -    ) -> Self { -        Self(iced_futures::Command::single(Action::Widget( -            widget::Action::new(operation), -        ))) +    pub fn widget(operation: impl widget::Operation<T> + 'static) -> Self { +        Self::single(Action::Widget(Box::new(operation)))      }      /// Creates a [`Command`] that performs the action of the given future. @@ -51,9 +53,17 @@ impl<T> Command<T> {      ///      /// Once this command is run, all the commands will be executed at once.      pub fn batch(commands: impl IntoIterator<Item = Command<T>>) -> Self { -        Self(iced_futures::Command::batch( -            commands.into_iter().map(|Command(command)| command), -        )) +        let mut batch = Vec::new(); + +        for Command(command) in commands { +            match command { +                Internal::None => {} +                Internal::Single(command) => batch.push(command), +                Internal::Batch(commands) => batch.extend(commands), +            } +        } + +        Self(Internal::Batch(batch))      }      /// Applies a transformation to the result of a [`Command`]. @@ -65,16 +75,27 @@ impl<T> Command<T> {          T: 'static,          A: 'static,      { -        let Command(command) = self; - -        Command(command.map(move |action| action.map(f.clone()))) +        match self.0 { +            Internal::None => Command::none(), +            Internal::Single(action) => Command::single(action.map(f)), +            Internal::Batch(batch) => Command(Internal::Batch( +                batch +                    .into_iter() +                    .map(|action| action.map(f.clone())) +                    .collect(), +            )), +        }      }      /// Returns all of the actions of the [`Command`].      pub fn actions(self) -> Vec<Action<T>> {          let Command(command) = self; -        command.actions() +        match command { +            Internal::None => Vec::new(), +            Internal::Single(action) => vec![action], +            Internal::Batch(batch) => batch, +        }      }  } diff --git a/native/src/command/action.rs b/native/src/command/action.rs index d1589c05..6c74f0ef 100644 --- a/native/src/command/action.rs +++ b/native/src/command/action.rs @@ -1,7 +1,7 @@  use crate::clipboard; +use crate::core::widget;  use crate::font;  use crate::system; -use crate::widget;  use crate::window;  use iced_futures::MaybeSend; @@ -28,7 +28,7 @@ pub enum Action<T> {      System(system::Action<T>),      /// Run a widget action. -    Widget(widget::Action<T>), +    Widget(Box<dyn widget::Operation<T>>),      /// Load a font from its bytes.      LoadFont { @@ -59,7 +59,9 @@ impl<T> Action<T> {              Self::Clipboard(action) => Action::Clipboard(action.map(f)),              Self::Window(window) => Action::Window(window.map(f)),              Self::System(system) => Action::System(system.map(f)), -            Self::Widget(widget) => Action::Widget(widget.map(f)), +            Self::Widget(operation) => { +                Action::Widget(Box::new(widget::operation::map(operation, f))) +            }              Self::LoadFont { bytes, tagger } => Action::LoadFont {                  bytes,                  tagger: Box::new(move |result| f(tagger(result))), diff --git a/native/src/lib.rs b/native/src/lib.rs index 2d2e5b38..aa45e57a 100644 --- a/native/src/lib.rs +++ b/native/src/lib.rs @@ -50,7 +50,6 @@ pub mod keyboard;  pub mod program;  pub mod system;  pub mod user_interface; -pub mod widget;  pub mod window;  // We disable debug capabilities on release builds unless the `debug` feature diff --git a/native/src/widget.rs b/native/src/widget.rs deleted file mode 100644 index 0fdade54..00000000 --- a/native/src/widget.rs +++ /dev/null @@ -1,16 +0,0 @@ -//! Use the built-in widgets or create your own. -//! -//! # Built-in widgets -//! Every built-in drawable widget has its own module with a `Renderer` trait -//! that must be implemented by a [renderer] before being able to use it as -//! a [`Widget`]. -//! -//! # Custom widgets -//! If you want to implement a custom widget, you simply need to implement the -//! [`Widget`] trait. You can use the API of the built-in widgets as a guide or -//! source of inspiration. -//! -//! [renderer]: crate::renderer -mod action; - -pub use action::Action; diff --git a/native/src/widget/action.rs b/native/src/widget/action.rs deleted file mode 100644 index f50d7aec..00000000 --- a/native/src/widget/action.rs +++ /dev/null @@ -1,153 +0,0 @@ -use iced_core::widget::operation::{ -    self, Focusable, Operation, Scrollable, TextInput, -}; -use iced_core::widget::Id; -use iced_futures::MaybeSend; - -use std::any::Any; -use std::rc::Rc; - -/// 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: Rc::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: Rc<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> { -            operation: &'a mut dyn Operation<A>, -        } - -        impl<'a, A, B> Operation<B> for MapRef<'a, A> { -            fn container( -                &mut self, -                id: Option<&Id>, -                operate_on_children: &mut dyn FnMut(&mut dyn Operation<B>), -            ) { -                let Self { operation, .. } = self; - -                operation.container(id, &mut |operation| { -                    operate_on_children(&mut MapRef { operation }); -                }); -            } - -            fn scrollable( -                &mut self, -                state: &mut dyn Scrollable, -                id: Option<&Id>, -            ) { -                self.operation.scrollable(state, id); -            } - -            fn focusable( -                &mut self, -                state: &mut dyn Focusable, -                id: Option<&Id>, -            ) { -                self.operation.focusable(state, id); -            } - -            fn text_input( -                &mut self, -                state: &mut dyn TextInput, -                id: Option<&Id>, -            ) { -                self.operation.text_input(state, id); -            } - -            fn custom(&mut self, state: &mut dyn Any, id: Option<&Id>) { -                self.operation.custom(state, id); -            } -        } - -        let Self { operation, .. } = self; - -        MapRef { -            operation: operation.as_mut(), -        } -        .container(id, operate_on_children); -    } - -    fn focusable( -        &mut self, -        state: &mut dyn operation::Focusable, -        id: Option<&Id>, -    ) { -        self.operation.focusable(state, id); -    } - -    fn scrollable( -        &mut self, -        state: &mut dyn operation::Scrollable, -        id: Option<&Id>, -    ) { -        self.operation.scrollable(state, id); -    } - -    fn text_input( -        &mut self, -        state: &mut dyn operation::TextInput, -        id: Option<&Id>, -    ) { -        self.operation.text_input(state, id); -    } - -    fn custom(&mut self, state: &mut dyn Any, id: Option<&Id>) { -        self.operation.custom(state, id); -    } - -    fn finish(&self) -> operation::Outcome<B> { -        match self.operation.finish() { -            operation::Outcome::None => operation::Outcome::None, -            operation::Outcome::Some(output) => { -                operation::Outcome::Some((self.f)(output)) -            } -            operation::Outcome::Chain(next) => { -                operation::Outcome::Chain(Box::new(Map { -                    operation: next, -                    f: self.f.clone(), -                })) -            } -        } -    } -} | 
