diff options
author | 2023-11-29 22:28:31 +0100 | |
---|---|---|
committer | 2023-11-29 22:28:31 +0100 | |
commit | e09b4e24dda51b8212d8ece52431dacaa3922a7b (patch) | |
tree | 7005e181528134ebdde5bbbe5909273db9f30174 /examples/todos | |
parent | 83c7870c569a2976923ee6243a19813094d44673 (diff) | |
parent | 7f8b17604a31e00becc43130ec516c1a53552c88 (diff) | |
download | iced-e09b4e24dda51b8212d8ece52431dacaa3922a7b.tar.gz iced-e09b4e24dda51b8212d8ece52431dacaa3922a7b.tar.bz2 iced-e09b4e24dda51b8212d8ece52431dacaa3922a7b.zip |
Merge branch 'master' into feat/multi-window-support
Diffstat (limited to 'examples/todos')
-rw-r--r-- | examples/todos/Cargo.toml | 18 | ||||
-rw-r--r-- | examples/todos/README.md | 13 | ||||
-rw-r--r-- | examples/todos/src/main.rs | 62 |
3 files changed, 50 insertions, 43 deletions
diff --git a/examples/todos/Cargo.toml b/examples/todos/Cargo.toml index 7ad4d558..3c62bfbc 100644 --- a/examples/todos/Cargo.toml +++ b/examples/todos/Cargo.toml @@ -6,18 +6,26 @@ edition = "2021" publish = false [dependencies] -iced = { path = "../..", features = ["async-std", "debug"] } +iced.workspace = true +iced.features = ["async-std", "debug"] + +once_cell.workspace = true serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" -once_cell = "1.15" +uuid = { version = "1.0", features = ["v4", "fast-rng", "serde"] } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] -async-std = "1.0" +async-std.workspace = true directories-next = "2.0" +tracing-subscriber = "0.3" [target.'cfg(target_arch = "wasm32")'.dependencies] -web-sys = { version = "0.3", features = ["Window", "Storage"] } -wasm-timer = "0.2" +iced.workspace = true +iced.features = ["debug", "webgl"] + +uuid = { version = "1.0", features = ["js"] } +web-sys = { workspace = true, features = ["Window", "Storage"] } +wasm-timer.workspace = true [package.metadata.deb] assets = [ diff --git a/examples/todos/README.md b/examples/todos/README.md index 9c2598b9..5e42f166 100644 --- a/examples/todos/README.md +++ b/examples/todos/README.md @@ -5,8 +5,8 @@ A todos tracker inspired by [TodoMVC]. It showcases dynamic layout, text input, All the example code is located in the __[`main`]__ file. <div align="center"> - <a href="https://gfycat.com/littlesanehalicore"> - <img src="https://thumbs.gfycat.com/LittleSaneHalicore-small.gif" height="400px"> + <a href="https://iced.rs/examples/todos.mp4"> + <img src="https://iced.rs/examples/todos.gif"> </a> </div> @@ -14,7 +14,14 @@ You can run the native version with `cargo run`: ``` cargo run --package todos ``` -We have not yet implemented a `LocalStorage` version of the auto-save feature. Therefore, it does not work on web _yet_! + +The web version can be run with [`trunk`]: + +``` +cd examples/todos +trunk serve +``` [`main`]: src/main.rs [TodoMVC]: http://todomvc.com/ +[`trunk`]: https://trunkrs.dev/ diff --git a/examples/todos/src/main.rs b/examples/todos/src/main.rs index 04c8f618..a7ba69b9 100644 --- a/examples/todos/src/main.rs +++ b/examples/todos/src/main.rs @@ -1,12 +1,10 @@ use iced::alignment::{self, Alignment}; -use iced::event::{self, Event}; use iced::font::{self, Font}; -use iced::keyboard::{self, KeyCode, Modifiers}; -use iced::subscription; +use iced::keyboard; use iced::theme::{self, Theme}; use iced::widget::{ - self, button, checkbox, column, container, row, scrollable, text, - text_input, Text, + self, button, checkbox, column, container, keyed_column, row, scrollable, + text, text_input, Text, }; use iced::window; use iced::{Application, Element}; @@ -14,10 +12,14 @@ use iced::{Color, Command, Length, Settings, Subscription}; use once_cell::sync::Lazy; use serde::{Deserialize, Serialize}; +use uuid::Uuid; static INPUT_ID: Lazy<text_input::Id> = Lazy::new(text_input::Id::unique); pub fn main() -> iced::Result { + #[cfg(not(target_arch = "wasm32"))] + tracing_subscriber::fmt::init(); + Todos::run(Settings { window: window::Settings { size: (500, 800), @@ -222,17 +224,19 @@ impl Application for Todos { tasks.iter().filter(|task| filter.matches(task)); let tasks: Element<_> = if filtered_tasks.count() > 0 { - column( + keyed_column( tasks .iter() .enumerate() .filter(|(_, task)| filter.matches(task)) .map(|(i, task)| { - task.view(i).map(move |message| { - Message::TaskMessage(i, message) - }) - }) - .collect(), + ( + task.id, + task.view(i).map(move |message| { + Message::TaskMessage(i, message) + }), + ) + }), ) .spacing(10) .into() @@ -262,39 +266,27 @@ impl Application for Todos { } fn subscription(&self) -> Subscription<Message> { - subscription::events_with(|event, status| match (event, status) { - ( - Event::Keyboard(keyboard::Event::KeyPressed { - key_code: keyboard::KeyCode::Tab, - modifiers, - .. - }), - event::Status::Ignored, - ) => Some(Message::TabPressed { - shift: modifiers.shift(), - }), - ( - Event::Keyboard(keyboard::Event::KeyPressed { - key_code, - modifiers: Modifiers::SHIFT, + keyboard::on_key_press(|key_code, modifiers| { + match (key_code, modifiers) { + (keyboard::KeyCode::Tab, _) => Some(Message::TabPressed { + shift: modifiers.shift(), }), - event::Status::Ignored, - ) => match key_code { - KeyCode::Up => { + (keyboard::KeyCode::Up, keyboard::Modifiers::SHIFT) => { Some(Message::ToggleFullscreen(window::Mode::Fullscreen)) } - KeyCode::Down => { + (keyboard::KeyCode::Down, keyboard::Modifiers::SHIFT) => { Some(Message::ToggleFullscreen(window::Mode::Windowed)) } _ => None, - }, - _ => None, + } }) } } #[derive(Debug, Clone, Serialize, Deserialize)] struct Task { + #[serde(default = "Uuid::new_v4")] + id: Uuid, description: String, completed: bool, @@ -330,6 +322,7 @@ impl Task { fn new(description: String) -> Self { Task { + id: Uuid::new_v4(), description, completed: false, state: TaskState::Idle, @@ -422,8 +415,7 @@ fn view_controls(tasks: &[Task], current_filter: Filter) -> Element<Message> { row![ text(format!( - "{} {} left", - tasks_left, + "{tasks_left} {} left", if tasks_left == 1 { "task" } else { "tasks" } )) .width(Length::Fill), @@ -451,7 +443,7 @@ pub enum Filter { } impl Filter { - fn matches(&self, task: &Task) -> bool { + fn matches(self, task: &Task) -> bool { match self { Filter::All => true, Filter::Active => !task.completed, |