From af6574a2b9d127123e093580c73ae118e2a3d49b Mon Sep 17 00:00:00 2001 From: dam Date: Sat, 13 Aug 2022 00:49:59 +0000 Subject: Prototype of adaptative layout. --- task_tracker.c | 232 +++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 183 insertions(+), 49 deletions(-) diff --git a/task_tracker.c b/task_tracker.c index b21ad3c..02ed8c3 100644 --- a/task_tracker.c +++ b/task_tracker.c @@ -23,21 +23,13 @@ #define DB_CSV_PATH_NAME "./database.csv" -// TODO The hash is overkill... right? And I could decouple it from the task_t. -struct task_event { - char* name; - time_t start; - time_t end; -}; typedef struct { - char name[MAX_TASK_NAME+1]; // Allow space for null termination char. + char name[MAX_TASK_NAME+1]; // Allow space for null termination char. uint32_t time[7]; - uint32_t hash; -// uint32_t time[sizeof(DAYS_OF_WEEK)]; -// #define DAYS_ON_WEEK sizeof(DAYS_OF_WEEK) -// uint32_t time[DAYS_ON_WEEK]; + uint8_t state; + uint32_t hash; // TODO Is this an overkill? Maybe decouple from task_t? } task_t; @@ -50,11 +42,7 @@ const uint8_t DAYS_ON_WEEK = sizeof(DAYS_OF_WEEK)/sizeof(char*); task_t* tasks = NULL; uint32_t tasks_count = 0; uint32_t tasks_capacity = 0; - -int selected_task = -1; -char** tasks_names = NULL; -uint32_t tasks_names_size = 0; -uint32_t tasks_names_capacity = 0; +uint32_t selected_task = -1; char* replace_char(char* string, char find, char replace){ @@ -356,10 +344,10 @@ void prototype() { /////////////////////////////////////////////////////////////////////////// // Prepare some data for testing. - uint32_t tasks_count = 3; - task_t* tasks = calloc(SIZEOF_TASK_T, 3); + tasks_count = 3; + tasks = calloc(tasks_count, SIZEOF_TASK_T); - task_t tmp[3] = { + task_t tmp[] = { { .name = "TASK-00 : Sample task name.", .time = { 3,2,1,0,1,2,3 }, @@ -376,7 +364,7 @@ void prototype() { .hash = hash_string("BAZINGA : Not a task!") } }; - memcpy(tasks, &tmp, SIZEOF_TASK_T * 3); + memcpy(tasks, &tmp, SIZEOF_TASK_T * tasks_count); /////////////////////////////////////////////////////////////////////////// @@ -428,41 +416,173 @@ void prototype() { /////////////////////////////////////////////////////////////////////////// // Release memory and exit. - free(tasks); - return; +// free(tasks); +// return; } -void draw_table() { - task_t asd; +char* line_buffer; +int size_x, size_y; +uint8_t selected_layout = 0; + +#define TABLE_HEADERS_SIZE 9 + +typedef struct { + int table_size; + int table_headers_size; + char* table_headers[TABLE_HEADERS_SIZE]; +} layout_t; + +layout_t* layouts = NULL; +// { +// .table_size = 8, +// .table_headers_size = 9, +// .table_headers = { " Task ", " Mon ", " Tue ", " Wed ", " Thu ", " Fri ", " Sat ", " Sun ", " Total " } +// }, +// { +// .table_size = 6, +// .table_headers_size = 9, +// .table_headers = { " T ", " M ", " T ", " W ", " T ", " F ", " S ", " S ", " # " } +// } +// }; + +void initialize_layouts() { + layout_t* layout = NULL; + + layouts = calloc(2, sizeof(layout_t)); + + // Layout : 0 : normal. + layout = &layouts[0]; + layout->table_size = 8; + layout->table_headers_size = TABLE_HEADERS_SIZE; + layout->table_headers[0] = " Task "; + layout->table_headers[1] = " Mon "; + layout->table_headers[2] = " Tue "; + layout->table_headers[3] = " Wed "; + layout->table_headers[4] = " Thu "; + layout->table_headers[5] = " Fri "; + layout->table_headers[6] = " Sat "; + layout->table_headers[7] = " Sun "; + layout->table_headers[8] = " Total "; +// layout->table_headers = { " Task ", " Mon ", " Tue ", " Wed ", " Thu ", " Fri ", " Sat ", " Sun ", " Total " }; + + // Layout : 1 : compact. + layout = &layouts[1]; + layout->table_size = 6; + layout->table_headers_size = TABLE_HEADERS_SIZE; + layout->table_headers[0] = " Task "; + layout->table_headers[1] = " M "; + layout->table_headers[2] = " T "; + layout->table_headers[3] = " W "; + layout->table_headers[4] = " T "; + layout->table_headers[5] = " F "; + layout->table_headers[6] = " S "; + layout->table_headers[7] = " S "; + layout->table_headers[8] = " # "; +// layout->table_headers = { " T ", " M ", " T ", " W ", " T ", " F ", " S ", " S ", " # " }; +} + +void free_memory() { + free(line_buffer); + free(tasks); // TODO Deallocate tasks. + free(layouts); } void draw_header() { - const char *table_headers[] = { "Task", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun", "Total" }; - const int table_headers_size = sizeof(table_headers)/sizeof(char*); - int row,col; /* to store the number of rows and the number of colums of the screen */ - initscr(); /* start the curses mode */ - getmaxyx(stdscr,row,col); /* get the number of rows and columns */ + layout_t* layout = &layouts[selected_layout]; + int table_size = layout->table_size; + char** table_headers = layout->table_headers; mvaddch(0, 0, ACS_ULCORNER); - for (int idx = 0; idx < table_headers_size; idx++) { - if (idx > 0) { - addch(ACS_TTEE); -// printw(" %c", ACS_PLUS); - } - addch(ACS_HLINE); - printw(" %s ", table_headers[idx]); + for (int idx = 1; idx < size_x-1; idx++) { addch(ACS_HLINE); - } + addch(ACS_URCORNER); - int cursor_y, cursor_x; - getyx(stdscr, cursor_y, cursor_x); - for (int idx = cursor_x; idx < col-1; idx++) { - addch(ACS_HLINE); + int start_columns = size_x - 1 - 8*table_size - 2; + int columns[] = { + 0, + start_columns+(table_size*0), + start_columns+(table_size*1), + start_columns+(table_size*2), + start_columns+(table_size*3), + start_columns+(table_size*4), + start_columns+(table_size*5), + start_columns+(table_size*6), + start_columns+(table_size*7), + }; + + mvaddstr(0, columns[0]+2, table_headers[0]); + for (int idx = 1; idx < 9; idx++) { + mvaddch(0, columns[idx], ACS_TTEE); + mvaddstr(0, columns[idx]+2, table_headers[idx]); + } +} + +void draw_table() { + task_t* task; + int x, y; + + layout_t* layout = &layouts[selected_layout]; + int table_size = layout->table_size; + char** table_headers = layout->table_headers; + + // TODO Colors + start_color(); + init_pair(1, COLOR_BLACK, COLOR_CYAN); + + + int start_columns = size_x - 1 - 8*table_size - 2; + int columns[] = { + 0, + start_columns+(table_size*0), + start_columns+(table_size*1), + start_columns+(table_size*2), + start_columns+(table_size*3), + start_columns+(table_size*4), + start_columns+(table_size*5), + start_columns+(table_size*6), + start_columns+(table_size*7), + size_x-1, + }; + + move(1, 0); + for (uint32_t idx = 0; idx < tasks_count; idx++){ + + task = &tasks[idx]; + + // Enable highlight color on selected entry. + if (idx == selected_task) { + attron(COLOR_PAIR(1)); + } + + // Clear line_buffer and add string termination. + memset(line_buffer, ' ', size_x * sizeof(char)); + line_buffer[size_x-1] = '\0'; + + // Check maximum available space for task name and print it accordingly. + size_t task_name_length = strlen(task->name)*sizeof(char); + size_t max_column_length = start_columns - 2; + size_t copy_length = task_name_length < max_column_length ? task_name_length : max_column_length; + memcpy(line_buffer+2, task->name, copy_length); + addstr(line_buffer); + + // Disable highlight color on selected entry. + if (idx == selected_task) { + attroff(COLOR_PAIR(1)); + } + + // Print columns separators. + getyx(stdscr,y,x); + for (int c_idx = 0; c_idx < sizeof(columns)/sizeof(int); c_idx++) { + mvaddch(y, columns[c_idx], ACS_VLINE); + } + + // Go to next line. + y++; + move(y, 0); } - addch(ACS_URCORNER); } void draw_footer() { @@ -473,8 +593,6 @@ void draw_footer() { initscr(); /* start the curses mode */ getmaxyx(stdscr,row,col); /* get the number of rows and columns */ - printw("Row %d", row); - mvaddch(row-1, 0, ACS_LLCORNER); addch(' '); printw(app_name); @@ -492,9 +610,9 @@ WINDOW *create_newwin(int height, int width, int starty, int startx); void destroy_win(WINDOW *local_win); int main(int argc, char *argv[]) { - prototype(); - return 0; + prototype(); // TODO + initialize_layouts(); WINDOW *my_win; int startx, starty, width, height; @@ -523,6 +641,11 @@ int main(int argc, char *argv[]) { { case KEY_RESIZE: erase(); + if (line_buffer != NULL) { + free(line_buffer); + } + getmaxyx(stdscr, size_y, size_x); + line_buffer = malloc(size_x * sizeof(char)); break; case KEY_LEFT: @@ -536,22 +659,33 @@ int main(int argc, char *argv[]) { break; case KEY_UP: + selected_task = selected_task == 0 ? 0 : selected_task - 1; destroy_win(my_win); my_win = create_newwin(height, width, --starty,startx); break; case KEY_DOWN: + selected_task = (selected_task+1) == tasks_count ? selected_task : selected_task + 1; destroy_win(my_win); my_win = create_newwin(height, width, ++starty,startx); break; } - draw_header(); - draw_table(); - draw_footer(); + selected_layout = size_x > 100 ? 0 : 1; + + if (size_x >= 60 && size_y > 2) { + draw_header(); + draw_table(); + draw_footer(); + } + else { + const char* INVALID_WINDOW_MESSAGE = "Please expand window."; + mvaddstr(size_y / 2, (size_x - strlen(INVALID_WINDOW_MESSAGE)) / 2, INVALID_WINDOW_MESSAGE); + } } while((ch = getch()) != KEY_F(1)); + free_memory(); endwin(); return 0; } -- cgit v1.2.3