From 07e8ff9a8d43754a2e78854ad78bfb6d0485b9d1 Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 18 Apr 2024 21:26:49 +0200 Subject: [PATCH 01/10] Backends: Win32: Fixed a warning + moved header cruft below Changelog. --- backends/imgui_impl_opengl3.h | 6 ++-- backends/imgui_impl_win32.cpp | 55 +++++++++++++++++++++++------------ 2 files changed, 39 insertions(+), 22 deletions(-) diff --git a/backends/imgui_impl_opengl3.h b/backends/imgui_impl_opengl3.h index 23eb9247..d66a15eb 100644 --- a/backends/imgui_impl_opengl3.h +++ b/backends/imgui_impl_opengl3.h @@ -41,9 +41,9 @@ IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyFontsTexture(); IMGUI_IMPL_API bool ImGui_ImplOpenGL3_CreateDeviceObjects(); IMGUI_IMPL_API void ImGui_ImplOpenGL3_DestroyDeviceObjects(); -// Specific OpenGL ES versions -//#define IMGUI_IMPL_OPENGL_ES2 // Auto-detected on Emscripten -//#define IMGUI_IMPL_OPENGL_ES3 // Auto-detected on iOS/Android +// Configuration flags to add in your imconfig file: +//#define IMGUI_IMPL_OPENGL_ES2 // Enable ES 2 (Auto-detected on Emscripten) +//#define IMGUI_IMPL_OPENGL_ES3 // Enable ES 3 (Auto-detected on iOS/Android) // You can explicitly select GLES2 or GLES3 API by using one of the '#define IMGUI_IMPL_OPENGL_LOADER_XXX' in imconfig.h or compiler command-line. #if !defined(IMGUI_IMPL_OPENGL_ES2) \ diff --git a/backends/imgui_impl_win32.cpp b/backends/imgui_impl_win32.cpp index 73ed700c..9d3e6364 100644 --- a/backends/imgui_impl_win32.cpp +++ b/backends/imgui_impl_win32.cpp @@ -16,27 +16,9 @@ // - Documentation https://dearimgui.com/docs (same as your local docs/ folder). // - Introduction, links and more at the top of imgui.cpp -#include "imgui.h" -#ifndef IMGUI_DISABLE -#include "imgui_impl_win32.h" -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif -#include -#include // GET_X_LPARAM(), GET_Y_LPARAM() -#include -#include - -// Configuration flags to add in your imconfig.h file: +// Configuration flags to add in your imconfig file: //#define IMGUI_IMPL_WIN32_DISABLE_GAMEPAD // Disable gamepad support. This was meaningful before <1.81 but we now load XInput dynamically so the option is now less relevant. -// Using XInput for gamepad (will load DLL dynamically) -#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD -#include -typedef DWORD (WINAPI *PFN_XInputGetCapabilities)(DWORD, DWORD, XINPUT_CAPABILITIES*); -typedef DWORD (WINAPI *PFN_XInputGetState)(DWORD, XINPUT_STATE*); -#endif - // CHANGELOG // (minor and older changes stripped away, please see git history for details) // 2023-10-05: Inputs: Added support for extra ImGuiKey values: F13 to F24 function keys, app back/forward keys. @@ -91,6 +73,34 @@ typedef DWORD (WINAPI *PFN_XInputGetState)(DWORD, XINPUT_STATE*); // 2017-10-23: Inputs: Using Win32 ::SetCapture/::GetCapture() to retrieve mouse positions outside the client area when dragging. // 2016-11-12: Inputs: Only call Win32 ::SetCursor(nullptr) when io.MouseDrawCursor is set. +#include "imgui.h" +#ifndef IMGUI_DISABLE +#include "imgui_impl_win32.h" +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif +#include +#include // GET_X_LPARAM(), GET_Y_LPARAM() +#include +#include + +// Using XInput for gamepad (will load DLL dynamically) +#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD +#include +typedef DWORD(WINAPI* PFN_XInputGetCapabilities)(DWORD, DWORD, XINPUT_CAPABILITIES*); +typedef DWORD(WINAPI* PFN_XInputGetState)(DWORD, XINPUT_STATE*); +#endif + +// Clang/GCC warnings with -Weverything +#if defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wcast-function-type" // warning: cast between incompatible function types (for loader) +#endif +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-function-type" // warning: cast between incompatible function types (for loader) +#endif + struct ImGui_ImplWin32_Data { HWND hWnd; @@ -900,4 +910,11 @@ void ImGui_ImplWin32_EnableAlphaCompositing(void* hwnd) //--------------------------------------------------------------------------------------------------------- +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif +#if defined(__clang__) +#pragma clang diagnostic pop +#endif + #endif // #ifndef IMGUI_DISABLE From b720c0f541c0d000df078433a59c0738c40df386 Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 19 Apr 2024 15:16:54 +0200 Subject: [PATCH 02/10] Backends: Vulkan: Added convenience support for Volk via IMGUI_IMPL_VULKAN_USE_VOLK define. (#6582, #4854) --- backends/imgui_impl_vulkan.cpp | 14 ++++++++------ backends/imgui_impl_vulkan.h | 11 +++++++++-- docs/CHANGELOG.txt | 4 ++++ examples/example_glfw_vulkan/main.cpp | 24 +++++++++++++++++------- examples/example_sdl2_vulkan/main.cpp | 24 +++++++++++++++++------- 5 files changed, 55 insertions(+), 22 deletions(-) diff --git a/backends/imgui_impl_vulkan.cpp b/backends/imgui_impl_vulkan.cpp index a8962ecd..52232901 100644 --- a/backends/imgui_impl_vulkan.cpp +++ b/backends/imgui_impl_vulkan.cpp @@ -33,6 +33,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2024-04-19: Vulkan: Added convenience support for Volk via IMGUI_IMPL_VULKAN_USE_VOLK define (you can also use IMGUI_IMPL_VULKAN_NO_PROTOTYPES + wrap Volk via ImGui_ImplVulkan_LoadFunctions().) // 2024-02-14: *BREAKING CHANGE*: Moved RenderPass parameter from ImGui_ImplVulkan_Init() function to ImGui_ImplVulkan_InitInfo structure. Not required when using dynamic rendering. // 2024-02-12: *BREAKING CHANGE*: Dynamic rendering now require filling PipelineRenderingCreateInfo structure. // 2024-01-19: Vulkan: Fixed vkAcquireNextImageKHR() validation errors in VulkanSDK 1.3.275 by allocating one extra semaphore than in-flight frames. (#7236) @@ -108,12 +109,13 @@ void ImGui_ImplVulkanH_CreateWindowCommandBuffers(VkPhysicalDevice physical_devi // Vulkan prototypes for use with custom loaders // (see description of IMGUI_IMPL_VULKAN_NO_PROTOTYPES in imgui_impl_vulkan.h -#ifdef VK_NO_PROTOTYPES +#if defined(VK_NO_PROTOTYPES) && !defined(VOLK_H_) +#define IMGUI_IMPL_VULKAN_USE_LOADER static bool g_FunctionsLoaded = false; #else static bool g_FunctionsLoaded = true; #endif -#ifdef VK_NO_PROTOTYPES +#ifdef IMGUI_IMPL_VULKAN_USE_LOADER #define IMGUI_VULKAN_FUNC_MAP(IMGUI_VULKAN_FUNC_MAP_MACRO) \ IMGUI_VULKAN_FUNC_MAP_MACRO(vkAllocateCommandBuffers) \ IMGUI_VULKAN_FUNC_MAP_MACRO(vkAllocateDescriptorSets) \ @@ -184,7 +186,7 @@ static bool g_FunctionsLoaded = true; #define IMGUI_VULKAN_FUNC_DEF(func) static PFN_##func func; IMGUI_VULKAN_FUNC_MAP(IMGUI_VULKAN_FUNC_DEF) #undef IMGUI_VULKAN_FUNC_DEF -#endif // VK_NO_PROTOTYPES +#endif // IMGUI_IMPL_VULKAN_USE_LOADER #ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING static PFN_vkCmdBeginRenderingKHR ImGuiImplVulkanFuncs_vkCmdBeginRenderingKHR; @@ -1048,8 +1050,8 @@ bool ImGui_ImplVulkan_LoadFunctions(PFN_vkVoidFunction(*loader_func)(const ch // Load function pointers // You can use the default Vulkan loader using: // ImGui_ImplVulkan_LoadFunctions([](const char* function_name, void*) { return vkGetInstanceProcAddr(your_vk_isntance, function_name); }); - // But this would be equivalent to not setting VK_NO_PROTOTYPES. -#ifdef VK_NO_PROTOTYPES + // But this would be roughly equivalent to not setting VK_NO_PROTOTYPES. +#ifdef IMGUI_IMPL_VULKAN_USE_LOADER #define IMGUI_VULKAN_FUNC_LOAD(func) \ func = reinterpret_cast(loader_func(#func, user_data)); \ if (func == nullptr) \ @@ -1078,7 +1080,7 @@ bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info) if (info->UseDynamicRendering) { #ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING -#ifndef VK_NO_PROTOTYPES +#ifndef IMGUI_IMPL_VULKAN_USE_LOADER ImGuiImplVulkanFuncs_vkCmdBeginRenderingKHR = reinterpret_cast(vkGetInstanceProcAddr(info->Instance, "vkCmdBeginRenderingKHR")); ImGuiImplVulkanFuncs_vkCmdEndRenderingKHR = reinterpret_cast(vkGetInstanceProcAddr(info->Instance, "vkCmdEndRenderingKHR")); #endif diff --git a/backends/imgui_impl_vulkan.h b/backends/imgui_impl_vulkan.h index f77fc235..c174a6ca 100644 --- a/backends/imgui_impl_vulkan.h +++ b/backends/imgui_impl_vulkan.h @@ -42,13 +42,20 @@ // If you have no idea what this is, leave it alone! //#define IMGUI_IMPL_VULKAN_NO_PROTOTYPES -// Vulkan includes +// Convenience support for Volk +// (you can also technically use IMGUI_IMPL_VULKAN_NO_PROTOTYPES + wrap Volk via ImGui_ImplVulkan_LoadFunctions().) +//#define IMGUI_IMPL_VULKAN_USE_VOLK + #if defined(IMGUI_IMPL_VULKAN_NO_PROTOTYPES) && !defined(VK_NO_PROTOTYPES) #define VK_NO_PROTOTYPES #endif #if defined(VK_USE_PLATFORM_WIN32_KHR) && !defined(NOMINMAX) #define NOMINMAX -#include +#endif + +// Vulkan includes +#ifdef IMGUI_IMPL_VULKAN_USE_VOLK +#include #else #include #endif diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 6c4102ec..8b2c372e 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -66,8 +66,12 @@ Other changes: mitigitate issues with reading vertex indexing limits with 16-bit indices. (#7496, #5720) - Backends: OpenGL: Detect ES3 contexts on desktop based on version string, to e.g. avoid calling glPolygonMode() on them. (#7447) [@afraidofdark, @ocornut] +- Backends: Vulkan: Added convenience support for Volk via IMGUI_IMPL_VULKAN_USE_VOLK define. + (you could always use IMGUI_IMPL_VULKAN_NO_PROTOTYPES + ImGui_ImplVulkan_LoadFunctions() as well). + (#6582, #4854) [@adalsteinnh, @kennyalive, @ocornut] - Backends: SDL3: Fixed text inputs. Re-enable calling SDL_StartTextInput()/SDL_StopTextInput() as SDL3 no longer enables it by default. (#7452, #6306, #6071, #1953) [@Green-Sky] +- Examples: GLFW+Vulkan, SDL+Vulkan: Added optional support for Volk. (#6582, #4854) - Examples: GLFW+WebGPU: Added support for WebGPU-native/Dawn (#7435, #7132) [@eliasdaler, @Zelif] - Examples: GLFW+WebGPU: Renamed example_emscripten_wgpu/ to example_glfw_wgpu/. (#7435, #7132) diff --git a/examples/example_glfw_vulkan/main.cpp b/examples/example_glfw_vulkan/main.cpp index b1c596dd..b6e53ed8 100644 --- a/examples/example_glfw_vulkan/main.cpp +++ b/examples/example_glfw_vulkan/main.cpp @@ -21,8 +21,12 @@ #define GLFW_INCLUDE_NONE #define GLFW_INCLUDE_VULKAN #include -#include -//#include + +// Volk headers +#ifdef IMGUI_IMPL_VULKAN_USE_VOLK +#define VOLK_IMPLEMENTATION +#include +#endif // [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. @@ -113,6 +117,9 @@ static VkPhysicalDevice SetupVulkan_SelectPhysicalDevice() static void SetupVulkan(ImVector instance_extensions) { VkResult err; +#ifdef IMGUI_IMPL_VULKAN_USE_VOLK + volkInitialize(); +#endif // Create Vulkan Instance { @@ -151,17 +158,20 @@ static void SetupVulkan(ImVector instance_extensions) create_info.ppEnabledExtensionNames = instance_extensions.Data; err = vkCreateInstance(&create_info, g_Allocator, &g_Instance); check_vk_result(err); +#ifdef IMGUI_IMPL_VULKAN_USE_VOLK + volkLoadInstance(g_Instance); +#endif // Setup the debug report callback #ifdef APP_USE_VULKAN_DEBUG_REPORT - auto vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkCreateDebugReportCallbackEXT"); - IM_ASSERT(vkCreateDebugReportCallbackEXT != nullptr); + auto f_vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkCreateDebugReportCallbackEXT"); + IM_ASSERT(f_vkCreateDebugReportCallbackEXT != nullptr); VkDebugReportCallbackCreateInfoEXT debug_report_ci = {}; debug_report_ci.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT; debug_report_ci.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT; debug_report_ci.pfnCallback = debug_report; debug_report_ci.pUserData = nullptr; - err = vkCreateDebugReportCallbackEXT(g_Instance, &debug_report_ci, g_Allocator, &g_DebugReport); + err = f_vkCreateDebugReportCallbackEXT(g_Instance, &debug_report_ci, g_Allocator, &g_DebugReport); check_vk_result(err); #endif } @@ -277,8 +287,8 @@ static void CleanupVulkan() #ifdef APP_USE_VULKAN_DEBUG_REPORT // Remove the debug report callback - auto vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkDestroyDebugReportCallbackEXT"); - vkDestroyDebugReportCallbackEXT(g_Instance, g_DebugReport, g_Allocator); + auto f_vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkDestroyDebugReportCallbackEXT"); + f_vkDestroyDebugReportCallbackEXT(g_Instance, g_DebugReport, g_Allocator); #endif // APP_USE_VULKAN_DEBUG_REPORT vkDestroyDevice(g_Device, g_Allocator); diff --git a/examples/example_sdl2_vulkan/main.cpp b/examples/example_sdl2_vulkan/main.cpp index 633f8bb8..df0db4d1 100644 --- a/examples/example_sdl2_vulkan/main.cpp +++ b/examples/example_sdl2_vulkan/main.cpp @@ -20,8 +20,12 @@ #include // abort #include #include -#include -//#include + +// Volk headers +#ifdef IMGUI_IMPL_VULKAN_USE_VOLK +#define VOLK_IMPLEMENTATION +#include +#endif //#define APP_USE_UNLIMITED_FRAME_RATE #ifdef _DEBUG @@ -101,6 +105,9 @@ static VkPhysicalDevice SetupVulkan_SelectPhysicalDevice() static void SetupVulkan(ImVector instance_extensions) { VkResult err; +#ifdef IMGUI_IMPL_VULKAN_USE_VOLK + volkInitialize(); +#endif // Create Vulkan Instance { @@ -139,17 +146,20 @@ static void SetupVulkan(ImVector instance_extensions) create_info.ppEnabledExtensionNames = instance_extensions.Data; err = vkCreateInstance(&create_info, g_Allocator, &g_Instance); check_vk_result(err); +#ifdef IMGUI_IMPL_VULKAN_USE_VOLK + volkLoadInstance(g_Instance); +#endif // Setup the debug report callback #ifdef APP_USE_VULKAN_DEBUG_REPORT - auto vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkCreateDebugReportCallbackEXT"); - IM_ASSERT(vkCreateDebugReportCallbackEXT != nullptr); + auto f_vkCreateDebugReportCallbackEXT = (PFN_vkCreateDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkCreateDebugReportCallbackEXT"); + IM_ASSERT(f_vkCreateDebugReportCallbackEXT != nullptr); VkDebugReportCallbackCreateInfoEXT debug_report_ci = {}; debug_report_ci.sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CALLBACK_CREATE_INFO_EXT; debug_report_ci.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT | VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT; debug_report_ci.pfnCallback = debug_report; debug_report_ci.pUserData = nullptr; - err = vkCreateDebugReportCallbackEXT(g_Instance, &debug_report_ci, g_Allocator, &g_DebugReport); + err = f_vkCreateDebugReportCallbackEXT(g_Instance, &debug_report_ci, g_Allocator, &g_DebugReport); check_vk_result(err); #endif } @@ -265,8 +275,8 @@ static void CleanupVulkan() #ifdef APP_USE_VULKAN_DEBUG_REPORT // Remove the debug report callback - auto vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkDestroyDebugReportCallbackEXT"); - vkDestroyDebugReportCallbackEXT(g_Instance, g_DebugReport, g_Allocator); + auto f_vkDestroyDebugReportCallbackEXT = (PFN_vkDestroyDebugReportCallbackEXT)vkGetInstanceProcAddr(g_Instance, "vkDestroyDebugReportCallbackEXT"); + f_vkDestroyDebugReportCallbackEXT(g_Instance, g_DebugReport, g_Allocator); #endif // APP_USE_VULKAN_DEBUG_REPORT vkDestroyDevice(g_Device, g_Allocator); From da18fcb7aed0380600b6177452b4496b4c8fac1c Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 23 Apr 2024 18:39:40 +0200 Subject: [PATCH 03/10] Internals: ensure ButtonBehavior() is called with non 0 id. --- imgui_widgets.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 8985dd9e..e1589824 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -509,7 +509,7 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool #ifdef IMGUI_ENABLE_TEST_ENGINE // Alternate registration spot, for when caller didn't use ItemAdd() - if (id != 0 && g.LastItemData.ID != id) + if (g.LastItemData.ID != id) IMGUI_TEST_ENGINE_ITEM_ADD(id, bb, NULL); #endif @@ -537,6 +537,8 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool const ImGuiID test_owner_id = (flags & ImGuiButtonFlags_NoTestKeyOwner) ? ImGuiKeyOwner_Any : id; if (hovered) { + IM_ASSERT(id != 0); // Lazily check inside rare path. + // Poll mouse buttons // - 'mouse_button_clicked' is generally carried into ActiveIdMouseButton when setting ActiveId. // - Technically we only need some values in one code path, but since this is gated by hovered test this is fine. From baaaaea9e916146da9cc1d62c403ddf8634f50c7 Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 24 Apr 2024 18:20:02 +0200 Subject: [PATCH 04/10] Demo: tweak TreeNode demo. --- imgui_demo.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index b4929f60..f5bb26ce 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -901,13 +901,18 @@ static void ShowDemoWindowWidgets() if (i == 0) ImGui::SetNextItemOpen(true, ImGuiCond_Once); - if (ImGui::TreeNode((void*)(intptr_t)i, "Child %d", i)) + // Here we use PushID() to generate a unique base ID, and then the "" used as TreeNode id won't conflict. + // An alternative to using 'PushID() + TreeNode("", ...)' to generate a unique ID is to use 'TreeNode((void*)(intptr_t)i, ...)', + // aka generate a dummy pointer-sized value to be hashed. The demo below uses that technique. Both are fine. + ImGui::PushID(i); + if (ImGui::TreeNode("", "Child %d", i)) { ImGui::Text("blah blah"); ImGui::SameLine(); if (ImGui::SmallButton("button")) {} ImGui::TreePop(); } + ImGui::PopID(); } ImGui::TreePop(); } From b8a44b198c992fe1f987d03dac7c7a72db730baa Mon Sep 17 00:00:00 2001 From: "diego.mateos" Date: Tue, 17 Oct 2023 12:21:21 +0200 Subject: [PATCH 05/10] TreeNode: added ImGuiTreeNodeFlags_SpanTextWidth. (#6937) --- docs/CHANGELOG.txt | 2 ++ imgui.h | 11 ++++++----- imgui_demo.cpp | 12 +++++++++++- imgui_widgets.cpp | 11 ++++++----- 4 files changed, 25 insertions(+), 11 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 8b2c372e..9f660b63 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -62,6 +62,8 @@ Other changes: - Fonts: Fixed font ascent and descent calculation when a font hits exact integer values. It is possible that some prior manual use of ImFontConfig::GlyphOffset may become duplicate with this fix. (#7399, #7404) [@GamingMinds-DanielC] +- TreeNode: Added ImGuiTreeNodeFlags_SpanTextWidth to make hitbox and highlight only + cover the label. (#6937) [@dimateos] - Text, DrawList: Improved handling of long single-line wrapped text. Faster and mitigitate issues with reading vertex indexing limits with 16-bit indices. (#7496, #5720) - Backends: OpenGL: Detect ES3 contexts on desktop based on version string, diff --git a/imgui.h b/imgui.h index 510a09de..a457083f 100644 --- a/imgui.h +++ b/imgui.h @@ -1102,11 +1102,12 @@ enum ImGuiTreeNodeFlags_ ImGuiTreeNodeFlags_Leaf = 1 << 8, // No collapsing, no arrow (use as a convenience for leaf nodes). ImGuiTreeNodeFlags_Bullet = 1 << 9, // Display a bullet instead of arrow. IMPORTANT: node can still be marked open/close if you don't set the _Leaf flag! ImGuiTreeNodeFlags_FramePadding = 1 << 10, // Use FramePadding (even for an unframed text node) to vertically align text baseline to regular widget height. Equivalent to calling AlignTextToFramePadding(). - ImGuiTreeNodeFlags_SpanAvailWidth = 1 << 11, // Extend hit box to the right-most edge, even if not framed. This is not the default in order to allow adding other items on the same line. In the future we may refactor the hit system to be front-to-back, allowing natural overlaps and then this can become the default. - ImGuiTreeNodeFlags_SpanFullWidth = 1 << 12, // Extend hit box to the left-most and right-most edges (bypass the indented area). - ImGuiTreeNodeFlags_SpanAllColumns = 1 << 13, // Frame will span all columns of its container table (text will still fit in current column) - ImGuiTreeNodeFlags_NavLeftJumpsBackHere = 1 << 14, // (WIP) Nav: left direction may move to this TreeNode() from any of its child (items submitted between TreeNode and TreePop) - //ImGuiTreeNodeFlags_NoScrollOnOpen = 1 << 15, // FIXME: TODO: Disable automatic scroll on TreePop() if node got just open and contents is not visible + ImGuiTreeNodeFlags_SpanAvailWidth = 1 << 11, // Extend hit box to the right-most edge, even if not framed. This is not the default in order to allow adding other items on the same line without using AllowOverlap mode. + ImGuiTreeNodeFlags_SpanFullWidth = 1 << 12, // Extend hit box to the left-most and right-most edges (cover the indent area). + ImGuiTreeNodeFlags_SpanTextWidth = 1 << 13, // Narrow hit box + narrow hovering highlight, will only cover the label text. + ImGuiTreeNodeFlags_SpanAllColumns = 1 << 14, // Frame will span all columns of its container table (text will still fit in current column) + ImGuiTreeNodeFlags_NavLeftJumpsBackHere = 1 << 15, // (WIP) Nav: left direction may move to this TreeNode() from any of its child (items submitted between TreeNode and TreePop) + //ImGuiTreeNodeFlags_NoScrollOnOpen = 1 << 16, // FIXME: TODO: Disable automatic scroll on TreePop() if node got just open and contents is not visible ImGuiTreeNodeFlags_CollapsingHeader = ImGuiTreeNodeFlags_Framed | ImGuiTreeNodeFlags_NoTreePushOnOpen | ImGuiTreeNodeFlags_NoAutoOpenOnLog, #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS diff --git a/imgui_demo.cpp b/imgui_demo.cpp index f5bb26ce..05175a67 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -930,7 +930,10 @@ static void ShowDemoWindowWidgets() ImGui::CheckboxFlags("ImGuiTreeNodeFlags_OpenOnDoubleClick", &base_flags, ImGuiTreeNodeFlags_OpenOnDoubleClick); ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanAvailWidth", &base_flags, ImGuiTreeNodeFlags_SpanAvailWidth); ImGui::SameLine(); HelpMarker("Extend hit area to all available width instead of allowing more items to be laid out after the node."); ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanFullWidth", &base_flags, ImGuiTreeNodeFlags_SpanFullWidth); + ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanTextWidth", &base_flags, ImGuiTreeNodeFlags_SpanTextWidth); ImGui::SameLine(); HelpMarker("Reduce hit area to the text label and a bit of margin."); ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanAllColumns", &base_flags, ImGuiTreeNodeFlags_SpanAllColumns); ImGui::SameLine(); HelpMarker("For use in Tables only."); + ImGui::CheckboxFlags("ImGuiTreeNodeFlags_AllowOverlap", &base_flags, ImGuiTreeNodeFlags_AllowOverlap); + ImGui::CheckboxFlags("ImGuiTreeNodeFlags_Framed", &base_flags, ImGuiTreeNodeFlags_Framed); ImGui::SameLine(); HelpMarker("Draw frame with background (e.g. for CollapsingHeader)"); ImGui::Checkbox("Align label with current X position", &align_label_with_current_x_position); ImGui::Checkbox("Test tree node as drag source", &test_drag_and_drop); ImGui::Text("Hello!"); @@ -963,6 +966,12 @@ static void ShowDemoWindowWidgets() ImGui::Text("This is a drag and drop source"); ImGui::EndDragDropSource(); } + if (i == 2) + { + // Item 2 has an additional inline button to help demonstrate SpanTextWidth. + ImGui::SameLine(); + if (ImGui::SmallButton("button")) {} + } if (node_open) { ImGui::BulletText("Blah blah\nBlah Blah"); @@ -5146,7 +5155,8 @@ static void ShowDemoWindowTables() static ImGuiTableFlags flags = ImGuiTableFlags_BordersV | ImGuiTableFlags_BordersOuterH | ImGuiTableFlags_Resizable | ImGuiTableFlags_RowBg | ImGuiTableFlags_NoBordersInBody; static ImGuiTreeNodeFlags tree_node_flags = ImGuiTreeNodeFlags_SpanAllColumns; - ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanFullWidth", &tree_node_flags, ImGuiTreeNodeFlags_SpanFullWidth); + ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanFullWidth", &tree_node_flags, ImGuiTreeNodeFlags_SpanFullWidth); + ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanTextWidth", &tree_node_flags, ImGuiTreeNodeFlags_SpanTextWidth); ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanAllColumns", &tree_node_flags, ImGuiTreeNodeFlags_SpanAllColumns); HelpMarker("See \"Columns flags\" section to configure how indentation is applied to individual columns."); diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index e1589824..a9abff70 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -6185,13 +6185,17 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l label_end = FindRenderedTextEnd(label); const ImVec2 label_size = CalcTextSize(label, label_end, false); + const float text_offset_x = g.FontSize + (display_frame ? padding.x * 3 : padding.x * 2); // Collapsing arrow width + Spacing + const float text_offset_y = ImMax(padding.y, window->DC.CurrLineTextBaseOffset); // Latch before ItemSize changes it + const float text_width = g.FontSize + label_size.x + padding.x * 2; // Include collapsing arrow + // We vertically grow up to current line height up the typical widget height. const float frame_height = ImMax(ImMin(window->DC.CurrLineSize.y, g.FontSize + style.FramePadding.y * 2), label_size.y + padding.y * 2); const bool span_all_columns = (flags & ImGuiTreeNodeFlags_SpanAllColumns) != 0 && (g.CurrentTable != NULL); ImRect frame_bb; frame_bb.Min.x = span_all_columns ? window->ParentWorkRect.Min.x : (flags & ImGuiTreeNodeFlags_SpanFullWidth) ? window->WorkRect.Min.x : window->DC.CursorPos.x; frame_bb.Min.y = window->DC.CursorPos.y; - frame_bb.Max.x = span_all_columns ? window->ParentWorkRect.Max.x : window->WorkRect.Max.x; + frame_bb.Max.x = span_all_columns ? window->ParentWorkRect.Max.x : (flags & ImGuiTreeNodeFlags_SpanTextWidth) ? window->DC.CursorPos.x + text_width + padding.x : window->WorkRect.Max.x; frame_bb.Max.y = window->DC.CursorPos.y + frame_height; if (display_frame) { @@ -6201,15 +6205,12 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l frame_bb.Max.x += IM_TRUNC(window->WindowPadding.x * 0.5f); } - const float text_offset_x = g.FontSize + (display_frame ? padding.x * 3 : padding.x * 2); // Collapsing arrow width + Spacing - const float text_offset_y = ImMax(padding.y, window->DC.CurrLineTextBaseOffset); // Latch before ItemSize changes it - const float text_width = g.FontSize + label_size.x + padding.x * 2; // Include collapsing arrow ImVec2 text_pos(window->DC.CursorPos.x + text_offset_x, window->DC.CursorPos.y + text_offset_y); ItemSize(ImVec2(text_width, frame_height), padding.y); // For regular tree nodes, we arbitrary allow to click past 2 worth of ItemSpacing ImRect interact_bb = frame_bb; - if (!display_frame && (flags & (ImGuiTreeNodeFlags_SpanAvailWidth | ImGuiTreeNodeFlags_SpanFullWidth | ImGuiTreeNodeFlags_SpanAllColumns)) == 0) + if ((flags & (ImGuiTreeNodeFlags_Framed | ImGuiTreeNodeFlags_SpanAvailWidth | ImGuiTreeNodeFlags_SpanFullWidth | ImGuiTreeNodeFlags_SpanTextWidth | ImGuiTreeNodeFlags_SpanAllColumns)) == 0) interact_bb.Max.x = frame_bb.Min.x + text_width + (label_size.x > 0.0f ? style.ItemSpacing.x * 2.0f : 0.0f); // Modify ClipRect for the ItemAdd(), faster than doing a PushColumnsBackground/PushTableBackgroundChannel for every Selectable.. From c895e987adf746a997b655c64a6a8916c549ff6f Mon Sep 17 00:00:00 2001 From: gan74 Date: Wed, 24 Apr 2024 19:32:36 +0200 Subject: [PATCH 06/10] ProgressBar: added indeterminate mode by passing an animated negative value. (#5316, #5370, #1901) --- docs/CHANGELOG.txt | 2 ++ imgui_demo.cpp | 5 +++++ imgui_widgets.cpp | 44 ++++++++++++++++++++++++++++++++------------ 3 files changed, 39 insertions(+), 12 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 9f660b63..8fc68842 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -64,6 +64,8 @@ Other changes: duplicate with this fix. (#7399, #7404) [@GamingMinds-DanielC] - TreeNode: Added ImGuiTreeNodeFlags_SpanTextWidth to make hitbox and highlight only cover the label. (#6937) [@dimateos] +- ProgressBar: Added support for indeterminate progress bar by passing an animated + negative fraction, e.g. ProgressBar(-1.0f * GetTime()). (#5316, #5370, #1901)[@gan74] - Text, DrawList: Improved handling of long single-line wrapped text. Faster and mitigitate issues with reading vertex indexing limits with 16-bit indices. (#7496, #5720) - Backends: OpenGL: Detect ES3 contexts on desktop based on version string, diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 05175a67..2a42dc1e 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1909,6 +1909,11 @@ static void ShowDemoWindowWidgets() char buf[32]; sprintf(buf, "%d/%d", (int)(progress_saturated * 1753), 1753); ImGui::ProgressBar(progress, ImVec2(0.f, 0.f), buf); + + ImGui::ProgressBar(-1.0f * (float)ImGui::GetTime(), ImVec2(0.0f, 0.0f), "Searching.."); + ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); + ImGui::Text("Indeterminate"); + ImGui::TreePop(); } diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index a9abff70..22435081 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -1291,27 +1291,47 @@ void ImGui::ProgressBar(float fraction, const ImVec2& size_arg, const char* over if (!ItemAdd(bb, 0)) return; + // Fraction < 0.0f will display an indeterminate progress bar animation + // The value must be animated along with time, so e.g. passing '-1.0f * ImGui::GetTime()' as fraction works. + const bool is_indeterminate = (fraction < 0.0f); + if (!is_indeterminate) + fraction = ImSaturate(fraction); + // Out of courtesy we accept a NaN fraction without crashing - fraction = ImSaturate(fraction); - const float fraction_not_nan = (fraction == fraction) ? fraction : 0.0f; + float fill_n0 = 0.0f; + float fill_n1 = (fraction == fraction) ? fraction : 0.0f; + + if (is_indeterminate) + { + const float fill_width_n = 0.2f; + fill_n0 = ImFmod(-fraction, 1.0f) * (1.0f + fill_width_n) - fill_width_n; + fill_n1 = ImSaturate(fill_n0 + fill_width_n); + fill_n0 = ImSaturate(fill_n0); + } // Render RenderFrame(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding); bb.Expand(ImVec2(-style.FrameBorderSize, -style.FrameBorderSize)); - const ImVec2 fill_br = ImVec2(ImLerp(bb.Min.x, bb.Max.x, fraction_not_nan), bb.Max.y); - RenderRectFilledRangeH(window->DrawList, bb, GetColorU32(ImGuiCol_PlotHistogram), 0.0f, fraction_not_nan, style.FrameRounding); + RenderRectFilledRangeH(window->DrawList, bb, GetColorU32(ImGuiCol_PlotHistogram), fill_n0, fill_n1, style.FrameRounding); // Default displaying the fraction as percentage string, but user can override it - char overlay_buf[32]; - if (!overlay) + // Don't display text for indeterminate bars by default + if (!is_indeterminate || overlay != NULL) { - ImFormatString(overlay_buf, IM_ARRAYSIZE(overlay_buf), "%.0f%%", fraction * 100 + 0.01f); - overlay = overlay_buf; - } + char overlay_buf[32]; + if (!overlay) + { + ImFormatString(overlay_buf, IM_ARRAYSIZE(overlay_buf), "%.0f%%", fraction * 100 + 0.01f); + overlay = overlay_buf; + } - ImVec2 overlay_size = CalcTextSize(overlay, NULL); - if (overlay_size.x > 0.0f) - RenderTextClipped(ImVec2(ImClamp(fill_br.x + style.ItemSpacing.x, bb.Min.x, bb.Max.x - overlay_size.x - style.ItemInnerSpacing.x), bb.Min.y), bb.Max, overlay, NULL, &overlay_size, ImVec2(0.0f, 0.5f), &bb); + ImVec2 overlay_size = CalcTextSize(overlay, NULL); + if (overlay_size.x > 0.0f) + { + float text_x = is_indeterminate ? (bb.Min.x + bb.Max.x - overlay_size.x) * 0.5f : ImLerp(bb.Min.x, bb.Max.x, fill_n1) + style.ItemSpacing.x; + RenderTextClipped(ImVec2(ImClamp(text_x, bb.Min.x, bb.Max.x - overlay_size.x - style.ItemInnerSpacing.x), bb.Min.y), bb.Max, overlay, NULL, &overlay_size, ImVec2(0.0f, 0.5f), &bb); + } + } } void ImGui::Bullet() From 913151caa8905370229e361486b10c890aeaed45 Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 24 Apr 2024 19:39:03 +0200 Subject: [PATCH 07/10] Demo: move progress bars to their own section. --- imgui_demo.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 2a42dc1e..e7f52688 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1835,7 +1835,6 @@ static void ShowDemoWindowWidgets() ImGui::Checkbox("Animate", &animate); // Plot as lines and plot as histogram - IMGUI_DEMO_MARKER("Widgets/Plotting/PlotLines, PlotHistogram"); static float arr[] = { 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f }; ImGui::PlotLines("Frame Times", arr, IM_ARRAYSIZE(arr)); ImGui::PlotHistogram("Histogram", arr, IM_ARRAYSIZE(arr), 0, NULL, 0.0f, 1.0f, ImVec2(0, 80.0f)); @@ -1889,15 +1888,17 @@ static void ShowDemoWindowWidgets() ImGui::PlotHistogram("Histogram", func, NULL, display_count, 0, NULL, -1.0f, 1.0f, ImVec2(0, 80)); ImGui::Separator(); + ImGui::TreePop(); + } + + IMGUI_DEMO_MARKER("Widgets/Progress Bars"); + if (ImGui::TreeNode("Progress Bars")) + { // Animate a simple progress bar - IMGUI_DEMO_MARKER("Widgets/Plotting/ProgressBar"); static float progress = 0.0f, progress_dir = 1.0f; - if (animate) - { - progress += progress_dir * 0.4f * ImGui::GetIO().DeltaTime; - if (progress >= +1.1f) { progress = +1.1f; progress_dir *= -1.0f; } - if (progress <= -0.1f) { progress = -0.1f; progress_dir *= -1.0f; } - } + progress += progress_dir * 0.4f * ImGui::GetIO().DeltaTime; + if (progress >= +1.1f) { progress = +1.1f; progress_dir *= -1.0f; } + if (progress <= -0.1f) { progress = -0.1f; progress_dir *= -1.0f; } // Typically we would use ImVec2(-1.0f,0.0f) or ImVec2(-FLT_MIN,0.0f) to use all available width, // or ImVec2(width,0.0f) for a specified width. ImVec2(0.0f,0.0f) uses ItemWidth. @@ -1910,6 +1911,8 @@ static void ShowDemoWindowWidgets() sprintf(buf, "%d/%d", (int)(progress_saturated * 1753), 1753); ImGui::ProgressBar(progress, ImVec2(0.f, 0.f), buf); + // Pass an animated negative value, e.g. -1.0f * (float)ImGui::GetTime() is the recommended value. + // Adjust the factor if you want to adjust the animation speed. ImGui::ProgressBar(-1.0f * (float)ImGui::GetTime(), ImVec2(0.0f, 0.0f), "Searching.."); ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); ImGui::Text("Indeterminate"); From a60387a3c25c18d223494873c7429d965691ea7f Mon Sep 17 00:00:00 2001 From: Lukas Lipp <15105596+fknfilewalker@users.noreply.github.com> Date: Mon, 29 Apr 2024 19:24:17 +0200 Subject: [PATCH 08/10] Backends: GLFW: Add define guards for glfw native defines. (#7536) --- backends/imgui_impl_glfw.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/backends/imgui_impl_glfw.cpp b/backends/imgui_impl_glfw.cpp index a968fe30..13d5dd73 100644 --- a/backends/imgui_impl_glfw.cpp +++ b/backends/imgui_impl_glfw.cpp @@ -85,11 +85,15 @@ #ifdef _WIN32 #undef APIENTRY +#ifndef GLFW_EXPOSE_NATIVE_WIN32 #define GLFW_EXPOSE_NATIVE_WIN32 +#endif #include // for glfwGetWin32Window() #endif #ifdef __APPLE__ +#ifndef GLFW_EXPOSE_NATIVE_COCOA #define GLFW_EXPOSE_NATIVE_COCOA +#endif #include // for glfwGetCocoaWindow() #endif From 6ef4f67fa94ec978f4bbeb28312a8bc988e86ff3 Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 30 Apr 2024 10:00:46 +0200 Subject: [PATCH 09/10] ImDrawList: moved cold fields lower in the structure so hot fields are closer to each others + better packed ImGuiNavItemData --- imgui.h | 6 +++--- imgui_internal.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/imgui.h b/imgui.h index a457083f..229ed338 100644 --- a/imgui.h +++ b/imgui.h @@ -2723,15 +2723,15 @@ struct ImDrawList // [Internal, used while building lists] unsigned int _VtxCurrentIdx; // [Internal] generally == VtxBuffer.Size unless we are past 64K vertices, in which case this gets reset to 0. ImDrawListSharedData* _Data; // Pointer to shared draw data (you can use ImGui::GetDrawListSharedData() to get the one from current ImGui context) - const char* _OwnerName; // Pointer to owner window's name for debugging ImDrawVert* _VtxWritePtr; // [Internal] point within VtxBuffer.Data after each add command (to avoid using the ImVector<> operators too much) ImDrawIdx* _IdxWritePtr; // [Internal] point within IdxBuffer.Data after each add command (to avoid using the ImVector<> operators too much) - ImVector _ClipRectStack; // [Internal] - ImVector _TextureIdStack; // [Internal] ImVector _Path; // [Internal] current path building ImDrawCmdHeader _CmdHeader; // [Internal] template of active commands. Fields should match those of CmdBuffer.back(). ImDrawListSplitter _Splitter; // [Internal] for channels api (note: prefer using your own persistent instance of ImDrawListSplitter!) + ImVector _ClipRectStack; // [Internal] + ImVector _TextureIdStack; // [Internal] float _FringeScale; // [Internal] anti-alias fringe is scaled by this value, this helps to keep things sharp while zooming at vertex buffer content + const char* _OwnerName; // Pointer to owner window's name for debugging // If you want to create ImDrawList instances, pass them ImGui::GetDrawListSharedData() or create and use your own ImDrawListSharedData (so you can use ImDrawList without ImGui) ImDrawList(ImDrawListSharedData* shared_data) { memset(this, 0, sizeof(*this)); _Data = shared_data; } diff --git a/imgui_internal.h b/imgui_internal.h index 7c9a9924..5ac8d23f 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -126,7 +126,7 @@ struct ImDrawListSharedData; // Data shared between all ImDrawList instan struct ImGuiColorMod; // Stacked color modifier, backup of modified data so we can restore it struct ImGuiContext; // Main Dear ImGui context struct ImGuiContextHook; // Hook for extensions like ImGuiTestEngine -struct ImGuiDataVarInfo; // Variable information (e.g. to avoid style variables from an enum) +struct ImGuiDataVarInfo; // Variable information (e.g. to access style variables from an enum) struct ImGuiDataTypeInfo; // Type information associated to a ImGuiDataType enum struct ImGuiGroupData; // Stacked storage data for BeginGroup()/EndGroup() struct ImGuiInputTextState; // Internal state of the currently focused/edited text input box @@ -1598,10 +1598,10 @@ struct ImGuiNavItemData ImGuiID FocusScopeId; // Init,Move // Best candidate focus scope ID ImRect RectRel; // Init,Move // Best candidate bounding box in window relative space ImGuiItemFlags InFlags; // ????,Move // Best candidate item flags - ImGuiSelectionUserData SelectionUserData;//I+Mov // Best candidate SetNextItemSelectionData() value. float DistBox; // Move // Best candidate box distance to current NavId float DistCenter; // Move // Best candidate center distance to current NavId float DistAxial; // Move // Best candidate axial distance to current NavId + ImGuiSelectionUserData SelectionUserData;//I+Mov // Best candidate SetNextItemSelectionData() value. ImGuiNavItemData() { Clear(); } void Clear() { Window = NULL; ID = FocusScopeId = 0; InFlags = 0; SelectionUserData = -1; DistBox = DistCenter = DistAxial = FLT_MAX; } From 50b2ff0bf039aac26210a184113bfb116b43e7af Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 30 Apr 2024 10:23:03 +0200 Subject: [PATCH 10/10] ImGuiIO: moved IMGUI_DISABLE_OBSOLETE_KEYIO block lower in the structure so other fields layout are not affected by it (#7534) This is essentially a misleading grace feature allowing a build mistake to be made, as we technically are more flexible now. BUT if we reintroduce a need we may more harshly move it to the top of the structure to detect issues. --- imgui.cpp | 14 ++++++++------ imgui.h | 22 +++++++++++----------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 181d846e..a2a05569 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -9570,13 +9570,15 @@ bool ImGui::Shortcut(ImGuiKeyChord key_chord, ImGuiID owner_id, ImGuiInputFlags //----------------------------------------------------------------------------- // Helper function to verify ABI compatibility between caller code and compiled version of Dear ImGui. +// This is 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 an issue: -// - Most commonly: mismatched headers and compiled code version. -// - Or: mismatched configuration #define, compilation settings, packing pragma etc. -// The configuration settings mentioned in imconfig.h must be set for all compilation units involved with Dear ImGui, -// which is way it is required you put them in your imconfig file (and not just before including imgui.h). -// Otherwise it is possible that different compilation units would see different structure layout +// 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) +// - It could be because of mismatched configuration #define, compilation settings, packing pragma etc. +// THE CONFIGURATION SETTINGS MENTIONED IN imconfig.h MUST BE SET FOR ALL COMPILATION UNITS INVOLVED WITH DEAR IMGUI. +// Which is why it is required you put them in your imconfig file (and NOT only before including imgui.h). +// Otherwise it is possible that different compilation units would see different structure layout. +// If you don't want to modify imconfig.h you can use the IMGUI_USER_CONFIG define to change filename. bool ImGui::DebugCheckVersionAndDataLayout(const char* version, size_t sz_io, size_t sz_style, size_t sz_vec2, size_t sz_vec4, size_t sz_vert, size_t sz_idx) { bool error = false; diff --git a/imgui.h b/imgui.h index 229ed338..de499085 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.6 WIP" -#define IMGUI_VERSION_NUM 19052 +#define IMGUI_VERSION_NUM 19053 #define IMGUI_HAS_TABLE /* @@ -2199,16 +2199,6 @@ struct ImGuiIO int MetricsActiveWindows; // Number of active windows ImVec2 MouseDelta; // Mouse delta. Note that this is zero if either current or previous position are invalid (-FLT_MAX,-FLT_MAX), so a disappearing/reappearing mouse won't have a huge delta. - // Legacy: before 1.87, we required backend to fill io.KeyMap[] (imgui->native map) during initialization and io.KeysDown[] (native indices) every frame. - // This is still temporarily supported as a legacy feature. However the new preferred scheme is for backend to call io.AddKeyEvent(). - // Old (<1.87): ImGui::IsKeyPressed(ImGui::GetIO().KeyMap[ImGuiKey_Space]) --> New (1.87+) ImGui::IsKeyPressed(ImGuiKey_Space) -#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO - int KeyMap[ImGuiKey_COUNT]; // [LEGACY] Input: map of indices into the KeysDown[512] entries array which represent your "native" keyboard state. The first 512 are now unused and should be kept zero. Legacy backend will write into KeyMap[] using ImGuiKey_ indices which are always >512. - bool KeysDown[ImGuiKey_COUNT]; // [LEGACY] Input: Keyboard keys that are pressed (ideally left in the "native" order your engine has access to keyboard keys, so you can use your own defines/enums for keys). This used to be [512] sized. It is now ImGuiKey_COUNT to allow legacy io.KeysDown[GetKeyIndex(...)] to work without an overflow. - float NavInputs[ImGuiNavInput_COUNT]; // [LEGACY] Since 1.88, NavInputs[] was removed. Backends from 1.60 to 1.86 won't build. Feed gamepad inputs via io.AddKeyEvent() and ImGuiKey_GamepadXXX enums. - //void* ImeWindowHandle; // [Obsoleted in 1.87] Set ImGuiViewport::PlatformHandleRaw instead. Set this to your HWND to get automatic IME cursor positioning. -#endif - //------------------------------------------------------------------ // [Internal] Dear ImGui will maintain those fields. Forward compatibility not guaranteed! //------------------------------------------------------------------ @@ -2254,6 +2244,16 @@ struct ImGuiIO ImWchar16 InputQueueSurrogate; // For AddInputCharacterUTF16() ImVector InputQueueCharacters; // Queue of _characters_ input (obtained by platform backend). Fill using AddInputCharacter() helper. + // Legacy: before 1.87, we required backend to fill io.KeyMap[] (imgui->native map) during initialization and io.KeysDown[] (native indices) every frame. + // This is still temporarily supported as a legacy feature. However the new preferred scheme is for backend to call io.AddKeyEvent(). + // Old (<1.87): ImGui::IsKeyPressed(ImGui::GetIO().KeyMap[ImGuiKey_Space]) --> New (1.87+) ImGui::IsKeyPressed(ImGuiKey_Space) +#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO + int KeyMap[ImGuiKey_COUNT]; // [LEGACY] Input: map of indices into the KeysDown[512] entries array which represent your "native" keyboard state. The first 512 are now unused and should be kept zero. Legacy backend will write into KeyMap[] using ImGuiKey_ indices which are always >512. + bool KeysDown[ImGuiKey_COUNT]; // [LEGACY] Input: Keyboard keys that are pressed (ideally left in the "native" order your engine has access to keyboard keys, so you can use your own defines/enums for keys). This used to be [512] sized. It is now ImGuiKey_COUNT to allow legacy io.KeysDown[GetKeyIndex(...)] to work without an overflow. + float NavInputs[ImGuiNavInput_COUNT]; // [LEGACY] Since 1.88, NavInputs[] was removed. Backends from 1.60 to 1.86 won't build. Feed gamepad inputs via io.AddKeyEvent() and ImGuiKey_GamepadXXX enums. + //void* ImeWindowHandle; // [Obsoleted in 1.87] Set ImGuiViewport::PlatformHandleRaw instead. Set this to your HWND to get automatic IME cursor positioning. +#endif + IMGUI_API ImGuiIO(); };