mirror of
https://github.com/ocornut/imgui.git
synced 2026-11-05 22:15:45 +01:00
Tables: fixed various border overshooting issues, some mostly visible with transparent borders: (#4678, #9415)
As a side effect of cleaning up a few things, altering border size becomes closer to being correct.
This commit is contained in:
parent
0d0cd87dd2
commit
c1581882a4
@ -79,14 +79,17 @@ Other Changes:
|
||||
- Modals: fixed an assert displaying a modal in an environment where
|
||||
`io.DisplayFramebufferScale` is not an integer (regression in 1.93.0). (#9598)
|
||||
- Tables:
|
||||
- In non-scrolling tables, clamp lower border coordinates to stay within visible
|
||||
range (no visible changes, but ImDrawCmd AABB becomes more sensible).
|
||||
- Fixed various border overshooting issues, some mostly visible with transparent
|
||||
borders: (#4678)
|
||||
- On non-scrolling tables, inner horizontal borders slightly overlapped
|
||||
outer vertical ones with certain settings.
|
||||
- On non-scrolling tables, clamping lower border coordinates to stay within
|
||||
visible range (no visible change, but it makes ImDrawCmd AABB more sensible).
|
||||
- Fixed vertical inner borders slightly overlapping bottom outer border.
|
||||
- Fixed various issues with using `ImGuiTableFlags_NoHostExtendY`:
|
||||
- Fixed selectable highlight straying off the Y2 clipping limit.
|
||||
- Fixed parent window work rectangle affecting the Y2 clipping limit.
|
||||
- Fixed the Y2 clipping limit overlapping bottom outer border.
|
||||
- Fixed vertical inner borders slightly overlapping bottom outer border
|
||||
(may be visible with transparent borders).
|
||||
- ImVec2: added a check for cases where a custom `IM_VEC2_CLASS_EXTRA` macro
|
||||
adds an extra `operator=` to ImVec2. This isn't supported but should not
|
||||
be needed as you should have a constructor to convert from your type to ImVec2.
|
||||
|
||||
@ -653,6 +653,7 @@ struct IMGUI_API ImRect
|
||||
void TranslateY(float dy) { Min.y += dy; Max.y += dy; }
|
||||
void ClipWith(const ImRect& r) { Min = ImMax(Min, r.Min); Max = ImMin(Max, r.Max); } // Simple version, may lead to an inverted rectangle, which is fine for Contains/Overlaps test but not for display.
|
||||
void ClipWithFull(const ImRect& r) { Min = ImClamp(Min, r.Min, r.Max); Max = ImClamp(Max, r.Min, r.Max); } // Full version, ensure both points are fully clipped.
|
||||
void ShrinkClamp(const ImVec2& inset_min, const ImVec2& inset_max) { Min.x = ImMin(Min.x + inset_min.x, Max.x); Min.y = ImMin(Min.y + inset_min.y, Max.y); Max.x = ImMax(Max.x - inset_max.x, Min.x); Max.y = ImMax(Max.y - inset_max.y, Min.y); }
|
||||
bool IsInverted() const { return Min.x > Max.x || Min.y > Max.y; }
|
||||
ImVec4 ToVec4() const { return ImVec4(Min.x, Min.y, Max.x, Max.y); }
|
||||
const ImVec4& AsVec4() const { return *(const ImVec4*)&Min.x; }
|
||||
|
||||
@ -483,27 +483,22 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
|
||||
const float border_size = table->BorderSize = TABLE_BORDER_SIZE;
|
||||
|
||||
// Make borders not overlap our contents by offsetting HostClipRect (#6765, #7428, #3752)
|
||||
// (we normally shouldn't alter HostClipRect as we rely on TableMergeDrawChannels() expanding non-clipped column toward the
|
||||
// limits of that rectangle, in order for ImDrawListSplitter::Merge() to merge the draw commands. However since the overlap
|
||||
// problem only affect scrolling tables in this case we can get away with doing it without extra cost).
|
||||
if (inner_window != outer_window)
|
||||
// - We normally shouldn't alter HostClipRect as we rely on TableMergeDrawChannels() expanding non-clipped column toward the
|
||||
// limits of that rectangle, in order for ImDrawListSplitter::Merge() to merge the draw commands. However since the overlap
|
||||
// problem only affect scrolling tables in this case we can get away with doing it without extra cost).
|
||||
// - (FIXME: Because inner_window's Scrollbar doesn't know about border size, since it's not encoded in window->WindowBorderSize,
|
||||
// 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().)
|
||||
// - For non-scrolling window, this is applied to table->InnerClipRect below.
|
||||
ImRect border_size_outer =
|
||||
{
|
||||
// FIXME: Because inner_window's Scrollbar doesn't know about border size, since it's not encoded in window->WindowBorderSize,
|
||||
// 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().
|
||||
if (flags & ImGuiTableFlags_BordersOuterV)
|
||||
{
|
||||
table->HostClipRect.Min.x = ImMin(table->HostClipRect.Min.x + border_size, table->HostClipRect.Max.x);
|
||||
if (inner_window->DecoOuterSizeX2 == 0.0f)
|
||||
table->HostClipRect.Max.x = ImMax(table->HostClipRect.Max.x - border_size, table->HostClipRect.Min.x);
|
||||
}
|
||||
if (flags & ImGuiTableFlags_BordersOuterH)
|
||||
{
|
||||
table->HostClipRect.Min.y = ImMin(table->HostClipRect.Min.y + border_size, table->HostClipRect.Max.y);
|
||||
if (inner_window->DecoOuterSizeY2 == 0.0f)
|
||||
table->HostClipRect.Max.y = ImMax(table->HostClipRect.Max.y - border_size, table->HostClipRect.Min.y);
|
||||
}
|
||||
}
|
||||
(flags & ImGuiTableFlags_BordersOuterV) ? border_size : 0.0f,
|
||||
(flags & ImGuiTableFlags_BordersOuterH) ? 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)
|
||||
table->HostClipRect.ShrinkClamp(border_size_outer.Min, border_size_outer.Max);
|
||||
|
||||
// Padding and Spacing
|
||||
// - None ........Content..... Pad .....Content........
|
||||
@ -528,17 +523,13 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
|
||||
table->RowBgColorCounter = 0;
|
||||
table->LastRowFlags = ImGuiTableRowFlags_None;
|
||||
table->InnerClipRect = (inner_window == outer_window) ? table->WorkRect : inner_window->ClipRect;
|
||||
if (inner_window == outer_window)
|
||||
table->InnerClipRect.ShrinkClamp(border_size_outer.Min, border_size_outer.Max);
|
||||
table->InnerClipRect.ClipWith(table->WorkRect); // We need this to honor inner_width
|
||||
table->InnerClipRect.ClipWithFull(table->HostClipRect);
|
||||
if (flags & ImGuiTableFlags_NoHostExtendY)
|
||||
{
|
||||
if (flags & ImGuiTableFlags_BordersOuterH)
|
||||
table->InnerClipRect.Max.y = ImClamp(table->OuterRect.Max.y - border_size, table->InnerClipRect.Min.y, table->InnerClipRect.Max.y);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((flags & ImGuiTableFlags_NoHostExtendY) == 0)
|
||||
table->InnerClipRect.Max.y = table->HostClipRect.Max.y;
|
||||
}
|
||||
|
||||
table->RowPosY1 = table->RowPosY2 = table->WorkRect.Min.y; // This is needed somehow
|
||||
table->RowTextBaseline = 0.0f; // This will be cleared again by TableBeginRow()
|
||||
table->RowCellPaddingY = 0.0f;
|
||||
@ -1513,10 +1504,10 @@ void ImGui::EndTable()
|
||||
// but since the later is likely to be impossible to do we'd rather update both axes together.
|
||||
if (table->Flags & ImGuiTableFlags_ScrollX)
|
||||
{
|
||||
const float outer_padding_for_border = (table->Flags & ImGuiTableFlags_BordersOuterV) ? table->BorderSize : 0.0f;
|
||||
const float border_size_outer_w = (table->Flags & ImGuiTableFlags_BordersOuterV) ? table->BorderSize : 0.0f;
|
||||
float max_pos_x = inner_window->DC.CursorMaxPos.x;
|
||||
if (table->RightMostEnabledColumn != -1)
|
||||
max_pos_x = ImMax(max_pos_x, table->Columns[table->RightMostEnabledColumn].WorkMaxX + table->CellPaddingX + table->OuterPaddingX - outer_padding_for_border);
|
||||
max_pos_x = ImMax(max_pos_x, table->Columns[table->RightMostEnabledColumn].WorkMaxX + table->CellPaddingX + table->OuterPaddingX - border_size_outer_w);
|
||||
if (table->ResizedColumn != -1)
|
||||
max_pos_x = ImMax(max_pos_x, table->ResizeLockMinContentsX2);
|
||||
inner_window->DC.CursorMaxPos.x = max_pos_x + table->TempData->AngledHeadersExtraWidth;
|
||||
@ -3049,7 +3040,7 @@ void ImGui::TableDrawBorders(ImGuiTable* table)
|
||||
// Draw bottom-most row border between it and above outer border.
|
||||
const float border_y = table->RowPosY2;
|
||||
if (border_y >= table->BgClipRect.Min.y && border_y < table->BgClipRect.Max.y)
|
||||
inner_drawlist->AddLineH(table->BorderX1 + border_size_outer_w, table->BorderX2 - border_size_outer_w, border_y, table->BorderColorLight, border_size_inner);
|
||||
inner_drawlist->AddLineH(table->BorderX1, table->BorderX2, border_y, table->BorderColorLight, border_size_inner);
|
||||
}
|
||||
|
||||
inner_drawlist->PopClipRect();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user