From f6f597f3074c27fc3b34987d00bce831dbdbd124 Mon Sep 17 00:00:00 2001 From: dam Date: Wed, 5 Oct 2022 00:55:25 +0000 Subject: Implemented go-to action. Improved TUI. --- main.c | 101 +++++++++++++++++++++++++++++++++++++++++++------------------- readme.md | 4 +-- 2 files changed, 72 insertions(+), 33 deletions(-) diff --git a/main.c b/main.c index 092b74d..b39d6d0 100644 --- a/main.c +++ b/main.c @@ -719,6 +719,16 @@ void initialize_tui() { init_pair(THEME_E, COLOR_BLUE, COLOR_BLACK); } +void recalculate_tui() { + // Recalculate first column width: expands to fill the remaining space dynamically. + for (layout_st *layout = layouts; layout <= &layouts[NUM_LAYOUTS-1]; layout++) { + layout->columns[0].width = size_x - (NUM_COLUMNS - 1) - 2; + for (int idx = 1; idx < NUM_COLUMNS; idx++) { + layout->columns[0].width -= layout->columns[idx].width; + } + } +} + void draw_tui(database_st *db, layout_st *layout) { const static int adjust_first_day_of_week[] = { @@ -739,13 +749,7 @@ void draw_tui(database_st *db, layout_st *layout) { task_st *selected_task = get_selected_task(db); time_t now_utc = time(NULL); int now_week_day = localtime(&now_utc)->tm_wday; - - // The first column expands to fill the remaining space dynamically. - layout->columns[0].width = size_x - (NUM_COLUMNS - 1) - 2; - for (int idx = 1; idx < NUM_COLUMNS; idx++) { - layout->columns[0].width -= layout->columns[idx].width; - } - + // Reset theme and clear screen. attrset(A_NORMAL); erase(); @@ -1039,6 +1043,7 @@ int main(int argc, char *argv[]) { task_st *selected_task = get_selected_task(db); int selected_task_row = (db->selected_task % NUM_TABLE_ROWS) + NUM_HEADER_ROWS; int selected_task_theme = selected_task == active_task ? THEME_E : THEME_D; + layout_st *layout; update_timers(&database); @@ -1054,6 +1059,8 @@ int main(int argc, char *argv[]) { clear(); getmaxyx(stdscr, size_y, size_x); string_buffer = realloc(string_buffer, 511 | MAX_TASK_NAME | (size_x + 1)); // TODO This realloc sucks. + recalculate_tui(); // TODO Maybe rename this function. + layout = &layouts[size_x > 100 ? L_NORMAL : L_COMPACT]; break; } @@ -1085,10 +1092,9 @@ int main(int argc, char *argv[]) { } // Prepare row to input new task name. - attron(COLOR_PAIR(selected_task_theme) | A_BOLD); - mvaddch(selected_task_row, 0, ACS_DIAMOND); + attron(COLOR_PAIR(selected_task_theme) | A_BOLD | A_UNDERLINE); sprintf(string_buffer, "%*s", size_x - 2, ""); - addstr(string_buffer); + mvaddstr(selected_task_row, 1, string_buffer); // Get new task name. echo(); @@ -1110,16 +1116,15 @@ int main(int argc, char *argv[]) { if (selected_task == NULL || selected_task == active_task) { break; } - refresh(); - const char *message = "Press enter to delete."; - const size_t length = strlen(message); - int left_padding = ((size_x - 2) - length) / 2; - int right_padding = ((size_x - 2) - length) - left_padding; - sprintf(string_buffer, "%*s%s%*s", left_padding, "", message, right_padding, ""); attron(COLOR_PAIR(selected_task_theme) | A_BOLD); - mvaddch(selected_task_row, 0, ACS_DIAMOND); - addstr(string_buffer); + + move(selected_task_row, 1); + for (int idx = 0; idx < size_x - 2; idx++) { + addch(ACS_CKBOARD); + } + mvaddstr(selected_task_row, 2, " Press enter to delete. "); + attrset(A_NORMAL); if (getch() == '\n') { @@ -1128,37 +1133,71 @@ int main(int argc, char *argv[]) { break; } + case 'm': + case 'M': { + if (selected_task == NULL) { + 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: "); + + // Get line number. + echo(); + curs_set(1); + getnstr(string_buffer, MAX_TASK_NAME); // TODO use better value than MAX_TASK_NAME + noecho(); + curs_set(0); + + attrset(A_NORMAL); + + char *parser; + intmax_t input = strtoimax(string_buffer, &parser, 10) - 1; + + if (parser == string_buffer) { + break; + } + + // TODO Implement move-task-to logic. + db->selected_task = input < 0 ? 0 : + input >= db->count ? db->count - 1 : + input; + + break; + break; + } + case 'g': case 'G': { if (selected_task == NULL) { break; } - // TODO WIP - - const char *message = " Go to: "; - const int length = strlen(message); - int available = layouts[1].columns[0].width - length; - sprintf(string_buffer, "%s%*s", message, available, ""); + attron(COLOR_PAIR(selected_task_theme) | A_BOLD | A_UNDERLINE); - attron(COLOR_PAIR(selected_task_theme) | A_BOLD); - mvaddch(size_y - 1, 0, ACS_DIAMOND); - mvaddstr(size_y - 1, 1, string_buffer); + sprintf(string_buffer, "%*s", size_x - 2, ""); + mvaddstr(selected_task_row, 1, string_buffer); + mvaddstr(selected_task_row, 1, " Go to: "); // Get line number. echo(); curs_set(1); - mvgetnstr(size_y - 1, 1 + length, string_buffer, available-1); + getnstr(string_buffer, MAX_TASK_NAME); // TODO use better value than MAX_TASK_NAME noecho(); curs_set(0); attrset(A_NORMAL); - if (is_empty_string(string_buffer) == true) { + char *parser; + intmax_t input = strtoimax(string_buffer, &parser, 10) - 1; + + if (parser == string_buffer) { break; } - intmax_t input = strtoimax(string_buffer, NULL, 10) - 1; db->selected_task = input < 0 ? 0 : input >= db->count ? db->count - 1 : input; @@ -1298,7 +1337,7 @@ int main(int argc, char *argv[]) { } if (size_x >= 60 && size_y >= 3) { - draw_tui(db, &layouts[size_x > 100 ? L_NORMAL : L_COMPACT]); + draw_tui(db, layout); } else { const char *INVALID_WINDOW_MESSAGE = "Please expand window."; diff --git a/readme.md b/readme.md index 0de65fe..477a243 100644 --- a/readme.md +++ b/readme.md @@ -45,8 +45,8 @@ Task Time Tracker - [x] Confirm delete_task operation by show confirmation message on selected line (horizontally centered). - [x] Check totals update speedup using https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html - For 1M entries, generic C code runs in 12.0ms while special approaches using builtins or SIMD takes around 9.5ms. Not worth the effort. -- [ ] Change task order (using task_t tmp_task + memcpy); -- [ ] Allow to jump to specific task by index number using key `g` and `G`; +- [x] Allow to jump to specific task by index number using key `g` and `G`; +- [ ] Move task to (using task_t tmp_task + memcpy) using key `m` and `M`; - [ ] Add/remove time using keys: `F3`; - [ ] Add/remove time for any day of week; - [ ] Implement logs as described above. -- cgit v1.2.3