diff --git a/save_pattern.hexpat b/save_pattern.hexpat new file mode 100644 index 0000000..fbf0de4 --- /dev/null +++ b/save_pattern.hexpat @@ -0,0 +1,22 @@ +struct Category { + float r,g,b,a; + char name[64]; +}; + +struct Categorized_Day { + s32 year; + s32 month; + s32 day; + s32 category; +}; + +struct Calendar { + u32 version; + u32 num_categories; + u32 num_categorized_days; + + Category categories[num_categories]; + Categorized_Day categorized_days[num_categorized_days]; +}; + +Calendar calendar @ 0; \ No newline at end of file diff --git a/src/main_linux.cpp b/src/main_linux.cpp index cfb78cc..8e04f61 100644 --- a/src/main_linux.cpp +++ b/src/main_linux.cpp @@ -349,6 +349,9 @@ static void FramePresent(ImGui_ImplVulkanH_Window* wd) wd->SemaphoreIndex = (wd->SemaphoreIndex + 1) % wd->SemaphoreCount; // Now we can use the next set of semaphores } +bool should_exit = false; +bool show_demo_window = false; + // Main code int main(int, char**) { @@ -443,7 +446,6 @@ int main(int, char**) //IM_ASSERT(font != nullptr); // Our state - bool show_demo_window = true; bool show_another_window = false; ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); diff --git a/src/main_win32.cpp b/src/main_win32.cpp index e0898e5..39868b7 100644 --- a/src/main_win32.cpp +++ b/src/main_win32.cpp @@ -29,6 +29,9 @@ void CreateRenderTarget(); void CleanupRenderTarget(); LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +bool should_exit = false; +bool show_demo_window = false; + // Main code int main(int, char**) { @@ -106,15 +109,13 @@ int main(int, char**) //IM_ASSERT(font != nullptr); // Our state - bool show_demo_window = true; bool show_another_window = false; ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); init(); // Main loop - bool done = false; - while (!done) + while (!should_exit) { // Poll and handle messages (inputs, window resize, etc.) // See the WndProc() function below for our to dispatch events to the Win32 backend. @@ -124,9 +125,9 @@ int main(int, char**) ::TranslateMessage(&msg); ::DispatchMessage(&msg); if (msg.message == WM_QUIT) - done = true; + should_exit = true; } - if (done) + if (should_exit) break; // Handle window being minimized or screen locked diff --git a/src/work-calendar.cpp b/src/work-calendar.cpp index a588e23..f088182 100644 --- a/src/work-calendar.cpp +++ b/src/work-calendar.cpp @@ -1,9 +1,14 @@ #include #include #include +#include +#include #include "inter.h" +extern bool should_exit; +extern bool show_demo_window; + //standard year int year = 2025; @@ -49,6 +54,8 @@ void init(){ year = get_current_year(); } +static char* savefile_path = "./calendar"; + static const char* month_names[] = {"Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"}; typedef struct Category { @@ -57,7 +64,7 @@ typedef struct Category { char name[64] = "New Category"; } Category; -static size_t num_categories = 0; +static uint32_t num_categories = 0; static Category categories[128]; static bool legend_visible = true; @@ -72,7 +79,7 @@ typedef struct Categorized_Day { } Categorized_Day; static int year_min_size = 1; -static size_t num_categorized_days = 0; +static uint32_t num_categorized_days = 0; static Categorized_Day categorized_days[365*50]; //Colors @@ -82,6 +89,58 @@ ImVec4 table_sunday_bg = ImVec4(0.0f, 0.0f, 0.0f, 0.2f); ImVec4 table_hover_color = ImVec4(0.0f, 0.3f, 0.6f, 0.2f); +void save(){ + uint32_t version = 1; + FILE *save_file = fopen(savefile_path, "wb"); + fwrite(&version, sizeof(version), 1, save_file); + fwrite(&num_categories, sizeof(num_categories), 1, save_file); + fwrite(&num_categorized_days, sizeof(num_categorized_days), 1, save_file); + + for (int i = 0; i < num_categories; i++) { + fwrite(&categories[i].color, sizeof(categories[i].color), 1, save_file); + fwrite(&categories[i].name, sizeof(categories[i].name), 1, save_file); + } + + for (int i = 0; i < num_categorized_days; i++) { + fwrite(&categorized_days[i].year, sizeof(categorized_days[i].year), 1, save_file); + fwrite(&categorized_days[i].month, sizeof(categorized_days[i].month), 1, save_file); + fwrite(&categorized_days[i].day, sizeof(categorized_days[i].day), 1, save_file); + fwrite(&categorized_days[i].category, sizeof(categorized_days[i].category), 1, save_file); + } + + fclose (save_file); +} + +void load(){ + FILE *save_file = fopen(savefile_path, "rb"); + uint32_t version = 0; + fread(&version, sizeof(version), 1, save_file); + if(version != 1) { + return; //TODO Popup warning + } + + fread(&num_categories, sizeof(num_categories), 1, save_file); + fread(&num_categorized_days, sizeof(num_categorized_days), 1, save_file); + + if(num_categories > IM_ARRAYSIZE(categories) || num_categorized_days > IM_ARRAYSIZE(categorized_days)){ + return; //TODO Popup warning + } + + for (int i = 0; i < num_categories; i++) { + fread(&categories[i].color, sizeof(categories[i].color), 1, save_file); + fread(&categories[i].name, sizeof(categories[i].name), 1, save_file); + } + + for (int i = 0; i < num_categorized_days; i++) { + fread(&categorized_days[i].year, sizeof(categorized_days[i].year), 1, save_file); + fread(&categorized_days[i].month, sizeof(categorized_days[i].month), 1, save_file); + fread(&categorized_days[i].day, sizeof(categorized_days[i].day), 1, save_file); + fread(&categorized_days[i].category, sizeof(categorized_days[i].category), 1, save_file); + } + + fclose (save_file); +} + void per_frame(){ ImGuiStyle &style = ImGui::GetStyle(); @@ -101,8 +160,29 @@ void per_frame(){ } ImGui::DockSpaceOverViewport(main_viewport_dock, ImGui::GetMainViewport(), ImGuiDockNodeFlags_NoTabBar); + ImGuiID close_popup = ImGui::GetID("Close"); + ImGuiID open_popup = ImGui::GetID("Open"); + ImGuiID save_popup = ImGui::GetID("Save"); + ImGuiID logout_popup = ImGui::GetID("Logout"); //TODO + ImGuiID about_popup = ImGui::GetID("About"); + if (ImGui::BeginMainMenuBar()) { if (ImGui::BeginMenu("Datei")) { + if (ImGui::MenuItem("Kalender öffnen", NULL)) { + //TODO popup + filepicker + load(); + } + if (ImGui::MenuItem("Kalender speichern", NULL)) { + save(); + } + + ImGui::Separator(); + ImGui::MenuItem("Abmelden", NULL); + + ImGui::Separator(); + if (ImGui::MenuItem("Beenden", NULL)) { + ImGui::OpenPopup(close_popup); + } ImGui::EndMenu(); } @@ -111,9 +191,36 @@ void per_frame(){ ImGui::EndMenu(); } + if (ImGui::BeginMenu("Hilfe")) { + ImGui::MenuItem("Demo", NULL, &show_demo_window); + ImGui::MenuItem("Wiki", NULL); + ImGui::Separator(); + ImGui::MenuItem("Über", NULL); + ImGui::EndMenu(); + } + ImGui::EndMainMenuBar(); } + ImVec2 center = ImGui::GetMainViewport()->GetCenter(); + ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f)); + if (ImGui::BeginPopupModal("Close", NULL, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_AlwaysAutoResize)) { + ImGui::Text("Möchten Sie wirklich beenden?"); + + ImGui::SetItemDefaultFocus(); + if (ImGui::Button("Ja", ImVec2(120, 0))) { + should_exit = true; + ImGui::CloseCurrentPopup(); + } + + ImGui::SameLine(); + if (ImGui::Button("Nein", ImVec2(120, 0))) { + ImGui::CloseCurrentPopup(); + } + + ImGui::EndPopup(); + } + if (ImGui::Begin("Work Calendar", 0)) { ImGui::PushStyleColor(ImGuiCol_TableHeaderBg, {0,0,0,0}); ImGui::PushStyleColor(ImGuiCol_HeaderHovered, {0,0,0,0}); @@ -133,6 +240,7 @@ void per_frame(){ ImGui::TableSetColumnIndex(1); if (ImGui::ArrowButton("##left", ImGuiDir_Left)) year--; + ImGui::TableSetColumnIndex(2); ImGui::TextAligned(0.5, -FLT_MIN, "%d", year);