#include "base_context_cracking.h" #include "base_core.h" #include #include #include "math.h" #include "sourcecodepro.h" #include "third_party/raylib/src/raylib.h" #define TRUE 1 #define FALSE 0 typedef struct { Vector2 mouse_pos; Font font; } global_state; global_state state; // U64 millis() // { // struct timespec ts; // timespec_get(&ts, TIME_UTC); // U64 ms = (U64)ts.tv_sec * 1000 + ts.tv_nsec / 1000000; // return ms; // } U64 now() { return (U64)time(NULL); } #if 0 char my_button(int x, int y, int width, int height, int font_size, char *title) { char button_pressed = 0; Vector2 font_dimensions = MeasureTextEx(state.font, title, (float)font_size, 2); int padding = 10; Rectangle rect = { x, y, font_dimensions.x + (padding * 2), font_dimensions.y }; Color background_color = LIGHTGRAY; if(CheckCollisionPointRec(state.mouse_pos, rect)) { background_color = GRAY; if(IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) button_pressed = 1; } DrawRectangleRounded(rect, 0.7f, 96, background_color); DrawTextEx(state.font, title, (Vector2){ x + padding, y }, font_size, 2, BLUE); return button_pressed; } #endif char activity_button(int x, int y, int width, int height, char *title, char *subtitle, F32 font_size, Color color) { char button_pressed = 0; F32 subtitle_font_size = font_size - 8.0f; if(subtitle_font_size <= 0.0f) subtitle_font_size = font_size; Vector2 title_font_d = MeasureTextEx(state.font, title, (float)font_size, 2); Vector2 subtitle_font_d = MeasureTextEx(state.font, subtitle, (float)subtitle_font_size, 2); Rectangle rect = { x, y, width, height }; if(CheckCollisionPointRec(state.mouse_pos, rect)) { if(IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) button_pressed = 1; } DrawRectangleRounded(rect, 0.2f, 100, color); DrawTextEx(state.font, title, (Vector2){ (rect.x + rect.width / 2.0f - title_font_d.x / 2.0f), (rect.y + rect.height / 2.0f - title_font_d.y / 2.0f) }, font_size, 2, BLACK); DrawTextEx(state.font, subtitle, (Vector2){ (rect.x + rect.width / 2.0f - subtitle_font_d.x / 2.0f), (rect.y + rect.height / 2.0f - subtitle_font_d.y / 2.0f) + 20.0f }, subtitle_font_size, 2, BLACK); // WARNING: Substracting from font size like that is unsafe. return button_pressed; } // sleep, exercise, studying, gaming, // entertainment, reading, socializing, // housework, journaling, programmming (or projects?), // break, other enum activity_type { other, work, projects, gaming, exercise, activity_type_COUNT }; typedef struct Activity { enum activity_type activity; // TODO: Rename to kind or type. Color color; U64 began; U64 ended; } Activity; typedef struct Activity_Stat { U64 total_seconds; char seconds_str[24]; } Activity_Stat; typedef struct Hours { U64 hours; U64 minutes; U64 seconds; } Hours; Hours break_time(U64 seconds) { Hours hours; hours.hours = seconds / 60 / 60; hours.minutes = seconds / 60 - (60 * hours.hours); hours.seconds = seconds - ((hours.hours * 60 * 60) + (hours.minutes * 60)); return hours; } int main(int argc, char *argv[]) { U64 secs = now(); struct tm *t = localtime((time_t *)(&secs)); t->tm_hour = 0; t->tm_min = 0; t->tm_sec = 0; time_t ts = mktime(t); if(ts == (time_t)-1) { fprintf(stderr, "mktime failed.\n"); return 1; } U64 lower_bound_s = (U64)ts; U64 upper_bound_s = lower_bound_s + 86400; // U64 upper_bound_s = lower_bound_s + 3600; Activity activities[100]; U32 current_activity = 0; Activity_Stat activities_stats[activity_type_COUNT]; memset(activities_stats, 0, sizeof(activities_stats)); S32 window_w = 800; S32 window_h = 450; InitWindow(window_w, window_h, "Time Tracker"); SetWindowState(FLAG_MSAA_4X_HINT | FLAG_WINDOW_RESIZABLE); SetTargetFPS(30); state.font = LoadFontFromMemory(".ttf", sourcecodepro_ttf, sourcecodepro_ttf_len, 96, NULL, 0); if(!IsFontValid(state.font)) { fprintf(stderr, "Unable to load font\n"); return 1; } GenTextureMipmaps(&state.font.texture); SetTextureFilter(state.font.texture, TEXTURE_FILTER_BILINEAR); activities[current_activity].activity = other; activities[current_activity].color = RED; activities[current_activity].began = now(); activities[current_activity].ended = lower_bound_s; int font_size = 30; // DisableEventWaiting(); // EnableEventWaiting(); while(!WindowShouldClose()) { U64 now_s = now(); // fprintf(stderr, "%lu ... %lu: %lu\n", lower_bound_s, upper_bound_s, now_s); window_w = GetScreenWidth(); window_h = GetScreenHeight(); state.mouse_pos = GetMousePosition(); if(IsKeyPressed(KEY_Q)) break; else if(IsKeyPressed(KEY_UP)) font_size += 2; else if(IsKeyPressed(KEY_DOWN)) font_size -= 2; activities[current_activity].ended = now_s; BeginDrawing(); ClearBackground(BLACK); F32 padding_x = 10.0f; F32 padding_y = 10.0f; DrawRectangle(0, 0, window_w, 40, GRAY); for(U32 i = 0; i <= current_activity; i++) { // if((activities[i].ended_on - started_on_ms) <= (ended_on_ms - started_on_ms)) { F32 start_x = floor((F32)(activities[i].began - lower_bound_s) / (F32)(upper_bound_s - lower_bound_s) * (F32)window_w); F32 end_x = floor(((F32)(activities[i].ended - lower_bound_s) / (F32)(upper_bound_s - lower_bound_s)) * window_w); // DrawRectangleRounded((Rectangle){ start_x, 0, end_x - start_x, 40}, 0.0f, 100, activities[i].color); DrawRectangle(start_x, 0, end_x - start_x, 40, activities[i].color); // } } // TODO: CLEAN UP. F32 width = (window_w-padding_x*6.0f) / 5.0f; for(U32 i = 0; i <= current_activity; i++) { activities_stats[activities[i].activity].total_seconds += activities[i].ended - activities[i].began; } Hours time = break_time(activities_stats[other].total_seconds); snprintf(activities_stats[other].seconds_str, sizeof(activities_stats[other].seconds_str), "%02lu:%02lu:%02lu", time.hours, time.minutes, time.seconds); if(activity_button(padding_x, 60, width, (window_h-70), "Other", activities_stats[other].seconds_str, font_size, RED)) { if(activities[current_activity].activity != other) { current_activity++; activities[current_activity].activity = other; activities[current_activity].color = RED; activities[current_activity].began = now_s; activities[current_activity].ended = now_s; } } time = break_time(activities_stats[work].total_seconds); snprintf(activities_stats[work].seconds_str, sizeof(activities_stats[work].seconds_str), "%02lu:%02lu:%02lu", time.hours, time.minutes, time.seconds); if(activity_button((padding_x*2)+(width*1), 60, width, (window_h-70), "Work", activities_stats[work].seconds_str, font_size, BLUE)) { if(activities[current_activity].activity != work) { current_activity++; activities[current_activity].activity = work; activities[current_activity].color = BLUE; activities[current_activity].began = now_s; activities[current_activity].ended = now_s; } } time = break_time(activities_stats[projects].total_seconds); snprintf(activities_stats[projects].seconds_str, sizeof(activities_stats[projects].seconds_str), "%02lu:%02lu:%02lu", time.hours, time.minutes, time.seconds); if(activity_button((padding_x*3)+(width*2), 60, width, (window_h-70), "Projects", activities_stats[projects].seconds_str, font_size, YELLOW)) { if(activities[current_activity].activity != projects) { printf("Activity PROJECTS\n"); current_activity++; activities[current_activity].activity = projects; activities[current_activity].color = YELLOW; activities[current_activity].began = now_s; activities[current_activity].ended = now_s; } } time = break_time(activities_stats[gaming].total_seconds); snprintf(activities_stats[gaming].seconds_str, sizeof(activities_stats[gaming].seconds_str), "%02lu:%02lu:%02lu", time.hours, time.minutes, time.seconds); if(activity_button((padding_x*4)+(width*3), 60, width, (window_h-70), "Gaming", activities_stats[gaming].seconds_str, font_size, GREEN)) { if(activities[current_activity].activity != gaming) { printf("Activity GAMING\n"); current_activity++; activities[current_activity].activity = gaming; activities[current_activity].color = GREEN; activities[current_activity].began = now_s; activities[current_activity].ended = now_s; } } time = break_time(activities_stats[exercise].total_seconds); snprintf(activities_stats[exercise].seconds_str, sizeof(activities_stats[exercise].seconds_str), "%02lu:%02lu:%02lu", time.hours, time.minutes, time.seconds); if(activity_button((padding_x*5)+(width*4), 60, width, (window_h-70), "Exercise", activities_stats[exercise].seconds_str, font_size, PURPLE)) { if(activities[current_activity].activity != exercise) { printf("Activity EXERCISE\n"); current_activity++; activities[current_activity].activity = exercise; activities[current_activity].color = PURPLE; activities[current_activity].began = now_s; activities[current_activity].ended = now_s; } } // DrawTextEx(state.font, "Hello, world! && How are you?", (Vector2){100, 400}, font_size, 2, BLUE); EndDrawing(); for(U32 i = 0; i <= current_activity; i++) { activities_stats[activities[i].activity].total_seconds = 0; } } CloseWindow(); return 0; }