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

@ -4,7 +4,7 @@ use iced::widget::{
button, column, container, horizontal_space, pick_list, row, text,
text_editor, tooltip,
};
use iced::{Alignment, Command, Element, Font, Length, Subscription, Theme};
use iced::{Alignment, Element, Font, Length, Subscription, Task, Theme};
use std::ffi;
use std::io;
@ -51,26 +51,26 @@ impl Editor {
}
}
fn load() -> Command<Message> {
Command::perform(
fn load() -> Task<Message> {
Task::perform(
load_file(format!("{}/src/main.rs", env!("CARGO_MANIFEST_DIR"))),
Message::FileOpened,
)
}
fn update(&mut self, message: Message) -> Command<Message> {
fn update(&mut self, message: Message) -> Task<Message> {
match message {
Message::ActionPerformed(action) => {
self.is_dirty = self.is_dirty || action.is_edit();
self.content.perform(action);
Command::none()
Task::none()
}
Message::ThemeSelected(theme) => {
self.theme = theme;
Command::none()
Task::none()
}
Message::NewFile => {
if !self.is_loading {
@ -78,15 +78,15 @@ impl Editor {
self.content = text_editor::Content::new();
}
Command::none()
Task::none()
}
Message::OpenFile => {
if self.is_loading {
Command::none()
Task::none()
} else {
self.is_loading = true;
Command::perform(open_file(), Message::FileOpened)
Task::perform(open_file(), Message::FileOpened)
}
}
Message::FileOpened(result) => {
@ -98,15 +98,15 @@ impl Editor {
self.content = text_editor::Content::with_text(&contents);
}
Command::none()
Task::none()
}
Message::SaveFile => {
if self.is_loading {
Command::none()
Task::none()
} else {
self.is_loading = true;
Command::perform(
Task::perform(
save_file(self.file.clone(), self.content.text()),
Message::FileSaved,
)
@ -120,7 +120,7 @@ impl Editor {
self.is_dirty = false;
}
Command::none()
Task::none()
}
}
}

View file

@ -2,7 +2,7 @@ use iced::alignment;
use iced::event::{self, Event};
use iced::widget::{button, center, checkbox, text, Column};
use iced::window;
use iced::{Alignment, Command, Element, Length, Subscription};
use iced::{Alignment, Element, Length, Subscription, Task};
pub fn main() -> iced::Result {
iced::program("Events - Iced", Events::update, Events::view)
@ -25,7 +25,7 @@ enum Message {
}
impl Events {
fn update(&mut self, message: Message) -> Command<Message> {
fn update(&mut self, message: Message) -> Task<Message> {
match message {
Message::EventOccurred(event) if self.enabled => {
self.last.push(event);
@ -34,19 +34,19 @@ impl Events {
let _ = self.last.remove(0);
}
Command::none()
Task::none()
}
Message::EventOccurred(event) => {
if let Event::Window(window::Event::CloseRequested) = event {
window::close(window::Id::MAIN)
} else {
Command::none()
Task::none()
}
}
Message::Toggled(enabled) => {
self.enabled = enabled;
Command::none()
Task::none()
}
Message::Exit => window::close(window::Id::MAIN),
}

View file

@ -1,6 +1,6 @@
use iced::widget::{button, center, column};
use iced::window;
use iced::{Alignment, Command, Element};
use iced::{Alignment, Element, Task};
pub fn main() -> iced::Result {
iced::program("Exit - Iced", Exit::update, Exit::view).run()
@ -18,13 +18,13 @@ enum Message {
}
impl Exit {
fn update(&mut self, message: Message) -> Command<Message> {
fn update(&mut self, message: Message) -> Task<Message> {
match message {
Message::Confirm => window::close(window::Id::MAIN),
Message::Exit => {
self.show_confirm = true;
Command::none()
Task::none()
}
}
}

View file

@ -9,7 +9,7 @@ use iced::time;
use iced::widget::{
button, checkbox, column, container, pick_list, row, slider, text,
};
use iced::{Alignment, Command, Element, Length, Subscription, Theme};
use iced::{Alignment, Element, Length, Subscription, Task, Theme};
use std::time::Duration;
pub fn main() -> iced::Result {
@ -56,7 +56,7 @@ impl GameOfLife {
}
}
fn update(&mut self, message: Message) -> Command<Message> {
fn update(&mut self, message: Message) -> Task<Message> {
match message {
Message::Grid(message, version) => {
if version == self.version {
@ -75,7 +75,7 @@ impl GameOfLife {
let version = self.version;
return Command::perform(task, move |message| {
return Task::perform(task, move |message| {
Message::Grid(message, version)
});
}
@ -103,7 +103,7 @@ impl GameOfLife {
}
}
Command::none()
Task::none()
}
fn subscription(&self) -> Subscription<Message> {

View file

@ -2,7 +2,7 @@ use iced_wgpu::Renderer;
use iced_widget::{column, container, row, slider, text, text_input};
use iced_winit::core::alignment;
use iced_winit::core::{Color, Element, Length, Theme};
use iced_winit::runtime::{Command, Program};
use iced_winit::runtime::{Program, Task};
pub struct Controls {
background_color: Color,
@ -33,7 +33,7 @@ impl Program for Controls {
type Message = Message;
type Renderer = Renderer;
fn update(&mut self, message: Message) -> Command<Message> {
fn update(&mut self, message: Message) -> Task<Message> {
match message {
Message::BackgroundColorChanged(color) => {
self.background_color = color;
@ -43,7 +43,7 @@ impl Program for Controls {
}
}
Command::none()
Task::none()
}
fn view(&self) -> Element<Message, Theme, Renderer> {

View file

@ -119,10 +119,7 @@ impl Builder {
fn point(p: impl Into<Point>) -> lyon_algorithms::geom::Point<f32> {
let p: Point = p.into();
lyon_algorithms::geom::point(
p.x.min(1.0).max(0.0),
p.y.min(1.0).max(0.0),
)
lyon_algorithms::geom::point(p.x.clamp(0.0, 1.0), p.y.clamp(0.0, 1.0))
}
}

View file

@ -5,7 +5,7 @@ use iced::widget::{
self, button, center, column, container, horizontal_space, mouse_area,
opaque, pick_list, row, stack, text, text_input,
};
use iced::{Alignment, Color, Command, Element, Length, Subscription};
use iced::{Alignment, Color, Element, Length, Subscription, Task};
use std::fmt;
@ -39,7 +39,7 @@ impl App {
event::listen().map(Message::Event)
}
fn update(&mut self, message: Message) -> Command<Message> {
fn update(&mut self, message: Message) -> Task<Message> {
match message {
Message::ShowModal => {
self.show_modal = true;
@ -47,26 +47,26 @@ impl App {
}
Message::HideModal => {
self.hide_modal();
Command::none()
Task::none()
}
Message::Email(email) => {
self.email = email;
Command::none()
Task::none()
}
Message::Password(password) => {
self.password = password;
Command::none()
Task::none()
}
Message::Plan(plan) => {
self.plan = plan;
Command::none()
Task::none()
}
Message::Submit => {
if !self.email.is_empty() && !self.password.is_empty() {
self.hide_modal();
}
Command::none()
Task::none()
}
Message::Event(event) => match event {
Event::Keyboard(keyboard::Event::KeyPressed {
@ -85,9 +85,9 @@ impl App {
..
}) => {
self.hide_modal();
Command::none()
Task::none()
}
_ => Command::none(),
_ => Task::none(),
},
}
}

View file

@ -6,7 +6,7 @@ use iced::widget::{
};
use iced::window;
use iced::{
Alignment, Command, Element, Length, Point, Settings, Subscription, Theme,
Alignment, Element, Length, Point, Settings, Subscription, Task, Theme,
Vector,
};
@ -48,13 +48,13 @@ impl multi_window::Application for Example {
type Theme = Theme;
type Flags = ();
fn new(_flags: ()) -> (Self, Command<Message>) {
fn new(_flags: ()) -> (Self, Task<Message>) {
(
Example {
windows: HashMap::from([(window::Id::MAIN, Window::new(1))]),
next_window_pos: window::Position::Default,
},
Command::none(),
Task::none(),
)
}
@ -65,14 +65,14 @@ impl multi_window::Application for Example {
.unwrap_or("Example".to_string())
}
fn update(&mut self, message: Message) -> Command<Message> {
fn update(&mut self, message: Message) -> Task<Message> {
match message {
Message::ScaleInputChanged(id, scale) => {
let window =
self.windows.get_mut(&id).expect("Window not found!");
window.scale_input = scale;
Command::none()
Task::none()
}
Message::ScaleChanged(id, scale) => {
let window =
@ -83,7 +83,7 @@ impl multi_window::Application for Example {
.unwrap_or(window.current_scale)
.clamp(0.5, 5.0);
Command::none()
Task::none()
}
Message::TitleChanged(id, title) => {
let window =
@ -91,12 +91,12 @@ impl multi_window::Application for Example {
window.title = title;
Command::none()
Task::none()
}
Message::CloseWindow(id) => window::close(id),
Message::WindowClosed(id) => {
self.windows.remove(&id);
Command::none()
Task::none()
}
Message::WindowOpened(id, position) => {
if let Some(position) = position {
@ -108,13 +108,13 @@ impl multi_window::Application for Example {
if let Some(window) = self.windows.get(&id) {
text_input::focus(window.input_id.clone())
} else {
Command::none()
Task::none()
}
}
Message::NewWindow => {
let count = self.windows.len() + 1;
let (id, spawn_window) = window::spawn(window::Settings {
let (id, spawn_window) = window::open(window::Settings {
position: self.next_window_pos,
exit_on_close_request: count % 2 == 0,
..Default::default()

View file

@ -1,6 +1,6 @@
use iced::futures;
use iced::widget::{self, center, column, image, row, text};
use iced::{Alignment, Command, Element, Length};
use iced::{Alignment, Element, Length, Task};
pub fn main() -> iced::Result {
iced::program(Pokedex::title, Pokedex::update, Pokedex::view)
@ -25,8 +25,8 @@ enum Message {
}
impl Pokedex {
fn search() -> Command<Message> {
Command::perform(Pokemon::search(), Message::PokemonFound)
fn search() -> Task<Message> {
Task::perform(Pokemon::search(), Message::PokemonFound)
}
fn title(&self) -> String {
@ -39,20 +39,20 @@ impl Pokedex {
format!("{subtitle} - Pokédex")
}
fn update(&mut self, message: Message) -> Command<Message> {
fn update(&mut self, message: Message) -> Task<Message> {
match message {
Message::PokemonFound(Ok(pokemon)) => {
*self = Pokedex::Loaded { pokemon };
Command::none()
Task::none()
}
Message::PokemonFound(Err(_error)) => {
*self = Pokedex::Errored;
Command::none()
Task::none()
}
Message::Search => match self {
Pokedex::Loading => Command::none(),
Pokedex::Loading => Task::none(),
_ => {
*self = Pokedex::Loading;

View file

@ -4,7 +4,7 @@ use iced::widget::{button, column, container, image, row, text, text_input};
use iced::window;
use iced::window::screenshot::{self, Screenshot};
use iced::{
Alignment, Command, ContentFit, Element, Length, Rectangle, Subscription,
Alignment, ContentFit, Element, Length, Rectangle, Subscription, Task,
};
use ::image as img;
@ -44,13 +44,11 @@ enum Message {
}
impl Example {
fn update(&mut self, message: Message) -> Command<Message> {
fn update(&mut self, message: Message) -> Task<Message> {
match message {
Message::Screenshot => {
return iced::window::screenshot(
window::Id::MAIN,
Message::ScreenshotData,
);
return iced::window::screenshot(window::Id::MAIN)
.map(Message::ScreenshotData);
}
Message::ScreenshotData(screenshot) => {
self.screenshot = Some(screenshot);
@ -59,7 +57,7 @@ impl Example {
if let Some(screenshot) = &self.screenshot {
self.png_saving = true;
return Command::perform(
return Task::perform(
save_to_png(screenshot.clone()),
Message::PngSaved,
);
@ -103,7 +101,7 @@ impl Example {
}
}
Command::none()
Task::none()
}
fn view(&self) -> Element<'_, Message> {

View file

@ -3,7 +3,7 @@ use iced::widget::{
button, column, container, horizontal_space, progress_bar, radio, row,
scrollable, slider, text, vertical_space, Scrollable,
};
use iced::{Alignment, Border, Color, Command, Element, Length, Theme};
use iced::{Alignment, Border, Color, Element, Length, Task, Theme};
use once_cell::sync::Lazy;
@ -59,7 +59,7 @@ impl ScrollableDemo {
}
}
fn update(&mut self, message: Message) -> Command<Message> {
fn update(&mut self, message: Message) -> Task<Message> {
match message {
Message::SwitchDirection(direction) => {
self.current_scroll_offset = scrollable::RelativeOffset::START;
@ -82,17 +82,17 @@ impl ScrollableDemo {
Message::ScrollbarWidthChanged(width) => {
self.scrollbar_width = width;
Command::none()
Task::none()
}
Message::ScrollbarMarginChanged(margin) => {
self.scrollbar_margin = margin;
Command::none()
Task::none()
}
Message::ScrollerWidthChanged(width) => {
self.scroller_width = width;
Command::none()
Task::none()
}
Message::ScrollToBeginning => {
self.current_scroll_offset = scrollable::RelativeOffset::START;
@ -113,7 +113,7 @@ impl ScrollableDemo {
Message::Scrolled(viewport) => {
self.current_scroll_offset = viewport.relative_offset();
Command::none()
Task::none()
}
}
}

View file

@ -1,5 +1,5 @@
use iced::widget::{button, center, column, text};
use iced::{system, Command, Element};
use iced::{system, Element, Task};
pub fn main() -> iced::Result {
iced::program("System Information - Iced", Example::update, Example::view)
@ -24,19 +24,20 @@ enum Message {
}
impl Example {
fn update(&mut self, message: Message) -> Command<Message> {
fn update(&mut self, message: Message) -> Task<Message> {
match message {
Message::Refresh => {
*self = Self::Loading;
return system::fetch_information(Message::InformationReceived);
return system::fetch_information()
.map(Message::InformationReceived);
}
Message::InformationReceived(information) => {
*self = Self::Loaded { information };
}
}
Command::none()
Task::none()
}
fn view(&self) -> Element<Message> {

View file

@ -4,7 +4,7 @@ use iced::keyboard::key;
use iced::widget::{
self, button, center, column, pick_list, row, slider, text, text_input,
};
use iced::{Alignment, Command, Element, Length, Subscription};
use iced::{Alignment, Element, Length, Subscription, Task};
use toast::{Status, Toast};
@ -49,7 +49,7 @@ impl App {
event::listen().map(Message::Event)
}
fn update(&mut self, message: Message) -> Command<Message> {
fn update(&mut self, message: Message) -> Task<Message> {
match message {
Message::Add => {
if !self.editing.title.is_empty()
@ -57,27 +57,27 @@ impl App {
{
self.toasts.push(std::mem::take(&mut self.editing));
}
Command::none()
Task::none()
}
Message::Close(index) => {
self.toasts.remove(index);
Command::none()
Task::none()
}
Message::Title(title) => {
self.editing.title = title;
Command::none()
Task::none()
}
Message::Body(body) => {
self.editing.body = body;
Command::none()
Task::none()
}
Message::Status(status) => {
self.editing.status = status;
Command::none()
Task::none()
}
Message::Timeout(timeout) => {
self.timeout_secs = timeout as u64;
Command::none()
Task::none()
}
Message::Event(Event::Keyboard(keyboard::Event::KeyPressed {
key: keyboard::Key::Named(key::Named::Tab),
@ -88,7 +88,7 @@ impl App {
key: keyboard::Key::Named(key::Named::Tab),
..
})) => widget::focus_next(),
Message::Event(_) => Command::none(),
Message::Event(_) => Task::none(),
}
}
@ -347,7 +347,7 @@ mod toast {
state: &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(
@ -589,7 +589,7 @@ mod toast {
&mut self,
layout: Layout<'_>,
renderer: &Renderer,
operation: &mut dyn widget::Operation<Message>,
operation: &mut dyn widget::Operation<()>,
) {
operation.container(None, layout.bounds(), &mut |operation| {
self.toasts

View file

@ -5,7 +5,7 @@ use iced::widget::{
scrollable, text, text_input, Text,
};
use iced::window;
use iced::{Command, Element, Font, Length, Subscription};
use iced::{Element, Font, Length, Subscription, Task as Command};
use once_cell::sync::Lazy;
use serde::{Deserialize, Serialize};

View file

@ -5,8 +5,8 @@ use iced::widget::{
};
use iced::window;
use iced::{
Alignment, Color, Command, Element, Font, Length, Point, Rectangle,
Subscription, Theme,
Alignment, Color, Element, Font, Length, Point, Rectangle, Subscription,
Task, Theme,
};
pub fn main() -> iced::Result {
@ -33,14 +33,14 @@ enum Message {
}
impl Example {
fn update(&mut self, message: Message) -> Command<Message> {
fn update(&mut self, message: Message) -> Task<Message> {
match message {
Message::MouseMoved(position) => {
self.mouse_position = Some(position);
Command::none()
Task::none()
}
Message::Scrolled | Message::WindowResized => Command::batch(vec![
Message::Scrolled | Message::WindowResized => Task::batch(vec![
container::visible_bounds(OUTER_CONTAINER.clone())
.map(Message::OuterBoundsFetched),
container::visible_bounds(INNER_CONTAINER.clone())
@ -49,12 +49,12 @@ impl Example {
Message::OuterBoundsFetched(outer_bounds) => {
self.outer_bounds = outer_bounds;
Command::none()
Task::none()
}
Message::InnerBoundsFetched(inner_bounds) => {
self.inner_bounds = inner_bounds;
Command::none()
Task::none()
}
}
}

View file

@ -4,7 +4,7 @@ use iced::alignment::{self, Alignment};
use iced::widget::{
self, button, center, column, row, scrollable, text, text_input,
};
use iced::{color, Command, Element, Length, Subscription};
use iced::{color, Element, Length, Subscription, Task};
use once_cell::sync::Lazy;
pub fn main() -> iced::Result {
@ -30,19 +30,19 @@ enum Message {
}
impl WebSocket {
fn load() -> Command<Message> {
Command::batch([
Command::perform(echo::server::run(), |_| Message::Server),
fn load() -> Task<Message> {
Task::batch([
Task::perform(echo::server::run(), |_| Message::Server),
widget::focus_next(),
])
}
fn update(&mut self, message: Message) -> Command<Message> {
fn update(&mut self, message: Message) -> Task<Message> {
match message {
Message::NewMessageChanged(new_message) => {
self.new_message = new_message;
Command::none()
Task::none()
}
Message::Send(message) => match &mut self.state {
State::Connected(connection) => {
@ -50,9 +50,9 @@ impl WebSocket {
connection.send(message);
Command::none()
Task::none()
}
State::Disconnected => Command::none(),
State::Disconnected => Task::none(),
},
Message::Echo(event) => match event {
echo::Event::Connected(connection) => {
@ -60,14 +60,14 @@ impl WebSocket {
self.messages.push(echo::Message::connected());
Command::none()
Task::none()
}
echo::Event::Disconnected => {
self.state = State::Disconnected;
self.messages.push(echo::Message::disconnected());
Command::none()
Task::none()
}
echo::Event::MessageReceived(message) => {
self.messages.push(message);
@ -78,7 +78,7 @@ impl WebSocket {
)
}
},
Message::Server => Command::none(),
Message::Server => Task::none(),
}
}