Tables: Added TableSetColumnSortDirection() + added in default context menu code (disabled, feels unnecessary, but work is done to ensure programmatic access)

This commit is contained in:
ocornut 2020-09-24 15:10:47 +02:00
parent 9b37087fbe
commit cc12ea084b
3 changed files with 64 additions and 46 deletions

View File

@ -1073,7 +1073,7 @@ enum ImGuiTableFlags_
ImGuiTableFlags_Scroll = ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY, ImGuiTableFlags_Scroll = ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY,
// [Internal] Combinations and masks // [Internal] Combinations and masks
ImGuiTableFlags_SizingPolicyMaskX_ = ImGuiTableFlags_SizingPolicyStretchX | ImGuiTableFlags_SizingPolicyFixedX, ImGuiTableFlags_SizingPolicyMaskX_ = ImGuiTableFlags_SizingPolicyStretchX | ImGuiTableFlags_SizingPolicyFixedX
}; };
// Flags for ImGui::TableSetupColumn() // Flags for ImGui::TableSetupColumn()

View File

@ -2278,7 +2278,7 @@ namespace ImGui
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(ImGuiTable* table, int column_n);
IMGUI_API void TableReorderDrawChannelsForMerge(ImGuiTable* table); IMGUI_API void TableReorderDrawChannelsForMerge(ImGuiTable* table);
IMGUI_API void TableSortSpecsClickColumn(ImGuiTable* table, ImGuiTableColumn* column, bool add_to_existing_sort_orders); 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);
IMGUI_API void TableSortSpecsBuild(ImGuiTable* table); IMGUI_API void TableSortSpecsBuild(ImGuiTable* table);
IMGUI_API void TableBeginRow(ImGuiTable* table); IMGUI_API void TableBeginRow(ImGuiTable* table);
@ -2292,7 +2292,7 @@ namespace ImGui
IMGUI_API void PushTableBackground(); IMGUI_API void PushTableBackground();
IMGUI_API void PopTableBackground(); IMGUI_API void PopTableBackground();
// Tables - Settings // Tables: Settings
IMGUI_API void TableLoadSettings(ImGuiTable* table); IMGUI_API void TableLoadSettings(ImGuiTable* table);
IMGUI_API void TableSaveSettings(ImGuiTable* table); IMGUI_API void TableSaveSettings(ImGuiTable* table);
IMGUI_API ImGuiTableSettings* TableGetBoundSettings(ImGuiTable* table); IMGUI_API ImGuiTableSettings* TableGetBoundSettings(ImGuiTable* table);

View File

@ -1998,25 +1998,26 @@ void ImGui::TableDrawContextMenu(ImGuiTable* table)
return; return;
bool want_separator = false; bool want_separator = false;
const int selected_column_n = (table->ContextPopupColumn >= 0 && table->ContextPopupColumn < table->ColumnsCount) ? table->ContextPopupColumn : -1; const int column_n = (table->ContextPopupColumn >= 0 && table->ContextPopupColumn < table->ColumnsCount) ? table->ContextPopupColumn : -1;
ImGuiTableColumn* column = (column_n != -1) ? &table->Columns[column_n] : NULL;
// Sizing // Sizing
if (table->Flags & ImGuiTableFlags_Resizable) if (table->Flags & ImGuiTableFlags_Resizable)
{ {
if (ImGuiTableColumn* selected_column = (selected_column_n != -1) ? &table->Columns[selected_column_n] : NULL) if (column != NULL)
{ {
const bool can_resize = !(selected_column->Flags & (ImGuiTableColumnFlags_NoResize | ImGuiTableColumnFlags_WidthStretch)) && selected_column->IsVisible; const bool can_resize = !(column->Flags & (ImGuiTableColumnFlags_NoResize | ImGuiTableColumnFlags_WidthStretch)) && column->IsVisible;
if (MenuItem("Size column to fit", NULL, false, can_resize)) if (MenuItem("Size column to fit", NULL, false, can_resize))
TableSetColumnAutofit(table, selected_column_n); TableSetColumnAutofit(table, column_n);
} }
if (MenuItem("Size all columns to fit", NULL)) if (MenuItem("Size all columns to fit", NULL))
{ {
for (int column_n = 0; column_n < table->ColumnsCount; column_n++) for (int other_column_n = 0; other_column_n < table->ColumnsCount; other_column_n++)
{ {
ImGuiTableColumn* column = &table->Columns[column_n]; ImGuiTableColumn* other_column = &table->Columns[other_column_n];
if (column->IsVisible) if (other_column->IsVisible)
TableSetColumnAutofit(table, column_n); TableSetColumnAutofit(table, other_column_n);
} }
} }
want_separator = true; want_separator = true;
@ -2030,27 +2031,43 @@ void ImGui::TableDrawContextMenu(ImGuiTable* table)
want_separator = true; want_separator = true;
} }
// Sorting
#if 0
if ((table->Flags & ImGuiTableFlags_Sortable) && column != NULL && (column->Flags & ImGuiTableColumnFlags_NoSort) == 0)
{
if (want_separator)
Separator();
want_separator = true;
bool append_to_sort_specs = g.IO.KeyShift;
if (MenuItem("Sort in Ascending Order", NULL, column->SortOrder != -1 && column->SortDirection == ImGuiSortDirection_Ascending, (column->Flags & ImGuiTableColumnFlags_NoSortAscending) == 0))
TableSetColumnSortDirection(table, column_n, ImGuiSortDirection_Ascending, append_to_sort_specs);
if (MenuItem("Sort in Descending Order", NULL, column->SortOrder != -1 && column->SortDirection == ImGuiSortDirection_Descending, (column->Flags & ImGuiTableColumnFlags_NoSortDescending) == 0))
TableSetColumnSortDirection(table, column_n, ImGuiSortDirection_Descending, append_to_sort_specs);
}
#endif
// Hiding / Visibility // Hiding / Visibility
if (table->Flags & ImGuiTableFlags_Hideable) if (table->Flags & ImGuiTableFlags_Hideable)
{ {
if (want_separator) if (want_separator)
Separator(); Separator();
want_separator = false; want_separator = true;
PushItemFlag(ImGuiItemFlags_SelectableDontClosePopup, true); PushItemFlag(ImGuiItemFlags_SelectableDontClosePopup, true);
for (int column_n = 0; column_n < table->ColumnsCount; column_n++) for (int other_column_n = 0; other_column_n < table->ColumnsCount; other_column_n++)
{ {
ImGuiTableColumn* column = &table->Columns[column_n]; ImGuiTableColumn* other_column = &table->Columns[other_column_n];
const char* name = TableGetColumnName(table, column_n); const char* name = TableGetColumnName(table, other_column_n);
if (name == NULL) if (name == NULL)
name = "<Unknown>"; name = "<Unknown>";
// Make sure we can't hide the last active column // Make sure we can't hide the last active column
bool menu_item_active = (column->Flags & ImGuiTableColumnFlags_NoHide) ? false : true; bool menu_item_active = (other_column->Flags & ImGuiTableColumnFlags_NoHide) ? false : true;
if (column->IsVisible && table->ColumnsVisibleCount <= 1) if (other_column->IsVisible && table->ColumnsVisibleCount <= 1)
menu_item_active = false; menu_item_active = false;
if (MenuItem(name, NULL, column->IsVisible, menu_item_active)) if (MenuItem(name, NULL, other_column->IsVisible, menu_item_active))
column->IsVisibleNextFrame = !column->IsVisible; other_column->IsVisibleNextFrame = !other_column->IsVisible;
} }
PopItemFlag(); PopItemFlag();
} }
@ -2245,7 +2262,17 @@ void ImGui::TableHeader(const char* label)
// Handle clicking on column header to adjust Sort Order // Handle clicking on column header to adjust Sort Order
if (pressed && table->ReorderColumn != column_n) if (pressed && table->ReorderColumn != column_n)
TableSortSpecsClickColumn(table, column, g.IO.KeyShift); {
// Set new sort direction
// - If the PreferSortDescending flag is set, we will default to a Descending direction on the first click.
// - Note that the PreferSortAscending flag is never checked, it is essentially the default and therefore a no-op.
ImGuiSortDirection sort_direction;
if (column->SortOrder == -1)
sort_direction = (column->Flags & ImGuiTableColumnFlags_PreferSortDescending) ? ImGuiSortDirection_Descending : ImGuiSortDirection_Ascending;
else
sort_direction = (column->SortDirection == ImGuiSortDirection_Ascending) ? ImGuiSortDirection_Descending : ImGuiSortDirection_Ascending;
TableSetColumnSortDirection(table, column_n, sort_direction, g.IO.KeyShift);
}
} }
// Render clipped label. Clipping here ensure that in the majority of situations, all our header cells will // Render clipped label. Clipping here ensure that in the majority of situations, all our header cells will
@ -2265,38 +2292,29 @@ void ImGui::TableHeader(const char* label)
TableOpenContextMenu(table, column_n); TableOpenContextMenu(table, column_n);
} }
void ImGui::TableSortSpecsClickColumn(ImGuiTable* table, ImGuiTableColumn* clicked_column, bool add_to_existing_sort_orders) // Note that the NoSortAscending/NoSortDescending flags are processed in TableSortSpecsSanitize(), and they may change/revert
// the value of SortDirection. We could technically also do it here but it would be unnecessary and duplicate code.
void ImGui::TableSetColumnSortDirection(ImGuiTable* table, int column_n, ImGuiSortDirection sort_direction, bool append_to_sort_specs)
{ {
if (!(table->Flags & ImGuiTableFlags_MultiSortable)) if (!(table->Flags & ImGuiTableFlags_MultiSortable))
add_to_existing_sort_orders = false; append_to_sort_specs = false;
ImS8 sort_order_max = 0; ImS8 sort_order_max = 0;
if (add_to_existing_sort_orders) if (append_to_sort_specs)
for (int column_n = 0; column_n < table->ColumnsCount; column_n++) for (int other_column_n = 0; other_column_n < table->ColumnsCount; other_column_n++)
sort_order_max = ImMax(sort_order_max, table->Columns[column_n].SortOrder); sort_order_max = ImMax(sort_order_max, table->Columns[other_column_n].SortOrder);
for (int column_n = 0; column_n < table->ColumnsCount; column_n++) ImGuiTableColumn* column = &table->Columns[column_n];
column->SortDirection = (ImS8)sort_direction;
if (column->SortOrder == -1 || !append_to_sort_specs)
column->SortOrder = append_to_sort_specs ? sort_order_max + 1 : 0;
for (int other_column_n = 0; other_column_n < table->ColumnsCount; other_column_n++)
{ {
ImGuiTableColumn* column = &table->Columns[column_n]; ImGuiTableColumn* other_column = &table->Columns[other_column_n];
if (column == clicked_column) if (other_column != column && !append_to_sort_specs)
{ other_column->SortOrder = -1;
// Set new sort direction and sort order TableFixColumnSortDirection(other_column);
// - If the PreferSortDescending flag is set, we will default to a Descending direction on the first click.
// - Note that the PreferSortAscending flag is never checked, it is essentially the default and therefore a no-op.
// - Note that the NoSortAscending/NoSortDescending flags are processed in TableSortSpecsSanitize(), and they may change/revert
// the value of SortDirection. We could technically also do it here but it would be unnecessary and duplicate code.
if (column->SortOrder == -1)
column->SortDirection = (column->Flags & ImGuiTableColumnFlags_PreferSortDescending) ? (ImS8)ImGuiSortDirection_Descending : (ImU8)(ImGuiSortDirection_Ascending);
else
column->SortDirection = (ImU8)((column->SortDirection == ImGuiSortDirection_Ascending) ? ImGuiSortDirection_Descending : ImGuiSortDirection_Ascending);
if (column->SortOrder == -1 || !add_to_existing_sort_orders)
column->SortOrder = add_to_existing_sort_orders ? sort_order_max + 1 : 0;
}
else if (!add_to_existing_sort_orders)
{
column->SortOrder = -1;
}
TableFixColumnSortDirection(column);
} }
table->IsSettingsDirty = true; table->IsSettingsDirty = true;
table->IsSortSpecsDirty = true; table->IsSortSpecsDirty = true;