From 234e05696596675789e31300e978f994f4b02589 Mon Sep 17 00:00:00 2001 From: Ammerhai Date: Sat, 21 Mar 2026 13:08:09 +0100 Subject: [PATCH] add Open, Save calendar functionality add path information to window title #9 --- src/main_win32.cpp | 83 ++++++++++++++++++++++++++++++++++++++++++- src/work-calendar.cpp | 45 ++++++++++++++++++----- 2 files changed, 118 insertions(+), 10 deletions(-) diff --git a/src/main_win32.cpp b/src/main_win32.cpp index 39868b7..6050c17 100644 --- a/src/main_win32.cpp +++ b/src/main_win32.cpp @@ -22,6 +22,8 @@ static bool g_SwapChainOccluded = false; static UINT g_ResizeWidth = 0, g_ResizeHeight = 0; static ID3D11RenderTargetView* g_mainRenderTargetView = nullptr; +static HWND hwnd; + // Forward declarations of helper functions bool CreateDeviceD3D(HWND hWnd); void CleanupDeviceD3D(); @@ -32,6 +34,85 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); bool should_exit = false; bool show_demo_window = false; +void set_window_title(const char *window_title){ + SetWindowTextA(hwnd, window_title); +} + +char *open_file_dialog() { + + uint32_t file_name_buffer_size = 4096; + void *file_name_buffer = calloc(1, file_name_buffer_size); + + OPENFILENAMEA open_info = { + .lStructSize = sizeof(OPENFILENAMEA), + .hwndOwner = hwnd, + .hInstance = NULL, + .lpstrFilter = "Workcalendar (.wcl)\0*.wcl\0\0", + .lpstrCustomFilter = NULL, + .nMaxCustFilter = 0, + .nFilterIndex = 0, + .lpstrFile = (char *) file_name_buffer, + .nMaxFile = file_name_buffer_size, + .lpstrFileTitle = NULL, + .nMaxFileTitle = NULL, + .lpstrInitialDir = NULL, + .lpstrTitle = "Kalender öffnen", + .Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_LONGNAMES , + .nFileOffset = 0, + .nFileExtension = 0, + .lpstrDefExt = "wcl", + .lCustData = NULL, + .lpfnHook = NULL, + .lpTemplateName = NULL, + }; + + if(!GetOpenFileNameA(&open_info)) { + free(file_name_buffer); + return NULL; + } + + return (char *) file_name_buffer; +} + +char *save_file_dialog() { + + uint32_t file_name_buffer_size = 4096; + void *file_name_buffer = calloc(1, file_name_buffer_size); + if (save_file_path) { + memcpy(file_name_buffer, save_file_path, strlen(save_file_path)); + } + + OPENFILENAMEA open_info = { + .lStructSize = sizeof(OPENFILENAMEA), + .hwndOwner = hwnd, + .hInstance = NULL, + .lpstrFilter = "Workcalendar (.wcl)\0*.wcl\0\0", + .lpstrCustomFilter = NULL, + .nMaxCustFilter = 0, + .nFilterIndex = 0, + .lpstrFile = (char *) file_name_buffer, + .nMaxFile = file_name_buffer_size, + .lpstrFileTitle = NULL, + .nMaxFileTitle = NULL, + .lpstrInitialDir = NULL, + .lpstrTitle = "Kalender speichern unter", + .Flags = OFN_LONGNAMES | OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST, + .nFileOffset = 0, + .nFileExtension = 0, + .lpstrDefExt = "wcl", + .lCustData = NULL, + .lpfnHook = NULL, + .lpTemplateName = NULL, + }; + + if(!GetSaveFileNameA(&open_info)) { + free(file_name_buffer); + return NULL; + } + + return (char *) file_name_buffer; +} + // Main code int main(int, char**) { @@ -42,7 +123,7 @@ int main(int, char**) // Create application window WNDCLASSEXW wc = { sizeof(wc), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(nullptr), nullptr, nullptr, nullptr, nullptr, L"ImGui Example", nullptr }; ::RegisterClassExW(&wc); - HWND hwnd = ::CreateWindowW(wc.lpszClassName, L"Work Calendar", WS_OVERLAPPEDWINDOW, 100, 100, (int)(1600 * main_scale), (int)(900 * main_scale), nullptr, nullptr, wc.hInstance, nullptr); + hwnd = ::CreateWindowW(wc.lpszClassName, L"Work Calendar", WS_OVERLAPPEDWINDOW, 100, 100, (int)(1600 * main_scale), (int)(900 * main_scale), nullptr, nullptr, wc.hInstance, nullptr); // Initialize Direct3D if (!CreateDeviceD3D(hwnd)) diff --git a/src/work-calendar.cpp b/src/work-calendar.cpp index 04caae3..7858885 100644 --- a/src/work-calendar.cpp +++ b/src/work-calendar.cpp @@ -22,6 +22,10 @@ static int current_day = 1; static ImFont *inter_regular; static ImFont *inter_bold; +char *open_file_dialog(); +char *save_file_dialog(); +void set_window_title(const char *title); + int get_current_year(){ time_t t = time(NULL); struct tm tm = *localtime(&t); @@ -69,7 +73,7 @@ void init(){ year = get_current_year(); } -static const char *savefile_path = "./calendar"; +static char *save_file_path = NULL; static const char *wiki_url = "https://gitea.ammerhai.com/Ammerhai/work-calendar/wiki"; static const char *month_names[] = {"Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"}; @@ -106,8 +110,10 @@ 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(){ + if(!save_file_path) return; + uint32_t version = 1; - FILE *save_file = fopen(savefile_path, "wb"); + FILE *save_file = fopen(save_file_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); @@ -128,7 +134,7 @@ void save(){ } void load(){ - FILE *save_file = fopen(savefile_path, "rb"); + FILE *save_file = fopen(save_file_path, "rb"); uint32_t version = 0; fread(&version, sizeof(version), 1, save_file); if(version != 1) { @@ -184,16 +190,37 @@ void per_frame(){ if (ImGui::BeginMainMenuBar()) { if (ImGui::BeginMenu("Datei")) { - if (ImGui::MenuItem("Kalender öffnen", NULL)) { - //TODO popup + filepicker - load(); + if (ImGui::MenuItem("Öffnen", "Ctrl + O")) { + char *new_save_file_path = open_file_dialog(); + if(new_save_file_path) { + if(save_file_path) free(save_file_path); + save_file_path = new_save_file_path; + load(); + + char *title = (char *)calloc(1, strlen("Work Calendar - ") + strlen(save_file_path) + 1); + memcpy(title, "Work Calendar - ", strlen("Work Calendar - ")); + memcpy(title + strlen("Work Calendar - "), save_file_path, strlen(save_file_path)); + + set_window_title(title); + free(title); + } } - if (ImGui::MenuItem("Kalender speichern", NULL)) { + if (ImGui::MenuItem("Speichern", "Ctrl + S", false, !!save_file_path)) { save(); } + if (ImGui::MenuItem("Speichern unter", "Ctrl + Shift + S")) { + char *new_save_file_path = save_file_dialog(); + if(new_save_file_path) { + if(save_file_path) free(save_file_path); + save_file_path = new_save_file_path; + save(); + } + } + + //TODO ImGui::Separator(); - ImGui::MenuItem("Abmelden", NULL); + ImGui::MenuItem("Kalender Schließen", "Ctrl + X"); ImGui::Separator(); if (ImGui::MenuItem("Beenden", NULL)) { @@ -213,7 +240,7 @@ void per_frame(){ ImGui::GetPlatformIO().Platform_OpenInShellFn(ImGui::GetCurrentContext(), wiki_url); } ImGui::Separator(); - ImGui::MenuItem("Über", NULL); + ImGui::MenuItem("Über", NULL); //TODO ImGui::EndMenu(); }