Selectable: Fixed highlight/hit extent when used with horizontal scrolling (in or outside columns). (#3187, #3386)

# Conflicts:
#	imgui_widgets.cpp
This commit is contained in:
omar 2020-08-05 19:23:00 +02:00
parent fc61018b1c
commit 8074b49148
4 changed files with 12 additions and 6 deletions

View File

@ -49,6 +49,8 @@ Other Changes:
clipping, more than 16 KB characters are visible in the same low-level ImDrawList::RenderText 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 call. ImGui-level functions such as TextUnformatted() are not affected. This is quite rare
but it will be addressed later). (#3349) 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 - 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 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 side-effects. The behavior is still present in SetScrollHere functions as they are more explicitly

View File

@ -5898,6 +5898,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
window->WorkRect.Min.y = ImFloor(window->InnerRect.Min.y - window->Scroll.y + ImMax(window->WindowPadding.y, window->WindowBorderSize)); 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.x = window->WorkRect.Min.x + work_rect_size_x;
window->WorkRect.Max.y = window->WorkRect.Min.y + work_rect_size_y; window->WorkRect.Max.y = window->WorkRect.Min.y + work_rect_size_y;
window->ParentWorkRect = window->WorkRect;
// [LEGACY] Content Region // [LEGACY] Content Region
// FIXME-OBSOLETE: window->ContentRegionRect.Max is currently very misleading / partly faulty, but some BeginChild() patterns relies on it. // FIXME-OBSOLETE: window->ContentRegionRect.Max is currently very misleading / partly faulty, but some BeginChild() patterns relies on it.

View File

@ -1015,7 +1015,7 @@ struct ImGuiColumns
float HostCursorMaxPosX; // Backup of CursorMaxPos at the time of BeginColumns() float HostCursorMaxPosX; // Backup of CursorMaxPos at the time of BeginColumns()
ImRect HostInitialClipRect; // Backup of ClipRect at the time of BeginColumns() ImRect HostInitialClipRect; // Backup of ClipRect at the time of BeginColumns()
ImRect HostBackupClipRect; // Backup of ClipRect during PushColumnsBackground()/PopColumnsBackground() 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; ImVector<ImGuiColumnData> Columns;
ImDrawListSplitter Splitter; ImDrawListSplitter Splitter;
@ -1612,7 +1612,8 @@ struct IMGUI_API ImGuiWindow
ImRect OuterRectClipped; // == Window->Rect() just after setup in Begin(). == window->Rect() for root window. 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 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 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 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. 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. ImVec2ih HitTestHoleSize; // Define an optional rectangular hole where mouse will pass-through the window.

View File

@ -5704,8 +5704,8 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
ItemSize(size, 0.0f); ItemSize(size, 0.0f);
// Fill horizontal space // Fill horizontal space
const float min_x = (flags & ImGuiSelectableFlags_SpanAllColumns) ? window->ContentRegionRect.Min.x : pos.x; const float min_x = (flags & ImGuiSelectableFlags_SpanAllColumns) ? window->ParentWorkRect.Min.x : pos.x;
const float max_x = (flags & ImGuiSelectableFlags_SpanAllColumns) ? window->ContentRegionRect.Max.x : GetContentRegionMaxAbs().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)) if (size_arg.x == 0.0f || (flags & ImGuiSelectableFlags_SpanAvailWidth))
size.x = ImMax(label_size.x, max_x - min_x); size.x = ImMax(label_size.x, max_x - min_x);
@ -7665,7 +7665,8 @@ void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiColumnsFlag
columns->HostCursorPosY = window->DC.CursorPos.y; columns->HostCursorPosY = window->DC.CursorPos.y;
columns->HostCursorMaxPosX = window->DC.CursorMaxPos.x; columns->HostCursorMaxPosX = window->DC.CursorMaxPos.x;
columns->HostInitialClipRect = window->ClipRect; columns->HostInitialClipRect = window->ClipRect;
columns->HostWorkRect = window->WorkRect; columns->HostBackupParentWorkRect = window->ParentWorkRect;
window->ParentWorkRect = window->WorkRect;
// Set state for first column // 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 // 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 @@ void ImGui::EndColumns()
} }
columns->IsBeingResized = is_being_resized; columns->IsBeingResized = is_being_resized;
window->WorkRect = columns->HostWorkRect; window->WorkRect = window->ParentWorkRect;
window->ParentWorkRect = columns->HostBackupParentWorkRect;
window->DC.CurrentColumns = NULL; window->DC.CurrentColumns = NULL;
window->DC.ColumnsOffset.x = 0.0f; window->DC.ColumnsOffset.x = 0.0f;
window->DC.CursorPos.x = IM_FLOOR(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x); window->DC.CursorPos.x = IM_FLOOR(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x);