Selectable: Fixed highlight/hit extent when used with horizontal scrolling (in or outside columns). (#3187, #3386)
# Conflicts:
# imgui_widgets.cpp
diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt
index 7cc1631..c9d14d5 100644
--- a/docs/CHANGELOG.txt
+++ b/docs/CHANGELOG.txt
@@ -49,6 +49,8 @@
clipping, more than 16 KB characters are visible in the same low-level ImDrawList::RenderText
call. ImGui-level functions such as TextUnformatted() are not affected. This is quite rare
but it will be addressed later). (#3349)
+- Selectable: Fixed highlight/hit extent when used with horizontal scrolling (in or outside columns).
+ Also fixed related text clipping when used in a column after the first one. (#3187, #3386)
- Scrolling: Avoid SetScroll, SetScrollFromPos functions from snapping on the edge of scroll
limits when close-enough by (WindowPadding - ItemPadding), which was a tweak with too many
side-effects. The behavior is still present in SetScrollHere functions as they are more explicitly
diff --git a/imgui.cpp b/imgui.cpp
index e6d7f61..c612735 100644
--- a/imgui.cpp
+++ b/imgui.cpp
@@ -5898,6 +5898,7 @@
window->WorkRect.Min.y = ImFloor(window->InnerRect.Min.y - window->Scroll.y + ImMax(window->WindowPadding.y, window->WindowBorderSize));
window->WorkRect.Max.x = window->WorkRect.Min.x + work_rect_size_x;
window->WorkRect.Max.y = window->WorkRect.Min.y + work_rect_size_y;
+ window->ParentWorkRect = window->WorkRect;
// [LEGACY] Content Region
// FIXME-OBSOLETE: window->ContentRegionRect.Max is currently very misleading / partly faulty, but some BeginChild() patterns relies on it.
diff --git a/imgui_internal.h b/imgui_internal.h
index e0f8ae0..65e6e9e 100644
--- a/imgui_internal.h
+++ b/imgui_internal.h
@@ -1015,7 +1015,7 @@
float HostCursorMaxPosX; // Backup of CursorMaxPos at the time of BeginColumns()
ImRect HostInitialClipRect; // Backup of ClipRect at the time of BeginColumns()
ImRect HostBackupClipRect; // Backup of ClipRect during PushColumnsBackground()/PopColumnsBackground()
- ImRect HostWorkRect; // Backup of WorkRect at the time of BeginColumns()
+ ImRect HostBackupParentWorkRect;//Backup of WorkRect at the time of BeginColumns()
ImVector<ImGuiColumnData> Columns;
ImDrawListSplitter Splitter;
@@ -1612,7 +1612,8 @@
ImRect OuterRectClipped; // == Window->Rect() just after setup in Begin(). == window->Rect() for root window.
ImRect InnerRect; // Inner rectangle (omit title bar, menu bar, scroll bar)
ImRect InnerClipRect; // == InnerRect shrunk by WindowPadding*0.5f on each side, clipped within viewport or parent clip rect.
- ImRect WorkRect; // Cover the whole scrolling region, shrunk by WindowPadding*1.0f on each side. This is meant to replace ContentRegionRect over time (from 1.71+ onward).
+ ImRect WorkRect; // Initially covers the whole scrolling region. Reduced by containers e.g columns/tables when active. Shrunk by WindowPadding*1.0f on each side. This is meant to replace ContentRegionRect over time (from 1.71+ onward).
+ ImRect ParentWorkRect; // Backup of WorkRect before entering a container such as columns/tables. Used by e.g. SpanAllColumns functions to easily access. Stacked containers are responsible for maintaining this. // FIXME-WORKRECT: Could be a stack?
ImRect ClipRect; // Current clipping/scissoring rectangle, evolve as we are using PushClipRect(), etc. == DrawList->clip_rect_stack.back().
ImRect ContentRegionRect; // FIXME: This is currently confusing/misleading. It is essentially WorkRect but not handling of scrolling. We currently rely on it as right/bottom aligned sizing operation need some size to rely on.
ImVec2ih HitTestHoleSize; // Define an optional rectangular hole where mouse will pass-through the window.
diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp
index 55dc643..1d4362d 100644
--- a/imgui_widgets.cpp
+++ b/imgui_widgets.cpp
@@ -5704,8 +5704,8 @@
ItemSize(size, 0.0f);
// Fill horizontal space
- const float min_x = (flags & ImGuiSelectableFlags_SpanAllColumns) ? window->ContentRegionRect.Min.x : pos.x;
- const float max_x = (flags & ImGuiSelectableFlags_SpanAllColumns) ? window->ContentRegionRect.Max.x : GetContentRegionMaxAbs().x;
+ const float min_x = (flags & ImGuiSelectableFlags_SpanAllColumns) ? window->ParentWorkRect.Min.x : pos.x;
+ const float max_x = (flags & ImGuiSelectableFlags_SpanAllColumns) ? window->ParentWorkRect.Max.x : window->WorkRect.Max.x;
if (size_arg.x == 0.0f || (flags & ImGuiSelectableFlags_SpanAvailWidth))
size.x = ImMax(label_size.x, max_x - min_x);
@@ -7665,7 +7665,8 @@
columns->HostCursorPosY = window->DC.CursorPos.y;
columns->HostCursorMaxPosX = window->DC.CursorMaxPos.x;
columns->HostInitialClipRect = window->ClipRect;
- columns->HostWorkRect = window->WorkRect;
+ columns->HostBackupParentWorkRect = window->ParentWorkRect;
+ window->ParentWorkRect = window->WorkRect;
// Set state for first column
// We aim so that the right-most column will have the same clipping width as other after being clipped by parent ClipRect
@@ -7845,7 +7846,8 @@
}
columns->IsBeingResized = is_being_resized;
- window->WorkRect = columns->HostWorkRect;
+ window->WorkRect = window->ParentWorkRect;
+ window->ParentWorkRect = columns->HostBackupParentWorkRect;
window->DC.CurrentColumns = NULL;
window->DC.ColumnsOffset.x = 0.0f;
window->DC.CursorPos.x = IM_FLOOR(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x);