diff --git a/build_imgui_lib.cmd b/build_imgui_lib.cmd index c218cbb..29f0007 100644 --- a/build_imgui_lib.cmd +++ b/build_imgui_lib.cmd @@ -8,7 +8,7 @@ if "%~1"=="" ( set CONFIG=%~1 -if /I "%CONFIG%"=="Debug" ( +if /I "%CONFIG%"=="Debug" ( rem /Z7 embeds debug info into PDB so we don't need to pass /Fd to cl set CFLAGS=/MTd /Od /Z7 /DDEBUG /DEBUG -diagnostics:caret -diagnostics:column -D_CRT_SECURE_NO_WARNINGS -D_SILENCE_TR1_NAMESPACE_DEPRECATION_WARNING -D_CRT_NONSTDC_NO_DEPRECATE -D_USE_MATH_DEFINES set LIB_PATH=bin/Debug ) else if /I "%CONFIG%"=="Release" ( @@ -41,7 +41,7 @@ set INCLUDE_DIRS=^ set LINK_LIBS= -REM Build STATIC LIBRARY: +REM Build STATIC LIBRARY: rem /Fd%LIB_PATH%/%LIB_NAME%.pdb can be passed to cl if compiling with /Zi echo Building static LIB (%CONFIG%) cl /nologo /EHsc /DWIN32 /wd4530 %CFLAGS% %INCLUDE_DIRS% %SRC_FILES% /c /Fo%OBJDIR%\ lib /OUT:%LIB_PATH%\%LIB_NAME%.lib %OBJDIR%\*.obj %LINK_LIBS% diff --git a/exe_main.cpp b/exe_main.cpp index 76e37cb..8108303 100644 --- a/exe_main.cpp +++ b/exe_main.cpp @@ -1,6 +1,6 @@ #include "lib_main.cpp" -#define BASE_RUN_TESTS 1 +#define BASE_RUN_TESTS 0 #if BASE_RUN_TESTS #include "lib/Base/run_tests.cpp" #endif @@ -8,12 +8,15 @@ #define USE_DEAR_IMGUI 1 #if USE_DEAR_IMGUI #include + #include #pragma comment(lib, "d3d11.lib") #pragma comment(lib, "dxgi.lib") #include "lib/third_party/dear-imgui/imgui.h" #include "lib/third_party/dear-imgui/imgui_impl_win32.h" #include "lib/third_party/dear-imgui/imgui_impl_dx11.h" + #include "src/ImGui_Supplementary.cpp" + #include "src/imgui_main.cpp" #endif diff --git a/extras/fonts/RobotoMono-Regular.ttf b/extras/fonts/RobotoMono-Regular.ttf new file mode 100644 index 0000000..6df2b25 Binary files /dev/null and b/extras/fonts/RobotoMono-Regular.ttf differ diff --git a/lib/Base/Base.h b/lib/Base/Base.h index bf82a5f..17b07d1 100644 --- a/lib/Base/Base.h +++ b/lib/Base/Base.h @@ -251,6 +251,19 @@ struct Vec4 { }; }; +template T clamp (T v, T min, T max) { + // T must be a scalar type: + auto x = v; + if (x < min) { + x = min; + } + if (x > max) { + x = max; + } + + return x; +} + // #thread_primitives #move? #if OS_WINDOWS struct Condition_Variable { diff --git a/lib/Base/run_tests.cpp b/lib/Base/run_tests.cpp index 4ed6f4f..6c11e15 100644 --- a/lib/Base/run_tests.cpp +++ b/lib/Base/run_tests.cpp @@ -1,4 +1,5 @@ void run_pre_setup_tests() { + // #no_context: context will not be initialized at this point. printf("Running pre-setup tests...\n"); printf("\nFinished running pre-setup tests...\n"); } @@ -48,7 +49,6 @@ void run_post_setup_tests() { log("file_data: \n"); log("%s\n", file_data.data); } - // ImGui_Application(); { // Test hashing: u64 start = 0x512585; u32 sdbm = sdbm_hash(&start, sizeof(u64)); diff --git a/lib/OS/OS_Win32.cpp b/lib/OS/OS_Win32.cpp index 2499875..436527b 100644 --- a/lib/OS/OS_Win32.cpp +++ b/lib/OS/OS_Win32.cpp @@ -627,16 +627,20 @@ Window_Dimensions platform_get_centered_window_dimensions (bool open_on_largest_ // #window_creation -> put API in OS_Win32.h // Instead of returning WindowType, return the handle + other information. -bool os_create_window (string new_window_name, Window_Type parent, bool center_window, bool open_on_largest_monitor, bool display_window) { +bool os_create_window (string new_window_name, Window_Type parent, bool center_window, bool open_on_largest_monitor, bool display_window, void* wnd_proc_override) { local_persist string class_name = "Win32_Window_Class"; - + + WNDCLASSEXW wc = {}; if (!global_win32_state.process_info.window_class_initialized) { global_win32_state.process_info.window_class_initialized = true; - WNDCLASSEXW wc = {}; wc.cbSize = sizeof(WNDCLASSEXW); wc.style = CS_HREDRAW | CS_VREDRAW; - wc.lpfnWndProc = win32_wnd_proc; + if (!wnd_proc_override) { + wc.lpfnWndProc = win32_wnd_proc; + } else { + wc.lpfnWndProc = (WNDPROC)wnd_proc_override; + } wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = nullptr; @@ -662,7 +666,7 @@ bool os_create_window (string new_window_name, Window_Type parent, bool center_w HWND hwnd = CreateWindowExW( WS_EX_APPWINDOW, - (LPCWSTR)utf8_to_wide(class_name).data, + wc.lpszClassName, (LPCWSTR)utf8_to_wide(new_window_name).data, WS_OVERLAPPEDWINDOW, wd.window_x, wd.window_y, wd.window_width, wd.window_height, @@ -707,6 +711,18 @@ Window_Info get_main_window () { return {}; } +Window_Info* get_main_window_pointer () { + s64 window_count = global_win32_state.process_info.windows.count; + + for (s64 i = 0; i < window_count; i += 1) { + if (global_win32_state.process_info.windows[i].is_main_window) { + return &global_win32_state.process_info.windows[i]; + } + } + + return nullptr; +} + bool get_window_dimensions(Window_Info* info, s32* width, s32* height) { if (info == nullptr || width == nullptr || height == nullptr) return false; Assert(width && height); diff --git a/lib/OS/OS_Win32.h b/lib/OS/OS_Win32.h index 7706e30..1e71dca 100644 --- a/lib/OS/OS_Win32.h +++ b/lib/OS/OS_Win32.h @@ -80,7 +80,7 @@ struct Monitor { }; -bool os_create_window (string new_window_name, Window_Type parent=nullptr, bool center_window=true, bool open_on_largest_monitor=true, bool display_window=true); +bool os_create_window (string new_window_name, Window_Type parent=nullptr, bool center_window=true, bool open_on_largest_monitor=true, bool display_window=true, void* wnd_proc_override=nullptr); Window_Info get_main_window (); Window_Info* get_main_window_pointer (); diff --git a/src/Base_Entry_Point.cpp b/src/Base_Entry_Point.cpp index 87fd674..d42489c 100644 --- a/src/Base_Entry_Point.cpp +++ b/src/Base_Entry_Point.cpp @@ -18,16 +18,18 @@ internal void Main_Entry_Point (int argc, WCHAR **argv); internal void Main_Entry_Point (int argc, WCHAR **argv) { set_cpu_base_frequency(3200); // REQUIRED FOR TIMING MODULE! will depend on CPU - ImGui_Application(); -/* + #if BASE_RUN_TESTS - run_pre_setup_tests(); // #no_context + run_pre_setup_tests(); // #no_context: context will not be initialized at this point. #endif // #NOTE: Be careful using a timing or auto-release macros // before setting up the thread context! Bootstrap_Main_Thread_Context(); #if OS_WINDOWS Win32_Entry_Point(argc, argv); + Win32_Initialize_Ex(); + // #TODO: Initialize global hotkeys + ImGui_Application_Win32(); #endif #if OS_LINUX // Linux_Entry_Point(argc, argv); @@ -35,12 +37,7 @@ internal void Main_Entry_Point (int argc, WCHAR **argv) { #if BASE_RUN_TESTS run_post_setup_tests(); #endif - - // 2. Create Window - bool success = os_create_window("App Main Window", nullptr, true, true); - Assert(success); - - Window_Info main_window = get_main_window(); + /* Alternative if we're using OpenGL. s32 window_width; s32 window_height; success = get_window_dimensions(&main_window, &window_width, &window_height); Assert(success); diff --git a/src/ImGui_Supplementary.cpp b/src/ImGui_Supplementary.cpp index 0170c56..4eea72a 100644 --- a/src/ImGui_Supplementary.cpp +++ b/src/ImGui_Supplementary.cpp @@ -11,7 +11,7 @@ bool CreateDeviceD3D(HWND hWnd); void CleanupDeviceD3D(); void CreateRenderTarget(); void CleanupRenderTarget(); -LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); +LRESULT WINAPI ImGui_WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); // Helper functions bool CreateDeviceD3D(HWND hWnd) { @@ -82,7 +82,7 @@ extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg // - 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) { +LRESULT WINAPI ImGui_WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) return true; @@ -108,76 +108,160 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { #include "../lib/third_party/dear-imgui/imgui_internal.h" void Set_Custom_Style () { - ImGuiStyle* style = &ImGui::GetStyle(); - ImVec4* colors = style->Colors; + ImGuiStyle* style = &ImGui::GetStyle(); + ImVec4* colors = style->Colors; - style->Alpha = 1.0; - style->WindowRounding = 3.0f; - style->GrabRounding = 3.0f; - style->GrabMinSize = 20.0f; - style->FrameRounding = 8.0f; - style->TabRounding = 8.0f; + style->Alpha = 1.0; + style->WindowRounding = 3.0f; + style->GrabRounding = 3.0f; + style->GrabMinSize = 20.0f; + style->FrameRounding = 8.0f; + style->TabRounding = 8.0f; - colors[ImGuiCol_Text] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); - colors[ImGuiCol_TextDisabled] = ImVec4(0.50f, 0.50f, 0.50f, 1.00f); - colors[ImGuiCol_WindowBg] = ImVec4(0.06f, 0.06f, 0.06f, 0.94f); - colors[ImGuiCol_ChildBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); - colors[ImGuiCol_PopupBg] = ImVec4(0.08f, 0.08f, 0.08f, 0.94f); - colors[ImGuiCol_Border] = ImVec4(0.43f, 0.43f, 0.50f, 0.50f); - colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); - colors[ImGuiCol_FrameBg] = ImVec4(0.16f, 0.29f, 0.48f, 0.54f); - colors[ImGuiCol_FrameBgHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.40f); - colors[ImGuiCol_FrameBgActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f); - colors[ImGuiCol_TitleBg] = ImVec4(0.04f, 0.04f, 0.04f, 1.00f); - colors[ImGuiCol_TitleBgActive] = ImVec4(0.16f, 0.29f, 0.48f, 1.00f); - colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.00f, 0.00f, 0.00f, 0.51f); - colors[ImGuiCol_MenuBarBg] = ImVec4(0.14f, 0.14f, 0.14f, 1.00f); - colors[ImGuiCol_ScrollbarBg] = ImVec4(0.02f, 0.02f, 0.02f, 0.53f); - colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.31f, 0.31f, 0.31f, 1.00f); - colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.41f, 0.41f, 0.41f, 1.00f); - colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.51f, 0.51f, 0.51f, 1.00f); - colors[ImGuiCol_CheckMark] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); - colors[ImGuiCol_SliderGrab] = ImVec4(0.24f, 0.52f, 0.88f, 1.00f); - colors[ImGuiCol_SliderGrabActive] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); - colors[ImGuiCol_Button] = ImVec4(0.26f, 0.59f, 0.98f, 0.40f); - colors[ImGuiCol_ButtonHovered] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); - colors[ImGuiCol_ButtonActive] = ImVec4(0.06f, 0.53f, 0.98f, 1.00f); - colors[ImGuiCol_Header] = ImVec4(0.26f, 0.59f, 0.98f, 0.31f); - colors[ImGuiCol_HeaderHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.80f); - colors[ImGuiCol_HeaderActive] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); - colors[ImGuiCol_Separator] = colors[ImGuiCol_Border]; - colors[ImGuiCol_SeparatorHovered] = ImVec4(0.10f, 0.40f, 0.75f, 0.78f); - colors[ImGuiCol_SeparatorActive] = ImVec4(0.10f, 0.40f, 0.75f, 1.00f); - colors[ImGuiCol_ResizeGrip] = ImVec4(0.26f, 0.59f, 0.98f, 0.20f); - colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f); - colors[ImGuiCol_ResizeGripActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.95f); - colors[ImGuiCol_InputTextCursor] = colors[ImGuiCol_Text]; - colors[ImGuiCol_TabHovered] = colors[ImGuiCol_HeaderHovered]; - colors[ImGuiCol_Tab] = ImLerp(colors[ImGuiCol_Header], colors[ImGuiCol_TitleBgActive], 0.80f); - colors[ImGuiCol_TabSelected] = ImLerp(colors[ImGuiCol_HeaderActive], colors[ImGuiCol_TitleBgActive], 0.60f); - colors[ImGuiCol_TabSelectedOverline] = colors[ImGuiCol_HeaderActive]; - colors[ImGuiCol_TabDimmed] = ImLerp(colors[ImGuiCol_Tab], colors[ImGuiCol_TitleBg], 0.80f); - colors[ImGuiCol_TabDimmedSelected] = ImLerp(colors[ImGuiCol_TabSelected], colors[ImGuiCol_TitleBg], 0.40f); - colors[ImGuiCol_TabDimmedSelectedOverline] = ImVec4(0.50f, 0.50f, 0.50f, 0.00f); - colors[ImGuiCol_DockingPreview] = ImVec4(0.26f, 0.59f, 0.98f, 0.75f); //colors[ImGuiCol_HeaderActive] * ImVec4(1.0f, 1.0f, 1.0f, 0.7f); - colors[ImGuiCol_DockingEmptyBg] = ImVec4(0.20f, 0.20f, 0.20f, 1.00f); - colors[ImGuiCol_PlotLines] = ImVec4(0.61f, 0.61f, 0.61f, 1.00f); - colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.43f, 0.35f, 1.00f); - colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); - colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.60f, 0.00f, 1.00f); - colors[ImGuiCol_TableHeaderBg] = ImVec4(0.19f, 0.19f, 0.20f, 1.00f); - colors[ImGuiCol_TableBorderStrong] = ImVec4(0.31f, 0.31f, 0.35f, 1.00f); // Prefer using Alpha=1.0 here - colors[ImGuiCol_TableBorderLight] = ImVec4(0.23f, 0.23f, 0.25f, 1.00f); // Prefer using Alpha=1.0 here - colors[ImGuiCol_TableRowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); - colors[ImGuiCol_TableRowBgAlt] = ImVec4(1.00f, 1.00f, 1.00f, 0.06f); - colors[ImGuiCol_TextLink] = colors[ImGuiCol_HeaderActive]; - colors[ImGuiCol_TextSelectedBg] = ImVec4(0.26f, 0.59f, 0.98f, 0.35f); - colors[ImGuiCol_TreeLines] = colors[ImGuiCol_Border]; - colors[ImGuiCol_DragDropTarget] = ImVec4(1.00f, 1.00f, 0.00f, 0.90f); - colors[ImGuiCol_DragDropTargetBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); - colors[ImGuiCol_UnsavedMarker] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); - colors[ImGuiCol_NavCursor] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); - colors[ImGuiCol_NavWindowingHighlight] = ImVec4(1.00f, 1.00f, 1.00f, 0.70f); - colors[ImGuiCol_NavWindowingDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.20f); - colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.35f); + colors[ImGuiCol_Text] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); + colors[ImGuiCol_TextDisabled] = ImVec4(0.50f, 0.50f, 0.50f, 1.00f); + colors[ImGuiCol_WindowBg] = ImVec4(0.06f, 0.06f, 0.06f, 0.94f); + colors[ImGuiCol_ChildBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); + colors[ImGuiCol_PopupBg] = ImVec4(0.08f, 0.08f, 0.08f, 0.94f); + colors[ImGuiCol_Border] = ImVec4(0.43f, 0.43f, 0.50f, 0.50f); + colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); + colors[ImGuiCol_FrameBg] = ImVec4(0.16f, 0.29f, 0.48f, 0.54f); + colors[ImGuiCol_FrameBgHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.40f); + colors[ImGuiCol_FrameBgActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f); + colors[ImGuiCol_TitleBg] = ImVec4(0.04f, 0.04f, 0.04f, 1.00f); + colors[ImGuiCol_TitleBgActive] = ImVec4(0.16f, 0.29f, 0.48f, 1.00f); + colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.00f, 0.00f, 0.00f, 0.51f); + colors[ImGuiCol_MenuBarBg] = ImVec4(0.14f, 0.14f, 0.14f, 1.00f); + colors[ImGuiCol_ScrollbarBg] = ImVec4(0.02f, 0.02f, 0.02f, 0.53f); + colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.31f, 0.31f, 0.31f, 1.00f); + colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.41f, 0.41f, 0.41f, 1.00f); + colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.51f, 0.51f, 0.51f, 1.00f); + colors[ImGuiCol_CheckMark] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); + colors[ImGuiCol_SliderGrab] = ImVec4(0.24f, 0.52f, 0.88f, 1.00f); + colors[ImGuiCol_SliderGrabActive] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); + colors[ImGuiCol_Button] = ImVec4(0.26f, 0.59f, 0.98f, 0.40f); + colors[ImGuiCol_ButtonHovered] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); + colors[ImGuiCol_ButtonActive] = ImVec4(0.06f, 0.53f, 0.98f, 1.00f); + colors[ImGuiCol_Header] = ImVec4(0.26f, 0.59f, 0.98f, 0.31f); + colors[ImGuiCol_HeaderHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.80f); + colors[ImGuiCol_HeaderActive] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); + colors[ImGuiCol_Separator] = colors[ImGuiCol_Border]; + colors[ImGuiCol_SeparatorHovered] = ImVec4(0.10f, 0.40f, 0.75f, 0.78f); + colors[ImGuiCol_SeparatorActive] = ImVec4(0.10f, 0.40f, 0.75f, 1.00f); + colors[ImGuiCol_ResizeGrip] = ImVec4(0.26f, 0.59f, 0.98f, 0.20f); + colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f); + colors[ImGuiCol_ResizeGripActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.95f); + colors[ImGuiCol_InputTextCursor] = colors[ImGuiCol_Text]; + colors[ImGuiCol_TabHovered] = colors[ImGuiCol_HeaderHovered]; + colors[ImGuiCol_Tab] = ImLerp(colors[ImGuiCol_Header], colors[ImGuiCol_TitleBgActive], 0.80f); + colors[ImGuiCol_TabSelected] = ImLerp(colors[ImGuiCol_HeaderActive], colors[ImGuiCol_TitleBgActive], 0.60f); + colors[ImGuiCol_TabSelectedOverline] = colors[ImGuiCol_HeaderActive]; + colors[ImGuiCol_TabDimmed] = ImLerp(colors[ImGuiCol_Tab], colors[ImGuiCol_TitleBg], 0.80f); + colors[ImGuiCol_TabDimmedSelected] = ImLerp(colors[ImGuiCol_TabSelected], colors[ImGuiCol_TitleBg], 0.40f); + colors[ImGuiCol_TabDimmedSelectedOverline] = ImVec4(0.50f, 0.50f, 0.50f, 0.00f); + colors[ImGuiCol_DockingPreview] = ImVec4(0.26f, 0.59f, 0.98f, 0.75f); //colors[ImGuiCol_HeaderActive] * ImVec4(1.0f, 1.0f, 1.0f, 0.7f); + colors[ImGuiCol_DockingEmptyBg] = ImVec4(0.20f, 0.20f, 0.20f, 1.00f); + colors[ImGuiCol_PlotLines] = ImVec4(0.61f, 0.61f, 0.61f, 1.00f); + colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.43f, 0.35f, 1.00f); + colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); + colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.60f, 0.00f, 1.00f); + colors[ImGuiCol_TableHeaderBg] = ImVec4(0.19f, 0.19f, 0.20f, 1.00f); + colors[ImGuiCol_TableBorderStrong] = ImVec4(0.31f, 0.31f, 0.35f, 1.00f); // Prefer using Alpha=1.0 here + colors[ImGuiCol_TableBorderLight] = ImVec4(0.23f, 0.23f, 0.25f, 1.00f); // Prefer using Alpha=1.0 here + colors[ImGuiCol_TableRowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); + colors[ImGuiCol_TableRowBgAlt] = ImVec4(1.00f, 1.00f, 1.00f, 0.06f); + colors[ImGuiCol_TextLink] = colors[ImGuiCol_HeaderActive]; + colors[ImGuiCol_TextSelectedBg] = ImVec4(0.26f, 0.59f, 0.98f, 0.35f); + colors[ImGuiCol_TreeLines] = colors[ImGuiCol_Border]; + colors[ImGuiCol_DragDropTarget] = ImVec4(1.00f, 1.00f, 0.00f, 0.90f); + colors[ImGuiCol_DragDropTargetBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); + colors[ImGuiCol_UnsavedMarker] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); + colors[ImGuiCol_NavCursor] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); + colors[ImGuiCol_NavWindowingHighlight] = ImVec4(1.00f, 1.00f, 1.00f, 0.70f); + colors[ImGuiCol_NavWindowingDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.20f); + colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.35f); +} + +struct ImGui_Font_Size_Pair { + f32 font_size; + ImFont* data; +}; + +struct ImGui_Font_Info { + string font_name; + Array sizes; + s64 current_size = 1; +}; + +// We can make a more complicated structure here with a Map +// but we only have one font at this point, so it's redundant +global ImGuiContext* imgui_context; +global f32 imgui_font_sizes[6] = {18, 24, 30, 36, 42, 48}; +global ImGui_Font_Info imgui_default_font; + +bool ImGui_Default_Font_Loaded () { + return imgui_default_font.sizes.count > 0; +} + +f32 ImGui_Default_Font_Current_Size () { + return imgui_default_font.sizes[imgui_default_font.current_size].font_size; +} + +void ImGui_Push_Default_Font () { + // #TODO: Replace these asserts so it just returns if not present! + // And just warn in the UI that a font is missing. + Assert(imgui_default_font.sizes.count > 0); + Assert(imgui_default_font.current_size >= 0 && imgui_default_font.current_size < imgui_default_font.sizes.count); + if (ImGui_Default_Font_Loaded()) { + ImFont* font_data = imgui_default_font.sizes[imgui_default_font.current_size].data; + f32 unscaled_font_size = imgui_default_font.sizes[imgui_default_font.current_size].font_size; + ImGui::PushFont(font_data, unscaled_font_size); + } +} + +void ImGui_Pop_Default_Font () { + // This will break if we load font mid-frame! don't do this. + if (ImGui_Default_Font_Loaded()) { + ImGui::PopFont(); + } +} + +#define imgui_push_default_font_index(x) \ + ImGui_Font_Size Concat(_auto_push_font_, __LINE__)(x) + +struct ImGui_Font_Size { + ImGui_Font_Size (s64 size_index) { + s64 size_target = clamp(size_index, 0, 5); + ImFont* font_data = imgui_default_font.sizes[size_target].data; + f32 unscaled_font_size = imgui_default_font.sizes[size_target].font_size; + ImGui::PushFont(font_data, unscaled_font_size); + } + ~ImGui_Font_Size () { + ImGui::PopFont(); + } +}; + +void ImGui_Debug_Panel () { + ImGui::Begin("Debug Panel"); + + if (ImGui::Button("Debug_Break()")) { + debug_break(); + } + + ImGui::End(); +} + +void ImGui_Show_Font_Info () { + ImGui::Begin("Font Settings"); // imgui_push_default_font_index(0); + if (!ImGui_Default_Font_Loaded()){ + ImGui::Text("Default font not present!"); + } else { + ImGui::Text("Current font size: %.1f (index: %d)", ImGui_Default_Font_Current_Size(), + imgui_default_font.current_size); + ImGui::SameLine(); + if (ImGui::Button("Decrease Font Size")) { imgui_default_font.current_size = clamp(imgui_default_font.current_size - 1, 0, 5); } + ImGui::SameLine(); + if (ImGui::Button("Increase Font Size")) { imgui_default_font.current_size = clamp(imgui_default_font.current_size + 1, 0, 5); } + } + ImGui::End(); } \ No newline at end of file diff --git a/src/imgui_main.cpp b/src/imgui_main.cpp index 8329b1d..4b3a92b 100644 --- a/src/imgui_main.cpp +++ b/src/imgui_main.cpp @@ -1,29 +1,25 @@ -#include -#include -#include "ImGui_Supplementary.cpp" - -global ImGuiContext* imgui_context; - -void ImGui_Application () { - // Make process DPI aware and obtain main monitor scale +#include +void ImGui_Application_Win32 () { ImGui_ImplWin32_EnableDpiAwareness(); f32 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); - HWND hwnd = ::CreateWindowW(wc.lpszClassName, L"Dear ImGui DirectX11 Example", WS_OVERLAPPEDWINDOW, 100, 100, (int)(1280 * main_scale), (int)(800 * main_scale), nullptr, nullptr, wc.hInstance, nullptr); - + bool success = os_create_window("Main Window", nullptr, true, true, false, ImGui_WndProc); + Assert(success); + HWND hwnd = get_main_window().window; + // Initialize Direct3D if (!CreateDeviceD3D(hwnd)) { CleanupDeviceD3D(); - ::UnregisterClassW(wc.lpszClassName, wc.hInstance); return; } - // Show the window - ::ShowWindow(hwnd, SW_SHOWDEFAULT); - ::UpdateWindow(hwnd); + // Set dark titlebar + s64 dark_mode = 1; + DWORD USE_IMMERSIVE_DARK_MODE = 20; + ::DwmSetWindowAttribute(hwnd, USE_IMMERSIVE_DARK_MODE, &dark_mode, sizeof(s64)); + // A hacky workaround to display the dark title bar properly. Nothing else we've tried worked + ::ShowWindow(hwnd, SW_HIDE); + ::ShowWindow(hwnd, SW_SHOW); // Setup Dear ImGui context IMGUI_CHECKVERSION(); @@ -37,10 +33,8 @@ void ImGui_Application () { io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; // Enable Docking io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable; // Enable Multi-Viewport / Platform Windows - io.ConfigViewportsNoAutoMerge = true; - io.ConfigViewportsNoTaskBarIcon = true; - io.ConfigDockingAlwaysTabBar = true; - io.ConfigDockingTransparentPayload = true; + // io.ConfigViewportsNoAutoMerge = true; // io.ConfigViewportsNoTaskBarIcon = true; // io.ConfigDockingAlwaysTabBar = true; + // io.ConfigDockingTransparentPayload = true; // Setup Dear ImGui style // ImGui::StyleColorsDark(); @@ -54,32 +48,31 @@ void ImGui_Application () { io.ConfigDpiScaleViewports = true; // [Experimental] Scale Dear ImGui and Platform Windows when Monitor DPI changes. // When viewports are enabled we tweak WindowRounding/WindowBg so platform windows can look identical to regular ones. - if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) - { - style.WindowRounding = 0.0f; - style.Colors[ImGuiCol_WindowBg].w = 1.0f; + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) { + style.WindowRounding = 0.0f; + style.Colors[ImGuiCol_WindowBg].w = 1.0f; } // Setup Platform/Renderer backends ImGui_ImplWin32_Init(hwnd); ImGui_ImplDX11_Init(g_pd3dDevice, g_pd3dDeviceContext); - // #TODO: #ImGUI - 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. If you like the default font but want it to scale better, consider using the 'ProggyVector' from the same author! - // - 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 = 20.0f; + style.FontSizeBase = 24.0f; //io.Fonts->AddFontDefault(); - //io.Fonts->AddFontFromFileTTF("c:\\Windows\\Fonts\\segoeui.ttf"); - //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); + + string font_file_name = "RobotoMono-Regular.ttf"; + + imgui_default_font.sizes.allocator = GPAllocator(); + imgui_default_font.font_name = font_file_name; + + for (s64 i = 0; i < 6; i += 1) { + f32 font_size = imgui_font_sizes[i]; + ImFont* new_font = io.Fonts->AddFontFromFileTTF((char*)font_file_name.data, font_size); + if (new_font) { + ImGui_Font_Size_Pair pair = {font_size, new_font}; + array_add(imgui_default_font.sizes, pair); + } + } bool show_demo_window = true; bool show_another_window = false; @@ -121,29 +114,17 @@ void ImGui_Application () { ImGui_ImplWin32_NewFrame(); ImGui::NewFrame(); + ImGui_Push_Default_Font(); // Simple dockspace: ImGui::DockSpaceOverViewport(); - { - ImGui::Begin("Hello, world!"); - - if (ImGui::Button("Debug_Break()")) { - debug_break(); - } - - if (ImGui::Button("Create New Window")) { - // I think that create_window should take few parameters, and we have other APIs for - // styling, positioning, etc. I just call this and want to get a window. - // auto new_window = create_window(window_name); - } - - if (ImGui::Button("Position recently created Window")) { - - } - + { ImGui::Begin("Test panel"); ImGui::End(); } + ImGui_Show_Font_Info(); + + ImGui_Pop_Default_Font(); // Rendering ImGui::Render(); @@ -153,10 +134,9 @@ void ImGui_Application () { ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData()); // Update and Render additional Platform Windows - if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) - { - ImGui::UpdatePlatformWindows(); - ImGui::RenderPlatformWindowsDefault(); + if (io.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) { + ImGui::UpdatePlatformWindows(); + ImGui::RenderPlatformWindowsDefault(); } // Present @@ -172,5 +152,4 @@ void ImGui_Application () { CleanupDeviceD3D(); ::DestroyWindow(hwnd); - ::UnregisterClassW(wc.lpszClassName, wc.hInstance); } \ No newline at end of file