Introduce new iced_selector subcrate and refactor Operation
This commit is contained in:
parent
8ca25d627f
commit
63142d34fc
29 changed files with 839 additions and 521 deletions
|
|
@ -18,25 +18,16 @@ use std::sync::Arc;
|
|||
/// A piece of logic that can traverse the widget tree of an application in
|
||||
/// order to query or update some widget state.
|
||||
pub trait Operation<T = ()>: Send {
|
||||
/// Operates on a widget that contains other widgets.
|
||||
/// Requests further traversal of the widget tree to keep operating.
|
||||
///
|
||||
/// The `operate_on_children` function can be called to return control to
|
||||
/// the widget tree and keep traversing it.
|
||||
fn container(
|
||||
&mut self,
|
||||
id: Option<&Id>,
|
||||
bounds: Rectangle,
|
||||
operate_on_children: &mut dyn FnMut(&mut dyn Operation<T>),
|
||||
);
|
||||
/// The provided `operate` closure may be called by an [`Operation`]
|
||||
/// to return control to the widget tree and keep traversing it. If
|
||||
/// the closure is not called, the children of the widget asking for
|
||||
/// traversal will be skipped.
|
||||
fn traverse(&mut self, operate: &mut dyn FnMut(&mut dyn Operation<T>));
|
||||
|
||||
/// Operates on a widget that can be focused.
|
||||
fn focusable(
|
||||
&mut self,
|
||||
_id: Option<&Id>,
|
||||
_bounds: Rectangle,
|
||||
_state: &mut dyn Focusable,
|
||||
) {
|
||||
}
|
||||
/// Operates on a widget that contains other widgets.
|
||||
fn container(&mut self, _id: Option<&Id>, _bounds: Rectangle) {}
|
||||
|
||||
/// Operates on a widget that can be scrolled.
|
||||
fn scrollable(
|
||||
|
|
@ -49,6 +40,15 @@ pub trait Operation<T = ()>: Send {
|
|||
) {
|
||||
}
|
||||
|
||||
/// Operates on a widget that can be focused.
|
||||
fn focusable(
|
||||
&mut self,
|
||||
_id: Option<&Id>,
|
||||
_bounds: Rectangle,
|
||||
_state: &mut dyn Focusable,
|
||||
) {
|
||||
}
|
||||
|
||||
/// Operates on a widget that has text input.
|
||||
fn text_input(
|
||||
&mut self,
|
||||
|
|
@ -80,13 +80,12 @@ impl<T, O> Operation<O> for Box<T>
|
|||
where
|
||||
T: Operation<O> + ?Sized,
|
||||
{
|
||||
fn container(
|
||||
&mut self,
|
||||
id: Option<&Id>,
|
||||
bounds: Rectangle,
|
||||
operate_on_children: &mut dyn FnMut(&mut dyn Operation<O>),
|
||||
) {
|
||||
self.as_mut().container(id, bounds, operate_on_children);
|
||||
fn traverse(&mut self, operate: &mut dyn FnMut(&mut dyn Operation<O>)) {
|
||||
self.as_mut().traverse(operate);
|
||||
}
|
||||
|
||||
fn container(&mut self, id: Option<&Id>, bounds: Rectangle) {
|
||||
self.as_mut().container(id, bounds);
|
||||
}
|
||||
|
||||
fn focusable(
|
||||
|
|
@ -179,17 +178,19 @@ where
|
|||
}
|
||||
|
||||
impl<T, O> Operation<O> for BlackBox<'_, T> {
|
||||
fn container(
|
||||
&mut self,
|
||||
id: Option<&Id>,
|
||||
bounds: Rectangle,
|
||||
operate_on_children: &mut dyn FnMut(&mut dyn Operation<O>),
|
||||
) {
|
||||
self.operation.container(id, bounds, &mut |operation| {
|
||||
operate_on_children(&mut BlackBox { operation });
|
||||
fn traverse(&mut self, operate: &mut dyn FnMut(&mut dyn Operation<O>))
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
self.operation.traverse(&mut |operation| {
|
||||
operate(&mut BlackBox { operation });
|
||||
});
|
||||
}
|
||||
|
||||
fn container(&mut self, id: Option<&Id>, bounds: Rectangle) {
|
||||
self.operation.container(id, bounds);
|
||||
}
|
||||
|
||||
fn focusable(
|
||||
&mut self,
|
||||
id: Option<&Id>,
|
||||
|
|
@ -267,28 +268,25 @@ where
|
|||
A: 'static,
|
||||
B: 'static,
|
||||
{
|
||||
fn container(
|
||||
&mut self,
|
||||
id: Option<&Id>,
|
||||
bounds: Rectangle,
|
||||
operate_on_children: &mut dyn FnMut(&mut dyn Operation<B>),
|
||||
) {
|
||||
fn traverse(&mut self, operate: &mut dyn FnMut(&mut dyn Operation<B>)) {
|
||||
struct MapRef<'a, A> {
|
||||
operation: &'a mut dyn Operation<A>,
|
||||
}
|
||||
|
||||
impl<A, B> Operation<B> for MapRef<'_, A> {
|
||||
fn container(
|
||||
fn traverse(
|
||||
&mut self,
|
||||
id: Option<&Id>,
|
||||
bounds: Rectangle,
|
||||
operate_on_children: &mut dyn FnMut(&mut dyn Operation<B>),
|
||||
operate: &mut dyn FnMut(&mut dyn Operation<B>),
|
||||
) {
|
||||
self.operation.traverse(&mut |operation| {
|
||||
operate(&mut MapRef { operation });
|
||||
});
|
||||
}
|
||||
|
||||
fn container(&mut self, id: Option<&Id>, bounds: Rectangle) {
|
||||
let Self { operation, .. } = self;
|
||||
|
||||
operation.container(id, bounds, &mut |operation| {
|
||||
operate_on_children(&mut MapRef { operation });
|
||||
});
|
||||
operation.container(id, bounds);
|
||||
}
|
||||
|
||||
fn scrollable(
|
||||
|
|
@ -345,9 +343,13 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
let Self { operation, .. } = self;
|
||||
self.operation.traverse(&mut |operation| {
|
||||
operate(&mut MapRef { operation });
|
||||
});
|
||||
}
|
||||
|
||||
MapRef { operation }.container(id, bounds, operate_on_children);
|
||||
fn container(&mut self, id: Option<&Id>, bounds: Rectangle) {
|
||||
self.operation.container(id, bounds);
|
||||
}
|
||||
|
||||
fn focusable(
|
||||
|
|
@ -444,17 +446,16 @@ where
|
|||
A: 'static,
|
||||
B: Send + 'static,
|
||||
{
|
||||
fn container(
|
||||
&mut self,
|
||||
id: Option<&Id>,
|
||||
bounds: Rectangle,
|
||||
operate_on_children: &mut dyn FnMut(&mut dyn Operation<B>),
|
||||
) {
|
||||
self.operation.container(id, bounds, &mut |operation| {
|
||||
operate_on_children(&mut black_box(operation));
|
||||
fn traverse(&mut self, operate: &mut dyn FnMut(&mut dyn Operation<B>)) {
|
||||
self.operation.traverse(&mut |operation| {
|
||||
operate(&mut black_box(operation));
|
||||
});
|
||||
}
|
||||
|
||||
fn container(&mut self, id: Option<&Id>, bounds: Rectangle) {
|
||||
self.operation.container(id, bounds);
|
||||
}
|
||||
|
||||
fn focusable(
|
||||
&mut self,
|
||||
id: Option<&Id>,
|
||||
|
|
@ -531,21 +532,26 @@ pub fn scope<T: 'static>(
|
|||
) -> impl Operation<T> {
|
||||
struct ScopedOperation<Message> {
|
||||
target: Id,
|
||||
current: Option<Id>,
|
||||
operation: Box<dyn Operation<Message>>,
|
||||
}
|
||||
|
||||
impl<Message: 'static> Operation<Message> for ScopedOperation<Message> {
|
||||
fn container(
|
||||
fn traverse(
|
||||
&mut self,
|
||||
id: Option<&Id>,
|
||||
_bounds: Rectangle,
|
||||
operate_on_children: &mut dyn FnMut(&mut dyn Operation<Message>),
|
||||
operate: &mut dyn FnMut(&mut dyn Operation<Message>),
|
||||
) {
|
||||
if id == Some(&self.target) {
|
||||
operate_on_children(self.operation.as_mut());
|
||||
if self.current.as_ref() == Some(&self.target) {
|
||||
self.operation.as_mut().traverse(operate);
|
||||
} else {
|
||||
operate_on_children(self);
|
||||
operate(self);
|
||||
}
|
||||
|
||||
self.current = None;
|
||||
}
|
||||
|
||||
fn container(&mut self, id: Option<&Id>, _bounds: Rectangle) {
|
||||
self.current = id.cloned();
|
||||
}
|
||||
|
||||
fn finish(&self) -> Outcome<Message> {
|
||||
|
|
@ -553,6 +559,7 @@ pub fn scope<T: 'static>(
|
|||
Outcome::Chain(next) => {
|
||||
Outcome::Chain(Box::new(ScopedOperation {
|
||||
target: self.target.clone(),
|
||||
current: None,
|
||||
operation: next,
|
||||
}))
|
||||
}
|
||||
|
|
@ -563,6 +570,7 @@ pub fn scope<T: 'static>(
|
|||
|
||||
ScopedOperation {
|
||||
target,
|
||||
current: None,
|
||||
operation: Box::new(operation),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,13 +48,8 @@ pub fn focus<T>(target: Id) -> impl Operation<T> {
|
|||
}
|
||||
}
|
||||
|
||||
fn container(
|
||||
&mut self,
|
||||
_id: Option<&Id>,
|
||||
_bounds: Rectangle,
|
||||
operate_on_children: &mut dyn FnMut(&mut dyn Operation<T>),
|
||||
) {
|
||||
operate_on_children(self);
|
||||
fn traverse(&mut self, operate: &mut dyn FnMut(&mut dyn Operation<T>)) {
|
||||
operate(self);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -75,13 +70,8 @@ pub fn unfocus<T>() -> impl Operation<T> {
|
|||
state.unfocus();
|
||||
}
|
||||
|
||||
fn container(
|
||||
&mut self,
|
||||
_id: Option<&Id>,
|
||||
_bounds: Rectangle,
|
||||
operate_on_children: &mut dyn FnMut(&mut dyn Operation<T>),
|
||||
) {
|
||||
operate_on_children(self);
|
||||
fn traverse(&mut self, operate: &mut dyn FnMut(&mut dyn Operation<T>)) {
|
||||
operate(self);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -109,13 +99,11 @@ pub fn count() -> impl Operation<Count> {
|
|||
self.count.total += 1;
|
||||
}
|
||||
|
||||
fn container(
|
||||
fn traverse(
|
||||
&mut self,
|
||||
_id: Option<&Id>,
|
||||
_bounds: Rectangle,
|
||||
operate_on_children: &mut dyn FnMut(&mut dyn Operation<Count>),
|
||||
operate: &mut dyn FnMut(&mut dyn Operation<Count>),
|
||||
) {
|
||||
operate_on_children(self);
|
||||
operate(self);
|
||||
}
|
||||
|
||||
fn finish(&self) -> Outcome<Count> {
|
||||
|
|
@ -163,13 +151,8 @@ where
|
|||
self.current += 1;
|
||||
}
|
||||
|
||||
fn container(
|
||||
&mut self,
|
||||
_id: Option<&Id>,
|
||||
_bounds: Rectangle,
|
||||
operate_on_children: &mut dyn FnMut(&mut dyn Operation<T>),
|
||||
) {
|
||||
operate_on_children(self);
|
||||
fn traverse(&mut self, operate: &mut dyn FnMut(&mut dyn Operation<T>)) {
|
||||
operate(self);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -205,13 +188,8 @@ where
|
|||
self.current += 1;
|
||||
}
|
||||
|
||||
fn container(
|
||||
&mut self,
|
||||
_id: Option<&Id>,
|
||||
_bounds: Rectangle,
|
||||
operate_on_children: &mut dyn FnMut(&mut dyn Operation<T>),
|
||||
) {
|
||||
operate_on_children(self);
|
||||
fn traverse(&mut self, operate: &mut dyn FnMut(&mut dyn Operation<T>)) {
|
||||
operate(self);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -237,13 +215,11 @@ pub fn find_focused() -> impl Operation<Id> {
|
|||
}
|
||||
}
|
||||
|
||||
fn container(
|
||||
fn traverse(
|
||||
&mut self,
|
||||
_id: Option<&Id>,
|
||||
_bounds: Rectangle,
|
||||
operate_on_children: &mut dyn FnMut(&mut dyn Operation<Id>),
|
||||
operate: &mut dyn FnMut(&mut dyn Operation<Id>),
|
||||
) {
|
||||
operate_on_children(self);
|
||||
operate(self);
|
||||
}
|
||||
|
||||
fn finish(&self) -> Outcome<Id> {
|
||||
|
|
@ -279,17 +255,15 @@ pub fn is_focused(target: Id) -> impl Operation<bool> {
|
|||
}
|
||||
}
|
||||
|
||||
fn container(
|
||||
fn traverse(
|
||||
&mut self,
|
||||
_id: Option<&Id>,
|
||||
_bounds: Rectangle,
|
||||
operate_on_children: &mut dyn FnMut(&mut dyn Operation<bool>),
|
||||
operate: &mut dyn FnMut(&mut dyn Operation<bool>),
|
||||
) {
|
||||
if self.is_focused.is_some() {
|
||||
return;
|
||||
}
|
||||
|
||||
operate_on_children(self);
|
||||
operate(self);
|
||||
}
|
||||
|
||||
fn finish(&self) -> Outcome<bool> {
|
||||
|
|
|
|||
|
|
@ -28,13 +28,8 @@ pub fn snap_to<T>(target: Id, offset: RelativeOffset) -> impl Operation<T> {
|
|||
}
|
||||
|
||||
impl<T> Operation<T> for SnapTo {
|
||||
fn container(
|
||||
&mut self,
|
||||
_id: Option<&Id>,
|
||||
_bounds: Rectangle,
|
||||
operate_on_children: &mut dyn FnMut(&mut dyn Operation<T>),
|
||||
) {
|
||||
operate_on_children(self);
|
||||
fn traverse(&mut self, operate: &mut dyn FnMut(&mut dyn Operation<T>)) {
|
||||
operate(self);
|
||||
}
|
||||
|
||||
fn scrollable(
|
||||
|
|
@ -63,13 +58,8 @@ pub fn scroll_to<T>(target: Id, offset: AbsoluteOffset) -> impl Operation<T> {
|
|||
}
|
||||
|
||||
impl<T> Operation<T> for ScrollTo {
|
||||
fn container(
|
||||
&mut self,
|
||||
_id: Option<&Id>,
|
||||
_bounds: Rectangle,
|
||||
operate_on_children: &mut dyn FnMut(&mut dyn Operation<T>),
|
||||
) {
|
||||
operate_on_children(self);
|
||||
fn traverse(&mut self, operate: &mut dyn FnMut(&mut dyn Operation<T>)) {
|
||||
operate(self);
|
||||
}
|
||||
|
||||
fn scrollable(
|
||||
|
|
@ -98,13 +88,8 @@ pub fn scroll_by<T>(target: Id, offset: AbsoluteOffset) -> impl Operation<T> {
|
|||
}
|
||||
|
||||
impl<T> Operation<T> for ScrollBy {
|
||||
fn container(
|
||||
&mut self,
|
||||
_id: Option<&Id>,
|
||||
_bounds: Rectangle,
|
||||
operate_on_children: &mut dyn FnMut(&mut dyn Operation<T>),
|
||||
) {
|
||||
operate_on_children(self);
|
||||
fn traverse(&mut self, operate: &mut dyn FnMut(&mut dyn Operation<T>)) {
|
||||
operate(self);
|
||||
}
|
||||
|
||||
fn scrollable(
|
||||
|
|
|
|||
|
|
@ -45,13 +45,8 @@ pub fn move_cursor_to_front<T>(target: Id) -> impl Operation<T> {
|
|||
}
|
||||
}
|
||||
|
||||
fn container(
|
||||
&mut self,
|
||||
_id: Option<&Id>,
|
||||
_bounds: Rectangle,
|
||||
operate_on_children: &mut dyn FnMut(&mut dyn Operation<T>),
|
||||
) {
|
||||
operate_on_children(self);
|
||||
fn traverse(&mut self, operate: &mut dyn FnMut(&mut dyn Operation<T>)) {
|
||||
operate(self);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -80,13 +75,8 @@ pub fn move_cursor_to_end<T>(target: Id) -> impl Operation<T> {
|
|||
}
|
||||
}
|
||||
|
||||
fn container(
|
||||
&mut self,
|
||||
_id: Option<&Id>,
|
||||
_bounds: Rectangle,
|
||||
operate_on_children: &mut dyn FnMut(&mut dyn Operation<T>),
|
||||
) {
|
||||
operate_on_children(self);
|
||||
fn traverse(&mut self, operate: &mut dyn FnMut(&mut dyn Operation<T>)) {
|
||||
operate(self);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -116,13 +106,8 @@ pub fn move_cursor_to<T>(target: Id, position: usize) -> impl Operation<T> {
|
|||
}
|
||||
}
|
||||
|
||||
fn container(
|
||||
&mut self,
|
||||
_id: Option<&Id>,
|
||||
_bounds: Rectangle,
|
||||
operate_on_children: &mut dyn FnMut(&mut dyn Operation<T>),
|
||||
) {
|
||||
operate_on_children(self);
|
||||
fn traverse(&mut self, operate: &mut dyn FnMut(&mut dyn Operation<T>)) {
|
||||
operate(self);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -150,13 +135,8 @@ pub fn select_all<T>(target: Id) -> impl Operation<T> {
|
|||
}
|
||||
}
|
||||
|
||||
fn container(
|
||||
&mut self,
|
||||
_id: Option<&Id>,
|
||||
_bounds: Rectangle,
|
||||
operate_on_children: &mut dyn FnMut(&mut dyn Operation<T>),
|
||||
) {
|
||||
operate_on_children(self);
|
||||
fn traverse(&mut self, operate: &mut dyn FnMut(&mut dyn Operation<T>)) {
|
||||
operate(self);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue