diff options
| author | dam <dam@gudinoff> | 2024-05-10 15:55:36 +0100 |
|---|---|---|
| committer | dam <dam@gudinoff> | 2024-05-10 15:55:36 +0100 |
| commit | af6221d2b3d6d9f524959ffd15766a171f3ad798 (patch) | |
| tree | 4f6717526fc054f8f4bf4a5df85ee7b29a1839f6 /ttt.jai | |
| parent | 3dfabf220d80ae0329b828a848714e8e1ff7f291 (diff) | |
| download | task-time-tracker-af6221d2b3d6d9f524959ffd15766a171f3ad798.tar.zst task-time-tracker-af6221d2b3d6d9f524959ffd15766a171f3ad798.zip | |
Made start day of week configurable via input arg. Fixed display of time with decimals.
Diffstat (limited to 'ttt.jai')
| -rw-r--r-- | ttt.jai | 125 |
1 files changed, 63 insertions, 62 deletions
@@ -33,13 +33,9 @@ DEBUG_MEMORY :: true; #import "UTF8"; TUI :: #import "TUI"(COLOR_MODE_BITS=4); -// - fix/implement/finish TODO : use `dirty_bit_flag` to only update ehat has been changed - VERSION :: "2.0"; // Use only 3 chars (to fit layouts). YEAR :: "2024"; -FIRST_DAY_OF_WEEK :: 1; // (0-6, Sunday = 0). -NUM_WEEK_DAYS :: 7; // TODO This has to go - Just to be more clear about what we're looping about. -NAME_SIZE :: 72; // TODO Use this instead of Task.name.count ? +NUM_WEEK_DAYS :: 7; APP_FOLDER_NAME :: ".task_time_tracker_test"; // TODO Using different folder to avoid erasing my work data. DB_FILE_NAME :: "database.bin"; @@ -74,6 +70,7 @@ database : Database; archive : Database; is_autosave_enabled := true; countdown_to_autosave := -1; +first_day_of_week := 1; // (0-6, Sunday = 0, Monday = 1, ...) app_directory : string; db_file_path : string; ar_file_path : string; @@ -262,7 +259,7 @@ print_time :: (y: int, x: int, time: s64, space: int) -> int { ifx time >= #run mul_f64_s64(9.995, SECONDS_IN_DAY) then 1 else 2; print_padding(left_padding); - print("%d", FormatFloat.{value = value, trailing_width=decimals, width=4}); + print("%d", FormatFloat.{value = value, trailing_width=decimals, width=4, zero_removal=.NO}); print_padding(right_padding); return 0; } @@ -273,7 +270,7 @@ print_time :: (y: int, x: int, time: s64, space: int) -> int { ifx time >= #run mul_f64_s64(9.995, SECONDS_IN_YEAR) then 1 else 2; print_padding(left_padding); - print("%y", FormatFloat.{value = value, trailing_width=decimals, width=4}); + print("%y", FormatFloat.{value = value, trailing_width=decimals, width=4, zero_removal=.NO}); print_padding(right_padding); return 0; } @@ -318,7 +315,7 @@ add_task :: (db: *Database, task: *Task = null) -> task: *Task, index: s64 { // Deletes task from database. // If possible, shrinks the database capacity. // Returns success. -delete_task :: (using db: *Database, index: s64) -> bool { // TODO Maybe use `using db`. +delete_task :: (using db: *Database, index: s64) -> bool { assert(db != null, ASSERT_NOT_NULL, "db"); assert(is_valid_index(db, index), ASSERT_INVALID_INDEX, index); @@ -361,40 +358,40 @@ delete_task :: (using db: *Database, index: s64) -> bool { // TODO Maybe use `us // Moves task from source to target. // Source and target get clamped to database size. -move_task :: (db: *Database, source: s64, target: s64) { // TODO Maybe `using db` +move_task :: (using db: *Database, source: s64, target: s64) { assert(db != null, ASSERT_NOT_NULL, "db"); - source = clamp(source, 0, db.tasks.count-1); - target = clamp(target, 0, db.tasks.count-1); + source = clamp(source, 0, tasks.count-1); + target = clamp(target, 0, tasks.count-1); if (source == target) return; // Move task to new location, but first, shift the others to allow some space. - temp_task := db.tasks[source]; + temp_task := tasks[source]; move_size := abs(target - source); if target > source { for 0..move_size-1 - db.tasks[source + it] = db.tasks[source + it + 1]; + tasks[source + it] = tasks[source + it + 1]; } else { for < move_size-1..0 - db.tasks[target + it + 1] = db.tasks[target + it]; + tasks[target + it + 1] = tasks[target + it]; } - db.tasks[target] = temp_task; + tasks[target] = temp_task; // Adjust active and selected tasks. - if (db.active_idx == source) { - db.active_idx = target; + if (active_idx == source) { + active_idx = target; } - else if (source < db.active_idx && db.active_idx <= target) { - db.active_idx -= 1; + else if (source < active_idx && active_idx <= target) { + active_idx -= 1; } - else if (target <= db.active_idx && db.active_idx < source) { - db.active_idx += 1; + else if (target <= active_idx && active_idx < source) { + active_idx += 1; } - db.selected_idx = target; + selected_idx = target; } // Find similar task and return it's index, or -1 if not found. @@ -506,7 +503,7 @@ add_task_time :: (db: *Database, index: s64, day: int, time: s64) { } // Adds the time on the day and task provided (and adjusts database totals). -add_task_times :: (db: *Database, index: s64, times: [7] s64) { +add_task_times :: (db: *Database, index: s64, times: [NUM_WEEK_DAYS] s64) { assert(db != null, ASSERT_NOT_NULL, "db"); assert(is_valid_index(db, index), ASSERT_INVALID_INDEX, index); @@ -900,35 +897,36 @@ update_layout :: () { } } +// Pagination based on currently selected task (show page where selected task is). +// Display up to rows allowed by the layout, or less if reached end of database. +get_visible_tasks_indices :: (db: Database) -> first_visible_index: int, last_visible_index: int { + first_visible_index := + (db.selected_idx / layout_tasks_rows) * layout_tasks_rows; + + last_visible_index := + first_visible_index + + (ifx layout_tasks_rows > db.tasks.count - first_visible_index + then db.tasks.count - first_visible_index + else layout_tasks_rows); + + return first_visible_index, last_visible_index; +} + +get_day_index_from_layout_index :: inline (layout_index: int) -> int { + return (layout_index + first_day_of_week) % NUM_WEEK_DAYS; +} + +// Convert indices to allow using different days as the first-day-of-the-week. +get_layout_index_from_day_index :: inline (day_index: int) -> int { + return (day_index - first_day_of_week + NUM_WEEK_DAYS) % NUM_WEEK_DAYS; +} + dbg_average := 0; // DEBUG dbg_count := 0; // DEBUG buffer: String_Builder; // TODO draw_user_interface :: (db: *Database, layout: *Layout, redraw_all: bool = true) { - // Pagination based on currently selected task (show page where selected task is). - // Display up to rows allowed by the layout, or less if reached end of database. - get_visible_tasks_indices :: (db: Database) -> first_visible_index: int, last_visible_index: int { - first_visible_index := - (db.selected_idx / layout_tasks_rows) * layout_tasks_rows; - - last_visible_index := - first_visible_index + - (ifx layout_tasks_rows > db.tasks.count - first_visible_index - then db.tasks.count - first_visible_index - else layout_tasks_rows); - - return first_visible_index, last_visible_index; - } - - get_day_index_from_layout_index :: inline (layout_index: int) -> int { - return (layout_index + FIRST_DAY_OF_WEEK) % 7; - } - - // Convert indices to allow using different days as the first-day-of-the-week. - get_layout_index_from_day_index :: inline (day_index: int) -> int { - return (day_index - FIRST_DAY_OF_WEEK + 7) % 7; - } - + auto_release_temp(); @@ -1119,7 +1117,7 @@ draw_user_interface :: (db: *Database, layout: *Layout, redraw_all: bool = true) total_time = 0; for 0..NUM_WEEK_DAYS-1 { x += 1; - day_idx := (it + FIRST_DAY_OF_WEEK) % NUM_WEEK_DAYS; + day_idx := get_day_index_from_layout_index(it); column_width = layout.columns[L_DAYS_IDX + day_idx].width; task_time := task.times[day_idx]; total_time = add(total_time, task_time); @@ -1188,15 +1186,10 @@ free_memory :: () { free(ar_file_path); } -read_input_string :: (x: int, y: int, input_limit: int, padding: int = 0) -> value: string, success: bool { - - // TODO Draw padding (at end of inputbox)... padding was renamed to input_width... is this the best name? - // TODO Maybe add another optional arg with the placeholder text (to be preset on the input)? - // TODO COULD CACHE... but there's not need... - +read_input_string :: (x: int, y: int, input_limit: int, input_width: int = 0) -> value: string, success: bool { TUI.set_cursor_position(x + input_limit, y); write_string(TUI.Commands.DrawingMode); - for 1..padding { + for 1..input_width { write_string(TUI.Drawings.Checkerboard); } write_string(TUI.Commands.TextMode); @@ -1208,7 +1201,6 @@ read_input_string :: (x: int, y: int, input_limit: int, padding: int = 0) -> val value, key := TUI.read_input_line(input_limit); return value, key == TUI.Keys.Enter; - } // Returns success. @@ -1312,6 +1304,7 @@ main :: () { "Usage: ttt [OPTION]... [FILE]...\n", " -i, --import-csv [FILE] Import CSV file to database (discard first row).\n", " -e, --export-csv [FILE] Export database to CSV file.\n", + " -s, --start-of-week [NUMBER] Set first day of week (0 = Sunday, 1 = Monday ...).\n", " -n, --no-autosave Disable autosave feature (only save on exit).\n", " -h, --help Display this help and exit.\n", " -v, --version Output version information and exit.\n", @@ -1411,6 +1404,16 @@ main :: () { is_exit_requested = true; continue; } + + if is_equal_to_any(args[it], "--start-of-week", "-s") { + it += 1; + if it >= args.count { + print_error("Missing number for starting day of week."); + exit(1); + } + first_day_of_week = parse_int(*args[it]); + continue; + } if is_equal_to_any(args[it], "--no-autosave", "-n") { is_autosave_enabled = false; @@ -1422,8 +1425,7 @@ main :: () { } if is_exit_requested { - // exit(0); // TODO fucking exit does not report memory leaks. - return; + exit(0); } } @@ -1649,7 +1651,7 @@ TUI.tui_print("Average % us (% / % : % bytes) ---------", dbg_average/1000, cont // Apply changes. time := cast(s64)input_time; - day := (selected_day + FIRST_DAY_OF_WEEK) % NUM_WEEK_DAYS; + day := get_day_index_from_layout_index(selected_day); if is_assign set_task_time(db, db.selected_idx, day, time); else add_task_time(db, db.selected_idx, day, time); @@ -1765,7 +1767,6 @@ TUI.tui_print("Average % us (% / % : % bytes) ---------", dbg_average/1000, cont // Sort by. case #char "s"; #through; case #char "S"; - // TODO The initial part should only decide what's the sorting procedure... then we would would all in a single place. TUI.using_style(action_style); sort_by := prompt_user_key(selected_task_row, "Sort by (n) name, (1..7) day, or (t) total time."); show_processing(); @@ -1789,8 +1790,8 @@ TUI.tui_print("Average % us (% / % : % bytes) ---------", dbg_average/1000, cont case #char "5"; #through; case #char "6"; #through; case #char "7"; - sort_by_idx := sort_by - #char "1"; - day := (sort_by_idx + FIRST_DAY_OF_WEEK) % NUM_WEEK_DAYS; + sort_by_idx := cast(int)(sort_by - #char "1"); + day := get_day_index_from_layout_index(sort_by_idx); if day == { case 0; sort_procedure = (x, y) => x.times[0] - y.times[0]; case 1; sort_procedure = (x, y) => x.times[1] - y.times[1]; |
