From f890d8538161ed005680a29ab99af26d1ae5c46f Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 7 Oct 2024 22:12:09 +0200 Subject: [PATCH 01/22] Backends: Fixed typo in comments from old wip work 'io.BackendRendererRenderState' -> 'platform_io.Renderer_RenderState'. (#6969, #5834, #7468, #3590 Amend e94f95d --- backends/imgui_impl_dx11.cpp | 2 +- backends/imgui_impl_dx11.h | 4 ++-- backends/imgui_impl_dx12.cpp | 2 +- backends/imgui_impl_dx12.h | 4 ++-- backends/imgui_impl_vulkan.cpp | 2 +- backends/imgui_impl_vulkan.h | 4 ++-- backends/imgui_impl_wgpu.cpp | 2 +- backends/imgui_impl_wgpu.h | 4 ++-- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/backends/imgui_impl_dx11.cpp b/backends/imgui_impl_dx11.cpp index 088e4b67e..16d480e08 100644 --- a/backends/imgui_impl_dx11.cpp +++ b/backends/imgui_impl_dx11.cpp @@ -4,7 +4,7 @@ // Implemented features: // [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID! // [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices. -// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)platform_io.BackendRendererRenderState'. +// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'. // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. diff --git a/backends/imgui_impl_dx11.h b/backends/imgui_impl_dx11.h index cb79633c3..57b19bc03 100644 --- a/backends/imgui_impl_dx11.h +++ b/backends/imgui_impl_dx11.h @@ -4,7 +4,7 @@ // Implemented features: // [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID! // [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices. -// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)platform_io.BackendRendererRenderState'. +// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'. // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. @@ -33,7 +33,7 @@ IMGUI_IMPL_API void ImGui_ImplDX11_InvalidateDeviceObjects(); IMGUI_IMPL_API bool ImGui_ImplDX11_CreateDeviceObjects(); // [BETA] Selected render state data shared with callbacks. -// This is temporarily stored in io.BackendRendererRenderState during the ImGui_ImplDX11_RenderDrawData() call. +// This is temporarily stored in GetPlatformIO().Renderer_RenderState during the ImGui_ImplDX11_RenderDrawData() call. // (Please open an issue if you feel you need access to more data) struct ImGui_ImplDX11_RenderState { diff --git a/backends/imgui_impl_dx12.cpp b/backends/imgui_impl_dx12.cpp index 85a870269..8dbb1e508 100644 --- a/backends/imgui_impl_dx12.cpp +++ b/backends/imgui_impl_dx12.cpp @@ -4,7 +4,7 @@ // Implemented features: // [X] Renderer: User texture binding. Use 'D3D12_GPU_DESCRIPTOR_HANDLE' as ImTextureID. Read the FAQ about ImTextureID! // [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices. -// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)platform_io.BackendRendererRenderState'. +// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'. // Important: to compile on 32-bit systems, this backend requires code to be compiled with '#define ImTextureID ImU64'. // This is because we need ImTextureID to carry a 64-bit value and by default ImTextureID is defined as void*. diff --git a/backends/imgui_impl_dx12.h b/backends/imgui_impl_dx12.h index bee7454fa..74001db40 100644 --- a/backends/imgui_impl_dx12.h +++ b/backends/imgui_impl_dx12.h @@ -4,7 +4,7 @@ // Implemented features: // [X] Renderer: User texture binding. Use 'D3D12_GPU_DESCRIPTOR_HANDLE' as ImTextureID. Read the FAQ about ImTextureID! // [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices. -// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)platform_io.BackendRendererRenderState'. +// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'. // Important: to compile on 32-bit systems, this backend requires code to be compiled with '#define ImTextureID ImU64'. // See imgui_impl_dx12.cpp file for details. @@ -44,7 +44,7 @@ IMGUI_IMPL_API void ImGui_ImplDX12_InvalidateDeviceObjects(); IMGUI_IMPL_API bool ImGui_ImplDX12_CreateDeviceObjects(); // [BETA] Selected render state data shared with callbacks. -// This is temporarily stored in io.BackendRendererRenderState during the ImGui_ImplDX12_RenderDrawData() call. +// This is temporarily stored in GetPlatformIO().Renderer_RenderState during the ImGui_ImplDX12_RenderDrawData() call. // (Please open an issue if you feel you need access to more data) struct ImGui_ImplDX12_RenderState { diff --git a/backends/imgui_impl_vulkan.cpp b/backends/imgui_impl_vulkan.cpp index 31a2516a6..d670b82a0 100644 --- a/backends/imgui_impl_vulkan.cpp +++ b/backends/imgui_impl_vulkan.cpp @@ -4,7 +4,7 @@ // Implemented features: // [!] Renderer: User texture binding. Use 'VkDescriptorSet' as ImTextureID. Read the FAQ about ImTextureID! See https://github.com/ocornut/imgui/pull/914 for discussions. // [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices. -// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)platform_io.BackendRendererRenderState'. +// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'. // Important: on 32-bit systems, user texture binding is only supported if your imconfig file has '#define ImTextureID ImU64'. // This is because we need ImTextureID to carry a 64-bit value and by default ImTextureID is defined as void*. diff --git a/backends/imgui_impl_vulkan.h b/backends/imgui_impl_vulkan.h index a834d7d7a..cdbcb0caa 100644 --- a/backends/imgui_impl_vulkan.h +++ b/backends/imgui_impl_vulkan.h @@ -4,7 +4,7 @@ // Implemented features: // [!] Renderer: User texture binding. Use 'VkDescriptorSet' as ImTextureID. Read the FAQ about ImTextureID! See https://github.com/ocornut/imgui/pull/914 for discussions. // [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices. -// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)platform_io.BackendRendererRenderState'. +// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'. // Important: on 32-bit systems, user texture binding is only supported if your imconfig file has '#define ImTextureID ImU64'. // See imgui_impl_vulkan.cpp file for details. @@ -119,7 +119,7 @@ IMGUI_IMPL_API void ImGui_ImplVulkan_RemoveTexture(VkDescriptorSet d IMGUI_IMPL_API bool ImGui_ImplVulkan_LoadFunctions(PFN_vkVoidFunction(*loader_func)(const char* function_name, void* user_data), void* user_data = nullptr); // [BETA] Selected render state data shared with callbacks. -// This is temporarily stored in io.BackendRendererRenderState during the ImGui_ImplVulkan_RenderDrawData() call. +// This is temporarily stored in GetPlatformIO().Renderer_RenderState during the ImGui_ImplVulkan_RenderDrawData() call. // (Please open an issue if you feel you need access to more data) struct ImGui_ImplVulkan_RenderState { diff --git a/backends/imgui_impl_wgpu.cpp b/backends/imgui_impl_wgpu.cpp index a4f6c03e5..95f1b0c63 100644 --- a/backends/imgui_impl_wgpu.cpp +++ b/backends/imgui_impl_wgpu.cpp @@ -5,7 +5,7 @@ // Implemented features: // [X] Renderer: User texture binding. Use 'WGPUTextureView' as ImTextureID. Read the FAQ about ImTextureID! // [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices. -// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)platform_io.BackendRendererRenderState'. +// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'. // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. diff --git a/backends/imgui_impl_wgpu.h b/backends/imgui_impl_wgpu.h index a171fd6d0..e4398575c 100644 --- a/backends/imgui_impl_wgpu.h +++ b/backends/imgui_impl_wgpu.h @@ -12,7 +12,7 @@ // Implemented features: // [X] Renderer: User texture binding. Use 'WGPUTextureView' as ImTextureID. Read the FAQ about ImTextureID! // [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices. -// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)platform_io.BackendRendererRenderState'. +// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'. // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. @@ -56,7 +56,7 @@ IMGUI_IMPL_API void ImGui_ImplWGPU_InvalidateDeviceObjects(); IMGUI_IMPL_API bool ImGui_ImplWGPU_CreateDeviceObjects(); // [BETA] Selected render state data shared with callbacks. -// This is temporarily stored in io.BackendRendererRenderState during the ImGui_ImplWGPU_RenderDrawData() call. +// This is temporarily stored in GetPlatformIO().Renderer_RenderState during the ImGui_ImplWGPU_RenderDrawData() call. // (Please open an issue if you feel you need access to more data) struct ImGui_ImplWGPU_RenderState { From 19b494df89fdba00e903fcd61734eb119ac98bb3 Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 8 Oct 2024 12:37:33 +0200 Subject: [PATCH 02/22] Examples: DirectX12: update Windows SDK version. (VS2015 doesn't support latest) --- .../example_win32_directx12/example_win32_directx12.vcxproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/example_win32_directx12/example_win32_directx12.vcxproj b/examples/example_win32_directx12/example_win32_directx12.vcxproj index 7b64371ef..62191839e 100644 --- a/examples/example_win32_directx12/example_win32_directx12.vcxproj +++ b/examples/example_win32_directx12/example_win32_directx12.vcxproj @@ -21,7 +21,7 @@ {b4cf9797-519d-4afe-a8f4-5141a6b521d3} example_win32_directx12 - 10.0.18362.0 + 10.0.20348.0 From 92b94980c69ff3d3d7f5dc30c1c19abfb72db47e Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 7 Oct 2024 16:45:34 +0200 Subject: [PATCH 03/22] (Breaking) Default ImTextureID to use a Im64 instead of void* (#1641) --- backends/imgui_impl_dx12.cpp | 16 -------- backends/imgui_impl_dx12.h | 3 -- backends/imgui_impl_vulkan.cpp | 8 ---- backends/imgui_impl_vulkan.h | 3 -- docs/CHANGELOG.txt | 16 +++++++- docs/FAQ.md | 39 ++++++++++--------- examples/example_glfw_vulkan/CMakeLists.txt | 2 +- examples/example_glfw_vulkan/build_win32.bat | 4 +- examples/example_glfw_vulkan/build_win64.bat | 4 +- .../example_glfw_vulkan.vcxproj | 8 ++-- examples/example_sdl2_vulkan/build_win32.bat | 2 +- .../example_sdl2_vulkan.vcxproj | 10 ++--- .../example_win32_directx12/build_win32.bat | 3 +- .../example_win32_directx12.vcxproj | 8 ++-- examples/example_win32_directx12/main.cpp | 4 -- imgui.cpp | 8 ++++ imgui.h | 4 +- imgui_draw.cpp | 4 +- imgui_widgets.cpp | 2 +- 19 files changed, 69 insertions(+), 79 deletions(-) diff --git a/backends/imgui_impl_dx12.cpp b/backends/imgui_impl_dx12.cpp index 8dbb1e508..e9345013c 100644 --- a/backends/imgui_impl_dx12.cpp +++ b/backends/imgui_impl_dx12.cpp @@ -6,14 +6,6 @@ // [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices. // [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'. -// Important: to compile on 32-bit systems, this backend requires code to be compiled with '#define ImTextureID ImU64'. -// This is because we need ImTextureID to carry a 64-bit value and by default ImTextureID is defined as void*. -// To build this on 32-bit systems: -// - [Solution 1] IDE/msbuild: in "Properties/C++/Preprocessor Definitions" add 'ImTextureID=ImU64' (this is what we do in the 'example_win32_direct12/example_win32_direct12.vcxproj' project file) -// - [Solution 2] IDE/msbuild: in "Properties/C++/Preprocessor Definitions" add 'IMGUI_USER_CONFIG="my_imgui_config.h"' and inside 'my_imgui_config.h' add '#define ImTextureID ImU64' and as many other options as you like. -// - [Solution 3] IDE/msbuild: edit imconfig.h and add '#define ImTextureID ImU64' (prefer solution 2 to create your own config file!) -// - [Solution 4] command-line: add '/D ImTextureID=ImU64' to your cl.exe command-line (this is what we do in the example_win32_direct12/build_win32.bat file) - // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. // Learn about Dear ImGui: @@ -446,14 +438,6 @@ static void ImGui_ImplDX12_CreateFontsTexture() } // Store our identifier - // READ THIS IF THE STATIC_ASSERT() TRIGGERS: - // - Important: to compile on 32-bit systems, this backend requires code to be compiled with '#define ImTextureID ImU64'. - // - This is because we need ImTextureID to carry a 64-bit value and by default ImTextureID is defined as void*. - // [Solution 1] IDE/msbuild: in "Properties/C++/Preprocessor Definitions" add 'ImTextureID=ImU64' (this is what we do in the 'example_win32_direct12/example_win32_direct12.vcxproj' project file) - // [Solution 2] IDE/msbuild: in "Properties/C++/Preprocessor Definitions" add 'IMGUI_USER_CONFIG="my_imgui_config.h"' and inside 'my_imgui_config.h' add '#define ImTextureID ImU64' and as many other options as you like. - // [Solution 3] IDE/msbuild: edit imconfig.h and add '#define ImTextureID ImU64' (prefer solution 2 to create your own config file!) - // [Solution 4] command-line: add '/D ImTextureID=ImU64' to your cl.exe command-line (this is what we do in the example_win32_direct12/build_win32.bat file) - static_assert(sizeof(ImTextureID) >= sizeof(bd->hFontSrvGpuDescHandle.ptr), "Can't pack descriptor handle into TexID, 32-bit not supported yet."); io.Fonts->SetTexID((ImTextureID)bd->hFontSrvGpuDescHandle.ptr); } diff --git a/backends/imgui_impl_dx12.h b/backends/imgui_impl_dx12.h index 74001db40..5da528573 100644 --- a/backends/imgui_impl_dx12.h +++ b/backends/imgui_impl_dx12.h @@ -6,9 +6,6 @@ // [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices. // [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'. -// Important: to compile on 32-bit systems, this backend requires code to be compiled with '#define ImTextureID ImU64'. -// See imgui_impl_dx12.cpp file for details. - // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. // Learn about Dear ImGui: diff --git a/backends/imgui_impl_vulkan.cpp b/backends/imgui_impl_vulkan.cpp index d670b82a0..78d838955 100644 --- a/backends/imgui_impl_vulkan.cpp +++ b/backends/imgui_impl_vulkan.cpp @@ -6,14 +6,6 @@ // [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices. // [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'. -// Important: on 32-bit systems, user texture binding is only supported if your imconfig file has '#define ImTextureID ImU64'. -// This is because we need ImTextureID to carry a 64-bit value and by default ImTextureID is defined as void*. -// To build this on 32-bit systems and support texture changes: -// - [Solution 1] IDE/msbuild: in "Properties/C++/Preprocessor Definitions" add 'ImTextureID=ImU64' (this is what we do in our .vcxproj files) -// - [Solution 2] IDE/msbuild: in "Properties/C++/Preprocessor Definitions" add 'IMGUI_USER_CONFIG="my_imgui_config.h"' and inside 'my_imgui_config.h' add '#define ImTextureID ImU64' and as many other options as you like. -// - [Solution 3] IDE/msbuild: edit imconfig.h and add '#define ImTextureID ImU64' (prefer solution 2 to create your own config file!) -// - [Solution 4] command-line: add '/D ImTextureID=ImU64' to your cl.exe command-line (this is what we do in our batch files) - // The aim of imgui_impl_vulkan.h/.cpp is to be usable in your engine without any modification. // IF YOU FEEL YOU NEED TO MAKE ANY CHANGE TO THIS CODE, please share them and your feedback at https://github.com/ocornut/imgui/ diff --git a/backends/imgui_impl_vulkan.h b/backends/imgui_impl_vulkan.h index cdbcb0caa..ca5b4db64 100644 --- a/backends/imgui_impl_vulkan.h +++ b/backends/imgui_impl_vulkan.h @@ -6,9 +6,6 @@ // [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices. // [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'. -// Important: on 32-bit systems, user texture binding is only supported if your imconfig file has '#define ImTextureID ImU64'. -// See imgui_impl_vulkan.cpp file for details. - // The aim of imgui_impl_vulkan.h/.cpp is to be usable in your engine without any modification. // IF YOU FEEL YOU NEED TO MAKE ANY CHANGE TO THIS CODE, please share them and your feedback at https://github.com/ocornut/imgui/ diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 48496340b..96a52ff40 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -36,11 +36,25 @@ HOW TO UPDATE? - Please report any issue! ----------------------------------------------------------------------- - VERSION 1.91.4 WIP + VERSION 1.91.4 WIP (In Progress) ----------------------------------------------------------------------- Breaking changes: +- The typedef for ImTextureID now defaults to ImU64 instead of void*. (#1641) + - This removes the requirement to redefine it for backends which are e.g. storing + descriptor sets or other 64-bits structures when building on 32-bits archs. + It therefore simplify various building scripts/helpers. + - You may have compile-time issues if you were casting to 'void*' instead of 'ImTextureID' + when passing your types to functions taking ImTextureID values, e.g. ImGui::Image(). + In doubt it is almost always better to do an intermediate intptr_t cast, since it + allows casting any pointer/integer type without warning: + - May warn: ImGui::Image((void*)MyTextureData, ...); + - May warn: ImGui::Image((void*)(intptr_t)MyTextureData, ...); + - Won't warn: ImGui::Image((ImTextureID)(intptr_t)MyTextureData), ...); + - Note that you can always define ImTextureID to be your own high-level structures + (with dedicated constructors) if you like. + Other changes: - IO: added 'void* platform_io.Renderer_RenderState' which is set during the diff --git a/docs/FAQ.md b/docs/FAQ.md index 4e2a42576..38600fe47 100644 --- a/docs/FAQ.md +++ b/docs/FAQ.md @@ -380,8 +380,9 @@ node open/closed state differently. See what makes more sense in your situation! Short explanation: - Refer to [Image Loading and Displaying Examples](https://github.com/ocornut/imgui/wiki/Image-Loading-and-Displaying-Examples) on the [Wiki](https://github.com/ocornut/imgui/wiki). - You may use functions such as `ImGui::Image()`, `ImGui::ImageButton()` or lower-level `ImDrawList::AddImage()` to emit draw calls that will use your own textures. -- Actual textures are identified in a way that is up to the user/engine. Those identifiers are stored and passed as ImTextureID (void*) value. -- Loading image files from the disk and turning them into a texture is not within the scope of Dear ImGui (for a good reason). +- Actual textures are identified in a way that is up to the user/engine. Those identifiers are stored and passed as an opaque ImTextureID value. +- By default ImTextureID can store up to 64-bits. You may `#define` it to a custom type/structure if you need. +- Loading image files from the disk and turning them into a texture is not within the scope of Dear ImGui (for a good reason), but the examples linked above may be useful references. **Please read documentations or tutorials on your graphics API to understand how to display textures on the screen before moving onward.** @@ -389,27 +390,27 @@ Long explanation: - Dear ImGui's job is to create "meshes", defined in a renderer-agnostic format made of draw commands and vertices. At the end of the frame, those meshes (ImDrawList) will be displayed by your rendering function. They are made up of textured polygons and the code to render them is generally fairly short (a few dozen lines). In the examples/ folder, we provide functions for popular graphics APIs (OpenGL, DirectX, etc.). - Each rendering function decides on a data type to represent "textures". The concept of what is a "texture" is entirely tied to your underlying engine/graphics API. We carry the information to identify a "texture" in the ImTextureID type. -ImTextureID is nothing more than a void*, aka 4/8 bytes worth of data: just enough to store one pointer or integer of your choice. +ImTextureID default to ImU64 aka 8 bytes worth of data: just enough to store one pointer or integer of your choice. Dear ImGui doesn't know or understand what you are storing in ImTextureID, it merely passes ImTextureID values until they reach your rendering function. - In the [examples/](https://github.com/ocornut/imgui/tree/master/examples) backends, for each graphics API we decided on a type that is likely to be a good representation for specifying an image from the end-user perspective. This is what the _examples_ rendering functions are using: ```cpp OpenGL: -- ImTextureID = GLuint +- ImTextureID should contains 'GLuint' (GL texture identifier). - See ImGui_ImplOpenGL3_RenderDrawData() function in imgui_impl_opengl3.cpp ``` ```cpp DirectX9: -- ImTextureID = LPDIRECT3DTEXTURE9 +- ImTextureID should contain a 'LPDIRECT3DTEXTURE9' (pointer). - See ImGui_ImplDX9_RenderDrawData() function in imgui_impl_dx9.cpp ``` ```cpp DirectX11: -- ImTextureID = ID3D11ShaderResourceView* +- ImTextureID should contain a 'ID3D11ShaderResourceView*' (poiter) - See ImGui_ImplDX11_RenderDrawData() function in imgui_impl_dx11.cpp ``` ```cpp DirectX12: -- ImTextureID = D3D12_GPU_DESCRIPTOR_HANDLE +- ImTextureID should contain a 'D3D12_GPU_DESCRIPTOR_HANDLE' (always 64-bits) - See ImGui_ImplDX12_RenderDrawData() function in imgui_impl_dx12.cpp ``` For example, in the OpenGL example backend we store raw OpenGL texture identifier (GLuint) inside ImTextureID. @@ -421,14 +422,14 @@ If you are starting with OpenGL or DirectX or Vulkan and haven't built much of a User code may do: ```cpp -// Cast our texture type to ImTextureID / void* +// Cast our texture type to ImTextureID MyTexture* texture = g_CoffeeTableTexture; -ImGui::Image((void*)texture, ImVec2(texture->Width, texture->Height)); +ImGui::Image((ImTextureID)(intptr_t)texture, ImVec2(texture->Width, texture->Height)); ``` The renderer function called after ImGui::Render() will receive that same value that the user code passed: ```cpp -// Cast ImTextureID / void* stored in the draw command as our texture type -MyTexture* texture = (MyTexture*)pcmd->GetTexID(); +// Cast ImTextureID stored in the draw command as our texture type +MyTexture* texture = (MyTexture*)(intptr_t)pcmd->GetTexID(); MyEngineBindTexture2D(texture); ``` Once you understand this design, you will understand that loading image files and turning them into displayable textures is not within the scope of Dear ImGui. @@ -437,19 +438,19 @@ If you want to display an image file (e.g. PNG file) on the screen, please refer Refer to [Image Loading and Displaying Examples](https://github.com/ocornut/imgui/wiki/Image-Loading-and-Displaying-Examples) on the [Wiki](https://github.com/ocornut/imgui/wiki) to find simplified examples for loading textures with OpenGL, DirectX9 and DirectX11. -C/C++ tip: a void* is pointer-sized storage. You may safely store any pointer or integer into it by casting your value to ImTextureID / void*, and vice-versa. -Because both end-points (user code and rendering function) are under your control, you know exactly what is stored inside the ImTextureID / void*. +C/C++ tip: a u64 is 8 bytes. You may safely store any pointer or integer into it by casting your value to ImTextureID, and vice-versa. +Because both end-points (user code and rendering function) are under your control, you know exactly what is stored inside the ImTextureID. Here are some examples: ```cpp GLuint my_tex = XXX; -void* my_void_ptr; -my_void_ptr = (void*)(intptr_t)my_tex; // cast a GLuint into a void* (we don't take its address! we literally store the value inside the pointer) -my_tex = (GLuint)(intptr_t)my_void_ptr; // cast a void* into a GLuint +ImTextureID my_imtexid; +my_imtexid = (ImTextureID)(intptr_t)my_tex; // cast a GLuint into a ImTextureID (we don't take its address! we just copy the address) +my_tex = (GLuint)(intptr_t)my_imtexid; // cast a ImTextureID into a GLuint ID3D11ShaderResourceView* my_dx11_srv = XXX; -void* my_void_ptr; -my_void_ptr = (void*)my_dx11_srv; // cast a ID3D11ShaderResourceView* into an opaque void* -my_dx11_srv = (ID3D11ShaderResourceView*)my_void_ptr; // cast a void* into a ID3D11ShaderResourceView* +ImTextureID my_imtexid; +my_imtexid = (ImTextureID)(intptr_t)my_dx11_srv; // cast a ID3D11ShaderResourceView* into an opaque ImTextureID +my_dx11_srv = (ID3D11ShaderResourceView*)(intptr_t)_my_imtexid; // cast a ImTextureID into a ID3D11ShaderResourceView* ``` Finally, you may call `ImGui::ShowMetricsWindow()` to explore/visualize/understand how the ImDrawList are generated. diff --git a/examples/example_glfw_vulkan/CMakeLists.txt b/examples/example_glfw_vulkan/CMakeLists.txt index a6e5bf910..443a144ea 100644 --- a/examples/example_glfw_vulkan/CMakeLists.txt +++ b/examples/example_glfw_vulkan/CMakeLists.txt @@ -42,4 +42,4 @@ file(GLOB sources *.cpp) add_executable(example_glfw_vulkan ${sources} ${IMGUI_DIR}/backends/imgui_impl_glfw.cpp ${IMGUI_DIR}/backends/imgui_impl_vulkan.cpp ${IMGUI_DIR}/imgui.cpp ${IMGUI_DIR}/imgui_draw.cpp ${IMGUI_DIR}/imgui_demo.cpp ${IMGUI_DIR}/imgui_tables.cpp ${IMGUI_DIR}/imgui_widgets.cpp) target_link_libraries(example_glfw_vulkan ${LIBRARIES}) -target_compile_definitions(example_glfw_vulkan PUBLIC -DImTextureID=ImU64) + diff --git a/examples/example_glfw_vulkan/build_win32.bat b/examples/example_glfw_vulkan/build_win32.bat index be9239816..bb54a4210 100644 --- a/examples/example_glfw_vulkan/build_win32.bat +++ b/examples/example_glfw_vulkan/build_win32.bat @@ -7,8 +7,8 @@ @set OUT_DIR=Debug mkdir %OUT_DIR% -cl /nologo /Zi /MD /utf-8 %INCLUDES% /D ImTextureID=ImU64 %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% +cl /nologo /Zi /MD /utf-8 %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% @set OUT_DIR=Release mkdir %OUT_DIR% -cl /nologo /Zi /MD /utf-8 /Ox /Oi %INCLUDES% /D ImTextureID=ImU64 %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% +cl /nologo /Zi /MD /utf-8 /Ox /Oi %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% diff --git a/examples/example_glfw_vulkan/build_win64.bat b/examples/example_glfw_vulkan/build_win64.bat index c60b02789..54e40e3e8 100644 --- a/examples/example_glfw_vulkan/build_win64.bat +++ b/examples/example_glfw_vulkan/build_win64.bat @@ -6,8 +6,8 @@ @set OUT_DIR=Debug mkdir %OUT_DIR% -cl /nologo /Zi /MD /utf-8 %INCLUDES% /D ImTextureID=ImU64 %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% +cl /nologo /Zi /MD /utf-8 %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% @set OUT_DIR=Release mkdir %OUT_DIR% -cl /nologo /Zi /MD /utf-8 /Ox /Oi %INCLUDES% /D ImTextureID=ImU64 %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% +cl /nologo /Zi /MD /utf-8 /Ox /Oi %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% diff --git a/examples/example_glfw_vulkan/example_glfw_vulkan.vcxproj b/examples/example_glfw_vulkan/example_glfw_vulkan.vcxproj index d0d1c5f88..a81d328df 100644 --- a/examples/example_glfw_vulkan/example_glfw_vulkan.vcxproj +++ b/examples/example_glfw_vulkan/example_glfw_vulkan.vcxproj @@ -91,7 +91,7 @@ Level4 Disabled ..\..;..\..\backends;%VULKAN_SDK%\include;..\libs\glfw\include;%(AdditionalIncludeDirectories) - ImTextureID=ImU64;_MBCS;%(PreprocessorDefinitions) + _MBCS;%(PreprocessorDefinitions) /utf-8 %(AdditionalOptions) @@ -107,7 +107,7 @@ Level4 Disabled ..\..;..\..\backends;%VULKAN_SDK%\include;..\libs\glfw\include;%(AdditionalIncludeDirectories) - ImTextureID=ImU64;_MBCS;%(PreprocessorDefinitions) + _MBCS;%(PreprocessorDefinitions) /utf-8 %(AdditionalOptions) @@ -126,7 +126,7 @@ true ..\..;..\..\backends;%VULKAN_SDK%\include;..\libs\glfw\include;%(AdditionalIncludeDirectories) false - ImTextureID=ImU64;_MBCS;%(PreprocessorDefinitions) + _MBCS;%(PreprocessorDefinitions) /utf-8 %(AdditionalOptions) @@ -148,7 +148,7 @@ true ..\..;..\..\backends;%VULKAN_SDK%\include;..\libs\glfw\include;%(AdditionalIncludeDirectories) false - ImTextureID=ImU64;_MBCS;%(PreprocessorDefinitions) + _MBCS;%(PreprocessorDefinitions) /utf-8 %(AdditionalOptions) diff --git a/examples/example_sdl2_vulkan/build_win32.bat b/examples/example_sdl2_vulkan/build_win32.bat index 8a4aefc22..977a2c7e4 100644 --- a/examples/example_sdl2_vulkan/build_win32.bat +++ b/examples/example_sdl2_vulkan/build_win32.bat @@ -7,4 +7,4 @@ @set OUT_DIR=Debug mkdir %OUT_DIR% -cl /nologo /Zi /MD /utf-8 %INCLUDES% /D ImTextureID=ImU64 %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% /subsystem:console +cl /nologo /Zi /MD /utf-8 %INCLUDES% %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% /subsystem:console diff --git a/examples/example_sdl2_vulkan/example_sdl2_vulkan.vcxproj b/examples/example_sdl2_vulkan/example_sdl2_vulkan.vcxproj index ba6afaf72..bcf99a46c 100644 --- a/examples/example_sdl2_vulkan/example_sdl2_vulkan.vcxproj +++ b/examples/example_sdl2_vulkan/example_sdl2_vulkan.vcxproj @@ -91,7 +91,7 @@ Level4 Disabled ..\..;..\..\backends;%VULKAN_SDK%\include;%SDL2_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL2;%(AdditionalIncludeDirectories) - ImTextureID=ImU64;_MBCS;%(PreprocessorDefinitions) + _MBCS;%(PreprocessorDefinitions) /utf-8 %(AdditionalOptions) @@ -107,7 +107,7 @@ Level4 Disabled ..\..;..\..\backends;%VULKAN_SDK%\include;%SDL2_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL2;%(AdditionalIncludeDirectories) - ImTextureID=ImU64;_MBCS;%(PreprocessorDefinitions) + _MBCS;%(PreprocessorDefinitions) /utf-8 %(AdditionalOptions) @@ -126,7 +126,7 @@ true ..\..;..\..\backends;%VULKAN_SDK%\include;%SDL2_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL2;%(AdditionalIncludeDirectories) false - ImTextureID=ImU64;_MBCS;%(PreprocessorDefinitions) + _MBCS;%(PreprocessorDefinitions) /utf-8 %(AdditionalOptions) @@ -148,7 +148,7 @@ true ..\..;..\..\backends;%VULKAN_SDK%\include;%SDL2_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL2;%(AdditionalIncludeDirectories) false - ImTextureID=ImU64;_MBCS;%(PreprocessorDefinitions) + _MBCS;%(PreprocessorDefinitions) /utf-8 %(AdditionalOptions) @@ -187,4 +187,4 @@ - \ No newline at end of file + diff --git a/examples/example_win32_directx12/build_win32.bat b/examples/example_win32_directx12/build_win32.bat index 68e3c921e..cb5e8e273 100644 --- a/examples/example_win32_directx12/build_win32.bat +++ b/examples/example_win32_directx12/build_win32.bat @@ -1,9 +1,8 @@ @REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler. -@REM Important: to build on 32-bit systems, the DX12 backends needs '#define ImTextureID ImU64', so we pass it here. @set OUT_DIR=Debug @set OUT_EXE=example_win32_directx12 @set INCLUDES=/I..\.. /I..\..\backends /I "%WindowsSdkDir%Include\um" /I "%WindowsSdkDir%Include\shared" @set SOURCES=main.cpp ..\..\backends\imgui_impl_dx12.cpp ..\..\backends\imgui_impl_win32.cpp ..\..\imgui*.cpp @set LIBS=d3d12.lib d3dcompiler.lib dxgi.lib mkdir Debug -cl /nologo /Zi /MD /utf-8 %INCLUDES% /D ImTextureID=ImU64 /D UNICODE /D _UNICODE %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% +cl /nologo /Zi /MD /utf-8 %INCLUDES% /D UNICODE /D _UNICODE %SOURCES% /Fe%OUT_DIR%/%OUT_EXE%.exe /Fo%OUT_DIR%/ /link %LIBS% diff --git a/examples/example_win32_directx12/example_win32_directx12.vcxproj b/examples/example_win32_directx12/example_win32_directx12.vcxproj index 62191839e..bb98c4141 100644 --- a/examples/example_win32_directx12/example_win32_directx12.vcxproj +++ b/examples/example_win32_directx12/example_win32_directx12.vcxproj @@ -87,7 +87,7 @@ Level4 Disabled ..\..;..\..\backends;%(AdditionalIncludeDirectories) - ImTextureID=ImU64;_UNICODE;UNICODE;%(PreprocessorDefinitions) + _UNICODE;UNICODE;%(PreprocessorDefinitions) /utf-8 %(AdditionalOptions) @@ -102,7 +102,7 @@ Level4 Disabled ..\..;..\..\backends;%(AdditionalIncludeDirectories) - ImTextureID=ImU64;_UNICODE;UNICODE;%(PreprocessorDefinitions) + _UNICODE;UNICODE;%(PreprocessorDefinitions) /utf-8 %(AdditionalOptions) @@ -119,7 +119,7 @@ true true ..\..;..\..\backends;%(AdditionalIncludeDirectories) - ImTextureID=ImU64;_UNICODE;UNICODE;%(PreprocessorDefinitions) + _UNICODE;UNICODE;%(PreprocessorDefinitions) /utf-8 %(AdditionalOptions) @@ -138,7 +138,7 @@ true true ..\..;..\..\backends;%(AdditionalIncludeDirectories) - ImTextureID=ImU64;_UNICODE;UNICODE;%(PreprocessorDefinitions) + _UNICODE;UNICODE;%(PreprocessorDefinitions) /utf-8 %(AdditionalOptions) diff --git a/examples/example_win32_directx12/main.cpp b/examples/example_win32_directx12/main.cpp index 57a481c71..4173a8010 100644 --- a/examples/example_win32_directx12/main.cpp +++ b/examples/example_win32_directx12/main.cpp @@ -6,10 +6,6 @@ // - Documentation https://dearimgui.com/docs (same as your local docs/ folder). // - Introduction, links and more at the top of imgui.cpp -// Important: to compile on 32-bit systems, the DirectX12 backend requires code to be compiled with '#define ImTextureID ImU64'. -// This is because we need ImTextureID to carry a 64-bit value and by default ImTextureID is defined as void*. -// This define is set in the example .vcxproj file and need to be replicated in your app or by adding it to your imconfig.h file. - #include "imgui.h" #include "imgui_impl_win32.h" #include "imgui_impl_dx12.h" diff --git a/imgui.cpp b/imgui.cpp index 2d7edc43e..33170e430 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -430,6 +430,14 @@ CODE When you are not sure about an old symbol or function name, try using the Search/Find function of your IDE to look for comments or references in all imgui files. You can read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2024/10/10 (1.91.4) - the typedef for ImTextureID now defaults to ImU64 instead of void*. (#1641) + this removes the requirement to redefine it for backends which are e.g. storing descriptor sets or other 64-bits structures when building on 32-bits archs. It therefore simplify various building scripts/helpers. + you may have compile-time issues if you were casting to 'void*' instead of 'ImTextureID' when passing your types to functions taking ImTextureID values, e.g. ImGui::Image(). + in doubt it is almost always better to do an intermediate intptr_t cast, since it allows casting any pointer/integer type without warning: + - May warn: ImGui::Image((void*)MyTextureData, ...); + - May warn: ImGui::Image((void*)(intptr_t)MyTextureData, ...); + - Won't warn: ImGui::Image((ImTextureID)(intptr_t)MyTextureData), ...); + - note that you can always define ImTextureID to be your own high-level structures (with dedicated constructors) if you like. - 2024/10/03 (1.91.3) - drags: treat v_min==v_max as a valid clamping range when != 0.0f. Zero is a still special value due to legacy reasons, unless using ImGuiSliderFlags_ClampZeroRange. (#7968, #3361, #76) - drags: extended behavior of ImGuiSliderFlags_AlwaysClamp to include _ClampZeroRange. It considers v_min==v_max==0.0f as a valid clamping range (aka edits not allowed). although unlikely, it you wish to only clamp on text input but want v_min==v_max==0.0f to mean unclamped drags, you can use _ClampOnInput instead of _AlwaysClamp. (#7968, #3361, #76) diff --git a/imgui.h b/imgui.h index f3d5d83d4..87d77c2c2 100644 --- a/imgui.h +++ b/imgui.h @@ -249,8 +249,10 @@ typedef int ImGuiWindowFlags; // -> enum ImGuiWindowFlags_ // Flags: f // ImTexture: user data for renderer backend to identify a texture [Compile-time configurable type] // - To use something else than an opaque void* pointer: override with e.g. '#define ImTextureID MyTextureType*' in your imconfig.h file. // - This can be whatever to you want it to be! read the FAQ about ImTextureID for details. +// - You can make this a structure with various constructors if you need. You will have to implement ==/!= operators. +// - (note: before v1.91.4 (2024/10/08) the default type for ImTextureID was void*. Use intermediary intptr_t cast and read FAQ if you have casting warnings) #ifndef ImTextureID -typedef void* ImTextureID; // Default: store a pointer or an integer fitting in a pointer (most renderer backends are ok with that) +typedef ImU64 ImTextureID; // Default: store a pointer or an integer fitting in a pointer (most renderer backends are ok with that) #endif // ImDrawIdx: vertex index. [Compile-time configurable type] diff --git a/imgui_draw.cpp b/imgui_draw.cpp index b69bc789f..0c10a79b7 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -619,7 +619,7 @@ void ImDrawList::PushTextureID(ImTextureID texture_id) void ImDrawList::PopTextureID() { _TextureIdStack.pop_back(); - _CmdHeader.TextureId = (_TextureIdStack.Size == 0) ? (ImTextureID)NULL : _TextureIdStack.Data[_TextureIdStack.Size - 1]; + _CmdHeader.TextureId = (_TextureIdStack.Size == 0) ? ImTextureID() : _TextureIdStack.Data[_TextureIdStack.Size - 1]; _OnChangedTextureID(); } @@ -2777,7 +2777,7 @@ static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas) ImFontAtlasBuildInit(atlas); // Clear atlas - atlas->TexID = (ImTextureID)NULL; + atlas->TexID = ImTextureID(); atlas->TexWidth = atlas->TexHeight = 0; atlas->TexUvScale = ImVec2(0.0f, 0.0f); atlas->TexUvWhitePixel = ImVec2(0.0f, 0.0f); diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index baaf4f4e7..156e7a813 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -1122,7 +1122,7 @@ bool ImGui::ImageButton(const char* str_id, ImTextureID user_texture_id, const I bool ImGui::ImageButton(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, int frame_padding, const ImVec4& bg_col, const ImVec4& tint_col) { // Default to using texture ID as ID. User can still push string/integer prefixes. - PushID((void*)(intptr_t)user_texture_id); + PushID((ImTextureID)(intptr_t)user_texture_id); if (frame_padding >= 0) PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2((float)frame_padding, (float)frame_padding)); bool ret = ImageButton("", user_texture_id, size, uv0, uv1, bg_col, tint_col); From 6b8accbfa1bca2d755e6dd14c18da5c17ef61488 Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 8 Oct 2024 14:29:21 +0200 Subject: [PATCH 04/22] Fixed building when defining ImTextureID to a multi-token name. (#1641) Amend 92b9498 --- imgui_draw.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 0c10a79b7..b69bc789f 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -619,7 +619,7 @@ void ImDrawList::PushTextureID(ImTextureID texture_id) void ImDrawList::PopTextureID() { _TextureIdStack.pop_back(); - _CmdHeader.TextureId = (_TextureIdStack.Size == 0) ? ImTextureID() : _TextureIdStack.Data[_TextureIdStack.Size - 1]; + _CmdHeader.TextureId = (_TextureIdStack.Size == 0) ? (ImTextureID)NULL : _TextureIdStack.Data[_TextureIdStack.Size - 1]; _OnChangedTextureID(); } @@ -2777,7 +2777,7 @@ static bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas) ImFontAtlasBuildInit(atlas); // Clear atlas - atlas->TexID = ImTextureID(); + atlas->TexID = (ImTextureID)NULL; atlas->TexWidth = atlas->TexHeight = 0; atlas->TexUvScale = ImVec2(0.0f, 0.0f); atlas->TexUvWhitePixel = ImVec2(0.0f, 0.0f); From c3629adbeb22740c7f352a0dcc17870b80630e37 Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 8 Oct 2024 14:33:17 +0200 Subject: [PATCH 05/22] Backends: Metal: fixed ImTextureID cast. (#1641) Amend 92b9498 --- backends/imgui_impl_metal.mm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backends/imgui_impl_metal.mm b/backends/imgui_impl_metal.mm index 818961048..b8f82a65d 100644 --- a/backends/imgui_impl_metal.mm +++ b/backends/imgui_impl_metal.mm @@ -291,7 +291,7 @@ void ImGui_ImplMetal_RenderDrawData(ImDrawData* drawData, id c // Bind texture, Draw if (ImTextureID tex_id = pcmd->GetTexID()) - [commandEncoder setFragmentTexture:(__bridge id)(tex_id) atIndex:0]; + [commandEncoder setFragmentTexture:(__bridge id)(void*)(intptr_t)(tex_id) atIndex:0]; [commandEncoder setVertexBufferOffset:(vertexBufferOffset + pcmd->VtxOffset * sizeof(ImDrawVert)) atIndex:0]; [commandEncoder drawIndexedPrimitives:MTLPrimitiveTypeTriangle @@ -347,7 +347,7 @@ bool ImGui_ImplMetal_CreateFontsTexture(id device) id texture = [device newTextureWithDescriptor:textureDescriptor]; [texture replaceRegion:MTLRegionMake2D(0, 0, (NSUInteger)width, (NSUInteger)height) mipmapLevel:0 withBytes:pixels bytesPerRow:(NSUInteger)width * 4]; bd->SharedMetalContext.fontTexture = texture; - io.Fonts->SetTexID((__bridge void*)bd->SharedMetalContext.fontTexture); // ImTextureID == void* + io.Fonts->SetTexID((ImTextureID)(intptr_t)(__bridge void*)bd->SharedMetalContext.fontTexture); // ImTextureID == ImU64 return (bd->SharedMetalContext.fontTexture != nil); } From f3d242a90d645dec043d63d128015c87f0ac9fe8 Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 8 Oct 2024 19:45:58 +0200 Subject: [PATCH 06/22] Tables: fixed initial auto-sizing issue with synched-instances. (#8045, #7218) --- docs/CHANGELOG.txt | 1 + imgui.h | 2 +- imgui_tables.cpp | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 96a52ff40..32818837f 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -60,6 +60,7 @@ Other changes: - IO: added 'void* platform_io.Renderer_RenderState' which is set during the ImGui_ImplXXXX_RenderDrawData() of standard backend to expose selected render state to draw callbacks. (#6969, #5834, #7468, #3590) +- Tables: fixed initial auto-sizing issue with synched-instances. (#8045, #7218) - Backends: DX11, DX12, Vulkan, WGPU: expose selected state in ImGui_ImplXXXX_RenderState. structure during render loop. (#6969, #5834, #7468, #3590) - Backends: DX9, DX10, DX11, DX12, OpenGL, Vulkan, WGPU: Changed default texture sampler diff --git a/imgui.h b/imgui.h index 87d77c2c2..8cda26dea 100644 --- a/imgui.h +++ b/imgui.h @@ -29,7 +29,7 @@ // Library Version // (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345') #define IMGUI_VERSION "1.91.4 WIP" -#define IMGUI_VERSION_NUM 19131 +#define IMGUI_VERSION_NUM 19132 #define IMGUI_HAS_TABLE /* diff --git a/imgui_tables.cpp b/imgui_tables.cpp index 491566d7a..3ba15fef5 100644 --- a/imgui_tables.cpp +++ b/imgui_tables.cpp @@ -1160,7 +1160,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table) } // Don't decrement auto-fit counters until container window got a chance to submit its items - if (table->HostSkipItems == false) + if (table->HostSkipItems == false && table->InstanceCurrent == 0) { column->AutoFitQueue >>= 1; column->CannotSkipItemsQueue >>= 1; From 661bba09ce1fc815765d662fa982bc1d1d3f8c6e Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 9 Oct 2024 13:54:39 +0200 Subject: [PATCH 07/22] InputText: fixed an issue with not declaring ownership of Delete/Backspace/Arrow keys. (#8048) --- docs/CHANGELOG.txt | 4 +++- docs/README.md | 2 +- imgui_widgets.cpp | 8 ++++++++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 32818837f..1af37fc5f 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -61,10 +61,12 @@ Other changes: ImGui_ImplXXXX_RenderDrawData() of standard backend to expose selected render state to draw callbacks. (#6969, #5834, #7468, #3590) - Tables: fixed initial auto-sizing issue with synched-instances. (#8045, #7218) +- InputText: fixed an issue with not declaring ownership of Delete/Backspace/Arrow keys, + preventing use of external shortcuts not guarded by an ActiveId check. (#8048) [@geertbleyen] - Backends: DX11, DX12, Vulkan, WGPU: expose selected state in ImGui_ImplXXXX_RenderState. structure during render loop. (#6969, #5834, #7468, #3590) - Backends: DX9, DX10, DX11, DX12, OpenGL, Vulkan, WGPU: Changed default texture sampler - to Clamp instead of Repeat/Wrap. (#7468, #7511, #5999, #5502) + to Clamp instead of Repeat/Wrap. (#7468, #7511, #5999, #5502, #7230) ----------------------------------------------------------------------- diff --git a/docs/README.md b/docs/README.md index 0968727f1..c47f03b9b 100644 --- a/docs/README.md +++ b/docs/README.md @@ -196,7 +196,7 @@ Ongoing Dear ImGui development is and has been financially supported by users an **THANK YOU to all past and present supporters for helping to keep this project alive and thriving!** Dear ImGui is using software and services provided free of charge for open source projects: -- [PVS-Studio](https://www.viva64.com/en/b/0570/) for static analysis. +- [PVS-Studio](https://pvs-studio.com/en/pvs-studio/?utm_source=website&utm_medium=github&utm_campaign=open_source) for static analysis (supports C/C++/C#/Java). - [GitHub actions](https://github.com/features/actions) for continuous integration systems. - [OpenCppCoverage](https://github.com/OpenCppCoverage/OpenCppCoverage) for code coverage analysis. diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 156e7a813..4f6315879 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -4569,10 +4569,18 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ if (user_clicked) SetKeyOwner(ImGuiKey_MouseLeft, id); g.ActiveIdUsingNavDirMask |= (1 << ImGuiDir_Left) | (1 << ImGuiDir_Right); + SetKeyOwner(ImGuiKey_LeftArrow, id); + SetKeyOwner(ImGuiKey_RightArrow, id); if (is_multiline || (flags & ImGuiInputTextFlags_CallbackHistory)) + { g.ActiveIdUsingNavDirMask |= (1 << ImGuiDir_Up) | (1 << ImGuiDir_Down); + SetKeyOwner(ImGuiKey_UpArrow, id); + SetKeyOwner(ImGuiKey_DownArrow, id); + } SetKeyOwner(ImGuiKey_Enter, id); SetKeyOwner(ImGuiKey_KeypadEnter, id); + SetKeyOwner(ImGuiKey_Delete, id); + SetKeyOwner(ImGuiKey_Backspace, id); SetKeyOwner(ImGuiKey_Home, id); SetKeyOwner(ImGuiKey_End, id); if (is_multiline) From 9fbc3134591bdca66d548a97f284c3a5e2811b6f Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 9 Oct 2024 14:01:47 +0200 Subject: [PATCH 08/22] InputText: amend 661bba0. (#8048) --- imgui_widgets.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 4f6315879..9d4ef66da 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -4566,23 +4566,19 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ if (g.ActiveId == id) { // Declare some inputs, the other are registered and polled via Shortcut() routing system. + // FIXME: The reason we don't use Shortcut() is we would need a routing flag to specify multiple mods, or to all mods combinaison into individual shortcuts. + const ImGuiKey always_owned_keys[] = { ImGuiKey_LeftArrow, ImGuiKey_RightArrow, ImGuiKey_Enter, ImGuiKey_KeypadEnter, ImGuiKey_Delete, ImGuiKey_Backspace, ImGuiKey_Home, ImGuiKey_End }; + for (ImGuiKey key : always_owned_keys) + SetKeyOwner(key, id); if (user_clicked) SetKeyOwner(ImGuiKey_MouseLeft, id); g.ActiveIdUsingNavDirMask |= (1 << ImGuiDir_Left) | (1 << ImGuiDir_Right); - SetKeyOwner(ImGuiKey_LeftArrow, id); - SetKeyOwner(ImGuiKey_RightArrow, id); if (is_multiline || (flags & ImGuiInputTextFlags_CallbackHistory)) { g.ActiveIdUsingNavDirMask |= (1 << ImGuiDir_Up) | (1 << ImGuiDir_Down); SetKeyOwner(ImGuiKey_UpArrow, id); SetKeyOwner(ImGuiKey_DownArrow, id); } - SetKeyOwner(ImGuiKey_Enter, id); - SetKeyOwner(ImGuiKey_KeypadEnter, id); - SetKeyOwner(ImGuiKey_Delete, id); - SetKeyOwner(ImGuiKey_Backspace, id); - SetKeyOwner(ImGuiKey_Home, id); - SetKeyOwner(ImGuiKey_End, id); if (is_multiline) { SetKeyOwner(ImGuiKey_PageUp, id); From a0b811dd37392121227dce75710580834eff2294 Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 9 Oct 2024 16:39:28 +0200 Subject: [PATCH 09/22] Backends: SDLRenderer2/3: expose selected state in ImGui_ImplXXXX_RenderState structures during render loop. (#6969, #5834, #7468, #3590 + #7616) --- backends/imgui_impl_sdlrenderer2.cpp | 13 ++++++++++++- backends/imgui_impl_sdlrenderer2.h | 9 +++++++++ backends/imgui_impl_sdlrenderer3.cpp | 13 ++++++++++++- backends/imgui_impl_sdlrenderer3.h | 9 +++++++++ docs/CHANGELOG.txt | 4 ++-- 5 files changed, 44 insertions(+), 4 deletions(-) diff --git a/backends/imgui_impl_sdlrenderer2.cpp b/backends/imgui_impl_sdlrenderer2.cpp index 8203c6caf..27c952269 100644 --- a/backends/imgui_impl_sdlrenderer2.cpp +++ b/backends/imgui_impl_sdlrenderer2.cpp @@ -10,6 +10,7 @@ // Implemented features: // [X] Renderer: User texture binding. Use 'SDL_Texture*' as ImTextureID. Read the FAQ about ImTextureID! // [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices. +// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'. // You can copy and use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. @@ -20,6 +21,7 @@ // - Introduction, links and more at the top of imgui.cpp // CHANGELOG +// 2024-10-09: Expose selected render state in ImGui_ImplSDLRenderer2_RenderState, which you can access in 'void* platform_io.Renderer_RenderState' during draw callbacks. // 2024-05-14: *BREAKING CHANGE* ImGui_ImplSDLRenderer3_RenderDrawData() requires SDL_Renderer* passed as parameter. // 2023-05-30: Renamed imgui_impl_sdlrenderer.h/.cpp to imgui_impl_sdlrenderer2.h/.cpp to accommodate for upcoming SDL3. // 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11. @@ -140,12 +142,20 @@ void ImGui_ImplSDLRenderer2_RenderDrawData(ImDrawData* draw_data, SDL_Renderer* SDL_RenderGetViewport(renderer, &old.Viewport); SDL_RenderGetClipRect(renderer, &old.ClipRect); + // Setup desired state + ImGui_ImplSDLRenderer2_SetupRenderState(renderer); + + // Setup render state structure (for callbacks and custom texture bindings) + ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); + ImGui_ImplSDLRenderer2_RenderState render_state; + render_state.Renderer = renderer; + platform_io.Renderer_RenderState = &render_state; + // Will project scissor/clipping rectangles into framebuffer space ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports ImVec2 clip_scale = render_scale; // Render command lists - ImGui_ImplSDLRenderer2_SetupRenderState(renderer); for (int n = 0; n < draw_data->CmdListsCount; n++) { const ImDrawList* draw_list = draw_data->CmdLists[n]; @@ -198,6 +208,7 @@ void ImGui_ImplSDLRenderer2_RenderDrawData(ImDrawData* draw_data, SDL_Renderer* } } } + platform_io.Renderer_RenderState = NULL; // Restore modified SDL_Renderer state SDL_RenderSetViewport(renderer, &old.Viewport); diff --git a/backends/imgui_impl_sdlrenderer2.h b/backends/imgui_impl_sdlrenderer2.h index c067eaeea..804ca183d 100644 --- a/backends/imgui_impl_sdlrenderer2.h +++ b/backends/imgui_impl_sdlrenderer2.h @@ -10,6 +10,7 @@ // Implemented features: // [X] Renderer: User texture binding. Use 'SDL_Texture*' as ImTextureID. Read the FAQ about ImTextureID! // [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices. +// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'. // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. @@ -37,4 +38,12 @@ IMGUI_IMPL_API void ImGui_ImplSDLRenderer2_DestroyFontsTexture(); IMGUI_IMPL_API bool ImGui_ImplSDLRenderer2_CreateDeviceObjects(); IMGUI_IMPL_API void ImGui_ImplSDLRenderer2_DestroyDeviceObjects(); +// [BETA] Selected render state data shared with callbacks. +// This is temporarily stored in GetPlatformIO().Renderer_RenderState during the ImGui_ImplSDLRenderer2_RenderDrawData() call. +// (Please open an issue if you feel you need access to more data) +struct ImGui_ImplSDLRenderer2_RenderState +{ + SDL_Renderer* Renderer; +}; + #endif // #ifndef IMGUI_DISABLE diff --git a/backends/imgui_impl_sdlrenderer3.cpp b/backends/imgui_impl_sdlrenderer3.cpp index 9397a6467..5dabea199 100644 --- a/backends/imgui_impl_sdlrenderer3.cpp +++ b/backends/imgui_impl_sdlrenderer3.cpp @@ -12,6 +12,7 @@ // Implemented features: // [X] Renderer: User texture binding. Use 'SDL_Texture*' as ImTextureID. Read the FAQ about ImTextureID! // [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices. +// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'. // You can copy and use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. @@ -22,6 +23,7 @@ // - Introduction, links and more at the top of imgui.cpp // CHANGELOG +// 2024-10-09: Expose selected render state in ImGui_ImplSDLRenderer3_RenderState, which you can access in 'void* platform_io.Renderer_RenderState' during draw callbacks. // 2024-07-01: Update for SDL3 api changes: SDL_RenderGeometryRaw() uint32 version was removed (SDL#9009). // 2024-05-14: *BREAKING CHANGE* ImGui_ImplSDLRenderer3_RenderDrawData() requires SDL_Renderer* passed as parameter. // 2024-02-12: Amend to query SDL_RenderViewportSet() and restore viewport accordingly. @@ -163,12 +165,20 @@ void ImGui_ImplSDLRenderer3_RenderDrawData(ImDrawData* draw_data, SDL_Renderer* SDL_GetRenderViewport(renderer, &old.Viewport); SDL_GetRenderClipRect(renderer, &old.ClipRect); + // Setup desired state + ImGui_ImplSDLRenderer3_SetupRenderState(renderer); + + // Setup render state structure (for callbacks and custom texture bindings) + ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); + ImGui_ImplSDLRenderer3_RenderState render_state; + render_state.Renderer = renderer; + platform_io.Renderer_RenderState = &render_state; + // Will project scissor/clipping rectangles into framebuffer space ImVec2 clip_off = draw_data->DisplayPos; // (0,0) unless using multi-viewports ImVec2 clip_scale = render_scale; // Render command lists - ImGui_ImplSDLRenderer3_SetupRenderState(renderer); for (int n = 0; n < draw_data->CmdListsCount; n++) { const ImDrawList* draw_list = draw_data->CmdLists[n]; @@ -217,6 +227,7 @@ void ImGui_ImplSDLRenderer3_RenderDrawData(ImDrawData* draw_data, SDL_Renderer* } } } + platform_io.Renderer_RenderState = NULL; // Restore modified SDL_Renderer state SDL_SetRenderViewport(renderer, old.ViewportEnabled ? &old.Viewport : nullptr); diff --git a/backends/imgui_impl_sdlrenderer3.h b/backends/imgui_impl_sdlrenderer3.h index 6c23deca9..7d4c609e8 100644 --- a/backends/imgui_impl_sdlrenderer3.h +++ b/backends/imgui_impl_sdlrenderer3.h @@ -12,6 +12,7 @@ // Implemented features: // [X] Renderer: User texture binding. Use 'SDL_Texture*' as ImTextureID. Read the FAQ about ImTextureID! // [X] Renderer: Large meshes support (64k+ vertices) with 16-bit indices. +// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'. // You can copy and use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. @@ -39,4 +40,12 @@ IMGUI_IMPL_API void ImGui_ImplSDLRenderer3_DestroyFontsTexture(); IMGUI_IMPL_API bool ImGui_ImplSDLRenderer3_CreateDeviceObjects(); IMGUI_IMPL_API void ImGui_ImplSDLRenderer3_DestroyDeviceObjects(); +// [BETA] Selected render state data shared with callbacks. +// This is temporarily stored in GetPlatformIO().Renderer_RenderState during the ImGui_ImplSDLRenderer3_RenderDrawData() call. +// (Please open an issue if you feel you need access to more data) +struct ImGui_ImplSDLRenderer3_RenderState +{ + SDL_Renderer* Renderer; +}; + #endif // #ifndef IMGUI_DISABLE diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 1af37fc5f..427086625 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -63,8 +63,8 @@ Other changes: - Tables: fixed initial auto-sizing issue with synched-instances. (#8045, #7218) - InputText: fixed an issue with not declaring ownership of Delete/Backspace/Arrow keys, preventing use of external shortcuts not guarded by an ActiveId check. (#8048) [@geertbleyen] -- Backends: DX11, DX12, Vulkan, WGPU: expose selected state in ImGui_ImplXXXX_RenderState. - structure during render loop. (#6969, #5834, #7468, #3590) +- Backends: DX11, DX12, SDLRenderer2/3. Vulkan, WGPU: expose selected state in + ImGui_ImplXXXX_RenderState structures during render loop. (#6969, #5834, #7468, #3590) - Backends: DX9, DX10, DX11, DX12, OpenGL, Vulkan, WGPU: Changed default texture sampler to Clamp instead of Repeat/Wrap. (#7468, #7511, #5999, #5502, #7230) From f29e505d94ed41e556945ec0f9f29c07cf6c412c Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 9 Oct 2024 17:14:44 +0200 Subject: [PATCH 10/22] CI: remove --disableLicenseExpirationCheck. --- .github/workflows/static-analysis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml index 99b058c91..69df5cdf8 100644 --- a/.github/workflows/static-analysis.yml +++ b/.github/workflows/static-analysis.yml @@ -42,5 +42,5 @@ jobs: fi cd examples/example_null pvs-studio-analyzer trace -- make WITH_EXTRA_WARNINGS=1 - pvs-studio-analyzer analyze --disableLicenseExpirationCheck -e ../../imstb_rectpack.h -e ../../imstb_textedit.h -e ../../imstb_truetype.h -l ../../pvs-studio.lic -o pvs-studio.log + pvs-studio-analyzer analyze -e ../../imstb_rectpack.h -e ../../imstb_textedit.h -e ../../imstb_truetype.h -l ../../pvs-studio.lic -o pvs-studio.log plog-converter -a 'GA:1,2;OP:1' -d V1071 -t errorfile -w pvs-studio.log From 98d52b7b26cccae5d3523bbefddbcb8da627e130 Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 11 Oct 2024 13:29:13 +0200 Subject: [PATCH 11/22] DrawList: AddCallback() added an optional size parameter allowing to copy and store any amount of user data for usage by callbacks: (#6969, #4770, #7665) --- docs/CHANGELOG.txt | 8 ++++++++ docs/TODO.txt | 5 ++--- imgui.h | 23 ++++++++++++++++++----- imgui_draw.cpp | 30 ++++++++++++++++++++++++++++-- 4 files changed, 56 insertions(+), 10 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 427086625..4fda69c0e 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -60,6 +60,14 @@ Other changes: - IO: added 'void* platform_io.Renderer_RenderState' which is set during the ImGui_ImplXXXX_RenderDrawData() of standard backend to expose selected render state to draw callbacks. (#6969, #5834, #7468, #3590) +- DrawList: AddCallback() added an optional size parameter allowing to copy and + store any amount of user data for usage by callbacks: (#6969, #4770, #7665) + - If userdata_size == 0: we copy/store the 'userdata' argument as-is (existing behavior). + It will be available unmodified in ImDrawCmd::UserCallbackData during render. + - If userdata_size > 0, we copy/store 'userdata_size' bytes pointed to by 'userdata' (new behavior). + We store them in a buffer stored inside the drawlist. ImDrawCmd::UserCallbackData + will point inside that buffer so you have to retrieve data from there. Your callback + may need to use ImDrawCmd::UserCallbackDataSize if you expect dynamically-sized data. - Tables: fixed initial auto-sizing issue with synched-instances. (#8045, #7218) - InputText: fixed an issue with not declaring ownership of Delete/Backspace/Arrow keys, preventing use of external shortcuts not guarded by an ActiveId check. (#8048) [@geertbleyen] diff --git a/docs/TODO.txt b/docs/TODO.txt index ddceb3b3d..e61501d78 100644 --- a/docs/TODO.txt +++ b/docs/TODO.txt @@ -9,8 +9,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - doc: add a proper documentation system (maybe relying on automation? #435) - doc: checklist app to verify backends/integration of imgui (test inputs, rendering, callback, etc.). - doc/tips: tips of the day: website? applet in imgui_club? - - doc/wiki: work on the wiki https://github.com/ocornut/imgui/wiki - + - window: preserve/restore relative focus ordering (persistent or not), and e.g. of multiple reappearing windows (#2304) -> also see docking reference to same #. - window: calling SetNextWindowSize() every frame with <= 0 doesn't do anything, may be useful to allow (particularly when used for a single axis). (#690) - window: add a way for very transient windows (non-saved, temporary overlay over hundreds of objects) to "clean" up from the global window list. perhaps a lightweight explicit cleanup pass. @@ -44,7 +43,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - drawlist: maintaining bounding box per command would allow to merge draw command when clipping isn't relied on (typical non-scrolling window or non-overflowing column would merge with previous command). (WIP branch) - drawlist: make it easier to toggle AA per primitive, so we can use e.g. non-AA fill + AA borders more naturally - drawlist: non-AA strokes have gaps between points (#593, #288), glitch especially on RenderCheckmark() and ColorPicker4(). - - drawlist: callback: add an extra void* in ImDrawCallback to allow passing render-local data to the callback (would break API). + - drawlist: callback: add an extra void* in ImDrawCallback to expose render state instead of pulling from Renderer_RenderState (would break API). - drawlist: AddRect vs AddLine position confusing (#2441) - drawlist/opt: store rounded corners in texture to use 1 quad per corner (filled and wireframe) to lower the cost of rounding. (#1962) - drawlist/opt: AddRect() axis aligned pixel aligned (no-aa) could use 8 triangles instead of 16 and no normal calculation. diff --git a/imgui.h b/imgui.h index 8cda26dea..d18879ce1 100644 --- a/imgui.h +++ b/imgui.h @@ -29,7 +29,7 @@ // Library Version // (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345') #define IMGUI_VERSION "1.91.4 WIP" -#define IMGUI_VERSION_NUM 19132 +#define IMGUI_VERSION_NUM 19133 #define IMGUI_HAS_TABLE /* @@ -2953,9 +2953,11 @@ struct ImDrawCmd unsigned int IdxOffset; // 4 // Start offset in index buffer. unsigned int ElemCount; // 4 // Number of indices (multiple of 3) to be rendered as triangles. Vertices are stored in the callee ImDrawList's vtx_buffer[] array, indices in idx_buffer[]. ImDrawCallback UserCallback; // 4-8 // If != NULL, call the function instead of rendering the vertices. clip_rect and texture_id will be set normally. - void* UserCallbackData; // 4-8 // The draw callback code can access this. + void* UserCallbackData; // 4-8 // Callback user data (when UserCallback != NULL). If called AddCallback() with size == 0, this is a copy of the AddCallback() argument. If called AddCallback() with size > 0, this is pointing to a buffer where data is stored. + int UserCallbackDataSize; // 4 // Size of callback user data when using storage, otherwise 0. + int UserCallbackDataOffset;// 4 // [Internal] Offset of callback user data when using storage, otherwise -1. - ImDrawCmd() { memset(this, 0, sizeof(*this)); } // Also ensure our padding fields are zeroed + ImDrawCmd() { memset(this, 0, sizeof(*this)); } // Also ensure our padding fields are zeroed // Since 1.83: returns ImTextureID associated with this draw call. Warning: DO NOT assume this is always same as 'TextureId' (we will change this function for an upcoming feature) inline ImTextureID GetTexID() const { return TextureId; } @@ -3068,6 +3070,7 @@ struct ImDrawList ImDrawListSplitter _Splitter; // [Internal] for channels api (note: prefer using your own persistent instance of ImDrawListSplitter!) ImVector _ClipRectStack; // [Internal] ImVector _TextureIdStack; // [Internal] + ImVector _CallbacksDataBuf; // [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 @@ -3140,8 +3143,18 @@ struct ImDrawList IMGUI_API void PathBezierQuadraticCurveTo(const ImVec2& p2, const ImVec2& p3, int num_segments = 0); // Quadratic Bezier (3 control points) IMGUI_API void PathRect(const ImVec2& rect_min, const ImVec2& rect_max, float rounding = 0.0f, ImDrawFlags flags = 0); - // Advanced - IMGUI_API void AddCallback(ImDrawCallback callback, void* callback_data); // Your rendering function must check for 'UserCallback' in ImDrawCmd and call the function instead of rendering triangles. + // Advanced: Draw Callbacks + // - May be used to alter render state (change sampler, blending, current shader). May be used to emit custom rendering commands (difficult to do correctly, but possible). + // - Use special ImDrawCallback_ResetRenderState callback to instruct backend to reset its render state to the default. + // - Your rendering loop must check for 'UserCallback' in ImDrawCmd and call the function instead of rendering triangles. All standard backends are honoring this. + // - For some backends, the callback may access selected render-states exposed by the backend in a ImGui_ImplXXXX_RenderState structure pointed to by platform_io.Renderer_RenderState. + // - IMPORTANT: please be mindful of the different level of indirection between using size==0 (copying argument) and using size>0 (copying pointed data into a buffer). + // - If userdata_size == 0: we copy/store the 'userdata' argument as-is. It will be available unmodified in ImDrawCmd::UserCallbackData during render. + // - If userdata_size > 0, we copy/store 'userdata_size' bytes pointed to by 'userdata'. We store them in a buffer stored inside the drawlist. ImDrawCmd::UserCallbackData will point inside that buffer so you have to retrieve data from there. Your callback may need to use ImDrawCmd::UserCallbackDataSize if you expect dynamically-sized data. + // - Support for userdata_size > 0 was added in v1.91.4, October 2024. So earlier code always only allowed to copy/store a simple void*. + IMGUI_API void AddCallback(ImDrawCallback callback, void* userdata, size_t userdata_size = 0); + + // Advanced: Miscellaneous IMGUI_API void AddDrawCmd(); // This is useful if you need to forcefully create a new draw call (to allow for dependent rendering / blending). Otherwise primitives are merged into the same draw-call as much as possible IMGUI_API ImDrawList* CloneOutput() const; // Create a clone of the CmdBuffer/IdxBuffer/VtxBuffer. diff --git a/imgui_draw.cpp b/imgui_draw.cpp index b69bc789f..efee2ec9c 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -414,6 +414,7 @@ void ImDrawList::_ResetForNewFrame() _IdxWritePtr = NULL; _ClipRectStack.resize(0); _TextureIdStack.resize(0); + _CallbacksDataBuf.resize(0); _Path.resize(0); _Splitter.Clear(); CmdBuffer.push_back(ImDrawCmd()); @@ -431,6 +432,7 @@ void ImDrawList::_ClearFreeMemory() _IdxWritePtr = NULL; _ClipRectStack.clear(); _TextureIdStack.clear(); + _CallbacksDataBuf.clear(); _Path.clear(); _Splitter.ClearFreeMemory(); } @@ -470,7 +472,7 @@ void ImDrawList::_PopUnusedDrawCmd() } } -void ImDrawList::AddCallback(ImDrawCallback callback, void* callback_data) +void ImDrawList::AddCallback(ImDrawCallback callback, void* userdata, size_t userdata_size) { IM_ASSERT_PARANOID(CmdBuffer.Size > 0); ImDrawCmd* curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1]; @@ -480,8 +482,26 @@ void ImDrawList::AddCallback(ImDrawCallback callback, void* callback_data) AddDrawCmd(); curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1]; } + curr_cmd->UserCallback = callback; - curr_cmd->UserCallbackData = callback_data; + if (userdata_size == 0) + { + // Store user data directly in command (no indirection) + curr_cmd->UserCallbackData = userdata; + curr_cmd->UserCallbackDataSize = 0; + curr_cmd->UserCallbackDataOffset = -1; + } + else + { + // Copy and store user data in a buffer + IM_ASSERT(userdata != NULL); + IM_ASSERT(userdata_size < (1u << 31)); + curr_cmd->UserCallbackData = NULL; // Will be resolved during Render() + curr_cmd->UserCallbackDataSize = (int)userdata_size; + curr_cmd->UserCallbackDataOffset = _CallbacksDataBuf.Size; + _CallbacksDataBuf.resize(_CallbacksDataBuf.Size + (int)userdata_size); + memcpy(_CallbacksDataBuf.Data + (size_t)curr_cmd->UserCallbackDataOffset, userdata, userdata_size); + } AddDrawCmd(); // Force a new command after us (see comment below) } @@ -2222,6 +2242,12 @@ void ImGui::AddDrawListToDrawDataEx(ImDrawData* draw_data, ImVector if (sizeof(ImDrawIdx) == 2) IM_ASSERT(draw_list->_VtxCurrentIdx < (1 << 16) && "Too many vertices in ImDrawList using 16-bit indices. Read comment above"); + // Resolve callback data pointers + if (draw_list->_CallbacksDataBuf.Size > 0) + for (ImDrawCmd& cmd : draw_list->CmdBuffer) + if (cmd.UserCallback != NULL && cmd.UserCallbackDataOffset != -1 && cmd.UserCallbackDataSize > 0) + cmd.UserCallbackData = draw_list->_CallbacksDataBuf.Data + cmd.UserCallbackDataOffset; + // Add to output list + records state in ImDrawData out_list->push_back(draw_list); draw_data->CmdListsCount++; From c4bc6744824de148c3f825ffdcde785510e208ac Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 11 Oct 2024 15:31:01 +0200 Subject: [PATCH 12/22] IO: WantCaptureKeyboard is never set when ImGuiConfigFlags_NoKeyboard is enabled. (#4921) + Retroactively add missing changelog item in 1.90 + Backends: Vulkan: use GetTexID() for consistency. --- backends/imgui_impl_vulkan.cpp | 4 ++-- docs/CHANGELOG.txt | 2 ++ imgui.cpp | 11 ++++++++--- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/backends/imgui_impl_vulkan.cpp b/backends/imgui_impl_vulkan.cpp index 78d838955..a68f862b1 100644 --- a/backends/imgui_impl_vulkan.cpp +++ b/backends/imgui_impl_vulkan.cpp @@ -589,11 +589,11 @@ void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer comm vkCmdSetScissor(command_buffer, 0, 1, &scissor); // Bind DescriptorSet with font or user texture - VkDescriptorSet desc_set[1] = { (VkDescriptorSet)pcmd->TextureId }; + VkDescriptorSet desc_set[1] = { (VkDescriptorSet)pcmd->GetTexID() }; if (sizeof(ImTextureID) < sizeof(ImU64)) { // We don't support texture switches if ImTextureID hasn't been redefined to be 64-bit. Do a flaky check that other textures haven't been used. - IM_ASSERT(pcmd->TextureId == (ImTextureID)bd->FontDescriptorSet); + IM_ASSERT(pcmd->GetTexID() == (ImTextureID)bd->FontDescriptorSet); desc_set[0] = bd->FontDescriptorSet; } vkCmdBindDescriptorSets(command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, bd->PipelineLayout, 0, 1, desc_set, 0, nullptr); diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 4fda69c0e..8178df1f9 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -60,6 +60,7 @@ Other changes: - IO: added 'void* platform_io.Renderer_RenderState' which is set during the ImGui_ImplXXXX_RenderDrawData() of standard backend to expose selected render state to draw callbacks. (#6969, #5834, #7468, #3590) +- IO: WantCaptureKeyboard is never set when ImGuiConfigFlags_NoKeyboard is enabled. (#4921) - DrawList: AddCallback() added an optional size parameter allowing to copy and store any amount of user data for usage by callbacks: (#6969, #4770, #7665) - If userdata_size == 0: we copy/store the 'userdata' argument as-is (existing behavior). @@ -480,6 +481,7 @@ Other changes: which was pressed over void/underlying app, which is consistent/needed to allow the mouse up event of a drag over void/underlying app to catch release. (#1392) [@Moka42] - IO: Added io.ClearInputMouse() to clear mouse state. (#4921) +- IO: Added ImGuiConfigFlags_NoKeyboard for consistency and convenience. (#4921) - Windows: BeginChild(): fixed a glitch when during a resize of a child window which is tightly close to the boundaries of its parent (e.g. with zero WindowPadding), the child position could have temporarily be moved around by erroneous padding application. (#7706) diff --git a/imgui.cpp b/imgui.cpp index 33170e430..0b2d787c4 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4998,9 +4998,14 @@ void ImGui::UpdateHoveredWindowAndCaptureFlags() } // Update io.WantCaptureKeyboard for the user application (true = dispatch keyboard info to Dear ImGui only, false = dispatch keyboard info to Dear ImGui + underlying app) - io.WantCaptureKeyboard = (g.ActiveId != 0) || (modal_window != NULL); - if (io.NavActive && (io.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) && !(io.ConfigFlags & ImGuiConfigFlags_NavNoCaptureKeyboard)) - io.WantCaptureKeyboard = true; + io.WantCaptureKeyboard = false; + if ((io.ConfigFlags & ImGuiConfigFlags_NoKeyboard) == 0) + { + if ((g.ActiveId != 0) || (modal_window != NULL)) + io.WantCaptureKeyboard = true; + else if (io.NavActive && (io.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) && !(io.ConfigFlags & ImGuiConfigFlags_NavNoCaptureKeyboard)) + io.WantCaptureKeyboard = true; + } if (g.WantCaptureKeyboardNextFrame != -1) // Manual override io.WantCaptureKeyboard = (g.WantCaptureKeyboardNextFrame != 0); From 20ae8bd4c32fbeb048312ad23bc71dcf8a87fa89 Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 14 Oct 2024 10:22:24 +0200 Subject: [PATCH 13/22] Error Handling: turned IsItemHovered()/IsWindowHovered() checks into IM_ASSERT_USER_ERROR. (#1651) --- docs/CHANGELOG.txt | 1 + imgui.cpp | 8 +++----- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 8178df1f9..977db92e6 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -61,6 +61,7 @@ Other changes: ImGui_ImplXXXX_RenderDrawData() of standard backend to expose selected render state to draw callbacks. (#6969, #5834, #7468, #3590) - IO: WantCaptureKeyboard is never set when ImGuiConfigFlags_NoKeyboard is enabled. (#4921) +- Error Handling: turned a few more functions into recoverable errors. (#1651) - DrawList: AddCallback() added an optional size parameter allowing to copy and store any amount of user data for usage by callbacks: (#6969, #4770, #7665) - If userdata_size == 0: we copy/store the 'userdata' argument as-is (existing behavior). diff --git a/imgui.cpp b/imgui.cpp index 0b2d787c4..3bd7a473a 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4433,7 +4433,7 @@ bool ImGui::IsItemHovered(ImGuiHoveredFlags flags) { ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; - IM_ASSERT((flags & ~ImGuiHoveredFlags_AllowedMaskForIsItemHovered) == 0 && "Invalid flags for IsItemHovered()!"); + IM_ASSERT_USER_ERROR((flags & ~ImGuiHoveredFlags_AllowedMaskForIsItemHovered) == 0, "Invalid flags for IsItemHovered()!"); if (g.NavDisableMouseHover && !g.NavDisableHighlight && !(flags & ImGuiHoveredFlags_NoNavOverride)) { @@ -4455,8 +4455,6 @@ bool ImGui::IsItemHovered(ImGuiHoveredFlags flags) if (flags & ImGuiHoveredFlags_ForTooltip) flags = ApplyHoverFlagsForTooltip(flags, g.Style.HoverFlagsForTooltipMouse); - IM_ASSERT((flags & (ImGuiHoveredFlags_AnyWindow | ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows | ImGuiHoveredFlags_NoPopupHierarchy)) == 0); // Flags not supported by this function - // Done with rectangle culling so we can perform heavier checks now // Test if we are hovering the right window (our window could be behind another window) // [2021/03/02] Reworked / reverted the revert, finally. Note we want e.g. BeginGroup/ItemAdd/EndGroup to work as well. (#3851) @@ -8143,9 +8141,9 @@ bool ImGui::IsWindowAbove(ImGuiWindow* potential_above, ImGuiWindow* potential_b // Refer to FAQ entry "How can I tell whether to dispatch mouse/keyboard to Dear ImGui or my application?" for details. bool ImGui::IsWindowHovered(ImGuiHoveredFlags flags) { - IM_ASSERT((flags & ~ImGuiHoveredFlags_AllowedMaskForIsWindowHovered) == 0 && "Invalid flags for IsWindowHovered()!"); - ImGuiContext& g = *GImGui; + IM_ASSERT_USER_ERROR((flags & ~ImGuiHoveredFlags_AllowedMaskForIsWindowHovered) == 0, "Invalid flags for IsWindowHovered()!"); + ImGuiWindow* ref_window = g.HoveredWindow; ImGuiWindow* cur_window = g.CurrentWindow; if (ref_window == NULL) From 349af8766cbb6ea7e56b242b18be8476bebbe977 Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 14 Oct 2024 13:52:40 +0200 Subject: [PATCH 14/22] InputText: ensure mouse cursor is set regardless of whether keyboard mode is enabled or not. (#6417) + Nav comments (#8059) --- docs/CHANGELOG.txt | 2 ++ imgui.cpp | 5 ++++- imgui_internal.h | 1 + imgui_widgets.cpp | 6 +++++- 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 977db92e6..a01d5d6bc 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -73,6 +73,8 @@ Other changes: - Tables: fixed initial auto-sizing issue with synched-instances. (#8045, #7218) - InputText: fixed an issue with not declaring ownership of Delete/Backspace/Arrow keys, preventing use of external shortcuts not guarded by an ActiveId check. (#8048) [@geertbleyen] +- InputText: ensure mouse cursor shape is set regardless of whether keyboard mode is + enabled or not. (#6417) - Backends: DX11, DX12, SDLRenderer2/3. Vulkan, WGPU: expose selected state in ImGui_ImplXXXX_RenderState structures during render loop. (#6969, #5834, #7468, #3590) - Backends: DX9, DX10, DX11, DX12, OpenGL, Vulkan, WGPU: Changed default texture sampler diff --git a/imgui.cpp b/imgui.cpp index 3bd7a473a..971f48f16 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4606,7 +4606,7 @@ bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id, ImGuiItemFlags item_flag } #endif - if (g.NavDisableMouseHover) + if (g.NavDisableMouseHover && (item_flags & ImGuiItemFlags_NoNavDisableMouseHover) == 0) return false; return true; @@ -13340,8 +13340,11 @@ static void ImGui::NavUpdateCancelRequest() else { // Clear NavLastId for popups but keep it for regular child window so we can leave one and come back where we were + // FIXME-NAV: This should happen on window appearing. if (g.NavWindow && ((g.NavWindow->Flags & ImGuiWindowFlags_Popup) || !(g.NavWindow->Flags & ImGuiWindowFlags_ChildWindow))) g.NavWindow->NavLastIds[0] = 0; + + // Clear nav focus g.NavId = 0; } } diff --git a/imgui_internal.h b/imgui_internal.h index 05378c3d9..5722291af 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -833,6 +833,7 @@ enum ImGuiItemFlagsPrivate_ ImGuiItemFlags_MixedValue = 1 << 12, // false // [BETA] Represent a mixed/indeterminate value, generally multi-selection where values differ. Currently only supported by Checkbox() (later should support all sorts of widgets) ImGuiItemFlags_NoWindowHoverableCheck = 1 << 13, // false // Disable hoverable check in ItemHoverable() ImGuiItemFlags_AllowOverlap = 1 << 14, // false // Allow being overlapped by another widget. Not-hovered to Hovered transition deferred by a frame. + ImGuiItemFlags_NoNavDisableMouseHover = 1 << 15, // false // Nav keyboard/gamepad mode doesn't disable hover. // Controlled by widget code ImGuiItemFlags_Inputable = 1 << 20, // false // [WIP] Auto-activate input mode when tab focused. Currently only used and supported by a few items before it becomes a generic feature. diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 9d4ef66da..aac7383b1 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -4462,9 +4462,13 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ if (!ItemAdd(total_bb, id, &frame_bb, ImGuiItemFlags_Inputable)) return false; } - const bool hovered = ItemHoverable(frame_bb, id, g.LastItemData.InFlags); + + // Ensure mouse cursor is set even after switching to keyboard/gamepad mode. May generalize further? (#6417) + bool hovered = ItemHoverable(frame_bb, id, g.LastItemData.InFlags | ImGuiItemFlags_NoNavDisableMouseHover); if (hovered) SetMouseCursor(ImGuiMouseCursor_TextInput); + if (hovered && g.NavDisableMouseHover) + hovered = false; // We are only allowed to access the state if we are already the active widget. ImGuiInputTextState* state = GetInputTextState(id); From d885fe4dd0cda0166415d423e6a4a5d4ef5e997c Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 14 Oct 2024 15:28:00 +0200 Subject: [PATCH 15/22] (Breaking) moved ImGuiConfigFlags_NavEnableSetMousePos -> io.ConfigNavMoveSetMousePos, ImGuiConfigFlags_NavNoCaptureKeyboard -> ConfigNavCaptureKeyboard. (#2517, #2009) --- backends/imgui_impl_glfw.cpp | 2 +- backends/imgui_impl_sdl2.cpp | 2 +- backends/imgui_impl_sdl3.cpp | 2 +- backends/imgui_impl_win32.cpp | 2 +- docs/CHANGELOG.txt | 5 +++++ imgui.cpp | 27 +++++++++++++++++++------ imgui.h | 37 ++++++++++++++++++++--------------- imgui_demo.cpp | 12 ++++++++---- imgui_internal.h | 2 +- 9 files changed, 60 insertions(+), 31 deletions(-) diff --git a/backends/imgui_impl_glfw.cpp b/backends/imgui_impl_glfw.cpp index 7134d3e55..c725e9c01 100644 --- a/backends/imgui_impl_glfw.cpp +++ b/backends/imgui_impl_glfw.cpp @@ -728,7 +728,7 @@ static void ImGui_ImplGlfw_UpdateMouseData() #endif if (is_window_focused) { - // (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user) + // (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when io.ConfigNavMoveSetMousePos is enabled by user) if (io.WantSetMousePos) glfwSetCursorPos(window, (double)io.MousePos.x, (double)io.MousePos.y); diff --git a/backends/imgui_impl_sdl2.cpp b/backends/imgui_impl_sdl2.cpp index 6d98a697e..1abe8b93d 100644 --- a/backends/imgui_impl_sdl2.cpp +++ b/backends/imgui_impl_sdl2.cpp @@ -605,7 +605,7 @@ static void ImGui_ImplSDL2_UpdateMouseData() #endif if (is_app_focused) { - // (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user) + // (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when io.ConfigNavMoveSetMousePos is enabled by user) if (io.WantSetMousePos) SDL_WarpMouseInWindow(bd->Window, (int)io.MousePos.x, (int)io.MousePos.y); diff --git a/backends/imgui_impl_sdl3.cpp b/backends/imgui_impl_sdl3.cpp index 599d3fc44..517ba1ada 100644 --- a/backends/imgui_impl_sdl3.cpp +++ b/backends/imgui_impl_sdl3.cpp @@ -573,7 +573,7 @@ static void ImGui_ImplSDL3_UpdateMouseData() #endif if (is_app_focused) { - // (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user) + // (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when io.ConfigNavMoveSetMousePos is enabled by user) if (io.WantSetMousePos) SDL_WarpMouseInWindow(bd->Window, io.MousePos.x, io.MousePos.y); diff --git a/backends/imgui_impl_win32.cpp b/backends/imgui_impl_win32.cpp index 0e9164efe..bbfa1a5be 100644 --- a/backends/imgui_impl_win32.cpp +++ b/backends/imgui_impl_win32.cpp @@ -308,7 +308,7 @@ static void ImGui_ImplWin32_UpdateMouseData() const bool is_app_focused = (focused_window == bd->hWnd); if (is_app_focused) { - // (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user) + // (Optional) Set OS mouse position from Dear ImGui if requested (rarely used, only when io.ConfigNavMoveSetMousePos is enabled by user) if (io.WantSetMousePos) { POINT pos = { (int)io.MousePos.x, (int)io.MousePos.y }; diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index a01d5d6bc..d67abea37 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -54,6 +54,11 @@ Breaking changes: - Won't warn: ImGui::Image((ImTextureID)(intptr_t)MyTextureData), ...); - Note that you can always define ImTextureID to be your own high-level structures (with dedicated constructors) if you like. +- IO: moved ImGuiConfigFlags_NavEnableSetMousePos to standalone io.ConfigNavMoveSetMousePos bool. +- IO: moved ImGuiConfigFlags_NavNoCaptureKeyboard to standalone io.ConfigNavCaptureKeyboard bool + (note the inverted value!). (#2517, #2009) + Kept legacy names (will obsolete) + code that copies settings once the first time. + Dynamically changing the old value won't work. Switch to using the new value! Other changes: diff --git a/imgui.cpp b/imgui.cpp index 971f48f16..fa865503c 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -183,8 +183,8 @@ CODE - Consoles/Tablet/Phone users: Consider using a Synergy 1.x server (on your PC) + run examples/libs/synergy/uSynergy.c (on your console/tablet/phone app) in order to share your PC mouse/keyboard. - See https://github.com/ocornut/imgui/wiki/Useful-Extensions#remoting for other remoting solutions. - - On a TV/console system where readability may be lower or mouse inputs may be awkward, you may want to set the ImGuiConfigFlags_NavEnableSetMousePos flag. - Enabling ImGuiConfigFlags_NavEnableSetMousePos + ImGuiBackendFlags_HasSetMousePos instructs Dear ImGui to move your mouse cursor along with navigation movements. + - On a TV/console system where readability may be lower or mouse inputs may be awkward, you may want to set the io.ConfigNavMoveSetMousePos flag. + Enabling io.ConfigNavMoveSetMousePos + ImGuiBackendFlags_HasSetMousePos instructs Dear ImGui to move your mouse cursor along with navigation movements. When enabled, the NewFrame() function may alter 'io.MousePos' and set 'io.WantSetMousePos' to notify you that it wants the mouse cursor to be moved. When that happens your backend NEEDS to move the OS or underlying mouse cursor on the next frame. Some of the backends in examples/ do that. (If you set the NavEnableSetMousePos flag but don't honor 'io.WantSetMousePos' properly, Dear ImGui will misbehave as it will see your mouse moving back & forth!) @@ -430,6 +430,9 @@ CODE When you are not sure about an old symbol or function name, try using the Search/Find function of your IDE to look for comments or references in all imgui files. You can read releases logs https://github.com/ocornut/imgui/releases for more details. + - 2024/10/14 (1.91.4) - moved ImGuiConfigFlags_NavEnableSetMousePos to standalone io.ConfigNavMoveSetMousePos bool. + moved ImGuiConfigFlags_NavNoCaptureKeyboard to standalone io.ConfigNavCaptureKeyboard bool (note the inverted value!). + kept legacy names (will obsolete) + code that copies settings once the first time. Dynamically changing the old value won't work. Switch to using the new value! - 2024/10/10 (1.91.4) - the typedef for ImTextureID now defaults to ImU64 instead of void*. (#1641) this removes the requirement to redefine it for backends which are e.g. storing descriptor sets or other 64-bits structures when building on 32-bits archs. It therefore simplify various building scripts/helpers. you may have compile-time issues if you were casting to 'void*' instead of 'ImTextureID' when passing your types to functions taking ImTextureID values, e.g. ImGui::Image(). @@ -5001,7 +5004,7 @@ void ImGui::UpdateHoveredWindowAndCaptureFlags() { if ((g.ActiveId != 0) || (modal_window != NULL)) io.WantCaptureKeyboard = true; - else if (io.NavActive && (io.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) && !(io.ConfigFlags & ImGuiConfigFlags_NavNoCaptureKeyboard)) + else if (io.NavActive && (io.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) && io.ConfigNavCaptureKeyboard) io.WantCaptureKeyboard = true; } if (g.WantCaptureKeyboardNextFrame != -1) // Manual override @@ -10456,8 +10459,20 @@ static void ImGui::ErrorCheckNewFrameSanityChecks() if (g.IO.ConfigErrorRecovery) IM_ASSERT(g.IO.ConfigErrorRecoveryEnableAssert || g.IO.ConfigErrorRecoveryEnableDebugLog || g.IO.ConfigErrorRecoveryEnableTooltip || g.ErrorCallback != NULL); - // Remap legacy clipboard handlers (OBSOLETED in 1.91.1, August 2024) #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + // Remap legacy names + if (g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableSetMousePos) + { + g.IO.ConfigNavMoveSetMousePos = true; + g.IO.ConfigFlags &= ~ImGuiConfigFlags_NavEnableSetMousePos; + } + if (g.IO.ConfigFlags & ImGuiConfigFlags_NavNoCaptureKeyboard) + { + g.IO.ConfigNavCaptureKeyboard = false; + g.IO.ConfigFlags &= ~ImGuiConfigFlags_NavNoCaptureKeyboard; + } + + // Remap legacy clipboard handlers (OBSOLETED in 1.91.1, August 2024) if (g.IO.GetClipboardTextFn != NULL && (g.PlatformIO.Platform_GetClipboardTextFn == NULL || g.PlatformIO.Platform_GetClipboardTextFn == Platform_GetClipboardTextFn_DefaultImpl)) g.PlatformIO.Platform_GetClipboardTextFn = [](ImGuiContext* ctx) { return ctx->IO.GetClipboardTextFn(ctx->IO.ClipboardUserData); }; if (g.IO.SetClipboardTextFn != NULL && (g.PlatformIO.Platform_SetClipboardTextFn == NULL || g.PlatformIO.Platform_SetClipboardTextFn == Platform_SetClipboardTextFn_DefaultImpl)) @@ -12168,7 +12183,7 @@ ImVec2 ImGui::FindBestWindowPosForPopup(ImGuiWindow* window) ImVec2 tooltip_pos = g.IO.MousePos + TOOLTIP_DEFAULT_OFFSET_MOUSE * scale; ImRect r_avoid; - if (!g.NavDisableHighlight && g.NavDisableMouseHover && !(g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableSetMousePos)) + if (!g.NavDisableHighlight && g.NavDisableMouseHover && !g.IO.ConfigNavMoveSetMousePos) r_avoid = ImRect(ref_pos.x - 16, ref_pos.y - 8, ref_pos.x + 16, ref_pos.y + 8); else r_avoid = ImRect(ref_pos.x - 16, ref_pos.y - 8, ref_pos.x + 24 * scale, ref_pos.y + 24 * scale); // FIXME: Hard-coded based on mouse cursor shape expectation. Exact dimension not very important. @@ -12973,7 +12988,7 @@ static void ImGui::NavUpdate() // Update mouse position if requested // (This will take into account the possibility that a Scroll was queued in the window to offset our absolute mouse position before scroll has been applied) - if (set_mouse_pos && (io.ConfigFlags & ImGuiConfigFlags_NavEnableSetMousePos) && (io.BackendFlags & ImGuiBackendFlags_HasSetMousePos)) + if (set_mouse_pos && io.ConfigNavMoveSetMousePos && (io.BackendFlags & ImGuiBackendFlags_HasSetMousePos)) TeleportMousePos(NavCalcPreferredRefPos()); // [DEBUG] diff --git a/imgui.h b/imgui.h index d18879ce1..c2aa54420 100644 --- a/imgui.h +++ b/imgui.h @@ -29,7 +29,7 @@ // Library Version // (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345') #define IMGUI_VERSION "1.91.4 WIP" -#define IMGUI_VERSION_NUM 19133 +#define IMGUI_VERSION_NUM 19134 #define IMGUI_HAS_TABLE /* @@ -1597,8 +1597,6 @@ enum ImGuiConfigFlags_ ImGuiConfigFlags_None = 0, ImGuiConfigFlags_NavEnableKeyboard = 1 << 0, // Master keyboard navigation enable flag. Enable full Tabbing + directional arrows + space/enter to activate. ImGuiConfigFlags_NavEnableGamepad = 1 << 1, // Master gamepad navigation enable flag. Backend also needs to set ImGuiBackendFlags_HasGamepad. - ImGuiConfigFlags_NavEnableSetMousePos = 1 << 2, // Instruct navigation to move the mouse cursor. May be useful on TV/console systems where moving a virtual mouse is awkward. Will update io.MousePos and set io.WantSetMousePos=true. If enabled you MUST honor io.WantSetMousePos requests in your backend, otherwise ImGui will react as if the mouse is jumping around back and forth. - ImGuiConfigFlags_NavNoCaptureKeyboard = 1 << 3, // Instruct navigation to not set the io.WantCaptureKeyboard flag when io.NavActive is set. ImGuiConfigFlags_NoMouse = 1 << 4, // Instruct dear imgui to disable mouse inputs and interactions. ImGuiConfigFlags_NoMouseCursorChange = 1 << 5, // Instruct backend to not alter mouse cursor shape and visibility. Use if the backend cursor changes are interfering with yours and you don't want to use SetMouseCursor() to change mouse cursor. You may want to honor requests from imgui by reading GetMouseCursor() yourself instead. ImGuiConfigFlags_NoKeyboard = 1 << 6, // Instruct dear imgui to disable keyboard inputs and interactions. This is done by ignoring keyboard events and clearing existing states. @@ -1606,6 +1604,11 @@ enum ImGuiConfigFlags_ // User storage (to allow your backend/engine to communicate to code that may be shared between multiple projects. Those flags are NOT used by core Dear ImGui) ImGuiConfigFlags_IsSRGB = 1 << 20, // Application is SRGB-aware. ImGuiConfigFlags_IsTouchScreen = 1 << 21, // Application is using a touch screen instead of a mouse. + +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS + ImGuiConfigFlags_NavEnableSetMousePos = 1 << 2, // [moved/renamed in 1.91.4] -> use bool io.ConfigNavMoveSetMousePos + ImGuiConfigFlags_NavNoCaptureKeyboard = 1 << 3, // [moved/renamed in 1.91.4] -> use bool io.ConfigNavCaptureKeyboard +#endif }; // Backend capabilities flags stored in io.BackendFlags. Set by imgui_impl_xxx or custom backend. @@ -1614,7 +1617,7 @@ enum ImGuiBackendFlags_ ImGuiBackendFlags_None = 0, ImGuiBackendFlags_HasGamepad = 1 << 0, // Backend Platform supports gamepad and currently has one connected. ImGuiBackendFlags_HasMouseCursors = 1 << 1, // Backend Platform supports honoring GetMouseCursor() value to change the OS cursor shape. - ImGuiBackendFlags_HasSetMousePos = 1 << 2, // Backend Platform supports io.WantSetMousePos requests to reposition the OS mouse position (only used if ImGuiConfigFlags_NavEnableSetMousePos is set). + ImGuiBackendFlags_HasSetMousePos = 1 << 2, // Backend Platform supports io.WantSetMousePos requests to reposition the OS mouse position (only used if io.ConfigNavMoveSetMousePos is set). ImGuiBackendFlags_RendererHasVtxOffset = 1 << 3, // Backend Renderer supports ImDrawCmd::VtxOffset. This enables output of large meshes (64K+ vertices) while still using 16-bit indices. }; @@ -2242,17 +2245,19 @@ struct ImGuiIO // Miscellaneous options // (you can visualize and interact with all options in 'Demo->Configuration') - bool MouseDrawCursor; // = false // Request ImGui to draw a mouse cursor for you (if you are on a platform without a mouse cursor). Cannot be easily renamed to 'io.ConfigXXX' because this is frequently used by backend implementations. - bool ConfigMacOSXBehaviors; // = defined(__APPLE__) // Swap Cmd<>Ctrl keys + OS X style text editing cursor movement using Alt instead of Ctrl, Shortcuts using Cmd/Super instead of Ctrl, Line/Text Start and End using Cmd+Arrows instead of Home/End, Double click selects by word instead of selecting whole text, Multi-selection in lists uses Cmd/Super instead of Ctrl. - bool ConfigNavSwapGamepadButtons; // = false // Swap Activate<>Cancel (A<>B) buttons, matching typical "Nintendo/Japanese style" gamepad layout. - bool ConfigInputTrickleEventQueue; // = true // Enable input queue trickling: some types of events submitted during the same frame (e.g. button down + up) will be spread over multiple frames, improving interactions with low framerates. - bool ConfigInputTextCursorBlink; // = true // Enable blinking cursor (optional as some users consider it to be distracting). - bool ConfigInputTextEnterKeepActive; // = false // [BETA] Pressing Enter will keep item active and select contents (single-line only). - bool ConfigDragClickToInputText; // = false // [BETA] Enable turning DragXXX widgets into text input with a simple mouse click-release (without moving). Not desirable on devices without a keyboard. - bool ConfigWindowsResizeFromEdges; // = true // Enable resizing of windows from their edges and from the lower-left corner. This requires (io.BackendFlags & ImGuiBackendFlags_HasMouseCursors) because it needs mouse cursor feedback. (This used to be a per-window ImGuiWindowFlags_ResizeFromAnySide flag) - bool ConfigWindowsMoveFromTitleBarOnly; // = false // Enable allowing to move windows only when clicking on their title bar. Does not apply to windows without a title bar. - bool ConfigScrollbarScrollByPage; // = true // Enable scrolling page by page when clicking outside the scrollbar grab. When disabled, always scroll to clicked location. When enabled, Shift+Click scrolls to clicked location. - float ConfigMemoryCompactTimer; // = 60.0f // Timer (in seconds) to free transient windows/tables memory buffers when unused. Set to -1.0f to disable. + bool MouseDrawCursor; // = false // Request ImGui to draw a mouse cursor for you (if you are on a platform without a mouse cursor). Cannot be easily renamed to 'io.ConfigXXX' because this is frequently used by backend implementations. + bool ConfigMacOSXBehaviors; // = defined(__APPLE__) // Swap Cmd<>Ctrl keys + OS X style text editing cursor movement using Alt instead of Ctrl, Shortcuts using Cmd/Super instead of Ctrl, Line/Text Start and End using Cmd+Arrows instead of Home/End, Double click selects by word instead of selecting whole text, Multi-selection in lists uses Cmd/Super instead of Ctrl. + bool ConfigNavSwapGamepadButtons; // = false // Swap Activate<>Cancel (A<>B) buttons, matching typical "Nintendo/Japanese style" gamepad layout. + bool ConfigNavMoveSetMousePos; // = false // Directional/tabbing navigation teleports the mouse cursor. May be useful on TV/console systems where moving a virtual mouse is difficult. Will update io.MousePos and set io.WantSetMousePos=true. + bool ConfigNavCaptureKeyboard; // = true // Sets io.WantCaptureKeyboard when io.NavActive is set. + bool ConfigInputTrickleEventQueue; // = true // Enable input queue trickling: some types of events submitted during the same frame (e.g. button down + up) will be spread over multiple frames, improving interactions with low framerates. + bool ConfigInputTextCursorBlink; // = true // Enable blinking cursor (optional as some users consider it to be distracting). + bool ConfigInputTextEnterKeepActive; // = false // [BETA] Pressing Enter will keep item active and select contents (single-line only). + bool ConfigDragClickToInputText; // = false // [BETA] Enable turning DragXXX widgets into text input with a simple mouse click-release (without moving). Not desirable on devices without a keyboard. + bool ConfigWindowsResizeFromEdges; // = true // Enable resizing of windows from their edges and from the lower-left corner. This requires (io.BackendFlags & ImGuiBackendFlags_HasMouseCursors) because it needs mouse cursor feedback. (This used to be a per-window ImGuiWindowFlags_ResizeFromAnySide flag) + bool ConfigWindowsMoveFromTitleBarOnly; // = false // Enable allowing to move windows only when clicking on their title bar. Does not apply to windows without a title bar. + bool ConfigScrollbarScrollByPage; // = true // Enable scrolling page by page when clicking outside the scrollbar grab. When disabled, always scroll to clicked location. When enabled, Shift+Click scrolls to clicked location. + float ConfigMemoryCompactTimer; // = 60.0f // Timer (in seconds) to free transient windows/tables memory buffers when unused. Set to -1.0f to disable. // Inputs Behaviors // (other variables, ones which are expected to be tweaked within UI code, are exposed in ImGuiStyle) @@ -2358,7 +2363,7 @@ struct ImGuiIO bool WantCaptureMouse; // Set when Dear ImGui will use mouse inputs, in this case do not dispatch them to your main game/application (either way, always pass on mouse inputs to imgui). (e.g. unclicked mouse is hovering over an imgui window, widget is active, mouse was clicked over an imgui window, etc.). bool WantCaptureKeyboard; // Set when Dear ImGui will use keyboard inputs, in this case do not dispatch them to your main game/application (either way, always pass keyboard inputs to imgui). (e.g. InputText active, or an imgui window is focused and navigation is enabled, etc.). bool WantTextInput; // Mobile/console: when set, you may display an on-screen keyboard. This is set by Dear ImGui when it wants textual keyboard input to happen (e.g. when a InputText widget is active). - bool WantSetMousePos; // MousePos has been altered, backend should reposition mouse on next frame. Rarely used! Set only when ImGuiConfigFlags_NavEnableSetMousePos flag is enabled. + bool WantSetMousePos; // MousePos has been altered, backend should reposition mouse on next frame. Rarely used! Set only when io.ConfigNavMoveSetMousePos is enabled. bool WantSaveIniSettings; // When manual .ini load/save is active (io.IniFilename == NULL), this will be set to notify your application that you can call SaveIniSettingsToMemory() and save yourself. Important: clear io.WantSaveIniSettings yourself after saving! bool NavActive; // Keyboard/Gamepad navigation is currently allowed (will handle ImGuiKey_NavXXX events) = a window is focused and it doesn't use the ImGuiWindowFlags_NoNavInputs flag. bool NavVisible; // Keyboard/Gamepad navigation is visible and allowed (will handle ImGuiKey_NavXXX events). diff --git a/imgui_demo.cpp b/imgui_demo.cpp index a85e28e54..1cf4b5eb6 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -501,8 +501,6 @@ void ImGui::ShowDemoWindow(bool* p_open) ImGui::SameLine(); HelpMarker("Enable keyboard controls."); ImGui::CheckboxFlags("io.ConfigFlags: NavEnableGamepad", &io.ConfigFlags, ImGuiConfigFlags_NavEnableGamepad); ImGui::SameLine(); HelpMarker("Enable gamepad controls. Require backend to set io.BackendFlags |= ImGuiBackendFlags_HasGamepad.\n\nRead instructions in imgui.cpp for details."); - ImGui::CheckboxFlags("io.ConfigFlags: NavEnableSetMousePos", &io.ConfigFlags, ImGuiConfigFlags_NavEnableSetMousePos); - ImGui::SameLine(); HelpMarker("Instruct navigation to move the mouse cursor. See comment for ImGuiConfigFlags_NavEnableSetMousePos."); ImGui::CheckboxFlags("io.ConfigFlags: NoMouse", &io.ConfigFlags, ImGuiConfigFlags_NoMouse); ImGui::SameLine(); HelpMarker("Instruct dear imgui to disable mouse inputs and interactions."); @@ -529,6 +527,12 @@ void ImGui::ShowDemoWindow(bool* p_open) ImGui::Checkbox("io.MouseDrawCursor", &io.MouseDrawCursor); ImGui::SameLine(); HelpMarker("Instruct Dear ImGui to render a mouse cursor itself. Note that a mouse cursor rendered via your application GPU rendering path will feel more laggy than hardware cursor, but will be more in sync with your other visuals.\n\nSome desktop applications may use both kinds of cursors (e.g. enable software cursor only when resizing/dragging something)."); + ImGui::SeparatorText("Navigation"); + ImGui::Checkbox("io.ConfigNavSwapGamepadButtons", &io.ConfigNavSwapGamepadButtons); + ImGui::Checkbox("io.ConfigNavMoveSetMousePos", &io.ConfigNavMoveSetMousePos); + ImGui::SameLine(); HelpMarker("Directional/tabbing navigation teleports the mouse cursor. May be useful on TV/console systems where moving a virtual mouse is difficult"); + ImGui::Checkbox("io.ConfigNavCaptureKeyboard", &io.ConfigNavCaptureKeyboard); + ImGui::SeparatorText("Widgets"); ImGui::Checkbox("io.ConfigInputTextCursorBlink", &io.ConfigInputTextCursorBlink); ImGui::SameLine(); HelpMarker("Enable blinking cursor (optional as some users consider it to be distracting)."); @@ -7753,12 +7757,12 @@ void ImGui::ShowAboutWindow(bool* p_open) ImGui::Text("io.ConfigFlags: 0x%08X", io.ConfigFlags); if (io.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) ImGui::Text(" NavEnableKeyboard"); if (io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) ImGui::Text(" NavEnableGamepad"); - if (io.ConfigFlags & ImGuiConfigFlags_NavEnableSetMousePos) ImGui::Text(" NavEnableSetMousePos"); - if (io.ConfigFlags & ImGuiConfigFlags_NavNoCaptureKeyboard) ImGui::Text(" NavNoCaptureKeyboard"); if (io.ConfigFlags & ImGuiConfigFlags_NoMouse) ImGui::Text(" NoMouse"); if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange) ImGui::Text(" NoMouseCursorChange"); if (io.MouseDrawCursor) ImGui::Text("io.MouseDrawCursor"); if (io.ConfigMacOSXBehaviors) ImGui::Text("io.ConfigMacOSXBehaviors"); + if (io.ConfigNavMoveSetMousePos) ImGui::Text("io.ConfigNavMoveSetMousePos"); + if (io.ConfigNavCaptureKeyboard) ImGui::Text("io.ConfigNavCaptureKeyboard"); if (io.ConfigInputTextCursorBlink) ImGui::Text("io.ConfigInputTextCursorBlink"); if (io.ConfigWindowsResizeFromEdges) ImGui::Text("io.ConfigWindowsResizeFromEdges"); if (io.ConfigWindowsMoveFromTitleBarOnly) ImGui::Text("io.ConfigWindowsMoveFromTitleBarOnly"); diff --git a/imgui_internal.h b/imgui_internal.h index 5722291af..68593e8f4 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -2143,7 +2143,7 @@ struct ImGuiContext ImGuiInputSource NavInputSource; // Keyboard or Gamepad mode? THIS CAN ONLY BE ImGuiInputSource_Keyboard or ImGuiInputSource_Mouse ImGuiSelectionUserData NavLastValidSelectionUserData; // Last valid data passed to SetNextItemSelectionUser(), or -1. For current window. Not reset when focusing an item that doesn't have selection data. bool NavIdIsAlive; // Nav widget has been seen this frame ~~ NavRectRel is valid - bool NavMousePosDirty; // When set we will update mouse position if (io.ConfigFlags & ImGuiConfigFlags_NavEnableSetMousePos) if set (NB: this not enabled by default) + bool NavMousePosDirty; // When set we will update mouse position if io.ConfigNavMoveSetMousePos is set (not enabled by default) bool NavDisableHighlight; // When user starts using mouse, we hide gamepad/keyboard highlight (NB: but they are still available, which is why NavDisableHighlight isn't always != NavDisableMouseHover) bool NavDisableMouseHover; // When user starts using gamepad/keyboard, we hide mouse hovering highlight until mouse is touched again. From ba5161740ea84e883cd89c775607aaf96a8159c2 Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 14 Oct 2024 16:52:25 +0200 Subject: [PATCH 16/22] Amend d885fe4, fixes default value of ConfigNavCaptureKeyboard. (#2517, #2009) --- imgui.cpp | 2 ++ imgui.h | 24 ++++++++++++------------ imgui_demo.cpp | 1 + 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index fa865503c..47ea5f471 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1406,6 +1406,8 @@ ImGuiIO::ImGuiIO() ConfigMacOSXBehaviors = false; #endif ConfigNavSwapGamepadButtons = false; + ConfigNavMoveSetMousePos = false; + ConfigNavCaptureKeyboard = true; ConfigInputTrickleEventQueue = true; ConfigInputTextCursorBlink = true; ConfigInputTextEnterKeepActive = false; diff --git a/imgui.h b/imgui.h index c2aa54420..6a2523010 100644 --- a/imgui.h +++ b/imgui.h @@ -2245,19 +2245,19 @@ struct ImGuiIO // Miscellaneous options // (you can visualize and interact with all options in 'Demo->Configuration') - bool MouseDrawCursor; // = false // Request ImGui to draw a mouse cursor for you (if you are on a platform without a mouse cursor). Cannot be easily renamed to 'io.ConfigXXX' because this is frequently used by backend implementations. - bool ConfigMacOSXBehaviors; // = defined(__APPLE__) // Swap Cmd<>Ctrl keys + OS X style text editing cursor movement using Alt instead of Ctrl, Shortcuts using Cmd/Super instead of Ctrl, Line/Text Start and End using Cmd+Arrows instead of Home/End, Double click selects by word instead of selecting whole text, Multi-selection in lists uses Cmd/Super instead of Ctrl. - bool ConfigNavSwapGamepadButtons; // = false // Swap Activate<>Cancel (A<>B) buttons, matching typical "Nintendo/Japanese style" gamepad layout. - bool ConfigNavMoveSetMousePos; // = false // Directional/tabbing navigation teleports the mouse cursor. May be useful on TV/console systems where moving a virtual mouse is difficult. Will update io.MousePos and set io.WantSetMousePos=true. - bool ConfigNavCaptureKeyboard; // = true // Sets io.WantCaptureKeyboard when io.NavActive is set. - bool ConfigInputTrickleEventQueue; // = true // Enable input queue trickling: some types of events submitted during the same frame (e.g. button down + up) will be spread over multiple frames, improving interactions with low framerates. - bool ConfigInputTextCursorBlink; // = true // Enable blinking cursor (optional as some users consider it to be distracting). - bool ConfigInputTextEnterKeepActive; // = false // [BETA] Pressing Enter will keep item active and select contents (single-line only). - bool ConfigDragClickToInputText; // = false // [BETA] Enable turning DragXXX widgets into text input with a simple mouse click-release (without moving). Not desirable on devices without a keyboard. - bool ConfigWindowsResizeFromEdges; // = true // Enable resizing of windows from their edges and from the lower-left corner. This requires (io.BackendFlags & ImGuiBackendFlags_HasMouseCursors) because it needs mouse cursor feedback. (This used to be a per-window ImGuiWindowFlags_ResizeFromAnySide flag) + bool MouseDrawCursor; // = false // Request ImGui to draw a mouse cursor for you (if you are on a platform without a mouse cursor). Cannot be easily renamed to 'io.ConfigXXX' because this is frequently used by backend implementations. + bool ConfigMacOSXBehaviors; // = defined(__APPLE__) // Swap Cmd<>Ctrl keys + OS X style text editing cursor movement using Alt instead of Ctrl, Shortcuts using Cmd/Super instead of Ctrl, Line/Text Start and End using Cmd+Arrows instead of Home/End, Double click selects by word instead of selecting whole text, Multi-selection in lists uses Cmd/Super instead of Ctrl. + bool ConfigNavSwapGamepadButtons; // = false // Swap Activate<>Cancel (A<>B) buttons, matching typical "Nintendo/Japanese style" gamepad layout. + bool ConfigNavMoveSetMousePos; // = false // Directional/tabbing navigation teleports the mouse cursor. May be useful on TV/console systems where moving a virtual mouse is difficult. Will update io.MousePos and set io.WantSetMousePos=true. + bool ConfigNavCaptureKeyboard; // = true // Sets io.WantCaptureKeyboard when io.NavActive is set. + bool ConfigInputTrickleEventQueue; // = true // Enable input queue trickling: some types of events submitted during the same frame (e.g. button down + up) will be spread over multiple frames, improving interactions with low framerates. + bool ConfigInputTextCursorBlink; // = true // Enable blinking cursor (optional as some users consider it to be distracting). + bool ConfigInputTextEnterKeepActive; // = false // [BETA] Pressing Enter will keep item active and select contents (single-line only). + bool ConfigDragClickToInputText; // = false // [BETA] Enable turning DragXXX widgets into text input with a simple mouse click-release (without moving). Not desirable on devices without a keyboard. + bool ConfigWindowsResizeFromEdges; // = true // Enable resizing of windows from their edges and from the lower-left corner. This requires (io.BackendFlags & ImGuiBackendFlags_HasMouseCursors) because it needs mouse cursor feedback. (This used to be a per-window ImGuiWindowFlags_ResizeFromAnySide flag) bool ConfigWindowsMoveFromTitleBarOnly; // = false // Enable allowing to move windows only when clicking on their title bar. Does not apply to windows without a title bar. - bool ConfigScrollbarScrollByPage; // = true // Enable scrolling page by page when clicking outside the scrollbar grab. When disabled, always scroll to clicked location. When enabled, Shift+Click scrolls to clicked location. - float ConfigMemoryCompactTimer; // = 60.0f // Timer (in seconds) to free transient windows/tables memory buffers when unused. Set to -1.0f to disable. + bool ConfigScrollbarScrollByPage; // = true // Enable scrolling page by page when clicking outside the scrollbar grab. When disabled, always scroll to clicked location. When enabled, Shift+Click scrolls to clicked location. + float ConfigMemoryCompactTimer; // = 60.0f // Timer (in seconds) to free transient windows/tables memory buffers when unused. Set to -1.0f to disable. // Inputs Behaviors // (other variables, ones which are expected to be tweaked within UI code, are exposed in ImGuiStyle) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 1cf4b5eb6..9c9868aa5 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -7759,6 +7759,7 @@ void ImGui::ShowAboutWindow(bool* p_open) if (io.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) ImGui::Text(" NavEnableGamepad"); if (io.ConfigFlags & ImGuiConfigFlags_NoMouse) ImGui::Text(" NoMouse"); if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange) ImGui::Text(" NoMouseCursorChange"); + if (io.ConfigFlags & ImGuiConfigFlags_NoKeyboard) ImGui::Text(" NoKeyboard"); if (io.MouseDrawCursor) ImGui::Text("io.MouseDrawCursor"); if (io.ConfigMacOSXBehaviors) ImGui::Text("io.ConfigMacOSXBehaviors"); if (io.ConfigNavMoveSetMousePos) ImGui::Text("io.ConfigNavMoveSetMousePos"); From b0010389011de8c5229775b71233a79e05ec1e7f Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 14 Oct 2024 16:57:34 +0200 Subject: [PATCH 17/22] Nav: added io.ConfigNavEscapeClearFocusWindow to clear focused window on Escape. (#3200) + pressing escape to hide nav highlight doesn't clear location from when ctrl+tabbing back into same window later. --- docs/CHANGELOG.txt | 3 +++ imgui.cpp | 7 +++++-- imgui.h | 1 + imgui_demo.cpp | 2 ++ 4 files changed, 11 insertions(+), 2 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index d67abea37..aa64698c8 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -67,6 +67,9 @@ Other changes: state to draw callbacks. (#6969, #5834, #7468, #3590) - IO: WantCaptureKeyboard is never set when ImGuiConfigFlags_NoKeyboard is enabled. (#4921) - Error Handling: turned a few more functions into recoverable errors. (#1651) +- Nav: added io.ConfigNavEscapeClearFocusWindow to clear focused window on Escape. (#3200) +- Nav: pressing escape to hide nav highlight doesn't clear location from when ctrl+tabbing back + into same window later. - DrawList: AddCallback() added an optional size parameter allowing to copy and store any amount of user data for usage by callbacks: (#6969, #4770, #7665) - If userdata_size == 0: we copy/store the 'userdata' argument as-is (existing behavior). diff --git a/imgui.cpp b/imgui.cpp index 47ea5f471..486832ec3 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1408,6 +1408,7 @@ ImGuiIO::ImGuiIO() ConfigNavSwapGamepadButtons = false; ConfigNavMoveSetMousePos = false; ConfigNavCaptureKeyboard = true; + ConfigNavEscapeClearFocusWindow = false; ConfigInputTrickleEventQueue = true; ConfigInputTextCursorBlink = true; ConfigInputTextEnterKeepActive = false; @@ -13316,7 +13317,7 @@ void ImGui::NavMoveRequestApplyResult() NavRestoreHighlightAfterMove(); } -// Process NavCancel input (to close a popup, get back to parent, clear focus) +// Process Escape/NavCancel input (to close a popup, get back to parent, clear focus) // FIXME: In order to support e.g. Escape to clear a selection we'll need: // - either to store the equivalent of ActiveIdUsingKeyInputMask for a FocusScope and test for it. // - either to move most/all of those tests to the epilogue/end functions of the scope they are dealing with (e.g. exit child window in EndChild()) or in EndFrame(), to allow an earlier intercept @@ -13358,11 +13359,13 @@ static void ImGui::NavUpdateCancelRequest() { // Clear NavLastId for popups but keep it for regular child window so we can leave one and come back where we were // FIXME-NAV: This should happen on window appearing. - if (g.NavWindow && ((g.NavWindow->Flags & ImGuiWindowFlags_Popup) || !(g.NavWindow->Flags & ImGuiWindowFlags_ChildWindow))) + if (g.NavWindow && ((g.NavWindow->Flags & ImGuiWindowFlags_Popup)))// || !(g.NavWindow->Flags & ImGuiWindowFlags_ChildWindow))) g.NavWindow->NavLastIds[0] = 0; // Clear nav focus g.NavId = 0; + if (g.IO.ConfigNavEscapeClearFocusWindow) + FocusWindow(NULL); } } diff --git a/imgui.h b/imgui.h index 6a2523010..7d17aede6 100644 --- a/imgui.h +++ b/imgui.h @@ -2250,6 +2250,7 @@ struct ImGuiIO bool ConfigNavSwapGamepadButtons; // = false // Swap Activate<>Cancel (A<>B) buttons, matching typical "Nintendo/Japanese style" gamepad layout. bool ConfigNavMoveSetMousePos; // = false // Directional/tabbing navigation teleports the mouse cursor. May be useful on TV/console systems where moving a virtual mouse is difficult. Will update io.MousePos and set io.WantSetMousePos=true. bool ConfigNavCaptureKeyboard; // = true // Sets io.WantCaptureKeyboard when io.NavActive is set. + bool ConfigNavEscapeClearFocusWindow;// = false // Pressing Escape (when no item is active, no popup open etc.) clears focused window + navigation id/highlight. bool ConfigInputTrickleEventQueue; // = true // Enable input queue trickling: some types of events submitted during the same frame (e.g. button down + up) will be spread over multiple frames, improving interactions with low framerates. bool ConfigInputTextCursorBlink; // = true // Enable blinking cursor (optional as some users consider it to be distracting). bool ConfigInputTextEnterKeepActive; // = false // [BETA] Pressing Enter will keep item active and select contents (single-line only). diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 9c9868aa5..dca674054 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -532,6 +532,8 @@ void ImGui::ShowDemoWindow(bool* p_open) ImGui::Checkbox("io.ConfigNavMoveSetMousePos", &io.ConfigNavMoveSetMousePos); ImGui::SameLine(); HelpMarker("Directional/tabbing navigation teleports the mouse cursor. May be useful on TV/console systems where moving a virtual mouse is difficult"); ImGui::Checkbox("io.ConfigNavCaptureKeyboard", &io.ConfigNavCaptureKeyboard); + ImGui::Checkbox("io.ConfigNavEscapeClearFocusWindow", &io.ConfigNavEscapeClearFocusWindow); + ImGui::SameLine(); HelpMarker("Pressing Escape clears focused window."); ImGui::SeparatorText("Widgets"); ImGui::Checkbox("io.ConfigInputTextCursorBlink", &io.ConfigInputTextCursorBlink); From 626d358e55e92ceaacf6c0200d32cbf9d36fe6eb Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 14 Oct 2024 17:10:36 +0200 Subject: [PATCH 18/22] Nav: fixed Ctrl+Tab so when starting with no focused window it starts from the top-most window. (#3200) --- docs/CHANGELOG.txt | 6 ++++-- imgui.cpp | 15 +++++++++------ 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index aa64698c8..203d4d954 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -68,8 +68,10 @@ Other changes: - IO: WantCaptureKeyboard is never set when ImGuiConfigFlags_NoKeyboard is enabled. (#4921) - Error Handling: turned a few more functions into recoverable errors. (#1651) - Nav: added io.ConfigNavEscapeClearFocusWindow to clear focused window on Escape. (#3200) -- Nav: pressing escape to hide nav highlight doesn't clear location from when ctrl+tabbing back - into same window later. +- Nav: pressing escape to hide nav highlight doesn't clear location from when ctrl+tabbing + back into same window later. +- Nav: fixed Ctrl+Tab so when starting with no focused window it starts from the top-most + window. (#3200) - DrawList: AddCallback() added an optional size parameter allowing to copy and store any amount of user data for usage by callbacks: (#6969, #4770, #7665) - If userdata_size == 0: we copy/store the 'userdata' argument as-is (existing behavior). diff --git a/imgui.cpp b/imgui.cpp index 486832ec3..7da199c5c 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -13540,7 +13540,7 @@ static ImGuiWindow* FindWindowNavFocusable(int i_start, int i_stop, int dir) // return NULL; } -static void NavUpdateWindowingHighlightWindow(int focus_change_dir) +static void NavUpdateWindowingTarget(int focus_change_dir) { ImGuiContext& g = *GImGui; IM_ASSERT(g.NavWindowingTarget); @@ -13592,14 +13592,17 @@ static void ImGui::NavUpdateWindowing() const bool keyboard_prev_window = allow_windowing && g.ConfigNavWindowingKeyPrev && Shortcut(g.ConfigNavWindowingKeyPrev, ImGuiInputFlags_Repeat | ImGuiInputFlags_RouteAlways, owner_id); const bool start_windowing_with_gamepad = allow_windowing && nav_gamepad_active && !g.NavWindowingTarget && IsKeyPressed(ImGuiKey_NavGamepadMenu, ImGuiInputFlags_None); const bool start_windowing_with_keyboard = allow_windowing && !g.NavWindowingTarget && (keyboard_next_window || keyboard_prev_window); // Note: enabled even without NavEnableKeyboard! + bool just_started_windowing_from_null_focus = false; if (start_windowing_with_gamepad || start_windowing_with_keyboard) if (ImGuiWindow* window = g.NavWindow ? g.NavWindow : FindWindowNavFocusable(g.WindowsFocusOrder.Size - 1, -INT_MAX, -1)) { - g.NavWindowingTarget = g.NavWindowingTargetAnim = window->RootWindow; + g.NavWindowingTarget = g.NavWindowingTargetAnim = window->RootWindow; // Current location g.NavWindowingTimer = g.NavWindowingHighlightAlpha = 0.0f; g.NavWindowingAccumDeltaPos = g.NavWindowingAccumDeltaSize = ImVec2(0.0f, 0.0f); g.NavWindowingToggleLayer = start_windowing_with_gamepad ? true : false; // Gamepad starts toggling layer g.NavInputSource = start_windowing_with_keyboard ? ImGuiInputSource_Keyboard : ImGuiInputSource_Gamepad; + if (g.NavWindow == NULL) + just_started_windowing_from_null_focus = true; // Manually register ownership of our mods. Using a global route in the Shortcut() calls instead would probably be correct but may have more side-effects. if (keyboard_next_window || keyboard_prev_window) @@ -13615,9 +13618,9 @@ static void ImGui::NavUpdateWindowing() // Select window to focus const int focus_change_dir = (int)IsKeyPressed(ImGuiKey_GamepadL1) - (int)IsKeyPressed(ImGuiKey_GamepadR1); - if (focus_change_dir != 0) + if (focus_change_dir != 0 && !just_started_windowing_from_null_focus) { - NavUpdateWindowingHighlightWindow(focus_change_dir); + NavUpdateWindowingTarget(focus_change_dir); g.NavWindowingHighlightAlpha = 1.0f; } @@ -13640,8 +13643,8 @@ static void ImGui::NavUpdateWindowing() ImGuiKeyChord shared_mods = ((g.ConfigNavWindowingKeyNext ? g.ConfigNavWindowingKeyNext : ImGuiMod_Mask_) & (g.ConfigNavWindowingKeyPrev ? g.ConfigNavWindowingKeyPrev : ImGuiMod_Mask_)) & ImGuiMod_Mask_; IM_ASSERT(shared_mods != 0); // Next/Prev shortcut currently needs a shared modifier to "hold", otherwise Prev actions would keep cycling between two windows. g.NavWindowingHighlightAlpha = ImMax(g.NavWindowingHighlightAlpha, ImSaturate((g.NavWindowingTimer - NAV_WINDOWING_HIGHLIGHT_DELAY) / 0.05f)); // 1.0f - if (keyboard_next_window || keyboard_prev_window) - NavUpdateWindowingHighlightWindow(keyboard_next_window ? -1 : +1); + if ((keyboard_next_window || keyboard_prev_window) && !just_started_windowing_from_null_focus) + NavUpdateWindowingTarget(keyboard_next_window ? -1 : +1); else if ((io.KeyMods & shared_mods) != shared_mods) apply_focus_window = g.NavWindowingTarget; } From ad37b79bca2bf548c22ca2276dd209f05583e729 Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 14 Oct 2024 17:30:14 +0200 Subject: [PATCH 19/22] Nav: shallow tidying up. --- imgui.cpp | 8 +++----- imgui_internal.h | 2 +- imgui_widgets.cpp | 4 ++-- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 7da199c5c..eafb7a84d 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4443,9 +4443,9 @@ bool ImGui::IsItemHovered(ImGuiHoveredFlags flags) if (g.NavDisableMouseHover && !g.NavDisableHighlight && !(flags & ImGuiHoveredFlags_NoNavOverride)) { - if ((g.LastItemData.InFlags & ImGuiItemFlags_Disabled) && !(flags & ImGuiHoveredFlags_AllowWhenDisabled)) + if (g.LastItemData.ID == g.NavId && g.NavId != 0) // IsItemFocused() return false; - if (!IsItemFocused()) + if ((g.LastItemData.InFlags & ImGuiItemFlags_Disabled) && !(flags & ImGuiHoveredFlags_AllowWhenDisabled)) return false; if (flags & ImGuiHoveredFlags_ForTooltip) @@ -5784,9 +5784,7 @@ bool ImGui::IsItemDeactivatedAfterEdit() bool ImGui::IsItemFocused() { ImGuiContext& g = *GImGui; - if (g.NavId != g.LastItemData.ID || g.NavId == 0) - return false; - return true; + return g.NavId == g.LastItemData.ID && g.NavId != 0; } // Important: this can be useful but it is NOT equivalent to the behavior of e.g.Button()! diff --git a/imgui_internal.h b/imgui_internal.h index 68593e8f4..99421b700 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -906,7 +906,7 @@ enum ImGuiButtonFlagsPrivate_ ImGuiButtonFlags_DontClosePopups = 1 << 13, // disable automatically closing parent popup on press // [UNUSED] //ImGuiButtonFlags_Disabled = 1 << 14, // disable interactions -> use BeginDisabled() or ImGuiItemFlags_Disabled ImGuiButtonFlags_AlignTextBaseLine = 1 << 15, // vertically align button to match text baseline - ButtonEx() only // FIXME: Should be removed and handled by SmallButton(), not possible currently because of DC.CursorPosPrevLine - ImGuiButtonFlags_NoKeyModifiers = 1 << 16, // disable mouse interaction if a key modifier is held + ImGuiButtonFlags_NoKeyModsAllowed = 1 << 16, // disable mouse interaction if a key modifier is held ImGuiButtonFlags_NoHoldingActiveId = 1 << 17, // don't set ActiveId while holding the mouse (ImGuiButtonFlags_PressedOnClick only) ImGuiButtonFlags_NoNavFocus = 1 << 18, // don't override navigation focus when activated (FIXME: this is essentially used every time an item uses ImGuiItemFlags_NoNav, but because legacy specs don't requires LastItemData to be set ButtonBehavior(), we can't poll g.LastItemData.InFlags) ImGuiButtonFlags_NoHoveredOnFocus = 1 << 19, // don't report as hovered when nav focus is on this item diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index aac7383b1..8cdd4aa27 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -561,7 +561,7 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool } // Process initial action - if (!(flags & ImGuiButtonFlags_NoKeyModifiers) || (!g.IO.KeyCtrl && !g.IO.KeyShift && !g.IO.KeyAlt)) + if (!(flags & ImGuiButtonFlags_NoKeyModsAllowed) || (!g.IO.KeyCtrl && !g.IO.KeyShift && !g.IO.KeyAlt)) { if (mouse_button_clicked != -1 && g.ActiveId != id) { @@ -6604,7 +6604,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l else { if (window != g.HoveredWindow || !is_mouse_x_over_arrow) - button_flags |= ImGuiButtonFlags_NoKeyModifiers; + button_flags |= ImGuiButtonFlags_NoKeyModsAllowed; } bool hovered, held; From 462d167456852387dcc6c3d03f1ad502992108c0 Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 14 Oct 2024 17:37:36 +0200 Subject: [PATCH 20/22] Nav: rectangle highlight not rendered for items with ImGuiItemFlags_NoNav. (#8057) Not fully honored in ItemHoverable/IsItemHovered, seems more destructive. This is mostly designed to avoid rectangle being rendered by large InvisibleButton() when ctrl+tabbing back to a window with a big one. --- docs/CHANGELOG.txt | 2 ++ imgui.cpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 203d4d954..6a062c459 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -72,6 +72,8 @@ Other changes: back into same window later. - Nav: fixed Ctrl+Tab so when starting with no focused window it starts from the top-most window. (#3200) +- Nav: rectangle highlight not rendered for items with ImGuiItemFlags_NoNav. Can be relevant + when e.g activating the item with mouse, then ctrl+tabbing back and forth. - DrawList: AddCallback() added an optional size parameter allowing to copy and store any amount of user data for usage by callbacks: (#6969, #4770, #7665) - If userdata_size == 0: we copy/store the 'userdata' argument as-is (existing behavior). diff --git a/imgui.cpp b/imgui.cpp index eafb7a84d..0ca2f4ab1 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3701,6 +3701,8 @@ void ImGui::RenderNavHighlight(const ImRect& bb, ImGuiID id, ImGuiNavHighlightFl return; if (g.NavDisableHighlight && !(flags & ImGuiNavHighlightFlags_AlwaysDraw)) return; + if (id == g.LastItemData.ID && (g.LastItemData.InFlags & ImGuiItemFlags_NoNav)) + return; ImGuiWindow* window = g.CurrentWindow; if (window->DC.NavHideHighlightOneFrame) return; From 97da66209cffd84a6959bced872da06a91213402 Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 14 Oct 2024 19:03:33 +0200 Subject: [PATCH 21/22] Internals: removing ImGuiButtonFlags_Repeat (in favor of ImGuiItemFlags_ButtonRepeat), ImGuiButtonFlags_DontClosePopups (unused) --- imgui_internal.h | 4 ++-- imgui_widgets.cpp | 15 ++++++++------- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/imgui_internal.h b/imgui_internal.h index 99421b700..5e378d669 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -900,10 +900,10 @@ enum ImGuiButtonFlagsPrivate_ ImGuiButtonFlags_PressedOnRelease = 1 << 7, // return true on release (default requires click+release) ImGuiButtonFlags_PressedOnDoubleClick = 1 << 8, // return true on double-click (default requires click+release) ImGuiButtonFlags_PressedOnDragDropHold = 1 << 9, // return true when held into while we are drag and dropping another item (used by e.g. tree nodes, collapsing headers) - ImGuiButtonFlags_Repeat = 1 << 10, // hold to repeat + //ImGuiButtonFlags_Repeat = 1 << 10, // hold to repeat ImGuiButtonFlags_FlattenChildren = 1 << 11, // allow interactions even if a child window is overlapping ImGuiButtonFlags_AllowOverlap = 1 << 12, // require previous frame HoveredId to either match id or be null before being usable. - ImGuiButtonFlags_DontClosePopups = 1 << 13, // disable automatically closing parent popup on press // [UNUSED] + //ImGuiButtonFlags_DontClosePopups = 1 << 13, // disable automatically closing parent popup on press //ImGuiButtonFlags_Disabled = 1 << 14, // disable interactions -> use BeginDisabled() or ImGuiItemFlags_Disabled ImGuiButtonFlags_AlignTextBaseLine = 1 << 15, // vertically align button to match text baseline - ButtonEx() only // FIXME: Should be removed and handled by SmallButton(), not possible currently because of DC.CursorPosPrevLine ImGuiButtonFlags_NoKeyModsAllowed = 1 << 16, // disable mouse interaction if a key modifier is held diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 8cdd4aa27..2a7b1e9a8 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -508,8 +508,6 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool ImGuiItemFlags item_flags = (g.LastItemData.ID == id ? g.LastItemData.InFlags : g.CurrentItemFlags); if (flags & ImGuiButtonFlags_AllowOverlap) item_flags |= ImGuiItemFlags_AllowOverlap; - if (flags & ImGuiButtonFlags_Repeat) - item_flags |= ImGuiItemFlags_ButtonRepeat; ImGuiWindow* backup_hovered_window = g.HoveredWindow; const bool flatten_hovered_children = (flags & ImGuiButtonFlags_FlattenChildren) && g.HoveredWindow && g.HoveredWindow->RootWindow == window; @@ -3689,21 +3687,22 @@ bool ImGui::InputScalar(const char* label, ImGuiDataType data_type, void* p_data // Step buttons const ImVec2 backup_frame_padding = style.FramePadding; style.FramePadding.x = style.FramePadding.y; - ImGuiButtonFlags button_flags = ImGuiButtonFlags_Repeat | ImGuiButtonFlags_DontClosePopups; if (flags & ImGuiInputTextFlags_ReadOnly) BeginDisabled(); + PushItemFlag(ImGuiItemFlags_ButtonRepeat, true); SameLine(0, style.ItemInnerSpacing.x); - if (ButtonEx("-", ImVec2(button_size, button_size), button_flags)) + if (ButtonEx("-", ImVec2(button_size, button_size))) { DataTypeApplyOp(data_type, '-', p_data, p_data, g.IO.KeyCtrl && p_step_fast ? p_step_fast : p_step); value_changed = true; } SameLine(0, style.ItemInnerSpacing.x); - if (ButtonEx("+", ImVec2(button_size, button_size), button_flags)) + if (ButtonEx("+", ImVec2(button_size, button_size))) { DataTypeApplyOp(data_type, '+', p_data, p_data, g.IO.KeyCtrl && p_step_fast ? p_step_fast : p_step); value_changed = true; } + PopItemFlag(); if (flags & ImGuiInputTextFlags_ReadOnly) EndDisabled(); @@ -9753,17 +9752,19 @@ static ImGuiTabItem* ImGui::TabBarScrollingButtons(ImGuiTabBar* tab_bar) PushStyleColor(ImGuiCol_Text, arrow_col); PushStyleColor(ImGuiCol_Button, ImVec4(0, 0, 0, 0)); + PushItemFlag(ImGuiItemFlags_ButtonRepeat, true); const float backup_repeat_delay = g.IO.KeyRepeatDelay; const float backup_repeat_rate = g.IO.KeyRepeatRate; g.IO.KeyRepeatDelay = 0.250f; g.IO.KeyRepeatRate = 0.200f; float x = ImMax(tab_bar->BarRect.Min.x, tab_bar->BarRect.Max.x - scrolling_buttons_width); window->DC.CursorPos = ImVec2(x, tab_bar->BarRect.Min.y); - if (ArrowButtonEx("##<", ImGuiDir_Left, arrow_button_size, ImGuiButtonFlags_PressedOnClick | ImGuiButtonFlags_Repeat)) + if (ArrowButtonEx("##<", ImGuiDir_Left, arrow_button_size, ImGuiButtonFlags_PressedOnClick)) select_dir = -1; window->DC.CursorPos = ImVec2(x + arrow_button_size.x, tab_bar->BarRect.Min.y); - if (ArrowButtonEx("##>", ImGuiDir_Right, arrow_button_size, ImGuiButtonFlags_PressedOnClick | ImGuiButtonFlags_Repeat)) + if (ArrowButtonEx("##>", ImGuiDir_Right, arrow_button_size, ImGuiButtonFlags_PressedOnClick)) select_dir = +1; + PopItemFlag(); PopStyleColor(2); g.IO.KeyRepeatRate = backup_repeat_rate; g.IO.KeyRepeatDelay = backup_repeat_delay; From fcdd58757a60b459a8ec057ec9d5123cd99ff76c Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 14 Oct 2024 19:13:04 +0200 Subject: [PATCH 22/22] Backends: comments. --- backends/imgui_impl_dx12.cpp | 1 + backends/imgui_impl_vulkan.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/backends/imgui_impl_dx12.cpp b/backends/imgui_impl_dx12.cpp index e9345013c..be117b6c1 100644 --- a/backends/imgui_impl_dx12.cpp +++ b/backends/imgui_impl_dx12.cpp @@ -18,6 +18,7 @@ // (minor and older changes stripped away, please see git history for details) // 2024-10-07: DirectX12: Changed default texture sampler to Clamp instead of Repeat/Wrap. // 2024-10-07: DirectX12: Expose selected render state in ImGui_ImplDX12_RenderState, which you can access in 'void* platform_io.Renderer_RenderState' during draw callbacks. +// 2024-10-07: DirectX12: Compiling with '#define ImTextureID=ImU64' is unnecessary now that dear imgui defaults ImTextureID to u64 instead of void*. // 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11. // 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX). // 2021-05-19: DirectX12: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement) diff --git a/backends/imgui_impl_vulkan.cpp b/backends/imgui_impl_vulkan.cpp index a68f862b1..4e4e332fc 100644 --- a/backends/imgui_impl_vulkan.cpp +++ b/backends/imgui_impl_vulkan.cpp @@ -28,6 +28,7 @@ // (minor and older changes stripped away, please see git history for details) // 2024-10-07: Vulkan: Changed default texture sampler to Clamp instead of Repeat/Wrap. // 2024-10-07: Vulkan: Expose selected render state in ImGui_ImplVulkan_RenderState, which you can access in 'void* platform_io.Renderer_RenderState' during draw callbacks. +// 2024-10-07: Vulkan: Compiling with '#define ImTextureID=ImU64' is unnecessary now that dear imgui defaults ImTextureID to u64 instead of void*. // 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.