From f48aae600a2b610403b17fc8d2fcb72bfc023e10 Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 13 May 2024 14:47:37 +0200 Subject: [PATCH 01/10] Version 1.90.7 WIP --- docs/CHANGELOG.txt | 9 +++++++++ imgui.cpp | 2 +- imgui.h | 6 +++--- imgui_demo.cpp | 2 +- imgui_draw.cpp | 2 +- imgui_internal.h | 2 +- imgui_tables.cpp | 2 +- imgui_widgets.cpp | 2 +- 8 files changed, 18 insertions(+), 9 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index dd82faaee..07fc7bee8 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -35,6 +35,15 @@ HOW TO UPDATE? and API updates have been a little more frequent lately. They are documented below and in imgui.cpp and should not affect all users. - Please report any issue! +----------------------------------------------------------------------- + VERSION 1.90.7 WIP (In Progress) +----------------------------------------------------------------------- + +Breaking changes: + +Other changes: + + ----------------------------------------------------------------------- VERSION 1.90.6 (Released 2024-05-08) ----------------------------------------------------------------------- diff --git a/imgui.cpp b/imgui.cpp index 4e3d2ddf7..604dac2b4 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.90.6 +// dear imgui, v1.90.7 WIP // (main code and documentation) // Help: diff --git a/imgui.h b/imgui.h index 45a012283..38d589b77 100644 --- a/imgui.h +++ b/imgui.h @@ -1,4 +1,4 @@ -// dear imgui, v1.90.6 WIP +// dear imgui, v1.90.7 WIP // (headers) // Help: @@ -27,8 +27,8 @@ // Library Version // (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345') -#define IMGUI_VERSION "1.90.6" -#define IMGUI_VERSION_NUM 19060 +#define IMGUI_VERSION "1.90.7 WIP" +#define IMGUI_VERSION_NUM 19061 #define IMGUI_HAS_TABLE /* diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 0130cdb41..fc576c8b9 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.90.6 +// dear imgui, v1.90.7 WIP // (demo code) // Help: diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 04aba119e..00b8948fb 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.90.6 +// dear imgui, v1.90.7 WIP // (drawing and font code) /* diff --git a/imgui_internal.h b/imgui_internal.h index c519d3a37..3ac6b2009 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1,4 +1,4 @@ -// dear imgui, v1.90.6 +// dear imgui, v1.90.7 WIP // (internal structures/api) // You may use this file to debug, understand or extend Dear ImGui features but we don't provide any guarantee of forward compatibility. diff --git a/imgui_tables.cpp b/imgui_tables.cpp index 6815af5ad..11e0d2de2 100644 --- a/imgui_tables.cpp +++ b/imgui_tables.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.90.6 +// dear imgui, v1.90.7 WIP // (tables and columns code) /* diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 69ab7e68a..db43f03f3 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.90.6 +// dear imgui, v1.90.7 WIP // (widgets code) /* From 510eb8f4801adf5096cebe5f15700625d0d9357d Mon Sep 17 00:00:00 2001 From: prabu Date: Sat, 11 May 2024 18:26:45 +0530 Subject: [PATCH 02/10] Tables: fixed cell background of fully clipped row overlapping with header. (#7575, #7041) --- docs/CHANGELOG.txt | 2 ++ imgui_tables.cpp | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 07fc7bee8..150dde530 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -43,6 +43,8 @@ Breaking changes: Other changes: +- Tables: fixed cell background of fully clipped row overlapping with header. (#7575, #7041) [@prabuinet] + ----------------------------------------------------------------------- VERSION 1.90.6 (Released 2024-05-08) diff --git a/imgui_tables.cpp b/imgui_tables.cpp index 11e0d2de2..d4a1fa3ac 100644 --- a/imgui_tables.cpp +++ b/imgui_tables.cpp @@ -1963,7 +1963,8 @@ void ImGui::TableEndRow(ImGuiTable* table) cell_bg_rect.ClipWith(table->BgClipRect); cell_bg_rect.Min.x = ImMax(cell_bg_rect.Min.x, column->ClipRect.Min.x); // So that first column after frozen one gets clipped when scrolling cell_bg_rect.Max.x = ImMin(cell_bg_rect.Max.x, column->MaxX); - window->DrawList->AddRectFilled(cell_bg_rect.Min, cell_bg_rect.Max, cell_data->BgColor); + if (cell_bg_rect.Min.y < cell_bg_rect.Max.y) + window->DrawList->AddRectFilled(cell_bg_rect.Min, cell_bg_rect.Max, cell_data->BgColor); } } From 5e2368045418a7cf6e21f555f0f018e778e2eae2 Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 13 May 2024 15:07:13 +0200 Subject: [PATCH 03/10] Backends: all backends + demo now call IMGUI_CHECKVERSION() to verify ABI compatibility between caller code and compiled version of dear imgui. (#7568) --- backends/imgui_impl_allegro5.cpp | 1 + backends/imgui_impl_android.cpp | 2 ++ backends/imgui_impl_dx10.cpp | 1 + backends/imgui_impl_dx11.cpp | 1 + backends/imgui_impl_dx12.cpp | 1 + backends/imgui_impl_dx9.cpp | 1 + backends/imgui_impl_glfw.cpp | 1 + backends/imgui_impl_glut.cpp | 1 + backends/imgui_impl_metal.mm | 6 ++++-- backends/imgui_impl_opengl2.cpp | 1 + backends/imgui_impl_opengl3.cpp | 1 + backends/imgui_impl_osx.mm | 9 +++++---- backends/imgui_impl_sdl2.cpp | 1 + backends/imgui_impl_sdl3.cpp | 1 + backends/imgui_impl_sdlrenderer2.cpp | 1 + backends/imgui_impl_sdlrenderer3.cpp | 1 + backends/imgui_impl_vulkan.cpp | 1 + backends/imgui_impl_wgpu.cpp | 1 + backends/imgui_impl_win32.cpp | 1 + docs/CHANGELOG.txt | 3 +++ imgui.cpp | 14 +++++++------- imgui.h | 2 ++ imgui_demo.cpp | 3 +++ 23 files changed, 42 insertions(+), 13 deletions(-) diff --git a/backends/imgui_impl_allegro5.cpp b/backends/imgui_impl_allegro5.cpp index 2214ffd1d..03a457082 100644 --- a/backends/imgui_impl_allegro5.cpp +++ b/backends/imgui_impl_allegro5.cpp @@ -423,6 +423,7 @@ static ImGuiKey ImGui_ImplAllegro5_KeyCodeToImGuiKey(int key_code) bool ImGui_ImplAllegro5_Init(ALLEGRO_DISPLAY* display) { ImGuiIO& io = ImGui::GetIO(); + IMGUI_CHECKVERSION(); IM_ASSERT(io.BackendPlatformUserData == nullptr && "Already initialized a platform backend!"); // Setup backend capabilities flags diff --git a/backends/imgui_impl_android.cpp b/backends/imgui_impl_android.cpp index 7dd2afc2e..b0c463931 100644 --- a/backends/imgui_impl_android.cpp +++ b/backends/imgui_impl_android.cpp @@ -263,6 +263,8 @@ int32_t ImGui_ImplAndroid_HandleInputEvent(const AInputEvent* input_event) bool ImGui_ImplAndroid_Init(ANativeWindow* window) { + IMGUI_CHECKVERSION(); + g_Window = window; g_Time = 0.0; diff --git a/backends/imgui_impl_dx10.cpp b/backends/imgui_impl_dx10.cpp index a440eb3ed..9691b49fd 100644 --- a/backends/imgui_impl_dx10.cpp +++ b/backends/imgui_impl_dx10.cpp @@ -534,6 +534,7 @@ void ImGui_ImplDX10_InvalidateDeviceObjects() bool ImGui_ImplDX10_Init(ID3D10Device* device) { ImGuiIO& io = ImGui::GetIO(); + IMGUI_CHECKVERSION(); IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!"); // Setup backend capabilities flags diff --git a/backends/imgui_impl_dx11.cpp b/backends/imgui_impl_dx11.cpp index c55c2621a..167bda673 100644 --- a/backends/imgui_impl_dx11.cpp +++ b/backends/imgui_impl_dx11.cpp @@ -546,6 +546,7 @@ void ImGui_ImplDX11_InvalidateDeviceObjects() bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_context) { ImGuiIO& io = ImGui::GetIO(); + IMGUI_CHECKVERSION(); IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!"); // Setup backend capabilities flags diff --git a/backends/imgui_impl_dx12.cpp b/backends/imgui_impl_dx12.cpp index 67334c83f..32f1622cd 100644 --- a/backends/imgui_impl_dx12.cpp +++ b/backends/imgui_impl_dx12.cpp @@ -702,6 +702,7 @@ bool ImGui_ImplDX12_Init(ID3D12Device* device, int num_frames_in_flight, DXGI_FO D3D12_CPU_DESCRIPTOR_HANDLE font_srv_cpu_desc_handle, D3D12_GPU_DESCRIPTOR_HANDLE font_srv_gpu_desc_handle) { ImGuiIO& io = ImGui::GetIO(); + IMGUI_CHECKVERSION(); IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!"); // Setup backend capabilities flags diff --git a/backends/imgui_impl_dx9.cpp b/backends/imgui_impl_dx9.cpp index 7e89bb964..3eff9ab5d 100644 --- a/backends/imgui_impl_dx9.cpp +++ b/backends/imgui_impl_dx9.cpp @@ -285,6 +285,7 @@ void ImGui_ImplDX9_RenderDrawData(ImDrawData* draw_data) bool ImGui_ImplDX9_Init(IDirect3DDevice9* device) { ImGuiIO& io = ImGui::GetIO(); + IMGUI_CHECKVERSION(); IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!"); // Setup backend capabilities flags diff --git a/backends/imgui_impl_glfw.cpp b/backends/imgui_impl_glfw.cpp index 4b4f61525..883917875 100644 --- a/backends/imgui_impl_glfw.cpp +++ b/backends/imgui_impl_glfw.cpp @@ -556,6 +556,7 @@ void ImGui_ImplGlfw_SetCallbacksChainForAllWindows(bool chain_for_all_windows) static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, GlfwClientApi client_api) { ImGuiIO& io = ImGui::GetIO(); + IMGUI_CHECKVERSION(); IM_ASSERT(io.BackendPlatformUserData == nullptr && "Already initialized a platform backend!"); //printf("GLFW_VERSION: %d.%d.%d (%d)", GLFW_VERSION_MAJOR, GLFW_VERSION_MINOR, GLFW_VERSION_REVISION, GLFW_VERSION_COMBINED); diff --git a/backends/imgui_impl_glut.cpp b/backends/imgui_impl_glut.cpp index 5dada3037..d8ffc9073 100644 --- a/backends/imgui_impl_glut.cpp +++ b/backends/imgui_impl_glut.cpp @@ -167,6 +167,7 @@ static ImGuiKey ImGui_ImplGLUT_KeyToImGuiKey(int key) bool ImGui_ImplGLUT_Init() { ImGuiIO& io = ImGui::GetIO(); + IMGUI_CHECKVERSION(); #ifdef FREEGLUT io.BackendPlatformName = "imgui_impl_glut (freeglut)"; diff --git a/backends/imgui_impl_metal.mm b/backends/imgui_impl_metal.mm index 29534d510..f9fd1087e 100644 --- a/backends/imgui_impl_metal.mm +++ b/backends/imgui_impl_metal.mm @@ -79,7 +79,6 @@ struct ImGui_ImplMetal_Data ImGui_ImplMetal_Data() { memset(this, 0, sizeof(*this)); } }; -static ImGui_ImplMetal_Data* ImGui_ImplMetal_CreateBackendData() { return IM_NEW(ImGui_ImplMetal_Data)(); } static ImGui_ImplMetal_Data* ImGui_ImplMetal_GetBackendData() { return ImGui::GetCurrentContext() ? (ImGui_ImplMetal_Data*)ImGui::GetIO().BackendRendererUserData : nullptr; } static void ImGui_ImplMetal_DestroyBackendData(){ IM_DELETE(ImGui_ImplMetal_GetBackendData()); } @@ -125,8 +124,11 @@ bool ImGui_ImplMetal_CreateDeviceObjects(MTL::Device* device) bool ImGui_ImplMetal_Init(id device) { - ImGui_ImplMetal_Data* bd = ImGui_ImplMetal_CreateBackendData(); ImGuiIO& io = ImGui::GetIO(); + IMGUI_CHECKVERSION(); + IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!"); + + ImGui_ImplMetal_Data* bd = IM_NEW(ImGui_ImplMetal_Data)(); io.BackendRendererUserData = (void*)bd; io.BackendRendererName = "imgui_impl_metal"; io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset; // We can honor the ImDrawCmd::VtxOffset field, allowing for large meshes. diff --git a/backends/imgui_impl_opengl2.cpp b/backends/imgui_impl_opengl2.cpp index 115aaac56..3eb092afd 100644 --- a/backends/imgui_impl_opengl2.cpp +++ b/backends/imgui_impl_opengl2.cpp @@ -83,6 +83,7 @@ static ImGui_ImplOpenGL2_Data* ImGui_ImplOpenGL2_GetBackendData() bool ImGui_ImplOpenGL2_Init() { ImGuiIO& io = ImGui::GetIO(); + IMGUI_CHECKVERSION(); IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!"); // Setup backend capabilities flags diff --git a/backends/imgui_impl_opengl3.cpp b/backends/imgui_impl_opengl3.cpp index 2d492f750..189371f36 100644 --- a/backends/imgui_impl_opengl3.cpp +++ b/backends/imgui_impl_opengl3.cpp @@ -275,6 +275,7 @@ struct ImGui_ImplOpenGL3_VtxAttribState bool ImGui_ImplOpenGL3_Init(const char* glsl_version) { ImGuiIO& io = ImGui::GetIO(); + IMGUI_CHECKVERSION(); IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!"); // Initialize our loader diff --git a/backends/imgui_impl_osx.mm b/backends/imgui_impl_osx.mm index 38b278203..322798022 100644 --- a/backends/imgui_impl_osx.mm +++ b/backends/imgui_impl_osx.mm @@ -84,7 +84,6 @@ struct ImGui_ImplOSX_Data ImGui_ImplOSX_Data() { memset(this, 0, sizeof(*this)); } }; -static ImGui_ImplOSX_Data* ImGui_ImplOSX_CreateBackendData() { return IM_NEW(ImGui_ImplOSX_Data)(); } static ImGui_ImplOSX_Data* ImGui_ImplOSX_GetBackendData() { return (ImGui_ImplOSX_Data*)ImGui::GetIO().BackendPlatformUserData; } static void ImGui_ImplOSX_DestroyBackendData() { IM_DELETE(ImGui_ImplOSX_GetBackendData()); } @@ -392,13 +391,15 @@ IMGUI_IMPL_API void ImGui_ImplOSX_NewFrame(void* _Nullable view) { bool ImGui_ImplOSX_Init(NSView* view) { ImGuiIO& io = ImGui::GetIO(); - ImGui_ImplOSX_Data* bd = ImGui_ImplOSX_CreateBackendData(); - io.BackendPlatformUserData = (void*)bd; + IMGUI_CHECKVERSION(); + IM_ASSERT(io.BackendPlatformUserData == nullptr && "Already initialized a platform backend!"); // Setup backend capabilities flags + ImGui_ImplOSX_Data* bd = IM_NEW(ImGui_ImplOSX_Data)(); + io.BackendPlatformUserData = (void*)bd; + io.BackendPlatformName = "imgui_impl_osx"; io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors; // We can honor GetMouseCursor() values (optional) //io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used) - io.BackendPlatformName = "imgui_impl_osx"; bd->Observer = [ImGuiObserver new]; diff --git a/backends/imgui_impl_sdl2.cpp b/backends/imgui_impl_sdl2.cpp index b7fe7645f..892fe9050 100644 --- a/backends/imgui_impl_sdl2.cpp +++ b/backends/imgui_impl_sdl2.cpp @@ -400,6 +400,7 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event) static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer) { ImGuiIO& io = ImGui::GetIO(); + IMGUI_CHECKVERSION(); IM_ASSERT(io.BackendPlatformUserData == nullptr && "Already initialized a platform backend!"); // Check and store if we are on a SDL backend that supports global mouse position diff --git a/backends/imgui_impl_sdl3.cpp b/backends/imgui_impl_sdl3.cpp index 3aee74a9b..1a5c78576 100644 --- a/backends/imgui_impl_sdl3.cpp +++ b/backends/imgui_impl_sdl3.cpp @@ -369,6 +369,7 @@ static void ImGui_ImplSDL3_SetupPlatformHandles(ImGuiViewport* viewport, SDL_Win static bool ImGui_ImplSDL3_Init(SDL_Window* window, SDL_Renderer* renderer, void* sdl_gl_context) { ImGuiIO& io = ImGui::GetIO(); + IMGUI_CHECKVERSION(); IM_ASSERT(io.BackendPlatformUserData == nullptr && "Already initialized a platform backend!"); IM_UNUSED(sdl_gl_context); // Unused in this branch diff --git a/backends/imgui_impl_sdlrenderer2.cpp b/backends/imgui_impl_sdlrenderer2.cpp index 49caa7d0a..bee874687 100644 --- a/backends/imgui_impl_sdlrenderer2.cpp +++ b/backends/imgui_impl_sdlrenderer2.cpp @@ -63,6 +63,7 @@ static ImGui_ImplSDLRenderer2_Data* ImGui_ImplSDLRenderer2_GetBackendData() bool ImGui_ImplSDLRenderer2_Init(SDL_Renderer* renderer) { ImGuiIO& io = ImGui::GetIO(); + IMGUI_CHECKVERSION(); IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!"); IM_ASSERT(renderer != nullptr && "SDL_Renderer not initialized!"); diff --git a/backends/imgui_impl_sdlrenderer3.cpp b/backends/imgui_impl_sdlrenderer3.cpp index 8cb3bb63b..2a86f859a 100644 --- a/backends/imgui_impl_sdlrenderer3.cpp +++ b/backends/imgui_impl_sdlrenderer3.cpp @@ -59,6 +59,7 @@ static ImGui_ImplSDLRenderer3_Data* ImGui_ImplSDLRenderer3_GetBackendData() bool ImGui_ImplSDLRenderer3_Init(SDL_Renderer* renderer) { ImGuiIO& io = ImGui::GetIO(); + IMGUI_CHECKVERSION(); IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!"); IM_ASSERT(renderer != nullptr && "SDL_Renderer not initialized!"); diff --git a/backends/imgui_impl_vulkan.cpp b/backends/imgui_impl_vulkan.cpp index 7d1c230c4..ad233f44e 100644 --- a/backends/imgui_impl_vulkan.cpp +++ b/backends/imgui_impl_vulkan.cpp @@ -1092,6 +1092,7 @@ bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info) } ImGuiIO& io = ImGui::GetIO(); + IMGUI_CHECKVERSION(); IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!"); // Setup backend capabilities flags diff --git a/backends/imgui_impl_wgpu.cpp b/backends/imgui_impl_wgpu.cpp index 7c6bc3b99..bf741e1a4 100644 --- a/backends/imgui_impl_wgpu.cpp +++ b/backends/imgui_impl_wgpu.cpp @@ -724,6 +724,7 @@ void ImGui_ImplWGPU_InvalidateDeviceObjects() bool ImGui_ImplWGPU_Init(ImGui_ImplWGPU_InitInfo* init_info) { ImGuiIO& io = ImGui::GetIO(); + IMGUI_CHECKVERSION(); IM_ASSERT(io.BackendRendererUserData == nullptr && "Already initialized a renderer backend!"); // Setup backend capabilities flags diff --git a/backends/imgui_impl_win32.cpp b/backends/imgui_impl_win32.cpp index bf852c539..248cf521c 100644 --- a/backends/imgui_impl_win32.cpp +++ b/backends/imgui_impl_win32.cpp @@ -146,6 +146,7 @@ static void ImGui_ImplWin32_UpdateKeyboardCodePage() static bool ImGui_ImplWin32_InitEx(void* hwnd, bool platform_has_own_dc) { ImGuiIO& io = ImGui::GetIO(); + IMGUI_CHECKVERSION(); IM_ASSERT(io.BackendPlatformUserData == nullptr && "Already initialized a platform backend!"); INT64 perf_frequency, perf_counter; diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 150dde530..60d605bb9 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -44,6 +44,9 @@ Breaking changes: Other changes: - Tables: fixed cell background of fully clipped row overlapping with header. (#7575, #7041) [@prabuinet] +- Backends: all backends + demo now call IMGUI_CHECKVERSION() to verify ABI compatibility between caller + code and compiled version of Dear ImGui. If you get an assert it most likely mean you have a build issue, + read comments near the assert. (#7568) ----------------------------------------------------------------------- diff --git a/imgui.cpp b/imgui.cpp index 604dac2b4..4704f89b2 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9639,8 +9639,8 @@ bool ImGui::Shortcut(ImGuiKeyChord key_chord, ImGuiID owner_id, ImGuiInputFlags // [SECTION] ERROR CHECKING //----------------------------------------------------------------------------- -// Helper function to verify ABI compatibility between caller code and compiled version of Dear ImGui. -// This is called by IMGUI_CHECKVERSION(). +// Verify ABI compatibility between caller code and compiled version of Dear ImGui. This helps detects some build issues. +// Called by IMGUI_CHECKVERSION(). // Verify that the type sizes are matching between the calling file's compilation unit and imgui.cpp's compilation unit // If this triggers you have mismatched headers and compiled code versions. // - It could be because of a build issue (using new headers with old compiled code) @@ -9653,12 +9653,12 @@ bool ImGui::DebugCheckVersionAndDataLayout(const char* version, size_t sz_io, si { bool error = false; if (strcmp(version, IMGUI_VERSION) != 0) { error = true; IM_ASSERT(strcmp(version, IMGUI_VERSION) == 0 && "Mismatched version string!"); } - if (sz_io != sizeof(ImGuiIO)) { error = true; IM_ASSERT(sz_io == sizeof(ImGuiIO) && "Mismatched struct layout!"); } + if (sz_io != sizeof(ImGuiIO)) { error = true; IM_ASSERT(sz_io == sizeof(ImGuiIO) && "Mismatched struct layout!"); } if (sz_style != sizeof(ImGuiStyle)) { error = true; IM_ASSERT(sz_style == sizeof(ImGuiStyle) && "Mismatched struct layout!"); } - if (sz_vec2 != sizeof(ImVec2)) { error = true; IM_ASSERT(sz_vec2 == sizeof(ImVec2) && "Mismatched struct layout!"); } - if (sz_vec4 != sizeof(ImVec4)) { error = true; IM_ASSERT(sz_vec4 == sizeof(ImVec4) && "Mismatched struct layout!"); } - if (sz_vert != sizeof(ImDrawVert)) { error = true; IM_ASSERT(sz_vert == sizeof(ImDrawVert) && "Mismatched struct layout!"); } - if (sz_idx != sizeof(ImDrawIdx)) { error = true; IM_ASSERT(sz_idx == sizeof(ImDrawIdx) && "Mismatched struct layout!"); } + if (sz_vec2 != sizeof(ImVec2)) { error = true; IM_ASSERT(sz_vec2 == sizeof(ImVec2) && "Mismatched struct layout!"); } + if (sz_vec4 != sizeof(ImVec4)) { error = true; IM_ASSERT(sz_vec4 == sizeof(ImVec4) && "Mismatched struct layout!"); } + if (sz_vert != sizeof(ImDrawVert)) { error = true; IM_ASSERT(sz_vert == sizeof(ImDrawVert) && "Mismatched struct layout!"); } + if (sz_idx != sizeof(ImDrawIdx)) { error = true; IM_ASSERT(sz_idx == sizeof(ImDrawIdx) && "Mismatched struct layout!"); } return !error; } diff --git a/imgui.h b/imgui.h index 38d589b77..e37fb202d 100644 --- a/imgui.h +++ b/imgui.h @@ -90,6 +90,8 @@ Index of this file: #endif #define IM_ARRAYSIZE(_ARR) ((int)(sizeof(_ARR) / sizeof(*(_ARR)))) // Size of a static C-style array. Don't use on pointers! #define IM_UNUSED(_VAR) ((void)(_VAR)) // Used to silence "unused variable warnings". Often useful as asserts may be stripped out from final builds. + +// Check that version and structures layouts are matching between compiled imgui code and caller. Read comments above DebugCheckVersionAndDataLayout() for details. #define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx)) // Helper Macros - IM_FMTARGS, IM_FMTLIST: Apply printf-style warnings to our formatting functions. diff --git a/imgui_demo.cpp b/imgui_demo.cpp index fc576c8b9..f144572b9 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -266,6 +266,9 @@ void ImGui::ShowDemoWindow(bool* p_open) // Most functions would normally just assert/crash if the context is missing. IM_ASSERT(ImGui::GetCurrentContext() != NULL && "Missing Dear ImGui context. Refer to examples app!"); + // Verify ABI compatibility between caller code and compiled version of Dear ImGui. This helps detects some build issues. + IMGUI_CHECKVERSION(); + // Examples Apps (accessible from the "Examples" menu) static bool show_app_main_menu_bar = false; static bool show_app_console = false; From d06b8b58d84562f1d1a8d8f975da96bf51ef5c5f Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 13 May 2024 15:25:11 +0200 Subject: [PATCH 04/10] Nav: fixed holding Ctrl or gamepad L1 from not slowing down keyboard/gamepad tweak speed. Broken by 8b8a61bd + Comments (#7570) --- docs/CHANGELOG.txt | 2 ++ imgui.h | 3 ++- imgui_widgets.cpp | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 60d605bb9..13a1a4d6c 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -43,6 +43,8 @@ Breaking changes: Other changes: +- Nav: fixed holding Ctrl or gamepad L1 from not slowing down keyboard/gamepad tweak speed. + Broken during a refactor refactor for 1.89. Holding Shift/R1 to speed up wasn't broken. - Tables: fixed cell background of fully clipped row overlapping with header. (#7575, #7041) [@prabuinet] - Backends: all backends + demo now call IMGUI_CHECKVERSION() to verify ABI compatibility between caller code and compiled version of Dear ImGui. If you get an assert it most likely mean you have a build issue, diff --git a/imgui.h b/imgui.h index e37fb202d..e2a7ffd62 100644 --- a/imgui.h +++ b/imgui.h @@ -699,7 +699,8 @@ namespace ImGui // Tooltips // - Tooltips are windows following the mouse. They do not take focus away. - // - A tooltip window can contain items of any types. SetTooltip() is a shortcut for the 'if (BeginTooltip()) { Text(...); EndTooltip(); }' idiom. + // - A tooltip window can contain items of any types. + // - SetTooltip() is more or less a shortcut for the 'if (BeginTooltip()) { Text(...); EndTooltip(); }' idiom (with a subtlety that it discard any previously submitted tooltip) IMGUI_API bool BeginTooltip(); // begin/append a tooltip window. IMGUI_API void EndTooltip(); // only call EndTooltip() if BeginTooltip()/BeginItemTooltip() returns true! IMGUI_API void SetTooltip(const char* fmt, ...) IM_FMTARGS(1); // set a text-only tooltip. Often used after a ImGui::IsItemHovered() check. Override any previous call to SetTooltip(). diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index db43f03f3..442f113e5 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -2309,7 +2309,7 @@ bool ImGui::DragBehaviorT(ImGuiDataType data_type, TYPE* v, float v_speed, const const int decimal_precision = is_floating_point ? ImParseFormatPrecision(format, 3) : 0; const bool tweak_slow = IsKeyDown((g.NavInputSource == ImGuiInputSource_Gamepad) ? ImGuiKey_NavGamepadTweakSlow : ImGuiKey_NavKeyboardTweakSlow); const bool tweak_fast = IsKeyDown((g.NavInputSource == ImGuiInputSource_Gamepad) ? ImGuiKey_NavGamepadTweakFast : ImGuiKey_NavKeyboardTweakFast); - const float tweak_factor = tweak_slow ? 1.0f / 1.0f : tweak_fast ? 10.0f : 1.0f; + const float tweak_factor = tweak_slow ? 1.0f / 10.0f : tweak_fast ? 10.0f : 1.0f; adjust_delta = GetNavTweakPressedAmount(axis) * tweak_factor; v_speed = ImMax(v_speed, GetMinimumStepAtDecimalPrecision(decimal_precision)); } From 0a5d40a0161d0b3d24222ac18f42bb02f1a4510e Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 14 May 2024 11:40:23 +0200 Subject: [PATCH 05/10] Update FAQ.md --- docs/FAQ.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/FAQ.md b/docs/FAQ.md index 7e9842cc4..095cb2aa2 100644 --- a/docs/FAQ.md +++ b/docs/FAQ.md @@ -23,7 +23,7 @@ or view this file with any Markdown viewer. | [I integrated Dear ImGui in my engine and some elements are clipping or disappearing when I move windows around...](#q-i-integrated-dear-imgui-in-my-engine-and-some-elements-are-clipping-or-disappearing-when-i-move-windows-around) | | [I integrated Dear ImGui in my engine and some elements are displaying outside their expected windows boundaries...](#q-i-integrated-dear-imgui-in-my-engine-and-some-elements-are-displaying-outside-their-expected-windows-boundaries) | | **Q&A: Usage** | -| **[About the ID Stack system..
Why is my widget not reacting when I click on it?
How can I have widgets with an empty label?
How can I have multiple widgets with the same label?
How can I have multiple windows with the same label?](#q-about-the-id-stack-system)** | +| **[About the ID Stack system..
Why is my widget not reacting when I click on it?
Why is the wrong widget reacting when I click on one?
How can I have widgets with an empty label?
How can I have multiple widgets with the same label?
How can I have multiple windows with the same label?](#q-about-the-id-stack-system)** | | [How can I display an image? What is ImTextureID, how does it work?](#q-how-can-i-display-an-image-what-is-imtextureid-how-does-it-work)| | [How can I use maths operators with ImVec2?](#q-how-can-i-use-maths-operators-with-imvec2) | | [How can I use my own maths types instead of ImVec2/ImVec4?](#q-how-can-i-use-my-own-maths-types-instead-of-imvec2imvec4) | @@ -199,6 +199,7 @@ ctx->RSSetScissorRects(1, &r); ### Q: About the ID Stack system... ### Q: Why is my widget not reacting when I click on it? +### Q: Why is the wrong widget reacting when I click on one? ### Q: How can I have widgets with an empty label? ### Q: How can I have multiple widgets with the same label? ### Q: How can I have multiple windows with the same label? From ac90e1bd5bdcc19d1c6d5f49f0c9839b2b984508 Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 14 May 2024 12:10:06 +0200 Subject: [PATCH 06/10] Backends: Win32: replace bd != nullptr assert with early out. (#6275) + fixed inconsistent use of break vs return 0 in WndProcHandler (had no tangible effect). --- backends/imgui_impl_win32.cpp | 13 ++++++------- docs/CHANGELOG.txt | 3 +++ imgui_widgets.cpp | 1 + 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/backends/imgui_impl_win32.cpp b/backends/imgui_impl_win32.cpp index 248cf521c..3e59b62e3 100644 --- a/backends/imgui_impl_win32.cpp +++ b/backends/imgui_impl_win32.cpp @@ -582,11 +582,10 @@ static ImGuiMouseSource GetMouseSourceFromMessageExtraInfo() IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { // Most backends don't have silent checks like this one, but we need it because WndProc are called early in CreateWindow(). - if (ImGui::GetCurrentContext() == nullptr) - return 0; - + // We silently allow both context or just only backend data to be nullptr. ImGui_ImplWin32_Data* bd = ImGui_ImplWin32_GetBackendData(); - IM_ASSERT(bd != nullptr && "Context or backend not initialized! Did you call ImGui_ImplWin32_Init()?"); + if (bd == nullptr) + return 0; ImGuiIO& io = ImGui::GetIO(); switch (msg) @@ -609,10 +608,10 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA } POINT mouse_pos = { (LONG)GET_X_LPARAM(lParam), (LONG)GET_Y_LPARAM(lParam) }; if (msg == WM_NCMOUSEMOVE && ::ScreenToClient(hwnd, &mouse_pos) == FALSE) // WM_NCMOUSEMOVE are provided in absolute coordinates. - break; + return 0; io.AddMouseSourceEvent(mouse_source); io.AddMousePosEvent((float)mouse_pos.x, (float)mouse_pos.y); - break; + return 0; } case WM_MOUSELEAVE: case WM_NCMOUSELEAVE: @@ -625,7 +624,7 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA bd->MouseTrackedArea = 0; io.AddMousePosEvent(-FLT_MAX, -FLT_MAX); } - break; + return 0; } case WM_LBUTTONDOWN: case WM_LBUTTONDBLCLK: case WM_RBUTTONDOWN: case WM_RBUTTONDBLCLK: diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 13a1a4d6c..4293ad78a 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -49,6 +49,9 @@ Other changes: - Backends: all backends + demo now call IMGUI_CHECKVERSION() to verify ABI compatibility between caller code and compiled version of Dear ImGui. If you get an assert it most likely mean you have a build issue, read comments near the assert. (#7568) +- Backends: Win32: undo an assert introduced in 1.90.6 which didn't allow WndProc + handler to be called before backend initialization. Because of how ::CreateWindow() + calls in WndProc this is facilitating. (#6275) [@MennoVink] ----------------------------------------------------------------------- diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 442f113e5..d12934262 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -4506,6 +4506,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ const bool is_cancel = Shortcut(ImGuiKey_Escape, id, f_repeat) || (nav_gamepad_active && Shortcut(ImGuiKey_NavGamepadCancel, id, f_repeat)); // FIXME: Should use more Shortcut() and reduce IsKeyPressed()+SetKeyOwner(), but requires modifiers combination to be taken account of. + // FIXME-OSX: Missing support for Alt(option)+Right/Left = go to end of line, or next line if already in end of line. if (IsKeyPressed(ImGuiKey_LeftArrow)) { state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINESTART : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDLEFT : STB_TEXTEDIT_K_LEFT) | k_mask); } else if (IsKeyPressed(ImGuiKey_RightArrow)) { state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINEEND : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDRIGHT : STB_TEXTEDIT_K_RIGHT) | k_mask); } else if (IsKeyPressed(ImGuiKey_UpArrow) && is_multiline) { if (io.KeyCtrl) SetScrollY(draw_window, ImMax(draw_window->Scroll.y - g.FontSize, 0.0f)); else state->OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_TEXTSTART : STB_TEXTEDIT_K_UP) | k_mask); } From f0912833ba92f7ee55582318d04935621995b68a Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 14 May 2024 14:09:46 +0200 Subject: [PATCH 07/10] Update FAQ.md (#7581) --- docs/FAQ.md | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/docs/FAQ.md b/docs/FAQ.md index 095cb2aa2..9c7df2334 100644 --- a/docs/FAQ.md +++ b/docs/FAQ.md @@ -204,6 +204,37 @@ ctx->RSSetScissorRects(1, &r); ### Q: How can I have multiple widgets with the same label? ### Q: How can I have multiple windows with the same label? +**USING THE SAME LABEL+ID IS THE MOST COMMON USER MISTAKE:** + + + + + +
+
+ImGui::Begin("Incorrect!");
+ImGui::DragFloat2("My value", &objects[0]->pos.x);
+ImGui::DragFloat2("My value", &objects[1]->pos.x);
+ImGui::DragFloat2("My value", &objects[2]->pos.x);
+ImGui::End();
+ 
+ImGui::Begin("Correct!");
+ImGui::DragFloat2("My value", &objects[0]->pos.x);
+ImGui::DragFloat2("My value##2", &objects[1]->pos.x);
+ImGui::DragFloat2("My value##3", &objects[2]->pos.x);
+ImGui::End();
+ 
+ImGui::Begin("Also Correct!");
+for (int n = 0; n < 3; n++)
+{
+    ImGui::PushID(n);
+    ImGui::DragFloat2("My value", &objects[n]->pos.x);
+    ImGui::PopID();
+}
+ImGui::End();
+
+
+ A primer on labels and the ID Stack... Dear ImGui internally needs to uniquely identify UI elements. From f806c76e97bbbd25e6e5ded3e761fde75689deb4 Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 14 May 2024 14:34:52 +0200 Subject: [PATCH 08/10] Tables, Dpi: added dummy g.DpiScale storage (to be altered in docking), using to scale tables border hit thickness. + Added note about how equivalent resize padding for windows (sourced from WINDOWS_HOVER_PADDING) would need further rework. --- imgui.cpp | 4 ++++ imgui_internal.h | 5 +++-- imgui_tables.cpp | 10 +++++----- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 4704f89b2..afb59acfe 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3811,6 +3811,7 @@ static void SetCurrentWindow(ImGuiWindow* window) ImGuiContext& g = *GImGui; g.CurrentWindow = window; g.CurrentTable = window && window->DC.CurrentTableIdx != -1 ? g.Tables.GetByIndex(window->DC.CurrentTableIdx) : NULL; + g.DpiScale = 1.0f; // FIXME-DPI: WIP this is modified in docking if (window) { g.FontSize = g.DrawListSharedData.FontSize = window->CalcFontSize(); @@ -4477,6 +4478,9 @@ void ImGui::UpdateHoveredWindowAndCaptureFlags() { ImGuiContext& g = *GImGui; ImGuiIO& io = g.IO; + + // FIXME-DPI: This storage was added on 2021/03/31 for test engine, but if we want to multiply WINDOWS_HOVER_PADDING + // by DpiScale, we need to make this window-agnostic anyhow, maybe need storing inside ImGuiWindow. g.WindowsHoverPadding = ImMax(g.Style.TouchExtraPadding, ImVec2(WINDOWS_HOVER_PADDING, WINDOWS_HOVER_PADDING)); // Find the window hovered by mouse: diff --git a/imgui_internal.h b/imgui_internal.h index 3ac6b2009..d96c8f86a 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1942,6 +1942,7 @@ struct ImGuiContext ImFont* Font; // (Shortcut) == FontStack.empty() ? IO.Font : FontStack.back() float FontSize; // (Shortcut) == FontBaseSize * g.CurrentWindow->FontWindowScale == window->FontSize(). Text height for current window. float FontBaseSize; // (Shortcut) == IO.FontGlobalScale * Font->Scale * Font->FontSize. Base text height. + float DpiScale; // Current window DpiScale ImDrawListSharedData DrawListSharedData; double Time; int FrameCount; @@ -1967,7 +1968,7 @@ struct ImGuiContext ImVector CurrentWindowStack; ImGuiStorage WindowsById; // Map window's ImGuiID to ImGuiWindow* int WindowsActiveCount; // Number of unique windows submitted by frame - ImVec2 WindowsHoverPadding; // Padding around resizable windows for which hovering on counts as hovering the window == ImMax(style.TouchExtraPadding, WINDOWS_HOVER_PADDING) + ImVec2 WindowsHoverPadding; // Padding around resizable windows for which hovering on counts as hovering the window == ImMax(style.TouchExtraPadding, WINDOWS_HOVER_PADDING). ImGuiID DebugBreakInWindow; // Set to break in Begin() call. ImGuiWindow* CurrentWindow; // Window being drawn into ImGuiWindow* HoveredWindow; // Window the mouse is hovering. Will typically catch mouse inputs. @@ -2268,7 +2269,7 @@ struct ImGuiContext Initialized = false; FontAtlasOwnedByContext = shared_font_atlas ? false : true; Font = NULL; - FontSize = FontBaseSize = 0.0f; + FontSize = FontBaseSize = DpiScale = 0.0f; IO.Fonts = shared_font_atlas ? shared_font_atlas : IM_NEW(ImFontAtlas)(); Time = 0.0f; FrameCount = 0; diff --git a/imgui_tables.cpp b/imgui_tables.cpp index d4a1fa3ac..f63b5c4c7 100644 --- a/imgui_tables.cpp +++ b/imgui_tables.cpp @@ -1256,7 +1256,7 @@ void ImGui::TableUpdateBorders(ImGuiTable* table) // really problematic (whereas the actual visual will be displayed in EndTable() and using the current frame height). // Actual columns highlight/render will be performed in EndTable() and not be affected. ImGuiTableInstanceData* table_instance = TableGetInstanceData(table, table->InstanceCurrent); - const float hit_half_width = TABLE_RESIZE_SEPARATOR_HALF_THICKNESS; + const float hit_half_width = ImTrunc(TABLE_RESIZE_SEPARATOR_HALF_THICKNESS * g.DpiScale); const float hit_y1 = (table->FreezeRowsCount >= 1 ? table->OuterRect.Min.y : table->WorkRect.Min.y) + table->AngledHeadersHeight; const float hit_y2_body = ImMax(table->OuterRect.Max.y, hit_y1 + table_instance->LastOuterHeight - table->AngledHeadersHeight); const float hit_y2_head = hit_y1 + table_instance->LastTopHeadersRowHeight; @@ -1433,7 +1433,7 @@ void ImGui::EndTable() if (table->ResizedColumn != -1 && table->InstanceCurrent == table->InstanceInteracted) { ImGuiTableColumn* column = &table->Columns[table->ResizedColumn]; - const float new_x2 = (g.IO.MousePos.x - g.ActiveIdClickOffset.x + TABLE_RESIZE_SEPARATOR_HALF_THICKNESS); + const float new_x2 = (g.IO.MousePos.x - g.ActiveIdClickOffset.x + ImTrunc(TABLE_RESIZE_SEPARATOR_HALF_THICKNESS * g.DpiScale)); const float new_width = ImTrunc(new_x2 - column->MinX - table->CellSpacingX1 - table->CellPaddingX * 2.0f); table->ResizedColumnNextWidth = new_width; } @@ -4041,7 +4041,7 @@ float ImGui::GetColumnNormFromOffset(const ImGuiOldColumns* columns, float offse return offset / (columns->OffMaxX - columns->OffMinX); } -static const float COLUMNS_HIT_RECT_HALF_WIDTH = 4.0f; +static const float COLUMNS_HIT_RECT_HALF_THICKNESS = 4.0f; static float GetDraggedColumnOffset(ImGuiOldColumns* columns, int column_index) { @@ -4052,7 +4052,7 @@ static float GetDraggedColumnOffset(ImGuiOldColumns* columns, int column_index) IM_ASSERT(column_index > 0); // We are not supposed to drag column 0. IM_ASSERT(g.ActiveId == columns->ID + ImGuiID(column_index)); - float x = g.IO.MousePos.x - g.ActiveIdClickOffset.x + COLUMNS_HIT_RECT_HALF_WIDTH - window->Pos.x; + float x = g.IO.MousePos.x - g.ActiveIdClickOffset.x + ImTrunc(COLUMNS_HIT_RECT_HALF_THICKNESS * g.DpiScale) - window->Pos.x; x = ImMax(x, ImGui::GetColumnOffset(column_index - 1) + g.Style.ColumnsMinSpacing); if ((columns->Flags & ImGuiOldColumnFlags_NoPreserveWidths)) x = ImMin(x, ImGui::GetColumnOffset(column_index + 1) - g.Style.ColumnsMinSpacing); @@ -4367,7 +4367,7 @@ void ImGui::EndColumns() ImGuiOldColumnData* column = &columns->Columns[n]; float x = window->Pos.x + GetColumnOffset(n); const ImGuiID column_id = columns->ID + ImGuiID(n); - const float column_hit_hw = COLUMNS_HIT_RECT_HALF_WIDTH; + const float column_hit_hw = ImTrunc(COLUMNS_HIT_RECT_HALF_THICKNESS * g.DpiScale); const ImRect column_hit_rect(ImVec2(x - column_hit_hw, y1), ImVec2(x + column_hit_hw, y2)); if (!ItemAdd(column_hit_rect, column_id, NULL, ImGuiItemFlags_NoNav)) continue; From d0524df88794e860405de6f5548f5a344a65abdb Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 14 May 2024 15:47:38 +0200 Subject: [PATCH 09/10] Internals: slight refactor FindHoveredWindow() -> FindHoveredWindowEx() toward reducing far-away code duplication. --- imgui.cpp | 41 ++++++++++++++++++++++++++--------------- imgui.h | 2 +- imgui_internal.h | 1 + 3 files changed, 28 insertions(+), 16 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index afb59acfe..f5bb7cb4d 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4488,7 +4488,7 @@ void ImGui::UpdateHoveredWindowAndCaptureFlags() // - When moving a window we can skip the search, which also conveniently bypasses the fact that window->WindowRectClipped is lagging as this point of the frame. // - We also support the moved window toggling the NoInputs flag after moving has started in order to be able to detect windows below it, which is useful for e.g. docking mechanisms. bool clear_hovered_windows = false; - FindHoveredWindow(); + FindHoveredWindowEx(g.IO.MousePos, false, &g.HoveredWindow, &g.HoveredWindowUnderMovingWindow); // Modal windows prevents mouse from hovering behind them. ImGuiWindow* modal_window = GetTopMostPopupModal(); @@ -5215,15 +5215,17 @@ ImVec2 ImGui::CalcTextSize(const char* text, const char* text_end, bool hide_tex } // Find window given position, search front-to-back -// FIXME: Note that we have an inconsequential lag here: OuterRectClipped is updated in Begin(), so windows moved programmatically -// with SetWindowPos() and not SetNextWindowPos() will have that rectangle lagging by a frame at the time FindHoveredWindow() is -// called, aka before the next Begin(). Moving window isn't affected. -static void FindHoveredWindow() +// - Typically write output back to g.HoveredWindow and g.HoveredWindowUnderMovingWindow. +// - FIXME: Note that we have an inconsequential lag here: OuterRectClipped is updated in Begin(), so windows moved programmatically +// with SetWindowPos() and not SetNextWindowPos() will have that rectangle lagging by a frame at the time FindHoveredWindow() is +// called, aka before the next Begin(). Moving window isn't affected. +// - The 'find_first_and_in_any_viewport = true' mode is only used by TestEngine. It is simpler to maintain here. +void ImGui::FindHoveredWindowEx(const ImVec2& pos, bool find_first_and_in_any_viewport, ImGuiWindow** out_hovered_window, ImGuiWindow** out_hovered_window_under_moving_window) { ImGuiContext& g = *GImGui; ImGuiWindow* hovered_window = NULL; - ImGuiWindow* hovered_window_ignoring_moving_window = NULL; + ImGuiWindow* hovered_window_under_moving_window = NULL; if (g.MovingWindow && !(g.MovingWindow->Flags & ImGuiWindowFlags_NoMouseInputs)) hovered_window = g.MovingWindow; @@ -5240,7 +5242,7 @@ static void FindHoveredWindow() // Using the clipped AABB, a child window will typically be clipped by its parent (not always) ImVec2 hit_padding = (window->Flags & (ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize)) ? padding_regular : padding_for_resize; - if (!window->OuterRectClipped.ContainsWithPad(g.IO.MousePos, hit_padding)) + if (!window->OuterRectClipped.ContainsWithPad(pos, hit_padding)) continue; // Support for one rectangular hole in any given window @@ -5249,21 +5251,30 @@ static void FindHoveredWindow() { ImVec2 hole_pos(window->Pos.x + (float)window->HitTestHoleOffset.x, window->Pos.y + (float)window->HitTestHoleOffset.y); ImVec2 hole_size((float)window->HitTestHoleSize.x, (float)window->HitTestHoleSize.y); - if (ImRect(hole_pos, hole_pos + hole_size).Contains(g.IO.MousePos)) + if (ImRect(hole_pos, hole_pos + hole_size).Contains(pos)) continue; } - if (hovered_window == NULL) + if (find_first_and_in_any_viewport) + { hovered_window = window; - IM_MSVC_WARNING_SUPPRESS(28182); // [Static Analyzer] Dereferencing NULL pointer. - if (hovered_window_ignoring_moving_window == NULL && (!g.MovingWindow || window->RootWindow != g.MovingWindow->RootWindow)) - hovered_window_ignoring_moving_window = window; - if (hovered_window && hovered_window_ignoring_moving_window) break; + } + else + { + if (hovered_window == NULL) + hovered_window = window; + IM_MSVC_WARNING_SUPPRESS(28182); // [Static Analyzer] Dereferencing NULL pointer. + if (hovered_window_under_moving_window == NULL && (!g.MovingWindow || window->RootWindow != g.MovingWindow->RootWindow)) + hovered_window_under_moving_window = window; + if (hovered_window && hovered_window_under_moving_window) + break; + } } - g.HoveredWindow = hovered_window; - g.HoveredWindowUnderMovingWindow = hovered_window_ignoring_moving_window; + *out_hovered_window = hovered_window; + if (out_hovered_window_under_moving_window != NULL) + *out_hovered_window_under_moving_window = hovered_window_under_moving_window; } bool ImGui::IsItemActive() diff --git a/imgui.h b/imgui.h index e2a7ffd62..b6fa23c1b 100644 --- a/imgui.h +++ b/imgui.h @@ -28,7 +28,7 @@ // Library Version // (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345') #define IMGUI_VERSION "1.90.7 WIP" -#define IMGUI_VERSION_NUM 19061 +#define IMGUI_VERSION_NUM 19062 #define IMGUI_HAS_TABLE /* diff --git a/imgui_internal.h b/imgui_internal.h index d96c8f86a..06224c529 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -3065,6 +3065,7 @@ namespace ImGui // NewFrame IMGUI_API void UpdateInputEvents(bool trickle_fast_inputs); IMGUI_API void UpdateHoveredWindowAndCaptureFlags(); + IMGUI_API void FindHoveredWindowEx(const ImVec2& pos, bool find_first_and_in_any_viewport, ImGuiWindow** out_hovered_window, ImGuiWindow** out_hovered_window_under_moving_window); IMGUI_API void StartMouseMovingWindow(ImGuiWindow* window); IMGUI_API void UpdateMouseMovingWindowNewFrame(); IMGUI_API void UpdateMouseMovingWindowEndFrame(); From e4576914cb9bcd6ed9067569a8818085b93fac0d Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 14 May 2024 16:17:13 +0200 Subject: [PATCH 10/10] Internals: amend f806c76 to better match docking + fixed unused static forward declaration warning. --- imgui.cpp | 7 +++---- imgui_internal.h | 4 ++-- imgui_tables.cpp | 8 ++++---- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index f5bb7cb4d..54978a2fc 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1077,7 +1077,6 @@ static const ImVec2 TOOLTIP_DEFAULT_OFFSET = ImVec2(16, 10); // Multi //------------------------------------------------------------------------- static void SetCurrentWindow(ImGuiWindow* window); -static void FindHoveredWindow(); static ImGuiWindow* CreateNewWindow(const char* name, ImGuiWindowFlags flags); static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window); @@ -3811,7 +3810,7 @@ static void SetCurrentWindow(ImGuiWindow* window) ImGuiContext& g = *GImGui; g.CurrentWindow = window; g.CurrentTable = window && window->DC.CurrentTableIdx != -1 ? g.Tables.GetByIndex(window->DC.CurrentTableIdx) : NULL; - g.DpiScale = 1.0f; // FIXME-DPI: WIP this is modified in docking + g.CurrentDpiScale = 1.0f; // FIXME-DPI: WIP this is modified in docking if (window) { g.FontSize = g.DrawListSharedData.FontSize = window->CalcFontSize(); @@ -5223,10 +5222,10 @@ ImVec2 ImGui::CalcTextSize(const char* text, const char* text_end, bool hide_tex void ImGui::FindHoveredWindowEx(const ImVec2& pos, bool find_first_and_in_any_viewport, ImGuiWindow** out_hovered_window, ImGuiWindow** out_hovered_window_under_moving_window) { ImGuiContext& g = *GImGui; - ImGuiWindow* hovered_window = NULL; ImGuiWindow* hovered_window_under_moving_window = NULL; - if (g.MovingWindow && !(g.MovingWindow->Flags & ImGuiWindowFlags_NoMouseInputs)) + + if (find_first_and_in_any_viewport == false && g.MovingWindow && !(g.MovingWindow->Flags & ImGuiWindowFlags_NoMouseInputs)) hovered_window = g.MovingWindow; ImVec2 padding_regular = g.Style.TouchExtraPadding; diff --git a/imgui_internal.h b/imgui_internal.h index 06224c529..af00d1bcc 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1942,7 +1942,7 @@ struct ImGuiContext ImFont* Font; // (Shortcut) == FontStack.empty() ? IO.Font : FontStack.back() float FontSize; // (Shortcut) == FontBaseSize * g.CurrentWindow->FontWindowScale == window->FontSize(). Text height for current window. float FontBaseSize; // (Shortcut) == IO.FontGlobalScale * Font->Scale * Font->FontSize. Base text height. - float DpiScale; // Current window DpiScale + float CurrentDpiScale; // Current window/viewport DpiScale ImDrawListSharedData DrawListSharedData; double Time; int FrameCount; @@ -2269,7 +2269,7 @@ struct ImGuiContext Initialized = false; FontAtlasOwnedByContext = shared_font_atlas ? false : true; Font = NULL; - FontSize = FontBaseSize = DpiScale = 0.0f; + FontSize = FontBaseSize = CurrentDpiScale = 0.0f; IO.Fonts = shared_font_atlas ? shared_font_atlas : IM_NEW(ImFontAtlas)(); Time = 0.0f; FrameCount = 0; diff --git a/imgui_tables.cpp b/imgui_tables.cpp index f63b5c4c7..4c0890be9 100644 --- a/imgui_tables.cpp +++ b/imgui_tables.cpp @@ -1256,7 +1256,7 @@ void ImGui::TableUpdateBorders(ImGuiTable* table) // really problematic (whereas the actual visual will be displayed in EndTable() and using the current frame height). // Actual columns highlight/render will be performed in EndTable() and not be affected. ImGuiTableInstanceData* table_instance = TableGetInstanceData(table, table->InstanceCurrent); - const float hit_half_width = ImTrunc(TABLE_RESIZE_SEPARATOR_HALF_THICKNESS * g.DpiScale); + const float hit_half_width = ImTrunc(TABLE_RESIZE_SEPARATOR_HALF_THICKNESS * g.CurrentDpiScale); const float hit_y1 = (table->FreezeRowsCount >= 1 ? table->OuterRect.Min.y : table->WorkRect.Min.y) + table->AngledHeadersHeight; const float hit_y2_body = ImMax(table->OuterRect.Max.y, hit_y1 + table_instance->LastOuterHeight - table->AngledHeadersHeight); const float hit_y2_head = hit_y1 + table_instance->LastTopHeadersRowHeight; @@ -1433,7 +1433,7 @@ void ImGui::EndTable() if (table->ResizedColumn != -1 && table->InstanceCurrent == table->InstanceInteracted) { ImGuiTableColumn* column = &table->Columns[table->ResizedColumn]; - const float new_x2 = (g.IO.MousePos.x - g.ActiveIdClickOffset.x + ImTrunc(TABLE_RESIZE_SEPARATOR_HALF_THICKNESS * g.DpiScale)); + const float new_x2 = (g.IO.MousePos.x - g.ActiveIdClickOffset.x + ImTrunc(TABLE_RESIZE_SEPARATOR_HALF_THICKNESS * g.CurrentDpiScale)); const float new_width = ImTrunc(new_x2 - column->MinX - table->CellSpacingX1 - table->CellPaddingX * 2.0f); table->ResizedColumnNextWidth = new_width; } @@ -4052,7 +4052,7 @@ static float GetDraggedColumnOffset(ImGuiOldColumns* columns, int column_index) IM_ASSERT(column_index > 0); // We are not supposed to drag column 0. IM_ASSERT(g.ActiveId == columns->ID + ImGuiID(column_index)); - float x = g.IO.MousePos.x - g.ActiveIdClickOffset.x + ImTrunc(COLUMNS_HIT_RECT_HALF_THICKNESS * g.DpiScale) - window->Pos.x; + float x = g.IO.MousePos.x - g.ActiveIdClickOffset.x + ImTrunc(COLUMNS_HIT_RECT_HALF_THICKNESS * g.CurrentDpiScale) - window->Pos.x; x = ImMax(x, ImGui::GetColumnOffset(column_index - 1) + g.Style.ColumnsMinSpacing); if ((columns->Flags & ImGuiOldColumnFlags_NoPreserveWidths)) x = ImMin(x, ImGui::GetColumnOffset(column_index + 1) - g.Style.ColumnsMinSpacing); @@ -4367,7 +4367,7 @@ void ImGui::EndColumns() ImGuiOldColumnData* column = &columns->Columns[n]; float x = window->Pos.x + GetColumnOffset(n); const ImGuiID column_id = columns->ID + ImGuiID(n); - const float column_hit_hw = ImTrunc(COLUMNS_HIT_RECT_HALF_THICKNESS * g.DpiScale); + const float column_hit_hw = ImTrunc(COLUMNS_HIT_RECT_HALF_THICKNESS * g.CurrentDpiScale); const ImRect column_hit_rect(ImVec2(x - column_hit_hw, y1), ImVec2(x + column_hit_hw, y2)); if (!ItemAdd(column_hit_rect, column_id, NULL, ImGuiItemFlags_NoNav)) continue;