Tables: fixed Selectable/TreeNode highlight overlapping left/right-most edges when using a border + no scrolling. (#4678)

This commit is contained in:
ocornut 2026-11-02 16:22:54 +01:00
parent c6affd1145
commit 852269e25f
2 changed files with 9 additions and 10 deletions

View File

@ -3262,6 +3262,7 @@ struct IMGUI_API ImGuiTableTempData
int TableIndex; // Index in g.Tables.Buf[] pool int TableIndex; // Index in g.Tables.Buf[] pool
float LastTimeActive; // Last timestamp this structure was used float LastTimeActive; // Last timestamp this structure was used
float AngledHeadersExtraWidth; // Used in EndTable() float AngledHeadersExtraWidth; // Used in EndTable()
ImRect BorderOuterSizes;
ImVector<ImGuiTableHeaderData> AngledHeadersRequests; // Used in TableAngledHeadersRow() // FIXME: Single instance is enough? ImVector<ImGuiTableHeaderData> AngledHeadersRequests; // Used in TableAngledHeadersRow() // FIXME: Single instance is enough?
// Topology change // Topology change

View File

@ -490,15 +490,12 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
// it already overlaps it and doesn't need an extra offset. Ideally we should be able to pass custom border size with // it already overlaps it and doesn't need an extra offset. Ideally we should be able to pass custom border size with
// different x/y values to BeginChild().) // different x/y values to BeginChild().)
// - For non-scrolling window, this is applied to table->InnerClipRect below. // - For non-scrolling window, this is applied to table->InnerClipRect below.
ImRect border_size_outer = temp_data->BorderOuterSizes.Min.x = (flags & ImGuiTableFlags_BordersOuterV) ? border_size : 0.0f;
{ temp_data->BorderOuterSizes.Min.y = (flags & ImGuiTableFlags_BordersOuterH) ? border_size : 0.0f;
(flags & ImGuiTableFlags_BordersOuterV) ? border_size : 0.0f, temp_data->BorderOuterSizes.Max.x = ((flags & ImGuiTableFlags_BordersOuterV) && ((inner_window == outer_window) || inner_window->DecoOuterSizeX2 == 0.0f)) ? border_size : 0.0f;
(flags & ImGuiTableFlags_BordersOuterH) ? border_size : 0.0f, temp_data->BorderOuterSizes.Max.y = ((flags & ImGuiTableFlags_BordersOuterH) && ((inner_window == outer_window) || inner_window->DecoOuterSizeY2 == 0.0f)) ? border_size : 0.0f;
((flags & ImGuiTableFlags_BordersOuterV) && ((inner_window == outer_window) || inner_window->DecoOuterSizeX2 == 0.0f)) ? border_size : 0.0f,
((flags & ImGuiTableFlags_BordersOuterH) && ((inner_window == outer_window) || inner_window->DecoOuterSizeY2 == 0.0f)) ? border_size : 0.0f,
};
if (inner_window != outer_window) if (inner_window != outer_window)
table->HostClipRect.ShrinkClamp(border_size_outer.Min, border_size_outer.Max); table->HostClipRect.ShrinkClamp(temp_data->BorderOuterSizes.Min, temp_data->BorderOuterSizes.Max);
// Padding and Spacing // Padding and Spacing
// - None ........Content..... Pad .....Content........ // - None ........Content..... Pad .....Content........
@ -536,7 +533,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
table->CurrentRow = -1; table->CurrentRow = -1;
table->InnerClipRect = (inner_window == outer_window) ? table->WorkRect : inner_window->ClipRect; table->InnerClipRect = (inner_window == outer_window) ? table->WorkRect : inner_window->ClipRect;
if (inner_window == outer_window) if (inner_window == outer_window)
table->InnerClipRect.ShrinkClamp(border_size_outer.Min, border_size_outer.Max); table->InnerClipRect.ShrinkClamp(temp_data->BorderOuterSizes.Min, temp_data->BorderOuterSizes.Max);
table->InnerClipRect.ClipWith(table->WorkRect); // We need this to honor inner_width table->InnerClipRect.ClipWith(table->WorkRect); // We need this to honor inner_width
table->InnerClipRect.ClipWithFull(table->HostClipRect); table->InnerClipRect.ClipWithFull(table->HostClipRect);
if ((flags & ImGuiTableFlags_NoHostExtendY) == 0) if ((flags & ImGuiTableFlags_NoHostExtendY) == 0)
@ -1313,7 +1310,8 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
table->OuterRect.Max.x = table->WorkRect.Max.x = ImMin(table->OuterRect.Max.x, unused_x1 + border_size_outer_w); table->OuterRect.Max.x = table->WorkRect.Max.x = ImMin(table->OuterRect.Max.x, unused_x1 + border_size_outer_w);
table->InnerClipRect.Max.x = ImClamp(table->OuterRect.Max.x - border_size_outer_w, table->InnerClipRect.Min.x, table->InnerClipRect.Max.x); table->InnerClipRect.Max.x = ImClamp(table->OuterRect.Max.x - border_size_outer_w, table->InnerClipRect.Min.x, table->InnerClipRect.Max.x);
} }
table->InnerWindow->ParentWorkRect = table->WorkRect; table->InnerWindow->ParentWorkRect = table->WorkRect; // Used by Selectable/TreeNode highlight
table->InnerWindow->ParentWorkRect.ShrinkClamp(temp_data->BorderOuterSizes.Min, temp_data->BorderOuterSizes.Max);
table->BorderX1 = table->InnerClipRect.Min.x; table->BorderX1 = table->InnerClipRect.Min.x;
table->BorderX2 = table->InnerClipRect.Max.x; table->BorderX2 = table->InnerClipRect.Max.x;