Tables: four small fixes.

Fixed last item flags leaking to disabled column, affecting IsItemHovered(). (#3651).
Validate and fix invalid DisplayOrder data from ini file.
Allow TableHeaderRows() to function will missing TableSetupColumn() calls.
Made TableHeader() use AllowItemOverlap mode to allow submit subsequent item in same cell, since it covers the whole cell area.
This commit is contained in:
ocornut 2020-12-13 19:19:23 +01:00
parent 738606a294
commit f2df804fcc
2 changed files with 21 additions and 4 deletions

View File

@ -4749,6 +4749,7 @@ bool ImGui::IsItemEdited()
} }
// Allow last item to be overlapped by a subsequent item. Both may be activated during the same frame before the later one takes priority. // Allow last item to be overlapped by a subsequent item. Both may be activated during the same frame before the later one takes priority.
// FIXME: Although this is exposed, its interaction and ideal idiom with using ImGuiButtonFlags_AllowItemOverlap flag are extremely confusing, need rework.
void ImGui::SetItemAllowOverlap() void ImGui::SetItemAllowOverlap()
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;

View File

@ -1369,7 +1369,8 @@ const char* ImGui::TableGetColumnName(int column_n)
const char* ImGui::TableGetColumnName(const ImGuiTable* table, int column_n) const char* ImGui::TableGetColumnName(const ImGuiTable* table, int column_n)
{ {
IM_ASSERT(table->IsLayoutLocked == true || column_n <= table->DeclColumnsCount); // NameOffset is invalid otherwise if (table->IsLayoutLocked == false && column_n >= table->DeclColumnsCount)
return ""; // NameOffset is invalid at this point
const ImGuiTableColumn* column = &table->Columns[column_n]; const ImGuiTableColumn* column = &table->Columns[column_n];
if (column->NameOffset == -1) if (column->NameOffset == -1)
return ""; return "";
@ -1762,7 +1763,6 @@ void ImGui::TableBeginCell(ImGuiTable* table, int column_n)
window->DC.CursorMaxPos.x = window->DC.CursorPos.x; window->DC.CursorMaxPos.x = window->DC.CursorPos.x;
window->DC.ColumnsOffset.x = start_x - window->Pos.x - window->DC.Indent.x; // FIXME-WORKRECT window->DC.ColumnsOffset.x = start_x - window->Pos.x - window->DC.Indent.x; // FIXME-WORKRECT
window->DC.CurrLineTextBaseOffset = table->RowTextBaseline; window->DC.CurrLineTextBaseOffset = table->RowTextBaseline;
window->DC.LastItemId = 0;
window->DC.NavLayerCurrent = (ImGuiNavLayer)column->NavLayerCurrent; window->DC.NavLayerCurrent = (ImGuiNavLayer)column->NavLayerCurrent;
window->WorkRect.Min.y = window->DC.CursorPos.y; window->WorkRect.Min.y = window->DC.CursorPos.y;
@ -1775,6 +1775,12 @@ void ImGui::TableBeginCell(ImGuiTable* table, int column_n)
window->DC.CursorPos.y = ImMax(window->DC.CursorPos.y, table->RowPosY2); window->DC.CursorPos.y = ImMax(window->DC.CursorPos.y, table->RowPosY2);
window->SkipItems = column->IsSkipItems; window->SkipItems = column->IsSkipItems;
if (column->IsSkipItems)
{
window->DC.LastItemId = 0;
window->DC.LastItemStatusFlags = 0;
}
if (table->Flags & ImGuiTableFlags_NoClip) if (table->Flags & ImGuiTableFlags_NoClip)
{ {
// FIXME: if we end up drawing all borders/bg in EndTable, could remove this and just assert that channel hasn't changed. // FIXME: if we end up drawing all borders/bg in EndTable, could remove this and just assert that channel hasn't changed.
@ -2638,8 +2644,10 @@ void ImGui::TableHeader(const char* label)
//GetForegroundDrawList()->AddRect(cell_r.Min, cell_r.Max, IM_COL32(255, 0, 0, 255)); // [DEBUG] //GetForegroundDrawList()->AddRect(cell_r.Min, cell_r.Max, IM_COL32(255, 0, 0, 255)); // [DEBUG]
//GetForegroundDrawList()->AddRect(bb.Min, bb.Max, IM_COL32(255, 0, 0, 255)); // [DEBUG] //GetForegroundDrawList()->AddRect(bb.Min, bb.Max, IM_COL32(255, 0, 0, 255)); // [DEBUG]
// Using AllowItemOverlap mode because we cover the whole cell, and we want user to be able to submit subsequent items.
bool hovered, held; bool hovered, held;
bool pressed = ButtonBehavior(bb, id, &hovered, &held, ImGuiButtonFlags_None); bool pressed = ButtonBehavior(bb, id, &hovered, &held, ImGuiButtonFlags_AllowItemOverlap);
SetItemAllowOverlap();
if (hovered || selected) if (hovered || selected)
{ {
const ImU32 col = GetColorU32(held ? ImGuiCol_HeaderActive : hovered ? ImGuiCol_HeaderHovered : ImGuiCol_Header); const ImU32 col = GetColorU32(held ? ImGuiCol_HeaderActive : hovered ? ImGuiCol_HeaderHovered : ImGuiCol_Header);
@ -3025,6 +3033,7 @@ void ImGui::TableLoadSettings(ImGuiTable* table)
// Serialize ImGuiTableSettings/ImGuiTableColumnSettings into ImGuiTable/ImGuiTableColumn // Serialize ImGuiTableSettings/ImGuiTableColumnSettings into ImGuiTable/ImGuiTableColumn
ImGuiTableColumnSettings* column_settings = settings->GetColumnSettings(); ImGuiTableColumnSettings* column_settings = settings->GetColumnSettings();
ImU64 display_order_mask = 0;
for (int data_n = 0; data_n < settings->ColumnsCount; data_n++, column_settings++) for (int data_n = 0; data_n < settings->ColumnsCount; data_n++, column_settings++)
{ {
int column_n = column_settings->Index; int column_n = column_settings->Index;
@ -3044,12 +3053,19 @@ void ImGui::TableLoadSettings(ImGuiTable* table)
column->DisplayOrder = column_settings->DisplayOrder; column->DisplayOrder = column_settings->DisplayOrder;
else else
column->DisplayOrder = (ImGuiTableColumnIdx)column_n; column->DisplayOrder = (ImGuiTableColumnIdx)column_n;
display_order_mask |= (ImU64)1 << column->DisplayOrder;
column->IsEnabled = column->IsEnabledNextFrame = column_settings->IsEnabled; column->IsEnabled = column->IsEnabledNextFrame = column_settings->IsEnabled;
column->SortOrder = column_settings->SortOrder; column->SortOrder = column_settings->SortOrder;
column->SortDirection = column_settings->SortDirection; column->SortDirection = column_settings->SortDirection;
} }
// FIXME-TABLE: Need to validate .ini data // Validate and fix invalid display order data
const ImU64 expected_display_order_mask = (settings->ColumnsCount == 64) ? ~0 : ((ImU64)1 << settings->ColumnsCount) - 1;
if (display_order_mask != expected_display_order_mask)
for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
table->Columns[column_n].DisplayOrder = (ImGuiTableColumnIdx)column_n;
// Rebuild index
for (int column_n = 0; column_n < table->ColumnsCount; column_n++) for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
table->DisplayOrderToIndex[table->Columns[column_n].DisplayOrder] = (ImGuiTableColumnIdx)column_n; table->DisplayOrderToIndex[table->Columns[column_n].DisplayOrder] = (ImGuiTableColumnIdx)column_n;
} }