Tables: Added ImGuiTableFlags_ContextMenuInBody flag.

Worked to get TableOpenContextMenu() in public API but kept it internal.
This commit is contained in:
ocornut 2020-10-01 19:54:10 +02:00
parent 6182973bde
commit e66b28693a
4 changed files with 85 additions and 33 deletions

29
imgui.h
View File

@ -1056,28 +1056,29 @@ enum ImGuiTableFlags_
ImGuiTableFlags_Sortable = 1 << 3, // Allow sorting on one column (sort_specs_count will always be == 1). Call TableGetSortSpecs() to obtain sort specs. ImGuiTableFlags_Sortable = 1 << 3, // Allow sorting on one column (sort_specs_count will always be == 1). Call TableGetSortSpecs() to obtain sort specs.
ImGuiTableFlags_MultiSortable = 1 << 4, // Allow sorting on multiple columns by holding Shift (sort_specs_count may be > 1). Call TableGetSortSpecs() to obtain sort specs. ImGuiTableFlags_MultiSortable = 1 << 4, // Allow sorting on multiple columns by holding Shift (sort_specs_count may be > 1). Call TableGetSortSpecs() to obtain sort specs.
ImGuiTableFlags_NoSavedSettings = 1 << 5, // Disable persisting columns order, width and sort settings in the .ini file. ImGuiTableFlags_NoSavedSettings = 1 << 5, // Disable persisting columns order, width and sort settings in the .ini file.
ImGuiTableFlags_ContextMenuInBody = 1 << 6, // Right-click on columns body/contents will display table context menu. By default it is available in TableHeadersRow().
// Decoration // Decoration
ImGuiTableFlags_RowBg = 1 << 6, // Set each RowBg color with ImGuiCol_TableRowBg or ImGuiCol_TableRowBgAlt (equivalent to calling TableSetBgColor with ImGuiTableBgFlags_RowBg0 on each row manually) ImGuiTableFlags_RowBg = 1 << 7, // Set each RowBg color with ImGuiCol_TableRowBg or ImGuiCol_TableRowBgAlt (equivalent to calling TableSetBgColor with ImGuiTableBgFlags_RowBg0 on each row manually)
ImGuiTableFlags_BordersInnerH = 1 << 7, // Draw horizontal borders between rows. ImGuiTableFlags_BordersInnerH = 1 << 8, // Draw horizontal borders between rows.
ImGuiTableFlags_BordersOuterH = 1 << 8, // Draw horizontal borders at the top and bottom. ImGuiTableFlags_BordersOuterH = 1 << 9, // Draw horizontal borders at the top and bottom.
ImGuiTableFlags_BordersInnerV = 1 << 9, // Draw vertical borders between columns. ImGuiTableFlags_BordersInnerV = 1 << 10, // Draw vertical borders between columns.
ImGuiTableFlags_BordersOuterV = 1 << 10, // Draw vertical borders on the left and right sides. ImGuiTableFlags_BordersOuterV = 1 << 11, // Draw vertical borders on the left and right sides.
ImGuiTableFlags_BordersH = ImGuiTableFlags_BordersInnerH | ImGuiTableFlags_BordersOuterH, // Draw horizontal borders. ImGuiTableFlags_BordersH = ImGuiTableFlags_BordersInnerH | ImGuiTableFlags_BordersOuterH, // Draw horizontal borders.
ImGuiTableFlags_BordersV = ImGuiTableFlags_BordersInnerV | ImGuiTableFlags_BordersOuterV, // Draw vertical borders. ImGuiTableFlags_BordersV = ImGuiTableFlags_BordersInnerV | ImGuiTableFlags_BordersOuterV, // Draw vertical borders.
ImGuiTableFlags_BordersInner = ImGuiTableFlags_BordersInnerV | ImGuiTableFlags_BordersInnerH, // Draw inner borders. ImGuiTableFlags_BordersInner = ImGuiTableFlags_BordersInnerV | ImGuiTableFlags_BordersInnerH, // Draw inner borders.
ImGuiTableFlags_BordersOuter = ImGuiTableFlags_BordersOuterV | ImGuiTableFlags_BordersOuterH, // Draw outer borders. ImGuiTableFlags_BordersOuter = ImGuiTableFlags_BordersOuterV | ImGuiTableFlags_BordersOuterH, // Draw outer borders.
ImGuiTableFlags_Borders = ImGuiTableFlags_BordersInner | ImGuiTableFlags_BordersOuter, // Draw all borders. ImGuiTableFlags_Borders = ImGuiTableFlags_BordersInner | ImGuiTableFlags_BordersOuter, // Draw all borders.
ImGuiTableFlags_BordersFullHeightV = 1 << 11, // Borders covers all rows even when Headers are being used. Allow resizing from any rows. ImGuiTableFlags_BordersFullHeightV = 1 << 12, // Borders covers all rows even when Headers are being used. Allow resizing from any rows.
// Padding, Sizing // Padding, Sizing
ImGuiTableFlags_SizingPolicyFixedX = 1 << 12, // Default if ScrollX is on. Columns will default to use _WidthFixed or _WidthAlwaysAutoResize policy. Read description above for more details. ImGuiTableFlags_SizingPolicyFixedX = 1 << 13, // Default if ScrollX is on. Columns will default to use _WidthFixed or _WidthAlwaysAutoResize policy. Read description above for more details.
ImGuiTableFlags_SizingPolicyStretchX = 1 << 13, // Default if ScrollX is off. Columns will default to use _WidthStretch policy. Read description above for more details. ImGuiTableFlags_SizingPolicyStretchX = 1 << 14, // Default if ScrollX is off. Columns will default to use _WidthStretch policy. Read description above for more details.
ImGuiTableFlags_NoHeadersWidth = 1 << 14, // Disable header width contribution to automatic width calculation. ImGuiTableFlags_NoHeadersWidth = 1 << 15, // Disable header width contribution to automatic width calculation.
ImGuiTableFlags_NoHostExtendY = 1 << 15, // (FIXME-TABLE: Reword as SizingPolicy?) Disable extending past the limit set by outer_size.y, only meaningful when neither of ScrollX|ScrollY are set (data below the limit will be clipped and not visible) ImGuiTableFlags_NoHostExtendY = 1 << 16, // (FIXME-TABLE: Reword as SizingPolicy?) Disable extending past the limit set by outer_size.y, only meaningful when neither of ScrollX|ScrollY are set (data below the limit will be clipped and not visible)
ImGuiTableFlags_NoKeepColumnsVisible = 1 << 16, // (FIXME-TABLE) Disable code that keeps column always minimally visible when table width gets too small and horizontal scrolling is off. ImGuiTableFlags_NoKeepColumnsVisible = 1 << 17, // (FIXME-TABLE) Disable code that keeps column always minimally visible when table width gets too small and horizontal scrolling is off.
ImGuiTableFlags_NoClip = 1 << 17, // Disable clipping rectangle for every individual columns (reduce draw command count, items will be able to overflow into other columns). Generally incompatible with ScrollFreeze options. ImGuiTableFlags_NoClip = 1 << 18, // Disable clipping rectangle for every individual columns (reduce draw command count, items will be able to overflow into other columns). Generally incompatible with ScrollFreeze options.
// Scrolling // Scrolling
ImGuiTableFlags_ScrollX = 1 << 20, // Enable horizontal scrolling. Require 'outer_size' parameter of BeginTable() to specify the container size. Because this create a child window, ScrollY is currently generally recommended when using ScrollX. ImGuiTableFlags_ScrollX = 1 << 19, // Enable horizontal scrolling. Require 'outer_size' parameter of BeginTable() to specify the container size. Because this create a child window, ScrollY is currently generally recommended when using ScrollX.
ImGuiTableFlags_ScrollY = 1 << 21, // Enable vertical scrolling. Require 'outer_size' parameter of BeginTable() to specify the container size. ImGuiTableFlags_ScrollY = 1 << 20, // Enable vertical scrolling. Require 'outer_size' parameter of BeginTable() to specify the container size.
ImGuiTableFlags_Scroll = ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY, ImGuiTableFlags_Scroll = ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY,
// [Internal] Combinations and masks // [Internal] Combinations and masks

View File

@ -4104,54 +4104,91 @@ static void ShowDemoWindowTables()
ImGui::SetNextItemOpen(open_action != 0); ImGui::SetNextItemOpen(open_action != 0);
if (ImGui::TreeNode("Context menus")) if (ImGui::TreeNode("Context menus"))
{ {
HelpMarker("By default, TableHeadersRow()/TableHeader() will open a context-menu on right-click."); HelpMarker("By default, right-clicking over a TableHeadersRow()/TableHeader() line will open the default context-menu.\nUsing ImGuiTableFlags_ContextMenuInBody we also allow right-clicking over columns body.");
ImGuiTableFlags flags = ImGuiTableFlags_Resizable | ImGuiTableFlags_SizingPolicyFixedX | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable | ImGuiTableFlags_Borders; static ImGuiTableFlags flags1 = ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable | ImGuiTableFlags_Borders | ImGuiTableFlags_ContextMenuInBody;
ImGui::CheckboxFlags("ImGuiTableFlags_ContextMenuInBody", (unsigned int*)&flags1, ImGuiTableFlags_ContextMenuInBody);
// Context Menus: first example
// [1.1] Right-click on the TableHeadersRow() line to open the default table context menu.
// [1.2] Right-click in columns also open the default table context menu (if ImGuiTableFlags_ContextMenuInBody is set)
const int COLUMNS_COUNT = 3; const int COLUMNS_COUNT = 3;
if (ImGui::BeginTable("##table1", COLUMNS_COUNT, flags)) if (ImGui::BeginTable("##table1", COLUMNS_COUNT, flags1))
{ {
ImGui::TableSetupColumn("One"); ImGui::TableSetupColumn("One");
ImGui::TableSetupColumn("Two"); ImGui::TableSetupColumn("Two");
ImGui::TableSetupColumn("Three"); ImGui::TableSetupColumn("Three");
// Context Menu 1: right-click on header (including empty section after the third column!) should open Default Table Popup // [1.1]] Right-click on the TableHeadersRow() line to open the default table context menu.
ImGui::TableHeadersRow(); ImGui::TableHeadersRow();
// Submit dummy contents
for (int row = 0; row < 4; row++) for (int row = 0; row < 4; row++)
{ {
ImGui::TableNextRow(); ImGui::TableNextRow();
for (int column = 0; column < COLUMNS_COUNT; column++) for (int column = 0; column < COLUMNS_COUNT; column++)
{ {
ImGui::TableSetColumnIndex(column); ImGui::TableSetColumnIndex(column);
ImGui::PushID(row * COLUMNS_COUNT + column); ImGui::Text("Cell %d,%d", 0, row);
}
}
ImGui::EndTable();
}
// Context Menus: second example
// [2.1] Right-click on the TableHeadersRow() line to open the default table context menu.
// [2.2] Right-click on the ".." to open a custom popup
// [2.3] Right-click in columns to open another custom popup
HelpMarker("Demonstrate mixing table context menu (over header), item context button (over button) and custom per-colum context menu (over column body).");
ImGuiTableFlags flags2 = ImGuiTableFlags_Resizable | ImGuiTableFlags_SizingPolicyFixedX | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable | ImGuiTableFlags_Borders;
if (ImGui::BeginTable("##table2", COLUMNS_COUNT, flags2))
{
ImGui::TableSetupColumn("One");
ImGui::TableSetupColumn("Two");
ImGui::TableSetupColumn("Three");
// [2.1] Right-click on the TableHeadersRow() line to open the default table context menu.
ImGui::TableHeadersRow();
for (int row = 0; row < 4; row++)
{
ImGui::TableNextRow();
for (int column = 0; column < COLUMNS_COUNT; column++)
{
// Submit dummy contents
ImGui::TableSetColumnIndex(column);
ImGui::Text("Cell %d,%d", column, row); ImGui::Text("Cell %d,%d", column, row);
ImGui::SameLine(); ImGui::SameLine();
// Context Menu 2: right-click on buttons open Custom Button Popup // [2.2] Right-click on the ".." to open a custom popup
ImGui::PushID(row * COLUMNS_COUNT + column);
ImGui::SmallButton(".."); ImGui::SmallButton("..");
if (ImGui::BeginPopupContextItem()) if (ImGui::BeginPopupContextItem())
{ {
ImGui::Text("This is the popup for Button() On Cell %d,%d", column, row); ImGui::Text("This is the popup for Button(\"..\") in Cell %d,%d", column, row);
ImGui::Selectable("Close"); if (ImGui::Button("Close"))
ImGui::CloseCurrentPopup();
ImGui::EndPopup(); ImGui::EndPopup();
} }
ImGui::PopID(); ImGui::PopID();
} }
} }
// Context Menu 3: Right-click anywhere in columns opens a custom popup // [2.3] Right-click anywhere in columns to open another custom popup
// We use the ImGuiPopupFlags_NoOpenOverExistingPopup flag to avoid displaying over either the standard TableHeader context-menu or the Button context-menu. // (instead of testing for !IsAnyItemHovered() we could also call OpenPopup() with ImGuiPopupFlags_NoOpenOverExistingPopup
// to manage popup priority as the popups triggers, here "are we hovering a column" are overlapping)
const int hovered_column = ImGui::TableGetHoveredColumn(); const int hovered_column = ImGui::TableGetHoveredColumn();
for (int column = 0; column < COLUMNS_COUNT + 1; column++) for (int column = 0; column < COLUMNS_COUNT + 1; column++)
{ {
ImGui::PushID(column); ImGui::PushID(column);
if (hovered_column == column && ImGui::IsMouseReleased(1)) if (hovered_column == column && !ImGui::IsAnyItemHovered() && ImGui::IsMouseReleased(1))
ImGui::OpenPopup("MyPopup", ImGuiPopupFlags_NoOpenOverExistingPopup); ImGui::OpenPopup("MyPopup");
if (ImGui::BeginPopup("MyPopup")) if (ImGui::BeginPopup("MyPopup"))
{ {
if (column == COLUMNS_COUNT) if (column == COLUMNS_COUNT)
ImGui::Text("This is the popup for unused space after the last column."); ImGui::Text("This is a custom popup for unused space after the last column.");
else else
ImGui::Text("This is the popup for Column '%s'", ImGui::TableGetColumnName(column)); ImGui::Text("This is a custom popup for Column %d", column);
ImGui::Selectable("Close"); if (ImGui::Button("Close"))
ImGui::CloseCurrentPopup();
ImGui::EndPopup(); ImGui::EndPopup();
} }
ImGui::PopID(); ImGui::PopID();
@ -4289,6 +4326,7 @@ static void ShowDemoWindowTables()
ImGui::CheckboxFlags("ImGuiTableFlags_Sortable", (unsigned int*)&flags, ImGuiTableFlags_Sortable); ImGui::CheckboxFlags("ImGuiTableFlags_Sortable", (unsigned int*)&flags, ImGuiTableFlags_Sortable);
ImGui::CheckboxFlags("ImGuiTableFlags_MultiSortable", (unsigned int*)&flags, ImGuiTableFlags_MultiSortable); ImGui::CheckboxFlags("ImGuiTableFlags_MultiSortable", (unsigned int*)&flags, ImGuiTableFlags_MultiSortable);
ImGui::CheckboxFlags("ImGuiTableFlags_NoSavedSettings", (unsigned int*)&flags, ImGuiTableFlags_NoSavedSettings); ImGui::CheckboxFlags("ImGuiTableFlags_NoSavedSettings", (unsigned int*)&flags, ImGuiTableFlags_NoSavedSettings);
ImGui::CheckboxFlags("ImGuiTableFlags_ContextMenuInBody", (unsigned int*)&flags, ImGuiTableFlags_ContextMenuInBody);
ImGui::Unindent(); ImGui::Unindent();
ImGui::BulletText("Decoration:"); ImGui::BulletText("Decoration:");

View File

@ -2276,7 +2276,7 @@ namespace ImGui
IMGUI_API void TableSetColumnWidth(ImGuiTable* table, ImGuiTableColumn* column, float width); IMGUI_API void TableSetColumnWidth(ImGuiTable* table, ImGuiTableColumn* column, float width);
IMGUI_API void TableDrawBorders(ImGuiTable* table); IMGUI_API void TableDrawBorders(ImGuiTable* table);
IMGUI_API void TableDrawContextMenu(ImGuiTable* table); IMGUI_API void TableDrawContextMenu(ImGuiTable* table);
IMGUI_API void TableOpenContextMenu(ImGuiTable* table, int column_n); IMGUI_API void TableOpenContextMenu(int column_n = -1);
IMGUI_API void TableReorderDrawChannelsForMerge(ImGuiTable* table); IMGUI_API void TableReorderDrawChannelsForMerge(ImGuiTable* table);
IMGUI_API void TableSetColumnSortDirection(ImGuiTable* table, int column_n, ImGuiSortDirection sort_direction, bool append_to_sort_specs); IMGUI_API void TableSetColumnSortDirection(ImGuiTable* table, int column_n, ImGuiSortDirection sort_direction, bool append_to_sort_specs);
IMGUI_API void TableSortSpecsSanitize(ImGuiTable* table); IMGUI_API void TableSortSpecsSanitize(ImGuiTable* table);

View File

@ -1002,6 +1002,11 @@ void ImGui::EndTable()
if (table->IsInsideRow) if (table->IsInsideRow)
TableEndRow(table); TableEndRow(table);
// Context menu in columns body
if (flags & ImGuiTableFlags_ContextMenuInBody)
if (table->HoveredColumnBody != -1 && !ImGui::IsAnyItemHovered() && ImGui::IsMouseReleased(ImGuiMouseButton_Right))
TableOpenContextMenu((int)table->HoveredColumnBody);
// Finalize table height // Finalize table height
inner_window->SkipItems = table->HostSkipItems; inner_window->SkipItems = table->HostSkipItems;
inner_window->DC.CursorMaxPos = table->HostCursorMaxPos; inner_window->DC.CursorMaxPos = table->HostCursorMaxPos;
@ -2040,6 +2045,7 @@ void ImGui::TableDrawContextMenu(ImGuiTable* table)
} }
// Sorting // Sorting
// (modify TableOpenContextMenu() to add _Sortable flag if enabling this)
#if 0 #if 0
if ((table->Flags & ImGuiTableFlags_Sortable) && column != NULL && (column->Flags & ImGuiTableColumnFlags_NoSort) == 0) if ((table->Flags & ImGuiTableFlags_Sortable) && column != NULL && (column->Flags & ImGuiTableColumnFlags_NoSort) == 0)
{ {
@ -2082,8 +2088,14 @@ void ImGui::TableDrawContextMenu(ImGuiTable* table)
} }
// Use -1 to open menu not specific to a given column. // Use -1 to open menu not specific to a given column.
void ImGui::TableOpenContextMenu(ImGuiTable* table, int column_n) void ImGui::TableOpenContextMenu(int column_n)
{ {
ImGuiContext& g = *GImGui;
ImGuiTable* table = g.CurrentTable;
if (column_n == -1 && table->CurrentColumn != -1) // When called within a column automatically use this one (for consistency)
column_n = table->CurrentColumn;
if (column_n == table->ColumnsCount) // To facilitate using with TableGetHoveredColumn()
column_n = -1;
IM_ASSERT(column_n >= -1 && column_n < table->ColumnsCount); IM_ASSERT(column_n >= -1 && column_n < table->ColumnsCount);
if (table->Flags & (ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable)) if (table->Flags & (ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable))
{ {
@ -2157,7 +2169,7 @@ void ImGui::TableHeadersRow()
ImVec2 mouse_pos = ImGui::GetMousePos(); ImVec2 mouse_pos = ImGui::GetMousePos();
if (IsMouseReleased(1) && TableGetHoveredColumn() == columns_count) if (IsMouseReleased(1) && TableGetHoveredColumn() == columns_count)
if (mouse_pos.y >= row_y1 && mouse_pos.y < row_y1 + row_height) if (mouse_pos.y >= row_y1 && mouse_pos.y < row_y1 + row_height)
TableOpenContextMenu(table, -1); // Will open a non-column-specific popup. TableOpenContextMenu(-1); // Will open a non-column-specific popup.
} }
// Emit a column header (text + optional sort order) // Emit a column header (text + optional sort order)
@ -2297,7 +2309,7 @@ void ImGui::TableHeader(const char* label)
// We don't use BeginPopupContextItem() because we want the popup to stay up even after the column is hidden // We don't use BeginPopupContextItem() because we want the popup to stay up even after the column is hidden
if (IsMouseReleased(1) && IsItemHovered()) if (IsMouseReleased(1) && IsItemHovered())
TableOpenContextMenu(table, column_n); TableOpenContextMenu(column_n);
} }
// Note that the NoSortAscending/NoSortDescending flags are processed in TableSortSpecsSanitize(), and they may change/revert // Note that the NoSortAscending/NoSortDescending flags are processed in TableSortSpecsSanitize(), and they may change/revert
@ -2359,6 +2371,7 @@ bool ImGui::TableGetColumnIsSorted(int column_n)
return (column->SortOrder != -1); return (column->SortOrder != -1);
} }
// Return -1 when table is not hovered. return columns_count if the unused space at the right of visible columns is hovered.
int ImGui::TableGetHoveredColumn() int ImGui::TableGetHoveredColumn()
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;