From 178e8c135a60e9f206dcfbad8bab7bb868e6a294 Mon Sep 17 00:00:00 2001 From: Aldrik Ramaekers Date: Fri, 26 Dec 2025 09:41:24 +0100 Subject: linux port --- libs/ImGuiDatePicker/ImGuiDatePicker.cpp | 5 + libs/xml.c/src/xml.c | 20 +- libs/xml.c/src/xml.h | 1 + libs/zip/src/miniz.h | 6 +- run.bat | 55 ------ run_linux64.sh | 55 ++++++ run_win64.bat | 55 ++++++ src/main.cpp | 315 ------------------------------ src/main_linux.cpp | 142 ++++++++++++++ src/main_windows.cpp | 319 +++++++++++++++++++++++++++++++ src/ui/ui_tax.cpp | 2 +- 11 files changed, 594 insertions(+), 381 deletions(-) delete mode 100644 run.bat create mode 100755 run_linux64.sh create mode 100644 run_win64.bat delete mode 100644 src/main.cpp create mode 100644 src/main_linux.cpp create mode 100644 src/main_windows.cpp diff --git a/libs/ImGuiDatePicker/ImGuiDatePicker.cpp b/libs/ImGuiDatePicker/ImGuiDatePicker.cpp index 207a902..c69c8ba 100644 --- a/libs/ImGuiDatePicker/ImGuiDatePicker.cpp +++ b/libs/ImGuiDatePicker/ImGuiDatePicker.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #define GET_DAY(timePoint) int(timePoint.tm_mday) @@ -152,7 +153,11 @@ namespace ImGui std::time_t currentTime = std::chrono::system_clock::to_time_t(now); tm res; + #ifdef win64 gmtime_s(&res, ¤tTime); + #else + gmtime_r(¤tTime, &res); + #endif return res; } diff --git a/libs/xml.c/src/xml.c b/libs/xml.c/src/xml.c index 6d14213..0b435cd 100644 --- a/libs/xml.c/src/xml.c +++ b/libs/xml.c/src/xml.c @@ -320,11 +320,11 @@ static void xml_parser_error(struct xml_parser* parser, enum xml_parser_offset o int row = 0; int column = 0; - //#define min(X,Y) ((X) < (Y) ? (X) : (Y)) - //#define max(X,Y) ((X) > (Y) ? (X) : (Y)) + #define min(X,Y) ((X) < (Y) ? (X) : (Y)) + #define max(X,Y) ((X) > (Y) ? (X) : (Y)) size_t character = max(0, min(parser->length, parser->position + offset)); - //#undef min - //#undef max + #undef min + #undef max size_t position = 0; for (; position < character; ++position) { column++; @@ -1140,9 +1140,9 @@ void xml_string_copy(struct xml_string* string, uint8_t* buffer, size_t length) return; } - //#define min(X,Y) ((X) < (Y) ? (X) : (Y)) + #define min(X,Y) ((X) < (Y) ? (X) : (Y)) length = min(length, string->length); - //#undef min + #undef min memcpy(buffer, string->buffer, length); } @@ -1328,5 +1328,11 @@ time_t xml_get_date_x(struct xml_node* root, char* child_name, ...) time_t result = mktime(&tm_info); if (result == -1) return 0; - else return result - _timezone; + else { + #ifdef win64 + return result - _timezone; + #else + return result - timezone; + #endif + } } \ No newline at end of file diff --git a/libs/xml.c/src/xml.h b/libs/xml.c/src/xml.h index ef8d55c..43e7f0f 100644 --- a/libs/xml.c/src/xml.h +++ b/libs/xml.c/src/xml.h @@ -31,6 +31,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { diff --git a/libs/zip/src/miniz.h b/libs/zip/src/miniz.h index b3c3237..ac7f4d3 100644 --- a/libs/zip/src/miniz.h +++ b/libs/zip/src/miniz.h @@ -1,8 +1,8 @@ #ifndef MINIZ_EXPORT #define MINIZ_EXPORT -__pragma(warning(push)) -__pragma(warning(disable:4127)) +//__pragma(warning(push)) +//__pragma(warning(disable:4127)) #endif /* miniz.c 3.0.2 - public domain deflate/inflate, zlib-subset, ZIP @@ -10204,7 +10204,7 @@ mz_bool mz_zip_end(mz_zip_archive *pZip) { return MZ_FALSE; } -__pragma(warning(pop)) +//__pragma(warning(pop)) #ifdef __cplusplus } diff --git a/run.bat b/run.bat deleted file mode 100644 index 1f13fcc..0000000 --- a/run.bat +++ /dev/null @@ -1,55 +0,0 @@ -@echo off - -if "%1"=="docs" ( - cd manual - doxygen.exe - cd .. - .\build\manual\latex\make.bat - MOVE build\manual\latex\refman.pdf manual\OpenBooks_Manual.pdf - exit -) - -REM Find the latest Visual Studio installation path -for /f "usebackq tokens=*" %%i in (`"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -latest -products * -property installationPath`) do ( - set VSPath=%%i -) -if not defined VSPath ( - echo Visual Studio not found. - exit /b 1 -) - -set VCVARSALL=%VSPath%\VC\Auxiliary\Build\vcvarsall.bat -if not exist "%VCVARSALL%" ( - echo vcvarsall.bat not found at "%VCVARSALL%" - exit /b 1 -) - -for /f "delims=" %%i in ('git rev-parse --short HEAD') do set COMMIT_ID=%%i - -call "%VCVARSALL%" x64 -@set OUT_DIR=build\\ -@set OUT_EXE=accounting -set LIB_SOURCES=libs\imgui-1.92.1\backends\imgui_impl_dx11.cpp^ - libs\imgui-1.92.1\backends\imgui_impl_win32.cpp^ - libs\imgui-1.92.1\imgui*.cpp^ - libs\simclist-1.5\simclist.c^ - libs\ImGuiDatePicker\*.cpp^ - libs\zip\src\*.c^ - libs\xml.c\src\*.c^ - libs\timer_lib\*.c^ - libs\tinyfiledialogs\tinyfiledialogs.c -@set SOURCES= src\*.cpp src\ui\*.cpp src\locales\*.cpp src\ai_providers\*.cpp -@set LIBS=opengl32.lib Advapi32.lib Shell32.lib Ole32.lib User32.lib Pathcch.lib D3D11.lib Comdlg32.lib Kernel32.lib /LIBPATH:"libs/openssl-3.6.0-beta1/x64/lib" libssl.lib libcrypto.lib -@set FLAGS=/nologo /Ob0 /MD /Oy- /Zi /FS /W4 /EHsc /utf-8 /F16000000 -@set INCLUDE_DIRS=/I"libs/imgui-1.92.1" /I"libs/imgui-1.92.1/backends" /I"/" /I"libs/openssl-3.6.0-beta1/x64/include" /I"libs/cpp-httplib" /I"libs/timer_lib" /I"libs/greatest" /I"libs/simclist-1.5" /I"libs/tinyfiledialogs" /I"libs/zip/src" /I"libs/xml.c/src" /I"libs/" /Iinclude -@set DEFINITIONS=/D_PLATFORM_=\"win64\" /D_CRT_SECURE_NO_WARNINGS - -if "%1"=="-t" @set SOURCES= tests\main.cpp src\administration.cpp src\administration_writer.cpp src\administration_reader.cpp src\strops.cpp src\logger.cpp src\locales.cpp src\locales\*.cpp src\ai_providers\*.cpp src\importer.cpp src\memops.cpp src\countries.cpp -if "%1"=="-t" @set OUT_EXE=accounting_tests -if "%1"=="-t" @set DEFINITIONS=/D_PLATFORM_=\"win64\" /D_CRT_SECURE_NO_WARNINGS /D_TESTING_MODE_ - -cl %FLAGS% %INCLUDE_DIRS% %DEFINITIONS% %SOURCES% %LIB_SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fd%OUT_DIR%/vc140.pdb /Fo%OUT_DIR%/ /link %LIBS% -if "%1"=="-r" call "%OUT_DIR%/%OUT_EXE%.exe" C:\Users\aldri\Desktop\Vault\Projects\accounting\build\example.openbook -if "%1"=="-t" call "%OUT_DIR%/%OUT_EXE%.exe" -v -if "%1"=="-d" call devenv "%OUT_DIR%/%OUT_EXE%.exe" -if "%1"=="-l" call drmemory.exe -leaks_only -brief -batch -- "%OUT_DIR%/%OUT_EXE%.exe" C:\Users\aldri\Desktop\Vault\Projects\accounting\build\example.openbook \ No newline at end of file diff --git a/run_linux64.sh b/run_linux64.sh new file mode 100755 index 0000000..719e1d7 --- /dev/null +++ b/run_linux64.sh @@ -0,0 +1,55 @@ +#!/bin/bash + +# Function to print errors and exit +function error_exit { + echo "$1" + exit 1 +} + +# Set environment variables +OUT_DIR="build" +OUT_EXE="accounting" +LIB_SOURCES="libs/imgui-1.92.1/backends/imgui_impl_glfw.cpp \ +libs/imgui-1.92.1/backends/imgui_impl_opengl2.cpp \ +libs/imgui-1.92.1/imgui*.cpp \ +libs/simclist-1.5/simclist.c \ +libs/ImGuiDatePicker/*.cpp \ +libs/zip/src/*.c \ +libs/xml.c/src/*.c \ +libs/timer_lib/*.c \ +libs/tinyfiledialogs/tinyfiledialogs.c" +SOURCES="src/*.cpp src/ui/*.cpp src/locales/*.cpp src/ai_providers/*.cpp" +LIBS="-lstdc++ -lglfw -lGL -lm -lssl -lcrypto" +FLAGS="--no-warnings -g" +INCLUDE_DIRS="-Ilibs/imgui-1.92.1 \ +-Ilibs/imgui-1.92.1/backends \ +-Ilibs/openssl-3.6.0-beta1/x64/include \ +-Ilibs/cpp-httplib \ +-Ilibs/timer_lib \ +-Ilibs/greatest \ +-Ilibs/simclist-1.5 \ +-Ilibs/tinyfiledialogs \ +-Ilibs/zip/src \ +-Ilibs/xml.c/src \ +-Ilibs/ \ +-Iinclude" +DEFINITIONS="-D_PLATFORM_=\"linux64\"" + +# Check for test flag +if [ "$1" == "-t" ]; then + SOURCES="tests/main_linux.cpp src/administration.cpp src/administration_writer.cpp src/administration_reader.cpp src/strops.cpp src/logger.cpp src/locales.cpp src/locales/*.cpp src/ai_providers/*.cpp src/importer.cpp src/memops.cpp src/countries.cpp" + OUT_EXE="accounting_tests" + DEFINITIONS="-D_PLATFORM_=\"linux64\" -D_TESTING_MODE_" +fi + +# Compilation command +gcc $FLAGS $INCLUDE_DIRS $DEFINITIONS $SOURCES $LIB_SOURCES -o $OUT_DIR/$OUT_EXE $LIBS + +# Run commands based on input arguments +if [ "$1" == "-r" ]; then + "$OUT_DIR/$OUT_EXE" "/path/to/example.openbook" +elif [ "$1" == "-t" ]; then + "$OUT_DIR/$OUT_EXE" -v +elif [ "$1" == "-d" ]; then + gdb "$OUT_DIR/$OUT_EXE" +fi \ No newline at end of file diff --git a/run_win64.bat b/run_win64.bat new file mode 100644 index 0000000..1f13fcc --- /dev/null +++ b/run_win64.bat @@ -0,0 +1,55 @@ +@echo off + +if "%1"=="docs" ( + cd manual + doxygen.exe + cd .. + .\build\manual\latex\make.bat + MOVE build\manual\latex\refman.pdf manual\OpenBooks_Manual.pdf + exit +) + +REM Find the latest Visual Studio installation path +for /f "usebackq tokens=*" %%i in (`"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -latest -products * -property installationPath`) do ( + set VSPath=%%i +) +if not defined VSPath ( + echo Visual Studio not found. + exit /b 1 +) + +set VCVARSALL=%VSPath%\VC\Auxiliary\Build\vcvarsall.bat +if not exist "%VCVARSALL%" ( + echo vcvarsall.bat not found at "%VCVARSALL%" + exit /b 1 +) + +for /f "delims=" %%i in ('git rev-parse --short HEAD') do set COMMIT_ID=%%i + +call "%VCVARSALL%" x64 +@set OUT_DIR=build\\ +@set OUT_EXE=accounting +set LIB_SOURCES=libs\imgui-1.92.1\backends\imgui_impl_dx11.cpp^ + libs\imgui-1.92.1\backends\imgui_impl_win32.cpp^ + libs\imgui-1.92.1\imgui*.cpp^ + libs\simclist-1.5\simclist.c^ + libs\ImGuiDatePicker\*.cpp^ + libs\zip\src\*.c^ + libs\xml.c\src\*.c^ + libs\timer_lib\*.c^ + libs\tinyfiledialogs\tinyfiledialogs.c +@set SOURCES= src\*.cpp src\ui\*.cpp src\locales\*.cpp src\ai_providers\*.cpp +@set LIBS=opengl32.lib Advapi32.lib Shell32.lib Ole32.lib User32.lib Pathcch.lib D3D11.lib Comdlg32.lib Kernel32.lib /LIBPATH:"libs/openssl-3.6.0-beta1/x64/lib" libssl.lib libcrypto.lib +@set FLAGS=/nologo /Ob0 /MD /Oy- /Zi /FS /W4 /EHsc /utf-8 /F16000000 +@set INCLUDE_DIRS=/I"libs/imgui-1.92.1" /I"libs/imgui-1.92.1/backends" /I"/" /I"libs/openssl-3.6.0-beta1/x64/include" /I"libs/cpp-httplib" /I"libs/timer_lib" /I"libs/greatest" /I"libs/simclist-1.5" /I"libs/tinyfiledialogs" /I"libs/zip/src" /I"libs/xml.c/src" /I"libs/" /Iinclude +@set DEFINITIONS=/D_PLATFORM_=\"win64\" /D_CRT_SECURE_NO_WARNINGS + +if "%1"=="-t" @set SOURCES= tests\main.cpp src\administration.cpp src\administration_writer.cpp src\administration_reader.cpp src\strops.cpp src\logger.cpp src\locales.cpp src\locales\*.cpp src\ai_providers\*.cpp src\importer.cpp src\memops.cpp src\countries.cpp +if "%1"=="-t" @set OUT_EXE=accounting_tests +if "%1"=="-t" @set DEFINITIONS=/D_PLATFORM_=\"win64\" /D_CRT_SECURE_NO_WARNINGS /D_TESTING_MODE_ + +cl %FLAGS% %INCLUDE_DIRS% %DEFINITIONS% %SOURCES% %LIB_SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fd%OUT_DIR%/vc140.pdb /Fo%OUT_DIR%/ /link %LIBS% +if "%1"=="-r" call "%OUT_DIR%/%OUT_EXE%.exe" C:\Users\aldri\Desktop\Vault\Projects\accounting\build\example.openbook +if "%1"=="-t" call "%OUT_DIR%/%OUT_EXE%.exe" -v +if "%1"=="-d" call devenv "%OUT_DIR%/%OUT_EXE%.exe" +if "%1"=="-l" call drmemory.exe -leaks_only -brief -batch -- "%OUT_DIR%/%OUT_EXE%.exe" C:\Users\aldri\Desktop\Vault\Projects\accounting\build\example.openbook \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp deleted file mode 100644 index ffdeb03..0000000 --- a/src/main.cpp +++ /dev/null @@ -1,315 +0,0 @@ -/* -* Copyright (c) 2025 Aldrik Ramaekers -* -* Permission to use, copy, modify, and/or distribute this software for any -* purpose with or without fee is hereby granted, provided that the above -* copyright notice and this permission notice appear in all copies. -* -* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -*/ - -#include "imgui.h" -#include "imgui_impl_win32.h" -#include "imgui_impl_dx11.h" -#include -#include -#include "timer.h" -#include "ui.hpp" -#include "administration.hpp" -#include "administration_writer.hpp" -#include "administration_reader.hpp" - -// Data -static HWND hwnd; -static ID3D11Device* g_pd3dDevice = nullptr; -static ID3D11DeviceContext* g_pd3dDeviceContext = nullptr; -static IDXGISwapChain* g_pSwapChain = nullptr; -static bool g_SwapChainOccluded = false; -static UINT g_ResizeWidth = 0, g_ResizeHeight = 0; -static ID3D11RenderTargetView* g_mainRenderTargetView = nullptr; - -// Forward declarations of helper functions -bool CreateDeviceD3D(HWND hWnd); -void CleanupDeviceD3D(); -void CreateRenderTarget(); -void CleanupRenderTarget(); -LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); - -void platorm_maximize_window() -{ - LONG style = GetWindowLong(hwnd, GWL_STYLE); - - // allow resizing + maximize - style |= (WS_THICKFRAME | WS_MAXIMIZEBOX); - - SetWindowLong(hwnd, GWL_STYLE, style); - - // Apply style changes - SetWindowPos(hwnd, NULL, 0, 0, 0, 0, - SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); - - ShowWindow(hwnd, SW_MAXIMIZE); -} - -// Main code -//int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) -int main(int argc, char** argv) -{ - int start_width = 1280; - int start_height = 800; - - // Make process DPI aware and obtain main monitor scale - ImGui_ImplWin32_EnableDpiAwareness(); - float main_scale = ImGui_ImplWin32_GetDpiScaleForMonitor(::MonitorFromPoint(POINT{ 0, 0 }, MONITOR_DEFAULTTOPRIMARY)); - - // Create application window - WNDCLASSEXW wc = { sizeof(wc), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(nullptr), nullptr, nullptr, nullptr, nullptr, L"ImGui Example", nullptr }; - ::RegisterClassExW(&wc); - - // Get screen size - int screenW = GetSystemMetrics(SM_CXSCREEN); - int screenH = GetSystemMetrics(SM_CYSCREEN); - - // Calculate top-left so window is centered - int x = (screenW - start_width) / 2; - int y = (screenH - start_height) / 2; - - hwnd = ::CreateWindowW(wc.lpszClassName, L"OpenBooks", WS_OVERLAPPEDWINDOW, - x, y, (int)(start_width * main_scale), (int)(start_height * main_scale), nullptr, nullptr, wc.hInstance, nullptr); - - // Initialize Direct3D - if (!CreateDeviceD3D(hwnd)) - { - CleanupDeviceD3D(); - ::UnregisterClassW(wc.lpszClassName, wc.hInstance); - return 1; - } - - // Show the window - ::ShowWindow(hwnd, SW_SHOWDEFAULT); - ::UpdateWindow(hwnd); - - // Setup Dear ImGui context - IMGUI_CHECKVERSION(); - ImGui::CreateContext(); - ImGuiIO& io = ImGui::GetIO(); - io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls - io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls - io.IniFilename = NULL; - io.LogFilename = NULL; - - // Setup Dear ImGui style - ImGui::StyleColorsDark(); - //ImGui::StyleColorsLight(); - - // Setup scaling - ImGuiStyle& style = ImGui::GetStyle(); - style.ScaleAllSizes(main_scale); // Bake a fixed style scale. (until we have a solution for dynamic style scaling, changing this requires resetting Style + calling this again) - style.FontScaleDpi = main_scale; // Set initial font scale. (using io.ConfigDpiScaleFonts=true makes this unnecessary. We leave both here for documentation purpose) - - // Setup Platform/Renderer backends - ImGui_ImplWin32_Init(hwnd); - ImGui_ImplDX11_Init(g_pd3dDevice, g_pd3dDeviceContext); - - // Load Fonts - // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. - // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. - // - If the file cannot be loaded, the function will return a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit). - // - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering. - // - Read 'docs/FONTS.md' for more instructions and details. - // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ ! - style.FontSizeBase = 18.0f; - //io.Fonts->AddFontDefault(); - io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf"); - //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\seguisym.ttf"); - ui::fontBold = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeuib.ttf"); - ui::fontBig = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeuib.ttf", 30); - //io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf"); - //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf"); - //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf"); - //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf"); - //IM_ASSERT(font != nullptr); - - ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); - - timer_lib_initialize(); - administration_writer::create(); - - if (argc < 2) { - administration::create_default(""); - } - else { - administration_reader::open_existing(argv[1]); - } - - // Main loop - bool done = false; - while (!done) - { - // Poll and handle messages (inputs, window resize, etc.) - // See the WndProc() function below for our to dispatch events to the Win32 backend. - MSG msg; - while (::PeekMessage(&msg, nullptr, 0U, 0U, PM_REMOVE)) - { - ::TranslateMessage(&msg); - ::DispatchMessage(&msg); - if (msg.message == WM_QUIT) - done = true; - } - if (done) - break; - - // Handle window being minimized or screen locked - if (g_SwapChainOccluded && g_pSwapChain->Present(0, DXGI_PRESENT_TEST) == DXGI_STATUS_OCCLUDED) - { - ::Sleep(10); - continue; - } - g_SwapChainOccluded = false; - - // Handle window resize (we don't resize directly in the WM_SIZE handler) - if (g_ResizeWidth != 0 && g_ResizeHeight != 0) - { - CleanupRenderTarget(); - g_pSwapChain->ResizeBuffers(0, g_ResizeWidth, g_ResizeHeight, DXGI_FORMAT_UNKNOWN, 0); - g_ResizeWidth = g_ResizeHeight = 0; - CreateRenderTarget(); - } - - // Start the Dear ImGui frame - ImGui_ImplDX11_NewFrame(); - ImGui_ImplWin32_NewFrame(); - ImGui::NewFrame(); - - ui::draw_main(); - - // Rendering - ImGui::Render(); - const float clear_color_with_alpha[4] = { clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w }; - g_pd3dDeviceContext->OMSetRenderTargets(1, &g_mainRenderTargetView, nullptr); - g_pd3dDeviceContext->ClearRenderTargetView(g_mainRenderTargetView, clear_color_with_alpha); - ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData()); - - // Present - HRESULT hr = g_pSwapChain->Present(1, 0); // Present with vsync - //HRESULT hr = g_pSwapChain->Present(0, 0); // Present without vsync - g_SwapChainOccluded = (hr == DXGI_STATUS_OCCLUDED); - } - - administration_writer::destroy(); - timer_lib_shutdown(); - administration::destroy(); - - // Cleanup - ImGui_ImplDX11_Shutdown(); - ImGui_ImplWin32_Shutdown(); - ImGui::DestroyContext(); - - CleanupDeviceD3D(); - ::DestroyWindow(hwnd); - ::UnregisterClassW(wc.lpszClassName, wc.hInstance); - - return 0; -} - -// Helper functions - -bool CreateDeviceD3D(HWND hWnd) -{ - // Setup swap chain - DXGI_SWAP_CHAIN_DESC sd; - ZeroMemory(&sd, sizeof(sd)); - sd.BufferCount = 2; - sd.BufferDesc.Width = 0; - sd.BufferDesc.Height = 0; - sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; - sd.BufferDesc.RefreshRate.Numerator = 60; - sd.BufferDesc.RefreshRate.Denominator = 1; - sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; - sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - sd.OutputWindow = hWnd; - sd.SampleDesc.Count = 1; - sd.SampleDesc.Quality = 0; - sd.Windowed = TRUE; - sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; - - UINT createDeviceFlags = 0; - //createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; - D3D_FEATURE_LEVEL featureLevel; - const D3D_FEATURE_LEVEL featureLevelArray[2] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_0, }; - HRESULT res = D3D11CreateDeviceAndSwapChain(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, createDeviceFlags, featureLevelArray, 2, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &featureLevel, &g_pd3dDeviceContext); - if (res == DXGI_ERROR_UNSUPPORTED) // Try high-performance WARP software driver if hardware is not available. - res = D3D11CreateDeviceAndSwapChain(nullptr, D3D_DRIVER_TYPE_WARP, nullptr, createDeviceFlags, featureLevelArray, 2, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &featureLevel, &g_pd3dDeviceContext); - if (res != S_OK) - return false; - - CreateRenderTarget(); - return true; -} - -void CleanupDeviceD3D() -{ - CleanupRenderTarget(); - if (g_pSwapChain) { g_pSwapChain->Release(); g_pSwapChain = nullptr; } - if (g_pd3dDeviceContext) { g_pd3dDeviceContext->Release(); g_pd3dDeviceContext = nullptr; } - if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = nullptr; } -} - -void CreateRenderTarget() -{ - ID3D11Texture2D* pBackBuffer; - g_pSwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer)); - g_pd3dDevice->CreateRenderTargetView(pBackBuffer, nullptr, &g_mainRenderTargetView); - pBackBuffer->Release(); -} - -void CleanupRenderTarget() -{ - if (g_mainRenderTargetView) { g_mainRenderTargetView->Release(); g_mainRenderTargetView = nullptr; } -} - -// Forward declare message handler from imgui_impl_win32.cpp -extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); - -// Win32 message handler -// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. -// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or clear/overwrite your copy of the mouse data. -// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or clear/overwrite your copy of the keyboard data. -// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. -LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) - return true; - - switch (msg) - { - case WM_GETMINMAXINFO: - { - MINMAXINFO* minMaxInfo = (MINMAXINFO*)lParam; - minMaxInfo->ptMinTrackSize.x = 1400; // Minimum width - minMaxInfo->ptMinTrackSize.y = 900; // Minimum height - return 0; - } - - case WM_SIZE: - if (wParam == SIZE_MINIMIZED) - return 0; - g_ResizeWidth = (UINT)LOWORD(lParam); // Queue resize - g_ResizeHeight = (UINT)HIWORD(lParam); - return 0; - case WM_SYSCOMMAND: - if ((wParam & 0xfff0) == SC_KEYMENU) // Disable ALT application menu - return 0; - break; - case WM_DESTROY: - ::PostQuitMessage(0); - return 0; - } - return ::DefWindowProcW(hWnd, msg, wParam, lParam); -} \ No newline at end of file diff --git a/src/main_linux.cpp b/src/main_linux.cpp new file mode 100644 index 0000000..f30f063 --- /dev/null +++ b/src/main_linux.cpp @@ -0,0 +1,142 @@ +// Dear ImGui: standalone example application for GLFW + OpenGL2, using legacy fixed pipeline +// (GLFW is a cross-platform general purpose library for handling windows, inputs, OpenGL/Vulkan/Metal graphics context creation, etc.) + +// Learn about Dear ImGui: +// - FAQ https://dearimgui.com/faq +// - Getting Started https://dearimgui.com/getting-started +// - Documentation https://dearimgui.com/docs (same as your local docs/ folder). +// - Introduction, links and more at the top of imgui.cpp + +// **DO NOT USE THIS CODE IF YOUR CODE/ENGINE IS USING MODERN OPENGL (SHADERS, VBO, VAO, etc.)** +// **Prefer using the code in the example_glfw_opengl2/ folder** +// See imgui_impl_glfw.cpp for details. + +#include "imgui.h" +#include "imgui_impl_glfw.h" +#include "imgui_impl_opengl2.h" +#include +#ifdef __APPLE__ +#define GL_SILENCE_DEPRECATION +#endif +#include + +#include "timer.h" +#include "ui.hpp" +#include "administration.hpp" +#include "administration_writer.hpp" +#include "administration_reader.hpp" + +// [Win32] Our example includes a copy of glfw3.lib pre-compiled with VS2010 to maximize ease of testing and compatibility with old VS compilers. +// To link with VS2010-era libraries, VS2015+ requires linking with legacy_stdio_definitions.lib, which we do using this pragma. +// Your own project should not be affected, as you are likely to link with a newer binary of GLFW that is adequate for your version of Visual Studio. +#if defined(_MSC_VER) && (_MSC_VER >= 1900) && !defined(IMGUI_DISABLE_WIN32_FUNCTIONS) +#pragma comment(lib, "legacy_stdio_definitions") +#endif + +static void glfw_error_callback(int error, const char* description) +{ + fprintf(stderr, "GLFW Error %d: %s\n", error, description); +} + +// Main code +int main(int argc, char** argv) +{ + glfwSetErrorCallback(glfw_error_callback); + if (!glfwInit()) + return 1; + + // Create window with graphics context + float main_scale = ImGui_ImplGlfw_GetContentScaleForMonitor(glfwGetPrimaryMonitor()); // Valid on GLFW 3.3+ only + GLFWwindow* window = glfwCreateWindow((int)(1280 * main_scale), (int)(800 * main_scale), "OpenBooks", nullptr, nullptr); + if (window == nullptr) + return 1; + glfwMakeContextCurrent(window); + glfwSwapInterval(1); // Enable vsync + + // Setup Dear ImGui context + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + ImGuiIO& io = ImGui::GetIO(); (void)io; + io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls + + // Setup Dear ImGui style + ImGui::StyleColorsDark(); + //ImGui::StyleColorsLight(); + + // Setup scaling + ImGuiStyle& style = ImGui::GetStyle(); + style.ScaleAllSizes(main_scale); // Bake a fixed style scale. (until we have a solution for dynamic style scaling, changing this requires resetting Style + calling this again) + style.FontScaleDpi = main_scale; // Set initial font scale. (using io.ConfigDpiScaleFonts=true makes this unnecessary. We leave both here for documentation purpose) + + // Setup Platform/Renderer backends + ImGui_ImplGlfw_InitForOpenGL(window, true); + ImGui_ImplOpenGL2_Init(); + + style.FontSizeBase = 18.0f; + io.Fonts->AddFontFromFileTTF("build/Segoe UI.ttf"); + ui::fontBold = io.Fonts->AddFontFromFileTTF("build/Segoe UI Bold.ttf"); + ui::fontBig = io.Fonts->AddFontFromFileTTF("build/Segoe UI Bold.ttf", 30); + + ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); + + timer_lib_initialize(); + administration_writer::create(); + + if (argc < 2) { + administration::create_default(""); + } + else { + administration_reader::open_existing(argv[1]); + } + + while (!glfwWindowShouldClose(window)) + { + glfwPollEvents(); + if (glfwGetWindowAttrib(window, GLFW_ICONIFIED) != 0) + { + ImGui_ImplGlfw_Sleep(10); + continue; + } + + // Start the Dear ImGui frame + ImGui_ImplOpenGL2_NewFrame(); + ImGui_ImplGlfw_NewFrame(); + ImGui::NewFrame(); + + ui::draw_main(); + + // Rendering + ImGui::Render(); + int display_w, display_h; + glfwGetFramebufferSize(window, &display_w, &display_h); + glViewport(0, 0, display_w, display_h); + glClearColor(clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w); + glClear(GL_COLOR_BUFFER_BIT); + + // If you are using this code with non-legacy OpenGL header/contexts (which you should not, prefer using imgui_impl_opengl3.cpp!!), + // you may need to backup/reset/restore other state, e.g. for current shader using the commented lines below. + //GLint last_program; + //glGetIntegerv(GL_CURRENT_PROGRAM, &last_program); + //glUseProgram(0); + ImGui_ImplOpenGL2_RenderDrawData(ImGui::GetDrawData()); + //glUseProgram(last_program); + + glfwMakeContextCurrent(window); + glfwSwapBuffers(window); + } + + administration_writer::destroy(); + timer_lib_shutdown(); + administration::destroy(); + + // Cleanup + ImGui_ImplOpenGL2_Shutdown(); + ImGui_ImplGlfw_Shutdown(); + ImGui::DestroyContext(); + + glfwDestroyWindow(window); + glfwTerminate(); + + return 0; +} diff --git a/src/main_windows.cpp b/src/main_windows.cpp new file mode 100644 index 0000000..974949b --- /dev/null +++ b/src/main_windows.cpp @@ -0,0 +1,319 @@ +/* +* Copyright (c) 2025 Aldrik Ramaekers +* +* Permission to use, copy, modify, and/or distribute this software for any +* purpose with or without fee is hereby granted, provided that the above +* copyright notice and this permission notice appear in all copies. +* +* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#ifdef win64 + +#include "imgui.h" +#include "imgui_impl_win32.h" +#include "imgui_impl_dx11.h" +#include +#include +#include "timer.h" +#include "ui.hpp" +#include "administration.hpp" +#include "administration_writer.hpp" +#include "administration_reader.hpp" + +// Data +static HWND hwnd; +static ID3D11Device* g_pd3dDevice = nullptr; +static ID3D11DeviceContext* g_pd3dDeviceContext = nullptr; +static IDXGISwapChain* g_pSwapChain = nullptr; +static bool g_SwapChainOccluded = false; +static UINT g_ResizeWidth = 0, g_ResizeHeight = 0; +static ID3D11RenderTargetView* g_mainRenderTargetView = nullptr; + +// Forward declarations of helper functions +bool CreateDeviceD3D(HWND hWnd); +void CleanupDeviceD3D(); +void CreateRenderTarget(); +void CleanupRenderTarget(); +LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); + +void platorm_maximize_window() +{ + LONG style = GetWindowLong(hwnd, GWL_STYLE); + + // allow resizing + maximize + style |= (WS_THICKFRAME | WS_MAXIMIZEBOX); + + SetWindowLong(hwnd, GWL_STYLE, style); + + // Apply style changes + SetWindowPos(hwnd, NULL, 0, 0, 0, 0, + SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED); + + ShowWindow(hwnd, SW_MAXIMIZE); +} + +// Main code +//int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) +int main(int argc, char** argv) +{ + int start_width = 1280; + int start_height = 800; + + // Make process DPI aware and obtain main monitor scale + ImGui_ImplWin32_EnableDpiAwareness(); + float main_scale = ImGui_ImplWin32_GetDpiScaleForMonitor(::MonitorFromPoint(POINT{ 0, 0 }, MONITOR_DEFAULTTOPRIMARY)); + + // Create application window + WNDCLASSEXW wc = { sizeof(wc), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(nullptr), nullptr, nullptr, nullptr, nullptr, L"ImGui Example", nullptr }; + ::RegisterClassExW(&wc); + + // Get screen size + int screenW = GetSystemMetrics(SM_CXSCREEN); + int screenH = GetSystemMetrics(SM_CYSCREEN); + + // Calculate top-left so window is centered + int x = (screenW - start_width) / 2; + int y = (screenH - start_height) / 2; + + hwnd = ::CreateWindowW(wc.lpszClassName, L"OpenBooks", WS_OVERLAPPEDWINDOW, + x, y, (int)(start_width * main_scale), (int)(start_height * main_scale), nullptr, nullptr, wc.hInstance, nullptr); + + // Initialize Direct3D + if (!CreateDeviceD3D(hwnd)) + { + CleanupDeviceD3D(); + ::UnregisterClassW(wc.lpszClassName, wc.hInstance); + return 1; + } + + // Show the window + ::ShowWindow(hwnd, SW_SHOWDEFAULT); + ::UpdateWindow(hwnd); + + // Setup Dear ImGui context + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + ImGuiIO& io = ImGui::GetIO(); + io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls + io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; // Enable Gamepad Controls + io.IniFilename = NULL; + io.LogFilename = NULL; + + // Setup Dear ImGui style + ImGui::StyleColorsDark(); + //ImGui::StyleColorsLight(); + + // Setup scaling + ImGuiStyle& style = ImGui::GetStyle(); + style.ScaleAllSizes(main_scale); // Bake a fixed style scale. (until we have a solution for dynamic style scaling, changing this requires resetting Style + calling this again) + style.FontScaleDpi = main_scale; // Set initial font scale. (using io.ConfigDpiScaleFonts=true makes this unnecessary. We leave both here for documentation purpose) + + // Setup Platform/Renderer backends + ImGui_ImplWin32_Init(hwnd); + ImGui_ImplDX11_Init(g_pd3dDevice, g_pd3dDeviceContext); + + // Load Fonts + // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. + // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. + // - If the file cannot be loaded, the function will return a nullptr. Please handle those errors in your application (e.g. use an assertion, or display an error and quit). + // - Use '#define IMGUI_ENABLE_FREETYPE' in your imconfig file to use Freetype for higher quality font rendering. + // - Read 'docs/FONTS.md' for more instructions and details. + // - Remember that in C/C++ if you want to include a backslash \ in a string literal you need to write a double backslash \\ ! + style.FontSizeBase = 18.0f; + //io.Fonts->AddFontDefault(); + io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf"); + //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\seguisym.ttf"); + ui::fontBold = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeuib.ttf"); + ui::fontBig = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeuib.ttf", 30); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/DroidSans.ttf"); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Roboto-Medium.ttf"); + //io.Fonts->AddFontFromFileTTF("../../misc/fonts/Cousine-Regular.ttf"); + //ImFont* font = io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\ArialUni.ttf"); + //IM_ASSERT(font != nullptr); + + ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); + + timer_lib_initialize(); + administration_writer::create(); + + if (argc < 2) { + administration::create_default(""); + } + else { + administration_reader::open_existing(argv[1]); + } + + // Main loop + bool done = false; + while (!done) + { + // Poll and handle messages (inputs, window resize, etc.) + // See the WndProc() function below for our to dispatch events to the Win32 backend. + MSG msg; + while (::PeekMessage(&msg, nullptr, 0U, 0U, PM_REMOVE)) + { + ::TranslateMessage(&msg); + ::DispatchMessage(&msg); + if (msg.message == WM_QUIT) + done = true; + } + if (done) + break; + + // Handle window being minimized or screen locked + if (g_SwapChainOccluded && g_pSwapChain->Present(0, DXGI_PRESENT_TEST) == DXGI_STATUS_OCCLUDED) + { + ::Sleep(10); + continue; + } + g_SwapChainOccluded = false; + + // Handle window resize (we don't resize directly in the WM_SIZE handler) + if (g_ResizeWidth != 0 && g_ResizeHeight != 0) + { + CleanupRenderTarget(); + g_pSwapChain->ResizeBuffers(0, g_ResizeWidth, g_ResizeHeight, DXGI_FORMAT_UNKNOWN, 0); + g_ResizeWidth = g_ResizeHeight = 0; + CreateRenderTarget(); + } + + // Start the Dear ImGui frame + ImGui_ImplDX11_NewFrame(); + ImGui_ImplWin32_NewFrame(); + ImGui::NewFrame(); + + ui::draw_main(); + + // Rendering + ImGui::Render(); + const float clear_color_with_alpha[4] = { clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w }; + g_pd3dDeviceContext->OMSetRenderTargets(1, &g_mainRenderTargetView, nullptr); + g_pd3dDeviceContext->ClearRenderTargetView(g_mainRenderTargetView, clear_color_with_alpha); + ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData()); + + // Present + HRESULT hr = g_pSwapChain->Present(1, 0); // Present with vsync + //HRESULT hr = g_pSwapChain->Present(0, 0); // Present without vsync + g_SwapChainOccluded = (hr == DXGI_STATUS_OCCLUDED); + } + + administration_writer::destroy(); + timer_lib_shutdown(); + administration::destroy(); + + // Cleanup + ImGui_ImplDX11_Shutdown(); + ImGui_ImplWin32_Shutdown(); + ImGui::DestroyContext(); + + CleanupDeviceD3D(); + ::DestroyWindow(hwnd); + ::UnregisterClassW(wc.lpszClassName, wc.hInstance); + + return 0; +} + +// Helper functions + +bool CreateDeviceD3D(HWND hWnd) +{ + // Setup swap chain + DXGI_SWAP_CHAIN_DESC sd; + ZeroMemory(&sd, sizeof(sd)); + sd.BufferCount = 2; + sd.BufferDesc.Width = 0; + sd.BufferDesc.Height = 0; + sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + sd.BufferDesc.RefreshRate.Numerator = 60; + sd.BufferDesc.RefreshRate.Denominator = 1; + sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH; + sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + sd.OutputWindow = hWnd; + sd.SampleDesc.Count = 1; + sd.SampleDesc.Quality = 0; + sd.Windowed = TRUE; + sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; + + UINT createDeviceFlags = 0; + //createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; + D3D_FEATURE_LEVEL featureLevel; + const D3D_FEATURE_LEVEL featureLevelArray[2] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_0, }; + HRESULT res = D3D11CreateDeviceAndSwapChain(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, createDeviceFlags, featureLevelArray, 2, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &featureLevel, &g_pd3dDeviceContext); + if (res == DXGI_ERROR_UNSUPPORTED) // Try high-performance WARP software driver if hardware is not available. + res = D3D11CreateDeviceAndSwapChain(nullptr, D3D_DRIVER_TYPE_WARP, nullptr, createDeviceFlags, featureLevelArray, 2, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &featureLevel, &g_pd3dDeviceContext); + if (res != S_OK) + return false; + + CreateRenderTarget(); + return true; +} + +void CleanupDeviceD3D() +{ + CleanupRenderTarget(); + if (g_pSwapChain) { g_pSwapChain->Release(); g_pSwapChain = nullptr; } + if (g_pd3dDeviceContext) { g_pd3dDeviceContext->Release(); g_pd3dDeviceContext = nullptr; } + if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = nullptr; } +} + +void CreateRenderTarget() +{ + ID3D11Texture2D* pBackBuffer; + g_pSwapChain->GetBuffer(0, IID_PPV_ARGS(&pBackBuffer)); + g_pd3dDevice->CreateRenderTargetView(pBackBuffer, nullptr, &g_mainRenderTargetView); + pBackBuffer->Release(); +} + +void CleanupRenderTarget() +{ + if (g_mainRenderTargetView) { g_mainRenderTargetView->Release(); g_mainRenderTargetView = nullptr; } +} + +// Forward declare message handler from imgui_impl_win32.cpp +extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); + +// Win32 message handler +// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs. +// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or clear/overwrite your copy of the mouse data. +// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or clear/overwrite your copy of the keyboard data. +// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. +LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) + return true; + + switch (msg) + { + case WM_GETMINMAXINFO: + { + MINMAXINFO* minMaxInfo = (MINMAXINFO*)lParam; + minMaxInfo->ptMinTrackSize.x = 1400; // Minimum width + minMaxInfo->ptMinTrackSize.y = 900; // Minimum height + return 0; + } + + case WM_SIZE: + if (wParam == SIZE_MINIMIZED) + return 0; + g_ResizeWidth = (UINT)LOWORD(lParam); // Queue resize + g_ResizeHeight = (UINT)HIWORD(lParam); + return 0; + case WM_SYSCOMMAND: + if ((wParam & 0xfff0) == SC_KEYMENU) // Disable ALT application menu + return 0; + break; + case WM_DESTROY: + ::PostQuitMessage(0); + return 0; + } + return ::DefWindowProcW(hWnd, msg, wParam, lParam); +} + +#endif \ No newline at end of file diff --git a/src/ui/ui_tax.cpp b/src/ui/ui_tax.cpp index 8a119e4..af05cd7 100644 --- a/src/ui/ui_tax.cpp +++ b/src/ui/ui_tax.cpp @@ -22,7 +22,7 @@ #include "locales.hpp" #include "administration.hpp" -tax_statement* statement = 0; +static tax_statement* statement = 0; void ui::setup_tax_report() { -- cgit v1.2.3-70-g09d2