From 07abd19a1710ca7a2a72e0e68cf7b8c77302e616 Mon Sep 17 00:00:00 2001 From: Marto Date: Fri, 7 Feb 2025 17:18:02 +0100 Subject: [PATCH] fin --- src/db.rs | 5 ++- src/todo.rs | 114 +++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 106 insertions(+), 13 deletions(-) diff --git a/src/db.rs b/src/db.rs index 8c78ed6..14e7159 100644 --- a/src/db.rs +++ b/src/db.rs @@ -1,8 +1,9 @@ -use crate::todo; use crate::todo::{ChangeType, TaskColumn, TaskListDB}; use rusqlite::{params, Connection, Error, Result}; use std::path::Path; +const DEFAULT_NAME: &str = "general"; + pub(crate) fn startup(path: &Path) -> std::result::Result { let conn = Connection::open(path)?; @@ -17,7 +18,7 @@ pub(crate) fn startup(path: &Path) -> std::result::Result { conn.execute( "INSERT OR IGNORE INTO task_group (value) VALUES (?1)", - (&todo::DEFAULT_NAME,) + (&DEFAULT_NAME,) )?; if let Err(e) = create_tasklist_tables(&conn) { diff --git a/src/todo.rs b/src/todo.rs index 1fdb0e9..063000d 100644 --- a/src/todo.rs +++ b/src/todo.rs @@ -1,10 +1,9 @@ use std::default::Default; +use std::fmt::Formatter; use crate::db; use iced::keyboard::key; use iced::widget::text::danger; -use iced::widget::{ - button, center, checkbox, column, combo_box, row, scrollable, text_input, Text, -}; +use iced::widget::{button, center, checkbox, column, combo_box, pick_list, row, scrollable, text_input, Text}; use iced::{event, keyboard, widget, Center, Element, Event, Length, Subscription, Task, Theme}; use rusqlite::Connection; @@ -37,6 +36,8 @@ pub(crate) struct Todo { task_list: Vec, current_task_list: Option, curr_tl_id: usize, + display: DisplayType, + display_selected: Option, } #[derive(Debug, Clone)] @@ -52,6 +53,9 @@ pub enum Message { ToggleUnselect(bool), SelectedTaskList(String), AddTaskList, + DisplayTypeSelection(DisplayType), + TaskHovered(String), + TaskClosed, } pub enum ChangeType { @@ -71,14 +75,30 @@ pub(crate) struct TaskListDB { pub(crate) value: String, } +#[derive(PartialEq)] +#[derive(Debug, Clone)] +enum DisplayType { + Active, + Archived, + All, +} + +impl std::fmt::Display for DisplayType { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.write_str(match self { + Self::Active => "Active tasks", + Self::Archived => "Archived tasks", + Self::All => "All tasks", + }) + } +} + impl Default for Todo { fn default() -> Self { Todo::new() } } -pub const DEFAULT_NAME: &str = "general"; - impl Todo { fn new() -> Self { let mut init = Self { @@ -93,6 +113,8 @@ impl Todo { task_list: Vec::new(), current_task_list: None, curr_tl_id: 1, + display: DisplayType::Active, + display_selected: Some(DisplayType::Active), }; Self::set_task_list(&mut init); @@ -353,7 +375,35 @@ impl Todo { } } Task::none() - } + }, + Message::DisplayTypeSelection(selection) => { + self.display = selection.clone(); + self.display_selected = Some(selection); + + Task::none() + }, + Message::TaskHovered(tasklist_name) => { + let curr_id = self.curr_tl_id.clone(); + self.completed_tasks = 0; + + for item in &self.task_list { + if item.value == tasklist_name { + self.curr_tl_id = item.id; + break; + } + } + + self.tasks.clear(); + self.load_data_from_db(); + + self.curr_tl_id = curr_id; + Task::none() + }, + Message::TaskClosed => { + self.tasks.clear(); + self.load_data_from_db(); + Task::none() + }, } } @@ -379,6 +429,20 @@ impl Todo { let mut saved_tasks = column![]; for (i, task) in self.tasks.iter().enumerate() { + match self.display { + DisplayType::Active => { + if task.checked { + continue; + } + }, + DisplayType::Archived => { + if !task.checked { + continue; + } + }, + DisplayType::All => {}, + } + let chk = checkbox("", task.checked) .size(25) .on_toggle(move |b| Message::CheckTask(b, i)); @@ -412,29 +476,33 @@ impl Todo { saved_tasks = saved_tasks.push(task_line); } - - let status = Text::new(format!("{} / {}", self.completed_tasks, self.tasks.len())); + + let status = Text::new(format!("{} / {}", self.completed_tasks, self.get_tasks_len())); let tasklist = combo_box( &self.task_list_state, - "Enter desired task list ...", + "Add tasklist ...", self.current_task_list.as_ref(), Message::SelectedTaskList, ) - .on_input(|str| Message::ContentUpdated(ContentType::NewList, str)); + .on_input(|str| Message::ContentUpdated(ContentType::NewList, str)) + .on_option_hovered(Message::TaskHovered) + .on_close(Message::TaskClosed); let add_tasklist = button("+").on_press(Message::AddTaskList); let tasklist_group = row![tasklist.width(Length::Fill), add_tasklist].spacing(5); + let archived_dropdown = pick_list([DisplayType::Active, DisplayType::Archived, DisplayType::All], self.display_selected.clone(), Message::DisplayTypeSelection); let unselect = checkbox("Select all", self.select_all).on_toggle(Message::ToggleUnselect); let footer = row![ status, tasklist_group, + archived_dropdown, unselect, ] .padding(10) .spacing(10); let mut output = column![new_task.padding(10)]; - output = if self.tasks.is_empty() { + output = if self.tasks.is_empty() || self.get_tasks_len() == 0 { output.push(saved_tasks.height(Length::Fill)) } else { output.push(scrollable(saved_tasks).height(Length::Fill).spacing(10)) @@ -513,4 +581,28 @@ impl Todo { Err(e) => eprintln!("[ERROR] Failed to get tasklists from DB:\n{e}"), } } + + fn get_tasks_len(&self) -> usize { + let mut counter = 0; + + for item in &self.tasks { + match self.display { + DisplayType::Active => { + if !item.checked { + counter += 1; + } + } + DisplayType::Archived => { + if item.checked { + counter += 1; + } + } + DisplayType::All => { + counter += 1; + } + } + } + + counter + } }