diff --git a/src/main.rs b/src/main.rs index cd9524e..f8a3fba 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,4 @@ -use iced::widget::{button, center, checkbox, column, row, scrollable, text_input, Space, Text}; +use iced::widget::{button, center, checkbox, column, row, scrollable, text_input, Text}; use iced::window::Settings; use iced::{Element, Length, Size, Theme}; use std::collections::HashMap; @@ -6,6 +6,8 @@ use std::collections::HashMap; struct TaskData { checked: bool, value: String, + edit: bool, + can_update: bool, } fn main() -> iced::Result { @@ -24,75 +26,155 @@ fn main() -> iced::Result { #[derive(Default)] struct Todo { new_task: String, + updated_task: String, tasks: HashMap, + task_id: usize, + completed_tasks: usize, } #[derive(Debug, Clone)] enum Message { AddTask, + CheckTask(bool, usize), + EditTask(usize), DeleteTask(usize), - ActivityTask, - ContentUpdated(String), + DeleteAll, + ContentUpdated(bool, String), } impl Todo { fn update(&mut self, message: Message) { match message { - Message::ContentUpdated(new_value) => self.new_task = new_value, + Message::ContentUpdated(new, value) => { + if new { + self.new_task = value + } else { + self.updated_task = value + } + } Message::AddTask => { if self.new_task.is_empty() { return; } let data = TaskData { checked: false, value: self.new_task.to_string(), + edit: false, + can_update: true, }; - self.tasks.insert(self.tasks.len(), data); - + self.tasks.insert(self.task_id, data); + self.task_id += 1; // temp disable for testing fixme - //self.new_task = String::from(""); + //self.new_task = String::new(); + }, + Message::DeleteTask(id) => { + // todo maybe some better checks + if let Some(t) = self.tasks.get_mut(&id) { + if t.checked { + self.completed_tasks -= 1; + } + } + + if let Some(t) = self.tasks.remove(&id) { + println!("Removed {}", t.value); + } + }, + Message::CheckTask(choice, id) => { + if let Some(t) = self.tasks.get_mut(&id) { + self.completed_tasks = if choice { self.completed_tasks + 1 } else { self.completed_tasks - 1 }; + t.checked = choice; + } + }, + Message::EditTask(id) => { + let mut set_update = None; + + if let Some(t) = self.tasks.get_mut(&id) { + if t.edit == true { + t.value = self.updated_task.clone(); + set_update = Some(true); + self.updated_task = String::new(); + } else { + set_update = Some(false); + } + + t.edit = !t.edit; + } + + if let Some(t) = set_update { + self.set_other_update(id, t); + } + }, + Message::DeleteAll => { + self.tasks.clear(); + self.completed_tasks = 0; }, - Message::DeleteTask(id) => todo!(), - Message::ActivityTask => todo!(), } } fn view(&self) -> Element { - let input = text_input("Enter new task", &self.new_task) .width(300) .size(25) - .on_input(Message::ContentUpdated); - + .on_input(|str| Message::ContentUpdated(true, str)); let add_btn = button( - Text::new("Add task") + Text::new("Add") .size(19) .center() ) .width(Length::Shrink) .padding(10) .on_press(Message::AddTask); - - let new_task = row![input, add_btn].spacing(10); + + let clear_btn = button( + Text::new("Clear") + .size(19) + .center() + ) + .width(Length::Shrink) + .padding(10) + .style(button::danger) + .on_press(Message::DeleteAll); + + let new_task = row![input, add_btn, clear_btn].spacing(10); let mut saved_tasks = column![]; for task in &self.tasks { - let chk = checkbox("", task.1.checked).size(25); + let chk = checkbox("", task.1.checked).size(25).on_toggle(|b| Message::CheckTask(b, *task.0)); let label = Text::new(&task.1.value).width(200); - let edit = button("edit").width(Length::Shrink); - let delete = button("delete").width(Length::Shrink); - let task_line = row![chk, label, edit, delete].spacing(10); + let input = text_input("Enter new name", &self.updated_task).width(200).on_input(|str| Message::ContentUpdated(false, str)); + let mut edit = button(if task.1.edit { "save" } else { "edit" }).width(Length::Shrink); + if task.1.can_update { + edit = edit.on_press(Message::EditTask(*task.0)); + } + let delete = button("delete").width(Length::Shrink).on_press(Message::DeleteTask(*task.0)); - saved_tasks = saved_tasks.push(task_line.padding(10)); + let mut task_line = row![chk]; + task_line = if task.1.edit { task_line.push(input) } else { task_line.push(label) }; + task_line = task_line.push(edit).push(delete).spacing(10).padding([5, 10]); + + saved_tasks = saved_tasks.push(task_line); } - let r = center(column![new_task, scrollable(saved_tasks).spacing(10), Space::with_height(Length::Fill)].spacing(20)); - r.into() + let footer = row![Text::new(format!("{} / {}", self.completed_tasks, self.tasks.len()))].padding(10); + + let mut output = column![new_task.padding(10)]; + output = if self.tasks.is_empty() { output.push(saved_tasks.height(Length::Fill)) } else { output.push(scrollable(saved_tasks).height(Length::Fill).spacing(10)) }; + + output = output.push(footer); + center(output).into() } fn theme(&self) -> Theme { Theme::Dark } + + fn set_other_update(&mut self, id: usize, enable: bool) { + for task in self.tasks.iter_mut() { + if id != self.task_id { + task.1.can_update = enable; + } + } + } } \ No newline at end of file