summaryrefslogtreecommitdiffstats
path: root/examples/todos
diff options
context:
space:
mode:
authorLibravatar Héctor Ramón <hector0193@gmail.com>2022-08-05 22:31:26 +0200
committerLibravatar GitHub <noreply@github.com>2022-08-05 22:31:26 +0200
commitf294c2d16249ce8b7989f8af6332678f53d8fb12 (patch)
treebb8d6f00fe25de9187b1d3b90a88ae95225b7428 /examples/todos
parenta003e797e8a1bb5d365c1db5de6af88e61a47329 (diff)
parentad5bd0970d7106a97d455a164a582ab1d0bff18b (diff)
downloadiced-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.toml1
-rw-r--r--examples/todos/src/main.rs85
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);