aboutsummaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
authordam <dam@gudinoff>2022-09-27 22:54:59 +0000
committerdam <dam@gudinoff>2022-09-27 22:54:59 +0000
commit18d7ea57eaff295aaf3e9a72390793855980aefe (patch)
treeb38e26f6ff62ac6d813ad409ed80b72dcd0cfb50 /main.c
parent6265ee44562abfe5ca38f18d10663462c700937d (diff)
downloadtask-time-tracker-18d7ea57eaff295aaf3e9a72390793855980aefe.tar.zst
task-time-tracker-18d7ea57eaff295aaf3e9a72390793855980aefe.zip
Tweaked layout structure and simplified draw_tui. Added archive title.
Diffstat (limited to 'main.c')
-rw-r--r--main.c168
1 files changed, 76 insertions, 92 deletions
diff --git a/main.c b/main.c
index 559d853..f704ccc 100644
--- a/main.c
+++ b/main.c
@@ -629,19 +629,18 @@ int size_x, size_y, pos_x, pos_y;
#define NUM_OF_COLUMNS 9
typedef struct {
- int timers_offset;
- char *table_headers[NUM_OF_COLUMNS];
- int column_widths[NUM_OF_COLUMNS];
- char alignments[NUM_OF_COLUMNS];
- int alignment_offsets[NUM_OF_COLUMNS];
-} layout_t;
+ char *header;
+ int width;
+ char alignment;
+ int alignment_offset;
+} column_st;
-layout_t *layouts = NULL;
+typedef struct {
+ column_st columns[NUM_OF_COLUMNS];
+ char *archive_title;
+} layout_st;
-// typedef enum {
-// L_NORMAL,
-// L_COMPACT,
-// } layout_type;
+layout_st layouts[2];
#define L_NORMAL 0
#define L_COMPACT 1
@@ -660,61 +659,57 @@ layout_t *layouts = NULL;
void initialize_tui() {
- layouts = calloc(2, sizeof(layout_t));
-
// Normal layout.
- layouts[L_NORMAL] = (layout_t) {
- .column_widths = { -1, 7, 7, 7, 7, 7, 7, 7, 9 },
- .alignments = { 'L', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C' },
- .table_headers = {
- " Task Time Tracker v1 ",
- " Sun ",
- " Mon ",
- " Tue ",
- " Wed ",
- " Thu ",
- " Fri ",
- " Sat ",
- " Total ",
- },
+ layouts[L_NORMAL] = (layout_st) {
+ .archive_title = " Archive ",
+ .columns = {
+ { .header = " Task Time Tracker v1 ", .width = -1, .alignment = 'L' },
+ { .header = " Sun ", .width = 7, .alignment = 'C' },
+ { .header = " Mon ", .width = 7, .alignment = 'C' },
+ { .header = " Tue ", .width = 7, .alignment = 'C' },
+ { .header = " Wed ", .width = 7, .alignment = 'C' },
+ { .header = " Thu ", .width = 7, .alignment = 'C' },
+ { .header = " Fri ", .width = 7, .alignment = 'C' },
+ { .header = " Sat ", .width = 7, .alignment = 'C' },
+ { .header = " Total ", .width = 9, .alignment = 'C' },
+ }
};
-
+
// Compact layout.
- layouts[L_COMPACT] = (layout_t){
- .column_widths = { -1, 5, 5, 5, 5, 5, 5, 5, 5 },
- .alignments = { 'L', 'C', 'C', 'C', 'C', 'C', 'C', 'C', 'C' },
- .table_headers = {
- " TTT v1 ",
- " S ",
- " M ",
- " T ",
- " W ",
- " T ",
- " F ",
- " S ",
- " # ",
- },
+ layouts[L_COMPACT] = (layout_st) {
+ .archive_title = " Archive ",
+ .columns = {
+ { .header = " TTT v1 ", .width = -1, .alignment = 'L' },
+ { .header = " S ", .width = 5, .alignment = 'C' },
+ { .header = " M ", .width = 5, .alignment = 'C' },
+ { .header = " T ", .width = 5, .alignment = 'C' },
+ { .header = " W ", .width = 5, .alignment = 'C' },
+ { .header = " T ", .width = 5, .alignment = 'C' },
+ { .header = " F ", .width = 5, .alignment = 'C' },
+ { .header = " S ", .width = 5, .alignment = 'C' },
+ { .header = " # ", .width = 5, .alignment = 'C' },
+ }
};
// Calculate alignment_offsets.
- for(layout_t *layout = layouts; layout <= layouts + 1; layout++) {
- for (int idx = 0; idx < NUM_OF_COLUMNS; idx++) {
+ for(layout_st *layout = layouts; layout <= layouts + 1; layout++) {
+ for (column_st *col = layout->columns; col <= layout->columns + NUM_OF_COLUMNS; col++) {
int offset;
- switch(layout->alignments[idx]) {
+ switch(col->alignment) {
default:
case 'L':
offset = 0;
break;
case 'C':
- offset = ((layout->column_widths[idx] - strlen(layout->table_headers[idx])) / 2);
+ offset = ((col->width - strlen(col->header)) / 2);
break;
case 'R':
- offset = (layout->column_widths[idx] - strlen(layout->table_headers[idx]));
+ offset = (col->width - strlen(col->header));
break;
}
- layout->alignment_offsets[idx] = offset;
+ col->alignment_offset = offset;
}
}
@@ -733,7 +728,7 @@ void initialize_tui() {
init_pair(THEME_E, COLOR_BLUE, COLOR_BLACK);
}
-void draw_tui(database_t *db, layout_t *layout) {
+void draw_tui(database_t *db, layout_st *layout) {
const static int adjust_first_day_of_week[] = {
(0 + FIRST_DAY_OF_WEEK) % WEEK_DAYS,
@@ -746,6 +741,7 @@ void draw_tui(database_t *db, layout_t *layout) {
};
int x, y;
+ column_st *col;
// Get context information.
task_t *active_task = get_active_task(db);
@@ -754,9 +750,9 @@ void draw_tui(database_t *db, layout_t *layout) {
int now_week_day = localtime(&now_utc)->tm_wday;
// The first column expands to fill the remaining space dynamically.
- layout->column_widths[0] = size_x - (NUM_OF_COLUMNS - 1) - 2;
+ layout->columns[0].width = size_x - (NUM_OF_COLUMNS - 1) - 2;
for (int idx = 1; idx < NUM_OF_COLUMNS; idx++) {
- layout->column_widths[0] -= layout->column_widths[idx];
+ layout->columns[0].width -= layout->columns[idx].width;
}
// Reset theme and clear screen.
@@ -770,7 +766,7 @@ void draw_tui(database_t *db, layout_t *layout) {
y = 0;
x = 0;
for (int idx = 0; idx < NUM_OF_COLUMNS - 1; idx++) {
- x += 1 + layout->column_widths[idx];
+ x += 1 + layout->columns[idx].width;
mvaddch(y, x, ACS_TTEE);
for (y = 1; y < size_y - 1; y++) {
mvaddch(y, x, ACS_VLINE);
@@ -778,13 +774,6 @@ void draw_tui(database_t *db, layout_t *layout) {
mvaddch(size_y - 1, x, ACS_BTEE);
}
- // Draw diamond symbol on top left corner when in archive mode.
- if (db == &archive) {
- attron(COLOR_PAIR(THEME_D)); // Apply theme
- mvaddch(0, 0, ACS_DIAMOND);
- attrset(A_NORMAL); // Reset theme.
- }
-
///////////////////////////////////////////////////////////////////////////
// Draw headers.
@@ -793,8 +782,9 @@ void draw_tui(database_t *db, layout_t *layout) {
// Headers : title
x++;
- mvaddstr(y, x + layout->alignment_offsets[L_TITLE_IDX], layout->table_headers[L_TITLE_IDX]);
- x += layout->column_widths[L_TITLE_IDX];
+ col = &layout->columns[L_TITLE_IDX];
+ mvaddstr(y, x + col->alignment_offset, (db == &archive ? layout->archive_title : col->header));
+ x += col->width;
// Headers : days
for (int raw_idx = 0; raw_idx < WEEK_DAYS; raw_idx++) {
@@ -809,8 +799,9 @@ void draw_tui(database_t *db, layout_t *layout) {
attron(COLOR_PAIR(THEME_D) | A_BOLD);
}
- mvaddstr(y, x + layout->alignment_offsets[idx + L_DAYS_IDX], layout->table_headers[idx + L_DAYS_IDX]);
- x += layout->column_widths[idx + L_DAYS_IDX];
+ col = &layout->columns[L_DAYS_IDX + idx];
+ mvaddstr(y, x + col->alignment_offset, col->header);
+ x += col->width;
// Reset theme.
attrset(A_NORMAL);
@@ -818,8 +809,8 @@ void draw_tui(database_t *db, layout_t *layout) {
// Headers : total
x++;
- mvaddstr(y, x + layout->alignment_offsets[L_TOTAL_IDX], layout->table_headers[L_TOTAL_IDX]);
- x += layout->column_widths[L_TOTAL_IDX]; // Not needed.
+ col = &layout->columns[L_TOTAL_IDX];
+ mvaddstr(y, x + col->alignment_offset, col->header);
///////////////////////////////////////////////////////////////////////////
@@ -853,7 +844,7 @@ void draw_tui(database_t *db, layout_t *layout) {
// Task title.
x++;
- column_width = layout->column_widths[L_TITLE_IDX];
+ column_width = layout->columns[L_TITLE_IDX].width;
sprintf(string_buffer, "%*s", column_width, "");
mvaddnstr(y, x, string_buffer, column_width);
mvaddnstr(y, x, task->name, column_width);
@@ -866,7 +857,7 @@ void draw_tui(database_t *db, layout_t *layout) {
int day_idx = (idx + FIRST_DAY_OF_WEEK) % WEEK_DAYS;
- int column_width = layout->column_widths[L_DAYS_IDX + day_idx];
+ column_width = layout->columns[L_DAYS_IDX + day_idx].width;
int64_t task_time = task->times[day_idx];
total_time = add_time(total_time, task_time);
format_time(string_buffer, task_time, column_width);
@@ -876,8 +867,7 @@ void draw_tui(database_t *db, layout_t *layout) {
// Task total.
x++;
- column_width = layout->column_widths[L_TOTAL_IDX]; // TODO
- format_time(string_buffer, total_time, column_width);
+ format_time(string_buffer, total_time, layout->columns[L_TOTAL_IDX].width);
mvaddstr(y, x, string_buffer);
// Reset theme.
@@ -888,7 +878,7 @@ void draw_tui(database_t *db, layout_t *layout) {
///////////////////////////////////////////////////////////////////////////
// Draw selected/total tasks.
sprintf(string_buffer, " %td/%zd ", db->selected_task+1, db->count);
- if (strlen(string_buffer) > layout->column_widths[L_TITLE_IDX]) {
+ if (strlen(string_buffer) > layout->columns[L_TITLE_IDX].width) {
sprintf(string_buffer, "%td", db->selected_task+1);
}
mvaddstr(size_y-1, 1, string_buffer);
@@ -896,23 +886,21 @@ void draw_tui(database_t *db, layout_t *layout) {
///////////////////////////////////////////////////////////////////////////
// Draw daily totals.
y = size_y-1;
- x = 0 + 1 + layout->column_widths[L_TITLE_IDX];
+ x = 0 + 1 + layout->columns[L_TITLE_IDX].width;
total_time = 0;
for (int idx = 0; idx < WEEK_DAYS; idx++) {
x++;
int day_idx = (idx + FIRST_DAY_OF_WEEK) % WEEK_DAYS;
int64_t daily_total = db->total_times[day_idx];
- column_width = layout->column_widths[day_idx + L_DAYS_IDX];
+ column_width = layout->columns[day_idx + L_DAYS_IDX].width;
total_time = add_time(total_time, daily_total);
format_time(string_buffer, daily_total, column_width);
mvaddstr(y, x, string_buffer);
x += column_width;
}
x++;
- column_width = layout->column_widths[L_TOTAL_IDX];
- format_time(string_buffer, total_time, column_width);
+ format_time(string_buffer, total_time, layout->columns[L_TOTAL_IDX].width);
mvaddstr(y, x, string_buffer);
- x += column_width;
}
@@ -922,9 +910,6 @@ void free_memory() {
free(string_buffer);
string_buffer = NULL;
-
- free(layouts);
- layouts = NULL;
}
#define INPUT_TIMEOUT_MS 1000
@@ -1011,18 +996,17 @@ int main(int argc, char *argv[]) {
store_database(&database, DB_BIN_PATH_NAME);
}
- // TODO
- // When this is active, it cancels selecting text with the mouse, and breaks the creation of a new task.
- // Fortunatelly, this only happens when we write on the line being selected. If we only update the places that changes, this problem goes away.
-
- int ch = KEY_RESIZE;
- do {
+ int ch;
+ ungetch(KEY_RESIZE);
+ while((ch = getch()) != 'q') {
+
+ timeout(INPUT_AWAIT_INF);
task_t *active_task = get_active_task(db);
task_t *selected_task = get_selected_task(db);
update_timers(&database);
- switch(ch)
- {
+ switch(ch) {
+
// When getch() times out.
case ERR:
break;
@@ -1031,12 +1015,12 @@ int main(int argc, char *argv[]) {
case KEY_RESIZE:
clear();
getmaxyx(stdscr, size_y, size_x);
- string_buffer = realloc(string_buffer, 511 | MAX_TASK_NAME | size_x);
+ string_buffer = realloc(string_buffer, 511 | MAX_TASK_NAME | size_x); // TODO This realloc sucks.
break;
case KEY_F(1):
{
- timeout(INPUT_AWAIT_INF);
+
task_t *new_task;
if (create_task(db, &new_task) == false) {
// ERROR
@@ -1069,7 +1053,6 @@ int main(int argc, char *argv[]) {
case KEY_F(2):
{
- timeout(INPUT_AWAIT_INF);
if (selected_task == NULL) {
break;
}
@@ -1188,15 +1171,16 @@ int main(int argc, char *argv[]) {
break;
}
- if (size_x >= 60 && size_y > 2) {
+ if (size_x >= 60 && size_y >= 3) {
draw_tui(db, &layouts[size_x > 100 ? L_NORMAL : L_COMPACT]);
}
else {
const char *INVALID_WINDOW_MESSAGE = "Please expand window.";
mvaddstr(size_y / 2, (size_x - strlen(INVALID_WINDOW_MESSAGE)) / 2, INVALID_WINDOW_MESSAGE);
}
- timeout(INPUT_TIMEOUT_MS); // Make getch() timeout.
- } while((ch = getch()) != 'q');
+
+ timeout(INPUT_TIMEOUT_MS);
+ }
update_timers(&database);
store_database(&database, DB_BIN_PATH_NAME);