diff options
| author | dam <dam@gudinoff> | 2023-04-04 17:45:05 +0100 |
|---|---|---|
| committer | dam <dam@gudinoff> | 2023-04-04 17:45:05 +0100 |
| commit | 98a21ce9edcd22bf7a9dde62f317f143e289ecf5 (patch) | |
| tree | 14613e8506a6fe481b2072fae7aad826809b1b19 | |
| parent | ee5fa34d14288a4ce79d77a0d3a89cc14b16a6b1 (diff) | |
| download | task-time-tracker-98a21ce9edcd22bf7a9dde62f317f143e289ecf5.tar.zst task-time-tracker-98a21ce9edcd22bf7a9dde62f317f143e289ecf5.zip | |
WIP Making ncurses work a bit.
| -rw-r--r-- | curses.jai | 303 | ||||
| -rw-r--r-- | sizeof.c | 47 | ||||
| -rw-r--r-- | ttt.jai | 213 |
3 files changed, 397 insertions, 166 deletions
@@ -1,62 +1,62 @@ ldat :: struct { - text :*void; /* text of the line */ - firstchar :s16; /* first changed character in the line */ - lastchar :s16; /* last changed character in the line */ - oldindex :s16; /* index of the line at last update */ + text :*void; /* text of the line */ + firstchar :s16; /* first changed character in the line */ + lastchar :s16; /* last changed character in the line */ + oldindex :s16; /* index of the line at last update */ }; // TODO This also works... -WINDOW :: struct { +WINDOWx :: struct { data : [88] u8; } -WINDOWx :: struct { - _cury, _curx : s16; /* current cursor position */ - - /* window location and size */ - _maxy, _maxx : s16; /* maximums of x and y, NOT window size */ - _begy, _begx : s16; /* screen coords of upper-left-hand corner */ - - _flags :s16; /* window state flags */ - - /* attribute tracking */ - _attrs :u8; /* current attribute for non-space character */ - _bkgd :u8; /* current background char/attribute pair */ - - /* option values set by user */ - _notimeout :bool; /* no time out on function-key entry? */ - _clear :bool; /* consider all data in the window invalid? */ - _leaveok :bool; /* OK to not reset cursor on exit? */ - _scroll :bool; /* OK to scroll this window? */ - _idlok :bool; /* OK to use insert/delete line? */ - _idcok :bool; /* OK to use insert/delete char? */ - _immed :bool; /* window in immed mode? (not yet used) */ - _sync :bool; /* window in sync mode? */ - _use_keypad :bool; /* process function keys into KEY_ symbols? */ - _delay :s32; /* 0 = nodelay, <0 = blocking, >0 = delay */ - - _line :*ldat; /* the actual line data */ - - /* global screen state */ - _regtop :s16; /* top line of scrolling region */ - _regbottom :s16; /* bottom line of scrolling region */ - - /* these are used only if this is a sub-window */ - _parx :s32; /* x coordinate of this window in parent */ - _pary :s32; /* y coordinate of this window in parent */ +WINDOW :: struct { + _cury, _curx : s16; /* current cursor position */ + + /* window location and size */ + _maxy, _maxx : s16; /* maximums of x and y, NOT window size */ + _begy, _begx : s16; /* screen coords of upper-left-hand corner */ + + _flags :s16; /* window state flags */ + + /* attribute tracking */ + _attrs :u8; /* current attribute for non-space character */ + _bkgd :u8; /* current background char/attribute pair */ + + /* option values set by user */ + _notimeout :bool; /* no time out on function-key entry? */ + _clear :bool; /* consider all data in the window invalid? */ + _leaveok :bool; /* OK to not reset cursor on exit? */ + _scroll :bool; /* OK to scroll this window? */ + _idlok :bool; /* OK to use insert/delete line? */ + _idcok :bool; /* OK to use insert/delete char? */ + _immed :bool; /* window in immed mode? (not yet used) */ + _sync :bool; /* window in sync mode? */ + _use_keypad :bool; /* process function keys into KEY_ symbols? */ + _delay :s32; /* 0 = nodelay, <0 = blocking, >0 = delay */ + + _line :*ldat; /* the actual line data */ + + /* global screen state */ + _regtop :s16; /* top line of scrolling region */ + _regbottom :s16; /* bottom line of scrolling region */ + + /* these are used only if this is a sub-window */ + _parx :s32; /* x coordinate of this window in parent */ + _pary :s32; /* y coordinate of this window in parent */ _parent :*WINDOW; /* pointer to parent if a sub-window */ - /* these are used only if this is a pad */ - pdat :: struct - { - _pad_y, _pad_x :s16 ; - _pad_top, _pad_left :s16; - _pad_bottom, _pad_right :s16; - }; + /* these are used only if this is a pad */ + pdat :: struct + { + _pad_y, _pad_x :s16 ; + _pad_top, _pad_left :s16; + _pad_bottom, _pad_right :s16; + }; _pad :pdat; - - _yoffset :s16; /* real begy is _begy + _yoffset */ + + _yoffset :s16; /* real begy is _begy + _yoffset */ /* #if NCURSES_WIDECHAR @@ -79,29 +79,214 @@ tinfo :: #system_library "libtinfo"; // Required by some of ncurses functions. // ncurses :: #system_library "libncurses"; ncurses :: #library "libncurses"; -COLOR_BLACK :: 0; -COLOR_RED :: 1; -COLOR_GREEN :: 2; -COLOR_YELLOW :: 3; -COLOR_BLUE :: 4; -COLOR_MAGENTA :: 5; -COLOR_CYAN :: 6; -COLOR_WHITE :: 7; - stdscr : *WINDOW; initscr :: () -> *WINDOW #foreign ncurses; -getch :: () -> s8 #foreign ncurses; +getch :: () -> s32 #foreign ncurses; endwin :: () -> void #foreign ncurses; cbreak :: () -> void #foreign ncurses; start_color :: () -> void #foreign ncurses; use_default_colors :: () -> void #foreign ncurses; - +flushinp :: () -> s32 #foreign ncurses; keypad :: (win: *WINDOW, bf: bool) -> s32 #foreign ncurses; +ungetch :: (ch: s32) -> s32 #foreign ncurses; +attrset :: (attrs: s32) -> s32 #foreign ncurses; +erase :: () -> s32 #foreign ncurses; curs_set :: (visibility: s32) -> s32 #foreign ncurses; mvaddstr :: (y: s32, x: s32, str: *u8) -> s32 #foreign ncurses; noecho :: () -> s32 #foreign ncurses; box :: (win: *WINDOW, verch: u8, horch: u8) -> s32 #foreign ncurses; init_pair :: (pair: s16, f: s16, b: s16) -> s32 #foreign ncurses; +timeout :: (delay: s32) -> void #foreign ncurses; +mvaddch :: (y: s32, x: s32, ch: u32) -> s32 #foreign ncurses; +clear :: () -> s32 #foreign ncurses; +refresh :: () -> s32 #foreign ncurses; + +getmaxyx :: inline (win: *WINDOW, y: *s32, x: *s32) { <<y = getmaxy(win); <<x = getmaxx(win); } +getmaxx :: inline (win: *WINDOW) -> s32 { return ifx win == null then ERR else win._maxx + 1; } +getmaxy :: inline (win: *WINDOW) -> s32 { return ifx win == null then ERR else win._maxy + 1; } +getcurx :: inline (win: *WINDOW) -> s32 { return ifx win == null then ERR else win._curx; } +getcury :: inline (win: *WINDOW) -> s32 { return ifx win == null then ERR else win._cury; } + +//#if CPU == .X64 { +//typedef unsigned chtype; // Used for mask and shift vars. +//typedef unsigned mmask_t; +//} else { +//typedef uint32_t chtype; +//typedef uint32_t mmask_t; +//} +NCURSES_ATTR_SHIFT :: 8; +NCURSES_BITS :: inline (mask: u32, shift: u32) -> u32 { return mask << (shift + NCURSES_ATTR_SHIFT); } + +A_NORMAL :: 0; +A_ATTRIBUTES :: #run NCURSES_BITS(~(cast(u32)(1 - 1)),0); +A_CHARTEXT :: #run (NCURSES_BITS(1,0) - 1); +A_COLOR :: #run NCURSES_BITS(((1) << 8) - 1,0); +A_STANDOUT :: #run NCURSES_BITS(1,8); +A_UNDERLINE :: #run NCURSES_BITS(1,9); +A_REVERSE :: #run NCURSES_BITS(1,10); +A_BLINK :: #run NCURSES_BITS(1,11); +A_DIM :: #run NCURSES_BITS(1,12); +A_BOLD :: #run NCURSES_BITS(1,13); +A_ALTCHARSET :: #run NCURSES_BITS(1,14); +A_INVIS :: #run NCURSES_BITS(1,15); +A_PROTECT :: #run NCURSES_BITS(1,16); +A_HORIZONTAL :: #run NCURSES_BITS(1,17); +A_LEFT :: #run NCURSES_BITS(1,18); +A_LOW :: #run NCURSES_BITS(1,19); +A_RIGHT :: #run NCURSES_BITS(1,20); +A_TOP :: #run NCURSES_BITS(1,21); +A_VERTICAL :: #run NCURSES_BITS(1,22); +A_ITALIC :: #run NCURSES_BITS(1,23); // ncurses extension + +// VT100 symbols begin here. +ACS_ULCORNER :: #run A_ALTCHARSET | #char "l"; /* upper left corner */ +ACS_LLCORNER :: #run A_ALTCHARSET | #char "m"; /* lower left corner */ +ACS_URCORNER :: #run A_ALTCHARSET | #char "k"; /* upper right corner */ +ACS_LRCORNER :: #run A_ALTCHARSET | #char "j"; /* lower right corner */ +ACS_LTEE :: #run A_ALTCHARSET | #char "t"; /* tee pointing right */ +ACS_RTEE :: #run A_ALTCHARSET | #char "u"; /* tee pointing left */ +ACS_BTEE :: #run A_ALTCHARSET | #char "v"; /* tee pointing up */ +ACS_TTEE :: #run A_ALTCHARSET | #char "w"; /* tee pointing down */ +ACS_HLINE :: #run A_ALTCHARSET | #char "q"; /* horizontal line */ +ACS_VLINE :: #run A_ALTCHARSET | #char "x"; /* vertical line */ +ACS_PLUS :: #run A_ALTCHARSET | #char "n"; /* large plus or crossover */ +ACS_S1 :: #run A_ALTCHARSET | #char "o"; /* scan line 1 */ +ACS_S9 :: #run A_ALTCHARSET | #char "s"; /* scan line 9 */ +ACS_DIAMOND :: #run A_ALTCHARSET | #char "`"; /* diamond */ +ACS_CKBOARD :: #run A_ALTCHARSET | #char "a"; /* checker board (stipple) */ +ACS_DEGREE :: #run A_ALTCHARSET | #char "f"; /* degree symbol */ +ACS_PLMINUS :: #run A_ALTCHARSET | #char "g"; /* plus/minus */ +ACS_BULLET :: #run A_ALTCHARSET | #char "~"; /* bullet */ +// Teletype 5410v1 symbols begin here. +ACS_LARROW :: #run A_ALTCHARSET | #char ","; /* arrow pointing left */ +ACS_RARROW :: #run A_ALTCHARSET | #char "+"; /* arrow pointing right */ +ACS_DARROW :: #run A_ALTCHARSET | #char "."; /* arrow pointing down */ +ACS_UARROW :: #run A_ALTCHARSET | #char "-"; /* arrow pointing up */ +ACS_BOARD :: #run A_ALTCHARSET | #char "h"; /* board of squares */ +ACS_LANTERN :: #run A_ALTCHARSET | #char "i"; /* lantern symbol */ +ACS_BLOCK :: #run A_ALTCHARSET | #char "0"; /* solid square block */ +// These aren't documented, but a lot of System Vs have them anyway +// (you can spot pprryyzz{{||}} in a lot of AT&T terminfo strings). +// The ACS_names may not match AT&T's, our source didn't know them. +ACS_S3 :: #run A_ALTCHARSET | #char "p"; /* scan line 3 */ +ACS_S7 :: #run A_ALTCHARSET | #char "r"; /* scan line 7 */ +ACS_LEQUAL :: #run A_ALTCHARSET | #char "y"; /* less/equal */ +ACS_GEQUAL :: #run A_ALTCHARSET | #char "z"; /* greater/equal */ +ACS_PI :: #run A_ALTCHARSET | #char "{"; /* Pi */ +ACS_NEQUAL :: #run A_ALTCHARSET | #char "|"; /* not equal */ +ACS_STERLING :: #run A_ALTCHARSET | #char "}"; /* UK pound sign */ + + +COLOR_PAIR :: (n: s32) -> s32 #foreign ncurses; + +COLOR_BLACK :: 0; +COLOR_RED :: 1; +COLOR_GREEN :: 2; +COLOR_YELLOW :: 3; +COLOR_BLUE :: 4; +COLOR_MAGENTA :: 5; +COLOR_CYAN :: 6; +COLOR_WHITE :: 7; + +ERR :: -1; +OK :: 0; + + +KEY_CODE_YES :: 0400; +KEY_MIN :: 0401; +KEY_BREAK :: 0401; +KEY_SRESET :: 0530; +KEY_RESET :: 0531; +KEY_DOWN :: 0402; +KEY_UP :: 0403; +KEY_LEFT :: 0404; +KEY_RIGHT :: 0405; +KEY_HOME :: 0406; +KEY_BACKSPACE :: 0407; +KEY_F0 :: 0410; +KEY_F :: inline (n: s32) -> s32 { return KEY_F0+n; }; +KEY_DL :: 0510; +KEY_IL :: 0511; +KEY_DC :: 0512; +KEY_IC :: 0513; +KEY_EIC :: 0514; +KEY_CLEAR :: 0515; +KEY_EOS :: 0516; +KEY_EOL :: 0517; +KEY_SF :: 0520; +KEY_SR :: 0521; +KEY_NPAGE :: 0522; +KEY_PPAGE :: 0523; +KEY_STAB :: 0524; +KEY_CTAB :: 0525; +KEY_CATAB :: 0526; +KEY_ENTER :: 0527; +KEY_PRINT :: 0532; +KEY_LL :: 0533; +KEY_A1 :: 0534; +KEY_A3 :: 0535; +KEY_B2 :: 0536; +KEY_C1 :: 0537; +KEY_C3 :: 0540; +KEY_BTAB :: 0541; +KEY_BEG :: 0542; +KEY_CANCEL :: 0543; +KEY_CLOSE :: 0544; +KEY_COMMAND :: 0545; +KEY_COPY :: 0546; +KEY_CREATE :: 0547; +KEY_END :: 0550; +KEY_EXIT :: 0551; +KEY_FIND :: 0552; +KEY_HELP :: 0553; +KEY_MARK :: 0554; +KEY_MESSAGE :: 0555; +KEY_MOVE :: 0556; +KEY_NEXT :: 0557; +KEY_OPEN :: 0560; +KEY_OPTIONS :: 0561; +KEY_PREVIOUS :: 0562; +KEY_REDO :: 0563; +KEY_REFERENCE :: 0564; +KEY_REFRESH :: 0565; +KEY_REPLACE :: 0566; +KEY_RESTART :: 0567; +KEY_RESUME :: 0570; +KEY_SAVE :: 0571; +KEY_SBEG :: 0572; +KEY_SCANCEL :: 0573; +KEY_SCOMMAND :: 0574; +KEY_SCOPY :: 0575; +KEY_SCREATE :: 0576; +KEY_SDC :: 0577; +KEY_SDL :: 0600; +KEY_SELECT :: 0601; +KEY_SEND :: 0602; +KEY_SEOL :: 0603; +KEY_SEXIT :: 0604; +KEY_SFIND :: 0605; +KEY_SHELP :: 0606; +KEY_SHOME :: 0607; +KEY_SIC :: 0610; +KEY_SLEFT :: 0611; +KEY_SMESSAGE :: 0612; +KEY_SMOVE :: 0613; +KEY_SNEXT :: 0614; +KEY_SOPTIONS :: 0615; +KEY_SPREVIOUS :: 0616; +KEY_SPRINT :: 0617; +KEY_SREDO :: 0620; +KEY_SREPLACE :: 0621; +KEY_SRIGHT :: 0622; +KEY_SRSUME :: 0623; +KEY_SSAVE :: 0624; +KEY_SSUSPEND :: 0625; +KEY_SUNDO :: 0626; +KEY_SUSPEND :: 0627; +KEY_UNDO :: 0630; +KEY_MOUSE :: 0631; +KEY_RESIZE :: 0632; +KEY_MAX :: 0777; diff --git a/sizeof.c b/sizeof.c new file mode 100644 index 0000000..4844cba --- /dev/null +++ b/sizeof.c @@ -0,0 +1,47 @@ +// compile with : gcc sizeof.c -lncurses + +#include <assert.h> +#include <errno.h> +#include <inttypes.h> +#include <limits.h> +#include <locale.h> +#include <ncurses.h> +#include <signal.h> +#include <stdarg.h> +#include <stdbool.h> +#include <stddef.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <time.h> + +int main(int argc, char **argv) { + initscr(); + + fprintf(stderr, "sizeof char: %d\n", sizeof(char)); + fprintf(stderr, "sizeof short: %d\n", sizeof(short)); + fprintf(stderr, "sizeof int: %d\n", sizeof(int)); + fprintf(stderr, "sizeof unsigned: %d\n", sizeof(unsigned)); + fprintf(stderr, "sizeof chtype: %d\n", sizeof(chtype)); + int w_size_x, w_size_y; + getmaxyx(stdscr, w_size_y, w_size_x); + char str[64]; + memset(str, 0, 64); + sprintf(str, "x,y : %dx%d\n", w_size_x, w_size_y); + mvaddstr(2, 2, str); + + unsigned m = ACS_DIAMOND; + fprintf(stderr, "sizeof ACS %d\n", sizeof(ACS_DIAMOND)); + + if (ACS_DIAMOND != 0 || ACS_URCORNER != 0){ + fprintf(stderr, "BAZINGA\n"); + } +// fprintf(stderr, ">%d<\n", strlen(ACS_DIAMOND)); + + mvaddch(0, 0, m); + getch(); + endwin(); +} + @@ -74,20 +74,23 @@ Database :: struct { database : Database; archive : Database; is_autosave_enabled := true; -// int countdown_to_autosave = -1; +countdown_to_autosave := -1; app_directory : string; db_file_path : string; ar_file_path : string; // char *string_buffer = NULL; // A temporary buffer for localized actions. Please avoid data leaks and out-of-bounds errors. // size_t string_buffer_size = 0; -// int size_x, size_y, pos_x, pos_y; +size_x : s32; +size_y : s32; +pos_x : s32; +pos_y : s32; Styles :: enum s16 { STYLE_SELECTED :: 1; - STYLE_SELECTED_INVERTED; + SELECTED_INVERTED; STYLE_ACTIVE; STYLE_ACTIVE_SELECTED; - STYLE_ERROR; + ERROR; } Layouts :: enum u8 { @@ -109,7 +112,7 @@ print_error :: (format :string, args : .. Any) { // int w_size_y = 4; // if (error_window == NULL) { // error_window = newwin(w_size_y, w_size_x, (size_y - w_size_y) / 2, (size_x - w_size_x) / 2); -// wattron(error_window, COLOR_PAIR(STYLE_ERROR)); +// wattron(error_window, COLOR_PAIR(ERROR)); // wborder(error_window, ' ', ' ', 0, 0, ACS_HLINE, ACS_HLINE, ACS_HLINE, ACS_HLINE); // mvwprintw(error_window, 0, 1, " Error "); // wmove(error_window, 1, 0); @@ -152,18 +155,15 @@ draw_error_window :: () { */ } -/* -void trigger_autosave() { +trigger_autosave :: () { countdown_to_autosave = 13375; // ms } -void show_processing() { +show_processing :: () { mvaddch(0, 0, ACS_DIAMOND); refresh(); } -*/ - // Returns true if string to_compare is equal to any of the other passed strings, false otherwise. is_equal_to_any :: (to_compare :string, test_a :string, test_b :string) -> bool { return to_compare == test_a || to_compare == test_b; @@ -299,29 +299,24 @@ sub_int64 :: (x :s64, y :s64) -> s64 { x - y; } -/* // Returns active task or NULL if none applies. -task_st *get_active_task(database_st *db) { - assert(db != NULL); - - task_st *task = NULL; - if (db->active_task >= 0) { - task = db->tasks + db->active_task; +get_active_task :: inline (db: Database) -> *Task { + task: *Task = null; + if (db.active_idx >= 0) { + task = *db.tasks[db.active_idx]; } return task; } // Returns selected task or NULL if none applies. -task_st *get_selected_task(database_st *db) { - assert(db != NULL); - - task_st *task = NULL; - if (db->selected_task >= 0) { - task = db->tasks + db->selected_task; +get_selected_task :: inline (db: Database) -> *Task { + task: *Task = null; + if (db.selected_idx >= 0) { + task = *db.tasks[db.selected_idx]; } return task; } -*/ + // Adds a task to the database. // If necessary, expands database capacity. // Returns success. @@ -528,11 +523,12 @@ void move_task_to_index(database_st *db, task_st *task, ptrdiff_t index) { } db->selected_task = target_index; } - +*/ // Updates the times on the active task (and adjusts database totals). -void update_times(database_st *db) { - assert(db != NULL); - +update_times :: (db: *Database) { + assert(db != null); + return; + /* // Get current UTC time. time_t stop_time = time(NULL); @@ -566,8 +562,9 @@ void update_times(database_st *db) { start_time = next_start; } + */ } - +/* // Recalculates database totals. void update_total_times(database_st *db) { assert(db != NULL); @@ -642,8 +639,7 @@ reset_database :: (db: *Database) { // Stores data from database into binary file. // Returns success. -store_database :: (db: *Database, path: string) -> success: bool { - assert(db != null, "Parameter 'db' is null."); +store_database :: (db: Database, path: string) -> success: bool { assert(xx path, "Parameter 'path' is empty."); // Open file. @@ -655,7 +651,7 @@ store_database :: (db: *Database, path: string) -> success: bool { defer file_close(*file); file_write(*file, DB_FILE_SIGN_STR); - file_write(*file, db, size_of(Database)); + file_write(*file, *db, size_of(Database)); file_write(*file, db.tasks.data, size_of(Task) * db.tasks.count); return true; @@ -710,8 +706,7 @@ load_database :: (db: *Database, path: string) -> success: bool { // Exports data into CSV file. // Returns success. -export_to_csv :: (db: *Database, path: string) -> success: bool { - assert(db != null, "Parameter 'db' is null."); +export_to_csv :: (db: Database, path: string) -> success: bool { assert(xx path, "Parameter 'path' is empty."); // TODO Make sure (IN ALL PROCEDURES) we're not receiving an empty path. @@ -1013,7 +1008,7 @@ initialize_tui :: () { // TODO //setlocale(LC_ALL, "C.UTF-8"); // Sets locale for C library functions; Allows usage of UTF-8. - stdscr = initscr(); // Start curses mode. + stdscr = initscr(); // Start curses mode. cbreak(); // Line buffering disabled; pass on everty thing to me. keypad(stdscr, true); // I need those nifty F1..F12. curs_set(0); // Set cursor invisible. @@ -1023,29 +1018,28 @@ initialize_tui :: () { start_color(); use_default_colors(); // Using default (-1) instead of COLOR_BLACK. init_pair(xx Styles.STYLE_SELECTED, COLOR_BLACK, COLOR_CYAN); - init_pair(xx Styles.STYLE_SELECTED_INVERTED, COLOR_CYAN, -1); + init_pair(xx Styles.SELECTED_INVERTED, COLOR_CYAN, -1); init_pair(xx Styles.STYLE_ACTIVE, COLOR_BLUE, -1); init_pair(xx Styles.STYLE_ACTIVE_SELECTED, COLOR_WHITE, COLOR_BLUE); - init_pair(xx Styles.STYLE_ERROR, COLOR_RED, -1); + init_pair(xx Styles.ERROR, COLOR_RED, -1); } -/* -void update_layout() { +update_layout :: () { // Calculate number of available rows to display tasks. layout_tasks_rows = (size_y - NUM_HEADER_ROWS - NUM_FOOTER_ROWS); // Calculate 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; + for * layout: layouts { + layout.columns[0].width = size_x - (NUM_COLUMNS - 1) - 2; + for 1..layout.columns.count-1 { + layout.columns[0].width -= layout.columns[it].width; } } } -void draw_tui(database_st *db, layout_st *layout) { - - const static int adjust_first_day_of_week[] = { +draw_tui :: (db: *Database, layout: *Layout) { + + adjust_first_day_of_week := int.[ (0 + FIRST_DAY_OF_WEEK) % NUM_WEEK_DAYS, (1 + FIRST_DAY_OF_WEEK) % NUM_WEEK_DAYS, (2 + FIRST_DAY_OF_WEEK) % NUM_WEEK_DAYS, @@ -1053,36 +1047,37 @@ void draw_tui(database_st *db, layout_st *layout) { (4 + FIRST_DAY_OF_WEEK) % NUM_WEEK_DAYS, (5 + FIRST_DAY_OF_WEEK) % NUM_WEEK_DAYS, (6 + FIRST_DAY_OF_WEEK) % NUM_WEEK_DAYS, - }; - - int x, y; - column_st *col; + ]; + x: int; + y: int; + col: *Column; + // Get context information. - task_st *active_task = get_active_task(db); - task_st *selected_task = get_selected_task(db); - time_t now_utc = time(NULL); - int now_week_day = localtime(&now_utc)->tm_wday; + active_task := get_active_task(db); + selected_task := get_selected_task(db); + now_utc := current_time_consensus(); + now_week_day := to_calendar(now_utc).day_of_week_starting_at_0; // Reset theme and clear screen. attrset(A_NORMAL); erase(); - + // Draw outer border. box(stdscr, 0, 0); - + // Draw table grids. y = 0; x = 0; - for (int idx = 0; idx < NUM_COLUMNS - 1; 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); + for layout.columns { + x += 1 + it.width; + mvaddch(xx y, xx x, ACS_TTEE); + for row: 1..size_y-1 { + mvaddch(xx row, xx x, ACS_VLINE); } - mvaddch(size_y - 1, x, ACS_BTEE); + mvaddch(size_y-1, xx x, ACS_BTEE); } - +return; /* /////////////////////////////////////////////////////////////////////////// // Draw headers. @@ -1105,7 +1100,7 @@ void draw_tui(database_st *db, layout_st *layout) { attron(COLOR_PAIR(STYLE_ACTIVE) | A_BOLD); } else if (idx == now_week_day) { - attron(COLOR_PAIR(STYLE_SELECTED_INVERTED) | A_BOLD); + attron(COLOR_PAIR(SELECTED_INVERTED) | A_BOLD); } col = &layout->columns[L_DAYS_IDX + idx]; @@ -1203,7 +1198,7 @@ void draw_tui(database_st *db, layout_st *layout) { attron(COLOR_PAIR(STYLE_ACTIVE) | A_BOLD); } else if (idx == now_week_day) { - attron(COLOR_PAIR(STYLE_SELECTED_INVERTED) | A_BOLD); + attron(COLOR_PAIR(SELECTED_INVERTED) | A_BOLD); } column_width = layout->columns[L_DAYS_IDX + idx].width; @@ -1216,8 +1211,9 @@ void draw_tui(database_st *db, layout_st *layout) { } x++; mvprintw_time(y, x, total_time, layout->columns[L_TOTAL_IDX].width); + */ } - +/* void *mem_alloc(size_t mem_size, const char *error_tag) { void *mem_pointer = malloc(mem_size); if (mem_pointer == NULL && mem_size > 0) { @@ -1335,14 +1331,14 @@ main :: () { { // Initialize database and archive files if needed. if (file_exists(db_file_path) == false) { - if (store_database(*database, db_file_path) == false) { + if (store_database(database, db_file_path) == false) { print_error("Failed to initialize database."); exit(1); } } if (file_exists(ar_file_path) == false) { - if (export_to_csv(*archive, ar_file_path) == false) { + if (export_to_csv(archive, ar_file_path) == false) { print_error("Failed to initialize archive."); exit(1); } @@ -1474,67 +1470,69 @@ main :: () { } initialize_tui(); - /* + // TODO Remove this?! //signal(SIGTERM, exit_gracefully); //signal(SIGINT, exit_gracefully); //signal(SIGQUIT, exit_gracefully); //signal(SIGHUP, exit_gracefully); + layout := *layouts[Layouts.COMPACT]; + db := *database; + flushinp(); ungetch(KEY_RESIZE); - for (int key; ((key = getch()) != 'q') && (key != 'Q'); ) { + while (true) { + key := getch(); + if key == #char "q" || key == #char "Q" break; - static layout_st *layout = &layouts[L_COMPACT]; - task_st *active_task = get_active_task(db); - task_st *selected_task = get_selected_task(db); - int action_style = A_BOLD | COLOR_PAIR(selected_task == active_task && selected_task != NULL ? STYLE_ACTIVE : STYLE_SELECTED_INVERTED); - int error_style = A_BOLD | COLOR_PAIR(STYLE_ERROR); - int selected_task_row = is_terminal_too_small ? 0 - : (db->selected_task < 0) ? 1 - : (db->selected_task % layout_tasks_rows) + NUM_HEADER_ROWS; + active_task := get_active_task(db); + selected_task := get_selected_task(db); + action_style := A_BOLD | COLOR_PAIR(xx ifx selected_task == active_task && selected_task != null + then Styles.STYLE_ACTIVE + else Styles.SELECTED_INVERTED); + error_style := A_BOLD | COLOR_PAIR(xx Styles.ERROR); + selected_task_row : int = ifx is_terminal_too_small then 0 + else ifx (db.selected_idx < 0) then 1 + else (db.selected_idx % layout_tasks_rows) + NUM_HEADER_ROWS; timeout(INPUT_AWAIT_INF); - update_times(&database); + update_times(*database); - switch(key) { + if key == { // When getch() times out. - case ERR: { + case ERR; if (is_autosave_enabled && countdown_to_autosave > 0) { countdown_to_autosave -= INPUT_TIMEOUT_MS; if (countdown_to_autosave <= 0) { show_processing(); - if (db == &archive) { - export_to_csv(&archive, ar_file_path); + if (db == *archive) { + export_to_csv(*archive, ar_file_path); } - store_database(&database, db_file_path); + store_database(database, db_file_path); } } - break; - } // When terminal is resized. - case KEY_RESIZE: { + case KEY_RESIZE; // BUG KEY_RESIZE is not happening. clear(); - getmaxyx(stdscr, size_y, size_x); + getmaxyx(stdscr, *size_y, *size_x); is_terminal_too_small = size_x < 60 || size_y < 3; - size_t new_size = 2047 | TASK_NAME_BYTES | (size_x + 1); - if (string_buffer_size < new_size) { - string_buffer_size = new_size; - string_buffer = realloc(string_buffer, string_buffer_size); - if (string_buffer == NULL && string_buffer_size > 0) { - print_error("Failed to allocate memory for string buffer: %s.", strerror(errno)); - flushinp(); - ungetch('q'); - break; - } - } + new_size := 2047 | TASK_NAME_BYTES | (size_x + 1); + //if (string_buffer_size < new_size) { + //string_buffer_size = new_size; + //string_buffer = realloc(string_buffer, string_buffer_size); + //if (string_buffer == NULL && string_buffer_size > 0) { + //print_error("Failed to allocate memory for string buffer: %s.", strerror(errno)); + //flushinp(); + //ungetch(#char "q"); + //break; + //} + //} update_layout(); - layout = &layouts[size_x > 100 ? L_NORMAL : L_COMPACT]; - break; - } - + layout = *layouts[ifx size_x > 100 then Layouts.NORMAL else Layouts.COMPACT]; +/* case 'n': case 'N':{ if (is_database_full(db)) { @@ -1849,12 +1847,12 @@ main :: () { select_task_by_delta(db, layout_tasks_rows); break; } +*/ } if (is_terminal_too_small) { - const char *INVALID_WINDOW_MESSAGE = "Terminal is too small: minimum 60x3."; - const int INVALID_WINDOW_MESSAGE_LENGTH = strlen(INVALID_WINDOW_MESSAGE); - mvaddstr(size_y / 2, (size_x - INVALID_WINDOW_MESSAGE_LENGTH) / 2, INVALID_WINDOW_MESSAGE); + INVALID_WINDOW_MESSAGE :: "Terminal is too small: minimum 60x3."; + mvaddstr(size_y / 2, (size_x - xx INVALID_WINDOW_MESSAGE.count) / 2, INVALID_WINDOW_MESSAGE); } else { draw_tui(db, layout); @@ -1862,8 +1860,9 @@ main :: () { } timeout(INPUT_TIMEOUT_MS); + } - */ + // Save any unsaved changes. // show_processing(); error_saving := false; |
