From 104b11051ff912ca26524e7043218a63d954ba39 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 20 Mar 2020 18:53:44 +0100 Subject: [PATCH] Tables: Added ImGuiTableColumnFlags_NoReorder. --- imgui.h | 1 + imgui_demo.cpp | 7 ++++++- imgui_internal.h | 7 ++++--- imgui_tables.cpp | 28 +++++++++++++++++----------- 4 files changed, 28 insertions(+), 15 deletions(-) diff --git a/imgui.h b/imgui.h index cc380ea0..998909c8 100644 --- a/imgui.h +++ b/imgui.h @@ -1081,6 +1081,7 @@ enum ImGuiTableColumnFlags_ ImGuiTableColumnFlags_PreferSortDescending = 1 << 13, // Make the initial sort direction Descending when first sorting on this column. ImGuiTableColumnFlags_IndentEnable = 1 << 14, // Use current Indent value when entering cell (default for 1st column). ImGuiTableColumnFlags_IndentDisable = 1 << 15, // Ignore current Indent value when entering cell (default for columns after the 1st one). Indentation changes _within_ the cell will still be honored. + ImGuiTableColumnFlags_NoReorder = 1 << 16, // Disable reordering this column, this will also prevent other columns from crossing over this column. // [Internal] Combinations and masks ImGuiTableColumnFlags_WidthMask_ = ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_WidthStretch | ImGuiTableColumnFlags_WidthAlwaysAutoResize, diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 6c84e023..93168cbd 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -3672,6 +3672,7 @@ static void ShowDemoWindowTables() ImGui::CheckboxFlags("_NoResize", (unsigned int*)&column_flags[column], ImGuiTableColumnFlags_NoResize); ImGui::CheckboxFlags("_NoClipX", (unsigned int*)&column_flags[column], ImGuiTableColumnFlags_NoClipX); ImGui::CheckboxFlags("_NoHide", (unsigned int*)&column_flags[column], ImGuiTableColumnFlags_NoHide); + ImGui::CheckboxFlags("_NoReorder", (unsigned int*)&column_flags[column], ImGuiTableColumnFlags_NoReorder); ImGui::CheckboxFlags("_DefaultSort", (unsigned int*)&column_flags[column], ImGuiTableColumnFlags_DefaultSort); ImGui::CheckboxFlags("_DefaultHide", (unsigned int*)&column_flags[column], ImGuiTableColumnFlags_DefaultHide); ImGui::CheckboxFlags("_NoSort", (unsigned int*)&column_flags[column], ImGuiTableColumnFlags_NoSort); @@ -4213,7 +4214,7 @@ static void ShowDemoWindowTables() const ImDrawList* table_draw_list = NULL; // " const float inner_width_to_use = (flags & ImGuiTableFlags_ScrollX) ? inner_width_with_scroll : inner_width_without_scroll; - if (ImGui::BeginTable("##table", 5, flags, outer_size_enabled ? outer_size_value : ImVec2(0, 0), inner_width_to_use)) + if (ImGui::BeginTable("##table", 6, flags, outer_size_enabled ? outer_size_value : ImVec2(0, 0), inner_width_to_use)) { // Declare columns // We use the "user_id" parameter of TableSetupColumn() to specify a user id that will be stored in the sort specifications. @@ -4223,6 +4224,7 @@ static void ShowDemoWindowTables() ImGui::TableSetupColumn("Action", ImGuiTableColumnFlags_NoSort | ImGuiTableColumnFlags_WidthFixed, -1.0f, MyItemColumnID_Action); ImGui::TableSetupColumn("Quantity Long Label", ImGuiTableColumnFlags_PreferSortDescending | ImGuiTableColumnFlags_WidthStretch, 1.0f, MyItemColumnID_Quantity);// , ImGuiTableColumnFlags_None | ImGuiTableColumnFlags_WidthAlwaysAutoResize); ImGui::TableSetupColumn("Description", ImGuiTableColumnFlags_WidthStretch, 1.0f, MyItemColumnID_Description);// , ImGuiTableColumnFlags_WidthAlwaysAutoResize); + ImGui::TableSetupColumn("Hidden", ImGuiTableColumnFlags_DefaultHide | ImGuiTableColumnFlags_NoSort); // Sort our data if sort specs have been changed! const ImGuiTableSortSpecs* sorts_specs = ImGui::TableGetSortSpecs(); @@ -4319,6 +4321,9 @@ static void ShowDemoWindowTables() else ImGui::Text("Lorem ipsum dolor sit amet"); + ImGui::TableNextCell(); + ImGui::Text("1234"); + ImGui::PopID(); } } diff --git a/imgui_internal.h b/imgui_internal.h index bb4e4b2e..b75119ec 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1888,6 +1888,7 @@ struct ImGuiTabBar #define IMGUI_TABLE_MAX_DRAW_CHANNELS (2 + 64 * 2) // See TableUpdateDrawChannels() // [Internal] sizeof() ~ 100 +// We use the terminology "Active" to refer to a column that is not Hidden by user or programmatically. We don't use the term "Visible" because it is ambiguous since an Active column can be non-visible because of scrolling. struct ImGuiTableColumn { ImRect ClipRect; // Clipping rectangle for the column @@ -1911,11 +1912,11 @@ struct ImGuiTableColumn ImS16 ContentWidthHeadersDesired; ImS16 NameOffset; // Offset into parent ColumnsNames[] bool IsActive; // Is the column not marked Hidden by the user (regardless of clipping). We're not calling this "Visible" here because visibility also depends on clipping. - bool NextIsActive; + bool IsActiveNextFrame; bool IsClipped; // Set when not overlapping the host window clipping rectangle. We don't use the opposite "!Visible" name because Clipped can be altered by events. bool SkipItems; ImS8 DisplayOrder; // Index within Table's IndexToDisplayOrder[] (column may be reordered by users) - ImS8 IndexWithinActiveSet; // Index within active set (<= IndexOrder) + ImS8 IndexWithinActiveSet; // Index within active/visible set (<= IndexToDisplayOrder) ImS8 DrawChannelCurrent; // Index within DrawSplitter.Channels[] ImS8 DrawChannelRowsBeforeFreeze; ImS8 DrawChannelRowsAfterFreeze; @@ -1931,7 +1932,7 @@ struct ImGuiTableColumn memset(this, 0, sizeof(*this)); ResizeWeight = WidthRequested = WidthGiven = -1.0f; NameOffset = -1; - IsActive = NextIsActive = true; + IsActive = IsActiveNextFrame = true; DisplayOrder = IndexWithinActiveSet = -1; DrawChannelCurrent = DrawChannelRowsBeforeFreeze = DrawChannelRowsAfterFreeze = -1; PrevActiveColumn = NextActiveColumn = -1; diff --git a/imgui_tables.cpp b/imgui_tables.cpp index 123b886d..5a9f7627 100644 --- a/imgui_tables.cpp +++ b/imgui_tables.cpp @@ -397,10 +397,10 @@ void ImGui::TableBeginUpdateColumns(ImGuiTable* table) ImGuiTableColumn* column = &table->Columns[column_n]; column->NameOffset = -1; if (!(table->Flags & ImGuiTableFlags_Hideable) || (column->Flags & ImGuiTableColumnFlags_NoHide)) - column->NextIsActive = true; - if (column->IsActive != column->NextIsActive) + column->IsActiveNextFrame = true; + if (column->IsActive != column->IsActiveNextFrame) { - column->IsActive = column->NextIsActive; + column->IsActive = column->IsActiveNextFrame; table->IsSettingsDirty = true; if (!column->IsActive && column->SortOrder != -1) table->IsSortSpecsDirty = true; @@ -1432,7 +1432,7 @@ void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, { // Init default visibility/sort state if (flags & ImGuiTableColumnFlags_DefaultHide) - column->IsActive = column->NextIsActive = false; + column->IsActive = column->IsActiveNextFrame = false; if (flags & ImGuiTableColumnFlags_DefaultSort) { column->SortOrder = 0; // Multiple columns using _DefaultSort will be reordered when building the sort specs. @@ -1859,7 +1859,7 @@ void ImGui::TableDrawContextMenu(ImGuiTable* table, int selected_column_n) if (column->IsActive && table->ColumnsActiveCount <= 1) menu_item_active = false; if (MenuItem(name, NULL, column->IsActive, menu_item_active)) - column->NextIsActive = !column->IsActive; + column->IsActiveNextFrame = !column->IsActive; } PopItemFlag(); } @@ -2018,19 +2018,25 @@ void ImGui::TableHeader(const char* label) table->HeldHeaderColumn = (ImS8)column_n; window->DC.CursorPos.y -= g.Style.ItemSpacing.y * 0.5f; - // Drag and drop: re-order columns. Frozen columns are not reorderable. + // Drag and drop to re-order columns. // FIXME-TABLE: Scroll request while reordering a column and it lands out of the scrolling zone. if (held && (table->Flags & ImGuiTableFlags_Reorderable) && IsMouseDragging(0) && !g.DragDropActive) { // 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->InstanceInteracted = table->InstanceNo; + + // 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 (column->PrevActiveColumn != -1 && (column->IndexWithinActiveSet < table->FreezeColumnsRequest) == (table->Columns[column->PrevActiveColumn].IndexWithinActiveSet < table->FreezeColumnsRequest)) - table->ReorderColumnDir = -1; + if (ImGuiTableColumn* prev_column = (column->PrevActiveColumn != -1) ? &table->Columns[column->PrevActiveColumn] : NULL) + if (!((column->Flags | prev_column->Flags) & ImGuiTableColumnFlags_NoReorder)) + if ((column->IndexWithinActiveSet < table->FreezeColumnsRequest) == (prev_column->IndexWithinActiveSet < table->FreezeColumnsRequest)) + table->ReorderColumnDir = -1; if (g.IO.MouseDelta.x > 0.0f && g.IO.MousePos.x > cell_r.Max.x) - if (column->NextActiveColumn != -1 && (column->IndexWithinActiveSet < table->FreezeColumnsRequest) == (table->Columns[column->NextActiveColumn].IndexWithinActiveSet < table->FreezeColumnsRequest)) - table->ReorderColumnDir = +1; + if (ImGuiTableColumn* next_column = (column->NextActiveColumn != -1) ? &table->Columns[column->NextActiveColumn] : NULL) + if (!((column->Flags | next_column->Flags) & ImGuiTableColumnFlags_NoReorder)) + if ((column->IndexWithinActiveSet < table->FreezeColumnsRequest) == (next_column->IndexWithinActiveSet < table->FreezeColumnsRequest)) + table->ReorderColumnDir = +1; } // Sort order arrow @@ -2374,7 +2380,7 @@ void ImGui::TableLoadSettings(ImGuiTable* table) column->SortOrder = column_settings->SortOrder; column->SortDirection = column_settings->SortDirection; } - column->IsActive = column->NextIsActive = column_settings->Visible; + column->IsActive = column->IsActiveNextFrame = column_settings->Visible; } // FIXME-TABLE: Need to validate .ini data