Converge Command types from iced_futures and iced_native
This commit is contained in:
parent
43414bbdfb
commit
8af69be47e
9 changed files with 161 additions and 266 deletions
|
|
@ -11,6 +11,7 @@ use crate::widget::Id;
|
|||
|
||||
use std::any::Any;
|
||||
use std::fmt;
|
||||
use std::rc::Rc;
|
||||
|
||||
/// A piece of logic that can traverse the widget tree of an application in
|
||||
/// order to query or update some widget state.
|
||||
|
|
@ -68,9 +69,122 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
/// Maps the output of an [`Operation`] using the given function.
|
||||
pub fn map<A, B>(
|
||||
operation: Box<dyn Operation<A>>,
|
||||
f: impl Fn(A) -> B + 'static,
|
||||
) -> impl Operation<B>
|
||||
where
|
||||
A: 'static,
|
||||
B: 'static,
|
||||
{
|
||||
#[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 Focusable, id: Option<&Id>) {
|
||||
self.operation.focusable(state, id);
|
||||
}
|
||||
|
||||
fn scrollable(&mut self, state: &mut dyn Scrollable, id: Option<&Id>) {
|
||||
self.operation.scrollable(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);
|
||||
}
|
||||
|
||||
fn finish(&self) -> Outcome<B> {
|
||||
match self.operation.finish() {
|
||||
Outcome::None => Outcome::None,
|
||||
Outcome::Some(output) => Outcome::Some((self.f)(output)),
|
||||
Outcome::Chain(next) => Outcome::Chain(Box::new(Map {
|
||||
operation: next,
|
||||
f: self.f.clone(),
|
||||
})),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Map {
|
||||
operation,
|
||||
f: Rc::new(f),
|
||||
}
|
||||
}
|
||||
|
||||
/// Produces an [`Operation`] that applies the given [`Operation`] to the
|
||||
/// children of a container with the given [`Id`].
|
||||
pub fn scoped<T: 'static>(
|
||||
pub fn scope<T: 'static>(
|
||||
target: Id,
|
||||
operation: impl Operation<T> + 'static,
|
||||
) -> impl Operation<T> {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue