diff options
author | 2022-08-05 22:31:26 +0200 | |
---|---|---|
committer | 2022-08-05 22:31:26 +0200 | |
commit | f294c2d16249ce8b7989f8af6332678f53d8fb12 (patch) | |
tree | bb8d6f00fe25de9187b1d3b90a88ae95225b7428 /examples/todos | |
parent | a003e797e8a1bb5d365c1db5de6af88e61a47329 (diff) | |
parent | ad5bd0970d7106a97d455a164a582ab1d0bff18b (diff) | |
download | iced-f294c2d16249ce8b7989f8af6332678f53d8fb12.tar.gz iced-f294c2d16249ce8b7989f8af6332678f53d8fb12.tar.bz2 iced-f294c2d16249ce8b7989f8af6332678f53d8fb12.zip |
Merge pull request #1399 from iced-rs/widget-operations
Widget Operations
Diffstat (limited to 'examples/todos')
-rw-r--r-- | examples/todos/Cargo.toml | 1 | ||||
-rw-r--r-- | examples/todos/src/main.rs | 85 |
2 files changed, 75 insertions, 11 deletions
diff --git a/examples/todos/Cargo.toml b/examples/todos/Cargo.toml index 5b068c78..2326ffc6 100644 --- a/examples/todos/Cargo.toml +++ b/examples/todos/Cargo.toml @@ -9,6 +9,7 @@ publish = false iced = { path = "../..", features = ["async-std", "debug"] } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" +lazy_static = "1.4" [target.'cfg(not(target_arch = "wasm32"))'.dependencies] async-std = "1.0" diff --git a/examples/todos/src/main.rs b/examples/todos/src/main.rs index 7dde235a..bb00aac6 100644 --- a/examples/todos/src/main.rs +++ b/examples/todos/src/main.rs @@ -1,14 +1,23 @@ use iced::alignment::{self, Alignment}; +use iced::event::{self, Event}; +use iced::keyboard; +use iced::subscription; use iced::theme::{self, Theme}; use iced::widget::{ - button, checkbox, column, container, row, scrollable, text, text_input, - Text, + self, button, checkbox, column, container, row, scrollable, text, + text_input, Text, }; use iced::window; use iced::{Application, Element}; -use iced::{Color, Command, Font, Length, Settings}; +use iced::{Color, Command, Font, Length, Settings, Subscription}; + +use lazy_static::lazy_static; use serde::{Deserialize, Serialize}; +lazy_static! { + static ref INPUT_ID: text_input::Id = text_input::Id::unique(); +} + pub fn main() -> iced::Result { Todos::run(Settings { window: window::Settings { @@ -42,6 +51,7 @@ enum Message { CreateTask, FilterChanged(Filter), TaskMessage(usize, TaskMessage), + TabPressed { shift: bool }, } impl Application for Todos { @@ -84,14 +94,16 @@ impl Application for Todos { _ => {} } - Command::none() + text_input::focus(INPUT_ID.clone()) } Todos::Loaded(state) => { let mut saved = false; - match message { + let command = match message { Message::InputChanged(value) => { state.input_value = value; + + Command::none() } Message::CreateTask => { if !state.input_value.is_empty() { @@ -100,30 +112,56 @@ impl Application for Todos { .push(Task::new(state.input_value.clone())); state.input_value.clear(); } + + Command::none() } Message::FilterChanged(filter) => { state.filter = filter; + + Command::none() } Message::TaskMessage(i, TaskMessage::Delete) => { state.tasks.remove(i); + + Command::none() } Message::TaskMessage(i, task_message) => { if let Some(task) = state.tasks.get_mut(i) { + let should_focus = + matches!(task_message, TaskMessage::Edit); + task.update(task_message); + + if should_focus { + text_input::focus(Task::text_input_id(i)) + } else { + Command::none() + } + } else { + Command::none() } } Message::Saved(_) => { state.saving = false; saved = true; + + Command::none() } - _ => {} - } + Message::TabPressed { shift } => { + if shift { + widget::focus_previous() + } else { + widget::focus_next() + } + } + _ => Command::none(), + }; if !saved { state.dirty = true; } - if state.dirty && !state.saving { + let save = if state.dirty && !state.saving { state.dirty = false; state.saving = true; @@ -138,7 +176,9 @@ impl Application for Todos { ) } else { Command::none() - } + }; + + Command::batch(vec![command, save]) } } } @@ -163,6 +203,7 @@ impl Application for Todos { input_value, Message::InputChanged, ) + .id(INPUT_ID.clone()) .padding(15) .size(30) .on_submit(Message::CreateTask); @@ -178,12 +219,13 @@ impl Application for Todos { .enumerate() .filter(|(_, task)| filter.matches(task)) .map(|(i, task)| { - task.view().map(move |message| { + task.view(i).map(move |message| { Message::TaskMessage(i, message) }) }) .collect(), ) + .spacing(10) .into() } else { empty_message(match filter { @@ -209,6 +251,22 @@ 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(), + }), + _ => None, + }) + } } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -242,6 +300,10 @@ pub enum TaskMessage { } impl Task { + fn text_input_id(i: usize) -> text_input::Id { + text_input::Id::new(format!("task-{}", i)) + } + fn new(description: String) -> Self { Task { description, @@ -270,7 +332,7 @@ impl Task { } } - fn view(&self) -> Element<TaskMessage> { + fn view(&self, i: usize) -> Element<TaskMessage> { match &self.state { TaskState::Idle => { let checkbox = checkbox( @@ -297,6 +359,7 @@ impl Task { &self.description, TaskMessage::DescriptionEdited, ) + .id(Self::text_input_id(i)) .on_submit(TaskMessage::FinishEdition) .padding(10); |