Merge branch 'docking' of git.alexdelcamp.fr:Alexandre_1a/imgui into docking
Added personals changes (modules)
This commit is contained in:
commit
d7cce3ad50
1
.github/ISSUE_TEMPLATE/issue_template.yml
vendored
1
.github/ISSUE_TEMPLATE/issue_template.yml
vendored
@ -14,6 +14,7 @@ body:
|
||||
attributes:
|
||||
value: |
|
||||
**Prerequisites:**
|
||||
- I am not using a LLM to think or write for me. Please distill information to what's necessary and meaningful.
|
||||
- I have read [Frequently Asked Questions](https://github.com/ocornut/imgui/blob/master/docs/FAQ.md).
|
||||
- I have read [Contributing Guidelines -> General Advices](https://github.com/ocornut/imgui/blob/master/docs/CONTRIBUTING.md#getting-started--general-advice).
|
||||
- I have read [Contributing Guidelines -> How to open an Issue](https://github.com/ocornut/imgui/blob/master/docs/CONTRIBUTING.md#how-to-open-an-issue).
|
||||
|
||||
2
.github/pull_request_template.md
vendored
2
.github/pull_request_template.md
vendored
@ -6,7 +6,7 @@
|
||||
|
||||
3. Consider running the [imgui_test_suite](https://github.com/ocornut/imgui_test_engine) or adding new tests to test for expected behaviors.
|
||||
|
||||
4. PLEASE DO NOT SUBMIT AI SLOP OR AUTOMATED REPORTS. Submissions that are lacking proper human review/judgement before being passed to us are not welcome.
|
||||
4. PLEASE DO NOT SUBMIT AI SLOP OR AUTOMATED AI REPORTS. Submissions that are lacking proper human review/judgement before being passed to us are not welcome. Do not let a LLM AI write most of the text for you.
|
||||
|
||||
5. Clear this template before submitting your PR.
|
||||
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
// [X] Renderer: User texture binding. Use 'ID3D10ShaderResourceView*' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||
// [X] Renderer: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access with ImGui_ImplDX10_GetRenderState().
|
||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
@ -18,6 +19,7 @@
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2026-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2026-09-07: Round framebuffer dimensions to the nearest integer instead of truncating them. (#9538, 9515, #8628)
|
||||
// 2026-04-23: DirectX10: Added support for standard draw callbacks (in platform_io): DrawCallback_ResetRenderState, DrawCallback_SetSamplerLinear, DrawCallback_SetSamplerNearest. Obsoleting samplers from ImGui_ImplDX10_RenderState. (#9378)
|
||||
// 2026-01-19: DirectX10: Added 'SamplerNearest' in ImGui_ImplDX10_RenderState. Renamed 'SamplerDefault' to 'SamplerLinear'.
|
||||
// 2025-09-18: Call platform_io.ClearRendererHandlers() on shutdown.
|
||||
@ -101,6 +103,11 @@ static ImGui_ImplDX10_Data* ImGui_ImplDX10_GetBackendData()
|
||||
return ImGui::GetCurrentContext() ? (ImGui_ImplDX10_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
||||
}
|
||||
|
||||
ImGui_ImplDX10_RenderState* ImGui_ImplDX10_GetRenderState()
|
||||
{
|
||||
return (ImGui_ImplDX10_RenderState*)ImGui::GetPlatformIO().Renderer_RenderState;
|
||||
}
|
||||
|
||||
// Forward Declarations
|
||||
static void ImGui_ImplDX10_InitMultiViewportSupport();
|
||||
static void ImGui_ImplDX10_ShutdownMultiViewportSupport();
|
||||
@ -112,8 +119,8 @@ static void ImGui_ImplDX10_SetupRenderState(ImDrawData* draw_data, ID3D10Device*
|
||||
|
||||
// Setup viewport
|
||||
D3D10_VIEWPORT vp = {};
|
||||
vp.Width = (UINT)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x);
|
||||
vp.Height = (UINT)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
|
||||
vp.Width = (UINT)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x + 0.5f);
|
||||
vp.Height = (UINT)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y + 0.5f);
|
||||
vp.MinDepth = 0.0f;
|
||||
vp.MaxDepth = 1.0f;
|
||||
vp.TopLeftX = vp.TopLeftY = 0;
|
||||
@ -767,10 +774,12 @@ static void ImGui_ImplDX10_SetWindowSize(ImGuiViewport* viewport, ImVec2 size)
|
||||
}
|
||||
}
|
||||
|
||||
static void ImGui_ImplDX10_RenderViewport(ImGuiViewport* viewport, void*)
|
||||
static void ImGui_ImplDX10_RenderWindow(ImGuiViewport* viewport, void*)
|
||||
{
|
||||
ImGui_ImplDX10_Data* bd = ImGui_ImplDX10_GetBackendData();
|
||||
ImGui_ImplDX10_ViewportData* vd = (ImGui_ImplDX10_ViewportData*)viewport->RendererUserData;
|
||||
if (vd->RTView == nullptr) // Swap chain creation or resize failed (e.g. device removed)
|
||||
return;
|
||||
ImVec4 clear_color = ImVec4(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
bd->pd3dDevice->OMSetRenderTargets(1, &vd->RTView, nullptr);
|
||||
if (!(viewport->Flags & ImGuiViewportFlags_NoRendererClear))
|
||||
@ -791,7 +800,7 @@ void ImGui_ImplDX10_InitMultiViewportSupport()
|
||||
platform_io.Renderer_CreateWindow = ImGui_ImplDX10_CreateWindow;
|
||||
platform_io.Renderer_DestroyWindow = ImGui_ImplDX10_DestroyWindow;
|
||||
platform_io.Renderer_SetWindowSize = ImGui_ImplDX10_SetWindowSize;
|
||||
platform_io.Renderer_RenderWindow = ImGui_ImplDX10_RenderViewport;
|
||||
platform_io.Renderer_RenderWindow = ImGui_ImplDX10_RenderWindow;
|
||||
platform_io.Renderer_SwapBuffers = ImGui_ImplDX10_SwapBuffers;
|
||||
}
|
||||
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
// [X] Renderer: User texture binding. Use 'ID3D10ShaderResourceView*' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||
// [X] Renderer: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access with ImGui_ImplDX10_GetRenderState().
|
||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
@ -46,5 +47,6 @@ struct ImGui_ImplDX10_RenderState
|
||||
//ID3D10SamplerState* SamplerLinear; // Use ImDrawList::AddCallback(ImGui::GetPlatform().DrawCallback_SetSamplerLinear)
|
||||
//ID3D10SamplerState* SamplerNearest; // Use ImDrawList::AddCallback(ImGui::GetPlatform().DrawCallback_SetSamplerNearest)
|
||||
};
|
||||
IMGUI_IMPL_API ImGui_ImplDX10_RenderState* ImGui_ImplDX10_GetRenderState();
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
// [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||
// [X] Renderer: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access with ImGui_ImplDX11_GetRenderState().
|
||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
@ -107,6 +107,11 @@ static ImGui_ImplDX11_Data* ImGui_ImplDX11_GetBackendData()
|
||||
return ImGui::GetCurrentContext() ? (ImGui_ImplDX11_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
||||
}
|
||||
|
||||
ImGui_ImplDX11_RenderState* ImGui_ImplDX11_GetRenderState()
|
||||
{
|
||||
return (ImGui_ImplDX11_RenderState*)ImGui::GetPlatformIO().Renderer_RenderState;
|
||||
}
|
||||
|
||||
// Forward Declarations
|
||||
static void ImGui_ImplDX11_InitMultiViewportSupport();
|
||||
static void ImGui_ImplDX11_ShutdownMultiViewportSupport();
|
||||
@ -118,8 +123,8 @@ static void ImGui_ImplDX11_SetupRenderState(const ImDrawData* draw_data, ID3D11D
|
||||
|
||||
// Setup viewport
|
||||
D3D11_VIEWPORT vp = {};
|
||||
vp.Width = draw_data->DisplaySize.x * draw_data->FramebufferScale.x;
|
||||
vp.Height = draw_data->DisplaySize.y * draw_data->FramebufferScale.y;
|
||||
vp.Width = (float)(int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x + 0.5f);
|
||||
vp.Height = (float)(int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y + 0.5f);
|
||||
vp.MinDepth = 0.0f;
|
||||
vp.MaxDepth = 1.0f;
|
||||
vp.TopLeftX = vp.TopLeftY = 0;
|
||||
@ -802,6 +807,8 @@ static void ImGui_ImplDX11_RenderWindow(ImGuiViewport* viewport, void*)
|
||||
{
|
||||
ImGui_ImplDX11_Data* bd = ImGui_ImplDX11_GetBackendData();
|
||||
ImGui_ImplDX11_ViewportData* vd = (ImGui_ImplDX11_ViewportData*)viewport->RendererUserData;
|
||||
if (vd->RTView == nullptr) // Swap chain creation or resize failed (e.g. device removed)
|
||||
return;
|
||||
ImVec4 clear_color = ImVec4(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
bd->pd3dDeviceContext->OMSetRenderTargets(1, &vd->RTView, nullptr);
|
||||
if (!(viewport->Flags & ImGuiViewportFlags_NoRendererClear))
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
// [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||
// [X] Renderer: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access with ImGui_ImplDX11_GetRenderState().
|
||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
|
||||
// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this.
|
||||
@ -49,5 +49,6 @@ struct ImGui_ImplDX11_RenderState
|
||||
//ID3D11SamplerState* SamplerLinear; // Use ImDrawList::AddCallback(ImGui::GetPlatform().DrawCallback_SetSamplerLinear)
|
||||
//ID3D11SamplerState* SamplerNearest; // Use ImDrawList::AddCallback(ImGui::GetPlatform().DrawCallback_SetSamplerNearest)
|
||||
};
|
||||
IMGUI_IMPL_API ImGui_ImplDX11_RenderState* ImGui_ImplDX11_GetRenderState();
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
// [X] Renderer: User texture binding. Use 'D3D12_GPU_DESCRIPTOR_HANDLE' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||
// [X] Renderer: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access with ImGui_ImplDX12_GetRenderState().
|
||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
// FIXME: The transition from removing a viewport and moving the window in an existing hosted viewport tends to flicker.
|
||||
|
||||
@ -23,6 +23,7 @@
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2026-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2026-09-07: Round framebuffer dimensions to the nearest integer instead of truncating them. (#9538, 9515, #8628)
|
||||
// 2026-08-05: DirectX12: *BREAKING CHANGE* Removed support for legacy `ImGui_ImplDX12_Init()` signature obsoleted in 1.91.6 (2024-11-15) because it needed to forcefully disable support for ImGuiBackendFlags_RendererHasTextures. (#9487)
|
||||
// 2026-04-23: Added support for standard draw callbacks (in platform_io): DrawCallback_ResetRenderState, DrawCallback_SetSamplerLinear, DrawCallback_SetSamplerNearest. (#9378)
|
||||
// 2025-10-23: [Docking] DirectX12: Fixed an issue in synchronization logic improving rendering throughput for secondary viewports. (#8961, #9025)
|
||||
@ -133,6 +134,11 @@ static ImGui_ImplDX12_Data* ImGui_ImplDX12_GetBackendData()
|
||||
return ImGui::GetCurrentContext() ? (ImGui_ImplDX12_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
||||
}
|
||||
|
||||
ImGui_ImplDX12_RenderState* ImGui_ImplDX12_GetRenderState()
|
||||
{
|
||||
return (ImGui_ImplDX12_RenderState*)ImGui::GetPlatformIO().Renderer_RenderState;
|
||||
}
|
||||
|
||||
// Buffers used during the rendering of a frame
|
||||
struct ImGui_ImplDX12_RenderBuffers
|
||||
{
|
||||
@ -258,8 +264,8 @@ static void ImGui_ImplDX12_SetupRenderState(ImDrawData* draw_data, ID3D12Graphic
|
||||
|
||||
// Setup viewport
|
||||
D3D12_VIEWPORT vp = {};
|
||||
vp.Width = draw_data->DisplaySize.x * draw_data->FramebufferScale.x;
|
||||
vp.Height = draw_data->DisplaySize.y * draw_data->FramebufferScale.y;
|
||||
vp.Width = (float)(int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x + 0.5f);
|
||||
vp.Height = (float)(int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y + 0.5f);
|
||||
vp.MinDepth = 0.0f;
|
||||
vp.MaxDepth = 1.0f;
|
||||
vp.TopLeftX = vp.TopLeftY = 0.0f;
|
||||
@ -1255,6 +1261,8 @@ static void ImGui_ImplDX12_RenderWindow(ImGuiViewport* viewport, void*)
|
||||
{
|
||||
ImGui_ImplDX12_Data* bd = ImGui_ImplDX12_GetBackendData();
|
||||
ImGui_ImplDX12_ViewportData* vd = (ImGui_ImplDX12_ViewportData*)viewport->RendererUserData;
|
||||
if (vd->SwapChain == nullptr)
|
||||
return;
|
||||
|
||||
ImGui_ImplDX12_FrameContext* frame_context = ImGui_WaitForNextFrameContext(vd);
|
||||
UINT back_buffer_idx = vd->SwapChain->GetCurrentBackBufferIndex();
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
// [X] Renderer: User texture binding. Use 'D3D12_GPU_DESCRIPTOR_HANDLE' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||
// [X] Renderer: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access with ImGui_ImplDX12_GetRenderState().
|
||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
|
||||
// The aim of imgui_impl_dx12.h/.cpp is to be usable in your engine without any modification.
|
||||
@ -75,6 +75,7 @@ struct ImGui_ImplDX12_RenderState
|
||||
ID3D12Device* Device;
|
||||
ID3D12GraphicsCommandList* CommandList;
|
||||
};
|
||||
IMGUI_IMPL_API ImGui_ImplDX12_RenderState* ImGui_ImplDX12_GetRenderState();
|
||||
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
// Legacy initialization API Obsoleted in 1.91.5
|
||||
|
||||
@ -32,6 +32,7 @@
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2026-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2026-09-15: [Docking] Fixed applying mouse cursor shapes to secondary viewports (broken in 1.92.6, 2025-12-10).
|
||||
// 2026-04-21: Added a Win32-specific implementation of ImGui_ImplGlfw_GetContentScaleXXXX functions for legacy GLFW 3.2.
|
||||
// 2026-03-25: Mouse cursor is properly restored if changed by user app/code while using glfwSetInputMode(..., GLFW_CURSOR_DISABLED) or ImGuiConfigFlags_NoMouseCursorChange. Amend change from 2025-12-10.
|
||||
// 2026-02-10: Try to set IMGUI_IMPL_GLFW_DISABLE_X11 / IMGUI_IMPL_GLFW_DISABLE_WAYLAND automatically if corresponding headers are not accessible. (#9225)
|
||||
@ -996,12 +997,21 @@ static void ImGui_ImplGlfw_UpdateMouseCursor()
|
||||
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData();
|
||||
if ((io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange) || glfwGetInputMode(bd->Window, GLFW_CURSOR) == GLFW_CURSOR_DISABLED)
|
||||
{
|
||||
bd->LastMouseCursor = nullptr; // Invalidate so that if user changes underlying cursor we will update it next time we can.
|
||||
bd->LastMouseCursor = nullptr; // Invalidate so that if user changes underlying cursor we will update it next time we can.
|
||||
return;
|
||||
}
|
||||
|
||||
ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor();
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
|
||||
#if GLFW_HAS_CREATECURSOR
|
||||
GLFWcursor* set_mouse_cursor = bd->MouseCursors[imgui_cursor] ? bd->MouseCursors[imgui_cursor] : bd->MouseCursors[ImGuiMouseCursor_Arrow];
|
||||
if (bd->LastMouseCursor == set_mouse_cursor)
|
||||
set_mouse_cursor = NULL;
|
||||
else
|
||||
bd->LastMouseCursor = set_mouse_cursor;
|
||||
#endif
|
||||
|
||||
for (int n = 0; n < platform_io.Viewports.Size; n++)
|
||||
{
|
||||
GLFWwindow* window = (GLFWwindow*)platform_io.Viewports[n]->PlatformHandle;
|
||||
@ -1019,12 +1029,8 @@ static void ImGui_ImplGlfw_UpdateMouseCursor()
|
||||
// Show OS mouse cursor
|
||||
// FIXME-PLATFORM: Unfocused windows seems to fail changing the mouse cursor with GLFW 3.2, but 3.3 works here.
|
||||
#if GLFW_HAS_CREATECURSOR
|
||||
GLFWcursor* cursor = bd->MouseCursors[imgui_cursor] ? bd->MouseCursors[imgui_cursor] : bd->MouseCursors[ImGuiMouseCursor_Arrow];
|
||||
if (bd->LastMouseCursor != cursor)
|
||||
{
|
||||
glfwSetCursor(window, cursor);
|
||||
bd->LastMouseCursor = cursor;
|
||||
}
|
||||
if (set_mouse_cursor)
|
||||
glfwSetCursor(window, set_mouse_cursor);
|
||||
#endif
|
||||
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
|
||||
}
|
||||
@ -1422,6 +1428,7 @@ static void ImGui_ImplGlfw_CreateWindow(ImGuiViewport* viewport)
|
||||
glfwMakeContextCurrent(vd->Window);
|
||||
glfwSwapInterval(0);
|
||||
}
|
||||
bd->LastMouseCursor = nullptr; // Invalidate so that cursor is set again
|
||||
}
|
||||
|
||||
static void ImGui_ImplGlfw_DestroyWindow(ImGuiViewport* viewport)
|
||||
|
||||
@ -18,6 +18,7 @@
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2026-XX-XX: Metal: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2026-09-07: Round framebuffer dimensions to the nearest integer instead of truncating them. (#9538, 9515, #8628)
|
||||
// 2026-08-06: Metal: fixed resizing windows losing framebuffer scale. (#6828, #8856)
|
||||
// 2026-04-28: Added support for standard draw callbacks (in platform_io): DrawCallback_SetSamplerLinear and DrawCallback_SetSamplerNearest. (#9378, #9381)
|
||||
// 2026-04-23: Added support for standard draw callbacks (in platform_io): DrawCallback_ResetRenderState (others are not yet supported). (#9378)
|
||||
@ -172,8 +173,8 @@ static void ImGui_ImplMetal_SetupRenderState(ImDrawData* draw_data, id<MTLComman
|
||||
{
|
||||
.originX = 0.0,
|
||||
.originY = 0.0,
|
||||
.width = (double)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x),
|
||||
.height = (double)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y),
|
||||
.width = (double)(int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x + 0.5f),
|
||||
.height = (double)(int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y + 0.5f),
|
||||
.znear = 0.0,
|
||||
.zfar = 1.0
|
||||
};
|
||||
@ -212,8 +213,8 @@ void ImGui_ImplMetal_RenderDrawData(ImDrawData* draw_data, id<MTLCommandBuffer>
|
||||
MetalContext* ctx = bd->SharedMetalContext;
|
||||
|
||||
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
|
||||
int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x);
|
||||
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
|
||||
int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x + 0.5f);
|
||||
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y + 0.5f);
|
||||
if (fb_width <= 0 || fb_height <= 0 || draw_data->CmdLists.Size == 0)
|
||||
return;
|
||||
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2026-09-07: Round framebuffer dimensions to the nearest integer instead of truncating them. (#9538, 9515, #8628)
|
||||
// 2026-08-06: Metal 4: fixed resizing windows losing framebuffer scale. (#6828, #8856)
|
||||
// 2026-07-07: Metal 4: Added metal-cpp support. (#9461)
|
||||
// 2026-07-02: Metal 4: Added new Metal 4 backend implementation. (#9458)
|
||||
@ -181,8 +182,8 @@ static void ImGui_ImplMetal4_SetupRenderState(ImDrawData* draw_data, id<MTL4Comm
|
||||
{
|
||||
.originX = 0.0,
|
||||
.originY = 0.0,
|
||||
.width = (double)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x),
|
||||
.height = (double)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y),
|
||||
.width = (double)(int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x + 0.5f),
|
||||
.height = (double)(int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y + 0.5f),
|
||||
.znear = 0.0,
|
||||
.zfar = 1.0
|
||||
};
|
||||
@ -229,8 +230,8 @@ void ImGui_ImplMetal4_RenderDrawData(ImDrawData* draw_data, id<MTL4CommandBuffer
|
||||
MetalContext* ctx = bd->SharedMetalContext;
|
||||
|
||||
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
|
||||
int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x);
|
||||
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
|
||||
int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x + 0.5f);
|
||||
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y + 0.5f);
|
||||
if (fb_width <= 0 || fb_height <= 0 || draw_data->CmdLists.Size == 0)
|
||||
return;
|
||||
|
||||
|
||||
@ -28,6 +28,8 @@
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2026-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2026-09-17: OpenGL: Added support for platform_io.DrawCallback_SetSamplerFromTex. (#9378)
|
||||
// 2026-09-07: OpenGL: Round framebuffer dimensions to the nearest integer instead of truncating them. (#9538, 9515, #8628)
|
||||
// 2026-07-15: OpenGL: Backup and restore GL_UNPACK_ROW_LENGTH and GL_UNPACK_ALIGNMENT in UpdateTexture() to avoid corrupting caller GL state. (#8802, #9473)
|
||||
// 2026-04-23: OpenGL: Added support for standard draw callbacks (in platform_io): DrawCallback_ResetRenderState, DrawCallback_SetSamplerLinear, DrawCallback_SetSamplerNearest. (#9378)
|
||||
// 2026-03-12: OpenGL: Fixed invalid assert in ImGui_ImplOpenGL3_UpdateTexture() if ImTextureID_Invalid is defined to be != 0, which became the default since 2026-03-12. (#9295)
|
||||
@ -137,6 +139,8 @@ static void ImGui_ImplOpenGL2_SetupRenderState(ImDrawData* draw_data, int fb_wid
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
glShadeModel(GL_SMOOTH);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
|
||||
bd->UseTexParameterToSetSampler = false;
|
||||
bd->NextSampler = GL_LINEAR;
|
||||
|
||||
// If you are using this code with non-legacy OpenGL header/contexts (which you should not, prefer using imgui_impl_opengl3.cpp!!),
|
||||
@ -163,9 +167,13 @@ static void ImGui_ImplOpenGL2_SetupRenderState(ImDrawData* draw_data, int fb_wid
|
||||
}
|
||||
|
||||
// Draw callbacks
|
||||
static void ImGui_ImplOpenGL2_DrawCallback_ResetRenderState(const ImDrawList*, const ImDrawCmd*) {} // Intentionally empty. Used as an identifier for rendering loop to call its code. Simpler to implement this way.
|
||||
static void ImGui_ImplOpenGL2_DrawCallback_SetSamplerLinear(const ImDrawList*, const ImDrawCmd*) { ImGui_ImplOpenGL2_Data* bd = ImGui_ImplOpenGL2_GetBackendData(); bd->UseTexParameterToSetSampler = true; bd->NextSampler = GL_LINEAR; }
|
||||
static void ImGui_ImplOpenGL2_DrawCallback_SetSamplerNearest(const ImDrawList*, const ImDrawCmd*) { ImGui_ImplOpenGL2_Data* bd = ImGui_ImplOpenGL2_GetBackendData(); bd->UseTexParameterToSetSampler = true; bd->NextSampler = GL_NEAREST; }
|
||||
// - IMPORTANT: Using DrawCallback_SetSamplerLinear/DrawCallback_SetSamplerNearest will trash glTexParameteri() values for the texture!!
|
||||
// We cannot decently backup/restore that state because glGetTexParameteriv() is slow on many setups.
|
||||
// - Using DrawCallback_SetSamplerFromTex will basically instruct the backend to use existing glTexParameteri() values without modifying anything, which is the initial state.
|
||||
static void ImGui_ImplOpenGL2_DrawCallback_ResetRenderState(const ImDrawList*, const ImDrawCmd*) {} // Intentionally empty. Used as an identifier for rendering loop to call its code. Simpler to implement this way.
|
||||
static void ImGui_ImplOpenGL2_DrawCallback_SetSamplerLinear(const ImDrawList*, const ImDrawCmd*) { ImGui_ImplOpenGL2_Data* bd = ImGui_ImplOpenGL2_GetBackendData(); bd->UseTexParameterToSetSampler = true; bd->NextSampler = GL_LINEAR; }
|
||||
static void ImGui_ImplOpenGL2_DrawCallback_SetSamplerNearest(const ImDrawList*, const ImDrawCmd*) { ImGui_ImplOpenGL2_Data* bd = ImGui_ImplOpenGL2_GetBackendData(); bd->UseTexParameterToSetSampler = true; bd->NextSampler = GL_NEAREST; }
|
||||
static void ImGui_ImplOpenGL2_DrawCallback_SetSamplerFromTex(const ImDrawList*, const ImDrawCmd*) { ImGui_ImplOpenGL2_Data* bd = ImGui_ImplOpenGL2_GetBackendData(); bd->UseTexParameterToSetSampler = false; }
|
||||
|
||||
// OpenGL2 Render function.
|
||||
// Note that this implementation is little overcomplicated because we are saving/setting up/restoring every OpenGL state explicitly.
|
||||
@ -174,8 +182,8 @@ void ImGui_ImplOpenGL2_RenderDrawData(ImDrawData* draw_data)
|
||||
{
|
||||
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
|
||||
ImGui_ImplOpenGL2_Data* bd = ImGui_ImplOpenGL2_GetBackendData();
|
||||
int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x);
|
||||
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
|
||||
int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x + 0.5f);
|
||||
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y + 0.5f);
|
||||
if (fb_width == 0 || fb_height == 0)
|
||||
return;
|
||||
|
||||
@ -368,6 +376,7 @@ bool ImGui_ImplOpenGL2_Init()
|
||||
platform_io.DrawCallback_ResetRenderState = ImGui_ImplOpenGL2_DrawCallback_ResetRenderState;
|
||||
platform_io.DrawCallback_SetSamplerLinear = ImGui_ImplOpenGL2_DrawCallback_SetSamplerLinear;
|
||||
platform_io.DrawCallback_SetSamplerNearest = ImGui_ImplOpenGL2_DrawCallback_SetSamplerNearest;
|
||||
platform_io.DrawCallback_SetSamplerFromTex = ImGui_ImplOpenGL2_DrawCallback_SetSamplerFromTex;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
||||
// [x] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset) [Desktop OpenGL only!]
|
||||
// [X] Renderer: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access with ImGui_ImplOpenGL3_GetRenderState().
|
||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
|
||||
// About WebGL/ES:
|
||||
@ -25,6 +26,8 @@
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2026-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2026-09-17: OpenGL: Added support for platform_io.DrawCallback_SetSamplerFromTex. (#9378)
|
||||
// 2026-09-07: OpenGL: Round framebuffer dimensions to the nearest integer instead of truncating them. (#9538, 9515, #8628)
|
||||
// 2026-07-15: OpenGL: Backup and restore GL_UNPACK_ROW_LENGTH and GL_UNPACK_ALIGNMENT in UpdateTexture() to avoid corrupting caller GL state. (#8802, #9473)
|
||||
// 2026-06-17: OpenGL: Expose selected render state in ImGui_ImplOpenGL3_RenderState, Allowing to dynamically select between use of glBindSampler() and glTexParameter(). You can access in 'void* platform_io.Renderer_RenderState' during rendering.
|
||||
// 2026-06-03: OpenGL: GLSL version detection assume GLSL 410 when GL context is 4.1. Fixes an issue running on macOS with Wine. (#9427, #6577)
|
||||
@ -275,6 +278,11 @@ static ImGui_ImplOpenGL3_Data* ImGui_ImplOpenGL3_GetBackendData()
|
||||
return ImGui::GetCurrentContext() ? (ImGui_ImplOpenGL3_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
||||
}
|
||||
|
||||
ImGui_ImplOpenGL3_RenderState* ImGui_ImplOpenGL3_GetRenderState()
|
||||
{
|
||||
return (ImGui_ImplOpenGL3_RenderState*)ImGui::GetPlatformIO().Renderer_RenderState;
|
||||
}
|
||||
|
||||
// Forward Declarations
|
||||
static void ImGui_ImplOpenGL3_InitMultiViewportSupport();
|
||||
static void ImGui_ImplOpenGL3_ShutdownMultiViewportSupport();
|
||||
@ -391,9 +399,12 @@ static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, ImGui_Impl
|
||||
glUniform1i(bd->AttribLocationTex, 0);
|
||||
glUniformMatrix4fv(bd->AttribLocationProjMtx, 1, GL_FALSE, &ortho_projection[0][0]);
|
||||
|
||||
(void)render_state;
|
||||
render_state->UseBindSampler = bd->HasBindSampler;
|
||||
render_state->UseTexParameterFilter = false;
|
||||
render_state->CurrentSampler = 0;
|
||||
render_state->CurrentTexParameterFilter = 0;
|
||||
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER
|
||||
if (render_state->UseBindSampler)
|
||||
if (bd->HasBindSampler && render_state->UseBindSampler)
|
||||
{
|
||||
render_state->CurrentSampler = bd->TexSamplers[0];
|
||||
glBindSampler(0, render_state->CurrentSampler); // We use combined texture/sampler state. Applications using GL 3.3 and GL ES 3.0 may set that otherwise.
|
||||
@ -416,16 +427,15 @@ static void ImGui_ImplOpenGL3_SetupRenderState(ImDrawData* draw_data, ImGui_Impl
|
||||
GL_CALL(glVertexAttribPointer(bd->AttribLocationVtxColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(ImDrawVert), (GLvoid*)offsetof(ImDrawVert, col)));
|
||||
}
|
||||
|
||||
// Draw callbacks
|
||||
static void ImGui_ImplOpenGL3_DrawCallback_ResetRenderState(const ImDrawList*, const ImDrawCmd*) {} // Intentionally empty. Used as an identifier for rendering loop to call its code. Simpler to implement this way.
|
||||
static void ImGui_ImplOpenGL3_DrawCallback_SetSamplerLinear(const ImDrawList*, const ImDrawCmd*)
|
||||
static void ImGui_ImplOpenGL3_DrawCallback_SetSampler(unsigned int sampler_idx, unsigned int tex_parameter_filter)
|
||||
{
|
||||
ImGui_ImplOpenGL3_RenderState* render_state = ImGui_ImplOpenGL3_GetRenderState();
|
||||
IM_UNUSED(sampler_idx);
|
||||
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER
|
||||
ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData();
|
||||
if (bd->HasBindSampler)
|
||||
if (bd->HasBindSampler && render_state->UseBindSampler)
|
||||
{
|
||||
render_state->CurrentSampler = bd->TexSamplers[0];
|
||||
render_state->CurrentSampler = bd->TexSamplers[sampler_idx];
|
||||
render_state->UseTexParameterFilter = false;
|
||||
glBindSampler(0, render_state->CurrentSampler);
|
||||
}
|
||||
@ -433,26 +443,30 @@ static void ImGui_ImplOpenGL3_DrawCallback_SetSamplerLinear(const ImDrawList*, c
|
||||
#endif
|
||||
{
|
||||
render_state->UseTexParameterFilter = true;
|
||||
render_state->CurrentTexParameterFilter = GL_LINEAR;
|
||||
render_state->CurrentTexParameterFilter = tex_parameter_filter;
|
||||
}
|
||||
}
|
||||
static void ImGui_ImplOpenGL3_DrawCallback_SetSamplerNearest(const ImDrawList*, const ImDrawCmd*)
|
||||
|
||||
// Draw callbacks
|
||||
// - IMPORTANT: Using DrawCallback_SetSamplerLinear/DrawCallback_SetSamplerNearest will trash glTexParameteri() values for the texture if used on a GL context not supporting glBindSampler()!!
|
||||
// We cannot decently backup/restore that state because glGetTexParameteriv() is slow on many setups.
|
||||
// - Using DrawCallback_SetSamplerFromTex will basically instruct the backend to use existing glTexParameteri() values without modifying anything.
|
||||
static void ImGui_ImplOpenGL3_DrawCallback_ResetRenderState(const ImDrawList*, const ImDrawCmd*) {} // Intentionally empty. Used as an identifier for rendering loop to call its code. Simpler to implement this way.
|
||||
static void ImGui_ImplOpenGL3_DrawCallback_SetSamplerLinear(const ImDrawList*, const ImDrawCmd*) { ImGui_ImplOpenGL3_DrawCallback_SetSampler(0, GL_LINEAR); }
|
||||
static void ImGui_ImplOpenGL3_DrawCallback_SetSamplerNearest(const ImDrawList*, const ImDrawCmd*) { ImGui_ImplOpenGL3_DrawCallback_SetSampler(1, GL_NEAREST); }
|
||||
static void ImGui_ImplOpenGL3_DrawCallback_SetSamplerFromTex(const ImDrawList*, const ImDrawCmd*)
|
||||
{
|
||||
ImGui_ImplOpenGL3_RenderState* render_state = ImGui_ImplOpenGL3_GetRenderState();
|
||||
#ifdef IMGUI_IMPL_OPENGL_MAY_HAVE_BIND_SAMPLER
|
||||
ImGui_ImplOpenGL3_Data* bd = ImGui_ImplOpenGL3_GetBackendData();
|
||||
if (bd->HasBindSampler)
|
||||
{
|
||||
render_state->CurrentSampler = bd->TexSamplers[1];
|
||||
render_state->UseTexParameterFilter = false;
|
||||
glBindSampler(0, render_state->CurrentSampler);
|
||||
render_state->CurrentSampler = 0;
|
||||
glBindSampler(0, 0);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
render_state->UseTexParameterFilter = true;
|
||||
render_state->CurrentTexParameterFilter = GL_NEAREST;
|
||||
}
|
||||
render_state->UseBindSampler = false;
|
||||
render_state->UseTexParameterFilter = false;
|
||||
}
|
||||
|
||||
// OpenGL3 Render function.
|
||||
@ -461,8 +475,8 @@ static void ImGui_ImplOpenGL3_DrawCallback_SetSamplerNearest(const ImDrawList*,
|
||||
void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
|
||||
{
|
||||
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
|
||||
int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x);
|
||||
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
|
||||
int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x + 0.5f);
|
||||
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y + 0.5f);
|
||||
if (fb_width <= 0 || fb_height <= 0)
|
||||
return;
|
||||
|
||||
@ -526,11 +540,7 @@ void ImGui_ImplOpenGL3_RenderDrawData(ImDrawData* draw_data)
|
||||
|
||||
// Setup render state structure (for callbacks and custom texture bindings)
|
||||
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
|
||||
ImGui_ImplOpenGL3_RenderState render_state;
|
||||
render_state.UseBindSampler = bd->HasBindSampler;
|
||||
render_state.UseTexParameterFilter = false;
|
||||
render_state.CurrentSampler = 0;
|
||||
render_state.CurrentTexParameterFilter = 0;
|
||||
ImGui_ImplOpenGL3_RenderState render_state = {};
|
||||
platform_io.Renderer_RenderState = &render_state;
|
||||
|
||||
ImGui_ImplOpenGL3_SetupRenderState(draw_data, &render_state, fb_width, fb_height, vertex_array_object);
|
||||
@ -1101,6 +1111,7 @@ bool ImGui_ImplOpenGL3_Init(const char* glsl_version)
|
||||
platform_io.DrawCallback_ResetRenderState = ImGui_ImplOpenGL3_DrawCallback_ResetRenderState;
|
||||
platform_io.DrawCallback_SetSamplerLinear = ImGui_ImplOpenGL3_DrawCallback_SetSamplerLinear;
|
||||
platform_io.DrawCallback_SetSamplerNearest = ImGui_ImplOpenGL3_DrawCallback_SetSamplerNearest;
|
||||
platform_io.DrawCallback_SetSamplerFromTex = ImGui_ImplOpenGL3_DrawCallback_SetSamplerFromTex;
|
||||
|
||||
// Store GLSL version string so we can refer to it later in case we recreate shaders.
|
||||
// Note: GLSL version is NOT the same as GL version. Leave this to nullptr if unsure.
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
// [X] Renderer: User texture binding. Use 'GLuint' OpenGL texture as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
||||
// [x] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset) [Desktop OpenGL only!]
|
||||
// [X] Renderer: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access with ImGui_ImplOpenGL3_GetRenderState().
|
||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
|
||||
// About WebGL/ES:
|
||||
@ -73,10 +74,9 @@ struct ImGui_ImplOpenGL3_RenderState
|
||||
{
|
||||
bool UseBindSampler;
|
||||
bool UseTexParameterFilter;
|
||||
unsigned int CurrentSampler; // (GLuint) Used if UseBindSampler == true, otherwise always 0
|
||||
unsigned int CurrentTexParameterFilter; // (GLuint) Used if UseTexParameterToSetSampler == true
|
||||
unsigned int CurrentSampler; // (GLuint) Used if UseBindSampler == true (and are available), otherwise always 0
|
||||
unsigned int CurrentTexParameterFilter; // (GLuint) Used if UseTexParameterFilter == true
|
||||
};
|
||||
|
||||
static inline ImGui_ImplOpenGL3_RenderState* ImGui_ImplOpenGL3_GetRenderState() { return (ImGui_ImplOpenGL3_RenderState*)ImGui::GetPlatformIO().Renderer_RenderState; }
|
||||
IMGUI_IMPL_API ImGui_ImplOpenGL3_RenderState* ImGui_ImplOpenGL3_GetRenderState();
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
// [X] Renderer: User texture binding. Use 'SDL_GPUTexture*' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef! **IMPORTANT** Before 2025/08/08, ImTextureID was a reference to a SDL_GPUTextureSamplerBinding struct.
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||
// [X] Renderer: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access with ImGui_ImplSDLGPU3_GetRenderState().
|
||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
|
||||
// The aim of imgui_impl_sdlgpu3.h/.cpp is to be usable in your engine without any modification.
|
||||
@ -24,6 +25,7 @@
|
||||
|
||||
// CHANGELOG
|
||||
// 2026-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2026-09-07: Round framebuffer dimensions to the nearest integer instead of truncating them. (#9538, 9515, #8628)
|
||||
// 2026-04-23: Added support for standard draw callbacks (in platform_io): DrawCallback_ResetRenderState, DrawCallback_SetSamplerLinear, DrawCallback_SetSamplerNearest. Obsoleting samplers from ImGui_ImplSDLGPU3_RenderState. (#9378)
|
||||
// 2026-03-19: Fixed issue in ImGui_ImplSDLGPU3_DestroyTexture() if ImTextureID_Invalid is defined to be != 0, which became the default since 2026-03-12. (#9295, #9310)
|
||||
// 2026-02-25: Removed unnecessary call to SDL_WaitForGPUIdle when releasing vertex/index buffers. (#9262)
|
||||
@ -94,6 +96,11 @@ static ImGui_ImplSDLGPU3_Data* ImGui_ImplSDLGPU3_GetBackendData()
|
||||
return ImGui::GetCurrentContext() ? (ImGui_ImplSDLGPU3_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
||||
}
|
||||
|
||||
ImGui_ImplSDLGPU3_RenderState* ImGui_ImplSDLGPU3_GetRenderState()
|
||||
{
|
||||
return (ImGui_ImplSDLGPU3_RenderState*)ImGui::GetPlatformIO().Renderer_RenderState;
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDLGPU3_SetupRenderState(ImDrawData* draw_data, SDL_GPUGraphicsPipeline* pipeline, SDL_GPUCommandBuffer* command_buffer, SDL_GPURenderPass* render_pass, ImGui_ImplSDLGPU3_FrameData* fd, uint32_t fb_width, uint32_t fb_height)
|
||||
{
|
||||
ImGui_ImplSDLGPU3_Data* bd = ImGui_ImplSDLGPU3_GetBackendData();
|
||||
@ -165,8 +172,8 @@ static void CreateOrResizeBuffers(SDL_GPUBuffer** buffer, SDL_GPUTransferBuffer*
|
||||
void ImGui_ImplSDLGPU3_PrepareDrawData(ImDrawData* draw_data, SDL_GPUCommandBuffer* command_buffer)
|
||||
{
|
||||
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
|
||||
int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x);
|
||||
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
|
||||
int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x + 0.5f);
|
||||
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y + 0.5f);
|
||||
if (fb_width <= 0 || fb_height <= 0 || draw_data->TotalVtxCount <= 0)
|
||||
return;
|
||||
|
||||
@ -231,8 +238,8 @@ static void ImGui_ImplSDLGPU3_DrawCallback_SetSamplerNearest(const ImDrawList*,
|
||||
void ImGui_ImplSDLGPU3_RenderDrawData(ImDrawData* draw_data, SDL_GPUCommandBuffer* command_buffer, SDL_GPURenderPass* render_pass, SDL_GPUGraphicsPipeline* pipeline)
|
||||
{
|
||||
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
|
||||
int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x);
|
||||
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
|
||||
int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x + 0.5f);
|
||||
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y + 0.5f);
|
||||
if (fb_width <= 0 || fb_height <= 0)
|
||||
return;
|
||||
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
// [X] Renderer: User texture binding. Use 'SDL_GPUTexture*' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef! **IMPORTANT** Before 2025/08/08, ImTextureID was a reference to a SDL_GPUTextureSamplerBinding struct.
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||
// [X] Renderer: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access with ImGui_ImplSDLGPU3_GetRenderState().
|
||||
// [X] Renderer: Multi-viewport support (multiple windows). Enable with 'io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable'.
|
||||
|
||||
// The aim of imgui_impl_sdlgpu3.h/.cpp is to be usable in your engine without any modification.
|
||||
@ -59,5 +60,6 @@ struct ImGui_ImplSDLGPU3_RenderState
|
||||
{
|
||||
SDL_GPUDevice* Device;
|
||||
};
|
||||
IMGUI_IMPL_API ImGui_ImplSDLGPU3_RenderState* ImGui_ImplSDLGPU3_GetRenderState();
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
|
||||
@ -56,7 +56,8 @@
|
||||
#endif
|
||||
|
||||
// SDL
|
||||
#include <SDL.h>
|
||||
#include <SDL_render.h>
|
||||
#include <SDL_version.h>
|
||||
#if !SDL_VERSION_ATLEAST(2,0,17)
|
||||
#error This backend requires SDL 2.0.17+ because of SDL_RenderGeometry() function
|
||||
#endif
|
||||
@ -76,6 +77,11 @@ static ImGui_ImplSDLRenderer2_Data* ImGui_ImplSDLRenderer2_GetBackendData()
|
||||
return ImGui::GetCurrentContext() ? (ImGui_ImplSDLRenderer2_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
||||
}
|
||||
|
||||
ImGui_ImplSDLRenderer2_RenderState* ImGui_ImplSDLRenderer2_GetRenderState()
|
||||
{
|
||||
return (ImGui_ImplSDLRenderer2_RenderState*)ImGui::GetPlatformIO().Renderer_RenderState;
|
||||
}
|
||||
|
||||
// Functions
|
||||
static void ImGui_ImplSDLRenderer2_SetupRenderState(SDL_Renderer* renderer)
|
||||
{
|
||||
|
||||
@ -52,5 +52,6 @@ struct ImGui_ImplSDLRenderer2_RenderState
|
||||
{
|
||||
SDL_Renderer* Renderer;
|
||||
};
|
||||
IMGUI_IMPL_API ImGui_ImplSDLRenderer2_RenderState* ImGui_ImplSDLRenderer2_GetRenderState();
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
// [X] Renderer: User texture binding. Use 'SDL_Texture*' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||
// [X] Renderer: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access with ImGui_ImplSDLRenderer3_GetRenderState().
|
||||
// Missing features:
|
||||
// [ ] Renderer: Multi-viewport support (multiple windows).
|
||||
|
||||
@ -27,6 +27,7 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2026-09-17: Restore modified texture scale modes at the end of RenderDrawData(). Added DrawCallback_SetSamplerFromTex support. Added CurrentScaleMode in ImGui_ImplSDLRenderer3_RenderState (#9543, #9378)
|
||||
// 2026-07-15: Fixed default sampler state to be linear (broken 2026-04-23). (#9470, #9378)
|
||||
// 2026-04-23: Added support for standard draw callbacks (in platform_io): DrawCallback_ResetRenderState, DrawCallback_SetSamplerLinear, DrawCallback_SetSamplerNearest. (#9378)
|
||||
// 2026-03-12: Fixed invalid assert in ImGui_ImplSDLRenderer3_UpdateTexture() if ImTextureID_Invalid is defined to be != 0, which became the default since 2026-03-12. (#9295)
|
||||
@ -53,19 +54,24 @@
|
||||
#endif
|
||||
|
||||
// SDL
|
||||
#include <SDL3/SDL.h>
|
||||
#include <SDL3/SDL_render.h>
|
||||
#include <SDL3/SDL_version.h>
|
||||
#if !SDL_VERSION_ATLEAST(3,0,0)
|
||||
#error This backend requires SDL 3.0.0+
|
||||
#endif
|
||||
|
||||
// SDL_Renderer data
|
||||
struct ImGui_ImplSDLRenderer3_TexScaleModeEntry
|
||||
{
|
||||
SDL_Texture* Texture;
|
||||
SDL_ScaleMode ScaleModeBackup;
|
||||
};
|
||||
|
||||
struct ImGui_ImplSDLRenderer3_Data
|
||||
{
|
||||
SDL_Renderer* Renderer; // Main viewport's renderer
|
||||
ImVector<SDL_FColor> ColorBuffer;
|
||||
|
||||
// Render State
|
||||
SDL_ScaleMode CurrentScaleMode;
|
||||
ImVector<ImGui_ImplSDLRenderer3_TexScaleModeEntry> TexScaleModeBackups; // Backup of texture scale modes
|
||||
|
||||
ImGui_ImplSDLRenderer3_Data() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
@ -77,17 +83,21 @@ static ImGui_ImplSDLRenderer3_Data* ImGui_ImplSDLRenderer3_GetBackendData()
|
||||
return ImGui::GetCurrentContext() ? (ImGui_ImplSDLRenderer3_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
||||
}
|
||||
|
||||
ImGui_ImplSDLRenderer3_RenderState* ImGui_ImplSDLRenderer3_GetRenderState()
|
||||
{
|
||||
return (ImGui_ImplSDLRenderer3_RenderState*)ImGui::GetPlatformIO().Renderer_RenderState;
|
||||
}
|
||||
|
||||
// Functions
|
||||
static void ImGui_ImplSDLRenderer3_SetupRenderState(SDL_Renderer* renderer)
|
||||
{
|
||||
ImGui_ImplSDLRenderer3_Data* bd = ImGui_ImplSDLRenderer3_GetBackendData();
|
||||
ImGui_ImplSDLRenderer3_RenderState* render_state = ImGui_ImplSDLRenderer3_GetRenderState();
|
||||
|
||||
// Clear out any viewports and cliprect set by the user
|
||||
// FIXME: Technically speaking there are lots of other things we could backup/setup/restore during our render process.
|
||||
SDL_SetRenderViewport(renderer, nullptr);
|
||||
SDL_SetRenderClipRect(renderer, nullptr);
|
||||
|
||||
bd->CurrentScaleMode = SDL_SCALEMODE_LINEAR;
|
||||
render_state->CurrentScaleMode = SDL_SCALEMODE_LINEAR;
|
||||
}
|
||||
|
||||
void ImGui_ImplSDLRenderer3_NewFrame()
|
||||
@ -117,8 +127,61 @@ static int SDL_RenderGeometryRaw8BitColor(SDL_Renderer* renderer, ImVector<SDL_F
|
||||
|
||||
// Draw callbacks
|
||||
static void ImGui_ImplSDLRenderer3_DrawCallback_ResetRenderState(const ImDrawList*, const ImDrawCmd*) {} // Intentionally empty. Used as an identifier for rendering loop to call its code. Simpler to implement this way.
|
||||
static void ImGui_ImplSDLRenderer3_DrawCallback_SetSamplerLinear(const ImDrawList*, const ImDrawCmd*) { ImGui_ImplSDLRenderer3_Data* bd = ImGui_ImplSDLRenderer3_GetBackendData(); bd->CurrentScaleMode = SDL_SCALEMODE_LINEAR; }
|
||||
static void ImGui_ImplSDLRenderer3_DrawCallback_SetSamplerNearest(const ImDrawList*, const ImDrawCmd*) { ImGui_ImplSDLRenderer3_Data* bd = ImGui_ImplSDLRenderer3_GetBackendData(); bd->CurrentScaleMode = SDL_SCALEMODE_NEAREST; }
|
||||
static void ImGui_ImplSDLRenderer3_DrawCallback_SetSamplerLinear(const ImDrawList*, const ImDrawCmd*) { ImGui_ImplSDLRenderer3_RenderState* render_state = ImGui_ImplSDLRenderer3_GetRenderState(); render_state->CurrentScaleMode = SDL_SCALEMODE_LINEAR; }
|
||||
static void ImGui_ImplSDLRenderer3_DrawCallback_SetSamplerNearest(const ImDrawList*, const ImDrawCmd*) { ImGui_ImplSDLRenderer3_RenderState* render_state = ImGui_ImplSDLRenderer3_GetRenderState(); render_state->CurrentScaleMode = SDL_SCALEMODE_NEAREST; }
|
||||
static void ImGui_ImplSDLRenderer3_DrawCallback_SetSamplerFromTex(const ImDrawList*, const ImDrawCmd*) { ImGui_ImplSDLRenderer3_RenderState* render_state = ImGui_ImplSDLRenderer3_GetRenderState(); render_state->CurrentScaleMode = SDL_SCALEMODE_INVALID; } // SDL_SCALEMODE_INVALID = use/keep value in texture.
|
||||
|
||||
// SDLRenderer has various design issues which makes it hard to do it compared to regular graphics API.
|
||||
// - scale/filtering mode is tied to a texture.
|
||||
// - scale/filtering mode is not queued as part of the SDL_RenderGeometryXXX commands, so a change in one texture requires a flush.
|
||||
static void ImGui_ImplSDLRenderer3_TexScaleModeUpdate(SDL_Renderer* renderer, SDL_Texture* tex, SDL_ScaleMode desired_scale_mode)
|
||||
{
|
||||
ImGui_ImplSDLRenderer3_Data* bd = ImGui_ImplSDLRenderer3_GetBackendData();
|
||||
if (desired_scale_mode != SDL_SCALEMODE_INVALID)
|
||||
{
|
||||
// Enforce a scale mode
|
||||
SDL_ScaleMode tex_scale_mode = desired_scale_mode;
|
||||
if (!SDL_GetTextureScaleMode(tex, &tex_scale_mode) || tex_scale_mode == desired_scale_mode)
|
||||
return;
|
||||
SDL_FlushRenderer(renderer);
|
||||
SDL_SetTextureScaleMode(tex, desired_scale_mode);
|
||||
|
||||
// Store backup of old scale mode (FIXME-OPT)
|
||||
for (ImGui_ImplSDLRenderer3_TexScaleModeEntry& entry : bd->TexScaleModeBackups)
|
||||
if (entry.Texture == tex)
|
||||
{
|
||||
if (entry.ScaleModeBackup == SDL_SCALEMODE_INVALID)
|
||||
entry.ScaleModeBackup = tex_scale_mode;
|
||||
return;
|
||||
}
|
||||
ImGui_ImplSDLRenderer3_TexScaleModeEntry entry = { tex, tex_scale_mode };
|
||||
bd->TexScaleModeBackups.push_back(entry);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use scale mode that was set in texture by user. If there is an entry, restore it and clear the entry.
|
||||
for (ImGui_ImplSDLRenderer3_TexScaleModeEntry& entry : bd->TexScaleModeBackups)
|
||||
if (entry.Texture == tex && entry.ScaleModeBackup != SDL_SCALEMODE_INVALID)
|
||||
{
|
||||
SDL_FlushRenderer(renderer);
|
||||
SDL_SetTextureScaleMode(tex, entry.ScaleModeBackup);
|
||||
entry.ScaleModeBackup = SDL_SCALEMODE_INVALID;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ImGui_ImplSDLRenderer3_TexScaleModeRestoreBackups(SDL_Renderer* renderer)
|
||||
{
|
||||
ImGui_ImplSDLRenderer3_Data* bd = ImGui_ImplSDLRenderer3_GetBackendData();
|
||||
if (bd->TexScaleModeBackups.Size == 0)
|
||||
return;
|
||||
SDL_FlushRenderer(renderer);
|
||||
for (ImGui_ImplSDLRenderer3_TexScaleModeEntry& entry : bd->TexScaleModeBackups)
|
||||
if (entry.ScaleModeBackup != SDL_SCALEMODE_INVALID)
|
||||
SDL_SetTextureScaleMode(entry.Texture, entry.ScaleModeBackup);
|
||||
bd->TexScaleModeBackups.resize(0);
|
||||
}
|
||||
|
||||
void ImGui_ImplSDLRenderer3_RenderDrawData(ImDrawData* draw_data, SDL_Renderer* renderer)
|
||||
{
|
||||
@ -161,19 +224,19 @@ 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;
|
||||
|
||||
// Setup desired state
|
||||
ImGui_ImplSDLRenderer3_SetupRenderState(renderer);
|
||||
IM_ASSERT(bd->TexScaleModeBackups.Size == 0);
|
||||
|
||||
// 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;
|
||||
SDL_ScaleMode last_scale_mode = bd->CurrentScaleMode;
|
||||
|
||||
// Render command lists
|
||||
for (const ImDrawList* draw_list : draw_data->CmdLists)
|
||||
@ -203,20 +266,17 @@ void ImGui_ImplSDLRenderer3_RenderDrawData(ImDrawData* draw_data, SDL_Renderer*
|
||||
if (clip_max.y > (float)fb_height) { clip_max.y = (float)fb_height; }
|
||||
if (clip_max.x <= clip_min.x || clip_max.y <= clip_min.y)
|
||||
continue;
|
||||
|
||||
SDL_Rect r = { (int)(clip_min.x), (int)(clip_min.y), (int)(clip_max.x - clip_min.x), (int)(clip_max.y - clip_min.y) };
|
||||
SDL_SetRenderClipRect(renderer, &r);
|
||||
|
||||
// Setup texture scale/filtering mode
|
||||
SDL_Texture* tex = (SDL_Texture*)pcmd->GetTexID();
|
||||
ImGui_ImplSDLRenderer3_TexScaleModeUpdate(renderer, tex, render_state.CurrentScaleMode);
|
||||
|
||||
// Draw
|
||||
const float* xy = (const float*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + offsetof(ImDrawVert, pos));
|
||||
const float* uv = (const float*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + offsetof(ImDrawVert, uv));
|
||||
const SDL_Color* color = (const SDL_Color*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + offsetof(ImDrawVert, col)); // SDL 2.0.19+
|
||||
|
||||
if (last_scale_mode != bd->CurrentScaleMode)
|
||||
SDL_FlushRenderer(renderer);
|
||||
|
||||
// Bind texture, Draw
|
||||
SDL_Texture* tex = (SDL_Texture*)pcmd->GetTexID();
|
||||
SDL_SetTextureScaleMode(tex, bd->CurrentScaleMode);
|
||||
const SDL_Color* color = (const SDL_Color*)(const void*)((const char*)(vtx_buffer + pcmd->VtxOffset) + offsetof(ImDrawVert, col));
|
||||
SDL_RenderGeometryRaw8BitColor(renderer, bd->ColorBuffer, tex,
|
||||
xy, (int)sizeof(ImDrawVert),
|
||||
color, (int)sizeof(ImDrawVert),
|
||||
@ -231,6 +291,7 @@ void ImGui_ImplSDLRenderer3_RenderDrawData(ImDrawData* draw_data, SDL_Renderer*
|
||||
// Restore modified SDL_Renderer state
|
||||
SDL_SetRenderViewport(renderer, old.ViewportEnabled ? &old.Viewport : nullptr);
|
||||
SDL_SetRenderClipRect(renderer, old.ClipEnabled ? &old.ClipRect : nullptr);
|
||||
ImGui_ImplSDLRenderer3_TexScaleModeRestoreBackups(renderer);
|
||||
}
|
||||
|
||||
void ImGui_ImplSDLRenderer3_UpdateTexture(ImTextureData* tex)
|
||||
@ -312,6 +373,7 @@ bool ImGui_ImplSDLRenderer3_Init(SDL_Renderer* renderer)
|
||||
platform_io.DrawCallback_ResetRenderState = ImGui_ImplSDLRenderer3_DrawCallback_ResetRenderState;
|
||||
platform_io.DrawCallback_SetSamplerLinear = ImGui_ImplSDLRenderer3_DrawCallback_SetSamplerLinear;
|
||||
platform_io.DrawCallback_SetSamplerNearest = ImGui_ImplSDLRenderer3_DrawCallback_SetSamplerNearest;
|
||||
platform_io.DrawCallback_SetSamplerFromTex = ImGui_ImplSDLRenderer3_DrawCallback_SetSamplerFromTex;
|
||||
|
||||
bd->Renderer = renderer;
|
||||
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
// [X] Renderer: User texture binding. Use 'SDL_Texture*' as texture identifier. Read the FAQ about ImTextureID/ImTextureRef!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||
// [X] Renderer: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access with ImGui_ImplSDLRenderer3_GetRenderState().
|
||||
// Missing features:
|
||||
// [ ] Renderer: Multi-viewport support (multiple windows).
|
||||
|
||||
@ -29,7 +29,8 @@
|
||||
#include "imgui.h" // IMGUI_IMPL_API
|
||||
#ifndef IMGUI_DISABLE
|
||||
|
||||
struct SDL_Renderer;
|
||||
// For SDL_ScaleMode which cannot be forward declared.
|
||||
#include <SDL3/SDL_render.h>
|
||||
|
||||
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
|
||||
IMGUI_IMPL_API bool ImGui_ImplSDLRenderer3_Init(SDL_Renderer* renderer);
|
||||
@ -50,6 +51,8 @@ IMGUI_IMPL_API void ImGui_ImplSDLRenderer3_UpdateTexture(ImTextureData* tex)
|
||||
struct ImGui_ImplSDLRenderer3_RenderState
|
||||
{
|
||||
SDL_Renderer* Renderer;
|
||||
SDL_ScaleMode CurrentScaleMode; // Current scale mode during render. Set to SDL_SCALEMODE_INVALID to use "SetSamplerFromTex" mode.
|
||||
};
|
||||
IMGUI_IMPL_API ImGui_ImplSDLRenderer3_RenderState* ImGui_ImplSDLRenderer3_GetRenderState();
|
||||
|
||||
#endif // #ifndef IMGUI_DISABLE
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
// [!] Renderer: User texture binding. Use a VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE 'VkDescriptorSet' as texture identifier. Call ImGui_ImplVulkan_AddTexture() to register one. Read the FAQ about ImTextureID/ImTextureRef + https://github.com/ocornut/imgui/pull/914 for discussions.
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||
// [X] Renderer: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access with ImGui_ImplVulkan_GetRenderState().
|
||||
// [x] Renderer: Multi-viewport / platform windows. With issues (flickering when creating a new viewport).
|
||||
|
||||
// The aim of imgui_impl_vulkan.h/.cpp is to be usable in your engine without any modification.
|
||||
@ -29,6 +29,8 @@
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2026-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface.
|
||||
// 2026-09-07: Round framebuffer dimensions to the nearest integer instead of truncating them. (#9538, 9515, #8628)
|
||||
// 2026-09-03: Added for support for multiple Vulkan contexts with custom loaders. (#6616)
|
||||
// 2026-07-15: [Docking] Vulkan: fixed use-after-free when using multi-viewport with dynamic rendering path: deep-copy SurfaceFormat.format into the persistent buffer instead of storing a pointer to the viewport's wd->SurfaceFormat which dangles after the viewport is destroyed. (#9390, #9468)
|
||||
// 2026-04-23: Added support for standard draw callbacks (in platform_io): DrawCallback_ResetRenderState, DrawCallback_SetSamplerLinear, DrawCallback_SetSamplerNearest. (#9378)
|
||||
// 2026-04-22: *BREAKING CHANGE* redesigned to use separate ImageView + Sampler instead of Combined Image Sampler. This change allows us to facilitate changing samplers, in line with other backends.
|
||||
@ -241,10 +243,28 @@ static bool g_FunctionsLoaded = true;
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkUpdateDescriptorSets) \
|
||||
IMGUI_VULKAN_FUNC_MAP_MACRO(vkWaitForFences)
|
||||
|
||||
struct ImGui_ImplVulkan_Functions
|
||||
{
|
||||
// Define function pointers
|
||||
#define IMGUI_VULKAN_FUNC_DEF(func) static PFN_##func func;
|
||||
#define IMGUI_VULKAN_FUNC_DEF(func) PFN_##func pfn_##func;
|
||||
IMGUI_VULKAN_FUNC_MAP(IMGUI_VULKAN_FUNC_DEF)
|
||||
#undef IMGUI_VULKAN_FUNC_DEF
|
||||
};
|
||||
|
||||
// Globally available function pointers used for initialization of the backend data
|
||||
static ImGui_ImplVulkan_Functions ImGuiImplVulkanFuncs;
|
||||
|
||||
// Multi Vulkan contexts support: wrap each Vulkan function pointer to properly dispatch it using the current backend data
|
||||
static ImGui_ImplVulkan_Functions& ImGui_ImplVulkan_GetFunctions();
|
||||
#define IMGUI_VULKAN_FUNC_WRAPPER(func) \
|
||||
template<typename... Args> \
|
||||
auto func(Args&&... args) -> decltype(ImGui_ImplVulkan_GetFunctions().pfn_##func(args...)) \
|
||||
{ \
|
||||
return ImGui_ImplVulkan_GetFunctions().pfn_##func(args...); \
|
||||
}
|
||||
IMGUI_VULKAN_FUNC_MAP(IMGUI_VULKAN_FUNC_WRAPPER)
|
||||
#undef IMGUI_VULKAN_FUNC_WRAPPER
|
||||
|
||||
#endif // IMGUI_IMPL_VULKAN_USE_LOADER
|
||||
|
||||
#ifdef IMGUI_IMPL_VULKAN_HAS_DYNAMIC_RENDERING
|
||||
@ -326,6 +346,11 @@ struct ImGui_ImplVulkan_Data
|
||||
// Render buffers for main window
|
||||
ImGui_ImplVulkan_WindowRenderBuffers MainWindowRenderBuffers;
|
||||
|
||||
// Vulkan function pointers loaded for this context
|
||||
#ifdef IMGUI_IMPL_VULKAN_USE_LOADER
|
||||
ImGui_ImplVulkan_Functions Functions;
|
||||
#endif
|
||||
|
||||
ImGui_ImplVulkan_Data()
|
||||
{
|
||||
memset((void*)this, 0, sizeof(*this));
|
||||
@ -464,6 +489,21 @@ static ImGui_ImplVulkan_Data* ImGui_ImplVulkan_GetBackendData()
|
||||
return ImGui::GetCurrentContext() ? (ImGui_ImplVulkan_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
||||
}
|
||||
|
||||
ImGui_ImplVulkan_RenderState* ImGui_ImplVulkan_GetRenderState()
|
||||
{
|
||||
return (ImGui_ImplVulkan_RenderState*)ImGui::GetPlatformIO().Renderer_RenderState;
|
||||
}
|
||||
|
||||
#ifdef IMGUI_IMPL_VULKAN_USE_LOADER
|
||||
// Get the Vulkan function pointers used by the current backend.
|
||||
// If no backend is available, return the currently loaded global function pointers (ImGuiImplVulkanFuncs).
|
||||
static ImGui_ImplVulkan_Functions& ImGui_ImplVulkan_GetFunctions()
|
||||
{
|
||||
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
|
||||
return bd ? bd->Functions : ImGuiImplVulkanFuncs;
|
||||
}
|
||||
#endif
|
||||
|
||||
static uint32_t ImGui_ImplVulkan_MemoryType(VkMemoryPropertyFlags properties, uint32_t type_bits)
|
||||
{
|
||||
ImGui_ImplVulkan_Data* bd = ImGui_ImplVulkan_GetBackendData();
|
||||
@ -559,7 +599,7 @@ static void ImGui_ImplVulkan_SetupRenderState(ImDrawData* draw_data, VkPipeline
|
||||
constants[1] = 2.0f / draw_data->DisplaySize.y;
|
||||
constants[2] = -1.0f - draw_data->DisplayPos.x * constants[0]; // Translate
|
||||
constants[3] = -1.0f - draw_data->DisplayPos.y * constants[1];
|
||||
vkCmdPushConstants(command_buffer, bd->PipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(float) * 4, constants);
|
||||
vkCmdPushConstants(command_buffer, bd->PipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0, (uint32_t)sizeof(float) * 4, constants);
|
||||
|
||||
// Setup sampler
|
||||
vkCmdBindDescriptorSets(bd->RenderState->CommandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, bd->PipelineLayout, 1, 1, &bd->SamplerLinearDS, 0, nullptr);
|
||||
@ -583,8 +623,8 @@ void ImGui_ImplVulkan_DrawCallback_SetSamplerCustom(const ImDrawList*, const ImD
|
||||
void ImGui_ImplVulkan_RenderDrawData(ImDrawData* draw_data, VkCommandBuffer command_buffer, VkPipeline pipeline)
|
||||
{
|
||||
// Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
|
||||
int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x);
|
||||
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
|
||||
int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x + 0.5f);
|
||||
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y + 0.5f);
|
||||
if (fb_width <= 0 || fb_height <= 0)
|
||||
return;
|
||||
|
||||
@ -1354,8 +1394,8 @@ bool ImGui_ImplVulkan_LoadFunctions(uint32_t api_version, PFN_vkVoidFunction(
|
||||
|
||||
#ifdef IMGUI_IMPL_VULKAN_USE_LOADER
|
||||
#define IMGUI_VULKAN_FUNC_LOAD(func) \
|
||||
func = reinterpret_cast<decltype(func)>(loader_func(#func, user_data)); \
|
||||
if (func == nullptr) \
|
||||
ImGuiImplVulkanFuncs.pfn_##func = reinterpret_cast<PFN_##func>(loader_func(#func, user_data)); \
|
||||
if (ImGuiImplVulkanFuncs.pfn_##func == nullptr) \
|
||||
return false;
|
||||
IMGUI_VULKAN_FUNC_MAP(IMGUI_VULKAN_FUNC_LOAD)
|
||||
#undef IMGUI_VULKAN_FUNC_LOAD
|
||||
@ -1424,6 +1464,9 @@ bool ImGui_ImplVulkan_Init(ImGui_ImplVulkan_InitInfo* info)
|
||||
IM_ASSERT(info->PipelineInfoMain.RenderPass == VK_NULL_HANDLE && info->PipelineInfoForViewports.RenderPass == VK_NULL_HANDLE);
|
||||
|
||||
bd->VulkanInitInfo = *info;
|
||||
#ifdef IMGUI_IMPL_VULKAN_USE_LOADER
|
||||
bd->Functions = ImGuiImplVulkanFuncs;
|
||||
#endif
|
||||
|
||||
VkPhysicalDeviceProperties properties;
|
||||
vkGetPhysicalDeviceProperties(info->PhysicalDevice, &properties);
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
// [!] Renderer: User texture binding. Use a VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE 'VkDescriptorSet' as texture identifier. Call ImGui_ImplVulkan_AddTexture() to register one. Read the FAQ about ImTextureID/ImTextureRef + https://github.com/ocornut/imgui/pull/914 for discussions.
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||
// [X] Renderer: Texture updates support for dynamic font atlas (ImGuiBackendFlags_RendererHasTextures).
|
||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access with ImGui_ImplVulkan_GetRenderState().
|
||||
// [x] Renderer: Multi-viewport / platform windows. With issues (flickering when creating a new viewport).
|
||||
|
||||
// The aim of imgui_impl_vulkan.h/.cpp is to be usable in your engine without any modification.
|
||||
@ -183,6 +183,7 @@ struct ImGui_ImplVulkan_RenderState
|
||||
VkPipeline Pipeline;
|
||||
VkPipelineLayout PipelineLayout;
|
||||
};
|
||||
IMGUI_IMPL_API ImGui_ImplVulkan_RenderState* ImGui_ImplVulkan_GetRenderState();
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Internal / Miscellaneous Vulkan Helpers
|
||||
|
||||
@ -5,8 +5,8 @@
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'WGPUTextureView' as ImTextureID. Read the FAQ about ImTextureID/ImTextureRef!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
||||
// [X] Renderer: Texture updates support for dynamic font system (ImGuiBackendFlags_RendererHasTextures).
|
||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access with ImGui_ImplWGPU_GetRenderState().
|
||||
// Missing features or Issues:
|
||||
// [ ] Renderer: Multi-viewport support (multiple windows), useful for desktop.
|
||||
|
||||
@ -22,6 +22,8 @@
|
||||
|
||||
// CHANGELOG
|
||||
// (minor and older changes stripped away, please see git history for details)
|
||||
// 2026-09-07: Round framebuffer dimensions to the nearest integer instead of truncating them. (#9538, 9515, #8628)
|
||||
// 2026-08-31: Update to compile with wgpu-native 29.0. (#9377, #9532, #9530)
|
||||
// 2026-08-18: Fixed passing non-integer sizes to `wgpuRenderPassEncoderSetViewport() when FramebufferScale is >1.0f. (#9515, #8628)
|
||||
// 2026-04-23: Added support for standard draw callbacks (in platform_io): DrawCallback_ResetRenderState, DrawCallback_SetSamplerLinear, DrawCallback_SetSamplerNearest. (#9378)
|
||||
// 2026-03-25: Added support for WGVK native backend via IMGUI_IMPL_WEBGPU_BACKEND_WGVK define, with SPIRV shaders if WGSL is not available. (#9316, #9246, #9257)
|
||||
@ -68,12 +70,6 @@
|
||||
#error Emscripten <4.0.10 with '-sUSE_WEBGPU=1' is not supported anymore.
|
||||
#endif
|
||||
|
||||
#if defined IMGUI_IMPL_WEBGPU_BACKEND_DAWN || defined IMGUI_IMPL_WEBGPU_BACKEND_WGVK
|
||||
// Dawn renamed WGPUProgrammableStageDescriptor to WGPUComputeState (see: https://github.com/webgpu-native/webgpu-headers/pull/413)
|
||||
// Using type alias until WGPU adopts the same naming convention (#8369)
|
||||
using WGPUProgrammableStageDescriptor = WGPUComputeState;
|
||||
#endif
|
||||
|
||||
// Dear ImGui prototypes from imgui_internal.h
|
||||
extern ImGuiID ImHashData(const void* data_p, size_t data_size, ImU32 seed);
|
||||
#define MEMALIGN(_SIZE,_ALIGN) (((_SIZE) + ((_ALIGN) - 1)) & ~((_ALIGN) - 1)) // Memory align (copied from IM_ALIGN() macro).
|
||||
@ -135,6 +131,11 @@ static ImGui_ImplWGPU_Data* ImGui_ImplWGPU_GetBackendData()
|
||||
return ImGui::GetCurrentContext() ? (ImGui_ImplWGPU_Data*)ImGui::GetIO().BackendRendererUserData : nullptr;
|
||||
}
|
||||
|
||||
ImGui_ImplWGPU_RenderState* ImGui_ImplWGPU_GetRenderState()
|
||||
{
|
||||
return (ImGui_ImplWGPU_RenderState*)ImGui::GetPlatformIO().Renderer_RenderState;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// SHADERS
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -319,7 +320,7 @@ static void SafeRelease(FrameResources& res)
|
||||
SafeRelease(res.VertexBufferHost);
|
||||
}
|
||||
|
||||
static WGPUProgrammableStageDescriptor ImGui_ImplWGPU_CreateShaderModuleWGSL(const char* wgsl_source)
|
||||
static WGPUComputeState ImGui_ImplWGPU_CreateShaderModuleWGSL(const char* wgsl_source)
|
||||
{
|
||||
ImGui_ImplWGPU_Data* bd = ImGui_ImplWGPU_GetBackendData();
|
||||
IM_UNUSED(bd);
|
||||
@ -346,7 +347,7 @@ static WGPUProgrammableStageDescriptor ImGui_ImplWGPU_CreateShaderModuleWGSL(con
|
||||
pop_cb.userdata1 = &validation_error;
|
||||
wgpuDevicePopErrorScope(bd->wgpuDevice, pop_cb);
|
||||
|
||||
WGPUProgrammableStageDescriptor stage_desc = {};
|
||||
WGPUComputeState stage_desc = {};
|
||||
if (module && !validation_error)
|
||||
{
|
||||
stage_desc.module = module;
|
||||
@ -359,7 +360,7 @@ static WGPUProgrammableStageDescriptor ImGui_ImplWGPU_CreateShaderModuleWGSL(con
|
||||
return stage_desc;
|
||||
}
|
||||
|
||||
static WGPUProgrammableStageDescriptor ImGui_ImplWGPU_CreateShaderModuleSPIRV(const void* spirv_binary, size_t spirv_length)
|
||||
static WGPUComputeState ImGui_ImplWGPU_CreateShaderModuleSPIRV(const void* spirv_binary, size_t spirv_length)
|
||||
{
|
||||
ImGui_ImplWGPU_Data* bd = ImGui_ImplWGPU_GetBackendData();
|
||||
|
||||
@ -371,7 +372,7 @@ static WGPUProgrammableStageDescriptor ImGui_ImplWGPU_CreateShaderModuleSPIRV(co
|
||||
WGPUShaderModuleDescriptor desc = {};
|
||||
desc.nextInChain = (WGPUChainedStruct*)&spirv_desc;
|
||||
|
||||
WGPUProgrammableStageDescriptor stage_desc = {};
|
||||
WGPUComputeState stage_desc = {};
|
||||
stage_desc.module = wgpuDeviceCreateShaderModule(bd->wgpuDevice, &desc);
|
||||
|
||||
stage_desc.entryPoint = { "main", WGPU_STRLEN };
|
||||
@ -443,9 +444,9 @@ static void ImGui_ImplWGPU_SetupRenderState(ImDrawData* draw_data, WGPURenderPas
|
||||
}
|
||||
|
||||
// Setup viewport
|
||||
int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x);
|
||||
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
|
||||
wgpuRenderPassEncoderSetViewport(ctx, 0, 0, fb_width, fb_height, 0, 1);
|
||||
int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x + 0.5f);
|
||||
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y + 0.5f);
|
||||
wgpuRenderPassEncoderSetViewport(ctx, 0, 0, (float)fb_width, (float)fb_height, 0, 1);
|
||||
|
||||
// Bind shader and vertex buffers
|
||||
wgpuRenderPassEncoderSetVertexBuffer(ctx, 0, fr->VertexBuffer, 0, fr->VertexBufferSize * sizeof(ImDrawVert));
|
||||
@ -467,8 +468,8 @@ static void ImGui_ImplWGPU_DrawCallback_SetSamplerNearest(const ImDrawList*, con
|
||||
void ImGui_ImplWGPU_RenderDrawData(ImDrawData* draw_data, WGPURenderPassEncoder pass_encoder)
|
||||
{
|
||||
// Avoid rendering when minimized
|
||||
int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x);
|
||||
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
|
||||
int fb_width = (int)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x + 0.5f);
|
||||
int fb_height = (int)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y + 0.5f);
|
||||
if (fb_width <= 0 || fb_height <= 0 || draw_data->CmdLists.Size == 0)
|
||||
return;
|
||||
|
||||
@ -774,7 +775,7 @@ bool ImGui_ImplWGPU_CreateDeviceObjects()
|
||||
graphics_pipeline_desc.layout = wgpuDeviceCreatePipelineLayout(bd->wgpuDevice, &layout_desc);
|
||||
|
||||
// Create the vertex shader
|
||||
WGPUProgrammableStageDescriptor vertex_shader_desc = ImGui_ImplWGPU_CreateShaderModuleWGSL(__shader_vert_wgsl);
|
||||
WGPUComputeState vertex_shader_desc = ImGui_ImplWGPU_CreateShaderModuleWGSL(__shader_vert_wgsl);
|
||||
if (!vertex_shader_desc.module) vertex_shader_desc = ImGui_ImplWGPU_CreateShaderModuleSPIRV(__shader_vert_spirv, sizeof(__shader_vert_spirv));
|
||||
graphics_pipeline_desc.vertex.module = vertex_shader_desc.module;
|
||||
graphics_pipeline_desc.vertex.entryPoint = vertex_shader_desc.entryPoint;
|
||||
@ -782,15 +783,9 @@ bool ImGui_ImplWGPU_CreateDeviceObjects()
|
||||
// Vertex input configuration
|
||||
WGPUVertexAttribute attribute_desc[] =
|
||||
{
|
||||
#if defined IMGUI_IMPL_WEBGPU_BACKEND_DAWN || defined IMGUI_IMPL_WEBGPU_BACKEND_WGVK
|
||||
{ nullptr, WGPUVertexFormat_Float32x2, (uint64_t)offsetof(ImDrawVert, pos), 0 },
|
||||
{ nullptr, WGPUVertexFormat_Float32x2, (uint64_t)offsetof(ImDrawVert, uv), 1 },
|
||||
{ nullptr, WGPUVertexFormat_Unorm8x4, (uint64_t)offsetof(ImDrawVert, col), 2 },
|
||||
#else
|
||||
{ WGPUVertexFormat_Float32x2, (uint64_t)offsetof(ImDrawVert, pos), 0 },
|
||||
{ WGPUVertexFormat_Float32x2, (uint64_t)offsetof(ImDrawVert, uv), 1 },
|
||||
{ WGPUVertexFormat_Unorm8x4, (uint64_t)offsetof(ImDrawVert, col), 2 },
|
||||
#endif
|
||||
};
|
||||
|
||||
WGPUVertexBufferLayout buffer_layouts[1];
|
||||
@ -803,7 +798,7 @@ bool ImGui_ImplWGPU_CreateDeviceObjects()
|
||||
graphics_pipeline_desc.vertex.buffers = buffer_layouts;
|
||||
|
||||
// Create the pixel shader
|
||||
WGPUProgrammableStageDescriptor pixel_shader_desc = ImGui_ImplWGPU_CreateShaderModuleWGSL(__shader_frag_wgsl);
|
||||
WGPUComputeState pixel_shader_desc = ImGui_ImplWGPU_CreateShaderModuleWGSL(__shader_frag_wgsl);
|
||||
if (!pixel_shader_desc.module) pixel_shader_desc = ImGui_ImplWGPU_CreateShaderModuleSPIRV(__shader_frag_spirv, sizeof(__shader_frag_spirv));
|
||||
|
||||
// Create the blending setup
|
||||
@ -996,11 +991,7 @@ void ImGui_ImplWGPU_NewFrame()
|
||||
|
||||
bool ImGui_ImplWGPU_IsSurfaceStatusError(WGPUSurfaceGetCurrentTextureStatus status)
|
||||
{
|
||||
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) || defined(IMGUI_IMPL_WEBGPU_BACKEND_WGVK)
|
||||
return (status == WGPUSurfaceGetCurrentTextureStatus_Error);
|
||||
#else
|
||||
return (status == WGPUSurfaceGetCurrentTextureStatus_OutOfMemory || status == WGPUSurfaceGetCurrentTextureStatus_DeviceLost);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool ImGui_ImplWGPU_IsSurfaceStatusSubOptimal(WGPUSurfaceGetCurrentTextureStatus status)
|
||||
@ -1013,7 +1004,6 @@ bool ImGui_ImplWGPU_IsSurfaceStatusSubOptimal(WGPUSurfaceGetCurrentTextureStatus
|
||||
}
|
||||
|
||||
// Helpers to obtain a string
|
||||
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN) || defined(IMGUI_IMPL_WEBGPU_BACKEND_WGVK)
|
||||
const char* ImGui_ImplWGPU_GetErrorTypeName(WGPUErrorType type)
|
||||
{
|
||||
switch (type)
|
||||
@ -1036,7 +1026,7 @@ const char* ImGui_ImplWGPU_GetDeviceLostReasonName(WGPUDeviceLostReason type)
|
||||
default: return "Unknown";
|
||||
}
|
||||
}
|
||||
#elif !defined(__EMSCRIPTEN__)
|
||||
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) && !defined(__EMSCRIPTEN__)
|
||||
const char* ImGui_ImplWGPU_GetLogLevelName(WGPULogLevel level)
|
||||
{
|
||||
switch (level)
|
||||
|
||||
@ -17,8 +17,8 @@
|
||||
// Implemented features:
|
||||
// [X] Renderer: User texture binding. Use 'WGPUTextureView' as ImTextureID. Read the FAQ about ImTextureID/ImTextureRef!
|
||||
// [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset).
|
||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'.
|
||||
// [X] Renderer: Texture updates support for dynamic font system (ImGuiBackendFlags_RendererHasTextures).
|
||||
// [X] Renderer: Expose selected render state for draw callbacks to use. Access with ImGui_ImplWGPU_GetRenderState().
|
||||
// Missing features or Issues:
|
||||
// [ ] Renderer: Multi-viewport support (multiple windows), useful for desktop.
|
||||
|
||||
@ -83,6 +83,7 @@ struct ImGui_ImplWGPU_RenderState
|
||||
WGPUDevice Device;
|
||||
WGPURenderPassEncoder RenderPassEncoder;
|
||||
};
|
||||
IMGUI_IMPL_API ImGui_ImplWGPU_RenderState* ImGui_ImplWGPU_GetRenderState();
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Internal Helpers
|
||||
@ -97,10 +98,9 @@ bool ImGui_ImplWGPU_IsSurfaceStatusSubOptimal(WGPUSurfaceGetCurrentTextur
|
||||
void ImGui_ImplWGPU_DebugPrintAdapterInfo(const WGPUAdapter& adapter);
|
||||
const char* ImGui_ImplWGPU_GetBackendTypeName(WGPUBackendType type);
|
||||
const char* ImGui_ImplWGPU_GetAdapterTypeName(WGPUAdapterType type);
|
||||
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_DAWN)
|
||||
const char* ImGui_ImplWGPU_GetDeviceLostReasonName(WGPUDeviceLostReason type);
|
||||
const char* ImGui_ImplWGPU_GetErrorTypeName(WGPUErrorType type);
|
||||
#elif defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
||||
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU) && !defined(__EMSCRIPTEN__)
|
||||
const char* ImGui_ImplWGPU_GetLogLevelName(WGPULogLevel level);
|
||||
#endif
|
||||
|
||||
|
||||
@ -72,7 +72,7 @@ For example, the [example_win32_directx11](https://github.com/ocornut/imgui/tree
|
||||
|
||||
In the [backends/](https://github.com/ocornut/imgui/blob/master/backends) folder:
|
||||
|
||||
List of Platforms Backends:
|
||||
List of Platform Backends:
|
||||
|
||||
imgui_impl_android.cpp ; Android native app API
|
||||
imgui_impl_glfw.cpp ; GLFW (Windows, macOS, Linux, etc.) http://www.glfw.org/
|
||||
|
||||
@ -42,9 +42,11 @@ HOW TO UPDATE?
|
||||
Breaking Changes:
|
||||
|
||||
- Style: obsoleted `style.CurveTessellationTol (default 1.25)` which was in Pixels² unit in
|
||||
favor of `style.CurveTesselationMaxError` (default 1.12)` which is in Pixels unit. It is
|
||||
favor of `style.CurveTessellationMaxError` (default 1.12)` which is in Pixels unit. It is
|
||||
easier to tweak + this allows us to easily scale error threshold on high density screens.
|
||||
- style.CurveTesselationMaxError == sqrf(style.CurveTessellationTol).
|
||||
- style.CurveTessellationMaxError == sqrf(style.CurveTessellationTol).
|
||||
- ImGuiTextFilter: removed `float width` parameter of `Draw(const char* filter, float width)`:
|
||||
prefer using `SetNextItemWidth(float)` which is standard. Kept inline redirection function.
|
||||
- Backends:
|
||||
- DirectX12: Removed support for legacy `ImGui_ImplDX12_Init()` signature, which was
|
||||
obsoleted in 1.91.6 (December 2014), because it needed to forcefully disable support
|
||||
@ -52,28 +54,109 @@ Breaking Changes:
|
||||
|
||||
Other Changes:
|
||||
|
||||
- Drags, Sliders:
|
||||
- Fixed an overflow using `ImGuiSliderFlags_Logarithmic` with S32/S64 types which
|
||||
leads to clamped interactions. (#9526, #3361, #1823, #1316, #642) [@lailoken]
|
||||
- Ongoing drags may be cancelled using Right-Click, Escape or Gamepad Triangle.
|
||||
Cancelling reverts to the initial value. (#8564, #9534)
|
||||
- TreeNode:
|
||||
- Fixed issues/asserts with 32+ deep trees when using ImGuiTreeNodeFlags_DrawLinesXXX
|
||||
features or other features requiring stack storage. (#9509) [@lasrod]
|
||||
- TabBar:
|
||||
- Improved scroll target when clicking a Tab that is larger than the scrolling
|
||||
section width.
|
||||
- Using <> scrolling buttons while the selected Tab is at either end of the
|
||||
section mid-section but not fully visible always makes it fully visible
|
||||
(before eventually selecting a Tab in the leading/trailing section)
|
||||
- Selectable:
|
||||
- Fixed `ImGuiSelectableFlags_SelectOnNav` triggering during NavInit.
|
||||
- Fonts:
|
||||
- Reworked `AddFontDefault()` to use `io.DisplayFrameBufferScale` as part of the heuristic
|
||||
to select `AddFontDefaultVector()` by default, effectively using ProggyForever instead of
|
||||
ProggyClean on most Apple/Retina setups by default.
|
||||
- ImDrawList:
|
||||
- ColorEdit:
|
||||
- ColorButton, ColorEdit, ColorPicker: cancel-out alpha caused by BeginDisabled() so
|
||||
disabled color buttons have the same color as non-disabled oness. (#9511)
|
||||
- ColorButton: fixed issues/inconsistencies with checkerboard rendering when combining
|
||||
color alpha and global style alpha. (#9511) [@enjmiah, @ocornut]
|
||||
- Popups:
|
||||
- Amended context menu right-click opening code to check that the right-click
|
||||
hasn't been owned by another items. This is more correct and also necessary
|
||||
to avoid Drags/Sliders cancelling also triggering a cancel menu. (#8564, #9534)
|
||||
- ImGuiTextFilter:
|
||||
- Added support for space as an "and" filter, which is the standard. (#2435, #30)
|
||||
e.g. w/ filter 'hello world' (without quotes) both words needs to be in input data.
|
||||
- Added support for double-quoted "xxx" blocks to e.g. match words sequences. (#2435)
|
||||
e.g. w/ filter "hello world" the exact sequence needs to be in input data.
|
||||
- Fixed filtering when mixing "include" and "-exclude" keyword so that an "-exclude"
|
||||
match always filters out. (#2435) [@kudaba, @ocornut]
|
||||
- Added `DrawWithHint()` function. (#6206, #6395, #6447)
|
||||
- Added a "incl -excl" hint by default when the search field is empty. (#6206, #6395, #6447)
|
||||
- Style:
|
||||
- Inverted `ImGuiCol_TitleBgXXX` colors for `StyleColorsLight()` so that the selected
|
||||
window title bar appears brighter.
|
||||
- Misc:
|
||||
- Added `ImGuiItemFlags_MixedValue` flag for representing mixed/indeterminate values.
|
||||
Supported by: Checkbox(), RadioButton(), DragXXX(), SliderXXX(), InputXXX(), ColorXXX()
|
||||
and Combo() functions.
|
||||
The scoped flag is designed for usage by advanced property editors. (#5518, #5677, #6865)
|
||||
- Fixed `GetBackgroundDrawList()`/`GetForegroundDrawList()` not being properly reset
|
||||
every frame when cumulated session time is very large (e.g. a few days). [@lailoken]
|
||||
- Added `IM_NODEBUGSTEP` helper to tag functions with `__declspec(non_user_code)` (MSVC)
|
||||
or `[[gnu::artificial]]` (Clang/GCC) in order to provide a hint to debuggers to skip
|
||||
trivial functions when stepping into.
|
||||
- Tagged various trivial functions using `IM_NODEBUGSTEP`: `ImVec2()`, `ImVec4()` etc.
|
||||
and various operators.
|
||||
- IO: restore default clipboard/ime/shell platform handlers on ClearPlatformHandlers(), fixing
|
||||
issues switching backends mid-session to one relying on default. (#9537, #8945, #2769) [@lstalmir]
|
||||
- DrawList:
|
||||
- Per-viewport FramebufferScale for Apple/Retina screen is applied to draw lists:
|
||||
- AA Fringe is scaled accordingly.
|
||||
- Circle and Curves tessellation error are scaled accordingly.
|
||||
- Reworked assert in PushTexture() to allow convenience grace period of using a
|
||||
texture that was queue for destroy during the frame. Make it safe to stick to
|
||||
an existing texture during the frame. (#9528, #8465)
|
||||
- Added optional `platform_io.DrawCallback_SetSamplerFromTex` standard backend-agnostic
|
||||
draw callback for requesting to use the sampler associated already associated to a texture.
|
||||
Currently only supported by the OpenGL2/3 and SDLRenderer3 backend. (#9378)
|
||||
- Demo:
|
||||
- Added `Widgets->Mixed Values` section. (#5518, #5677, #6865)
|
||||
- Style Editor: fixed style/colors combo box applying style when opening Combo.
|
||||
- Backends:
|
||||
- QNX: added QNX Screen backend. (#9492) [@mgorchak-blackberry]
|
||||
- OpenGL2, OpenGL3: added support for `platform_io.DrawCallback_SetSamplerFromTex` draw
|
||||
callback to request using the sampler associated already associated to a texture. (#9378)
|
||||
- OpenGL2, OpenGL3: fixed `DrawCallback_ResetRenderState` handler not reseting all states
|
||||
in the glTexParameter() path. (#9378)
|
||||
- SDL2: fixed querying framebuffer scale/density when using Metal without
|
||||
going through a SDL_Renderer. (#5592) [@lailoken]
|
||||
- SDLRenderer3: restore any temporarily modified texture scale modes at the of `RenderDrawData()`. (#9378)
|
||||
- SDLRenderer3: expose CurrentScaleMode in ImGui_ImplSDLRenderer3_RenderState. (#9543, #9378) [@Clownacy]
|
||||
- SDLRenderer3: added support for `platform_io.DrawCallback_SetSamplerFromTex` draw callback to request
|
||||
using the sampler associated already associated to a texture via `SDL_SetTextureScaleMode()`. (#9378)
|
||||
It is equivalent to setting `render_state->CurrentScaleMode = SDL_SCALEMODE_INVALID`.
|
||||
Note: this callback is only supported by selected rendering backends: most other graphics API
|
||||
don't have the equivalent of `SDL_SetTextureScaleMode()` and the callback won't work with them.
|
||||
- Vulkan: added for support for multiple Vulkan contexts with custom loaders. (#6616) [@lstalmir]
|
||||
- WebGPU: fixed passing non-integer sizes to `wgpuRenderPassEncoderSetViewport()`
|
||||
when when `FramebufferScale` is >1.0f. (#9515, #8628) [@WayU]
|
||||
- WebGPU: update to build with wgpu-native 29.0+. (#9377, #9532, #9530) [@lucascompython, @ivan-enzhaev]
|
||||
- Examples:
|
||||
- SDL2+Metal: create Metal context without using a SDL_Renderer.
|
||||
- MSVC: disabled /JMC in Visual Studio projects (unnecessary overhead).
|
||||
- GLFW/SDL2/SDL3+WebGPU: fixed running with wgpu-native missing `wgpuInstanceWaitAny()`. (#9377)
|
||||
- SDL2+Metal: create Metal context without using a `SDL_Renderer`.
|
||||
- QNX+OpenGL3, QNX+Vulkan: added QNX Screen examples. (#9492) [@mgorchak-blackberry]
|
||||
- OSX+OpenGL3: added example_apple_opengl3/ (OSX/Cocoa + OpenGL 3.2 Core profile).
|
||||
|
||||
Docking+Viewports Branch:
|
||||
|
||||
- Style:
|
||||
- Changed `ImGuiCol_DockingEmptyBg` value for `StyleColorsLight()`.
|
||||
- Backends:
|
||||
- DX10, DX11, DX12: fixed crash when CreateSwapChain() or CreateRenderTargetView()
|
||||
calls are failing. (#9546)
|
||||
- GLFW: fixed applying mouse cursor shapes to secondary viewports, broken in 1.92.6
|
||||
when introducing a cache. (#9545) [@JamesWrigley]
|
||||
- Metal: fixed resizing windows losing framebuffer scale. (#6828, #8856) [@laikoken]
|
||||
- Examples:
|
||||
- SDL3+Metal, GLFW+Metal: fix multi-viewport support.
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
## Index
|
||||
|
||||
- [Getting Started & General Advice](#getting-started--general-advice)
|
||||
- [Issues vs Discussions](#issues-vs-discussions)
|
||||
- [Using "Issues" for almost everything!](using-issues-for-almost-everything)
|
||||
- [How to open an Issue](#how-to-open-an-issue)
|
||||
- [How to open a Pull Request](#how-to-open-a-pull-request)
|
||||
- [Copyright / Contributor License Agreement](#copyright--contributor-license-agreement)
|
||||
@ -23,18 +23,20 @@
|
||||
- If you get a crash or assert, use a debugger to locate the line triggering it and read the comments around.
|
||||
- Please don't be a [Help Vampire](https://slash7.com/2006/12/22/vampires/).
|
||||
|
||||
## 'Issues' vs 'Discussions'
|
||||
## Using "Issues" for almost everything!
|
||||
|
||||
We are happy to use 'Issues' for many type of open-ended questions. We are encouraging 'Issues' becoming an enormous, centralized and cross-referenced database of Dear ImGui contents.
|
||||
We are happy to use 'Issues' for many type of open-ended questions.
|
||||
We are encouraging 'Issues' becoming an enormous, centralized and cross-referenced database of Dear ImGui contents.
|
||||
|
||||
Only if you:
|
||||
- Need help using the API? Open an Issue!
|
||||
- Want to suggest a feature? Open an Issue!
|
||||
- etc.
|
||||
|
||||
ONLY IN THOSE CASE you can use the [Discussions forums](https://github.com/ocornut/imgui/discussions)
|
||||
- Cannot BUILD or LINK examples.
|
||||
- Cannot BUILD, or LINK, or RUN Dear ImGui in your application or custom engine.
|
||||
- Cannot LOAD a font.
|
||||
|
||||
Then please [use the Discussions forums](https://github.com/ocornut/imgui/discussions) instead of opening an issue.
|
||||
|
||||
If Dear ImGui is successfully showing in your app and you have used Dear ImGui before, you can open an Issue. Any form of discussions is welcome as a new issue.
|
||||
If Dear ImGui is successfully showing in your app and you have used Dear ImGui before, you can open an Issue. Any form of discussions is welcome as a new Issue.
|
||||
|
||||
## How to open an issue
|
||||
|
||||
|
||||
@ -92,6 +92,7 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
<SupportJustMyCode>false</SupportJustMyCode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
@ -107,6 +108,7 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
<SupportJustMyCode>false</SupportJustMyCode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
|
||||
@ -143,8 +143,8 @@
|
||||
ImDrawData* draw_data = ImGui::GetDrawData();
|
||||
|
||||
[[self openGLContext] makeCurrentContext];
|
||||
GLsizei width = (GLsizei)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x);
|
||||
GLsizei height = (GLsizei)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
|
||||
GLsizei width = (GLsizei)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x + 0.5f);
|
||||
GLsizei height = (GLsizei)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y + 0.5f);
|
||||
glViewport(0, 0, width, height);
|
||||
glClearColor(clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
@ -143,8 +143,8 @@
|
||||
ImDrawData* draw_data = ImGui::GetDrawData();
|
||||
|
||||
[[self openGLContext] makeCurrentContext];
|
||||
GLsizei width = (GLsizei)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x);
|
||||
GLsizei height = (GLsizei)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y);
|
||||
GLsizei width = (GLsizei)(draw_data->DisplaySize.x * draw_data->FramebufferScale.x + 0.5f);
|
||||
GLsizei height = (GLsizei)(draw_data->DisplaySize.y * draw_data->FramebufferScale.y + 0.5f);
|
||||
glViewport(0, 0, width, height);
|
||||
glClearColor(clear_color.x * clear_color.w, clear_color.y * clear_color.w, clear_color.z * clear_color.w, clear_color.w);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
@ -92,6 +92,7 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;..\libs\glfw\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
<SupportJustMyCode>false</SupportJustMyCode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
@ -107,6 +108,7 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;..\libs\glfw\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
<SupportJustMyCode>false</SupportJustMyCode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
|
||||
@ -92,6 +92,7 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;..\libs\glfw\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
<SupportJustMyCode>false</SupportJustMyCode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
@ -107,6 +108,7 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;..\libs\glfw\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
<SupportJustMyCode>false</SupportJustMyCode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
|
||||
@ -93,6 +93,7 @@
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%VULKAN_SDK%\include;..\libs\glfw\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
<SupportJustMyCode>false</SupportJustMyCode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
@ -109,6 +110,7 @@
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%VULKAN_SDK%\include;..\libs\glfw\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
<SupportJustMyCode>false</SupportJustMyCode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
|
||||
@ -1,10 +1,3 @@
|
||||
# Building for desktop with Dawn:
|
||||
# 1. git clone https://github.com/google/dawn dawn
|
||||
# 2. cmake -B build -DIMGUI_DAWN_DIR=dawn
|
||||
# 3. cmake --build build
|
||||
# The resulting binary will be found at one of the following locations:
|
||||
# * build/example_glfw_wgpu[.exe] or build/Debug/example_glfw_wgpu[.exe]
|
||||
|
||||
# Building for desktop with WGPU-Native:
|
||||
# 1. download WGPU-Native autogenerated binary modules for your platform/compiler from: https://github.com/gfx-rs/wgpu-native/releases
|
||||
# 2. unzip the downloaded file in your_preferred_folder
|
||||
@ -13,7 +6,14 @@
|
||||
# The resulting binary will be found at one of the following locations:
|
||||
# * build/example_glfw_wgpu[.exe] or build/Debug/example_glfw_wgpu[.exe]
|
||||
|
||||
# Building for desktop with WGVK (MUCH EASIER)
|
||||
# Building for desktop with Dawn: (VERY LONG TO BUILD)
|
||||
# 1. git clone https://github.com/google/dawn dawn
|
||||
# 2. cmake -B build -DIMGUI_DAWN_DIR=dawn
|
||||
# 3. cmake --build build
|
||||
# The resulting binary will be found at one of the following locations:
|
||||
# * build/example_glfw_wgpu[.exe] or build/Debug/example_glfw_wgpu[.exe]
|
||||
|
||||
# Building for desktop with WGVK:
|
||||
# 1. git clone https://github.com/manuel5975p/WGVK wgvk
|
||||
# 2. cmake -B build -DIMGUI_WGVK_DIR=wgvk
|
||||
# 3. cmake --build build
|
||||
@ -29,7 +29,7 @@
|
||||
# 4. emrun build/index.html
|
||||
|
||||
cmake_minimum_required(VERSION 3.22) # Dawn requires CMake >= 3.22
|
||||
project(imgui_example_glfw_wgpu C CXX)
|
||||
project(example_glfw_wgpu C CXX)
|
||||
|
||||
set(IMGUI_EXECUTABLE example_glfw_wgpu)
|
||||
|
||||
|
||||
@ -345,29 +345,25 @@ static WGPUDevice RequestDevice(wgpu::Instance& instance, wgpu::Adapter& adapter
|
||||
static void handle_request_adapter(WGPURequestAdapterStatus status, WGPUAdapter adapter, WGPUStringView message, void* userdata1, void* userdata2)
|
||||
{
|
||||
IM_UNUSED(userdata2);
|
||||
if (status == WGPURequestAdapterStatus_Success)
|
||||
if (status != WGPURequestAdapterStatus_Success)
|
||||
{
|
||||
WGPUAdapter* extAdapter = (WGPUAdapter*)userdata1;
|
||||
*extAdapter = adapter;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Request_adapter status=%#.8x message=%.*s\n", status, (int) message.length, message.data);
|
||||
printf("Request_adapter status=%#.8x message=%.*s\n", status, (int)message.length, message.data);
|
||||
return;
|
||||
}
|
||||
WGPUAdapter* extAdapter = (WGPUAdapter*)userdata1;
|
||||
*extAdapter = adapter;
|
||||
}
|
||||
|
||||
static void handle_request_device(WGPURequestDeviceStatus status, WGPUDevice device, WGPUStringView message, void* userdata1, void* userdata2)
|
||||
{
|
||||
IM_UNUSED(userdata2);
|
||||
if (status == WGPURequestDeviceStatus_Success)
|
||||
if (status != WGPURequestDeviceStatus_Success)
|
||||
{
|
||||
WGPUDevice* extDevice = (WGPUDevice*)userdata1;
|
||||
*extDevice = device;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Request_device status=%#.8x message=%.*s\n", status, (int) message.length, message.data);
|
||||
printf("Request_device status=%#.8x message=%.*s\n", status, (int)message.length, message.data);
|
||||
return;
|
||||
}
|
||||
WGPUDevice* extDevice = (WGPUDevice*)userdata1;
|
||||
*extDevice = device;
|
||||
}
|
||||
|
||||
static WGPUAdapter RequestAdapter(WGPUInstance& instance)
|
||||
@ -381,8 +377,10 @@ static WGPUAdapter RequestAdapter(WGPUInstance& instance)
|
||||
adapterCallbackInfo.userdata1 = &local_adapter;
|
||||
|
||||
WGPUFuture future = wgpuInstanceRequestAdapter(instance, &adapter_options, adapterCallbackInfo);
|
||||
#if !defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
||||
WGPUFutureWaitInfo waitInfo = { future, false };
|
||||
wgpuInstanceWaitAny(instance, 1, &waitInfo, ~0ull);
|
||||
#endif
|
||||
IM_ASSERT(local_adapter && "Error on Adapter request");
|
||||
return local_adapter;
|
||||
}
|
||||
@ -394,15 +392,20 @@ static WGPUDevice RequestDevice(WGPUInstance& instance, WGPUAdapter& adapter)
|
||||
deviceCallbackInfo.mode = WGPUCallbackMode_WaitAnyOnly;
|
||||
deviceCallbackInfo.callback = handle_request_device;
|
||||
deviceCallbackInfo.userdata1 = &local_device;
|
||||
|
||||
WGPUFuture future = wgpuAdapterRequestDevice(adapter, nullptr, deviceCallbackInfo);
|
||||
#if !defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
||||
WGPUFutureWaitInfo waitInfo = { future, false };
|
||||
wgpuInstanceWaitAny(instance, 1, &waitInfo, ~0ull);
|
||||
#else
|
||||
IM_UNUSED(instance);
|
||||
#endif
|
||||
IM_ASSERT(local_device && "Error on Device request");
|
||||
return local_device;
|
||||
}
|
||||
#endif // IMGUI_IMPL_WEBGPU_BACKEND_WGPU
|
||||
|
||||
bool InitWGPU(GLFWwindow* window)
|
||||
static bool InitWGPU(GLFWwindow* window)
|
||||
{
|
||||
WGPUTextureFormat preferred_fmt = WGPUTextureFormat_Undefined; // acquired from SurfaceCapabilities
|
||||
|
||||
@ -451,7 +454,7 @@ bool InitWGPU(GLFWwindow* window)
|
||||
|
||||
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
||||
wgpuSetLogCallback(
|
||||
[](WGPULogLevel level, WGPUStringView msg, void* userdata) { fprintf(stderr, "%s: %.*s\n", ImGui_ImplWGPU_GetLogLevelName(level), (int)msg.length, msg.data); }, nullptr
|
||||
[](WGPULogLevel level, WGPUStringView msg, void*) { fprintf(stderr, "%s: %.*s\n", ImGui_ImplWGPU_GetLogLevelName(level), (int)msg.length, msg.data); }, nullptr
|
||||
);
|
||||
wgpuSetLogLevel(WGPULogLevel_Warn);
|
||||
#endif
|
||||
|
||||
@ -92,6 +92,7 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>$(GLUT_INCLUDE_DIR);..\..;..\..\backends;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
<SupportJustMyCode>false</SupportJustMyCode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
@ -107,6 +108,7 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>$(GLUT_INCLUDE_DIR);..\..;..\..\backends;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
<SupportJustMyCode>false</SupportJustMyCode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
|
||||
@ -88,6 +88,7 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%(AdditionalIncludeDirectories);</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
<SupportJustMyCode>false</SupportJustMyCode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
@ -102,6 +103,7 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%(AdditionalIncludeDirectories);</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
<SupportJustMyCode>false</SupportJustMyCode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
|
||||
@ -93,6 +93,7 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%SDL2_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL2;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
<SupportJustMyCode>false</SupportJustMyCode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
@ -108,6 +109,7 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%SDL2_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL2;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
<SupportJustMyCode>false</SupportJustMyCode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
|
||||
@ -92,6 +92,7 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%SDL2_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL2;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
<SupportJustMyCode>false</SupportJustMyCode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
@ -107,6 +108,7 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%SDL2_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL2;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
<SupportJustMyCode>false</SupportJustMyCode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
|
||||
@ -92,6 +92,7 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%SDL2_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL2;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
<SupportJustMyCode>false</SupportJustMyCode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
@ -107,6 +108,7 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%SDL2_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL2;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
<SupportJustMyCode>false</SupportJustMyCode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
|
||||
@ -93,6 +93,7 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%SDL2_DIR%\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
<SupportJustMyCode>false</SupportJustMyCode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
@ -108,6 +109,7 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%SDL2_DIR%\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
<SupportJustMyCode>false</SupportJustMyCode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
|
||||
@ -93,6 +93,7 @@
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%VULKAN_SDK%\include;%SDL2_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL2;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
<SupportJustMyCode>false</SupportJustMyCode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
@ -109,6 +110,7 @@
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%VULKAN_SDK%\include;%SDL2_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL2;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
<SupportJustMyCode>false</SupportJustMyCode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
|
||||
@ -1,10 +1,3 @@
|
||||
# Building for desktop with Dawn:
|
||||
# 1. git clone https://github.com/google/dawn dawn
|
||||
# 2. cmake -B build -DIMGUI_DAWN_DIR=dawn
|
||||
# 3. cmake --build build
|
||||
# The resulting binary will be found at one of the following locations:
|
||||
# * build/example_sdl2_wgpu[.exe] or build/Debug/example_sdl2_wgpu[.exe]
|
||||
|
||||
# Building for desktop with WGPU-Native:
|
||||
# 1. download WGPU-Native autogenerated binary modules for your platform/compiler from: https://github.com/gfx-rs/wgpu-native/releases
|
||||
# 2. unzip the downloaded file in your_preferred_folder
|
||||
@ -13,7 +6,14 @@
|
||||
# The resulting binary will be found at one of the following locations:
|
||||
# * build/example_sdl2_wgpu[.exe] or build/Debug/example_sdl2_wgpu[.exe]
|
||||
|
||||
# Building for desktop with WGVK (MUCH EASIER)
|
||||
# Building for desktop with Dawn: (VERY LONG TO BUILD)
|
||||
# 1. git clone https://github.com/google/dawn dawn
|
||||
# 2. cmake -B build -DIMGUI_DAWN_DIR=dawn
|
||||
# 3. cmake --build build
|
||||
# The resulting binary will be found at one of the following locations:
|
||||
# * build/example_sdl2_wgpu[.exe] or build/Debug/example_sdl2_wgpu[.exe]
|
||||
|
||||
# Building for desktop with WGVK:
|
||||
# 1. git clone https://github.com/manuel5975p/WGVK wgvk
|
||||
# 2. cmake -B build -DIMGUI_WGVK_DIR=wgvk
|
||||
# 3. cmake --build build
|
||||
@ -29,7 +29,7 @@
|
||||
# 4. emrun build/index.html
|
||||
|
||||
cmake_minimum_required(VERSION 3.22) # Dawn requires CMake >= 3.22
|
||||
project(imgui_example_sdl2_wgpu C CXX)
|
||||
project(example_sdl2_wgpu C CXX)
|
||||
|
||||
set(IMGUI_EXECUTABLE example_sdl2_wgpu)
|
||||
|
||||
@ -37,7 +37,7 @@ if(NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE Debug CACHE STRING "" FORCE)
|
||||
endif()
|
||||
|
||||
set(CMAKE_CXX_STANDARD 10) # Dawn requires C++20
|
||||
set(CMAKE_CXX_STANDARD 20) # Dawn requires C++20
|
||||
|
||||
# Dear ImGui
|
||||
set(IMGUI_DIR ../../)
|
||||
|
||||
@ -330,29 +330,25 @@ static WGPUDevice RequestDevice(wgpu::Instance& instance, wgpu::Adapter& adapter
|
||||
static void handle_request_adapter(WGPURequestAdapterStatus status, WGPUAdapter adapter, WGPUStringView message, void* userdata1, void* userdata2)
|
||||
{
|
||||
IM_UNUSED(userdata2);
|
||||
if (status == WGPURequestAdapterStatus_Success)
|
||||
{
|
||||
WGPUAdapter* extAdapter = (WGPUAdapter*)userdata1;
|
||||
*extAdapter = adapter;
|
||||
}
|
||||
else
|
||||
if (status != WGPURequestAdapterStatus_Success)
|
||||
{
|
||||
printf("Request_adapter status=%#.8x message=%.*s\n", status, (int)message.length, message.data);
|
||||
return;
|
||||
}
|
||||
WGPUAdapter* extAdapter = (WGPUAdapter*)userdata1;
|
||||
*extAdapter = adapter;
|
||||
}
|
||||
|
||||
static void handle_request_device(WGPURequestDeviceStatus status, WGPUDevice device, WGPUStringView message, void* userdata1, void* userdata2)
|
||||
{
|
||||
IM_UNUSED(userdata2);
|
||||
if (status == WGPURequestDeviceStatus_Success)
|
||||
{
|
||||
WGPUDevice* extDevice = (WGPUDevice*)userdata1;
|
||||
*extDevice = device;
|
||||
}
|
||||
else
|
||||
if (status != WGPURequestDeviceStatus_Success)
|
||||
{
|
||||
printf("Request_device status=%#.8x message=%.*s\n", status, (int)message.length, message.data);
|
||||
return;
|
||||
}
|
||||
WGPUDevice* extDevice = (WGPUDevice*)userdata1;
|
||||
*extDevice = device;
|
||||
}
|
||||
|
||||
static WGPUAdapter RequestAdapter(WGPUInstance& instance)
|
||||
@ -366,8 +362,10 @@ static WGPUAdapter RequestAdapter(WGPUInstance& instance)
|
||||
adapterCallbackInfo.userdata1 = &local_adapter;
|
||||
|
||||
WGPUFuture future = wgpuInstanceRequestAdapter(instance, &adapter_options, adapterCallbackInfo);
|
||||
#if !defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
||||
WGPUFutureWaitInfo waitInfo = { future, false };
|
||||
wgpuInstanceWaitAny(instance, 1, &waitInfo, ~0ull);
|
||||
#endif
|
||||
IM_ASSERT(local_adapter && "Error on Adapter request");
|
||||
return local_adapter;
|
||||
}
|
||||
@ -379,9 +377,14 @@ static WGPUDevice RequestDevice(WGPUInstance& instance, WGPUAdapter& adapter)
|
||||
deviceCallbackInfo.mode = WGPUCallbackMode_WaitAnyOnly;
|
||||
deviceCallbackInfo.callback = handle_request_device;
|
||||
deviceCallbackInfo.userdata1 = &local_device;
|
||||
|
||||
WGPUFuture future = wgpuAdapterRequestDevice(adapter, nullptr, deviceCallbackInfo);
|
||||
#if !defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
||||
WGPUFutureWaitInfo waitInfo = { future, false };
|
||||
wgpuInstanceWaitAny(instance, 1, &waitInfo, ~0ull);
|
||||
#else
|
||||
IM_UNUSED(instance);
|
||||
#endif
|
||||
IM_ASSERT(local_device && "Error on Device request");
|
||||
return local_device;
|
||||
}
|
||||
@ -437,7 +440,7 @@ static bool InitWGPU(SDL_Window* window)
|
||||
|
||||
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
||||
wgpuSetLogCallback(
|
||||
[](WGPULogLevel level, WGPUStringView msg, void* userdata) { fprintf(stderr, "%s: %.*s\n", ImGui_ImplWGPU_GetLogLevelName(level), (int)msg.length, msg.data); }, nullptr
|
||||
[](WGPULogLevel level, WGPUStringView msg, void*) { fprintf(stderr, "%s: %.*s\n", ImGui_ImplWGPU_GetLogLevelName(level), (int)msg.length, msg.data); }, nullptr
|
||||
);
|
||||
wgpuSetLogLevel(WGPULogLevel_Warn);
|
||||
#endif
|
||||
|
||||
@ -93,6 +93,7 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%SDL3_DIR%\include;$(VcpkgCurrentInstalledDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
<SupportJustMyCode>false</SupportJustMyCode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
@ -108,6 +109,7 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%SDL3_DIR%\include;$(VcpkgCurrentInstalledDir)include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
<SupportJustMyCode>false</SupportJustMyCode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
|
||||
@ -92,6 +92,7 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%SDL3_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL3;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
<SupportJustMyCode>false</SupportJustMyCode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
@ -107,6 +108,7 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%SDL3_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL3;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
<SupportJustMyCode>false</SupportJustMyCode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
|
||||
@ -93,6 +93,7 @@
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%SDL3_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL3;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
<SupportJustMyCode>false</SupportJustMyCode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
@ -109,6 +110,7 @@
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%SDL3_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL3;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
<SupportJustMyCode>false</SupportJustMyCode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
|
||||
@ -92,6 +92,7 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%SDL3_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL3;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
<SupportJustMyCode>false</SupportJustMyCode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
@ -107,6 +108,7 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%SDL3_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL3;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
<SupportJustMyCode>false</SupportJustMyCode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
|
||||
@ -93,6 +93,7 @@
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%VULKAN_SDK%\include;%SDL3_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL3;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
<SupportJustMyCode>false</SupportJustMyCode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
@ -109,6 +110,7 @@
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%VULKAN_SDK%\include;%SDL3_DIR%\include;$(VcpkgCurrentInstalledDir)include\SDL3;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
<SupportJustMyCode>false</SupportJustMyCode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
|
||||
@ -29,7 +29,7 @@
|
||||
# 5. emrun build/index.html
|
||||
|
||||
cmake_minimum_required(VERSION 3.22) # Dawn requires CMake >= 3.22
|
||||
project(imgui_example_sdl3_wgpu C CXX)
|
||||
project(example_sdl3_wgpu C CXX)
|
||||
|
||||
set(IMGUI_EXECUTABLE example_sdl3_wgpu)
|
||||
|
||||
|
||||
@ -341,29 +341,25 @@ static WGPUDevice RequestDevice(wgpu::Instance& instance, wgpu::Adapter& adapter
|
||||
static void handle_request_adapter(WGPURequestAdapterStatus status, WGPUAdapter adapter, WGPUStringView message, void* userdata1, void* userdata2)
|
||||
{
|
||||
IM_UNUSED(userdata2);
|
||||
if (status == WGPURequestAdapterStatus_Success)
|
||||
{
|
||||
WGPUAdapter* extAdapter = (WGPUAdapter*)userdata1;
|
||||
*extAdapter = adapter;
|
||||
}
|
||||
else
|
||||
if (status != WGPURequestAdapterStatus_Success)
|
||||
{
|
||||
printf("Request_adapter status=%#.8x message=%.*s\n", status, (int)message.length, message.data);
|
||||
return;
|
||||
}
|
||||
WGPUAdapter* extAdapter = (WGPUAdapter*)userdata1;
|
||||
*extAdapter = adapter;
|
||||
}
|
||||
|
||||
static void handle_request_device(WGPURequestDeviceStatus status, WGPUDevice device, WGPUStringView message, void* userdata1, void* userdata2)
|
||||
{
|
||||
IM_UNUSED(userdata2);
|
||||
if (status == WGPURequestDeviceStatus_Success)
|
||||
{
|
||||
WGPUDevice* extDevice = (WGPUDevice*)userdata1;
|
||||
*extDevice = device;
|
||||
}
|
||||
else
|
||||
if (status != WGPURequestDeviceStatus_Success)
|
||||
{
|
||||
printf("Request_device status=%#.8x message=%.*s\n", status, (int)message.length, message.data);
|
||||
return;
|
||||
}
|
||||
WGPUDevice* extDevice = (WGPUDevice*)userdata1;
|
||||
*extDevice = device;
|
||||
}
|
||||
|
||||
static WGPUAdapter RequestAdapter(WGPUInstance& instance)
|
||||
@ -377,8 +373,10 @@ static WGPUAdapter RequestAdapter(WGPUInstance& instance)
|
||||
adapterCallbackInfo.userdata1 = &local_adapter;
|
||||
|
||||
WGPUFuture future = wgpuInstanceRequestAdapter(instance, &adapter_options, adapterCallbackInfo);
|
||||
#if !defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
||||
WGPUFutureWaitInfo waitInfo = { future, false };
|
||||
wgpuInstanceWaitAny(instance, 1, &waitInfo, ~0ull);
|
||||
#endif
|
||||
IM_ASSERT(local_adapter && "Error on Adapter request");
|
||||
return local_adapter;
|
||||
}
|
||||
@ -390,9 +388,14 @@ static WGPUDevice RequestDevice(WGPUInstance& instance, WGPUAdapter& adapter)
|
||||
deviceCallbackInfo.mode = WGPUCallbackMode_WaitAnyOnly;
|
||||
deviceCallbackInfo.callback = handle_request_device;
|
||||
deviceCallbackInfo.userdata1 = &local_device;
|
||||
|
||||
WGPUFuture future = wgpuAdapterRequestDevice(adapter, nullptr, deviceCallbackInfo);
|
||||
#if !defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
||||
WGPUFutureWaitInfo waitInfo = { future, false };
|
||||
wgpuInstanceWaitAny(instance, 1, &waitInfo, ~0ull);
|
||||
#else
|
||||
IM_UNUSED(instance);
|
||||
#endif
|
||||
IM_ASSERT(local_device && "Error on Device request");
|
||||
return local_device;
|
||||
}
|
||||
@ -448,7 +451,7 @@ static bool InitWGPU(SDL_Window* window)
|
||||
|
||||
#if defined(IMGUI_IMPL_WEBGPU_BACKEND_WGPU)
|
||||
wgpuSetLogCallback(
|
||||
[](WGPULogLevel level, WGPUStringView msg, void* userdata) { fprintf(stderr, "%s: %.*s\n", ImGui_ImplWGPU_GetLogLevelName(level), (int)msg.length, msg.data); }, nullptr
|
||||
[](WGPULogLevel level, WGPUStringView msg, void*) { fprintf(stderr, "%s: %.*s\n", ImGui_ImplWGPU_GetLogLevelName(level), (int)msg.length, msg.data); }, nullptr
|
||||
);
|
||||
wgpuSetLogLevel(WGPULogLevel_Warn);
|
||||
#endif
|
||||
|
||||
@ -88,6 +88,7 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%(AdditionalIncludeDirectories);</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
<SupportJustMyCode>false</SupportJustMyCode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
@ -102,6 +103,7 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%(AdditionalIncludeDirectories);</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
<SupportJustMyCode>false</SupportJustMyCode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
|
||||
@ -88,6 +88,7 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%(AdditionalIncludeDirectories);</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
<SupportJustMyCode>false</SupportJustMyCode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
@ -102,6 +103,7 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%(AdditionalIncludeDirectories);</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
<SupportJustMyCode>false</SupportJustMyCode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
|
||||
@ -89,6 +89,7 @@
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
<SupportJustMyCode>false</SupportJustMyCode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
@ -104,6 +105,7 @@
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
<SupportJustMyCode>false</SupportJustMyCode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
|
||||
@ -88,6 +88,7 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%(AdditionalIncludeDirectories);$(DXSDK_DIR)Include;</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
<SupportJustMyCode>false</SupportJustMyCode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
@ -102,6 +103,7 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%(AdditionalIncludeDirectories);$(DXSDK_DIR)Include;</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
<SupportJustMyCode>false</SupportJustMyCode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
|
||||
@ -88,6 +88,7 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
<SupportJustMyCode>false</SupportJustMyCode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
@ -102,6 +103,7 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
<SupportJustMyCode>false</SupportJustMyCode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
|
||||
@ -89,6 +89,7 @@
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%VULKAN_SDK%\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
<SupportJustMyCode>false</SupportJustMyCode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
@ -104,6 +105,7 @@
|
||||
<AdditionalIncludeDirectories>..\..;..\..\backends;%VULKAN_SDK%\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
|
||||
<SupportJustMyCode>false</SupportJustMyCode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
|
||||
15
imconfig.h
15
imconfig.h
@ -107,15 +107,18 @@
|
||||
// This will be inlined as part of ImVec2 and ImVec4 class declarations.
|
||||
/*
|
||||
#define IM_VEC2_CLASS_EXTRA \
|
||||
constexpr ImVec2(const MyVec2& f) : x(f.x), y(f.y) {} \
|
||||
operator MyVec2() const { return MyVec2(x,y); }
|
||||
IM_NODEBUGSTEP constexpr inline ImVec2(const MyVec2& f) : x(f.x), y(f.y) {} \
|
||||
IM_NODEBUGSTEP inline operator MyVec2() const { return MyVec2(x,y); }
|
||||
|
||||
#define IM_VEC4_CLASS_EXTRA \
|
||||
constexpr ImVec4(const MyVec4& f) : x(f.x), y(f.y), z(f.z), w(f.w) {} \
|
||||
operator MyVec4() const { return MyVec4(x,y,z,w); }
|
||||
#define IM_VEC4_CLASS_EXTRA \
|
||||
IM_NODEBUGSTEP constexpr inline ImVec4(const MyVec4& f) : x(f.x), y(f.y), z(f.z), w(f.w) {} \
|
||||
IM_NODEBUGSTEP inline operator MyVec4() const { return MyVec4(x,y,z,w); }
|
||||
*/
|
||||
//---- ...Or use Dear ImGui's own very basic math operators.
|
||||
//---- ...Or use Dear ImGui's own basic math operators in every file including imgui.h:
|
||||
//#ifndef IMGUI_DEFINE_MATH_OPERATORS
|
||||
//#define IMGUI_DEFINE_MATH_OPERATORS
|
||||
//#endif
|
||||
//---- ...Or manually '#define IMGUI_DEFINE_MATH_OPERATORS' before '#include "imgui.h"' to use from one file.
|
||||
|
||||
//---- Use 32-bit vertex indices (default is 16-bit) is one way to allow large meshes with more than 64K vertices.
|
||||
// Your renderer backend will need to support it (most example renderer backends support both 16/32-bit indices).
|
||||
|
||||
221
imgui.cpp
221
imgui.cpp
@ -402,8 +402,10 @@ IMPLEMENTING SUPPORT for ImGuiBackendFlags_RendererHasTextures:
|
||||
you may use GetMainViewport()->Pos to offset hard-coded positions, e.g. SetNextWindowPos(GetMainViewport()->Pos)
|
||||
- likewise io.MousePos and GetMousePos() will use OS coordinates.
|
||||
If you query mouse positions to interact with non-imgui coordinates you will need to offset them, e.g. subtract GetWindowViewport()->Pos.
|
||||
- 2026/08/03 (1.93.0) - Style: obsoleted `style.CurveTessellationTol (default 1.25)` which was in Pixels² unit in favor of `style.CurveTesselationMaxError` (default 1.12)` which is in Pixels unit.
|
||||
- style.CurveTesselationMaxError == sqrf(style.CurveTessellationTol).
|
||||
|
||||
- 2026/09/18 (1.93.0) - ImGuiTextFilter: removed `float width` parameter of `Draw(const char* filter, float width)`: prefer using `SetNextItemWidth(float)` which is standard. Kept inline redirection function.
|
||||
- 2026/08/03 (1.93.0) - Style: obsoleted `style.CurveTessellationTol (default 1.25)` which was in Pixels² unit in favor of `style.CurveTessellationMaxError` (default 1.12)` which is in Pixels unit.
|
||||
- style.CurveTessellationMaxError == sqrf(style.CurveTessellationTol).
|
||||
- 2026/07/20 (1.92.9) - DragXXX, SliderXXX, InputScalar: with `ImGuiItemFlags_LiveEditOnInputScalar` now defaulting to being disabled:
|
||||
inputting a value with the keyboard doesn't write intermediate values to backing variable. (#9476)
|
||||
- Before: DragFloat() with user typing "123" --> write back 1, then 12, then 123.
|
||||
@ -1404,10 +1406,9 @@ static void WindowSettingsHandler_ApplyAll(ImGuiContext*, ImGuiSetti
|
||||
static void WindowSettingsHandler_WriteAll(ImGuiContext*, ImGuiSettingsHandler*, ImGuiTextBuffer* buf);
|
||||
|
||||
// Platform Dependents default implementation for ImGuiPlatformIO functions
|
||||
static void InitializeDefaultPlatformHandlers(ImGuiPlatformIO& platform_io);
|
||||
static const char* Platform_GetClipboardTextFn_DefaultImpl(ImGuiContext* ctx);
|
||||
static void Platform_SetClipboardTextFn_DefaultImpl(ImGuiContext* ctx, const char* text);
|
||||
static void Platform_SetImeDataFn_DefaultImpl(ImGuiContext* ctx, ImGuiViewport* viewport, ImGuiPlatformImeData* data);
|
||||
static bool Platform_OpenInShellFn_DefaultImpl(ImGuiContext* ctx, const char* path);
|
||||
|
||||
namespace ImGui
|
||||
{
|
||||
@ -1603,7 +1604,7 @@ ImGuiStyle::ImGuiStyle()
|
||||
DockingSeparatorSize = 2.0f; // Thickness of resizing border between docked windows
|
||||
MouseCursorScale = 1.0f; // Scale software rendered mouse cursor (when io.MouseDrawCursor is enabled). May be removed later.
|
||||
|
||||
// Rendering & Tesselation
|
||||
// Rendering & Tessellation
|
||||
AntiAliasedLines = true; // Enable anti-aliased lines/borders. Disable if you are really tight on CPU/GPU.
|
||||
AntiAliasedLinesUseTex = true; // Enable anti-aliased lines/borders using textures where possible. Require backend to render with bilinear filtering (NOT point/nearest filtering).
|
||||
AntiAliasedFill = true; // Enable anti-aliased filled shapes (rounded rectangles, circles, etc.).
|
||||
@ -3155,11 +3156,11 @@ IM_MSVC_RUNTIME_CHECKS_RESTORE
|
||||
// [SECTION] ImGuiTextFilter
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Helper: Parse and apply text filters. In format "aaaaa[,bbbb][,ccccc]"
|
||||
// Helper: Parse and apply text filters e.g. 'aaa bbb -ccc'.
|
||||
ImGuiTextFilter::ImGuiTextFilter(const char* default_filter) //-V1077
|
||||
{
|
||||
InputBuf[0] = 0;
|
||||
CountGrep = 0;
|
||||
_CountExclude = 0;
|
||||
if (default_filter)
|
||||
{
|
||||
ImStrncpy(InputBuf, default_filter, IM_COUNTOF(InputBuf));
|
||||
@ -3167,84 +3168,110 @@ ImGuiTextFilter::ImGuiTextFilter(const char* default_filter) //-V1077
|
||||
}
|
||||
}
|
||||
|
||||
bool ImGuiTextFilter::Draw(const char* label, float width)
|
||||
bool ImGuiTextFilter::Draw(const char* label)
|
||||
{
|
||||
if (width != 0.0f)
|
||||
ImGui::SetNextItemWidth(width);
|
||||
bool value_changed = ImGui::InputText(label, InputBuf, IM_COUNTOF(InputBuf));
|
||||
return DrawWithHint(label, "incl -excl");
|
||||
}
|
||||
|
||||
// Use ImGui::SetNextItemWidth() manually if you want to use this.
|
||||
bool ImGuiTextFilter::DrawWithHint(const char* label, const char* hint)
|
||||
{
|
||||
bool value_changed = ImGui::InputTextWithHint(label, hint, InputBuf, IM_COUNTOF(InputBuf));
|
||||
if (value_changed)
|
||||
Build();
|
||||
return value_changed;
|
||||
}
|
||||
|
||||
void ImGuiTextFilter::ImGuiTextRange::split(char separator, ImVector<ImGuiTextRange>* out) const
|
||||
{
|
||||
out->resize(0);
|
||||
const char* wb = b;
|
||||
const char* we = wb;
|
||||
while (we < e)
|
||||
{
|
||||
if (*we == separator)
|
||||
{
|
||||
out->push_back(ImGuiTextRange(wb, we));
|
||||
wb = we + 1;
|
||||
}
|
||||
we++;
|
||||
}
|
||||
if (wb != we)
|
||||
out->push_back(ImGuiTextRange(wb, we));
|
||||
}
|
||||
|
||||
// Parse filter and split into a format optimal for PassFilter()
|
||||
void ImGuiTextFilter::Build()
|
||||
{
|
||||
Filters.resize(0);
|
||||
ImGuiTextRange input_range(InputBuf, InputBuf + ImStrlen(InputBuf));
|
||||
input_range.split(',', &Filters);
|
||||
_Items.resize(0);
|
||||
_CountExclude = 0;
|
||||
|
||||
CountGrep = 0;
|
||||
for (ImGuiTextRange& f : Filters)
|
||||
const char* buf_e = InputBuf + ImStrlen(InputBuf);
|
||||
const char* word_e;
|
||||
int seq_incl_start_idx = -1;
|
||||
for (const char* word_b = InputBuf; word_b < buf_e; word_b = word_e + 1)
|
||||
{
|
||||
while (f.b < f.e && ImCharIsBlankA(f.b[0]))
|
||||
f.b++;
|
||||
while (f.e > f.b && ImCharIsBlankA(f.e[-1]))
|
||||
f.e--;
|
||||
if (f.empty())
|
||||
continue;
|
||||
if (f.b[0] != '-')
|
||||
CountGrep += 1;
|
||||
}
|
||||
}
|
||||
|
||||
bool ImGuiTextFilter::PassFilter(const char* text, const char* text_end) const
|
||||
{
|
||||
if (Filters.Size == 0)
|
||||
return true;
|
||||
|
||||
if (text == NULL)
|
||||
text = text_end = "";
|
||||
|
||||
for (const ImGuiTextRange& f : Filters)
|
||||
{
|
||||
if (f.b == f.e)
|
||||
continue;
|
||||
if (f.b[0] == '-')
|
||||
// Trim blanks
|
||||
while (word_b < buf_e && ImCharIsBlankA(word_b[0])) // FIXME: UTF-8 support
|
||||
word_b++;
|
||||
const bool is_excl = (word_b < buf_e && word_b[0] == '-');
|
||||
if (is_excl)
|
||||
word_b++;
|
||||
const bool is_quote = (word_b < buf_e && word_b[0] == '\"');
|
||||
if (is_quote)
|
||||
{
|
||||
// Subtract
|
||||
if (ImStristr(text, text_end, f.b + 1, f.e) != NULL)
|
||||
return false;
|
||||
// Parsing quotes. Omit storing leading/trailing quotes.
|
||||
word_e = ImStrchrRange(++word_b, buf_e, '\"');
|
||||
if (word_e == NULL)
|
||||
word_e = buf_e;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Grep
|
||||
if (ImStristr(text, text_end, f.b, f.e) != NULL)
|
||||
return true;
|
||||
// Handle both ' ' and ',' separators.
|
||||
for (word_e = word_b; word_e < buf_e; word_e++)
|
||||
if (*word_e == ' ' || *word_e == ',')
|
||||
break;
|
||||
}
|
||||
|
||||
// Min length
|
||||
if (word_e - word_b > 0)
|
||||
{
|
||||
// Add to list. The '-' is not stored in items but implicitly inferred using (n < CountExclude).
|
||||
// FIXME-OPT: as items are derived from user input buffer and we expect the insert() to behave sanely.
|
||||
if (is_excl)
|
||||
{
|
||||
_Items.insert(_Items.Data + _CountExclude, ImGuiTextFilterItem(word_b, word_e));
|
||||
_CountExclude++;
|
||||
if (seq_incl_start_idx != -1)
|
||||
seq_incl_start_idx++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (seq_incl_start_idx == -1)
|
||||
seq_incl_start_idx = _Items.Size;
|
||||
_Items.insert(_Items.Data + _Items.Size, ImGuiTextFilterItem(word_b, word_e));
|
||||
_Items.Data[seq_incl_start_idx].CountInclude++;
|
||||
}
|
||||
}
|
||||
|
||||
// Next sequence
|
||||
if (word_e[0] == ',')
|
||||
seq_incl_start_idx = -1;
|
||||
}
|
||||
}
|
||||
|
||||
// Implicit * grep
|
||||
if (CountGrep == 0)
|
||||
// FIXME: Could use a specialized ImStristr() + pre-convert our filter to uppercase.
|
||||
bool ImGuiTextFilter::PassFilter(const char* text, const char* text_end) const
|
||||
{
|
||||
if (_Items.Size == 0)
|
||||
return true;
|
||||
if (text == NULL)
|
||||
text = text_end = "";
|
||||
|
||||
// Filters are sorted so that '-' ones are always leading.
|
||||
ImGuiTextFilterItem* seq = _Items.Data;
|
||||
ImGuiTextFilterItem* seq_excl_end = _Items.Data + _CountExclude;
|
||||
for (; seq < seq_excl_end; seq++)
|
||||
if (ImStristr(text, text_end, seq->Begin, seq->Begin + seq->Len) != NULL)
|
||||
return false;
|
||||
|
||||
// Process includes
|
||||
ImGuiTextFilterItem* seq_incl_end = _Items.Data + _Items.Size;
|
||||
if (seq == seq_incl_end) // When no inclusion are specified (only exclusions) we implicitly pass
|
||||
return true;
|
||||
while (seq < seq_incl_end)
|
||||
{
|
||||
ImGuiTextFilterItem* seq_next = seq + seq->CountInclude;
|
||||
IM_ASSERT_PARANOID(seq->CountInclude > 0 && seq_next <= seq_incl_end);
|
||||
for (; seq < seq_next; seq++)
|
||||
if (ImStristr(text, text_end, seq->Begin, seq->Begin + seq->Len) == NULL)
|
||||
break;
|
||||
if (seq == seq_next) // All matched
|
||||
return true;
|
||||
seq = seq_next; // Try next
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -4019,6 +4046,7 @@ void ImGui::RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end
|
||||
// Effectively as this is called from widget doing their own coarse clipping it's not very valuable presently. Next time function will take
|
||||
// better advantage of the render function taking size into account for coarse clipping.
|
||||
void ImGui::RenderTextClippedEx(ImDrawList* draw_list, const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_display_end, const ImVec2* text_size_if_known, const ImVec2& align, const ImRect* clip_rect)
|
||||
// DOES NOT CALL LogRenderedText(), unlike RenderTextClipped!!!
|
||||
{
|
||||
// Perform CPU side clipping for single clipped element to avoid using scissor state
|
||||
ImVec2 pos = pos_min;
|
||||
@ -4420,7 +4448,7 @@ ImGuiContext::ImGuiContext(ImFontAtlas* shared_font_atlas)
|
||||
|
||||
NavJustMovedFromFocusScopeId = NavJustMovedToId = NavJustMovedToFocusScopeId = 0;
|
||||
NavJustMovedToKeyMods = ImGuiMod_None;
|
||||
NavJustMovedToIsTabbing = false;
|
||||
NavJustMovedToIsTabbing = NavJustMovedToIsInit = false;
|
||||
NavJustMovedToHasSelectionData = false;
|
||||
|
||||
// All platforms use Ctrl+Tab but Ctrl<>Super are swapped on Mac...
|
||||
@ -4464,6 +4492,7 @@ ImGuiContext::ImGuiContext(ImFontAtlas* shared_font_atlas)
|
||||
MouseCursor = ImGuiMouseCursor_Arrow;
|
||||
MouseStationaryTimer = 0.0f;
|
||||
|
||||
MixedValueLabel = "-";
|
||||
InputTextPasswordFontBackupFlags = ImFontFlags_None;
|
||||
InputTextReactivateId = 0;
|
||||
TempInputId = 0;
|
||||
@ -4572,10 +4601,7 @@ void ImGui::Initialize()
|
||||
LocalizeRegisterEntries(GLocalizationEntriesEnUS, IM_COUNTOF(GLocalizationEntriesEnUS));
|
||||
|
||||
// Setup default ImGuiPlatformIO clipboard/IME handlers.
|
||||
g.PlatformIO.Platform_GetClipboardTextFn = Platform_GetClipboardTextFn_DefaultImpl; // Platform dependent default implementations
|
||||
g.PlatformIO.Platform_SetClipboardTextFn = Platform_SetClipboardTextFn_DefaultImpl;
|
||||
g.PlatformIO.Platform_OpenInShellFn = Platform_OpenInShellFn_DefaultImpl;
|
||||
g.PlatformIO.Platform_SetImeDataFn = Platform_SetImeDataFn_DefaultImpl;
|
||||
InitializeDefaultPlatformHandlers(g.PlatformIO);
|
||||
|
||||
// Setup session starting date
|
||||
#ifndef IMGUI_DISABLE_TIME_FUNCTIONS
|
||||
@ -5424,12 +5450,13 @@ static ImDrawList* GetViewportBgFgDrawList(ImGuiViewportP* viewport, size_t draw
|
||||
}
|
||||
|
||||
// Our ImDrawList system requires that there is always a command
|
||||
if (viewport->BgFgDrawListsLastTimeActive[drawlist_no] != (float)g.Time)
|
||||
if (viewport->BgFgDrawListsLastFrameActive[drawlist_no] != g.FrameCount)
|
||||
{
|
||||
draw_list->_ResetForNewFrame();
|
||||
draw_list->_SetPixelDensity(viewport->FramebufferScale.x);
|
||||
draw_list->PushTexture(g.IO.Fonts->TexRef);
|
||||
draw_list->PushClipRect(viewport->Pos, viewport->Pos + viewport->Size, false);
|
||||
viewport->BgFgDrawListsLastFrameActive[drawlist_no] = g.FrameCount;
|
||||
viewport->BgFgDrawListsLastTimeActive[drawlist_no] = (float)g.Time;
|
||||
}
|
||||
return draw_list;
|
||||
@ -6466,7 +6493,7 @@ void ImGui::Render()
|
||||
for (ImGuiViewportP* viewport : g.Viewports)
|
||||
{
|
||||
InitViewportDrawData(viewport);
|
||||
if (viewport->BgFgDrawLists[0] != NULL && viewport->BgFgDrawListsLastTimeActive[0] == (float)g.Time)
|
||||
if (viewport->BgFgDrawLists[0] != NULL && viewport->BgFgDrawListsLastFrameActive[0] == g.FrameCount)
|
||||
AddDrawListToDrawDataEx(&viewport->DrawDataP, viewport->DrawDataBuilder.Layers[0], GetBackgroundDrawList(viewport));
|
||||
}
|
||||
|
||||
@ -6498,7 +6525,7 @@ void ImGui::Render()
|
||||
FlattenDrawDataIntoSingleLayer(&viewport->DrawDataBuilder);
|
||||
|
||||
// Add foreground ImDrawList (for each active viewport)
|
||||
if (viewport->BgFgDrawLists[1] != NULL && viewport->BgFgDrawListsLastTimeActive[1] == (float)g.Time)
|
||||
if (viewport->BgFgDrawLists[1] != NULL && viewport->BgFgDrawListsLastFrameActive[1] == g.FrameCount)
|
||||
AddDrawListToDrawDataEx(&viewport->DrawDataP, viewport->DrawDataBuilder.Layers[0], GetForegroundDrawList(viewport));
|
||||
|
||||
// We call _PopUnusedDrawCmd() last thing, as RenderDimmedBackgrounds() rely on a valid command being there (especially in docking branch).
|
||||
@ -13474,7 +13501,7 @@ bool ImGui::IsPopupOpenRequestForItem(ImGuiPopupFlags popup_flags, ImGuiID id)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiMouseButton mouse_button = GetMouseButtonFromPopupFlags(popup_flags);
|
||||
if (IsMouseReleased(mouse_button) && IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup))
|
||||
if (IsMouseReleased(mouse_button, id) && IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup))
|
||||
return true;
|
||||
if (g.NavOpenContextMenuItemId == id && (IsItemFocused() || id == g.CurrentWindow->MoveId))
|
||||
return true;
|
||||
@ -13485,7 +13512,7 @@ bool ImGui::IsPopupOpenRequestForWindow(ImGuiPopupFlags popup_flags)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiMouseButton mouse_button = GetMouseButtonFromPopupFlags(popup_flags);
|
||||
if (IsMouseReleased(mouse_button) && IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup))
|
||||
if (IsMouseReleased(mouse_button, ImGuiKeyOwner_NoOwner) && IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup))
|
||||
if (!(popup_flags & ImGuiPopupFlags_NoOpenOverItems) || !IsAnyItemHovered())
|
||||
return true;
|
||||
if (g.NavOpenContextMenuWindowId && g.CurrentWindow->ID)
|
||||
@ -13556,9 +13583,9 @@ bool ImGui::BeginPopupContextVoid(const char* str_id, ImGuiPopupFlags popup_flag
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
if (!str_id)
|
||||
str_id = "void_context";
|
||||
ImGuiID id = window->GetID(str_id);
|
||||
ImGuiID id = window->GetID(str_id); // FIXME: Use a global ID?
|
||||
ImGuiMouseButton mouse_button = GetMouseButtonFromPopupFlags(popup_flags);
|
||||
if (IsMouseReleased(mouse_button) && !IsWindowHovered(ImGuiHoveredFlags_AnyWindow))
|
||||
if (IsMouseReleased(mouse_button, id) && !IsWindowHovered(ImGuiHoveredFlags_AnyWindow))
|
||||
if (GetTopMostPopupModal() == NULL)
|
||||
OpenPopupEx(id, popup_flags);
|
||||
return BeginPopupEx(id, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoSavedSettings);
|
||||
@ -14886,6 +14913,7 @@ void ImGui::NavInitRequestApplyResult()
|
||||
g.NavJustMovedToFocusScopeId = result->FocusScopeId;
|
||||
g.NavJustMovedToKeyMods = 0;
|
||||
g.NavJustMovedToIsTabbing = false;
|
||||
g.NavJustMovedToIsInit = true;
|
||||
g.NavJustMovedToHasSelectionData = (result->ItemFlags & ImGuiItemFlags_HasSelectionUserData) != 0;
|
||||
}
|
||||
|
||||
@ -15153,6 +15181,7 @@ void ImGui::NavMoveRequestApplyResult()
|
||||
g.NavJustMovedToFocusScopeId = result->FocusScopeId;
|
||||
g.NavJustMovedToKeyMods = g.NavMoveKeyMods;
|
||||
g.NavJustMovedToIsTabbing = (g.NavMoveFlags & ImGuiNavMoveFlags_IsTabbing) != 0;
|
||||
g.NavJustMovedToIsInit = false;
|
||||
g.NavJustMovedToHasSelectionData = (result->ItemFlags & ImGuiItemFlags_HasSelectionUserData) != 0;
|
||||
//IMGUI_DEBUG_LOG_NAV("[nav] NavJustMovedFromFocusScopeId = 0x%08X, NavJustMovedToFocusScopeId = 0x%08X\n", g.NavJustMovedFromFocusScopeId, g.NavJustMovedToFocusScopeId);
|
||||
}
|
||||
@ -16079,17 +16108,9 @@ const ImGuiPayload* ImGui::AcceptDragDropPayload(const char* type, ImGuiDragDrop
|
||||
flags |= (g.DragDropSourceFlags & ImGuiDragDropFlags_AcceptNoDrawDefaultRect); // Source can also inhibit the preview (useful for external sources that live for 1 frame)
|
||||
const bool draw_target_rect = payload.Preview && !(flags & ImGuiDragDropFlags_AcceptNoDrawDefaultRect);
|
||||
if (draw_target_rect && g.DragDropTargetFullViewport != 0)
|
||||
{
|
||||
ImGuiViewport* viewport = FindViewportByID(g.DragDropTargetFullViewport);
|
||||
IM_ASSERT(viewport != NULL);
|
||||
ImRect bb = g.DragDropTargetRect;
|
||||
bb.Expand(-3.5f);
|
||||
RenderDragDropTargetRectEx(GetForegroundDrawList(viewport), bb, g.Style.DragDropTargetRounding);
|
||||
}
|
||||
RenderDragDropTargetRectForViewport(g.DragDropTargetFullViewport, g.DragDropTargetRect);
|
||||
else if (draw_target_rect)
|
||||
{
|
||||
RenderDragDropTargetRectForItem(r);
|
||||
}
|
||||
|
||||
g.DragDropAcceptFrameCount = g.FrameCount;
|
||||
if ((g.DragDropSourceFlags & ImGuiDragDropFlags_SourceExtern) && g.DragDropMouseButton == -1)
|
||||
@ -16120,6 +16141,16 @@ void ImGui::RenderDragDropTargetRectForItem(const ImRect& bb)
|
||||
window->DrawList->PopClipRect();
|
||||
}
|
||||
|
||||
void ImGui::RenderDragDropTargetRectForViewport(ImGuiID viewport_id, const ImRect& bb)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiViewport* viewport = FindViewportByID(viewport_id);
|
||||
IM_ASSERT(viewport != NULL);
|
||||
ImRect bb_padded = bb;
|
||||
bb_padded.Expand(-g.Style.DragDropTargetPadding);
|
||||
RenderDragDropTargetRectEx(GetForegroundDrawList(viewport), bb_padded, g.Style.DragDropTargetRounding);
|
||||
}
|
||||
|
||||
void ImGui::RenderDragDropTargetRectEx(ImDrawList* draw_list, const ImRect& bb, float rounding)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
@ -16889,6 +16920,7 @@ void ImGuiPlatformIO::ClearPlatformHandlers()
|
||||
Platform_OnChangedViewport = NULL;
|
||||
Platform_GetWindowWorkAreaInsets = NULL;
|
||||
Platform_CreateVkSurface = NULL;
|
||||
InitializeDefaultPlatformHandlers(*this); // Prevents losing the functionality provided by Platform_*_DefaultImpl on backend re-creation.
|
||||
}
|
||||
|
||||
void ImGuiPlatformIO::ClearRendererHandlers()
|
||||
@ -16898,7 +16930,7 @@ void ImGuiPlatformIO::ClearRendererHandlers()
|
||||
Renderer_CreateWindow = Renderer_DestroyWindow = NULL;
|
||||
Renderer_SetWindowSize = NULL;
|
||||
Renderer_RenderWindow = Renderer_SwapBuffers = NULL;
|
||||
DrawCallback_ResetRenderState = DrawCallback_SetSamplerLinear = DrawCallback_SetSamplerNearest = NULL;
|
||||
DrawCallback_ResetRenderState = DrawCallback_SetSamplerLinear = DrawCallback_SetSamplerNearest = DrawCallback_SetSamplerFromTex = NULL;
|
||||
}
|
||||
|
||||
ImGuiViewport* ImGui::GetMainViewport()
|
||||
@ -21994,7 +22026,7 @@ static void Platform_SetClipboardTextFn_DefaultImpl(ImGuiContext*, const char* t
|
||||
::CloseClipboard();
|
||||
}
|
||||
|
||||
#elif defined(__APPLE__) && TARGET_OS_OSX && defined(IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS)
|
||||
#elif defined(__APPLE__) && defined(TARGET_OS_OSX) && TARGET_OS_OSX && defined(IMGUI_ENABLE_OSX_DEFAULT_CLIPBOARD_FUNCTIONS)
|
||||
|
||||
#include <Carbon/Carbon.h> // Use old API to avoid need for separate .mm file
|
||||
static PasteboardRef main_clipboard = 0;
|
||||
@ -22166,6 +22198,15 @@ static void Platform_SetImeDataFn_DefaultImpl(ImGuiContext*, ImGuiViewport*, ImG
|
||||
|
||||
#endif // Default IME handlers
|
||||
|
||||
// Setup default ImGuiPlatformIO clipboard/IME handlers
|
||||
static void InitializeDefaultPlatformHandlers(ImGuiPlatformIO& platform_io)
|
||||
{
|
||||
platform_io.Platform_GetClipboardTextFn = Platform_GetClipboardTextFn_DefaultImpl;
|
||||
platform_io.Platform_SetClipboardTextFn = Platform_SetClipboardTextFn_DefaultImpl;
|
||||
platform_io.Platform_OpenInShellFn = Platform_OpenInShellFn_DefaultImpl;
|
||||
platform_io.Platform_SetImeDataFn = Platform_SetImeDataFn_DefaultImpl;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] METRICS/DEBUGGER WINDOW
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -22584,7 +22625,7 @@ void ImGui::DebugNodeTexture(ImTextureData* tex, int int_id, const ImFontAtlasRe
|
||||
Checkbox("Show used rect", &cfg->ShowTextureUsedRect);
|
||||
PushStyleVar(ImGuiStyleVar_ImageBorderSize, ImMax(1.0f, g.Style.ImageBorderSize));
|
||||
ImVec2 p = GetCursorScreenPos();
|
||||
if (tex->WantDestroyNextFrame)
|
||||
if (tex->Status == ImTextureStatus_WantDestroy || tex->Status == ImTextureStatus_Destroyed)
|
||||
Dummy(ImVec2((float)tex->Width, (float)tex->Height));
|
||||
else
|
||||
ImageWithBg(tex->GetTexRef(), ImVec2((float)tex->Width, (float)tex->Height), ImVec2(0.0f, 0.0f), ImVec2(1.0f, 1.0f), ImVec4(0.0f, 0.0f, 0.0f, 1.0f));
|
||||
|
||||
155
imgui.h
155
imgui.h
@ -30,7 +30,7 @@
|
||||
// Library Version
|
||||
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345')
|
||||
#define IMGUI_VERSION "1.93.0 WIP"
|
||||
#define IMGUI_VERSION_NUM 19294
|
||||
#define IMGUI_VERSION_NUM 19297
|
||||
#define IMGUI_HAS_TABLE // Added BeginTable() - from IMGUI_VERSION_NUM >= 18000
|
||||
#define IMGUI_HAS_TEXTURES // Added ImGuiBackendFlags_RendererHasTextures - from IMGUI_VERSION_NUM >= 19198
|
||||
#define IMGUI_HAS_VIEWPORT // In 'docking' WIP branch.
|
||||
@ -130,6 +130,16 @@ Index of this file:
|
||||
#define IM_MSVC_RUNTIME_CHECKS_RESTORE
|
||||
#endif
|
||||
|
||||
// Alternative to using a .natstepfilter file or other scripts in misc/debuggers/ to skip debug-stepping selected trivial functions.
|
||||
// If you get a compiler error or warning related to use, please report it to us!
|
||||
#if (defined(__clang__) && (__clang_major__ >= 7)) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)))
|
||||
#define IM_NODEBUGSTEP [[gnu::artificial]]
|
||||
#elif defined(_MSC_VER) && (_MSC_VER >= 1915)
|
||||
#define IM_NODEBUGSTEP __declspec(non_user_code)
|
||||
#else
|
||||
#define IM_NODEBUGSTEP
|
||||
#endif
|
||||
|
||||
// Warnings
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (push)
|
||||
@ -299,11 +309,11 @@ typedef void (*ImGuiMemFreeFunc)(void* ptr, void* user_data);
|
||||
IM_MSVC_RUNTIME_CHECKS_OFF
|
||||
struct ImVec2
|
||||
{
|
||||
float x, y;
|
||||
constexpr ImVec2() : x(0.0f), y(0.0f) { }
|
||||
constexpr ImVec2(float _x, float _y) : x(_x), y(_y) { }
|
||||
float& operator[] (size_t idx) { IM_ASSERT(idx == 0 || idx == 1); return ((float*)(void*)(char*)this)[idx]; } // We very rarely use this [] operator, so the assert overhead is fine.
|
||||
float operator[] (size_t idx) const { IM_ASSERT(idx == 0 || idx == 1); return ((const float*)(const void*)(const char*)this)[idx]; }
|
||||
float x, y;
|
||||
IM_NODEBUGSTEP constexpr inline ImVec2() : x(0.0f), y(0.0f) { }
|
||||
IM_NODEBUGSTEP constexpr inline ImVec2(float _x, float _y) : x(_x), y(_y) { }
|
||||
float& operator[] (size_t idx) { IM_ASSERT(idx == 0 || idx == 1); return ((float*)(void*)(char*)this)[idx]; } // We very rarely use this [] operator, so the assert overhead is fine.
|
||||
float operator[] (size_t idx) const { IM_ASSERT(idx == 0 || idx == 1); return ((const float*)(const void*)(const char*)this)[idx]; }
|
||||
#ifdef IM_VEC2_CLASS_EXTRA
|
||||
IM_VEC2_CLASS_EXTRA // Define additional constructors and implicit cast operators in imconfig.h to convert back and forth between your math types and ImVec2.
|
||||
#endif
|
||||
@ -312,9 +322,9 @@ struct ImVec2
|
||||
// ImVec4: 4D vector used to store clipping rectangles, colors etc. [Compile-time configurable type]
|
||||
struct ImVec4
|
||||
{
|
||||
float x, y, z, w;
|
||||
constexpr ImVec4() : x(0.0f), y(0.0f), z(0.0f), w(0.0f) { }
|
||||
constexpr ImVec4(float _x, float _y, float _z, float _w) : x(_x), y(_y), z(_z), w(_w) { }
|
||||
float x, y, z, w;
|
||||
IM_NODEBUGSTEP constexpr inline ImVec4() : x(0.0f), y(0.0f), z(0.0f), w(0.0f) { }
|
||||
IM_NODEBUGSTEP constexpr inline ImVec4(float _x, float _y, float _z, float _w) : x(_x), y(_y), z(_z), w(_w) { }
|
||||
#ifdef IM_VEC4_CLASS_EXTRA
|
||||
IM_VEC4_CLASS_EXTRA // Define additional constructors and implicit cast operators in imconfig.h to convert back and forth between your math types and ImVec4.
|
||||
#endif
|
||||
@ -1308,6 +1318,17 @@ enum ImGuiItemFlags_
|
||||
ImGuiItemFlags_LiveEditOnInputText = 1 << 7, // true // InputText: apply keyboard edits to backing value while typing. Otherwise, edits are applied when validating, tabbing out or losing focus.
|
||||
ImGuiItemFlags_LiveEditOnInputScalar = 1 << 8, // false // DragXXX, SliderXXX, InputScalar: apply keyboard edits to backing value while typing. Otherwise, edits are applied when validating, tabbing out or losing focus.
|
||||
ImGuiItemFlags_LiveEditOnInput = ImGuiItemFlags_LiveEditOnInputText | ImGuiItemFlags_LiveEditOnInputScalar,
|
||||
|
||||
//---------------------------------------------------------------------------------
|
||||
// [BETA] MixedValue mode used to represent a mixed/indeterminate state, typically for multi-selection.
|
||||
// - Replace value display with "-" or a custom label.
|
||||
// - Enter key validation apply an edit and return true even if value hasn't changed (in order to apply to all).
|
||||
// - Supported by selected widgets: Checkbox, RadioButton, Sliders, Drags, Inputs, Combo.
|
||||
// - Note: InputText-side Undo cannot be reliably combined with MixedValue + LiveEdit On:
|
||||
// - Both the initial edit and subsequent undo/revert will typically make your app code write to all backing objects.
|
||||
// - If you use MixedMode and the simplest solution is to ensure LiveEdit is off but widgets where this applies.
|
||||
//---------------------------------------------------------------------------------
|
||||
ImGuiItemFlags_MixedValue = 1 << 9, // false // [BETA] Represent a mixed/indeterminate value. Replace value label with "-" and apply edits on validation.
|
||||
};
|
||||
|
||||
// Flags for ImGui::InputText()
|
||||
@ -2345,13 +2366,13 @@ struct ImVector
|
||||
inline int size_in_bytes() const { return Size * (int)sizeof(T); }
|
||||
inline int max_size() const { return 0x7FFFFFFF / (int)sizeof(T); }
|
||||
inline int capacity() const { return Capacity; }
|
||||
inline T& operator[](int i) { IM_ASSERT(i >= 0 && i < Size); return Data[i]; }
|
||||
inline const T& operator[](int i) const { IM_ASSERT(i >= 0 && i < Size); return Data[i]; }
|
||||
IM_NODEBUGSTEP inline T& operator[](int i) { IM_ASSERT(i >= 0 && i < Size); return Data[i]; }
|
||||
IM_NODEBUGSTEP inline const T& operator[](int i) const { IM_ASSERT(i >= 0 && i < Size); return Data[i]; }
|
||||
|
||||
inline T* begin() { return Data; }
|
||||
inline const T* begin() const { return Data; }
|
||||
inline T* end() { return Data + Size; }
|
||||
inline const T* end() const { return Data + Size; }
|
||||
IM_NODEBUGSTEP inline T* begin() { return Data; }
|
||||
IM_NODEBUGSTEP inline const T* begin() const { return Data; }
|
||||
IM_NODEBUGSTEP inline T* end() { return Data + Size; }
|
||||
IM_NODEBUGSTEP inline const T* end() const { return Data + Size; }
|
||||
inline T& front() { IM_ASSERT(Size > 0); return Data[0]; }
|
||||
inline const T& front() const { IM_ASSERT(Size > 0); return Data[0]; }
|
||||
inline T& back() { IM_ASSERT(Size > 0); return Data[Size - 1]; }
|
||||
@ -2462,7 +2483,7 @@ struct ImGuiStyle
|
||||
float DockingSeparatorSize; // Thickness of resizing border between docked windows
|
||||
float MouseCursorScale; // Scale software rendered mouse cursor (when io.MouseDrawCursor is enabled). We apply per-monitor DPI scaling over this scale. May be removed later.
|
||||
|
||||
// Rendering & Tesselation
|
||||
// Rendering & Tessellation
|
||||
bool AntiAliasedLines; // Enable anti-aliased lines/borders. Disable if you are really tight on CPU/GPU. Latched at the beginning of the frame (copied to ImDrawList).
|
||||
bool AntiAliasedLinesUseTex; // Enable anti-aliased lines/borders using textures where possible. Require backend to render with bilinear filtering (NOT point/nearest filtering). Latched at the beginning of the frame (copied to ImDrawList).
|
||||
bool AntiAliasedFill; // Enable anti-aliased edges around filled shapes (rounded rectangles, circles, etc.). Disable if you are really tight on CPU/GPU. Latched at the beginning of the frame (copied to ImDrawList).
|
||||
@ -2898,30 +2919,27 @@ struct ImGuiOnceUponAFrame
|
||||
operator bool() const { int current_frame = ImGui::GetFrameCount(); if (RefFrame == current_frame) return false; RefFrame = current_frame; return true; }
|
||||
};
|
||||
|
||||
// Helper: Parse and apply text filters. In format "aaaaa[,bbbb][,ccccc]"
|
||||
// Helper: Parse and apply text filters e.g. 'aaa bbb' (all), 'aaa,bbb' (any), '-aaa' (exclude), '"Hello, world"' (exact sequence)
|
||||
struct ImGuiTextFilterItem;
|
||||
struct ImGuiTextFilter
|
||||
{
|
||||
IMGUI_API ImGuiTextFilter(const char* default_filter = "");
|
||||
IMGUI_API bool Draw(const char* label = "Filter (inc,-exc)", float width = 0.0f); // Helper calling InputText+Build
|
||||
IMGUI_API bool PassFilter(const char* text, const char* text_end = NULL) const;
|
||||
IMGUI_API void Build();
|
||||
void Clear() { InputBuf[0] = 0; Build(); }
|
||||
bool IsActive() const { return !Filters.empty(); }
|
||||
IMGUI_API void Build(); // Update internal data when filter changes
|
||||
inline void Clear() { InputBuf[0] = 0; Build(); } // Clear filter
|
||||
inline bool IsActive() const { return _Items.Size != 0; } // Useful if you need e.g. an alternative code-path when there are no filters
|
||||
|
||||
// [Internal]
|
||||
struct ImGuiTextRange
|
||||
{
|
||||
const char* b;
|
||||
const char* e;
|
||||
// Helper to call InputText() + Build() when buffer is changed.
|
||||
IMGUI_API bool Draw(const char* label = "Filter");
|
||||
IMGUI_API bool DrawWithHint(const char* label = "Filter", const char* hint = "incl -excl");
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
inline bool Draw(const char* label, float width) { if (width != 0.0f) ImGui::SetNextItemWidth(width); return Draw(label); }
|
||||
#endif
|
||||
|
||||
ImGuiTextRange() { b = e = NULL; }
|
||||
ImGuiTextRange(const char* _b, const char* _e) { b = _b; e = _e; }
|
||||
bool empty() const { return b == e; }
|
||||
IMGUI_API void split(char separator, ImVector<ImGuiTextRange>* out) const;
|
||||
};
|
||||
char InputBuf[256];
|
||||
ImVector<ImGuiTextRange>Filters;
|
||||
int CountGrep;
|
||||
// Members
|
||||
char InputBuf[256]; // User input buffer
|
||||
int _CountExclude; // [Internal] >= 0 count of leading exclude
|
||||
ImVector<ImGuiTextFilterItem> _Items; // [Internal] Pre-parsed, trimmed, reordered items
|
||||
};
|
||||
|
||||
// Helper: Growable text buffer for logging/accumulating text
|
||||
@ -3074,41 +3092,41 @@ struct ImGuiListClipper
|
||||
#define IMGUI_DEFINE_MATH_OPERATORS_IMPLEMENTED
|
||||
IM_MSVC_RUNTIME_CHECKS_OFF
|
||||
// ImVec2 operators
|
||||
inline ImVec2 operator*(const ImVec2& lhs, const float rhs) { return ImVec2(lhs.x * rhs, lhs.y * rhs); }
|
||||
inline ImVec2 operator*(const float lhs, const ImVec2& rhs) { return ImVec2(lhs * rhs.x, lhs * rhs.y); }
|
||||
inline ImVec2 operator/(const ImVec2& lhs, const float rhs) { return ImVec2(lhs.x / rhs, lhs.y / rhs); }
|
||||
inline ImVec2 operator+(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x + rhs.x, lhs.y + rhs.y); }
|
||||
inline ImVec2 operator-(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x - rhs.x, lhs.y - rhs.y); }
|
||||
inline ImVec2 operator*(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x * rhs.x, lhs.y * rhs.y); }
|
||||
inline ImVec2 operator/(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x / rhs.x, lhs.y / rhs.y); }
|
||||
inline ImVec2 operator+(const ImVec2& lhs) { return lhs; }
|
||||
inline ImVec2 operator-(const ImVec2& lhs) { return ImVec2(-lhs.x, -lhs.y); }
|
||||
inline ImVec2& operator*=(ImVec2& lhs, const float rhs) { lhs.x *= rhs; lhs.y *= rhs; return lhs; }
|
||||
inline ImVec2& operator/=(ImVec2& lhs, const float rhs) { lhs.x /= rhs; lhs.y /= rhs; return lhs; }
|
||||
inline ImVec2& operator+=(ImVec2& lhs, const ImVec2& rhs) { lhs.x += rhs.x; lhs.y += rhs.y; return lhs; }
|
||||
inline ImVec2& operator-=(ImVec2& lhs, const ImVec2& rhs) { lhs.x -= rhs.x; lhs.y -= rhs.y; return lhs; }
|
||||
inline ImVec2& operator*=(ImVec2& lhs, const ImVec2& rhs) { lhs.x *= rhs.x; lhs.y *= rhs.y; return lhs; }
|
||||
inline ImVec2& operator/=(ImVec2& lhs, const ImVec2& rhs) { lhs.x /= rhs.x; lhs.y /= rhs.y; return lhs; }
|
||||
inline bool operator==(const ImVec2& lhs, const ImVec2& rhs) { return lhs.x == rhs.x && lhs.y == rhs.y; }
|
||||
inline bool operator!=(const ImVec2& lhs, const ImVec2& rhs) { return lhs.x != rhs.x || lhs.y != rhs.y; }
|
||||
IM_NODEBUGSTEP inline ImVec2 operator*(const ImVec2& lhs, const float rhs) { return ImVec2(lhs.x * rhs, lhs.y * rhs); }
|
||||
IM_NODEBUGSTEP inline ImVec2 operator*(const float lhs, const ImVec2& rhs) { return ImVec2(lhs * rhs.x, lhs * rhs.y); }
|
||||
IM_NODEBUGSTEP inline ImVec2 operator/(const ImVec2& lhs, const float rhs) { return ImVec2(lhs.x / rhs, lhs.y / rhs); }
|
||||
IM_NODEBUGSTEP inline ImVec2 operator+(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x + rhs.x, lhs.y + rhs.y); }
|
||||
IM_NODEBUGSTEP inline ImVec2 operator-(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x - rhs.x, lhs.y - rhs.y); }
|
||||
IM_NODEBUGSTEP inline ImVec2 operator*(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x * rhs.x, lhs.y * rhs.y); }
|
||||
IM_NODEBUGSTEP inline ImVec2 operator/(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x / rhs.x, lhs.y / rhs.y); }
|
||||
IM_NODEBUGSTEP inline ImVec2 operator+(const ImVec2& lhs) { return lhs; }
|
||||
IM_NODEBUGSTEP inline ImVec2 operator-(const ImVec2& lhs) { return ImVec2(-lhs.x, -lhs.y); }
|
||||
IM_NODEBUGSTEP inline ImVec2& operator*=(ImVec2& lhs, const float rhs) { lhs.x *= rhs; lhs.y *= rhs; return lhs; }
|
||||
IM_NODEBUGSTEP inline ImVec2& operator/=(ImVec2& lhs, const float rhs) { lhs.x /= rhs; lhs.y /= rhs; return lhs; }
|
||||
IM_NODEBUGSTEP inline ImVec2& operator+=(ImVec2& lhs, const ImVec2& rhs) { lhs.x += rhs.x; lhs.y += rhs.y; return lhs; }
|
||||
IM_NODEBUGSTEP inline ImVec2& operator-=(ImVec2& lhs, const ImVec2& rhs) { lhs.x -= rhs.x; lhs.y -= rhs.y; return lhs; }
|
||||
IM_NODEBUGSTEP inline ImVec2& operator*=(ImVec2& lhs, const ImVec2& rhs) { lhs.x *= rhs.x; lhs.y *= rhs.y; return lhs; }
|
||||
IM_NODEBUGSTEP inline ImVec2& operator/=(ImVec2& lhs, const ImVec2& rhs) { lhs.x /= rhs.x; lhs.y /= rhs.y; return lhs; }
|
||||
IM_NODEBUGSTEP inline bool operator==(const ImVec2& lhs, const ImVec2& rhs) { return lhs.x == rhs.x && lhs.y == rhs.y; }
|
||||
IM_NODEBUGSTEP inline bool operator!=(const ImVec2& lhs, const ImVec2& rhs) { return lhs.x != rhs.x || lhs.y != rhs.y; }
|
||||
// ImVec4 operators
|
||||
inline ImVec4 operator*(const ImVec4& lhs, const float rhs) { return ImVec4(lhs.x * rhs, lhs.y * rhs, lhs.z * rhs, lhs.w * rhs); }
|
||||
inline ImVec4 operator*(const float lhs, const ImVec4& rhs) { return ImVec4(lhs * rhs.x, lhs * rhs.y, lhs * rhs.z, lhs * rhs.w); }
|
||||
inline ImVec4 operator/(const ImVec4& lhs, const float rhs) { return ImVec4(lhs.x / rhs, lhs.y / rhs, lhs.z / rhs, lhs.w / rhs); }
|
||||
inline ImVec4 operator+(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z, lhs.w + rhs.w); }
|
||||
inline ImVec4 operator-(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z, lhs.w - rhs.w); }
|
||||
inline ImVec4 operator*(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x * rhs.x, lhs.y * rhs.y, lhs.z * rhs.z, lhs.w * rhs.w); }
|
||||
inline ImVec4 operator/(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x / rhs.x, lhs.y / rhs.y, lhs.z / rhs.z, lhs.w / rhs.w); }
|
||||
inline ImVec4 operator+(const ImVec4& lhs) { return lhs; }
|
||||
inline ImVec4 operator-(const ImVec4& lhs) { return ImVec4(-lhs.x, -lhs.y, -lhs.z, -lhs.w); }
|
||||
inline ImVec4& operator*=(ImVec4& lhs, const float rhs) { lhs.x *= rhs; lhs.y *= rhs; lhs.z *= rhs; lhs.w *= rhs; return lhs; }
|
||||
inline ImVec4& operator/=(ImVec4& lhs, const float rhs) { lhs.x /= rhs; lhs.y /= rhs; lhs.z /= rhs; lhs.w /= rhs; return lhs; }
|
||||
inline ImVec4& operator+=(ImVec4& lhs, const ImVec4& rhs) { lhs.x += rhs.x; lhs.y += rhs.y; lhs.z += rhs.z; lhs.w += rhs.w; return lhs; }
|
||||
inline ImVec4& operator-=(ImVec4& lhs, const ImVec4& rhs) { lhs.x -= rhs.x; lhs.y -= rhs.y; lhs.z -= rhs.z; lhs.w -= rhs.w; return lhs; }
|
||||
inline ImVec4& operator*=(ImVec4& lhs, const ImVec4& rhs) { lhs.x *= rhs.x; lhs.y *= rhs.y; lhs.z *= rhs.z; lhs.w *= rhs.w; return lhs; }
|
||||
inline ImVec4& operator/=(ImVec4& lhs, const ImVec4& rhs) { lhs.x /= rhs.x; lhs.y /= rhs.y; lhs.z /= rhs.z; lhs.w /= rhs.w; return lhs; }
|
||||
inline bool operator==(const ImVec4& lhs, const ImVec4& rhs) { return lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z && lhs.w == rhs.w; }
|
||||
inline bool operator!=(const ImVec4& lhs, const ImVec4& rhs) { return lhs.x != rhs.x || lhs.y != rhs.y || lhs.z != rhs.z || lhs.w != rhs.w; }
|
||||
IM_NODEBUGSTEP inline ImVec4 operator*(const ImVec4& lhs, const float rhs) { return ImVec4(lhs.x * rhs, lhs.y * rhs, lhs.z * rhs, lhs.w * rhs); }
|
||||
IM_NODEBUGSTEP inline ImVec4 operator*(const float lhs, const ImVec4& rhs) { return ImVec4(lhs * rhs.x, lhs * rhs.y, lhs * rhs.z, lhs * rhs.w); }
|
||||
IM_NODEBUGSTEP inline ImVec4 operator/(const ImVec4& lhs, const float rhs) { return ImVec4(lhs.x / rhs, lhs.y / rhs, lhs.z / rhs, lhs.w / rhs); }
|
||||
IM_NODEBUGSTEP inline ImVec4 operator+(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z, lhs.w + rhs.w); }
|
||||
IM_NODEBUGSTEP inline ImVec4 operator-(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z, lhs.w - rhs.w); }
|
||||
IM_NODEBUGSTEP inline ImVec4 operator*(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x * rhs.x, lhs.y * rhs.y, lhs.z * rhs.z, lhs.w * rhs.w); }
|
||||
IM_NODEBUGSTEP inline ImVec4 operator/(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x / rhs.x, lhs.y / rhs.y, lhs.z / rhs.z, lhs.w / rhs.w); }
|
||||
IM_NODEBUGSTEP inline ImVec4 operator+(const ImVec4& lhs) { return lhs; }
|
||||
IM_NODEBUGSTEP inline ImVec4 operator-(const ImVec4& lhs) { return ImVec4(-lhs.x, -lhs.y, -lhs.z, -lhs.w); }
|
||||
IM_NODEBUGSTEP inline ImVec4& operator*=(ImVec4& lhs, const float rhs) { lhs.x *= rhs; lhs.y *= rhs; lhs.z *= rhs; lhs.w *= rhs; return lhs; }
|
||||
IM_NODEBUGSTEP inline ImVec4& operator/=(ImVec4& lhs, const float rhs) { lhs.x /= rhs; lhs.y /= rhs; lhs.z /= rhs; lhs.w /= rhs; return lhs; }
|
||||
IM_NODEBUGSTEP inline ImVec4& operator+=(ImVec4& lhs, const ImVec4& rhs) { lhs.x += rhs.x; lhs.y += rhs.y; lhs.z += rhs.z; lhs.w += rhs.w; return lhs; }
|
||||
IM_NODEBUGSTEP inline ImVec4& operator-=(ImVec4& lhs, const ImVec4& rhs) { lhs.x -= rhs.x; lhs.y -= rhs.y; lhs.z -= rhs.z; lhs.w -= rhs.w; return lhs; }
|
||||
IM_NODEBUGSTEP inline ImVec4& operator*=(ImVec4& lhs, const ImVec4& rhs) { lhs.x *= rhs.x; lhs.y *= rhs.y; lhs.z *= rhs.z; lhs.w *= rhs.w; return lhs; }
|
||||
IM_NODEBUGSTEP inline ImVec4& operator/=(ImVec4& lhs, const ImVec4& rhs) { lhs.x /= rhs.x; lhs.y /= rhs.y; lhs.z /= rhs.z; lhs.w /= rhs.w; return lhs; }
|
||||
IM_NODEBUGSTEP inline bool operator==(const ImVec4& lhs, const ImVec4& rhs) { return lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z && lhs.w == rhs.w; }
|
||||
IM_NODEBUGSTEP inline bool operator!=(const ImVec4& lhs, const ImVec4& rhs) { return lhs.x != rhs.x || lhs.y != rhs.y || lhs.z != rhs.z || lhs.w != rhs.w; }
|
||||
IM_MSVC_RUNTIME_CHECKS_RESTORE
|
||||
#endif
|
||||
|
||||
@ -4303,6 +4321,7 @@ struct ImGuiPlatformIO
|
||||
ImDrawCallback DrawCallback_ResetRenderState; // Request to reset the graphics/render state.
|
||||
ImDrawCallback DrawCallback_SetSamplerLinear; // Request backend to set texture sampling to Linear.
|
||||
ImDrawCallback DrawCallback_SetSamplerNearest; // Request backend to set texture sampling to Nearest/Point.
|
||||
ImDrawCallback DrawCallback_SetSamplerFromTex; // Request backend to use sampler associated to texture - only available in some backends: OpenGL2/3 and SDLRenderer3.
|
||||
//ImDrawCallback DrawCallback_SetSamplerCustom; // Request backend to set texture sampling using Backend Specific data.
|
||||
|
||||
//------------------------------------------------------------------
|
||||
|
||||
128
imgui_demo.cpp
128
imgui_demo.cpp
@ -87,6 +87,7 @@ Index of this file:
|
||||
// [SECTION] DemoWindowWidgetsImages()
|
||||
// [SECTION] DemoWindowWidgetsListBoxes()
|
||||
// [SECTION] DemoWindowWidgetsLiveEdit()
|
||||
// [SECTION] DemoWindowWidgetsMixedValues()
|
||||
// [SECTION] DemoWindowWidgetsMultiComponents()
|
||||
// [SECTION] DemoWindowWidgetsPlotting()
|
||||
// [SECTION] DemoWindowWidgetsProgressBars()
|
||||
@ -1522,7 +1523,8 @@ static void DemoWindowWidgetsComboBoxes()
|
||||
filter.Clear();
|
||||
}
|
||||
ImGui::SetNextItemShortcut(ImGuiMod_Ctrl | ImGuiKey_F);
|
||||
filter.Draw("##Filter", -FLT_MIN);
|
||||
ImGui::SetNextItemWidth(-FLT_MIN);
|
||||
filter.DrawWithHint("##Filter", "Filter (incl -excl)");
|
||||
|
||||
for (int n = 0; n < IM_COUNTOF(items); n++)
|
||||
{
|
||||
@ -2091,7 +2093,7 @@ static void DemoWindowWidgetsLiveEdit(ImGuiDemoWindowData* demo_data)
|
||||
{
|
||||
if (ImGui::TreeNode("Live Edit Flags"))
|
||||
{
|
||||
IMGUI_DEMO_MARKER("Widgets/Live Edit Flgs");
|
||||
IMGUI_DEMO_MARKER("Widgets/Live Edit Flags");
|
||||
|
||||
ImGui::TextWrapped("Select whether to apply keyboard edits to backing variables _while_ typing.");
|
||||
|
||||
@ -2121,6 +2123,65 @@ static void DemoWindowWidgetsLiveEdit(ImGuiDemoWindowData* demo_data)
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] DemoWindowWidgetsMixedValues()
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static void DemoWindowWidgetsMixedValues()
|
||||
{
|
||||
if (ImGui::TreeNode("Mixed Values"))
|
||||
{
|
||||
// This is designed for advanced property editors which are generally reusable and data-driven.
|
||||
HelpMarker("Using ImGuiItemFlags_MixedValue.");
|
||||
|
||||
static bool use_liveedit = false;
|
||||
static float items[3] = { 12.0f, 0.0f, 0.0f };
|
||||
float* item_ref = &items[0];
|
||||
ImGui::Checkbox("ImGuiItemFlags_LiveEditOnInput", &use_liveedit);
|
||||
|
||||
ImGui::SeparatorText("Scalar/Text Widgets");
|
||||
const bool is_mixed = memcmp(&items[0], &items[1], sizeof(float)) != 0 || memcmp(&items[0], &items[2], sizeof(float)) != 0;
|
||||
|
||||
// Demonstrate Drags, Sliders, Inputs
|
||||
ImGui::PushItemFlag(ImGuiItemFlags_LiveEditOnInput, use_liveedit);
|
||||
ImGui::PushItemFlag(ImGuiItemFlags_MixedValue, is_mixed);
|
||||
bool edited = false;
|
||||
edited |= ImGui::DragFloat("DragFloat", item_ref);
|
||||
edited |= ImGui::SliderFloat("SliderFloat", item_ref, 0.0f, 100.0f);
|
||||
edited |= ImGui::InputFloat("InputFloat", item_ref, 1.0f);
|
||||
if (edited)
|
||||
for (float& item : items)
|
||||
if (&item != item_ref)
|
||||
item = *item_ref;
|
||||
ImGui::PopItemFlag();
|
||||
|
||||
ImGui::Text("Underlying data:");
|
||||
ImGui::InputFloat("item 0 (ref)", &items[0]);
|
||||
ImGui::InputFloat("item 1", &items[1]);
|
||||
ImGui::InputFloat("item 2", &items[2]);
|
||||
ImGui::PopItemFlag();
|
||||
|
||||
// Demonstrate Checkbox(), RadioButton(), Combo(), ColorEdit4()
|
||||
ImGui::SeparatorText("Others Widgets");
|
||||
ImGui::Text("(note: edits are not applied in this demo)"); // <-- Would need more state tracking.
|
||||
bool b_on = true, b_off = false;
|
||||
ImGui::Checkbox("Checkbox On", &b_on);
|
||||
ImGui::Checkbox("Checkbox Off", &b_off);
|
||||
ImGui::PushItemFlag(ImGuiItemFlags_MixedValue, true);
|
||||
ImGui::Checkbox("Checkbox Mixed", &b_off);
|
||||
ImGui::RadioButton("RadioButton Mixed", true);
|
||||
ImGui::SameLine();
|
||||
ImGui::RadioButton("RadioButton Mixed##2", true); // Showing 2 radio buttons makes the example more clear
|
||||
int combo_idx = 0;
|
||||
ImGui::Combo("Combo", &combo_idx, "One\0Two\0Three\0");
|
||||
ImVec4 color(0.5f, 0.5f, 0.5f, 0.5f);
|
||||
ImGui::ColorEdit4("ColorEdit4", &color.x);
|
||||
ImGui::PopItemFlag();
|
||||
|
||||
ImGui::TreePop();
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [SECTION] DemoWindowWidgetsMultiComponents()
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -2301,12 +2362,14 @@ static void DemoWindowWidgetsQueryingStatuses()
|
||||
};
|
||||
static int item_type = 4;
|
||||
static bool item_disabled = false;
|
||||
static bool item_mixedvalue = false;
|
||||
static bool liveedit_flags_override = false;
|
||||
static ImGuiItemFlags liveedit_flags = 0;
|
||||
ImGui::Combo("Item Type", &item_type, item_names, IM_COUNTOF(item_names), IM_COUNTOF(item_names));
|
||||
ImGui::SameLine();
|
||||
HelpMarker("Testing how various types of items are interacting with the IsItemXXX functions. Note that the bool return value of most ImGui function is generally equivalent to calling ImGui::IsItemHovered().");
|
||||
ImGui::Checkbox("Item Disabled", &item_disabled);
|
||||
ImGui::Checkbox("Item MixedValue", &item_mixedvalue);
|
||||
ImGui::Checkbox("Override LiveEdit:", &liveedit_flags_override);
|
||||
ImGui::SameLine();
|
||||
if (!liveedit_flags_override)
|
||||
@ -2331,6 +2394,8 @@ static void DemoWindowWidgetsQueryingStatuses()
|
||||
static char str[16] = {};
|
||||
if (item_disabled)
|
||||
ImGui::BeginDisabled(true);
|
||||
if (item_mixedvalue)
|
||||
ImGui::PushItemFlag(ImGuiItemFlags_MixedValue, true);
|
||||
if (item_type == 0) { ImGui::Text("ITEM: Text"); } // Testing text items with no identifier/interaction
|
||||
if (item_type == 1) { ret = ImGui::Button("ITEM: Button"); } // Testing button
|
||||
if (item_type == 2) { ImGui::PushItemFlag(ImGuiItemFlags_ButtonRepeat, true); ret = ImGui::Button("ITEM: Button"); ImGui::PopItemFlag(); } // Testing button (with repeater)
|
||||
@ -2414,6 +2479,8 @@ static void DemoWindowWidgetsQueryingStatuses()
|
||||
ImGui::PopItemFlag();
|
||||
ImGui::PopItemFlag();
|
||||
}
|
||||
if (item_mixedvalue)
|
||||
ImGui::PopItemFlag();
|
||||
if (item_disabled)
|
||||
ImGui::EndDisabled();
|
||||
|
||||
@ -3764,11 +3831,13 @@ static void DemoWindowWidgetsTabs()
|
||||
// but they tend to make more sense together)
|
||||
static bool show_leading_button = true;
|
||||
static bool show_trailing_button = true;
|
||||
static bool show_leading_trailing_tabs = false;
|
||||
ImGui::Checkbox("Show Leading TabItemButton()", &show_leading_button);
|
||||
ImGui::Checkbox("Show Trailing TabItemButton()", &show_trailing_button);
|
||||
ImGui::Checkbox("Show Leading+Trailing TabItem()", &show_leading_trailing_tabs);
|
||||
|
||||
// Expose some other flags which are useful to showcase how they interact with Leading/Trailing tabs
|
||||
static ImGuiTabBarFlags tab_bar_flags = ImGuiTabBarFlags_AutoSelectNewTabs | ImGuiTabBarFlags_Reorderable | ImGuiTabBarFlags_FittingPolicyShrink;
|
||||
static ImGuiTabBarFlags tab_bar_flags = ImGuiTabBarFlags_AutoSelectNewTabs | ImGuiTabBarFlags_Reorderable | ImGuiTabBarFlags_FittingPolicyMixed;
|
||||
EditTabBarFittingPolicyFlags(&tab_bar_flags);
|
||||
|
||||
if (ImGui::BeginTabBar("MyTabBar", tab_bar_flags))
|
||||
@ -3783,6 +3852,15 @@ static void DemoWindowWidgetsTabs()
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
// Demo Leading/Trailing Tabs
|
||||
if (show_leading_trailing_tabs)
|
||||
{
|
||||
if (ImGui::BeginTabItem("Leading", NULL, ImGuiTabItemFlags_Leading))
|
||||
ImGui::EndTabItem();
|
||||
if (ImGui::BeginTabItem("Trailing", NULL, ImGuiTabItemFlags_Trailing))
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
|
||||
// Demo Trailing Tabs: click the "+" button to add a new tab.
|
||||
// (In your app you may want to use a font icon instead of the "+")
|
||||
// We submit it before the regular tabs, but thanks to the ImGuiTabItemFlags_Trailing flag it will always appear at the end.
|
||||
@ -3951,14 +4029,24 @@ static void DemoWindowWidgetsTextFilter()
|
||||
static ImGuiTextFilter filter;
|
||||
ImGui::Text("Filter usage:\n"
|
||||
" \"\" display all lines\n"
|
||||
" \"xxx\" display lines containing \"xxx\"\n"
|
||||
" \"xxx,yyy\" display lines containing \"xxx\" or \"yyy\"\n"
|
||||
" \"-xxx\" hide lines containing \"xxx\"");
|
||||
filter.Draw();
|
||||
const char* lines[] = { "aaa1.c", "bbb1.c", "ccc1.c", "aaa2.cpp", "bbb2.cpp", "ccc2.cpp", "abc.h", "hello, world" };
|
||||
for (int i = 0; i < IM_COUNTOF(lines); i++)
|
||||
if (filter.PassFilter(lines[i]))
|
||||
ImGui::BulletText("%s", lines[i]);
|
||||
" xxx display lines containing \"xxx\"\n"
|
||||
" xxx yyy display lines containing \"xxx\" and \"yyy\"\n"
|
||||
" \"xxx yyy\" display lines containing \"xxx yyy\"\n"
|
||||
" xxx,yyy display lines containing \"xxx\" or \"yyy\"\n"
|
||||
" -xxx hide lines containing \"xxx\"");
|
||||
ImGui::SetNextItemWidth(-FLT_MIN);
|
||||
filter.DrawWithHint("##Filter", "Filter (incl -excl)");
|
||||
if (ImGui::BeginChild("##items", ImVec2(-FLT_MIN, ImGui::GetTextLineHeightWithSpacing() * 15), ImGuiChildFlags_FrameStyle))
|
||||
{
|
||||
const char* lines[] = { "aaa1.c", "bbb1.c", "ccc1.c", "aaa2.cpp", "bbb2.cpp", "ccc2.cpp", "abc.h", "hello, world" };
|
||||
for (const char* item : lines)
|
||||
if (filter.PassFilter(item))
|
||||
ImGui::TextUnformatted(item);
|
||||
for (const char* item : ExampleNames)
|
||||
if (filter.PassFilter(item))
|
||||
ImGui::TextUnformatted(item);
|
||||
}
|
||||
ImGui::EndChild();
|
||||
ImGui::TreePop();
|
||||
}
|
||||
}
|
||||
@ -4591,6 +4679,7 @@ static void DemoWindowWidgets(ImGuiDemoWindowData* demo_data)
|
||||
DemoWindowWidgetsImages();
|
||||
DemoWindowWidgetsListBoxes();
|
||||
DemoWindowWidgetsLiveEdit(demo_data);
|
||||
DemoWindowWidgetsMixedValues();
|
||||
DemoWindowWidgetsMultiComponents();
|
||||
DemoWindowWidgetsPlotting();
|
||||
DemoWindowWidgetsProgressBars();
|
||||
@ -8856,9 +8945,6 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
|
||||
SameLine(); SetNextItemWidth(GetFontSize() * 10); Combo("##output_type", &output_dest, "To Clipboard\0To TTY\0");
|
||||
SameLine(); Checkbox("Only Modified Colors", &output_only_modified);
|
||||
|
||||
static ImGuiTextFilter filter;
|
||||
filter.Draw("Filter colors", GetFontSize() * 16);
|
||||
|
||||
static ImGuiColorEditFlags alpha_flags = 0;
|
||||
if (RadioButton("Opaque", alpha_flags == ImGuiColorEditFlags_AlphaOpaque)) { alpha_flags = ImGuiColorEditFlags_AlphaOpaque; } SameLine();
|
||||
if (RadioButton("Alpha", alpha_flags == ImGuiColorEditFlags_None)) { alpha_flags = ImGuiColorEditFlags_None; } SameLine();
|
||||
@ -8868,6 +8954,10 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
|
||||
"Left-click on color square to open color picker,\n"
|
||||
"Right-click to open edit options menu.");
|
||||
|
||||
static ImGuiTextFilter filter;
|
||||
SetNextItemWidth(-FLT_MIN);
|
||||
filter.DrawWithHint("##FilterColors", "Filter Colors (incl -excl)");
|
||||
|
||||
SetNextWindowSizeConstraints(ImVec2(0.0f, GetTextLineHeightWithSpacing() * 10), ImVec2(FLT_MAX, FLT_MAX));
|
||||
BeginChild("##colors", ImVec2(0, 0), ImGuiChildFlags_Borders | ImGuiChildFlags_NavFlattened, ImGuiWindowFlags_AlwaysVerticalScrollbar | ImGuiWindowFlags_AlwaysHorizontalScrollbar);
|
||||
PushItemWidth(GetFontSize() * -12);
|
||||
@ -9280,7 +9370,10 @@ struct ExampleAppConsole
|
||||
if (ImGui::Button("Options"))
|
||||
ImGui::OpenPopup("Options");
|
||||
ImGui::SameLine();
|
||||
Filter.Draw("Filter (\"incl,-excl\") (\"error\")", 180);
|
||||
|
||||
ImGui::SetNextItemShortcut(ImGuiMod_Ctrl | ImGuiKey_F, ImGuiInputFlags_Tooltip);
|
||||
ImGui::SetNextItemWidth(-FLT_MIN);
|
||||
Filter.DrawWithHint("##Filter", "Filter (incl -excl)");
|
||||
ImGui::Separator();
|
||||
|
||||
// Reserve enough left-over height for 1 separator + 1 input text
|
||||
@ -9615,7 +9708,8 @@ struct ExampleAppLog
|
||||
ImGui::SameLine();
|
||||
bool copy = ImGui::Button("Copy");
|
||||
ImGui::SameLine();
|
||||
Filter.Draw("Filter", -100.0f);
|
||||
ImGui::SetNextItemWidth(-FLT_MIN);
|
||||
Filter.DrawWithHint("##Filter", "Filter (incl -excl)");
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
@ -9810,7 +9904,7 @@ struct ExampleAppPropertyEditor
|
||||
ImGui::Text("(%d root nodes)", root_node->Childs.Size);
|
||||
ImGui::SetNextItemWidth(-FLT_MIN);
|
||||
ImGui::SetNextItemShortcut(ImGuiMod_Ctrl | ImGuiKey_F, ImGuiInputFlags_Tooltip);
|
||||
if (ImGui::InputTextWithHint("##Filter", "incl,-excl", Filter.InputBuf, IM_COUNTOF(Filter.InputBuf), ImGuiInputTextFlags_EscapeClearsAll))
|
||||
if (ImGui::InputTextWithHint("##Filter", "incl -excl", Filter.InputBuf, IM_COUNTOF(Filter.InputBuf), ImGuiInputTextFlags_EscapeClearsAll))
|
||||
Filter.Build();
|
||||
ImGui::PopItemFlag();
|
||||
|
||||
|
||||
@ -340,9 +340,9 @@ void ImGui::StyleColorsLight(ImGuiStyle* dst)
|
||||
colors[ImGuiCol_FrameBg] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f);
|
||||
colors[ImGuiCol_FrameBgHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.40f);
|
||||
colors[ImGuiCol_FrameBgActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f);
|
||||
colors[ImGuiCol_TitleBg] = ImVec4(0.96f, 0.96f, 0.96f, 1.00f);
|
||||
colors[ImGuiCol_TitleBgActive] = ImVec4(0.82f, 0.82f, 0.82f, 1.00f);
|
||||
colors[ImGuiCol_TitleBgCollapsed] = ImVec4(1.00f, 1.00f, 1.00f, 0.51f);
|
||||
colors[ImGuiCol_TitleBg] = ImVec4(0.82f, 0.82f, 0.82f, 1.00f);
|
||||
colors[ImGuiCol_TitleBgActive] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f);
|
||||
colors[ImGuiCol_TitleBgCollapsed] = ImVec4(1.00f, 1.00f, 1.00f, 0.43f);
|
||||
colors[ImGuiCol_MenuBarBg] = ImVec4(0.86f, 0.86f, 0.86f, 1.00f);
|
||||
colors[ImGuiCol_ScrollbarBg] = ImVec4(0.98f, 0.98f, 0.98f, 0.53f);
|
||||
colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.69f, 0.69f, 0.69f, 0.80f);
|
||||
@ -373,7 +373,7 @@ void ImGui::StyleColorsLight(ImGuiStyle* dst)
|
||||
colors[ImGuiCol_TabDimmedSelected] = ImLerp(colors[ImGuiCol_TabSelected], colors[ImGuiCol_TitleBg], 0.40f);
|
||||
colors[ImGuiCol_TabDimmedSelectedOverline] = ImVec4(0.26f, 0.59f, 1.00f, 0.00f);
|
||||
colors[ImGuiCol_DockingPreview] = colors[ImGuiCol_Header] * ImVec4(1.0f, 1.0f, 1.0f, 0.7f);
|
||||
colors[ImGuiCol_DockingEmptyBg] = ImVec4(0.20f, 0.20f, 0.20f, 1.00f);
|
||||
colors[ImGuiCol_DockingEmptyBg] = ImVec4(0.68f, 0.69f, 0.73f, 1.00f);
|
||||
colors[ImGuiCol_PlotLines] = ImVec4(0.39f, 0.39f, 0.39f, 1.00f);
|
||||
colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.43f, 0.35f, 1.00f);
|
||||
colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f);
|
||||
@ -705,7 +705,7 @@ void ImDrawList::PushTexture(ImTextureRef tex_ref)
|
||||
_TextureStack.push_back(tex_ref);
|
||||
_CmdHeader.TexRef = tex_ref;
|
||||
if (tex_ref._TexData != NULL)
|
||||
IM_ASSERT(tex_ref._TexData->WantDestroyNextFrame == false);
|
||||
IM_ASSERT(tex_ref._TexData->Status != ImTextureStatus_WantDestroy && tex_ref._TexData->Status != ImTextureStatus_Destroyed);
|
||||
_OnChangedTexture();
|
||||
}
|
||||
|
||||
@ -6225,26 +6225,33 @@ ImDrawFlags ImGui::CalcRoundingFlagsForRectInRect(const ImRect& r_in, const ImRe
|
||||
// Helper for ColorPicker4()
|
||||
// NB: This is rather brittle and will show artifact when rounding this enabled if rounded corners overlap multiple cells. Caller currently responsible for avoiding that.
|
||||
// Spent a non reasonable amount of time trying to getting this right for ColorButton with rounding+anti-aliasing+ImGuiColorEditFlags_HalfAlphaPreview flag + various grid sizes and offsets, and eventually gave up... probably more reasonable to disable rounding altogether.
|
||||
// FIXME: uses ImGui::GetColorU32
|
||||
void ImGui::RenderColorRectWithAlphaCheckerboard(ImDrawList* draw_list, ImVec2 p_min, ImVec2 p_max, ImU32 col, float grid_step, ImVec2 grid_off, float rounding, ImDrawFlags flags)
|
||||
void ImGui::RenderColorRectWithAlphaCheckerboard(ImDrawList* draw_list, ImVec2 p_min, ImVec2 p_max, ImU32 col, float alpha, float grid_step, ImVec2 grid_off, float rounding, ImDrawFlags flags)
|
||||
{
|
||||
if ((flags & ImDrawFlags_RoundCornersMask_) == 0)
|
||||
flags = ImDrawFlags_RoundCornersDefault_;
|
||||
flags = ImDrawFlags_RoundCornersAll;
|
||||
if (((col & IM_COL32_A_MASK) >> IM_COL32_A_SHIFT) < 0xFF)
|
||||
{
|
||||
ImU32 col_bg1 = GetColorU32(ImAlphaBlendColors(IM_COL32(128, 128, 128, 255), col));
|
||||
ImU32 col_bg2 = GetColorU32(ImAlphaBlendColors(IM_COL32(204, 204, 204, 255), col));
|
||||
draw_list->AddRectFilled(p_min, p_max, col_bg1, rounding, flags);
|
||||
IM_ASSERT(alpha >= 0.0f && alpha <= 1.0f);
|
||||
const ImU32 a_mask = (ImU32)(alpha * 255.0f) << IM_COL32_A_SHIFT;
|
||||
ImU32 col_bg1 = (ImAlphaBlendColors(IM_COL32(128, 128, 128, 255), col) & ~IM_COL32_A_MASK) | a_mask;
|
||||
ImU32 col_bg2 = (ImAlphaBlendColors(IM_COL32(204, 204, 204, 255), col) & ~IM_COL32_A_MASK) | a_mask;
|
||||
const bool dual_layer = (alpha == 1.0f); // Dual layer is faster but incorrect if blending.
|
||||
if (dual_layer)
|
||||
draw_list->AddRectFilled(p_min, p_max, col_bg1, rounding, flags);
|
||||
|
||||
int yi = 0;
|
||||
for (float y = p_min.y + grid_off.y; y < p_max.y; y += grid_step, yi++)
|
||||
{
|
||||
float y1 = ImClamp(y, p_min.y, p_max.y), y2 = ImMin(y + grid_step, p_max.y);
|
||||
float y1 = ImClamp((float)(int)y, p_min.y, p_max.y), y2 = ImMin((float)(int)(y + grid_step), p_max.y);
|
||||
if (y2 <= y1)
|
||||
continue;
|
||||
for (float x = p_min.x + grid_off.x + ((yi ^ 1) & 1) * grid_step; x < p_max.x; x += grid_step * 2.0f)
|
||||
|
||||
const float x_start_off = dual_layer ? (((yi ^ 1) & 1) * grid_step) : 0.0f;
|
||||
const float x_step = dual_layer ? (grid_step * 2.0f) : (grid_step);
|
||||
int xi = 0;
|
||||
for (float x = p_min.x + grid_off.x + x_start_off; x < p_max.x; x += x_step, xi++)
|
||||
{
|
||||
float x1 = ImClamp(x, p_min.x, p_max.x), x2 = ImMin(x + grid_step, p_max.x);
|
||||
float x1 = ImClamp((float)(int)x, p_min.x, p_max.x), x2 = ImMin((float)(int)(x + grid_step), p_max.x);
|
||||
if (x2 <= x1)
|
||||
continue;
|
||||
ImDrawFlags cell_flags = ImDrawFlags_RoundCornersNone; // FIXME: Could use CalcRoundingFlagsForRectInRect()
|
||||
@ -6253,7 +6260,8 @@ void ImGui::RenderColorRectWithAlphaCheckerboard(ImDrawList* draw_list, ImVec2 p
|
||||
|
||||
// Combine flags
|
||||
cell_flags = (flags == ImDrawFlags_RoundCornersNone || cell_flags == ImDrawFlags_RoundCornersNone) ? ImDrawFlags_RoundCornersNone : (cell_flags & flags);
|
||||
draw_list->AddRectFilled(ImVec2(x1, y1), ImVec2(x2, y2), col_bg2, rounding, cell_flags);
|
||||
ImU32 col_bg = dual_layer ? col_bg2 : (((yi + xi) & 1) ? col_bg2 : col_bg1);
|
||||
draw_list->AddRectFilled(ImVec2(x1, y1), ImVec2(x2, y2), col_bg, rounding, cell_flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -194,6 +194,7 @@ struct ImGuiWindow; // Storage for one window
|
||||
struct ImGuiWindowDockStyle; // Storage for window-style data which needs to be stored for docking purpose
|
||||
struct ImGuiWindowTempData; // Temporary storage for one window (that's the data which in theory we could ditch at the end of the frame, in practice we currently keep it for each window)
|
||||
struct ImGuiWindowSettings; // Storage for a window .ini settings (we keep one of those even if the actual window wasn't instanced during this session)
|
||||
struct ImGuiWindowStackData; // Storage for each window pushed into the stack
|
||||
|
||||
// Enumerations
|
||||
// Use your programming IDE "Go to definition" facility on the names of the center columns to find the actual flags/enum lists.
|
||||
@ -378,6 +379,7 @@ extern IMGUI_API ImGuiContext* GImGui; // Current implicit context pointer
|
||||
// - Helper: ImPool<>
|
||||
// - Helper: ImChunkStream<>
|
||||
// - Helper: ImGuiTextIndex
|
||||
// - Helper: ImGuiTextFilterItem
|
||||
// - Helper: ImGuiStorage
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@ -417,7 +419,7 @@ IMGUI_API const char* ImStrSkipBlank(const char* str);
|
||||
IMGUI_API int ImStrlenW(const ImWchar* str); // Computer string length (ImWchar string)
|
||||
IMGUI_API const char* ImStrbol(const char* buf_mid_line, const char* buf_begin); // Find beginning-of-line
|
||||
IM_MSVC_RUNTIME_CHECKS_OFF
|
||||
inline char ImToUpper(char c) { return (c >= 'a' && c <= 'z') ? c &= ~32 : c; }
|
||||
inline char ImToUpper(char c) { return (c >= 'a' && c <= 'z') ? c & ~32 : c; }
|
||||
inline bool ImCharIsBlankA(char c) { return c == ' ' || c == '\t'; }
|
||||
inline bool ImCharIsBlankW(unsigned int c) { return c == ' ' || c == '\t' || c == 0x3000; }
|
||||
inline bool ImCharIsXdigitA(char c) { return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'); }
|
||||
@ -576,25 +578,25 @@ IM_MSVC_RUNTIME_CHECKS_OFF
|
||||
struct ImVec1
|
||||
{
|
||||
float x;
|
||||
constexpr ImVec1() : x(0.0f) { }
|
||||
constexpr ImVec1(float _x) : x(_x) { }
|
||||
IM_NODEBUGSTEP constexpr inline ImVec1() : x(0.0f) { }
|
||||
IM_NODEBUGSTEP constexpr inline ImVec1(float _x) : x(_x) { }
|
||||
};
|
||||
|
||||
// Helper: ImVec2i (2D vector, integer)
|
||||
struct ImVec2i
|
||||
{
|
||||
int x, y;
|
||||
constexpr ImVec2i() : x(0), y(0) {}
|
||||
constexpr ImVec2i(int _x, int _y) : x(_x), y(_y) {}
|
||||
IM_NODEBUGSTEP constexpr inline ImVec2i() : x(0), y(0) {}
|
||||
IM_NODEBUGSTEP constexpr inline ImVec2i(int _x, int _y) : x(_x), y(_y) {}
|
||||
};
|
||||
|
||||
// Helper: ImVec2ih (2D vector, half-size integer, for long-term packed storage)
|
||||
struct ImVec2ih
|
||||
{
|
||||
short x, y;
|
||||
constexpr ImVec2ih() : x(0), y(0) {}
|
||||
constexpr ImVec2ih(short _x, short _y) : x(_x), y(_y) {}
|
||||
constexpr explicit ImVec2ih(const ImVec2& rhs) : x((short)rhs.x), y((short)rhs.y) {}
|
||||
IM_NODEBUGSTEP constexpr inline ImVec2ih() : x(0), y(0) {}
|
||||
IM_NODEBUGSTEP constexpr inline ImVec2ih(short _x, short _y) : x(_x), y(_y) {}
|
||||
IM_NODEBUGSTEP constexpr inline explicit ImVec2ih(const ImVec2& rhs) : x((short)rhs.x), y((short)rhs.y) {}
|
||||
};
|
||||
|
||||
// Helper: ImRect (2D axis aligned bounding-box)
|
||||
@ -604,10 +606,10 @@ struct IMGUI_API ImRect
|
||||
ImVec2 Min; // Upper-left
|
||||
ImVec2 Max; // Lower-right
|
||||
|
||||
constexpr ImRect() : Min(0.0f, 0.0f), Max(0.0f, 0.0f) {}
|
||||
constexpr ImRect(const ImVec2& min, const ImVec2& max) : Min(min), Max(max) {}
|
||||
constexpr ImRect(const ImVec4& v) : Min(v.x, v.y), Max(v.z, v.w) {}
|
||||
constexpr ImRect(float x1, float y1, float x2, float y2) : Min(x1, y1), Max(x2, y2) {}
|
||||
IM_NODEBUGSTEP constexpr inline ImRect() : Min(0.0f, 0.0f), Max(0.0f, 0.0f) {}
|
||||
IM_NODEBUGSTEP constexpr inline ImRect(const ImVec2& min, const ImVec2& max) : Min(min), Max(max) {}
|
||||
IM_NODEBUGSTEP constexpr inline ImRect(const ImVec4& v) : Min(v.x, v.y), Max(v.z, v.w) {}
|
||||
IM_NODEBUGSTEP constexpr inline ImRect(float x1, float y1, float x2, float y2) : Min(x1, y1), Max(x2, y2) {}
|
||||
|
||||
ImVec2 GetCenter() const { return ImVec2((Min.x + Max.x) * 0.5f, (Min.y + Max.y) * 0.5f); }
|
||||
ImVec2 GetSize() const { return ImVec2(Max.x - Min.x, Max.y - Min.y); }
|
||||
@ -709,13 +711,13 @@ struct ImSpan
|
||||
inline bool empty() const { return Data == DataEnd; }
|
||||
inline int size() const { return (int)(ptrdiff_t)(DataEnd - Data); }
|
||||
inline int size_in_bytes() const { return (int)(ptrdiff_t)(DataEnd - Data) * (int)sizeof(T); }
|
||||
inline T& operator[](int i) { T* p = Data + i; IM_ASSERT(p >= Data && p < DataEnd); return *p; }
|
||||
inline const T& operator[](int i) const { const T* p = Data + i; IM_ASSERT(p >= Data && p < DataEnd); return *p; }
|
||||
|
||||
inline T* begin() { return Data; }
|
||||
inline const T* begin() const { return Data; }
|
||||
inline T* end() { return DataEnd; }
|
||||
inline const T* end() const { return DataEnd; }
|
||||
IM_NODEBUGSTEP inline T& operator[](int i) { T* p = Data + i; IM_ASSERT(p >= Data && p < DataEnd); return *p; }
|
||||
IM_NODEBUGSTEP inline const T& operator[](int i) const { const T* p = Data + i; IM_ASSERT(p >= Data && p < DataEnd); return *p; }
|
||||
IM_NODEBUGSTEP inline T* begin() { return Data; }
|
||||
IM_NODEBUGSTEP inline const T* begin() const { return Data; }
|
||||
IM_NODEBUGSTEP inline T* end() { return DataEnd; }
|
||||
IM_NODEBUGSTEP inline const T* end() const { return DataEnd; }
|
||||
|
||||
// Utilities
|
||||
inline int index_from_ptr(const T* it) const { IM_ASSERT(it >= Data && it < DataEnd); const ptrdiff_t off = it - Data; return (int)off; }
|
||||
@ -846,6 +848,15 @@ struct ImGuiTextIndex
|
||||
void append(const char* base, int old_size, int new_size);
|
||||
};
|
||||
|
||||
// [Internal] Types
|
||||
struct ImGuiTextFilterItem
|
||||
{
|
||||
const char* Begin;
|
||||
int Len;
|
||||
int CountInclude; // >0 when beginning of an AND chain.
|
||||
ImGuiTextFilterItem(const char* b, const char* e) { IM_ASSERT(e > b); Begin = b; Len = (int)(e - b); CountInclude = 0; }
|
||||
};
|
||||
|
||||
// Helper: ImGuiPackedDate (sizeof() == 2)
|
||||
// Store a date in a way that is efficient to read/write in text form. If we stored e.g. number of days since Epoch we'd need costlier back and forth.
|
||||
// This is specifically designed to be able to prune old .ini data.
|
||||
@ -943,6 +954,8 @@ struct ImFontStackData
|
||||
// [SECTION] Style support
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#define ImGuiCol_TextMixedValue ImGuiCol_TextDisabled
|
||||
|
||||
struct ImGuiStyleVarInfo
|
||||
{
|
||||
ImU32 Count : 8; // 1+
|
||||
@ -1004,7 +1017,6 @@ enum ImGuiItemFlagsPrivate_
|
||||
{
|
||||
// Controlled by user
|
||||
ImGuiItemFlags_ReadOnly = 1 << 11, // false // [ALPHA] Allow hovering interactions but underlying value is not changed.
|
||||
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 highlight (behave as if NavHighlightItemUnderNav==false).
|
||||
@ -1094,12 +1106,6 @@ enum ImGuiButtonFlagsPrivate_
|
||||
//ImGuiButtonFlags_NoKeyModifiers = ImGuiButtonFlags_NoKeyModsAllowed, // Renamed in 1.91.4
|
||||
};
|
||||
|
||||
// Extend ImGuiComboFlags_
|
||||
enum ImGuiComboFlagsPrivate_
|
||||
{
|
||||
ImGuiComboFlags_CustomPreview = 1 << 20, // enable BeginComboPreview()
|
||||
};
|
||||
|
||||
// Extend ImGuiSliderFlags_
|
||||
enum ImGuiSliderFlagsPrivate_
|
||||
{
|
||||
@ -1194,6 +1200,10 @@ enum ImGuiPlotType
|
||||
ImGuiPlotType_Histogram,
|
||||
};
|
||||
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
//ImGuiComboFlags_CustomPreview = 1 << 20, // enable BeginComboPreview() // [Obsoleted in 1.93.0] Unnecessary: can now use BeginComboPreview() without a flag.
|
||||
#endif
|
||||
|
||||
// Storage data for BeginComboPreview()/EndComboPreview()
|
||||
struct IMGUI_API ImGuiComboPreviewData
|
||||
{
|
||||
@ -1202,7 +1212,10 @@ struct IMGUI_API ImGuiComboPreviewData
|
||||
ImVec2 BackupCursorMaxPos;
|
||||
ImVec2 BackupCursorPosPrevLine;
|
||||
float BackupPrevLineTextBaseOffset;
|
||||
ImGuiLayoutType BackupLayout;
|
||||
float BackupWorkRectMaxX;
|
||||
float BackupContentRectMaxX;
|
||||
ImGuiLayoutType BackupLayout : 8;
|
||||
int WithinPreview : 2;
|
||||
|
||||
ImGuiComboPreviewData() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
@ -1291,6 +1304,7 @@ struct IMGUI_API ImGuiInputTextState
|
||||
bool SelectedAllMouseLock; // after a double-click to select all, we ignore further mouse drags to update selection
|
||||
bool EditedBefore; // edited since activated
|
||||
bool EditedThisFrame; // edited this frame
|
||||
bool ValidatedThisFrame;
|
||||
bool WantReloadUserBuf; // force a reload of user buf so it may be modified externally. may be automatic in future version.
|
||||
ImS8 LastMoveDirectionLR; // ImGuiDir_Left or ImGuiDir_Right. track last movement direction so when cursor cross over a word-wrapping boundaries we can display it on either line depending on last move.s
|
||||
int ReloadSelectionStart;
|
||||
@ -1476,7 +1490,7 @@ struct IMGUI_API ImGuiErrorRecoveryState
|
||||
ImGuiErrorRecoveryState() { memset((void*)this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
// Data saved for each window pushed into the stack
|
||||
// Storage for each window pushed into the stack.
|
||||
struct ImGuiWindowStackData
|
||||
{
|
||||
ImGuiWindow* Window;
|
||||
@ -1484,6 +1498,7 @@ struct ImGuiWindowStackData
|
||||
ImGuiErrorRecoveryState StackSizesInBegin; // Store size of various stacks for asserting
|
||||
bool DisabledOverrideReenable; // Non-child window override disabled flag
|
||||
float DisabledOverrideReenableAlphaBackup;
|
||||
ImRect ParentLastComboPreviewRect;
|
||||
};
|
||||
|
||||
struct ImGuiShrinkWidthItem
|
||||
@ -2180,8 +2195,9 @@ struct ImGuiViewportP : public ImGuiViewport
|
||||
float LastAlpha;
|
||||
bool LastFocusedHadNavWindow;// Instead of maintaining a LastFocusedWindow (which may harder to correctly maintain), we merely store weither NavWindow != NULL last time the viewport was focused.
|
||||
short PlatformMonitor;
|
||||
float BgFgDrawListsLastTimeActive[2]; // Last frame number the background (0) and foreground (1) draw lists were used
|
||||
ImDrawList* BgFgDrawLists[2]; // Convenience background (0) and foreground (1) draw lists. We use them to draw software mouser cursor when io.MouseDrawCursor is set and to draw most debug overlays.
|
||||
int BgFgDrawListsLastFrameActive[2]; // Last frame the background (0) and foreground (1) draw lists were used.
|
||||
float BgFgDrawListsLastTimeActive[2]; // Timestamps for Gc.
|
||||
ImDrawData DrawDataP;
|
||||
ImDrawDataBuilder DrawDataBuilder; // Temporary data while building final ImDrawData
|
||||
ImVec2 LastPlatformPos;
|
||||
@ -2197,7 +2213,7 @@ struct ImGuiViewportP : public ImGuiViewport
|
||||
ImVec2 BuildWorkInsetMin; // Work Area inset accumulator for current frame, to become next frame's WorkInset
|
||||
ImVec2 BuildWorkInsetMax; // "
|
||||
|
||||
ImGuiViewportP() { Window = NULL; Idx = -1; LastFrameActive = LastFocusedStampCount = -1; BgFgDrawListsLastTimeActive[0] = BgFgDrawListsLastTimeActive[1] = -1.0f; LastNameHash = 0; Alpha = LastAlpha = 1.0f; LastFocusedHadNavWindow = false; PlatformMonitor = -1; BgFgDrawLists[0] = BgFgDrawLists[1] = NULL; LastPlatformPos = LastPlatformSize = LastRendererSize = ImVec2(FLT_MAX, FLT_MAX); }
|
||||
ImGuiViewportP() { Window = NULL; Idx = -1; LastFrameActive = LastFocusedStampCount = -1; LastNameHash = 0; Alpha = LastAlpha = 1.0f; LastFocusedHadNavWindow = false; PlatformMonitor = -1; BgFgDrawLists[0] = BgFgDrawLists[1] = NULL; BgFgDrawListsLastFrameActive[0] = BgFgDrawListsLastFrameActive[1] = -1; BgFgDrawListsLastTimeActive[0] = BgFgDrawListsLastTimeActive[1] = -1.0; LastPlatformPos = LastPlatformSize = LastRendererSize = ImVec2(FLT_MAX, FLT_MAX); }
|
||||
~ImGuiViewportP() { if (BgFgDrawLists[0]) IM_DELETE(BgFgDrawLists[0]); if (BgFgDrawLists[1]) IM_DELETE(BgFgDrawLists[1]); }
|
||||
void ClearRequestFlags() { PlatformRequestClose = PlatformRequestMove = PlatformRequestResize = false; }
|
||||
|
||||
@ -2501,6 +2517,7 @@ struct ImGuiContext
|
||||
ImVec2 WheelingAxisAvg;
|
||||
|
||||
// Item/widgets state and tracking information
|
||||
const char* MixedValueLabel; // Value replacement when displaying a mixed value. Default to "-" (Unreal uses "Multiple values", Unity uses "---"). May be interpreted as a format: must not contain single %. Set to NULL to display original value.
|
||||
ImGuiID DebugDrawIdConflictsId; // Set when we detect multiple items with the same identifier
|
||||
ImGuiID DebugHookIdInfoId; // Will call core hooks: DebugHookIdInfo() from GetID functions, used by ID Stack Tool [next HoveredId/ActiveId to not pull in an extra cache-line]
|
||||
ImGuiID HoveredId; // Hovered widget, filled during the frame
|
||||
@ -2644,6 +2661,7 @@ struct ImGuiContext
|
||||
ImGuiID NavJustMovedToFocusScopeId; // Just navigated to this focus scope id (result of a successfully MoveRequest).
|
||||
ImGuiKeyChord NavJustMovedToKeyMods;
|
||||
bool NavJustMovedToIsTabbing; // Copy of ImGuiNavMoveFlags_IsTabbing. Maybe we should store whole flags.
|
||||
bool NavJustMovedToIsInit; // Copy of ImGuiNavMoveFlags_IsTabbing. Maybe we should store whole flags.
|
||||
bool NavJustMovedToHasSelectionData; // Copy of move result's ItemFlags & ImGuiItemFlags_HasSelectionUserData). Maybe we should just store ImGuiNavItemData.
|
||||
|
||||
// Navigation: extra config options (will be made public eventually)
|
||||
@ -2900,7 +2918,7 @@ struct IMGUI_API ImGuiWindowTempData
|
||||
ImVec2 MenuBarOffset; // MenuBarOffset.x is sort of equivalent of a per-layer CursorPos.x, saved/restored as we switch to the menu bar. The only situation when MenuBarOffset.y is > 0 if when (SafeAreaPadding.y > FramePadding.y), often used on TVs.
|
||||
ImGuiMenuColumns MenuColumns; // Simplified columns storage for menu items measurement
|
||||
int TreeDepth; // Current tree depth.
|
||||
ImU32 TreeHasStackDataDepthMask; // Store whether given depth has ImGuiTreeNodeStackData data. Could be turned into a ImU64 if necessary.
|
||||
ImU32 TreeHasStackDataDepthMask; // Store whether given depth has ImGuiTreeNodeStackData data. Could be turned into a ImU64 if necessary. Sync any changes with TREE_NODE_MAX_DEPTH/TREE_NODE_GET_DEPTH_MASK!
|
||||
ImU32 TreeRecordsClippedNodesY2Mask; // Store whether we should keep recording Y2. Cleared when passing clip max. Equivalent TreeHasStackDataDepthMask value should always be set.
|
||||
ImVector<ImGuiWindow*> ChildWindows;
|
||||
ImGuiStorage* StateStorage; // Current persistent per-window storage (store e.g. tree node open/close state)
|
||||
@ -3581,7 +3599,7 @@ namespace ImGui
|
||||
// - You are calling ImGui functions after ImGui::EndFrame()/ImGui::Render() and before the next ImGui::NewFrame(), which is also illegal.
|
||||
IMGUI_API ImGuiIO& GetIO(ImGuiContext* ctx);
|
||||
IMGUI_API ImGuiPlatformIO& GetPlatformIO(ImGuiContext* ctx);
|
||||
inline float GetScale() { ImGuiContext& g = *GImGui; return g.Style._MainScale; } // FIXME-DPI: I don't want to formalize this just yet. Because reasons. Please don't use.
|
||||
inline float GetScale() { ImGuiContext& g = *GImGui; return g.Style._MainScale; } // FIXME-DPI: PLEASE DO NOT USE. I don't want to formalize this just yet. Because reasons.
|
||||
inline ImGuiWindow* GetCurrentWindowRead() { ImGuiContext& g = *GImGui; return g.CurrentWindow; }
|
||||
inline ImGuiWindow* GetCurrentWindow() { ImGuiContext& g = *GImGui; g.CurrentWindow->WriteAccessed = true; return g.CurrentWindow; }
|
||||
IMGUI_API ImGuiWindow* FindWindowByID(ImGuiID id);
|
||||
@ -3771,7 +3789,7 @@ namespace ImGui
|
||||
|
||||
// Combos
|
||||
IMGUI_API bool BeginComboPopup(ImGuiID popup_id, const ImRect& bb, ImGuiComboFlags flags);
|
||||
IMGUI_API bool BeginComboPreview();
|
||||
IMGUI_API bool BeginComboPreview(); // Submit preview contents a combo. Call this after EndCombo() to display contents that's more than just a text label.
|
||||
IMGUI_API void EndComboPreview();
|
||||
|
||||
// Keyboard/Gamepad Navigation
|
||||
@ -3959,6 +3977,7 @@ namespace ImGui
|
||||
IMGUI_API void ClearDragDrop();
|
||||
IMGUI_API bool IsDragDropPayloadBeingAccepted();
|
||||
IMGUI_API void RenderDragDropTargetRectForItem(const ImRect& bb);
|
||||
IMGUI_API void RenderDragDropTargetRectForViewport(ImGuiID viewport_id, const ImRect& bb);
|
||||
IMGUI_API void RenderDragDropTargetRectEx(ImDrawList* draw_list, const ImRect& bb, float rounding);
|
||||
|
||||
// Typing-Select API
|
||||
@ -3992,6 +4011,7 @@ namespace ImGui
|
||||
IMGUI_API ImGuiTabItem* TabBarGetCurrentTab(ImGuiTabBar* tab_bar);
|
||||
inline int TabBarGetTabOrder(ImGuiTabBar* tab_bar, ImGuiTabItem* tab) { return tab_bar->Tabs.index_from_ptr(tab); }
|
||||
IMGUI_API const char* TabBarGetTabName(ImGuiTabBar* tab_bar, ImGuiTabItem* tab);
|
||||
IMGUI_API ImVec2 TabBarGetTabPos(ImGuiTabBar* tab_bar, ImGuiTabItem* tab);
|
||||
IMGUI_API void TabBarAddTab(ImGuiTabBar* tab_bar, ImGuiTabItemFlags tab_flags, ImGuiWindow* window);
|
||||
IMGUI_API void TabBarRemoveTab(ImGuiTabBar* tab_bar, ImGuiID tab_id);
|
||||
IMGUI_API void TabBarCloseTab(ImGuiTabBar* tab_bar, ImGuiTabItem* tab);
|
||||
@ -4018,7 +4038,7 @@ namespace ImGui
|
||||
IMGUI_API void RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool borders = true, float rounding = 0.0f);
|
||||
IMGUI_API void RenderFrameBorder(ImVec2 p_min, ImVec2 p_max, float rounding = 0.0f);
|
||||
IMGUI_API void RenderColorComponentMarker(const ImRect& bb, ImU32 col, float rounding);
|
||||
IMGUI_API void RenderColorRectWithAlphaCheckerboard(ImDrawList* draw_list, ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, float grid_step, ImVec2 grid_off, float rounding = 0.0f, ImDrawFlags flags = 0);
|
||||
IMGUI_API void RenderColorRectWithAlphaCheckerboard(ImDrawList* draw_list, ImVec2 p_min, ImVec2 p_max, ImU32 col, float alpha, float grid_step, ImVec2 grid_off, float rounding = 0.0f, ImDrawFlags flags = 0);
|
||||
IMGUI_API void RenderNavCursor(const ImRect& bb, ImGuiID id, ImGuiNavRenderCursorFlags flags = ImGuiNavRenderCursorFlags_None, float rounding = -1.0f); // Navigation highlight
|
||||
#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS
|
||||
inline void RenderNavHighlight(const ImRect& bb, ImGuiID id, ImGuiNavRenderCursorFlags flags = ImGuiNavRenderCursorFlags_None) { RenderNavCursor(bb, id, flags); } // Renamed in 1.91.4
|
||||
|
||||
@ -1405,7 +1405,7 @@ bool ImGui::RadioButton(const char* label, bool active)
|
||||
RenderNavCursor(total_bb, id);
|
||||
const int num_segment = window->DrawList->_CalcCircleAutoSegmentCount(radius);
|
||||
window->DrawList->AddCircleFilled(center, radius, GetColorU32((held && hovered) ? ImGuiCol_FrameBgActive : hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg), num_segment);
|
||||
if (active)
|
||||
if (active && (g.LastItemData.ItemFlags & ImGuiItemFlags_MixedValue) == 0)
|
||||
{
|
||||
const float pad = ImMax(1.0f, IM_TRUNC(square_sz / 6.0f));
|
||||
window->DrawList->AddCircleFilled(center, radius - pad, GetColorU32(ImGuiCol_CheckMark));
|
||||
@ -1958,7 +1958,7 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF
|
||||
const ImGuiID id = window->GetID(label);
|
||||
IM_ASSERT((flags & (ImGuiComboFlags_NoArrowButton | ImGuiComboFlags_NoPreview)) != (ImGuiComboFlags_NoArrowButton | ImGuiComboFlags_NoPreview)); // Can't use both flags together
|
||||
if (flags & ImGuiComboFlags_WidthFitPreview)
|
||||
IM_ASSERT((flags & (ImGuiComboFlags_NoPreview | (ImGuiComboFlags)ImGuiComboFlags_CustomPreview)) == 0);
|
||||
IM_ASSERT((flags & ImGuiComboFlags_NoPreview) == 0);
|
||||
|
||||
const float arrow_size = (flags & ImGuiComboFlags_NoArrowButton) ? 0.0f : GetFrameHeight();
|
||||
const char* label_end = FindRenderedTextEnd(label);
|
||||
@ -1998,13 +1998,8 @@ bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboF
|
||||
}
|
||||
RenderFrameBorder(bb.Min, bb.Max, style.FrameRounding);
|
||||
|
||||
// Custom preview
|
||||
if (flags & ImGuiComboFlags_CustomPreview)
|
||||
{
|
||||
g.ComboPreviewData.PreviewRect = ImRect(bb.Min.x, bb.Min.y, value_x2, bb.Max.y);
|
||||
IM_ASSERT(preview_value == NULL || preview_value[0] == 0);
|
||||
preview_value = NULL;
|
||||
}
|
||||
// Store geometry for BeginComboPreview() - only necessary when visible.
|
||||
g.ComboPreviewData.PreviewRect = (flags & ImGuiComboFlags_NoPreview) ? ImRect() : ImRect(bb.Min.x, bb.Min.y, value_x2, bb.Max.y);
|
||||
|
||||
// Render preview and label
|
||||
if (preview_value != NULL && !(flags & ImGuiComboFlags_NoPreview))
|
||||
@ -2086,6 +2081,7 @@ bool ImGui::BeginComboPopup(ImGuiID popup_id, const ImRect& bb, ImGuiComboFlags
|
||||
return false;
|
||||
}
|
||||
g.BeginComboDepth++;
|
||||
g.CurrentWindowStack.back().ParentLastComboPreviewRect = g.ComboPreviewData.PreviewRect;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2093,6 +2089,7 @@ void ImGui::EndCombo()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
g.BeginComboDepth--;
|
||||
g.ComboPreviewData.PreviewRect = g.CurrentWindowStack.back().ParentLastComboPreviewRect;
|
||||
char name[16];
|
||||
ImFormatString(name, IM_COUNTOF(name), "##Combo_%02d", g.BeginComboDepth); // FIXME: Move those to helpers?
|
||||
if (strcmp(g.CurrentWindow->Name, name) != 0)
|
||||
@ -2100,19 +2097,26 @@ void ImGui::EndCombo()
|
||||
EndPopup();
|
||||
}
|
||||
|
||||
// Call directly after the BeginCombo/EndCombo block. The preview is designed to only host non-interactive elements
|
||||
// (Experimental, see GitHub issues: #1658, #4168)
|
||||
// Submit preview contents for BeginCombo()/EndCombo(), to display contents that's more than just a text label.
|
||||
// - [BETA] See GitHub issues: #1658, #4168.
|
||||
// - Make sure you call this after EndCombo().
|
||||
// - The preview is designed to only host non-interactive elements.
|
||||
// - Not compatible with ImGuiComboFlags_WidthFitPreview.
|
||||
// - 2026-09-08 (1.93.0): removed ImGuiComboFlags_CustomPreview. You can use BeginComboPreview()/EndComboPreview() without an extra flag.
|
||||
bool ImGui::BeginComboPreview()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
ImGuiComboPreviewData* preview_data = &g.ComboPreviewData;
|
||||
|
||||
if (window->SkipItems || !(g.LastItemData.StatusFlags & ImGuiItemStatusFlags_Visible))
|
||||
return false;
|
||||
IM_ASSERT(g.LastItemData.Rect.Min.x == preview_data->PreviewRect.Min.x && g.LastItemData.Rect.Min.y == preview_data->PreviewRect.Min.y); // Didn't call after BeginCombo/EndCombo block or forgot to pass ImGuiComboFlags_CustomPreview flag?
|
||||
if (!window->ClipRect.Overlaps(preview_data->PreviewRect)) // Narrower test (optional)
|
||||
ImGuiComboPreviewData* preview_data = &g.ComboPreviewData;
|
||||
if (!window->ClipRect.Overlaps(preview_data->PreviewRect) || preview_data->PreviewRect.GetWidth() <= 0.0f) // Narrower test (optional) + handle _NoPreview
|
||||
return false;
|
||||
IM_ASSERT_USER_ERROR_RETV(g.LastItemData.Rect.Min.x == preview_data->PreviewRect.Min.x && g.LastItemData.Rect.Min.y == preview_data->PreviewRect.Min.y, false,
|
||||
"Call BeginComboPreview() after BeginCombo(), not after EndCombo()!"); // Calling after EndCombo() works only if you don't nest combos.
|
||||
IM_ASSERT_USER_ERROR_RETV(preview_data->WithinPreview == false, false,
|
||||
"Cannot recurse BeginComboPreview(): call EndComboPreview() before opening another combo.");
|
||||
|
||||
// FIXME: This could be contained in a PushWorkRect() api
|
||||
preview_data->BackupCursorPos = window->DC.CursorPos;
|
||||
@ -2120,6 +2124,10 @@ bool ImGui::BeginComboPreview()
|
||||
preview_data->BackupCursorPosPrevLine = window->DC.CursorPosPrevLine;
|
||||
preview_data->BackupPrevLineTextBaseOffset = window->DC.PrevLineTextBaseOffset;
|
||||
preview_data->BackupLayout = window->DC.LayoutType;
|
||||
preview_data->WithinPreview = true;
|
||||
preview_data->BackupWorkRectMaxX = window->WorkRect.Max.x;
|
||||
preview_data->BackupContentRectMaxX = window->ContentRegionRect.Max.x;
|
||||
window->WorkRect.Max.x = window->ContentRegionRect.Max.x = preview_data->PreviewRect.Max.x - g.Style.FramePadding.x;
|
||||
window->DC.CursorPos = preview_data->PreviewRect.Min + g.Style.FramePadding;
|
||||
window->DC.CursorMaxPos = window->DC.CursorPos;
|
||||
window->DC.LayoutType = ImGuiLayoutType_Horizontal;
|
||||
@ -2145,12 +2153,14 @@ void ImGui::EndComboPreview()
|
||||
}
|
||||
PopClipRect();
|
||||
window->DC.CursorPos = preview_data->BackupCursorPos;
|
||||
window->DC.CursorMaxPos = ImMax(window->DC.CursorMaxPos, preview_data->BackupCursorMaxPos);
|
||||
window->DC.CursorMaxPos = ImMax(window->DC.CursorMaxPos, preview_data->BackupCursorMaxPos); // No need to do the same with IdealMaxPos
|
||||
window->DC.CursorPosPrevLine = preview_data->BackupCursorPosPrevLine;
|
||||
window->DC.PrevLineTextBaseOffset = preview_data->BackupPrevLineTextBaseOffset;
|
||||
window->WorkRect.Max.x = preview_data->BackupWorkRectMaxX;
|
||||
window->ContentRegionRect.Max.x = preview_data->BackupContentRectMaxX;
|
||||
window->DC.LayoutType = preview_data->BackupLayout;
|
||||
window->DC.IsSameLine = false;
|
||||
preview_data->PreviewRect = ImRect();
|
||||
preview_data->WithinPreview = false;
|
||||
}
|
||||
|
||||
// Getter for the old Combo() API: const char*[]
|
||||
@ -2183,7 +2193,9 @@ bool ImGui::Combo(const char* label, int* current_item, const char* (*getter)(vo
|
||||
|
||||
// Call the getter to obtain the preview string which is a parameter to BeginCombo()
|
||||
const char* preview_value = NULL;
|
||||
if (*current_item >= 0 && *current_item < items_count)
|
||||
if ((g.NextItemData.ItemFlagsSet | g.CurrentItemFlags) & ImGuiItemFlags_MixedValue)
|
||||
preview_value = "";
|
||||
else if (*current_item >= 0 && *current_item < items_count)
|
||||
preview_value = getter(user_data, *current_item);
|
||||
|
||||
// The old Combo() API exposed "popup_max_height_in_items". The new more general BeginCombo() API doesn't have/need it, but we emulate it here.
|
||||
@ -2667,19 +2679,39 @@ bool ImGui::DragBehaviorT(ImGuiDataType data_type, TYPE* v, float v_speed, const
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool ShortcutsForCancel(ImGuiID id)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
bool is_cancel_with_keyboard = ImGui::Shortcut(ImGuiKey_Escape, ImGuiInputFlags_None, id);
|
||||
bool is_cancel_with_gamepad = (g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad) != 0 && (g.IO.BackendFlags & ImGuiBackendFlags_HasGamepad) != 0 && ImGui::Shortcut(ImGuiKey_NavGamepadCancel, ImGuiInputFlags_None, id);
|
||||
bool is_cancel_with_mouse = ImGui::IsMouseReleased(ImGuiMouseButton_Right, id);
|
||||
if (is_cancel_with_mouse)
|
||||
ImGui::SetKeyOwner(ImGuiKey_MouseRight, id);
|
||||
return is_cancel_with_keyboard || is_cancel_with_gamepad || is_cancel_with_mouse;
|
||||
}
|
||||
|
||||
bool ImGui::DragBehavior(ImGuiID id, ImGuiDataType data_type, void* p_v, float v_speed, const void* p_min, const void* p_max, const char* format, ImGuiSliderFlags flags)
|
||||
{
|
||||
// Read imgui.cpp "API BREAKING CHANGES" section for 1.78 if you hit this assert.
|
||||
IM_ASSERT((flags == 1 || (flags & ImGuiSliderFlags_InvalidMask_) == 0) && "Invalid ImGuiSliderFlags flags! Has the legacy 'float power' argument been mistakenly cast to flags? Call function with ImGuiSliderFlags_Logarithmic flags instead.");
|
||||
|
||||
// Things we can do easily outside the DragBehaviorT<> template, saves code generation.
|
||||
ImGuiContext& g = *GImGui;
|
||||
if (g.ActiveId == id)
|
||||
{
|
||||
// Those are the things we can do easily outside the DragBehaviorT<> template, saves code generation.
|
||||
if (g.ActiveIdSource == ImGuiInputSource_Mouse && !g.IO.MouseDown[0])
|
||||
ClearActiveID();
|
||||
else if ((g.ActiveIdSource == ImGuiInputSource_Keyboard || g.ActiveIdSource == ImGuiInputSource_Gamepad) && g.NavActivatePressedId == id && !g.ActiveIdIsJustActivated)
|
||||
ClearActiveID();
|
||||
if (ShortcutsForCancel(id) && g.ActiveId == id) //-V560
|
||||
{
|
||||
// Canceling action reverts to initial value
|
||||
size_t data_size = DataTypeGetInfo(data_type)->Size;
|
||||
bool value_changed = memcmp(p_v, &g.ActiveIdValueOnActivation, data_size);
|
||||
memcpy(p_v, &g.ActiveIdValueOnActivation, data_size);
|
||||
ClearActiveID();
|
||||
return value_changed;
|
||||
}
|
||||
}
|
||||
if (g.ActiveId != id)
|
||||
return false;
|
||||
@ -2802,11 +2834,16 @@ bool ImGui::DragScalar(const char* label, ImGuiDataType data_type, void* p_data,
|
||||
MarkItemEdited(id);
|
||||
|
||||
// Display value using user-provided display format so user can add prefix/suffix/decorations to the value.
|
||||
const bool is_mixed = (g.LastItemData.ItemFlags & ImGuiItemFlags_MixedValue) != 0;
|
||||
char value_buf[64];
|
||||
const char* value_buf_end = value_buf + DataTypeFormatString(value_buf, IM_COUNTOF(value_buf), data_type, p_data, format);
|
||||
const char* value_buf_end = value_buf + DataTypeFormatString(value_buf, IM_COUNTOF(value_buf), data_type, p_data, (is_mixed && g.MixedValueLabel != NULL) ? g.MixedValueLabel : format);
|
||||
if (g.LogEnabled)
|
||||
LogSetNextTextDecoration("{", "}");
|
||||
if (is_mixed)
|
||||
PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextMixedValue]);
|
||||
RenderTextClipped(frame_bb.Min, frame_bb.Max, value_buf, value_buf_end, NULL, ImVec2(0.5f, 0.5f));
|
||||
if (is_mixed)
|
||||
PopStyleColor();
|
||||
|
||||
if (label_size.x > 0.0f)
|
||||
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label, label_end, false);
|
||||
@ -3013,7 +3050,7 @@ float ImGui::ScaleRatioFromValueT(ImGuiDataType data_type, TYPE v, TYPE v_min, T
|
||||
result = 0.0f; // Workaround for values that are in-range but below our fudge
|
||||
else if (v_clamped >= v_max_fudged)
|
||||
result = 1.0f; // Workaround for values that are in-range but above our fudge
|
||||
else if ((v_min * v_max) < 0.0f) // Range crosses zero, so split into two portions
|
||||
else if (((FLOATTYPE)v_min * (FLOATTYPE)v_max) < 0.0f) // Range crosses zero, so split into two portions
|
||||
{
|
||||
float zero_point_center = (-(float)v_min) / ((float)v_max - (float)v_min); // The zero point in parametric space. There's an argument we should take the logarithmic nature into account when calculating this, but for now this should do (and the most common case of a symmetrical range works fine)
|
||||
float zero_point_snap_L = zero_point_center - zero_deadzone_halfsize;
|
||||
@ -3067,7 +3104,7 @@ TYPE ImGui::ScaleValueFromRatioT(ImGuiDataType data_type, float t, TYPE v_min, T
|
||||
|
||||
float t_with_flip = flipped ? (1.0f - t) : t; // t, but flipped if necessary to account for us flipping the range
|
||||
|
||||
if ((v_min * v_max) < 0.0f) // Range crosses zero, so we have to do this in two parts
|
||||
if (((FLOATTYPE)v_min * (FLOATTYPE)v_max) < 0.0f) // Range crosses zero, so we have to do this in two parts
|
||||
{
|
||||
float zero_point_center = (-(float)ImMin(v_min, v_max)) / ImAbs((float)v_max - (float)v_min); // The zero point in parametric space
|
||||
float zero_point_snap_L = zero_point_center - zero_deadzone_halfsize;
|
||||
@ -3092,13 +3129,13 @@ TYPE ImGui::ScaleValueFromRatioT(ImGuiDataType data_type, float t, TYPE v_min, T
|
||||
{
|
||||
result = ImLerp(v_min, v_max, t);
|
||||
}
|
||||
else if (t < 1.0)
|
||||
else // t is already < 1.0 here
|
||||
{
|
||||
// - For integer values we want the clicking position to match the grab box so we round above
|
||||
// This code is carefully tuned to work with large values (e.g. high ranges of U64) while preserving this property..
|
||||
// - Not doing a *1.0 multiply at the end of a range as it tends to be lossy. While absolute aiming at a large s64/u64
|
||||
// range is going to be imprecise anyway, with this check we at least make the edge values matches expected limits.
|
||||
FLOATTYPE v_new_off_f = (SIGNEDTYPE)(v_max - v_min) * t;
|
||||
FLOATTYPE v_new_off_f = (FLOATTYPE)(SIGNEDTYPE)(v_max - v_min) * (FLOATTYPE)t;
|
||||
result = (TYPE)((SIGNEDTYPE)v_min + (SIGNEDTYPE)(v_new_off_f + (FLOATTYPE)(v_min > v_max ? -0.5 : 0.5)));
|
||||
}
|
||||
}
|
||||
@ -3147,37 +3184,24 @@ bool ImGui::SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_typ
|
||||
float clicked_t = 0.0f;
|
||||
if (g.ActiveIdSource == ImGuiInputSource_Mouse)
|
||||
{
|
||||
if (!g.IO.MouseDown[0])
|
||||
const float mouse_pos = g.IO.MousePos[axis];
|
||||
if (g.ActiveIdIsJustActivated)
|
||||
{
|
||||
ClearActiveID();
|
||||
}
|
||||
else
|
||||
{
|
||||
const float mouse_abs_pos = g.IO.MousePos[axis];
|
||||
if (g.ActiveIdIsJustActivated)
|
||||
{
|
||||
float grab_t = ScaleRatioFromValueT<TYPE, SIGNEDTYPE, FLOATTYPE>(data_type, *v, v_min, v_max, logarithmic_zero_epsilon, zero_deadzone_halfsize);
|
||||
if (axis == ImGuiAxis_Y)
|
||||
grab_t = 1.0f - grab_t;
|
||||
const float grab_pos = ImLerp(slider_usable_pos_min, slider_usable_pos_max, grab_t);
|
||||
const bool clicked_around_grab = (mouse_abs_pos >= grab_pos - grab_sz * 0.5f - 1.0f) && (mouse_abs_pos <= grab_pos + grab_sz * 0.5f + 1.0f); // No harm being extra generous here.
|
||||
g.SliderGrabClickOffset = (clicked_around_grab && is_floating_point) ? mouse_abs_pos - grab_pos : 0.0f;
|
||||
}
|
||||
if (slider_usable_sz > 0.0f)
|
||||
clicked_t = ImSaturate((mouse_abs_pos - g.SliderGrabClickOffset - slider_usable_pos_min) / slider_usable_sz);
|
||||
float grab_t = ScaleRatioFromValueT<TYPE, SIGNEDTYPE, FLOATTYPE>(data_type, *v, v_min, v_max, logarithmic_zero_epsilon, zero_deadzone_halfsize);
|
||||
if (axis == ImGuiAxis_Y)
|
||||
clicked_t = 1.0f - clicked_t;
|
||||
set_new_value = true;
|
||||
grab_t = 1.0f - grab_t;
|
||||
const float grab_pos = ImLerp(slider_usable_pos_min, slider_usable_pos_max, grab_t);
|
||||
const bool clicked_around_grab = (mouse_pos >= grab_pos - grab_sz * 0.5f - 1.0f) && (mouse_pos <= grab_pos + grab_sz * 0.5f + 1.0f); // No harm being extra generous here.
|
||||
g.SliderGrabClickOffset = (clicked_around_grab && is_floating_point) ? mouse_pos - grab_pos : 0.0f;
|
||||
}
|
||||
if (slider_usable_sz > 0.0f)
|
||||
clicked_t = ImSaturate((mouse_pos - g.SliderGrabClickOffset - slider_usable_pos_min) / slider_usable_sz);
|
||||
if (axis == ImGuiAxis_Y)
|
||||
clicked_t = 1.0f - clicked_t;
|
||||
set_new_value = true;
|
||||
}
|
||||
else if (g.ActiveIdSource == ImGuiInputSource_Keyboard || g.ActiveIdSource == ImGuiInputSource_Gamepad)
|
||||
{
|
||||
if (g.ActiveIdIsJustActivated)
|
||||
{
|
||||
g.SliderCurrentAccum = 0.0f; // Reset any stored nav delta upon activation
|
||||
g.SliderCurrentAccumDirty = false;
|
||||
}
|
||||
|
||||
float input_delta = (axis == ImGuiAxis_X) ? GetNavTweakPressedAmount(axis) : -GetNavTweakPressedAmount(axis);
|
||||
if (input_delta != 0.0f)
|
||||
{
|
||||
@ -3205,11 +3229,7 @@ bool ImGui::SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_typ
|
||||
}
|
||||
|
||||
float delta = g.SliderCurrentAccum;
|
||||
if (g.NavActivatePressedId == id && !g.ActiveIdIsJustActivated)
|
||||
{
|
||||
ClearActiveID();
|
||||
}
|
||||
else if (g.SliderCurrentAccumDirty)
|
||||
if (g.SliderCurrentAccumDirty)
|
||||
{
|
||||
clicked_t = ScaleRatioFromValueT<TYPE, SIGNEDTYPE, FLOATTYPE>(data_type, *v, v_min, v_max, logarithmic_zero_epsilon, zero_deadzone_halfsize);
|
||||
|
||||
@ -3235,7 +3255,6 @@ bool ImGui::SliderBehaviorT(const ImRect& bb, ImGuiID id, ImGuiDataType data_typ
|
||||
else
|
||||
g.SliderCurrentAccum -= ImMax(new_clicked_t - old_clicked_t, delta);
|
||||
}
|
||||
|
||||
g.SliderCurrentAccumDirty = false;
|
||||
}
|
||||
}
|
||||
@ -3290,6 +3309,33 @@ bool ImGui::SliderBehavior(const ImRect& bb, ImGuiID id, ImGuiDataType data_type
|
||||
IM_ASSERT((flags == 1 || (flags & ImGuiSliderFlags_InvalidMask_) == 0) && "Invalid ImGuiSliderFlags flags! Has the legacy 'float power' argument been mistakenly cast to flags? Call function with ImGuiSliderFlags_Logarithmic flags instead.");
|
||||
IM_ASSERT((flags & ImGuiSliderFlags_WrapAround) == 0); // Not supported by SliderXXX(), only by DragXXX()
|
||||
|
||||
// Things we can do easily outside the SliderBehaviorT<> template, saves code generation.
|
||||
ImGuiContext& g = *GImGui;
|
||||
if (g.ActiveId == id)
|
||||
{
|
||||
if (g.ActiveIdSource == ImGuiInputSource_Mouse && !g.IO.MouseDown[0])
|
||||
ClearActiveID();
|
||||
if (g.ActiveIdSource == ImGuiInputSource_Keyboard || g.ActiveIdSource == ImGuiInputSource_Gamepad)
|
||||
{
|
||||
if (g.ActiveIdIsJustActivated)
|
||||
{
|
||||
g.SliderCurrentAccum = 0.0f; // Reset any stored nav delta upon activation
|
||||
g.SliderCurrentAccumDirty = false;
|
||||
}
|
||||
if (g.NavActivatePressedId == id && !g.ActiveIdIsJustActivated)
|
||||
ClearActiveID();
|
||||
}
|
||||
if (ShortcutsForCancel(id) && g.ActiveId == id) //-V560
|
||||
{
|
||||
// Canceling action reverts to initial value
|
||||
size_t data_size = DataTypeGetInfo(data_type)->Size;
|
||||
bool value_changed = memcmp(p_v, &g.ActiveIdValueOnActivation, data_size);
|
||||
memcpy(p_v, &g.ActiveIdValueOnActivation, data_size);
|
||||
ClearActiveID();
|
||||
return value_changed;
|
||||
}
|
||||
}
|
||||
|
||||
switch (data_type)
|
||||
{
|
||||
case ImGuiDataType_S8: { ImS32 v32 = (ImS32)*(ImS8*)p_v; bool r = SliderBehaviorT<ImS32, ImS32, float>(bb, id, ImGuiDataType_S32, &v32, *(const ImS8*)p_min, *(const ImS8*)p_max, format, flags, out_grab_bb); if (r) *(ImS8*)p_v = (ImS8)v32; return r; }
|
||||
@ -3400,11 +3446,16 @@ bool ImGui::SliderScalar(const char* label, ImGuiDataType data_type, void* p_dat
|
||||
window->DrawList->AddRectFilled(grab_bb.Min, grab_bb.Max, GetColorU32(g.ActiveId == id ? ImGuiCol_SliderGrabActive : ImGuiCol_SliderGrab), style.GrabRounding);
|
||||
|
||||
// Display value using user-provided display format so user can add prefix/suffix/decorations to the value.
|
||||
const bool is_mixed = (g.LastItemData.ItemFlags & ImGuiItemFlags_MixedValue) != 0;
|
||||
char value_buf[64];
|
||||
const char* value_buf_end = value_buf + DataTypeFormatString(value_buf, IM_COUNTOF(value_buf), data_type, p_data, format);
|
||||
const char* value_buf_end = value_buf + DataTypeFormatString(value_buf, IM_COUNTOF(value_buf), data_type, p_data, (is_mixed && g.MixedValueLabel != NULL) ? g.MixedValueLabel : format);
|
||||
if (g.LogEnabled)
|
||||
LogSetNextTextDecoration("{", "}");
|
||||
if (is_mixed)
|
||||
PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextMixedValue]);
|
||||
RenderTextClipped(frame_bb.Min, frame_bb.Max, value_buf, value_buf_end, NULL, ImVec2(0.5f, 0.5f));
|
||||
if (is_mixed)
|
||||
PopStyleColor();
|
||||
|
||||
if (label_size.x > 0.0f)
|
||||
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label, label_end, false);
|
||||
@ -3554,9 +3605,15 @@ bool ImGui::VSliderScalar(const char* label, const ImVec2& size, ImGuiDataType d
|
||||
|
||||
// Display value using user-provided display format so user can add prefix/suffix/decorations to the value.
|
||||
// For the vertical slider we allow centered text to overlap the frame padding
|
||||
const bool is_mixed = (g.LastItemData.ItemFlags & ImGuiItemFlags_MixedValue) != 0;
|
||||
char value_buf[64];
|
||||
const char* value_buf_end = value_buf + DataTypeFormatString(value_buf, IM_COUNTOF(value_buf), data_type, p_data, format);
|
||||
const char* value_buf_end = value_buf + DataTypeFormatString(value_buf, IM_COUNTOF(value_buf), data_type, p_data, (is_mixed && g.MixedValueLabel != NULL) ? g.MixedValueLabel : format);
|
||||
if (is_mixed)
|
||||
PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextMixedValue]);
|
||||
RenderTextClipped(ImVec2(frame_bb.Min.x, frame_bb.Min.y + style.FramePadding.y), frame_bb.Max, value_buf, value_buf_end, NULL, ImVec2(0.5f, 0.0f));
|
||||
if (is_mixed)
|
||||
PopStyleColor();
|
||||
|
||||
if (label_size.x > 0.0f)
|
||||
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label, label_end, false);
|
||||
|
||||
@ -3794,6 +3851,10 @@ bool ImGui::TempInputScalar(const ImRect& bb, ImGuiID id, const char* label, ImG
|
||||
// Only mark as edited if new value is different
|
||||
g.LastItemData.ItemFlags &= ~ImGuiItemFlags_NoMarkEdited;
|
||||
bool value_changed = memcmp(&data_backup, p_data, data_type_size) != 0;
|
||||
if (g.LastItemData.ItemFlags & ImGuiItemFlags_MixedValue)
|
||||
if (ImGuiInputTextState* state = GetInputTextState(g.LastItemData.ID))
|
||||
value_changed |= (g.LastItemData.ItemFlags & ImGuiItemFlags_LiveEditOnInputScalar) ? (state->EditedThisFrame | state->ValidatedThisFrame) : state->ValidatedThisFrame;
|
||||
|
||||
if (value_changed)
|
||||
MarkItemEdited(id);
|
||||
return value_changed;
|
||||
@ -3870,6 +3931,9 @@ bool ImGui::InputScalar(const char* label, ImGuiDataType data_type, void* p_data
|
||||
value_changed = DataTypeApplyFromText(buf, data_type, p_data, format, (flags & ImGuiInputTextFlags_ParseEmptyRefVal) ? p_data_default : NULL);
|
||||
}
|
||||
}
|
||||
if (g.LastItemData.ItemFlags & ImGuiItemFlags_MixedValue)
|
||||
if (ImGuiInputTextState* state = GetInputTextState(g.LastItemData.ID))
|
||||
value_changed |= (g.LastItemData.ItemFlags & ImGuiItemFlags_LiveEditOnInputScalar) ? (state->EditedThisFrame | state->ValidatedThisFrame) : state->ValidatedThisFrame;
|
||||
|
||||
// Step buttons
|
||||
if (has_step_buttons)
|
||||
@ -4835,6 +4899,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
const bool is_password = (flags & ImGuiInputTextFlags_Password) != 0;
|
||||
const bool is_undoable = (flags & ImGuiInputTextFlags_NoUndoRedo) == 0;
|
||||
const bool is_resizable = (flags & ImGuiInputTextFlags_CallbackResize) != 0;
|
||||
const bool is_mixed = (g.LastItemData.ItemFlags & ImGuiItemFlags_MixedValue) != 0;
|
||||
if (is_resizable)
|
||||
IM_ASSERT(callback != NULL); // Must provide a callback if you set the ImGuiInputTextFlags_CallbackResize flag!
|
||||
|
||||
@ -4921,7 +4986,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
|
||||
if (!is_multiline)
|
||||
{
|
||||
if (flags & ImGuiInputTextFlags_AutoSelectAll)
|
||||
if ((flags & ImGuiInputTextFlags_AutoSelectAll) || is_mixed)
|
||||
select_all = true;
|
||||
if (input_requested_by_nav && (!recycle_state || !(g.NavActivateFlags & ImGuiActivateFlags_TryToPreserveState)))
|
||||
select_all = true;
|
||||
@ -4999,7 +5064,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
|
||||
// Select the buffer to render.
|
||||
const bool buf_display_from_state = (render_cursor || render_selection || g.ActiveId == id) && !is_readonly && state;
|
||||
bool is_displaying_hint = (hint != NULL && (buf_display_from_state ? state->TextA.Data : buf)[0] == 0);
|
||||
bool is_displaying_hint = (hint != NULL && (buf_display_from_state ? state->TextA.Data : buf)[0] == 0) && !is_mixed;
|
||||
|
||||
// Password pushes a temporary font with only a fallback glyph
|
||||
if (is_password && !is_displaying_hint)
|
||||
@ -5008,6 +5073,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
if (state != NULL && state->ID == id)
|
||||
{
|
||||
state->Flags = flags;
|
||||
state->EditedThisFrame = state->ValidatedThisFrame = false;
|
||||
//state->LastFrameActive = g.FrameCount;
|
||||
|
||||
// Word-wrapping: attempt to keep cursor in view while resizing frame/parent (FIXME-WORDWRAP: would be better to preserve same relative offset)
|
||||
@ -5023,7 +5089,6 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
if (g.ActiveId == id)
|
||||
{
|
||||
IM_ASSERT(state != NULL);
|
||||
state->EditedThisFrame = false;
|
||||
state->BufCapacity = buf_size;
|
||||
state->WrapWidth = wrap_width;
|
||||
|
||||
@ -5426,7 +5491,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
if (g.LastItemData.ItemFlags & ImGuiItemFlags_LiveEditOnInputText)
|
||||
{
|
||||
// Apply when modified
|
||||
if (strcmp(state->TextSrc, buf) != 0)
|
||||
if (strcmp(state->TextSrc, buf) != 0 || (is_mixed && (state->EditedThisFrame || validated)))
|
||||
{
|
||||
apply_new_text = state->TextSrc;
|
||||
apply_new_text_length = state->TextLen;
|
||||
@ -5436,7 +5501,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
else
|
||||
{
|
||||
// Apply on validation/deactivation, otherwise cancel out previous apply attempts (e.g. revert)
|
||||
value_changed = ((validated || clear_active_id || revert_edit) && strcmp(state->TextSrc, buf) != 0);
|
||||
value_changed = (validated || clear_active_id || revert_edit) && (strcmp(state->TextSrc, buf) != 0 || (is_mixed && validated));
|
||||
apply_new_text = value_changed ? state->TextSrc : NULL;
|
||||
apply_new_text_length = value_changed ? state->TextLen : 0;
|
||||
}
|
||||
@ -5521,7 +5586,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
|
||||
// Display hint when contents is empty
|
||||
// At this point we need to handle the possibility that a callback could have modified the underlying buffer (#8368)
|
||||
const bool new_is_displaying_hint = (hint != NULL && (buf_display_from_state ? state->TextA.Data : buf)[0] == 0);
|
||||
const bool new_is_displaying_hint = (hint != NULL && (buf_display_from_state ? state->TextA.Data : buf)[0] == 0) && !is_mixed;
|
||||
if (new_is_displaying_hint != is_displaying_hint)
|
||||
{
|
||||
if (is_password && !is_displaying_hint)
|
||||
@ -5530,10 +5595,17 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
if (is_password && !is_displaying_hint)
|
||||
PushPasswordFont();
|
||||
}
|
||||
if (is_displaying_hint)
|
||||
const bool is_displaying_mixed = is_mixed && g.ActiveId != id && apply_new_text == NULL;
|
||||
if (is_displaying_mixed && g.MixedValueLabel != NULL)
|
||||
{
|
||||
buf_display = g.MixedValueLabel;
|
||||
buf_display_end = buf_display + strlen(g.MixedValueLabel);
|
||||
render_cursor = render_selection = false;
|
||||
}
|
||||
else if (is_displaying_hint)
|
||||
{
|
||||
buf_display = hint;
|
||||
buf_display_end = hint + ImStrlen(hint);
|
||||
buf_display_end = buf_display + ImStrlen(buf_display);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -5573,7 +5645,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
ImVec2 draw_scroll;
|
||||
|
||||
// Render text. We currently only render selection when the widget is active or while scrolling.
|
||||
const ImU32 text_col = GetColorU32(is_displaying_hint ? ImGuiCol_TextDisabled : ImGuiCol_Text);
|
||||
const ImU32 text_col = GetColorU32(is_displaying_mixed ? ImGuiCol_TextMixedValue : is_displaying_hint ? ImGuiCol_TextDisabled : ImGuiCol_Text);
|
||||
if (render_cursor || render_selection)
|
||||
{
|
||||
// Render text (with cursor and selection)
|
||||
@ -5746,6 +5818,8 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
|
||||
if (label_size.x > 0)
|
||||
RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label, label_end, false);
|
||||
|
||||
if (state && validated)
|
||||
state->ValidatedThisFrame = true;
|
||||
if (value_changed)
|
||||
MarkItemEdited(id);
|
||||
|
||||
@ -6022,7 +6096,9 @@ bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flag
|
||||
ImGuiColorEditFlags picker_flags_to_forward = ImGuiColorEditFlags_DataTypeMask_ | ImGuiColorEditFlags_PickerMask_ | ImGuiColorEditFlags_InputMask_ | ImGuiColorEditFlags_HDR | ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_AlphaBar;
|
||||
ImGuiColorEditFlags picker_flags = (flags_untouched & picker_flags_to_forward) | ImGuiColorEditFlags_DisplayMask_ | ImGuiColorEditFlags_NoLabel | ImGuiColorEditFlags_AlphaPreviewHalf;
|
||||
SetNextItemWidth(square_sz * 12.0f); // Use 256 + bar sizes?
|
||||
PushItemFlag(ImGuiItemFlags_MixedValue, false);
|
||||
value_changed |= ColorPicker4("##picker", col, picker_flags, &g.ColorPickerRef.x);
|
||||
PopItemFlag();
|
||||
}
|
||||
EndPopup();
|
||||
}
|
||||
@ -6136,6 +6212,10 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl
|
||||
const bool is_readonly = ((g.NextItemData.ItemFlagsSet | g.CurrentItemFlags) & ImGuiItemFlags_ReadOnly) != 0;
|
||||
g.NextItemData.ClearFlags();
|
||||
|
||||
const float backup_alpha = g.Style.Alpha;
|
||||
if (g.DisabledStackSize > 0)
|
||||
g.Style.Alpha = g.DisabledAlphaBackup; // Cancel out effect of BeginDisabled() for color swatches.
|
||||
|
||||
PushID(label);
|
||||
const bool set_current_color_edit_id = (g.ColorEditCurrentID == 0);
|
||||
if (set_current_color_edit_id)
|
||||
@ -6293,6 +6373,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl
|
||||
if (!(flags & ImGuiColorEditFlags_NoSidePreview))
|
||||
{
|
||||
PushItemFlag(ImGuiItemFlags_NoNavDefaultFocus, true);
|
||||
PushItemFlag(ImGuiItemFlags_MixedValue, false);
|
||||
ImVec4 col_v4(col[0], col[1], col[2], (flags & ImGuiColorEditFlags_NoAlpha) ? 1.0f : col[3]);
|
||||
if ((flags & ImGuiColorEditFlags_NoLabel))
|
||||
Text("Current");
|
||||
@ -6310,6 +6391,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl
|
||||
}
|
||||
}
|
||||
PopItemFlag();
|
||||
PopItemFlag();
|
||||
EndGroup();
|
||||
}
|
||||
|
||||
@ -6475,7 +6557,7 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl
|
||||
{
|
||||
float alpha = ImSaturate(col[3]);
|
||||
ImRect bar1_bb(bar1_pos_x, picker_pos.y, bar1_pos_x + bars_width, picker_pos.y + sv_picker_size);
|
||||
RenderColorRectWithAlphaCheckerboard(draw_list, bar1_bb.Min, bar1_bb.Max, 0, bar1_bb.GetWidth() / 2.0f, ImVec2(0.0f, 0.0f));
|
||||
RenderColorRectWithAlphaCheckerboard(draw_list, bar1_bb.Min, bar1_bb.Max, IM_COL32(0,0,0,0), style.Alpha, bar1_bb.GetWidth() / 2.0f, ImVec2(0.0f, 0.0f));
|
||||
draw_list->AddRectFilledMultiColor(bar1_bb.Min, bar1_bb.Max, user_col32_striped_of_alpha, user_col32_striped_of_alpha, user_col32_striped_of_alpha & ~IM_COL32_A_MASK, user_col32_striped_of_alpha & ~IM_COL32_A_MASK);
|
||||
float bar1_line_y = IM_ROUND(picker_pos.y + (1.0f - alpha) * sv_picker_size);
|
||||
RenderFrameBorder(bar1_bb.Min, bar1_bb.Max, 0.0f);
|
||||
@ -6493,6 +6575,9 @@ bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags fl
|
||||
g.ColorEditCurrentID = 0;
|
||||
PopID();
|
||||
|
||||
if (g.DisabledStackSize > 0)
|
||||
g.Style.Alpha = backup_alpha;
|
||||
|
||||
return value_changed;
|
||||
}
|
||||
|
||||
@ -6525,34 +6610,42 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl
|
||||
if (flags & ImGuiColorEditFlags_InputHSV)
|
||||
ColorConvertHSVtoRGB(col_rgb.x, col_rgb.y, col_rgb.z, col_rgb.x, col_rgb.y, col_rgb.z);
|
||||
|
||||
ImVec4 col_rgb_without_alpha(col_rgb.x, col_rgb.y, col_rgb.z, 1.0f);
|
||||
float grid_step = ImMin(size.x, size.y) / 2.99f;
|
||||
float rounding = ImMin(g.Style.FrameRounding, grid_step * 0.5f);
|
||||
ImRect bb_inner = bb;
|
||||
float off = 0.0f;
|
||||
if ((flags & ImGuiColorEditFlags_NoBorder) == 0)
|
||||
const ImVec4 col_rgb_without_alpha(col_rgb.x, col_rgb.y, col_rgb.z, 1.0f);
|
||||
const float grid_step = ImMin(size.x, size.y) / 2.99f;
|
||||
const float rounding = ImMin(g.Style.FrameRounding, grid_step * 0.5f);
|
||||
const bool is_mixed = (g.LastItemData.ItemFlags & ImGuiItemFlags_MixedValue) != 0;
|
||||
|
||||
const float backup_alpha = g.Style.Alpha;
|
||||
if (g.DisabledStackSize > 0)
|
||||
g.Style.Alpha = g.DisabledAlphaBackup; // Cancel out effect of BeginDisabled() for color swatches.
|
||||
if (is_mixed)
|
||||
{
|
||||
off = -0.75f; // The border (using Col_FrameBg) tends to look off when color is near-opaque and rounding is enabled. This offset seemed like a good middle ground to reduce those artifacts.
|
||||
bb_inner.Expand(off);
|
||||
window->DrawList->AddRectFilled(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg), rounding);
|
||||
PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextMixedValue]);
|
||||
if (g.MixedValueLabel != NULL)
|
||||
RenderTextClipped(ImVec2(bb.Min.x, bb.Min.y + g.Style.FramePadding.y), bb.Max, g.MixedValueLabel, NULL, NULL, ImVec2(0.5f, 0.0f));
|
||||
PopStyleColor();
|
||||
}
|
||||
if ((flags & ImGuiColorEditFlags_AlphaPreviewHalf) && col_rgb.w < 1.0f)
|
||||
else if ((flags & ImGuiColorEditFlags_AlphaPreviewHalf) && col_rgb.w < 1.0f)
|
||||
{
|
||||
float mid_x = IM_ROUND((bb_inner.Min.x + bb_inner.Max.x) * 0.5f);
|
||||
float mid_x = IM_ROUND((bb.Min.x + bb.Max.x) * 0.5f);
|
||||
if ((flags & ImGuiColorEditFlags_AlphaNoBg) == 0)
|
||||
RenderColorRectWithAlphaCheckerboard(window->DrawList, ImVec2(bb_inner.Min.x + grid_step, bb_inner.Min.y), bb_inner.Max, GetColorU32(col_rgb), grid_step, ImVec2(-grid_step + off, off), rounding, ImDrawFlags_RoundCornersRight);
|
||||
RenderColorRectWithAlphaCheckerboard(window->DrawList, ImVec2(bb.Min.x + grid_step, bb.Min.y), bb.Max, ColorConvertFloat4ToU32(col_rgb), g.Style.Alpha, grid_step, ImVec2(-grid_step, 0.0f), rounding, ImDrawFlags_RoundCornersRight);
|
||||
else
|
||||
window->DrawList->AddRectFilled(ImVec2(bb_inner.Min.x + grid_step, bb_inner.Min.y), bb_inner.Max, GetColorU32(col_rgb), rounding, ImDrawFlags_RoundCornersRight);
|
||||
window->DrawList->AddRectFilled(bb_inner.Min, ImVec2(mid_x, bb_inner.Max.y), GetColorU32(col_rgb_without_alpha), rounding, ImDrawFlags_RoundCornersLeft);
|
||||
window->DrawList->AddRectFilled(ImVec2(bb.Min.x + grid_step, bb.Min.y), bb.Max, GetColorU32(col_rgb), rounding, ImDrawFlags_RoundCornersRight);
|
||||
window->DrawList->AddRectFilled(bb.Min, ImVec2(mid_x, bb.Max.y), GetColorU32(col_rgb_without_alpha), rounding, ImDrawFlags_RoundCornersLeft);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Because GetColorU32() multiplies by the global style Alpha and we don't want to display a checkerboard if the source code had no alpha
|
||||
ImVec4 col_source = (flags & ImGuiColorEditFlags_AlphaOpaque) ? col_rgb_without_alpha : col_rgb;
|
||||
if (col_source.w < 1.0f && (flags & ImGuiColorEditFlags_AlphaNoBg) == 0)
|
||||
RenderColorRectWithAlphaCheckerboard(window->DrawList, bb_inner.Min, bb_inner.Max, GetColorU32(col_source), grid_step, ImVec2(off, off), rounding);
|
||||
RenderColorRectWithAlphaCheckerboard(window->DrawList, bb.Min, bb.Max, ColorConvertFloat4ToU32(col_source), g.Style.Alpha, grid_step, ImVec2(0.0f, 0.0f), rounding);
|
||||
else
|
||||
window->DrawList->AddRectFilled(bb_inner.Min, bb_inner.Max, GetColorU32(col_source), rounding);
|
||||
window->DrawList->AddRectFilled(bb.Min, bb.Max, GetColorU32(col_source), rounding);
|
||||
}
|
||||
if (g.DisabledStackSize > 0)
|
||||
g.Style.Alpha = backup_alpha;
|
||||
RenderNavCursor(bb, id);
|
||||
if ((flags & ImGuiColorEditFlags_NoBorder) == 0)
|
||||
{
|
||||
@ -6570,7 +6663,9 @@ bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFl
|
||||
SetDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_3F, &col_rgb, sizeof(float) * 3, ImGuiCond_Once);
|
||||
else
|
||||
SetDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_4F, &col_rgb, sizeof(float) * 4, ImGuiCond_Once);
|
||||
PushItemFlag(ImGuiItemFlags_MixedValue, false);
|
||||
ColorButton(desc_id, col, flags);
|
||||
PopItemFlag();
|
||||
SameLine();
|
||||
TextEx("Color");
|
||||
EndDragDropSource();
|
||||
@ -6614,7 +6709,9 @@ void ImGui::ColorTooltip(const char* text, const float* col, ImGuiColorEditFlags
|
||||
ImVec4 cf(col[0], col[1], col[2], (flags & ImGuiColorEditFlags_NoAlpha) ? 1.0f : col[3]);
|
||||
int cr = IM_F32_TO_INT8_SAT(col[0]), cg = IM_F32_TO_INT8_SAT(col[1]), cb = IM_F32_TO_INT8_SAT(col[2]), ca = (flags & ImGuiColorEditFlags_NoAlpha) ? 255 : IM_F32_TO_INT8_SAT(col[3]);
|
||||
ImGuiColorEditFlags flags_to_forward = ImGuiColorEditFlags_InputMask_ | ImGuiColorEditFlags_AlphaMask_;
|
||||
PushItemFlag(ImGuiItemFlags_MixedValue, false);
|
||||
ColorButton("##preview", cf, (flags & flags_to_forward) | ImGuiColorEditFlags_NoTooltip, sz);
|
||||
PopItemFlag();
|
||||
SameLine();
|
||||
if ((flags & ImGuiColorEditFlags_InputRGB) || !(flags & ImGuiColorEditFlags_InputMask_))
|
||||
{
|
||||
@ -6896,7 +6993,7 @@ bool ImGui::TreeNodeUpdateNextOpen(ImGuiID storage_id, ImGuiTreeNodeFlags flags)
|
||||
}
|
||||
|
||||
// Store ImGuiTreeNodeStackData for just submitted node.
|
||||
// Currently only supports 32 level deep and we are fine with (1 << Depth) overflowing into a zero, easy to increase.
|
||||
// Currently only supports 32 level deep. Easy to increase to e.g. 64.
|
||||
static void TreeNodeStoreStackData(ImGuiTreeNodeFlags flags, float x1)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
@ -6919,6 +7016,9 @@ static void TreeNodeStoreStackData(ImGuiTreeNodeFlags flags, float x1)
|
||||
window->DC.TreeRecordsClippedNodesY2Mask |= (1 << window->DC.TreeDepth);
|
||||
}
|
||||
|
||||
#define TREE_NODE_MAX_DEPTH 32
|
||||
#define TREE_NODE_GET_DEPTH_MASK(_DEPTH) (((ImU32)(_DEPTH) < TREE_NODE_MAX_DEPTH) ? (1u << (_DEPTH)) : 0u)
|
||||
|
||||
bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* label, const char* label_end)
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindow();
|
||||
@ -6995,7 +7095,7 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
||||
if ((flags & ImGuiTreeNodeFlags_DrawLinesMask_) == 0)
|
||||
flags |= g.Style.TreeLinesFlags;
|
||||
const bool draw_tree_lines = (flags & (ImGuiTreeNodeFlags_DrawLinesFull | ImGuiTreeNodeFlags_DrawLinesToNodes)) && (frame_bb.Min.y < window->ClipRect.Max.y) && (g.Style.TreeLinesSize > 0.0f);
|
||||
if (!(flags & ImGuiTreeNodeFlags_NoTreePushOnOpen))
|
||||
if (!(flags & ImGuiTreeNodeFlags_NoTreePushOnOpen) && window->DC.TreeDepth < TREE_NODE_MAX_DEPTH)
|
||||
{
|
||||
store_tree_node_stack_data = draw_tree_lines;
|
||||
if ((flags & ImGuiTreeNodeFlags_NavLeftJumpsToParent) && !g.NavIdIsAlive)
|
||||
@ -7006,12 +7106,16 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
|
||||
const bool is_leaf = (flags & ImGuiTreeNodeFlags_Leaf) != 0;
|
||||
if (!is_visible)
|
||||
{
|
||||
if ((flags & ImGuiTreeNodeFlags_DrawLinesToNodes) && (window->DC.TreeRecordsClippedNodesY2Mask & (1 << (window->DC.TreeDepth - 1))))
|
||||
if (flags & ImGuiTreeNodeFlags_DrawLinesToNodes)
|
||||
{
|
||||
ImGuiTreeNodeStackData* parent_data = &g.TreeNodeStack.Data[g.TreeNodeStack.Size - 1];
|
||||
parent_data->DrawLinesToNodesY2 = ImMax(parent_data->DrawLinesToNodesY2, window->DC.CursorPos.y); // Don't need to aim to mid Y position as we are clipped anyway.
|
||||
if (frame_bb.Min.y >= window->ClipRect.Max.y)
|
||||
window->DC.TreeRecordsClippedNodesY2Mask &= ~(1 << (window->DC.TreeDepth - 1)); // Done
|
||||
const ImU32 tree_depth_mask = TREE_NODE_GET_DEPTH_MASK(window->DC.TreeDepth - 1);
|
||||
if (window->DC.TreeRecordsClippedNodesY2Mask & tree_depth_mask)
|
||||
{
|
||||
ImGuiTreeNodeStackData* parent_data = &g.TreeNodeStack.Data[g.TreeNodeStack.Size - 1];
|
||||
parent_data->DrawLinesToNodesY2 = ImMax(parent_data->DrawLinesToNodesY2, window->DC.CursorPos.y); // Don't need to aim to mid Y position as we are clipped anyway.
|
||||
if (frame_bb.Min.y >= window->ClipRect.Max.y)
|
||||
window->DC.TreeRecordsClippedNodesY2Mask &= ~tree_depth_mask; // Done
|
||||
}
|
||||
}
|
||||
if (is_open && store_tree_node_stack_data)
|
||||
TreeNodeStoreStackData(flags, text_pos.x - text_offset_x); // Call before TreePushOverrideID()
|
||||
@ -7208,7 +7312,7 @@ void ImGui::TreeNodeDrawLineToChildNode(const ImVec2& target_pos)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindow* window = g.CurrentWindow;
|
||||
if (window->DC.TreeDepth == 0 || (window->DC.TreeHasStackDataDepthMask & (1 << (window->DC.TreeDepth - 1))) == 0)
|
||||
if ((window->DC.TreeHasStackDataDepthMask & TREE_NODE_GET_DEPTH_MASK(window->DC.TreeDepth - 1)) == 0)
|
||||
return;
|
||||
|
||||
ImGuiTreeNodeStackData* parent_data = &g.TreeNodeStack.Data[g.TreeNodeStack.Size - 1];
|
||||
@ -7292,8 +7396,7 @@ void ImGui::TreePop()
|
||||
Unindent();
|
||||
|
||||
window->DC.TreeDepth--;
|
||||
ImU32 tree_depth_mask = (1 << window->DC.TreeDepth);
|
||||
|
||||
ImU32 tree_depth_mask = TREE_NODE_GET_DEPTH_MASK(window->DC.TreeDepth);
|
||||
if (window->DC.TreeHasStackDataDepthMask & tree_depth_mask)
|
||||
{
|
||||
const ImGuiTreeNodeStackData* data = &g.TreeNodeStack.Data[g.TreeNodeStack.Size - 1];
|
||||
@ -7520,7 +7623,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
|
||||
// - (1) it would require focus scope to be set, need exposing PushFocusScope() or equivalent (e.g. BeginSelection() calling PushFocusScope())
|
||||
// - (2) usage will fail with clipped items
|
||||
// The multi-select API aim to fix those issues, e.g. may be replaced with a BeginSelection() API.
|
||||
if ((flags & ImGuiSelectableFlags_SelectOnNav) && g.NavJustMovedToId != 0 && g.NavJustMovedToFocusScopeId == g.CurrentFocusScopeId)
|
||||
if ((flags & ImGuiSelectableFlags_SelectOnNav) && g.NavJustMovedToId != 0 && g.NavJustMovedToFocusScopeId == g.CurrentFocusScopeId && !g.NavJustMovedToIsInit)
|
||||
if (g.NavJustMovedToId == id && (g.NavJustMovedToKeyMods & ImGuiMod_Ctrl) == 0)
|
||||
selected = pressed = auto_selected = true;
|
||||
}
|
||||
@ -10132,16 +10235,17 @@ static void ImGui::TabBarLayout(ImGuiTabBar* tab_bar)
|
||||
}
|
||||
|
||||
// Horizontal scrolling buttons
|
||||
// Important: note that TabBarScrollButtons() will alter BarRect.Max.x.
|
||||
// - Important: note that TabBarScrollButtons() will alter BarRect.Max.x.
|
||||
// - Selection skips buttons and might cross through sections if there are Tabs in Leading/Trailing sections.
|
||||
const bool can_scroll = (tab_bar->Flags & ImGuiTabBarFlags_FittingPolicyScroll) || (tab_bar->Flags & ImGuiTabBarFlags_FittingPolicyMixed);
|
||||
const float width_all_tabs_to_use_for_scroll = (tab_bar->Flags & ImGuiTabBarFlags_FittingPolicyScroll) ? tab_bar->WidthAllTabs : width_all_tabs_after_min_width_shrink;
|
||||
tab_bar->ScrollButtonEnabled = ((width_all_tabs_to_use_for_scroll > tab_bar->BarRect.GetWidth() && tab_bar->Tabs.Size > 1) && !(tab_bar->Flags & ImGuiTabBarFlags_NoTabListScrollingButtons) && can_scroll);
|
||||
if (tab_bar->ScrollButtonEnabled)
|
||||
if (ImGuiTabItem* scroll_and_select_tab = TabBarScrollingButtons(tab_bar))
|
||||
{
|
||||
scroll_to_tab_id = scroll_and_select_tab->ID;
|
||||
if ((scroll_and_select_tab->Flags & ImGuiTabItemFlags_Button) == 0)
|
||||
tab_bar->SelectedTabId = scroll_to_tab_id;
|
||||
tab_bar->SelectedTabId = scroll_and_select_tab->ID;
|
||||
scroll_to_tab_id = scroll_and_select_tab->ID;
|
||||
}
|
||||
if (scroll_to_tab_id == 0 && scroll_to_selected_tab)
|
||||
scroll_to_tab_id = tab_bar->SelectedTabId;
|
||||
@ -10334,6 +10438,14 @@ const char* ImGui::TabBarGetTabName(ImGuiTabBar* tab_bar, ImGuiTabItem* tab)
|
||||
return tab_bar->TabsNames.Buf.Data + tab->NameOffset;
|
||||
}
|
||||
|
||||
ImVec2 ImGui::TabBarGetTabPos(ImGuiTabBar* tab_bar, ImGuiTabItem* tab)
|
||||
{
|
||||
if ((tab->Flags & ImGuiTabItemFlags_SectionMask_) == 0)
|
||||
return tab_bar->BarRect.Min + ImVec2(IM_TRUNC(tab->Offset - tab_bar->ScrollingAnim), 0.0f);
|
||||
else
|
||||
return tab_bar->BarRect.Min + ImVec2(tab->Offset, 0.0f);
|
||||
}
|
||||
|
||||
// The purpose of this call is to register tab in advance so we can control their order at the time they appear.
|
||||
// Otherwise calling this is unnecessary as tabs are appending as needed by the BeginTabItem() function.
|
||||
void ImGui::TabBarAddTab(ImGuiTabBar* tab_bar, ImGuiTabItemFlags tab_flags, ImGuiWindow* window)
|
||||
@ -10402,11 +10514,20 @@ static void ImGui::TabBarScrollToTab(ImGuiTabBar* tab_bar, ImGuiID tab_id, ImGui
|
||||
ImGuiTabItem* tab = TabBarFindTabByID(tab_bar, tab_id);
|
||||
if (tab == NULL)
|
||||
return;
|
||||
|
||||
// Clamp attempt to scroll to leading/trailing sections items.
|
||||
// This could be done at the TabBarScrollingButtons() call site as well, but here works.
|
||||
if (tab->Flags & ImGuiTabItemFlags_Leading)
|
||||
tab = &tab_bar->Tabs[sections[0].TabCount];
|
||||
else if (tab->Flags & ImGuiTabItemFlags_Trailing)
|
||||
tab = &tab_bar->Tabs[sections[0].TabCount + sections[1].TabCount];
|
||||
if (tab->Flags & ImGuiTabItemFlags_SectionMask_)
|
||||
return;
|
||||
|
||||
// When scrolling to make Tab N+1 visible always make a bit of N visible to suggest more scrolling area (since we don't have a scrollbar)
|
||||
// Disable the margin if the scrolling section is too small for the target tab: prefer displaying a maximum of the label.
|
||||
ImGuiContext& g = *GImGui;
|
||||
float margin = g.FontSize * 1.0f; // When to scroll to make Tab N+1 visible always make a bit of N visible to suggest more scrolling area (since we don't have a scrollbar)
|
||||
float margin = ImClamp(tab_bar->ScrollingRectMaxX - tab_bar->ScrollingRectMinX - tab->Width, g.Style.ItemInnerSpacing.x, g.FontSize * 1.0f);
|
||||
int order = TabBarGetTabOrder(tab_bar, tab);
|
||||
|
||||
// Scrolling happens only in the central section (leading/trailing sections are not scrolling)
|
||||
@ -10811,10 +10932,7 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
|
||||
// Layout
|
||||
const bool is_central_section = (tab->Flags & ImGuiTabItemFlags_SectionMask_) == 0;
|
||||
size.x = tab->Width;
|
||||
if (is_central_section)
|
||||
window->DC.CursorPos = tab_bar->BarRect.Min + ImVec2(IM_TRUNC(tab->Offset - tab_bar->ScrollingAnim), 0.0f);
|
||||
else
|
||||
window->DC.CursorPos = tab_bar->BarRect.Min + ImVec2(tab->Offset, 0.0f);
|
||||
window->DC.CursorPos = TabBarGetTabPos(tab_bar, tab);
|
||||
ImVec2 pos = window->DC.CursorPos;
|
||||
ImRect bb(pos, pos + size);
|
||||
|
||||
|
||||
@ -1,12 +1,14 @@
|
||||
|
||||
HELPER FILES FOR POPULAR DEBUGGERS
|
||||
-----------------------------------------------------------------------------
|
||||
HELPER FILES FOR POPULAR DEBUGGERS
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
imgui.gdb
|
||||
GDB: disable stepping into trivial functions.
|
||||
GDB: disable stepping into trivial functions (*1).
|
||||
(read comments inside file for details)
|
||||
|
||||
imgui.natstepfilter
|
||||
Visual Studio Debugger: disable stepping into trivial functions.
|
||||
Visual Studio Debugger: disable stepping into trivial functions (*1).
|
||||
(read comments inside file for details)
|
||||
|
||||
imgui.natvis
|
||||
@ -15,7 +17,23 @@ imgui.natvis
|
||||
(read comments inside file for details)
|
||||
|
||||
imgui_lldb.py
|
||||
LLDB-based debuggers (*): synthetic children provider and summaries for Dear ImGui types.
|
||||
LLDB-based debuggers (*2): synthetic children provider and summaries for Dear ImGui types.
|
||||
With this, types like ImVector<> will be displayed nicely in the debugger.
|
||||
(read comments inside file for details)
|
||||
(*) Xcode, Android Studio, may be used from VS Code, C++Builder, CLion, Eclipse etc.
|
||||
(*2) Xcode, Android Studio, may be used from VS Code, C++Builder, CLion, Eclipse etc.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
NEW! DISABLED STEPPING INTO TRIVIAL FUNCTIONS
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
Since 1.93.0 WIP (September 2026),
|
||||
Dear ImGui uses a IM_NODEBUGSTEP macro to tag functions with __declspec(non_user_code)
|
||||
or [[gnu::artificial]] to automatically tell debuggers to skip them.
|
||||
|
||||
(*1) Assuming the new IM_NODEBUGSTEP macro works, using imgui.natstepfilter etc.
|
||||
may become unnecessary. Exact side effects on user experience yet to be clarified.
|
||||
|
||||
Additional references:
|
||||
https://maskray.me/blog/skipping-boring-functions-in-debuggers
|
||||
and https://news.ycombinator.com/item?id=42547576
|
||||
|
||||
|
||||
@ -9,4 +9,5 @@
|
||||
# * https://sourceware.org/gdb/current/onlinedocs/gdb/Init-File-in-the-Current-Directory.html#Init-File-in-the-Current-Directory
|
||||
|
||||
# Disable stepping into trivial functions
|
||||
# ...since Dear ImGui 1.93.0 WIP (September 2026): we use a IM_NODEBUGSTEP() macro to provide the equivalent feature via [[gnu::artificial]].
|
||||
skip -rfunction Im(Vec2|Vec4|Strv|Vector|Span)::.+
|
||||
|
||||
@ -14,6 +14,8 @@ If you have multiple VS version installed, the version that matters is the one y
|
||||
of (not the compiling toolset). This is supported since Visual Studio 2012.
|
||||
|
||||
More information at: https://docs.microsoft.com/en-us/visualstudio/debugger/just-my-code?view=vs-2019#BKMK_C___Just_My_Code
|
||||
|
||||
Since Dear ImGui 1.93.0 WIP (September 2026): we use a IM_NODEBUGSTEP() macro to provide the equivalent feature via __declspec(non_user_code).
|
||||
-->
|
||||
|
||||
<StepFilter xmlns="http://schemas.microsoft.com/vstudio/debugger/natstepfilter/2010">
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
// dear imgui: single-file wrapper include
|
||||
// We use this to validate compiling all *.cpp files in a same compilation unit.
|
||||
// Users of that technique (also called "Unity builds") can generally provide this themselves,
|
||||
// so we don't really recommend you use this in your projects.
|
||||
// Users of that technique (also called "Unity builds") can generally provide this themselves easily.
|
||||
|
||||
// Do this:
|
||||
// #define IMGUI_IMPLEMENTATION
|
||||
// Before you include this file in *one* C++ file to create the implementation.
|
||||
// #include "imgui_single_file.h"
|
||||
// In *one* C++ file to create the implementation.
|
||||
// Using this in your project will leak the contents of imgui_internal.h and ImVec2 operators in this compilation unit.
|
||||
|
||||
#ifdef IMGUI_IMPLEMENTATION
|
||||
#if defined(IMGUI_IMPLEMENTATION) && !defined(IMGUI_DEFINE_MATH_OPERATORS)
|
||||
#define IMGUI_DEFINE_MATH_OPERATORS
|
||||
#endif
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user