Tables: Internals: Added TableGetColumnResizeID(), renamed InstanceNo > InstanceCurrent.

This commit is contained in:
omar 2020-04-06 17:20:17 +02:00 committed by ocornut
parent 104b11051f
commit e60b5a3f75
2 changed files with 24 additions and 15 deletions

View File

@ -1959,7 +1959,7 @@ struct ImGuiTable
int ColumnsActiveCount; // Number of non-hidden columns (<= ColumnsCount) int ColumnsActiveCount; // Number of non-hidden columns (<= ColumnsCount)
int CurrentColumn; int CurrentColumn;
int CurrentRow; int CurrentRow;
ImS16 InstanceNo; // Count of BeginTable() calls with same ID in the same frame (generally 0) ImS16 InstanceCurrent; // Count of BeginTable() calls with same ID in the same frame (generally 0). This is a little bit similar to BeginCount for a window, but multiple table with same ID look are multiple tables, they are just synched.
ImS16 InstanceInteracted; // Mark which instance (generally 0) of the same ID is being interacted with ImS16 InstanceInteracted; // Mark which instance (generally 0) of the same ID is being interacted with
float RowPosY1; float RowPosY1;
float RowPosY2; float RowPosY2;
@ -2001,7 +2001,7 @@ struct ImGuiTable
ImS8 DeclColumnsCount; // Count calls to TableSetupColumn() ImS8 DeclColumnsCount; // Count calls to TableSetupColumn()
ImS8 HoveredColumnBody; // [DEBUG] Unlike HoveredColumnBorder this doesn't fulfill all Hovering rules properly. Used for debugging/tools for now. ImS8 HoveredColumnBody; // [DEBUG] Unlike HoveredColumnBorder this doesn't fulfill all Hovering rules properly. Used for debugging/tools for now.
ImS8 HoveredColumnBorder; // Index of column whose right-border is being hovered (for resizing). ImS8 HoveredColumnBorder; // Index of column whose right-border is being hovered (for resizing).
ImS8 ResizedColumn; // Index of column being resized. Reset by InstanceNo==0. ImS8 ResizedColumn; // Index of column being resized. Reset when InstanceCurrent==0.
ImS8 LastResizedColumn; // Index of column being resized from previous frame. ImS8 LastResizedColumn; // Index of column being resized from previous frame.
ImS8 HeldHeaderColumn; // Index of column header being held. ImS8 HeldHeaderColumn; // Index of column header being held.
ImS8 ReorderColumn; // Index of column being reordered. (not cleared) ImS8 ReorderColumn; // Index of column being reordered. (not cleared)
@ -2264,6 +2264,7 @@ namespace ImGui
IMGUI_API void TableEndCell(ImGuiTable* table); IMGUI_API void TableEndCell(ImGuiTable* table);
IMGUI_API ImRect TableGetCellRect(); IMGUI_API ImRect TableGetCellRect();
IMGUI_API const char* TableGetColumnName(ImGuiTable* table, int column_n); IMGUI_API const char* TableGetColumnName(ImGuiTable* table, int column_n);
IMGUI_API ImGuiID TableGetColumnResizeID(ImGuiTable* table, int column_n, int instance_no = 0);
IMGUI_API void TableSetColumnAutofit(ImGuiTable* table, int column_n); IMGUI_API void TableSetColumnAutofit(ImGuiTable* table, int column_n);
IMGUI_API void PushTableBackground(); IMGUI_API void PushTableBackground();
IMGUI_API void PopTableBackground(); IMGUI_API void PopTableBackground();

View File

@ -186,7 +186,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
// Acquire storage for the table // Acquire storage for the table
ImGuiTable* table = g.Tables.GetOrAddByKey(id); ImGuiTable* table = g.Tables.GetOrAddByKey(id);
const ImGuiTableFlags table_last_flags = table->Flags; const ImGuiTableFlags table_last_flags = table->Flags;
const int instance_no = (table->LastFrameActive != g.FrameCount) ? 0 : table->InstanceNo + 1; const int instance_no = (table->LastFrameActive != g.FrameCount) ? 0 : table->InstanceCurrent + 1;
const ImGuiID instance_id = id + instance_no; const ImGuiID instance_id = id + instance_no;
if (instance_no > 0) if (instance_no > 0)
IM_ASSERT(table->ColumnsCount == columns_count && "BeginTable(): Cannot change columns count mid-frame while preserving same ID"); IM_ASSERT(table->ColumnsCount == columns_count && "BeginTable(): Cannot change columns count mid-frame while preserving same ID");
@ -194,7 +194,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
// Initialize // Initialize
table->ID = id; table->ID = id;
table->Flags = flags; table->Flags = flags;
table->InstanceNo = (ImS16)instance_no; table->InstanceCurrent = (ImS16)instance_no;
table->LastFrameActive = g.FrameCount; table->LastFrameActive = g.FrameCount;
table->OuterWindow = table->InnerWindow = outer_window; table->OuterWindow = table->InnerWindow = outer_window;
table->ColumnsCount = columns_count; table->ColumnsCount = columns_count;
@ -332,7 +332,7 @@ void ImGui::TableBeginUpdateColumns(ImGuiTable* table)
// (We process this at the first TableBegin of the frame) // (We process this at the first TableBegin of the frame)
// FIXME-TABLE: Preserve contents width _while resizing down_ until releasing. // FIXME-TABLE: Preserve contents width _while resizing down_ until releasing.
// FIXME-TABLE: Contains columns if our work area doesn't allow for scrolling. // FIXME-TABLE: Contains columns if our work area doesn't allow for scrolling.
if (table->InstanceNo == 0) if (table->InstanceCurrent == 0)
{ {
if (table->ResizedColumn != -1 && table->ResizedColumnNextWidth != FLT_MAX) if (table->ResizedColumn != -1 && table->ResizedColumnNextWidth != FLT_MAX)
TableSetColumnWidth(table, &table->Columns[table->ResizedColumn], table->ResizedColumnNextWidth); TableSetColumnWidth(table, &table->Columns[table->ResizedColumn], table->ResizedColumnNextWidth);
@ -343,7 +343,7 @@ void ImGui::TableBeginUpdateColumns(ImGuiTable* table)
// Handle reordering request // Handle reordering request
// Note: we don't clear ReorderColumn after handling the request. // Note: we don't clear ReorderColumn after handling the request.
if (table->InstanceNo == 0) if (table->InstanceCurrent == 0)
{ {
if (table->HeldHeaderColumn == -1 && table->ReorderColumn != -1) if (table->HeldHeaderColumn == -1 && table->ReorderColumn != -1)
table->ReorderColumn = -1; table->ReorderColumn = -1;
@ -799,7 +799,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
table->IsUsingHeaders = false; table->IsUsingHeaders = false;
// Context menu // Context menu
if (table->IsContextPopupOpen && table->InstanceNo == table->InstanceInteracted) if (table->IsContextPopupOpen && table->InstanceCurrent == table->InstanceInteracted)
{ {
if (BeginPopup("##TableContextMenu")) if (BeginPopup("##TableContextMenu"))
{ {
@ -856,7 +856,7 @@ void ImGui::TableUpdateBorders(ImGuiTable* table)
if (column->Flags & (ImGuiTableColumnFlags_NoResize | ImGuiTableColumnFlags_NoDirectResize_)) if (column->Flags & (ImGuiTableColumnFlags_NoResize | ImGuiTableColumnFlags_NoDirectResize_))
continue; continue;
ImGuiID column_id = table->ID + (table->InstanceNo * table->ColumnsCount) + column_n; ImGuiID column_id = TableGetColumnResizeID(table, column_n, table->InstanceCurrent);
ImRect hit_rect(column->MaxX - hit_half_width, hit_y1, column->MaxX + hit_half_width, hit_y2); ImRect hit_rect(column->MaxX - hit_half_width, hit_y1, column->MaxX + hit_half_width, hit_y2);
//GetForegroundDrawList()->AddRect(hit_rect.Min, hit_rect.Max, IM_COL32(255, 0, 0, 100)); //GetForegroundDrawList()->AddRect(hit_rect.Min, hit_rect.Max, IM_COL32(255, 0, 0, 100));
KeepAliveID(column_id); KeepAliveID(column_id);
@ -873,7 +873,7 @@ void ImGui::TableUpdateBorders(ImGuiTable* table)
if (held) if (held)
{ {
table->ResizedColumn = (ImS8)column_n; table->ResizedColumn = (ImS8)column_n;
table->InstanceInteracted = table->InstanceNo; table->InstanceInteracted = table->InstanceCurrent;
} }
if ((hovered && g.HoveredIdTimer > TABLE_RESIZE_SEPARATOR_FEEDBACK_TIMER) || held) if ((hovered && g.HoveredIdTimer > TABLE_RESIZE_SEPARATOR_FEEDBACK_TIMER) || held)
{ {
@ -963,7 +963,7 @@ void ImGui::EndTable()
{ {
inner_window->Scroll.x = 0.0f; inner_window->Scroll.x = 0.0f;
} }
else if (table->LastResizedColumn != -1 && table->ResizedColumn == -1 && inner_window->ScrollbarX && table->InstanceInteracted == table->InstanceNo) else if (table->LastResizedColumn != -1 && table->ResizedColumn == -1 && inner_window->ScrollbarX && table->InstanceInteracted == table->InstanceCurrent)
{ {
ImGuiTableColumn* column = &table->Columns[table->LastResizedColumn]; ImGuiTableColumn* column = &table->Columns[table->LastResizedColumn];
if (column->MaxX < table->InnerClipRect.Min.x) if (column->MaxX < table->InnerClipRect.Min.x)
@ -1052,7 +1052,7 @@ void ImGui::TableDrawBorders(ImGuiTable* table)
const int column_n = table->DisplayOrderToIndex[order_n]; const int column_n = table->DisplayOrderToIndex[order_n];
ImGuiTableColumn* column = &table->Columns[column_n]; ImGuiTableColumn* column = &table->Columns[column_n];
const bool is_hovered = (table->HoveredColumnBorder == column_n); const bool is_hovered = (table->HoveredColumnBorder == column_n);
const bool is_resized = (table->ResizedColumn == column_n) && (table->InstanceInteracted == table->InstanceNo); const bool is_resized = (table->ResizedColumn == column_n) && (table->InstanceInteracted == table->InstanceCurrent);
const bool is_resizable = (column->Flags & (ImGuiTableColumnFlags_NoResize | ImGuiTableColumnFlags_NoDirectResize_)) == 0; const bool is_resizable = (column->Flags & (ImGuiTableColumnFlags_NoResize | ImGuiTableColumnFlags_NoDirectResize_)) == 0;
bool draw_right_border = (column->MaxX <= table->InnerClipRect.Max.x) || (is_resized || is_hovered); bool draw_right_border = (column->MaxX <= table->InnerClipRect.Max.x) || (is_resized || is_hovered);
if (column->NextActiveColumn == -1 && !is_resizable) if (column->NextActiveColumn == -1 && !is_resizable)
@ -1769,6 +1769,14 @@ const char* ImGui::TableGetColumnName(ImGuiTable* table, int column_n)
return &table->ColumnsNames.Buf[column->NameOffset]; return &table->ColumnsNames.Buf[column->NameOffset];
} }
// Return the resizing ID for the right-side of the given column.
ImGuiID ImGui::TableGetColumnResizeID(ImGuiTable* table, int column_n, int instance_no)
{
IM_ASSERT(column_n < table->ColumnsCount);
ImGuiID id = table->ID + (instance_no * table->ColumnsCount) + column_n;
return id;
}
void ImGui::TableSetColumnAutofit(ImGuiTable* table, int column_n) void ImGui::TableSetColumnAutofit(ImGuiTable* table, int column_n)
{ {
// Disable clipping then auto-fit, will take 2 frames // Disable clipping then auto-fit, will take 2 frames
@ -1917,7 +1925,7 @@ void ImGui::TableAutoHeaders()
//if (g.IO.KeyCtrl) { static char buf[32]; name = buf; ImGuiTableColumn* c = &table->Columns[column_n]; if (c->Flags & ImGuiTableColumnFlags_WidthStretch) ImFormatString(buf, 32, "%.3f>%.1f", c->ResizeWeight, c->WidthGiven); else ImFormatString(buf, 32, "%.1f", c->WidthGiven); } //if (g.IO.KeyCtrl) { static char buf[32]; name = buf; ImGuiTableColumn* c = &table->Columns[column_n]; if (c->Flags & ImGuiTableColumnFlags_WidthStretch) ImFormatString(buf, 32, "%.3f>%.1f", c->ResizeWeight, c->WidthGiven); else ImFormatString(buf, 32, "%.1f", c->WidthGiven); }
// Push an id to allow unnamed labels (generally accidental, but let's behave nicely with them) // Push an id to allow unnamed labels (generally accidental, but let's behave nicely with them)
PushID(table->InstanceNo * table->ColumnsCount + column_n); PushID(table->InstanceCurrent * table->ColumnsCount + column_n);
TableHeader(name); TableHeader(name);
PopID(); PopID();
@ -1964,7 +1972,7 @@ void ImGui::TableAutoHeaders()
{ {
table->IsContextPopupOpen = true; table->IsContextPopupOpen = true;
table->ContextPopupColumn = (ImS8)open_context_popup; table->ContextPopupColumn = (ImS8)open_context_popup;
table->InstanceInteracted = table->InstanceNo; table->InstanceInteracted = table->InstanceCurrent;
OpenPopup("##TableContextMenu"); OpenPopup("##TableContextMenu");
} }
} }
@ -2011,7 +2019,7 @@ void ImGui::TableHeader(const char* label)
//window->DC.CursorPos.x = column->MinX + table->CellPadding.x; //window->DC.CursorPos.x = column->MinX + table->CellPadding.x;
// Keep header highlighted when context menu is open. (FIXME-TABLE: however we cannot assume the ID of said popup if it has been created by the user...) // Keep header highlighted when context menu is open. (FIXME-TABLE: however we cannot assume the ID of said popup if it has been created by the user...)
const bool selected = (table->IsContextPopupOpen && table->ContextPopupColumn == column_n && table->InstanceInteracted == table->InstanceNo); const bool selected = (table->IsContextPopupOpen && table->ContextPopupColumn == column_n && table->InstanceInteracted == table->InstanceCurrent);
const bool pressed = Selectable("", selected, ImGuiSelectableFlags_DrawHoveredWhenHeld | ImGuiSelectableFlags_DontClosePopups, ImVec2(0.0f, label_height)); const bool pressed = Selectable("", selected, ImGuiSelectableFlags_DrawHoveredWhenHeld | ImGuiSelectableFlags_DontClosePopups, ImVec2(0.0f, label_height));
const bool held = IsItemActive(); const bool held = IsItemActive();
if (held) if (held)
@ -2024,7 +2032,7 @@ void ImGui::TableHeader(const char* label)
{ {
// While moving a column it will jump on the other side of the mouse, so we also test for MouseDelta.x // While moving a column it will jump on the other side of the mouse, so we also test for MouseDelta.x
table->ReorderColumn = (ImS8)column_n; table->ReorderColumn = (ImS8)column_n;
table->InstanceInteracted = table->InstanceNo; table->InstanceInteracted = table->InstanceCurrent;
// We don't reorder: through the frozen<>unfrozen line, or through a column that is marked with ImGuiTableColumnFlags_NoReorder. // We don't reorder: through the frozen<>unfrozen line, or through a column that is marked with ImGuiTableColumnFlags_NoReorder.
if (g.IO.MouseDelta.x < 0.0f && g.IO.MousePos.x < cell_r.Min.x) if (g.IO.MouseDelta.x < 0.0f && g.IO.MousePos.x < cell_r.Min.x)