Selectable: Avoid pushing span-column background if clipped.

This commit is contained in:
ocornut 2020-11-04 20:11:34 +01:00
parent 7a27b2a282
commit 046057cebb

View File

@ -5909,10 +5909,6 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
const ImGuiStyle& style = g.Style; const ImGuiStyle& style = g.Style;
const bool span_all_columns = (flags & ImGuiSelectableFlags_SpanAllColumns) != 0;
if (span_all_columns && window->DC.CurrentColumns) // FIXME-OPT: Avoid if vertically clipped.
PushColumnsBackground();
// Submit label or explicit size to ItemSize(), whereas ItemAdd() will submit a larger/spanning rectangle. // Submit label or explicit size to ItemSize(), whereas ItemAdd() will submit a larger/spanning rectangle.
ImGuiID id = window->GetID(label); ImGuiID id = window->GetID(label);
ImVec2 label_size = CalcTextSize(label, NULL, true); ImVec2 label_size = CalcTextSize(label, NULL, true);
@ -5923,6 +5919,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
// Fill horizontal space // Fill horizontal space
// We don't support (size < 0.0f) in Selectable() because the ItemSpacing extension would make explicitely right-aligned sizes not visibly match other widgets. // We don't support (size < 0.0f) in Selectable() because the ItemSpacing extension would make explicitely right-aligned sizes not visibly match other widgets.
const bool span_all_columns = (flags & ImGuiSelectableFlags_SpanAllColumns) != 0;
const float min_x = span_all_columns ? window->ParentWorkRect.Min.x : pos.x; const float min_x = span_all_columns ? window->ParentWorkRect.Min.x : pos.x;
const float max_x = span_all_columns ? window->ParentWorkRect.Max.x : window->WorkRect.Max.x; const float max_x = span_all_columns ? 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))
@ -5947,6 +5944,15 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
} }
//if (g.IO.KeyCtrl) { GetForegroundDrawList()->AddRect(bb.Min, bb.Max, IM_COL32(0, 255, 0, 255)); } //if (g.IO.KeyCtrl) { GetForegroundDrawList()->AddRect(bb.Min, bb.Max, IM_COL32(0, 255, 0, 255)); }
// Modify ClipRect for the ItemAdd(), faster than doing a PushColumnsBackground/PushTableBackground for every Selectable..
const float backup_clip_rect_min_x = window->ClipRect.Min.x;
const float backup_clip_rect_max_x = window->ClipRect.Max.x;
if (span_all_columns)
{
window->ClipRect.Min.x = window->ParentWorkRect.Min.x;
window->ClipRect.Max.x = window->ParentWorkRect.Max.x;
}
bool item_add; bool item_add;
if (flags & ImGuiSelectableFlags_Disabled) if (flags & ImGuiSelectableFlags_Disabled)
{ {
@ -5959,13 +5965,21 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
{ {
item_add = ItemAdd(bb, id); item_add = ItemAdd(bb, id);
} }
if (!item_add)
if (span_all_columns)
{ {
if (span_all_columns && window->DC.CurrentColumns) window->ClipRect.Min.x = backup_clip_rect_min_x;
PopColumnsBackground(); window->ClipRect.Max.x = backup_clip_rect_max_x;
return false;
} }
if (!item_add)
return false;
// FIXME: We can standardize the behavior of those two, we could also keep the fast path of override ClipRect + full push on render only,
// which would be advantageous since most selectable are not selected.
if (span_all_columns && window->DC.CurrentColumns)
PushColumnsBackground();
// We use NoHoldingActiveID on menus so user can click and _hold_ on a menu then drag to browse child entries // We use NoHoldingActiveID on menus so user can click and _hold_ on a menu then drag to browse child entries
ImGuiButtonFlags button_flags = 0; ImGuiButtonFlags button_flags = 0;
if (flags & ImGuiSelectableFlags_NoHoldingActiveID) { button_flags |= ImGuiButtonFlags_NoHoldingActiveId; } if (flags & ImGuiSelectableFlags_NoHoldingActiveID) { button_flags |= ImGuiButtonFlags_NoHoldingActiveId; }