Replace Command with a new Task API with chain support

This commit is contained in:
Héctor Ramón Jiménez 2024-06-14 01:47:39 +02:00
parent e6d0b3bda5
commit a25b1af456
No known key found for this signature in database
GPG key ID: 7CC46565708259A7
74 changed files with 1351 additions and 1767 deletions

View file

@ -205,7 +205,7 @@ where
tree: &mut Tree,
layout: Layout<'_>,
renderer: &Renderer,
operation: &mut dyn Operation<Message>,
operation: &mut dyn Operation<()>,
) {
operation.container(None, layout.bounds(), &mut |operation| {
self.content.as_widget().operate(

View file

@ -208,7 +208,7 @@ where
tree: &mut Tree,
layout: Layout<'_>,
renderer: &Renderer,
operation: &mut dyn Operation<Message>,
operation: &mut dyn Operation<()>,
) {
operation.container(None, layout.bounds(), &mut |operation| {
self.children

View file

@ -13,7 +13,7 @@ use crate::core::{
Padding, Pixels, Point, Rectangle, Shadow, Shell, Size, Theme, Vector,
Widget,
};
use crate::runtime::Command;
use crate::runtime::Task;
/// An element decorating some content.
///
@ -258,7 +258,7 @@ where
tree: &mut Tree,
layout: Layout<'_>,
renderer: &Renderer,
operation: &mut dyn Operation<Message>,
operation: &mut dyn Operation<()>,
) {
operation.container(
self.id.as_ref().map(|id| &id.0),
@ -457,9 +457,9 @@ impl From<Id> for widget::Id {
}
}
/// Produces a [`Command`] that queries the visible screen bounds of the
/// Produces a [`Task`] that queries the visible screen bounds of the
/// [`Container`] with the given [`Id`].
pub fn visible_bounds(id: Id) -> Command<Option<Rectangle>> {
pub fn visible_bounds(id: Id) -> Task<Option<Rectangle>> {
struct VisibleBounds {
target: widget::Id,
depth: usize,
@ -538,7 +538,7 @@ pub fn visible_bounds(id: Id) -> Command<Option<Rectangle>> {
}
}
Command::widget(VisibleBounds {
Task::widget(VisibleBounds {
target: id.into(),
depth: 0,
scrollables: Vec::new(),

View file

@ -12,7 +12,7 @@ use crate::pick_list::{self, PickList};
use crate::progress_bar::{self, ProgressBar};
use crate::radio::{self, Radio};
use crate::rule::{self, Rule};
use crate::runtime::Command;
use crate::runtime::{Action, Task};
use crate::scrollable::{self, Scrollable};
use crate::slider::{self, Slider};
use crate::text::{self, Text};
@ -275,7 +275,7 @@ where
state: &mut Tree,
layout: Layout<'_>,
renderer: &Renderer,
operation: &mut dyn operation::Operation<Message>,
operation: &mut dyn operation::Operation<()>,
) {
self.content
.as_widget()
@ -477,7 +477,7 @@ where
tree: &mut Tree,
layout: Layout<'_>,
renderer: &Renderer,
operation: &mut dyn operation::Operation<Message>,
operation: &mut dyn operation::Operation<()>,
) {
let children = [&self.base, &self.top]
.into_iter()
@ -929,19 +929,13 @@ where
}
/// Focuses the previous focusable widget.
pub fn focus_previous<Message>() -> Command<Message>
where
Message: 'static,
{
Command::widget(operation::focusable::focus_previous())
pub fn focus_previous<T>() -> Task<T> {
Task::effect(Action::widget(operation::focusable::focus_previous()))
}
/// Focuses the next focusable widget.
pub fn focus_next<Message>() -> Command<Message>
where
Message: 'static,
{
Command::widget(operation::focusable::focus_next())
pub fn focus_next<T>() -> Task<T> {
Task::effect(Action::widget(operation::focusable::focus_next()))
}
/// A container intercepting mouse events.

View file

@ -265,7 +265,7 @@ where
tree: &mut Tree,
layout: Layout<'_>,
renderer: &Renderer,
operation: &mut dyn Operation<Message>,
operation: &mut dyn Operation<()>,
) {
operation.container(None, layout.bounds(), &mut |operation| {
self.children

View file

@ -182,7 +182,7 @@ where
tree: &mut Tree,
layout: Layout<'_>,
renderer: &Renderer,
operation: &mut dyn widget::Operation<Message>,
operation: &mut dyn widget::Operation<()>,
) {
self.with_element(|element| {
element.as_widget().operate(

View file

@ -59,7 +59,7 @@ pub trait Component<Message, Theme = crate::Theme, Renderer = crate::Renderer> {
fn operate(
&self,
_state: &mut Self::State,
_operation: &mut dyn widget::Operation<Message>,
_operation: &mut dyn widget::Operation<()>,
) {
}
@ -172,7 +172,7 @@ where
fn rebuild_element_with_operation(
&self,
operation: &mut dyn widget::Operation<Message>,
operation: &mut dyn widget::Operation<()>,
) {
let heads = self.state.borrow_mut().take().unwrap().into_heads();
@ -358,70 +358,17 @@ where
tree: &mut Tree,
layout: Layout<'_>,
renderer: &Renderer,
operation: &mut dyn widget::Operation<Message>,
operation: &mut dyn widget::Operation<()>,
) {
self.rebuild_element_with_operation(operation);
struct MapOperation<'a, B> {
operation: &'a mut dyn widget::Operation<B>,
}
impl<'a, T, B> widget::Operation<T> for MapOperation<'a, B> {
fn container(
&mut self,
id: Option<&widget::Id>,
bounds: Rectangle,
operate_on_children: &mut dyn FnMut(
&mut dyn widget::Operation<T>,
),
) {
self.operation.container(id, bounds, &mut |operation| {
operate_on_children(&mut MapOperation { operation });
});
}
fn focusable(
&mut self,
state: &mut dyn widget::operation::Focusable,
id: Option<&widget::Id>,
) {
self.operation.focusable(state, id);
}
fn text_input(
&mut self,
state: &mut dyn widget::operation::TextInput,
id: Option<&widget::Id>,
) {
self.operation.text_input(state, id);
}
fn scrollable(
&mut self,
state: &mut dyn widget::operation::Scrollable,
id: Option<&widget::Id>,
bounds: Rectangle,
translation: Vector,
) {
self.operation.scrollable(state, id, bounds, translation);
}
fn custom(
&mut self,
state: &mut dyn std::any::Any,
id: Option<&widget::Id>,
) {
self.operation.custom(state, id);
}
}
let tree = tree.state.downcast_mut::<Rc<RefCell<Option<Tree>>>>();
self.with_element(|element| {
element.as_widget().operate(
&mut tree.borrow_mut().as_mut().unwrap().children[0],
layout,
renderer,
&mut MapOperation { operation },
operation,
);
});
}

View file

@ -161,7 +161,7 @@ where
tree: &mut Tree,
layout: Layout<'_>,
renderer: &Renderer,
operation: &mut dyn widget::Operation<Message>,
operation: &mut dyn widget::Operation<()>,
) {
let state = tree.state.downcast_mut::<State>();
let mut content = self.content.borrow_mut();

View file

@ -178,7 +178,7 @@ where
tree: &mut Tree,
layout: Layout<'_>,
renderer: &Renderer,
operation: &mut dyn Operation<Message>,
operation: &mut dyn Operation<()>,
) {
self.content.as_widget().operate(
&mut tree.children[0],

View file

@ -324,7 +324,7 @@ where
tree: &mut Tree,
layout: Layout<'_>,
renderer: &Renderer,
operation: &mut dyn widget::Operation<Message>,
operation: &mut dyn widget::Operation<()>,
) {
operation.container(None, layout.bounds(), &mut |operation| {
self.contents

View file

@ -214,7 +214,7 @@ where
tree: &mut Tree,
layout: Layout<'_>,
renderer: &Renderer,
operation: &mut dyn widget::Operation<Message>,
operation: &mut dyn widget::Operation<()>,
) {
let body_layout = if let Some(title_bar) = &self.title_bar {
let mut children = layout.children();

View file

@ -278,7 +278,7 @@ where
tree: &mut Tree,
layout: Layout<'_>,
renderer: &Renderer,
operation: &mut dyn widget::Operation<Message>,
operation: &mut dyn widget::Operation<()>,
) {
let mut children = layout.children();
let padded = children.next().unwrap();

View file

@ -197,7 +197,7 @@ where
tree: &mut Tree,
layout: Layout<'_>,
renderer: &Renderer,
operation: &mut dyn Operation<Message>,
operation: &mut dyn Operation<()>,
) {
operation.container(None, layout.bounds(), &mut |operation| {
self.children

View file

@ -15,7 +15,7 @@ use crate::core::{
self, Background, Border, Clipboard, Color, Element, Layout, Length,
Pixels, Point, Rectangle, Shell, Size, Theme, Vector, Widget,
};
use crate::runtime::Command;
use crate::runtime::{Action, Task};
pub use operation::scrollable::{AbsoluteOffset, RelativeOffset};
@ -295,7 +295,7 @@ where
tree: &mut Tree,
layout: Layout<'_>,
renderer: &Renderer,
operation: &mut dyn Operation<Message>,
operation: &mut dyn Operation<()>,
) {
let state = tree.state.downcast_mut::<State>();
@ -952,22 +952,18 @@ impl From<Id> for widget::Id {
}
}
/// Produces a [`Command`] that snaps the [`Scrollable`] with the given [`Id`]
/// Produces a [`Task`] that snaps the [`Scrollable`] with the given [`Id`]
/// to the provided `percentage` along the x & y axis.
pub fn snap_to<Message: 'static>(
id: Id,
offset: RelativeOffset,
) -> Command<Message> {
Command::widget(operation::scrollable::snap_to(id.0, offset))
pub fn snap_to<T>(id: Id, offset: RelativeOffset) -> Task<T> {
Task::effect(Action::widget(operation::scrollable::snap_to(id.0, offset)))
}
/// Produces a [`Command`] that scrolls the [`Scrollable`] with the given [`Id`]
/// Produces a [`Task`] that scrolls the [`Scrollable`] with the given [`Id`]
/// to the provided [`AbsoluteOffset`] along the x & y axis.
pub fn scroll_to<Message: 'static>(
id: Id,
offset: AbsoluteOffset,
) -> Command<Message> {
Command::widget(operation::scrollable::scroll_to(id.0, offset))
pub fn scroll_to<T>(id: Id, offset: AbsoluteOffset) -> Task<T> {
Task::effect(Action::widget(operation::scrollable::scroll_to(
id.0, offset,
)))
}
/// Returns [`true`] if the viewport actually changed.

View file

@ -189,7 +189,7 @@ where
tree: &mut Tree,
layout: Layout<'_>,
renderer: &Renderer,
operation: &mut dyn Operation<Message>,
operation: &mut dyn Operation<()>,
) {
operation.container(None, layout.bounds(), &mut |operation| {
self.children

View file

@ -30,7 +30,7 @@ use crate::core::{
Background, Border, Color, Element, Layout, Length, Padding, Pixels, Point,
Rectangle, Shell, Size, Theme, Vector, Widget,
};
use crate::runtime::Command;
use crate::runtime::{Action, Task};
/// A field that can be filled with text.
///
@ -540,7 +540,7 @@ where
tree: &mut Tree,
_layout: Layout<'_>,
_renderer: &Renderer,
operation: &mut dyn Operation<Message>,
operation: &mut dyn Operation<()>,
) {
let state = tree.state.downcast_mut::<State<Renderer::Paragraph>>();
@ -1140,35 +1140,38 @@ impl From<Id> for widget::Id {
}
}
/// Produces a [`Command`] that focuses the [`TextInput`] with the given [`Id`].
pub fn focus<Message: 'static>(id: Id) -> Command<Message> {
Command::widget(operation::focusable::focus(id.0))
/// Produces a [`Task`] that focuses the [`TextInput`] with the given [`Id`].
pub fn focus<T>(id: Id) -> Task<T> {
Task::effect(Action::widget(operation::focusable::focus(id.0)))
}
/// Produces a [`Command`] that moves the cursor of the [`TextInput`] with the given [`Id`] to the
/// Produces a [`Task`] that moves the cursor of the [`TextInput`] with the given [`Id`] to the
/// end.
pub fn move_cursor_to_end<Message: 'static>(id: Id) -> Command<Message> {
Command::widget(operation::text_input::move_cursor_to_end(id.0))
pub fn move_cursor_to_end<T>(id: Id) -> Task<T> {
Task::effect(Action::widget(operation::text_input::move_cursor_to_end(
id.0,
)))
}
/// Produces a [`Command`] that moves the cursor of the [`TextInput`] with the given [`Id`] to the
/// Produces a [`Task`] that moves the cursor of the [`TextInput`] with the given [`Id`] to the
/// front.
pub fn move_cursor_to_front<Message: 'static>(id: Id) -> Command<Message> {
Command::widget(operation::text_input::move_cursor_to_front(id.0))
pub fn move_cursor_to_front<T>(id: Id) -> Task<T> {
Task::effect(Action::widget(operation::text_input::move_cursor_to_front(
id.0,
)))
}
/// Produces a [`Command`] that moves the cursor of the [`TextInput`] with the given [`Id`] to the
/// Produces a [`Task`] that moves the cursor of the [`TextInput`] with the given [`Id`] to the
/// provided position.
pub fn move_cursor_to<Message: 'static>(
id: Id,
position: usize,
) -> Command<Message> {
Command::widget(operation::text_input::move_cursor_to(id.0, position))
pub fn move_cursor_to<T>(id: Id, position: usize) -> Task<T> {
Task::effect(Action::widget(operation::text_input::move_cursor_to(
id.0, position,
)))
}
/// Produces a [`Command`] that selects all the content of the [`TextInput`] with the given [`Id`].
pub fn select_all<Message: 'static>(id: Id) -> Command<Message> {
Command::widget(operation::text_input::select_all(id.0))
/// Produces a [`Task`] that selects all the content of the [`TextInput`] with the given [`Id`].
pub fn select_all<T>(id: Id) -> Task<T> {
Task::effect(Action::widget(operation::text_input::select_all(id.0)))
}
/// The state of a [`TextInput`].

View file

@ -104,7 +104,7 @@ where
tree: &mut Tree,
layout: Layout<'_>,
renderer: &Renderer,
operation: &mut dyn Operation<Message>,
operation: &mut dyn Operation<()>,
) {
self.content
.as_widget()
@ -236,7 +236,7 @@ where
&mut self,
layout: Layout<'_>,
renderer: &Renderer,
operation: &mut dyn Operation<Message>,
operation: &mut dyn Operation<()>,
) {
self.content.operate(layout, renderer, operation);
}