From e3033c397503f85bdc6eb82c75c0a381cebaac96 Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 24 Apr 2026 17:38:51 +0200 Subject: [PATCH 1/7] Examples: moving example_win32_directx11 on top of the .sln makes it the default selected project. --- examples/imgui_examples.sln | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/imgui_examples.sln b/examples/imgui_examples.sln index 96087aeac..3deffd150 100644 --- a/examples/imgui_examples.sln +++ b/examples/imgui_examples.sln @@ -3,12 +3,12 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.2.32616.157 MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_win32_directx11", "example_win32_directx11\example_win32_directx11.vcxproj", "{9F316E83-5AE5-4939-A723-305A94F48005}" +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_win32_directx9", "example_win32_directx9\example_win32_directx9.vcxproj", "{4165A294-21F2-44CA-9B38-E3F935ABADF5}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_win32_directx10", "example_win32_directx10\example_win32_directx10.vcxproj", "{345A953E-A004-4648-B442-DC5F9F11068C}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_win32_directx11", "example_win32_directx11\example_win32_directx11.vcxproj", "{9F316E83-5AE5-4939-A723-305A94F48005}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_win32_directx12", "example_win32_directx12\example_win32_directx12.vcxproj", "{B4CF9797-519D-4AFE-A8F4-5141A6B521D3}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example_glfw_opengl2", "example_glfw_opengl2\example_glfw_opengl2.vcxproj", "{9CDA7840-B7A5-496D-A527-E95571496D18}" From ab36fbaf48393399ea689b9ed28e989e265e0b66 Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 27 Apr 2026 18:23:56 +0200 Subject: [PATCH 2/7] Drag and Drop, Style: added ImGuiStyleVar_DragDropTargetRounding. (#9056) + readded rounding arg to RenderDragDropTargetRectEx(). --- docs/CHANGELOG.txt | 1 + imgui.cpp | 11 ++++++----- imgui.h | 3 ++- imgui_internal.h | 2 +- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 09d33ae90..d7bffe784 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -129,6 +129,7 @@ Other Changes: - Style: - Fixed vertical scrollbar top coordinates when using thick borders on windows with no title bar and no menu bar. (#9366) + - Added ImGuiStyleVar_DragDropTargetRounding. (#9056) - Fonts: - imgui_freetype: add FreeType headers & compiled version in 'About Dear ImGui' details. - Assert when using MergeMode with an explicit size over a target font with an implicit diff --git a/imgui.cpp b/imgui.cpp index 1829d4fcb..d31563855 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3659,6 +3659,7 @@ static const ImGuiStyleVarInfo GStyleVarsInfo[] = { 2, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, TableAngledHeadersTextAlign)},// ImGuiStyleVar_TableAngledHeadersTextAlign { 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, TreeLinesSize)}, // ImGuiStyleVar_TreeLinesSize { 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, TreeLinesRounding)}, // ImGuiStyleVar_TreeLinesRounding + { 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, DragDropTargetRounding)}, // ImGuiStyleVar_DragDropTargetRounding { 2, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, ButtonTextAlign) }, // ImGuiStyleVar_ButtonTextAlign { 2, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, SelectableTextAlign) }, // ImGuiStyleVar_SelectableTextAlign { 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, SeparatorSize)}, // ImGuiStyleVar_SeparatorSize @@ -15118,7 +15119,7 @@ const ImGuiPayload* ImGui::AcceptDragDropPayload(const char* type, ImGuiDragDrop { ImRect bb = g.DragDropTargetRect; bb.Expand(-3.5f); - RenderDragDropTargetRectEx(GetForegroundDrawList(), bb); + RenderDragDropTargetRectEx(GetForegroundDrawList(), bb, g.Style.DragDropTargetRounding); } else if (draw_target_rect) { @@ -15149,16 +15150,16 @@ void ImGui::RenderDragDropTargetRectForItem(const ImRect& bb) bool push_clip_rect = !window->ClipRect.Contains(bb_display); if (push_clip_rect) window->DrawList->PushClipRectFullScreen(); - RenderDragDropTargetRectEx(window->DrawList, bb_display); + RenderDragDropTargetRectEx(window->DrawList, bb_display, g.Style.DragDropTargetRounding); if (push_clip_rect) window->DrawList->PopClipRect(); } -void ImGui::RenderDragDropTargetRectEx(ImDrawList* draw_list, const ImRect& bb) +void ImGui::RenderDragDropTargetRectEx(ImDrawList* draw_list, const ImRect& bb, float rounding) { ImGuiContext& g = *GImGui; - draw_list->AddRectFilled(bb.Min, bb.Max, GetColorU32(ImGuiCol_DragDropTargetBg), g.Style.DragDropTargetRounding, 0); - draw_list->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_DragDropTarget), g.Style.DragDropTargetRounding, 0, g.Style.DragDropTargetBorderSize); + draw_list->AddRectFilled(bb.Min, bb.Max, GetColorU32(ImGuiCol_DragDropTargetBg), rounding, 0); + draw_list->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_DragDropTarget), rounding, 0, g.Style.DragDropTargetBorderSize); } const ImGuiPayload* ImGui::GetDragDropPayload() diff --git a/imgui.h b/imgui.h index 41a93dea3..9699ebf28 100644 --- a/imgui.h +++ b/imgui.h @@ -1852,6 +1852,7 @@ enum ImGuiStyleVar_ ImGuiStyleVar_TableAngledHeadersTextAlign,// ImVec2 TableAngledHeadersTextAlign ImGuiStyleVar_TreeLinesSize, // float TreeLinesSize ImGuiStyleVar_TreeLinesRounding, // float TreeLinesRounding + ImGuiStyleVar_DragDropTargetRounding, // float DragDropTargetRounding ImGuiStyleVar_ButtonTextAlign, // ImVec2 ButtonTextAlign ImGuiStyleVar_SelectableTextAlign, // ImVec2 SelectableTextAlign ImGuiStyleVar_SeparatorSize, // float SeparatorSize @@ -2328,7 +2329,7 @@ struct ImGuiStyle ImGuiTreeNodeFlags TreeLinesFlags; // Default way to draw lines connecting TreeNode hierarchy. ImGuiTreeNodeFlags_DrawLinesNone or ImGuiTreeNodeFlags_DrawLinesFull or ImGuiTreeNodeFlags_DrawLinesToNodes. float TreeLinesSize; // Thickness of outlines when using ImGuiTreeNodeFlags_DrawLines. float TreeLinesRounding; // Radius of lines connecting child nodes to the vertical line. - float DragDropTargetRounding; // Radius of the drag and drop target frame. + float DragDropTargetRounding; // Radius of the drag and drop target frame. When <0.0f: use FrameRounding. float DragDropTargetBorderSize; // Thickness of the drag and drop target border. float DragDropTargetPadding; // Size to expand the drag and drop target from actual target item size. float ColorMarkerSize; // Size of R/G/B/A color markers for ColorEdit4() and for Drags/Sliders when using ImGuiSliderFlags_ColorMarkers. diff --git a/imgui_internal.h b/imgui_internal.h index e1b27f2ed..b3792abb4 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -3494,7 +3494,7 @@ namespace ImGui IMGUI_API void ClearDragDrop(); IMGUI_API bool IsDragDropPayloadBeingAccepted(); IMGUI_API void RenderDragDropTargetRectForItem(const ImRect& bb); - IMGUI_API void RenderDragDropTargetRectEx(ImDrawList* draw_list, const ImRect& bb); + IMGUI_API void RenderDragDropTargetRectEx(ImDrawList* draw_list, const ImRect& bb, float rounding); // Typing-Select API // (provide Windows Explorer style "select items by typing partial name" + "cycle through items by typing same letter" feature) From d1a8995634fa4413b03c56a4772334ea27a967e1 Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 28 Apr 2026 14:58:29 +0200 Subject: [PATCH 3/7] MultiSelect: Box-Select + Tables: fixed when using SpanAllColumns paths. (#9383, #7994) Amend ac88294 + d7b40ab --- imgui_widgets.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 59d0ceb85..ecad830a7 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -8367,11 +8367,20 @@ void ImGui::MultiSelectItemFooter(ImGuiID id, bool* p_selected, bool* p_pressed) if (ImGuiTable* table = g.CurrentTable) if (table->CurrentColumn != -1) { - // FIXME: We cannot use current ClipRect as it includes HostClipRect. - // A more generic version would be nice, but window->WorkRect.Min/Max exclude CellPadding. (#7994) + // FIXME: We cannot solely use current ClipRect as it includes HostClipRect. + // However we account for ClipRect being larger than current column (e.g. when using SpanAllColumns) + // A more generic version would be nice, but window->WorkRect.Min/Max exclude CellPadding. (#7994, #9383) ImGuiTableColumn* column = &table->Columns[table->CurrentColumn]; item_rect.Min.x = ImMax(item_rect.Min.x, column->MinX); item_rect.Max.x = ImMin(item_rect.Max.x, column->MaxX); + float clip_min_x = (g.LastItemData.ItemFlags & ImGuiItemStatusFlags_HasClipRect) ? g.LastItemData.ClipRect.Min.x : window->ClipRect.Min.x; + float clip_max_x = (g.LastItemData.ItemFlags & ImGuiItemStatusFlags_HasClipRect) ? g.LastItemData.ClipRect.Max.x : window->ClipRect.Max.x; + if (clip_min_x != clip_max_x) // When zero sized we expect that bounds have been clamped and thus are unreliable + { + item_rect.Min.x = ImMax(item_rect.Min.x, clip_min_x); + item_rect.Max.x = ImMin(item_rect.Max.x, clip_max_x); + } + } const bool rect_overlap_curr = bs->BoxSelectRectCurr.Overlaps(item_rect); const bool rect_overlap_prev = bs->BoxSelectRectPrev.Overlaps(item_rect); From dee9b15bbec8c8a7120e4dfddf73b35ae60947f1 Mon Sep 17 00:00:00 2001 From: Vlad Date: Mon, 27 Apr 2026 16:06:33 +0900 Subject: [PATCH 4/7] Backends: Metal: add sampler states and DrawCallback_SetSamplerLinear / DrawCallback_SetSamplerNearest callbacks. (#9381, #9371, #9378) --- backends/imgui_impl_metal.h | 2 -- backends/imgui_impl_metal.mm | 33 +++++++++++++++++++++++++++------ docs/CHANGELOG.txt | 4 ++-- imgui.h | 8 ++++---- 4 files changed, 33 insertions(+), 14 deletions(-) diff --git a/backends/imgui_impl_metal.h b/backends/imgui_impl_metal.h index 879fadcf0..8af2c8b6b 100644 --- a/backends/imgui_impl_metal.h +++ b/backends/imgui_impl_metal.h @@ -5,8 +5,6 @@ // [X] Renderer: User texture binding. Use 'MTLTexture' 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). -// Missing features or Issues: -// [ ] Renderer: Missing support for DrawCallback_SetSamplerLinear, DrawCallback_SetSamplerNearest callbacks. // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. diff --git a/backends/imgui_impl_metal.mm b/backends/imgui_impl_metal.mm index db2fcd3c8..652668c78 100644 --- a/backends/imgui_impl_metal.mm +++ b/backends/imgui_impl_metal.mm @@ -5,8 +5,6 @@ // [X] Renderer: User texture binding. Use 'MTLTexture' 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). -// Missing features or Issues: -// [ ] Renderer: Missing support for DrawCallback_SetSamplerLinear, DrawCallback_SetSamplerNearest callbacks. // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. @@ -18,6 +16,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 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) // 2026-04-14: Metal: use a dedicated bufferCacheLock to avoid crashing when bufferCache is replaced by a new object while being used for @synchronize(). (#9367) // 2026-04-03: Metal: avoid redundant vertex buffer bind in SetupRenderState. (#9343) @@ -79,6 +78,8 @@ @interface MetalContext : NSObject @property (nonatomic, strong) id device; @property (nonatomic, strong) id depthStencilState; +@property (nonatomic, strong) id samplerStateLinear; +@property (nonatomic, strong) id samplerStateNearest; @property (nonatomic, strong) FramebufferDescriptor* framebufferDescriptor; // framebuffer descriptor for current frame; transient @property (nonatomic, strong) NSMutableDictionary* renderPipelineStateCache; // pipeline cache; keyed on framebuffer descriptors @property (nonatomic, strong) NSMutableArray* bufferCache; @@ -91,6 +92,7 @@ struct ImGui_ImplMetal_Data { MetalContext* SharedMetalContext; + id RenderCommandEncoder; ImGui_ImplMetal_Data() { memset((void*)this, 0, sizeof(*this)); } }; @@ -185,12 +187,15 @@ static void ImGui_ImplMetal_SetupRenderState(ImDrawData* draw_data, idSharedMetalContext.samplerStateLinear atIndex:0]; [commandEncoder setVertexBuffer:vertexBuffer.buffer offset:vertexBufferOffset atIndex:0]; } // Draw callbacks -static void ImGui_ImplMetal_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_ImplMetal_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_ImplMetal_DrawCallback_SetSamplerLinear(const ImDrawList*, const ImDrawCmd*) { ImGui_ImplMetal_Data* bd = ImGui_ImplMetal_GetBackendData(); [bd->RenderCommandEncoder setFragmentSamplerState:bd->SharedMetalContext.samplerStateLinear atIndex:0]; } +static void ImGui_ImplMetal_DrawCallback_SetSamplerNearest(const ImDrawList*, const ImDrawCmd*) { ImGui_ImplMetal_Data* bd = ImGui_ImplMetal_GetBackendData(); [bd->RenderCommandEncoder setFragmentSamplerState:bd->SharedMetalContext.samplerStateNearest atIndex:0]; } // Metal Render function. void ImGui_ImplMetal_RenderDrawData(ImDrawData* draw_data, id commandBuffer, id commandEncoder) @@ -228,6 +233,7 @@ void ImGui_ImplMetal_RenderDrawData(ImDrawData* draw_data, id MetalBuffer* vertexBuffer = [ctx dequeueReusableBufferOfLength:vertexBufferLength device:commandBuffer.device]; MetalBuffer* indexBuffer = [ctx dequeueReusableBufferOfLength:indexBufferLength device:commandBuffer.device]; + bd->RenderCommandEncoder = commandEncoder; ImGui_ImplMetal_SetupRenderState(draw_data, commandBuffer, commandEncoder, renderPipelineState, vertexBuffer, 0); // Will project scissor/clipping rectangles into framebuffer space @@ -306,6 +312,7 @@ void ImGui_ImplMetal_RenderDrawData(ImDrawData* draw_data, id [sharedMetalContext.bufferCache addObject:indexBuffer]; } }]; + bd->RenderCommandEncoder = nil; } static void ImGui_ImplMetal_DestroyTexture(ImTextureData* tex) @@ -382,7 +389,17 @@ bool ImGui_ImplMetal_CreateDeviceObjects(id device) depthStencilDescriptor.depthWriteEnabled = NO; depthStencilDescriptor.depthCompareFunction = MTLCompareFunctionAlways; bd->SharedMetalContext.depthStencilState = [device newDepthStencilStateWithDescriptor:depthStencilDescriptor]; + MTLSamplerDescriptor* samplerDescriptor = [[MTLSamplerDescriptor alloc] init]; + samplerDescriptor.minFilter = MTLSamplerMinMagFilterLinear; + samplerDescriptor.magFilter = MTLSamplerMinMagFilterLinear; + samplerDescriptor.mipFilter = MTLSamplerMipFilterLinear; + bd->SharedMetalContext.samplerStateLinear = [device newSamplerStateWithDescriptor:samplerDescriptor]; + samplerDescriptor.minFilter = MTLSamplerMinMagFilterNearest; + samplerDescriptor.magFilter = MTLSamplerMinMagFilterNearest; + samplerDescriptor.mipFilter = MTLSamplerMipFilterNearest; + bd->SharedMetalContext.samplerStateNearest = [device newSamplerStateWithDescriptor:samplerDescriptor]; #ifdef IMGUI_IMPL_METAL_CPP + [samplerDescriptor release]; [depthStencilDescriptor release]; #endif @@ -399,6 +416,8 @@ void ImGui_ImplMetal_DestroyDeviceObjects() ImGui_ImplMetal_DestroyTexture(tex); [bd->SharedMetalContext.renderPipelineStateCache removeAllObjects]; + bd->SharedMetalContext.samplerStateLinear = nil; + bd->SharedMetalContext.samplerStateNearest = nil; } bool ImGui_ImplMetal_Init(id device) @@ -415,6 +434,8 @@ bool ImGui_ImplMetal_Init(id device) ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); platform_io.DrawCallback_ResetRenderState = ImGui_ImplMetal_DrawCallback_ResetRenderState; + platform_io.DrawCallback_SetSamplerLinear = ImGui_ImplMetal_DrawCallback_SetSamplerLinear; + platform_io.DrawCallback_SetSamplerNearest = ImGui_ImplMetal_DrawCallback_SetSamplerNearest; bd->SharedMetalContext = [[MetalContext alloc] init]; bd->SharedMetalContext.device = device; @@ -599,9 +620,9 @@ void ImGui_ImplMetal_Shutdown() "}\n" "\n" "fragment half4 fragment_main(VertexOut in [[stage_in]],\n" - " texture2d texture [[texture(0)]]) {\n" - " constexpr sampler linearSampler(coord::normalized, min_filter::linear, mag_filter::linear, mip_filter::linear);\n" - " half4 texColor = texture.sample(linearSampler, in.texCoords);\n" + " texture2d texture [[texture(0)]],\n" + " sampler textureSampler [[sampler(0)]]) {\n" + " half4 texColor = texture.sample(textureSampler, in.texCoords);\n" " return half4(in.color) * texColor;\n" "}\n"; diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index d7bffe784..5b12ba40e 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -149,7 +149,7 @@ Other Changes: - DX10: Reset SetSamplerLinear SetSamplerNearest - DX11: Reset SetSamplerLinear SetSamplerNearest - DX12: Reset SetSamplerLinear SetSamplerNearest - - Metal: Reset *missing* *missing* + - Metal: Reset SetSamplerLinear SetSamplerNearest - OpenGL2: Reset SetSamplerLinear SetSamplerNearest - OpenGL3+: Reset SetSamplerLinear SetSamplerNearest - SDLGPU3: Reset SetSamplerLinear SetSamplerNearest @@ -157,7 +157,7 @@ Other Changes: - SDLRenderer3: Reset SetSamplerLinear SetSamplerNearest - Vulkan: Reset SetSamplerLinear SetSamplerNearest - WebGPU: Reset SetSamplerLinear SetSamplerNearest - (Vulkan backend by @yaz0r, others by @ocornut) + (Vulkan backend by @yaz0r, Metal by @ssh4net, others by @ocornut) - GLFW: added a Win32-specific implementation of `ImGui_ImplGlfw_GetContentScaleXXXX` functions for legacy GLFW 3.2. (#9003) - Metal: avoid redundant vertex buffer bind in `SetupRenderState()`, which leads diff --git a/imgui.h b/imgui.h index 9699ebf28..51be8c554 100644 --- a/imgui.h +++ b/imgui.h @@ -4018,11 +4018,11 @@ struct ImGuiPlatformIO // Written by some backends during ImGui_ImplXXXX_RenderDrawData() call to point backend_specific ImGui_ImplXXXX_RenderState* structure. void* Renderer_RenderState; - // Standard draw callbacks + // Standard draw callbacks provided by renderer backend. ImDrawCallback DrawCallback_ResetRenderState; // Request to reset the graphics/render state. - ImDrawCallback DrawCallback_SetSamplerLinear; // Request to set current texture sampling to Linear - ImDrawCallback DrawCallback_SetSamplerNearest; // Request to set current texture sampling to Nearest/Point - //ImDrawCallback DrawCallback_SetSamplerCustom; // Request to set current texture sampling using Backend Specific data. + 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_SetSamplerCustom; // Request backend to set texture sampling using Backend Specific data. //------------------------------------------------------------------ // Output From 865a6dfa59052188979797117e0ded2f01f96c42 Mon Sep 17 00:00:00 2001 From: "Alexander \"FireFox\" Ong" Date: Tue, 28 Apr 2026 20:44:20 +1000 Subject: [PATCH 5/7] InputScalar: fixed not parsing user input when the display format is configured not to show the scalar value. (#9385) Useful e.g. for displaying "mixed" inputs, where a single field might represent multiple different values. --- docs/CHANGELOG.txt | 2 ++ imgui_widgets.cpp | 7 ++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 5b12ba40e..dce8025f2 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -97,6 +97,8 @@ Other Changes: with 1.91.4 behavior. - In a majority of cases you should use IsItemDeactivatedAfterEdit() instead, but it still has a few edge cases flaws (to be addressed soon). +- InputInt, InputFloat, InputScalar: allow passing a format string that does not display + the scalar value. Parsing input with default format for the type. (#9385) [@FireFox2000000] - Multi-Select: - Fixed an issue using Multi-Select within a Table causing column width measurement to be invalid when trailing column contents is not submitted in the last row. (#9341, #8250) diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index ecad830a7..d05857d3c 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -2375,12 +2375,17 @@ bool ImGui::DataTypeApplyFromText(const char* buf, ImGuiDataType data_type, void // Sanitize format // - For float/double we have to ignore format with precision (e.g. "%.2f") because sscanf doesn't take them in, so force them into %f and %lf - // - In theory could treat empty format as using default, but this would only cover rare/bizarre case of using InputScalar() + integer + format string without %. char format_sanitized[32]; if (data_type == ImGuiDataType_Float || data_type == ImGuiDataType_Double) + { format = type_info->ScanFmt; + } else + { format = ImParseFormatSanitizeForScanning(format, format_sanitized, IM_COUNTOF(format_sanitized)); + if (format[0] == '\0') + format = type_info->ScanFmt; // Format doesn't want us to show the number currently, but we still need to parse the resulting input + } // Small types need a 32-bit buffer to receive the result from scanf() int v32 = 0; From c0b693b1d494cd4746f1b18221c58d76a76c46a0 Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 28 Apr 2026 15:56:50 +0200 Subject: [PATCH 6/7] MultiSelect: Box-Select + Tables: fixed when using SpanAllColumns paths. (#9383, #7994) Amend d1a8995 which didn't fix the thing it claimed to fix, as my naive last minute refactor broke it. --- imgui_widgets.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index d05857d3c..5f8749cad 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -8376,16 +8376,19 @@ void ImGui::MultiSelectItemFooter(ImGuiID id, bool* p_selected, bool* p_pressed) // However we account for ClipRect being larger than current column (e.g. when using SpanAllColumns) // A more generic version would be nice, but window->WorkRect.Min/Max exclude CellPadding. (#7994, #9383) ImGuiTableColumn* column = &table->Columns[table->CurrentColumn]; - item_rect.Min.x = ImMax(item_rect.Min.x, column->MinX); - item_rect.Max.x = ImMin(item_rect.Max.x, column->MaxX); float clip_min_x = (g.LastItemData.ItemFlags & ImGuiItemStatusFlags_HasClipRect) ? g.LastItemData.ClipRect.Min.x : window->ClipRect.Min.x; float clip_max_x = (g.LastItemData.ItemFlags & ImGuiItemStatusFlags_HasClipRect) ? g.LastItemData.ClipRect.Max.x : window->ClipRect.Max.x; if (clip_min_x != clip_max_x) // When zero sized we expect that bounds have been clamped and thus are unreliable { - item_rect.Min.x = ImMax(item_rect.Min.x, clip_min_x); - item_rect.Max.x = ImMin(item_rect.Max.x, clip_max_x); + item_rect.Min.x = ImMax(item_rect.Min.x, ImMin(column->MinX, clip_min_x)); + item_rect.Max.x = ImMin(item_rect.Max.x, ImMax(column->MaxX, clip_max_x)); } - + else + { + item_rect.Min.x = ImMax(item_rect.Min.x, column->MinX); + item_rect.Max.x = ImMin(item_rect.Max.x, column->MaxX); + } + //GetForegroundDrawList()->AddRect(item_rect.Min, item_rect.Max, IM_COL32(255, 0, 255, 255)); } const bool rect_overlap_curr = bs->BoxSelectRectCurr.Overlaps(item_rect); const bool rect_overlap_prev = bs->BoxSelectRectPrev.Overlaps(item_rect); From 691b89baae95d56df42a59b031c9d19685b7ab2f Mon Sep 17 00:00:00 2001 From: Mikko Mononen Date: Tue, 14 Apr 2026 12:30:16 +0300 Subject: [PATCH 7/7] ImDrawList: added AddLineH(), AddLineV() helpers. (#9360) This commit is aimed to be a lossless transform. Further layout fixes in subsequent commits. --- docs/CHANGELOG.txt | 1 + imgui.cpp | 22 +++++++++++----------- imgui.h | 2 ++ imgui_demo.cpp | 8 ++++---- imgui_draw.cpp | 20 +++++++++++++++++++- imgui_tables.cpp | 18 +++++++++--------- imgui_widgets.cpp | 14 +++++++------- 7 files changed, 53 insertions(+), 32 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index dce8025f2..844dc0318 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -74,6 +74,7 @@ Other Changes: (#9378, #9371, #3590, #8926, #2973, #7485, #7468, #6969, #5118, #7616, #9173, #8322, #7230, #5999, #6452, #5156, #7342, #7592, #7511) - Made AddCallback() user data default to Null for convenience. + - Added AddLineH(), AddLineV() helpers to draw horizontal and vertical lines. [@memononen] - InputText: - InputTextMultiline: fixed an issue processing deactivation logic when an active multi-line edit is clipped due to being out of view. diff --git a/imgui.cpp b/imgui.cpp index d31563855..34b281856 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3927,8 +3927,8 @@ void ImGui::RenderTextEllipsis(ImDrawList* draw_list, const ImVec2& pos_min, con text_end_full = FindRenderedTextEnd(text); const ImVec2 text_size = text_size_if_known ? *text_size_if_known : CalcTextSize(text, text_end_full, false, 0.0f); - //draw_list->AddLine(ImVec2(pos_max.x, pos_min.y - 4), ImVec2(pos_max.x, pos_max.y + 6), IM_COL32(0, 0, 255, 255)); - //draw_list->AddLine(ImVec2(ellipsis_max_x, pos_min.y - 2), ImVec2(ellipsis_max_x, pos_max.y + 3), IM_COL32(0, 255, 0, 255)); + //draw_list->AddLineV(pos_max.x, pos_min.y - 4, pos_max.y + 6, IM_COL32(0, 0, 255, 255)); + //draw_list->AddLineV(ellipsis_max_x, pos_min.y - 2, pos_max.y + 3, IM_COL32(0, 255, 0, 255)); // FIXME: We could technically remove (last_glyph->AdvanceX - last_glyph->X1) from text_size.x here and save a few pixels. if (text_size.x > pos_max.x - pos_min.x) @@ -7155,7 +7155,7 @@ static void ImGui::RenderWindowOuterBorders(ImGuiWindow* window) if (g.Style.FrameBorderSize > 0 && !(window->Flags & ImGuiWindowFlags_NoTitleBar)) { float y = window->Pos.y + window->TitleBarHeight - 1; - window->DrawList->AddLine(ImVec2(window->Pos.x + border_size * 0.5f, y), ImVec2(window->Pos.x + window->Size.x - border_size * 0.5f, y), border_col, g.Style.FrameBorderSize); + window->DrawList->AddLineH(window->Pos.x + border_size * 0.5f, window->Pos.x + window->Size.x - border_size * 0.5f, y, border_col, g.Style.FrameBorderSize); } } @@ -7223,7 +7223,7 @@ void ImGui::RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar menu_bar_rect.ClipWith(window->Rect()); // Soft clipping, in particular child window don't have minimum size covering the menu bar so this is useful for them. window->DrawList->AddRectFilled(menu_bar_rect.Min, menu_bar_rect.Max, GetColorU32(ImGuiCol_MenuBarBg), (flags & ImGuiWindowFlags_NoTitleBar) ? window_rounding : 0.0f, ImDrawFlags_RoundCornersTop); if (style.FrameBorderSize > 0.0f && menu_bar_rect.Max.y < window->Pos.y + window->Size.y) - window->DrawList->AddLine(menu_bar_rect.GetBL() + ImVec2(window_border_size * 0.5f, 0.0f), menu_bar_rect.GetBR() - ImVec2(window_border_size * 0.5f, 0.0f), GetColorU32(ImGuiCol_Border), style.FrameBorderSize); + window->DrawList->AddLineH(menu_bar_rect.Min.x + window_border_size * 0.5f, menu_bar_rect.Max.x - window_border_size * 0.5f, menu_bar_rect.Max.y, GetColorU32(ImGuiCol_Border), style.FrameBorderSize); } // Scrollbars @@ -17602,8 +17602,8 @@ void ImGui::DebugNodeTabBar(ImGuiTabBar* tab_bar, const char* label) { ImDrawList* draw_list = GetForegroundDrawList(tab_bar->Window); draw_list->AddRect(tab_bar->BarRect.Min, tab_bar->BarRect.Max, IM_COL32(255, 255, 0, 255)); - draw_list->AddLine(ImVec2(tab_bar->ScrollingRectMinX, tab_bar->BarRect.Min.y), ImVec2(tab_bar->ScrollingRectMinX, tab_bar->BarRect.Max.y), IM_COL32(0, 255, 0, 255)); - draw_list->AddLine(ImVec2(tab_bar->ScrollingRectMaxX, tab_bar->BarRect.Min.y), ImVec2(tab_bar->ScrollingRectMaxX, tab_bar->BarRect.Max.y), IM_COL32(0, 255, 0, 255)); + draw_list->AddLineV(tab_bar->ScrollingRectMinX, tab_bar->BarRect.Min.y, tab_bar->BarRect.Max.y, IM_COL32(0, 255, 0, 255)); + draw_list->AddLineV(tab_bar->ScrollingRectMaxX, tab_bar->BarRect.Min.y, tab_bar->BarRect.Max.y, IM_COL32(0, 255, 0, 255)); } if (open) { @@ -17932,8 +17932,8 @@ void ImGui::DebugDrawCursorPos(ImU32 col) ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; ImVec2 pos = window->DC.CursorPos; - window->DrawList->AddLine(ImVec2(pos.x, pos.y - 3.0f), ImVec2(pos.x, pos.y + 4.0f), col, 1.0f); - window->DrawList->AddLine(ImVec2(pos.x - 3.0f, pos.y), ImVec2(pos.x + 4.0f, pos.y), col, 1.0f); + window->DrawList->AddLineV(pos.x, pos.y - 3.0f, pos.y + 4.0f, col, 1.0f); + window->DrawList->AddLineH(pos.x - 3.0f, pos.x + 4.0f, pos.y, col, 1.0f); } // Draw a 10px wide rectangle around CurposPos.x using Line Y1/Y2 in current window's DrawList @@ -17944,9 +17944,9 @@ void ImGui::DebugDrawLineExtents(ImU32 col) float curr_x = window->DC.CursorPos.x; float line_y1 = (window->DC.IsSameLine ? window->DC.CursorPosPrevLine.y : window->DC.CursorPos.y); float line_y2 = line_y1 + (window->DC.IsSameLine ? window->DC.PrevLineSize.y : window->DC.CurrLineSize.y); - window->DrawList->AddLine(ImVec2(curr_x - 5.0f, line_y1), ImVec2(curr_x + 5.0f, line_y1), col, 1.0f); - window->DrawList->AddLine(ImVec2(curr_x - 0.5f, line_y1), ImVec2(curr_x - 0.5f, line_y2), col, 1.0f); - window->DrawList->AddLine(ImVec2(curr_x - 5.0f, line_y2), ImVec2(curr_x + 5.0f, line_y2), col, 1.0f); + window->DrawList->AddLineH(curr_x - 5.0f, curr_x + 5.0f, line_y1, col, 1.0f); + window->DrawList->AddLineV(curr_x - 0.5f, line_y1, line_y2, col, 1.0f); + window->DrawList->AddLineH(curr_x - 5.0f, curr_x + 5.0f, line_y2, col, 1.0f); } // Draw last item rect in ForegroundDrawList (so it is always visible) diff --git a/imgui.h b/imgui.h index 51be8c554..5a956d440 100644 --- a/imgui.h +++ b/imgui.h @@ -3322,6 +3322,8 @@ struct ImDrawList // In future versions we will use textures to provide cheaper and higher-quality circles. // Use AddNgon() and AddNgonFilled() functions if you need to guarantee a specific number of sides. IMGUI_API void AddLine(const ImVec2& p1, const ImVec2& p2, ImU32 col, float thickness = 1.0f); + IMGUI_API void AddLineH(float min_x, float max_x, float y, ImU32 col, float thickness = 1.0f); + IMGUI_API void AddLineV(float x, float min_y, float max_y, ImU32 col, float thickness = 1.0f); IMGUI_API void AddRect(const ImVec2& p_min, const ImVec2& p_max, ImU32 col, float rounding = 0.0f, ImDrawFlags flags = 0, float thickness = 1.0f); // a: upper-left, b: lower-right (== upper-left + size) IMGUI_API void AddRectFilled(const ImVec2& p_min, const ImVec2& p_max, ImU32 col, float rounding = 0.0f, ImDrawFlags flags = 0); // a: upper-left, b: lower-right (== upper-left + size) IMGUI_API void AddRectFilledMultiColor(const ImVec2& p_min, const ImVec2& p_max, ImU32 col_upr_left, ImU32 col_upr_right, ImU32 col_bot_right, ImU32 col_bot_left); diff --git a/imgui_demo.cpp b/imgui_demo.cpp index bbdfa1c3e..14950d603 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -10138,8 +10138,8 @@ static void ShowExampleAppCustomRendering(bool* p_open) //draw_list->AddTriangle(ImVec2(x+sz*0.2f,y), ImVec2(x, y+sz-0.5f), ImVec2(x+sz*0.4f, y+sz-0.5f), col, th);x+= sz*0.4f + spacing; // Thin triangle PathConcaveShape(draw_list, x, y, sz); draw_list->PathStroke(col, ImDrawFlags_Closed, th); x += sz + spacing; // Concave Shape //draw_list->AddPolyline(concave_shape, IM_COUNTOF(concave_shape), col, ImDrawFlags_Closed, th); - draw_list->AddLine(ImVec2(x, y), ImVec2(x + sz, y), col, th); x += sz + spacing; // Horizontal line (note: drawing a filled rectangle will be faster!) - draw_list->AddLine(ImVec2(x, y), ImVec2(x, y + sz), col, th); x += spacing; // Vertical line (note: drawing a filled rectangle will be faster!) + draw_list->AddLineH(x, x + sz, y, col, th); x += sz + spacing; // Horizontal line (note: drawing a filled rectangle will be faster!) + draw_list->AddLineV(x, y, y + sz, col, th); x += spacing; // Vertical line (note: drawing a filled rectangle will be faster!) draw_list->AddLine(ImVec2(x, y), ImVec2(x + sz, y + sz), col, th); x += sz + spacing; // Diagonal line // Path @@ -10278,9 +10278,9 @@ static void ShowExampleAppCustomRendering(bool* p_open) { const float GRID_STEP = 64.0f; for (float x = fmodf(scrolling.x, GRID_STEP); x < canvas_sz.x; x += GRID_STEP) - draw_list->AddLine(ImVec2(canvas_p0.x + x, canvas_p0.y), ImVec2(canvas_p0.x + x, canvas_p1.y), IM_COL32(200, 200, 200, 40)); + draw_list->AddLineV(canvas_p0.x + x, canvas_p0.y, canvas_p1.y, IM_COL32(200, 200, 200, 40)); for (float y = fmodf(scrolling.y, GRID_STEP); y < canvas_sz.y; y += GRID_STEP) - draw_list->AddLine(ImVec2(canvas_p0.x, canvas_p0.y + y), ImVec2(canvas_p1.x, canvas_p0.y + y), IM_COL32(200, 200, 200, 40)); + draw_list->AddLineH(canvas_p0.x, canvas_p1.x, canvas_p0.y + y, IM_COL32(200, 200, 200, 40)); } for (int n = 0; n < points.Size; n += 2) draw_list->AddLine(ImVec2(origin.x + points[n].x, origin.y + points[n].y), ImVec2(origin.x + points[n + 1].x, origin.y + points[n + 1].y), IM_COL32(255, 255, 0, 255), 2.0f); diff --git a/imgui_draw.cpp b/imgui_draw.cpp index dc814a4aa..c7415f96d 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1484,6 +1484,24 @@ void ImDrawList::AddLine(const ImVec2& p1, const ImVec2& p2, ImU32 col, float th PathStroke(col, 0, thickness); } +void ImDrawList::AddLineH(float min_x, float max_x, float y, ImU32 col, float thickness) +{ + if ((col & IM_COL32_A_MASK) == 0) + return; + PathLineTo(ImVec2(min_x + 0.5f, y + 0.5f)); // Same as AddLine() above. + PathLineTo(ImVec2(max_x + 0.5f, y + 0.5f)); + PathStroke(col, 0, thickness); +} + +void ImDrawList::AddLineV(float x, float min_y, float max_y, ImU32 col, float thickness) +{ + if ((col & IM_COL32_A_MASK) == 0) + return; + PathLineTo(ImVec2(x + 0.5f, min_y + 0.5f)); // Same as AddLine() above. + PathLineTo(ImVec2(x + 0.5f, max_y + 0.5f)); + PathStroke(col, 0, thickness); +} + // p_min = upper-left, p_max = lower-right // Note we don't render 1 pixels sized rectangles properly. void ImDrawList::AddRect(const ImVec2& p_min, const ImVec2& p_max, ImU32 col, float rounding, ImDrawFlags flags, float thickness) @@ -1659,7 +1677,7 @@ void ImDrawList::AddEllipse(const ImVec2& center, const ImVec2& radius, ImU32 co // Because we are filling a closed shape we remove 1 from the count of segments/points const float a_max = IM_PI * 2.0f * ((float)num_segments - 1.0f) / (float)num_segments; PathEllipticalArcTo(center, radius, rot, 0.0f, a_max, num_segments - 1); - PathStroke(col, true, thickness); + PathStroke(col, ImDrawFlags_Closed, thickness); } void ImDrawList::AddEllipseFilled(const ImVec2& center, const ImVec2& radius, ImU32 col, float rot, int num_segments) diff --git a/imgui_tables.cpp b/imgui_tables.cpp index cc910b989..ce225f461 100644 --- a/imgui_tables.cpp +++ b/imgui_tables.cpp @@ -2074,11 +2074,11 @@ void ImGui::TableEndRow(ImGuiTable* table) // Draw top border if (top_border_col && bg_y1 >= table->BgClipRect.Min.y && bg_y1 < table->BgClipRect.Max.y) - window->DrawList->AddLine(ImVec2(table->BorderX1, bg_y1), ImVec2(table->BorderX2, bg_y1), top_border_col, border_size); + window->DrawList->AddLineH(table->BorderX1, table->BorderX2, bg_y1, top_border_col, border_size); // Draw bottom border at the row unfreezing mark (always strong) if (draw_strong_bottom_border && bg_y2 >= table->BgClipRect.Min.y && bg_y2 < table->BgClipRect.Max.y) - window->DrawList->AddLine(ImVec2(table->BorderX1, bg_y2), ImVec2(table->BorderX2, bg_y2), table->BorderColorStrong, border_size); + window->DrawList->AddLineH(table->BorderX1, table->BorderX2, bg_y2, table->BorderColorStrong, border_size); } // End frozen rows (when we are past the last frozen row line, teleport cursor and alter clipping rectangle) @@ -2855,7 +2855,7 @@ void ImGui::TableDrawBorders(ImGuiTable* table) else if ((table->Flags & (ImGuiTableFlags_NoBordersInBodyUntilResize | ImGuiTableFlags_NoBordersInBody)) == 0) draw_y2 = draw_y2_body; if (draw_y2 > draw_y1) - inner_drawlist->AddLine(ImVec2(column->MaxX, draw_y1), ImVec2(column->MaxX, draw_y2), TableGetColumnBorderCol(table, order_n, column_n), border_size); + inner_drawlist->AddLineV(column->MaxX, draw_y1, draw_y2, TableGetColumnBorderCol(table, order_n, column_n), border_size); } } @@ -2876,13 +2876,13 @@ void ImGui::TableDrawBorders(ImGuiTable* table) } else if (table->Flags & ImGuiTableFlags_BordersOuterV) { - inner_drawlist->AddLine(outer_border.Min, ImVec2(outer_border.Min.x, outer_border.Max.y), outer_col, border_size); - inner_drawlist->AddLine(ImVec2(outer_border.Max.x, outer_border.Min.y), outer_border.Max, outer_col, border_size); + inner_drawlist->AddLineV(outer_border.Min.x, outer_border.Min.y, outer_border.Max.y, outer_col, border_size); + inner_drawlist->AddLineV(outer_border.Max.x, outer_border.Min.y, outer_border.Max.y, outer_col, border_size); } else if (table->Flags & ImGuiTableFlags_BordersOuterH) { - inner_drawlist->AddLine(outer_border.Min, ImVec2(outer_border.Max.x, outer_border.Min.y), outer_col, border_size); - inner_drawlist->AddLine(ImVec2(outer_border.Min.x, outer_border.Max.y), outer_border.Max, outer_col, border_size); + inner_drawlist->AddLineH(outer_border.Min.x, outer_border.Max.x, outer_border.Min.y, outer_col, border_size); + inner_drawlist->AddLineH(outer_border.Min.x, outer_border.Max.x, outer_border.Max.y, outer_col, border_size); } } if ((table->Flags & ImGuiTableFlags_BordersInnerH) && table->RowPosY2 < table->OuterRect.Max.y) @@ -2890,7 +2890,7 @@ void ImGui::TableDrawBorders(ImGuiTable* table) // Draw bottom-most row border between it is above outer border. const float border_y = table->RowPosY2; if (border_y >= table->BgClipRect.Min.y && border_y < table->BgClipRect.Max.y) - inner_drawlist->AddLine(ImVec2(table->BorderX1, border_y), ImVec2(table->BorderX2, border_y), table->BorderColorLight, border_size); + inner_drawlist->AddLineH(table->BorderX1, table->BorderX2, border_y, table->BorderColorLight, border_size); } inner_drawlist->PopClipRect(); @@ -4618,7 +4618,7 @@ void ImGui::EndColumns() // Draw column const ImU32 col = GetColorU32(held ? ImGuiCol_SeparatorActive : hovered ? ImGuiCol_SeparatorHovered : ImGuiCol_Separator); const float xi = IM_TRUNC(x); - window->DrawList->AddLine(ImVec2(xi, y1 + 1.0f), ImVec2(xi, y2), col); + window->DrawList->AddLineV(xi, y1 + 1.0f, y2, col); } // Apply dragging after drawing the column lines, so our rendered lines are in sync with how items were displayed during the frame. diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 5f8749cad..33b9a4c50 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -1556,7 +1556,7 @@ bool ImGui::TextLink(const char* label) } float line_y = bb.Max.y + ImFloor(g.FontBaked->Descent * g.FontBakedScale * 0.20f); - window->DrawList->AddLine(ImVec2(bb.Min.x, line_y), ImVec2(bb.Max.x, line_y), GetColorU32(line_colf), 1.0f * (float)(int)g.Style._MainScale); // FIXME-TEXT: Underline mode // FIXME-DPI + window->DrawList->AddLineH(bb.Min.x, bb.Max.x, line_y, GetColorU32(line_colf), 1.0f * (float)(int)g.Style._MainScale); // FIXME-TEXT: Underline mode // FIXME-DPI PushStyleColor(ImGuiCol_Text, GetColorU32(text_colf)); RenderText(bb.Min, label, label_end, false); @@ -1766,9 +1766,9 @@ void ImGui::SeparatorTextEx(ImGuiID id, const char* label, const char* label_end const float sep1_x2 = label_pos.x - style.ItemSpacing.x; const float sep2_x1 = label_pos.x + label_size.x + extra_w + style.ItemSpacing.x; if (sep1_x2 > sep1_x1 && separator_thickness > 0.0f) - window->DrawList->AddLine(ImVec2(sep1_x1, seps_y), ImVec2(sep1_x2, seps_y), separator_col, separator_thickness); + window->DrawList->AddLineH(sep1_x1, sep1_x2, seps_y, separator_col, separator_thickness); if (sep2_x2 > sep2_x1 && separator_thickness > 0.0f) - window->DrawList->AddLine(ImVec2(sep2_x1, seps_y), ImVec2(sep2_x2, seps_y), separator_col, separator_thickness); + window->DrawList->AddLineH(sep2_x1, sep2_x2, seps_y, separator_col, separator_thickness); if (g.LogEnabled) LogSetNextTextDecoration("---", NULL); RenderTextEllipsis(window->DrawList, label_pos, ImVec2(bb.Max.x, bb.Max.y + style.ItemSpacing.y), bb.Max.x, label, label_end, &label_size); @@ -1778,7 +1778,7 @@ void ImGui::SeparatorTextEx(ImGuiID id, const char* label, const char* label_end if (g.LogEnabled) LogText("---"); if (separator_thickness > 0.0f) - window->DrawList->AddLine(ImVec2(sep1_x1, seps_y), ImVec2(sep2_x2, seps_y), separator_col, separator_thickness); + window->DrawList->AddLineH(sep1_x1, sep2_x2, seps_y, separator_col, separator_thickness); } } @@ -5638,7 +5638,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ ImVec2 cursor_screen_pos = ImTrunc(draw_pos + cursor_offset - draw_scroll); ImRect cursor_screen_rect(cursor_screen_pos.x, cursor_screen_pos.y - g.FontSize + 0.5f, cursor_screen_pos.x + 1.0f, cursor_screen_pos.y - 1.5f); if (cursor_is_visible && cursor_screen_rect.Overlaps(clip_rect)) - draw_window->DrawList->AddLine(cursor_screen_rect.Min, cursor_screen_rect.GetBL(), GetColorU32(ImGuiCol_InputTextCursor), 1.0f * (float)(int)style._MainScale); // FIXME-DPI: Cursor thickness (#7031) + draw_window->DrawList->AddLineV(cursor_screen_rect.Min.x, cursor_screen_rect.Min.y, cursor_screen_rect.Max.y, GetColorU32(ImGuiCol_InputTextCursor), 1.0f * (float)(int)style._MainScale); // FIXME-DPI: Cursor thickness (#7031) // Notify OS of text input position for advanced IME (-1 x offset so that Windows IME can cover our cursor. Bit of an extra nicety.) // This is required for some backends (SDL3) to start emitting character/text inputs. @@ -7173,7 +7173,7 @@ void ImGui::TreeNodeDrawLineToChildNode(const ImVec2& target_pos) } else { - window->DrawList->AddLine(ImVec2(x1, y), ImVec2(x2, y), GetColorU32(ImGuiCol_TreeLines), g.Style.TreeLinesSize); + window->DrawList->AddLineH(x1, x2, y, GetColorU32(ImGuiCol_TreeLines), g.Style.TreeLinesSize); } } @@ -7199,7 +7199,7 @@ void ImGui::TreeNodeDrawLineToTreePop(const ImGuiTreeNodeStackData* data) float x = ImTrunc(data->DrawLinesX1); if (data->DrawLinesTableColumn != -1) TablePushColumnChannel(data->DrawLinesTableColumn); - window->DrawList->AddLine(ImVec2(x, y1), ImVec2(x, y2), GetColorU32(ImGuiCol_TreeLines), g.Style.TreeLinesSize); + window->DrawList->AddLineV(x, y1, y2, GetColorU32(ImGuiCol_TreeLines), g.Style.TreeLinesSize); if (data->DrawLinesTableColumn != -1) TablePopColumnChannel(); }