From dd524b83197d85e04948634a1741a1bebe2907ef Mon Sep 17 00:00:00 2001 From: dam Date: Mon, 10 Oct 2022 23:47:40 +0000 Subject: Implemented move-to action. Improved TUI and action-keys. --- main.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 74 insertions(+), 20 deletions(-) (limited to 'main.c') diff --git a/main.c b/main.c index b39d6d0..3c0d7d7 100644 --- a/main.c +++ b/main.c @@ -305,7 +305,7 @@ bool delete_task(database_st *db, task_st *task) { db->count--; // Adjust selected task. - if (db->selected_task >= db->count) { + if (db->selected_task >= db->count) { // TODO Can we compare ptrdiff_t with size_t? db->selected_task--; } @@ -333,8 +333,57 @@ bool delete_task(database_st *db, task_st *task) { return true; } +// Deletes the task provided in the pointer. If possible, shrinks the database capacity. +// Returns success. +bool move_task(database_st *db, task_st *task, size_t target) { + assert(db != NULL); + assert(task != NULL); + assert(task >= db->tasks && task < &db->tasks[db->count]); + assert(target >= 0 && target < db->count); + + + + // Move tasks after the index position to their new positions. + ptrdiff_t index = task - db->tasks; + task_st *target_task = &db->tasks[target]; + ptrdiff_t target_index = target_task - db->tasks; + + if (target_task == task) { + return true; + } + + task_st temp_task; + memcpy(&temp_task, task, SIZEOF_TASK_ST); + + // TODO Simplify code + if (target_index > index) { + memmove(task, task + 1, (target_index - index) * SIZEOF_TASK_ST); + } + else { + memmove(target_task + 1, target_task, (index - target_index) * SIZEOF_TASK_ST); + } + + memcpy(target_task, &temp_task, SIZEOF_TASK_ST); + + if (db->active_task == index) { + db->active_task = target_index; + } + else if (db->active_task > index && db->active_task <= target_index) { + db->active_task--; + } + else if (db->active_task >= target_index && db->active_task < index) { + db->active_task++; + } + + db->selected_task = target_index; + + return true; // TODO +} + // Resets database to the initial state and deallocates all memory taken by tasks. void reset_database(database_st *db) { + assert(db != NULL); + free(db->tasks); memset(db, 0, SIZEOF_DATABASE_ST); db->active_task = -1; @@ -344,7 +393,6 @@ void reset_database(database_st *db) { // Stores data from database into binary file. // Returns success. bool store_database(const database_st *db, const char *path) { - assert(db != NULL); assert(path != NULL); @@ -366,7 +414,6 @@ bool store_database(const database_st *db, const char *path) { // Loads data from binary file into database. // Returns success. bool load_database(database_st *db, const char *path) { - assert(db != NULL); assert(path != NULL); @@ -405,7 +452,6 @@ bool load_database(database_st *db, const char *path) { // Exports data into CSV file. // Returns success. bool export_to_csv(const database_st *db, const char *path) { - assert(db != NULL); assert(path != NULL); @@ -1064,7 +1110,8 @@ int main(int argc, char *argv[]) { break; } - case KEY_F(1): { + case 'n': + case 'N':{ // Create new task. task_st *new_task; if (create_task(db, &new_task) == false) { @@ -1139,16 +1186,19 @@ int main(int argc, char *argv[]) { break; } - attron(COLOR_PAIR(selected_task_theme) | A_BOLD | A_UNDERLINE); - - sprintf(string_buffer, "%*s", size_x - 2, ""); - mvaddstr(selected_task_row, 1, string_buffer); - mvaddstr(selected_task_row, 1, " Move to: "); + attron(COLOR_PAIR(selected_task_theme) | A_BOLD); + move(selected_task_row, 1); + addch(ACS_CKBOARD); + addstr(" Move to: "); + int input_pos_x = getcurx(stdscr); + sprintf(string_buffer, "%*s", size_x - input_pos_x - 1, ""); + attron(A_UNDERLINE); + addstr(string_buffer); // Get line number. echo(); curs_set(1); - getnstr(string_buffer, MAX_TASK_NAME); // TODO use better value than MAX_TASK_NAME + mvgetnstr(selected_task_row, input_pos_x, string_buffer, MAX_TASK_NAME); // TODO use better value than MAX_TASK_NAME noecho(); curs_set(0); @@ -1162,12 +1212,12 @@ int main(int argc, char *argv[]) { } // TODO Implement move-task-to logic. - db->selected_task = input < 0 ? 0 : + size_t target = input < 0 ? 0 : input >= db->count ? db->count - 1 : input; + move_task(db, selected_task, target); break; - break; } case 'g': @@ -1176,16 +1226,19 @@ int main(int argc, char *argv[]) { break; } - attron(COLOR_PAIR(selected_task_theme) | A_BOLD | A_UNDERLINE); - - sprintf(string_buffer, "%*s", size_x - 2, ""); - mvaddstr(selected_task_row, 1, string_buffer); - mvaddstr(selected_task_row, 1, " Go to: "); + attron(COLOR_PAIR(selected_task_theme) | A_BOLD); + move(selected_task_row, 1); + addch(ACS_CKBOARD); + addstr(" Go to: "); + int input_pos_x = getcurx(stdscr); + sprintf(string_buffer, "%*s", size_x - input_pos_x - 1, ""); + attron(A_UNDERLINE); + addstr(string_buffer); // Get line number. echo(); curs_set(1); - getnstr(string_buffer, MAX_TASK_NAME); // TODO use better value than MAX_TASK_NAME + mvgetnstr(selected_task_row, input_pos_x, string_buffer, MAX_TASK_NAME); // TODO use better value than MAX_TASK_NAME noecho(); curs_set(0); @@ -1205,7 +1258,8 @@ int main(int argc, char *argv[]) { break; } - case KEY_F(4): { + case 'd': + case 'D':{ if (selected_task == NULL) { break; } -- cgit v1.2.3