1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
use iced::{
scrollable, text::HorizontalAlignment, text_input, Align, Application,
Checkbox, Color, Column, Element, Scrollable, Text, TextInput,
};
pub fn main() {
Todos::default().run()
}
#[derive(Debug, Default)]
struct Todos {
scroll: scrollable::State,
input: text_input::State,
input_value: String,
tasks: Vec<Task>,
}
#[derive(Debug, Clone)]
pub enum Message {
InputChanged(String),
CreateTask,
TaskChanged(usize, bool),
}
impl Application for Todos {
type Message = Message;
fn title(&self) -> String {
String::from("Todos - Iced")
}
fn update(&mut self, message: Message) {
match message {
Message::InputChanged(value) => {
self.input_value = value;
}
Message::CreateTask => {
if !self.input_value.is_empty() {
self.tasks.push(Task::new(self.input_value.clone()));
self.input_value.clear();
}
}
Message::TaskChanged(i, completed) => {
if let Some(task) = self.tasks.get_mut(i) {
task.completed = completed;
}
}
}
dbg!(self);
}
fn view(&mut self) -> Element<Message> {
let title = Text::new("todos")
.size(100)
.color(GRAY)
.horizontal_alignment(HorizontalAlignment::Center);
let input = TextInput::new(
&mut self.input,
"What needs to be done?",
&self.input_value,
Message::InputChanged,
)
.padding(15)
.size(30)
.on_submit(Message::CreateTask);
let tasks = self.tasks.iter_mut().enumerate().fold(
Column::new().spacing(20),
|column, (i, task)| {
column.push(
task.view()
.map(move |state| Message::TaskChanged(i, state)),
)
},
);
let content = Column::new()
.max_width(800)
.align_self(Align::Center)
.spacing(20)
.push(title)
.push(input)
.push(tasks);
Scrollable::new(&mut self.scroll)
.padding(40)
.push(content)
.into()
}
}
#[derive(Debug)]
struct Task {
description: String,
completed: bool,
}
impl Task {
fn new(description: String) -> Self {
Task {
description,
completed: false,
}
}
fn view(&mut self) -> Element<bool> {
Checkbox::new(self.completed, &self.description, |checked| checked)
.into()
}
}
// Colors
const GRAY: Color = Color {
r: 0.5,
g: 0.5,
b: 0.5,
a: 1.0,
};
|