Tables: added ImGuiTableFlags_NoHostExtendX instead of using outer_size.x == 0.0f. Changed default outer_size to (0.0f, 0.0f). (#3605)
diff --git a/imgui.h b/imgui.h
index 8a71ef8..e6f16b5 100644
--- a/imgui.h
+++ b/imgui.h
@@ -680,7 +680,7 @@
// TableNextRow() -> Text("Hello 0") // Not OK! Missing TableSetColumnIndex() or TableNextColumn()! Text will not appear!
// --------------------------------------------------------------------------------------------------------
// - 5. Call EndTable()
- IMGUI_API bool BeginTable(const char* str_id, int columns_count, ImGuiTableFlags flags = 0, const ImVec2& outer_size = ImVec2(-FLT_MIN, 0), float inner_width = 0.0f);
+ IMGUI_API bool BeginTable(const char* str_id, int columns_count, ImGuiTableFlags flags = 0, const ImVec2& outer_size = ImVec2(0.0f, 0.0f), float inner_width = 0.0f);
IMGUI_API void EndTable(); // only call EndTable() if BeginTable() returns true!
IMGUI_API void TableNextRow(ImGuiTableRowFlags row_flags = 0, float min_row_height = 0.0f); // append into the first cell of a new row.
IMGUI_API bool TableNextColumn(); // append into the next column (or first column of next row if currently in last column). Return true when column is visible.
@@ -1083,21 +1083,22 @@
ImGuiTableFlags_SizingStretchProp = 3 << 13, // Columns default to _WidthStretch with default weights proportional to each columns contents widths.
ImGuiTableFlags_SizingStretchSame = 4 << 13, // Columns default to _WidthStretch with default weights all equal, unless overriden by TableSetupColumn().
// Sizing Extra Options
- ImGuiTableFlags_NoHostExtendY = 1 << 16, // Disable extending table past the limit set by outer_size.y. Only meaningful when neither ScrollX nor ScrollY are set (data below the limit will be clipped and not visible)
- ImGuiTableFlags_NoKeepColumnsVisible = 1 << 17, // Disable keeping column always minimally visible when ScrollX is off and table gets too small. Not recommended if columns are resizable.
- ImGuiTableFlags_PreciseWidths = 1 << 18, // Disable distributing remainder width to stretched columns (width allocation on a 100-wide table with 3 columns: Without this flag: 33,33,34. With this flag: 33,33,33). With larger number of columns, resizing will appear to be less smooth.
+ ImGuiTableFlags_NoHostExtendX = 1 << 16, // Make outer width auto-fit to columns, overriding outer_size.x value. Only available when ScrollX/ScrollY are disabled and Stretch columns are not used.
+ ImGuiTableFlags_NoHostExtendY = 1 << 17, // Make outer height stop exactly at outer_size.y (prevent auto-extending table past the limit). Only available when ScrollX/ScrollY are disabled. Data below the limit will be clipped and not visible.
+ ImGuiTableFlags_NoKeepColumnsVisible = 1 << 18, // Disable keeping column always minimally visible when ScrollX is off and table gets too small. Not recommended if columns are resizable.
+ ImGuiTableFlags_PreciseWidths = 1 << 19, // Disable distributing remainder width to stretched columns (width allocation on a 100-wide table with 3 columns: Without this flag: 33,33,34. With this flag: 33,33,33). With larger number of columns, resizing will appear to be less smooth.
// Clipping
- ImGuiTableFlags_NoClip = 1 << 19, // Disable clipping rectangle for every individual columns (reduce draw command count, items will be able to overflow into other columns). Generally incompatible with TableSetupScrollFreeze().
+ ImGuiTableFlags_NoClip = 1 << 20, // Disable clipping rectangle for every individual columns (reduce draw command count, items will be able to overflow into other columns). Generally incompatible with TableSetupScrollFreeze().
// Padding
- ImGuiTableFlags_PadOuterX = 1 << 20, // Default if BordersOuterV is on. Enable outer-most padding. Generally desirable if you have headers.
- ImGuiTableFlags_NoPadOuterX = 1 << 21, // Default if BordersOuterV is off. Disable outer-most padding.
- ImGuiTableFlags_NoPadInnerX = 1 << 22, // Disable inner padding between columns (double inner padding if BordersOuterV is on, single inner padding if BordersOuterV is off).
+ ImGuiTableFlags_PadOuterX = 1 << 21, // Default if BordersOuterV is on. Enable outer-most padding. Generally desirable if you have headers.
+ ImGuiTableFlags_NoPadOuterX = 1 << 22, // Default if BordersOuterV is off. Disable outer-most padding.
+ ImGuiTableFlags_NoPadInnerX = 1 << 23, // Disable inner padding between columns (double inner padding if BordersOuterV is on, single inner padding if BordersOuterV is off).
// Scrolling
- ImGuiTableFlags_ScrollX = 1 << 23, // Enable horizontal scrolling. Require 'outer_size' parameter of BeginTable() to specify the container size. Changes default sizing policy. Because this create a child window, ScrollY is currently generally recommended when using ScrollX.
- ImGuiTableFlags_ScrollY = 1 << 24, // Enable vertical scrolling. Require 'outer_size' parameter of BeginTable() to specify the container size.
+ ImGuiTableFlags_ScrollX = 1 << 24, // Enable horizontal scrolling. Require 'outer_size' parameter of BeginTable() to specify the container size. Changes default sizing policy. Because this create a child window, ScrollY is currently generally recommended when using ScrollX.
+ ImGuiTableFlags_ScrollY = 1 << 25, // Enable vertical scrolling. Require 'outer_size' parameter of BeginTable() to specify the container size.
// Sorting
- ImGuiTableFlags_SortMulti = 1 << 25, // Hold shift when clicking headers to sort on multiple column. TableGetSortSpecs() may return specs where (SpecsCount > 1).
- ImGuiTableFlags_SortTristate = 1 << 26, // Allow no sorting, disable default sorting. TableGetSortSpecs() may return specs where (SpecsCount == 0).
+ ImGuiTableFlags_SortMulti = 1 << 26, // Hold shift when clicking headers to sort on multiple column. TableGetSortSpecs() may return specs where (SpecsCount > 1).
+ ImGuiTableFlags_SortTristate = 1 << 27, // Allow no sorting, disable default sorting. TableGetSortSpecs() may return specs where (SpecsCount == 0).
// [Internal] Combinations and masks
ImGuiTableFlags_SizingMask_ = ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_SizingFixedSame | ImGuiTableFlags_SizingStretchProp | ImGuiTableFlags_SizingStretchSame
diff --git a/imgui_demo.cpp b/imgui_demo.cpp
index d110269..8423086 100644
--- a/imgui_demo.cpp
+++ b/imgui_demo.cpp
@@ -3957,7 +3957,7 @@
ImGui::PopID();
PopStyleCompact();
- outer_size = ImVec2(-FLT_MIN, TEXT_BASE_HEIGHT * 7);
+ outer_size = ImVec2(0.0f, TEXT_BASE_HEIGHT * 7);
if (ImGui::BeginTable("##table2", column_count, flags, outer_size))
{
for (int cell = 0; cell < 10 * column_count; cell++)
@@ -3999,8 +3999,8 @@
// When using ScrollX or ScrollY we need to specify a size for our table container!
// Otherwise by default the table will fit all available space, like a BeginChild() call.
- ImVec2 size = ImVec2(-FLT_MIN, TEXT_BASE_HEIGHT * 8);
- if (ImGui::BeginTable("##table1", 3, flags, size))
+ ImVec2 outer_size = ImVec2(0.0f, TEXT_BASE_HEIGHT * 8);
+ if (ImGui::BeginTable("##table1", 3, flags, outer_size))
{
ImGui::TableSetupScrollFreeze(0, 1); // Make top row always visible
ImGui::TableSetupColumn("One", ImGuiTableColumnFlags_None);
@@ -4053,7 +4053,7 @@
// When using ScrollX or ScrollY we need to specify a size for our table container!
// Otherwise by default the table will fit all available space, like a BeginChild() call.
- ImVec2 outer_size = ImVec2(-FLT_MIN, TEXT_BASE_HEIGHT * 8);
+ ImVec2 outer_size = ImVec2(0.0f, TEXT_BASE_HEIGHT * 8);
if (ImGui::BeginTable("##table1", 7, flags, outer_size))
{
ImGui::TableSetupScrollFreeze(freeze_cols, freeze_rows);
@@ -4154,8 +4154,8 @@
= ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY
| ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV
| ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable | ImGuiTableFlags_Sortable;
- ImVec2 size = ImVec2(-FLT_MIN, TEXT_BASE_HEIGHT * 9);
- if (ImGui::BeginTable("##table", column_count, flags, size))
+ ImVec2 outer_size = ImVec2(0.0f, TEXT_BASE_HEIGHT * 9);
+ if (ImGui::BeginTable("##table", column_count, flags, outer_size))
{
for (int column = 0; column < column_count; column++)
ImGui::TableSetupColumn(column_names[column], column_flags[column]);
@@ -4312,18 +4312,18 @@
ImGui::SetNextItemOpen(open_action != 0);
if (ImGui::TreeNode("Outer size"))
{
- // Showcasing use of outer_size.x == 0.0f and ImGuiTableFlags_NoHostExtendY
- // The default value of outer_size.x is -FLT_MIN which right-align tables.
- // Using outer_size.x == 0.0f on a table with no scrolling and no stretch column we can make them tighter.
- ImGui::Text("Using auto/all width, using NoHostExtendY:");
+ // Showcasing use of ImGuiTableFlags_NoHostExtendX and ImGuiTableFlags_NoHostExtendY
+ // Important to that note how the two flags have slightly different behaviors!
+ ImGui::Text("Using NoHostExtendX and NoHostExtendY:");
PushStyleCompact();
- static ImGuiTableFlags flags = ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_ContextMenuInBody | ImGuiTableFlags_RowBg | ImGuiTableFlags_SizingFixedFit;
- static bool fixed_fill = false;
- ImGui::Checkbox("fill", &fixed_fill);
+ static ImGuiTableFlags flags = ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_ContextMenuInBody | ImGuiTableFlags_RowBg | ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_NoHostExtendX;
+ ImGui::CheckboxFlags("ImGuiTableFlags_NoHostExtendX", &flags, ImGuiTableFlags_NoHostExtendX);
+ ImGui::SameLine(); HelpMarker("Make outer width auto-fit to columns, overriding outer_size.x value.\n\nOnly available when ScrollX/ScrollY are disabled and Stretch columns are not used.");
ImGui::CheckboxFlags("ImGuiTableFlags_NoHostExtendY", &flags, ImGuiTableFlags_NoHostExtendY);
+ ImGui::SameLine(); HelpMarker("Make outer height stop exactly at outer_size.y (prevent auto-extending table past the limit).\n\nOnly available when ScrollX/ScrollY are disabled. Data below the limit will be clipped and not visible.");
PopStyleCompact();
- ImVec2 outer_size = ImVec2(fixed_fill ? -FLT_MIN : 0.0f, TEXT_BASE_HEIGHT * 5.5f);
+ ImVec2 outer_size = ImVec2(0.0f, TEXT_BASE_HEIGHT * 5.5f);
if (ImGui::BeginTable("##table3", 3, flags, outer_size))
{
for (int row = 0; row < 10; row++)
@@ -4766,7 +4766,7 @@
ImGui::SameLine(); HelpMarker("When sorting is enabled: allow no sorting, disable default sorting. TableGetSortSpecs() may return specs where (SpecsCount == 0).");
PopStyleCompact();
- if (ImGui::BeginTable("##table", 4, flags, ImVec2(-FLT_MIN, TEXT_BASE_HEIGHT * 15), 0.0f))
+ if (ImGui::BeginTable("##table", 4, flags, ImVec2(0.0f, TEXT_BASE_HEIGHT * 15), 0.0f))
{
// Declare columns
// We use the "user_id" parameter of TableSetupColumn() to specify a user id that will be stored in the sort specifications.
@@ -4836,7 +4836,7 @@
static int freeze_cols = 1;
static int freeze_rows = 1;
static int items_count = IM_ARRAYSIZE(template_items_names) * 2;
- static ImVec2 outer_size_value = ImVec2(-FLT_MIN, TEXT_BASE_HEIGHT * 12);
+ static ImVec2 outer_size_value = ImVec2(0.0f, TEXT_BASE_HEIGHT * 12);
static float row_min_height = 0.0f; // Auto
static float inner_width_with_scroll = 0.0f; // Auto-extend
static bool outer_size_enabled = true;
@@ -4879,7 +4879,10 @@
{
EditTableSizingFlags(&flags);
ImGui::SameLine(); HelpMarker("In the Advanced demo we override the policy of each column so those table-wide settings have less effect that typical.");
+ ImGui::CheckboxFlags("ImGuiTableFlags_NoHostExtendX", &flags, ImGuiTableFlags_NoHostExtendX);
+ ImGui::SameLine(); HelpMarker("Make outer width auto-fit to columns, overriding outer_size.x value.\n\nOnly available when ScrollX/ScrollY are disabled and Stretch columns are not used.");
ImGui::CheckboxFlags("ImGuiTableFlags_NoHostExtendY", &flags, ImGuiTableFlags_NoHostExtendY);
+ ImGui::SameLine(); HelpMarker("Make outer height stop exactly at outer_size.y (prevent auto-extending table past the limit).\n\nOnly available when ScrollX/ScrollY are disabled. Data below the limit will be clipped and not visible.");
ImGui::CheckboxFlags("ImGuiTableFlags_NoKeepColumnsVisible", &flags, ImGuiTableFlags_NoKeepColumnsVisible);
ImGui::SameLine(); HelpMarker("Only available if ScrollX is disabled.");
ImGui::CheckboxFlags("ImGuiTableFlags_PreciseWidths", &flags, ImGuiTableFlags_PreciseWidths);
@@ -4985,7 +4988,7 @@
ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthFixed, 0.0f, MyItemColumnID_Name);
ImGui::TableSetupColumn("Action", ImGuiTableColumnFlags_NoSort | ImGuiTableColumnFlags_WidthFixed, 0.0f, MyItemColumnID_Action);
ImGui::TableSetupColumn("Quantity", ImGuiTableColumnFlags_PreferSortDescending, 0.0f, MyItemColumnID_Quantity);
- ImGui::TableSetupColumn("Description", ImGuiTableColumnFlags_WidthStretch, 0.0f, MyItemColumnID_Description);
+ ImGui::TableSetupColumn("Description", (flags & ImGuiTableFlags_NoHostExtendX) ? 0 : ImGuiTableColumnFlags_WidthStretch, 0.0f, MyItemColumnID_Description);
ImGui::TableSetupColumn("Hidden", ImGuiTableColumnFlags_DefaultHide | ImGuiTableColumnFlags_NoSort);
ImGui::TableSetupScrollFreeze(freeze_cols, freeze_rows);
diff --git a/imgui_internal.h b/imgui_internal.h
index 35329cb..1fbb371 100644
--- a/imgui_internal.h
+++ b/imgui_internal.h
@@ -2086,7 +2086,6 @@
bool IsResetAllRequest;
bool IsResetDisplayOrderRequest;
bool IsUnfrozenRows; // Set when we got past the frozen row.
- bool IsOuterRectMinFitX; // Set when outer_size.x == 0.0f in BeginTable(), scrolling is disabled, and there are no stretch columns.
bool IsDefaultSizingPolicy; // Set if user didn't explicitely set a sizing policy in BeginTable()
bool MemoryCompacted;
bool HostSkipItems; // Backup of InnerWindow->SkipItem at the end of BeginTable(), because we will overwrite InnerWindow->SkipItem on a per-column basis
diff --git a/imgui_tables.cpp b/imgui_tables.cpp
index da2b4c8..caecb1c 100644
--- a/imgui_tables.cpp
+++ b/imgui_tables.cpp
@@ -74,19 +74,23 @@
//-----------------------------------------------------------------------------
// About 'outer_size':
// Its meaning needs to differ slightly depending of if we are using ScrollX/ScrollY flags.
-// Default value is ImVec2(-FLT_MIN, 0.0f). When binding this in a scripting language please follow this default value.
+// Default value is ImVec2(0.0f, 0.0f).
// X
-// - outer_size.x < 0.0f -> Right-align from window/work-rect right-most edge. With -FLT_MIN will right-align exactly on right-most edge.
-// - outer_size.x = 0.0f -> Auto width. Generally use all available width. When NOT using scrolling and NOT using any Stretch column, use only necessary width, otherwise same as -FLT_MIN.
-// - outer_size.x > 0.0f -> Fixed width.
+// - outer_size.x <= 0.0f -> Right-align from window/work-rect right-most edge. With -FLT_MIN or 0.0f will align exactly on right-most edge.
+// - outer_size.x > 0.0f -> Set Fixed width.
// Y with ScrollX/ScrollY disabled: we output table directly in current window
-// - outer_size.y < 0.0f -> Bottom-align (but will auto extend, unless _NoHostExtendY is set). Not meaningful is parent window can vertically scroll.
-// - outer_size.y = 0.0f -> No minimum height (but will auto extend, unless _NoHostExtendY is set)
-// - outer_size.y > 0.0f -> Set Minimum height (but will auto extend, unless _NoHostExtenY is set)
+// - outer_size.y < 0.0f -> Bottom-align (but will auto extend, unless _NoHostExtendY is set). Not meaningful is parent window can vertically scroll.
+// - outer_size.y = 0.0f -> No minimum height (but will auto extend, unless _NoHostExtendY is set)
+// - outer_size.y > 0.0f -> Set Minimum height (but will auto extend, unless _NoHostExtenY is set)
// Y with ScrollX/ScrollY enabled: using a child window for scrolling
-// - outer_size.y < 0.0f -> Bottom-align. Not meaningful is parent window can vertically scroll.
-// - outer_size.y = 0.0f -> Bottom-align, consistent with BeginChild(). Not recommended unless table is last item in parent window.
-// - outer_size.y > 0.0f -> Set Exact height. Recommended when using Scrolling on any axis.
+// - outer_size.y < 0.0f -> Bottom-align. Not meaningful is parent window can vertically scroll.
+// - outer_size.y = 0.0f -> Bottom-align, consistent with BeginChild(). Not recommended unless table is last item in parent window.
+// - outer_size.y > 0.0f -> Set Exact height. Recommended when using Scrolling on any axis.
+//-----------------------------------------------------------------------------
+// Outer size is also affected by the NoHostExtendX/NoHostExtendY flags.
+// Important to that note how the two flags have slightly different behaviors!
+// - ImGuiTableFlags_NoHostExtendX -> Make outer width auto-fit to columns (overriding outer_size.x value). Only available when ScrollX/ScrollY are disabled and Stretch columns are not used.
+// - ImGuiTableFlags_NoHostExtendY -> Make outer height stop exactly at outer_size.y (prevent auto-extending table past the limit). Only available when ScrollX/ScrollY are disabled. Data below the limit will be clipped and not visible.
// In theory ImGuiTableFlags_NoHostExtendY could be the default and any non-scrolling tables with outer_size.y != 0.0f would use exact height.
// This would be consistent but perhaps less useful and more confusing (as vertically clipped items are not easily noticeable)
//-----------------------------------------------------------------------------
@@ -255,9 +259,9 @@
if (flags & ImGuiTableFlags_Resizable)
flags |= ImGuiTableFlags_BordersInnerV;
- // Adjust flags: disable NoHostExtendY if we have any scrolling going on
- if ((flags & ImGuiTableFlags_NoHostExtendY) && (flags & (ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY)) != 0)
- flags &= ~ImGuiTableFlags_NoHostExtendY;
+ // Adjust flags: disable NoHostExtendX/NoHostExtendY if we have any scrolling going on
+ if (flags & (ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY))
+ flags &= ~(ImGuiTableFlags_NoHostExtendX | ImGuiTableFlags_NoHostExtendY);
// Adjust flags: NoBordersInBodyUntilResize takes priority over NoBordersInBody
if (flags & ImGuiTableFlags_NoBordersInBodyUntilResize)
@@ -1036,8 +1040,9 @@
// [Part 8] Lock actual OuterRect/WorkRect right-most position.
// This is done late to handle the case of fixed-columns tables not claiming more widths that they need.
// Because of this we are careful with uses of WorkRect and InnerClipRect before this point.
- table->IsOuterRectMinFitX = (table->UserOuterSize.x == 0.0f) && table->RightMostStretchedColumn == -1 && (table->InnerWindow == table->OuterWindow);
- if (table->IsOuterRectMinFitX)
+ if (table->RightMostStretchedColumn != -1)
+ table->Flags &= ~ImGuiTableFlags_NoHostExtendX;
+ if (table->Flags & ImGuiTableFlags_NoHostExtendX)
{
table->OuterRect.Max.x = table->WorkRect.Max.x = unused_x1;
table->InnerClipRect.Max.x = ImMin(table->InnerClipRect.Max.x, unused_x1);
@@ -1300,7 +1305,7 @@
}
// Override declared contents width/height to enable auto-resize while not needlessly adding a scrollbar
- if (table->IsOuterRectMinFitX)
+ if (table->Flags & ImGuiTableFlags_NoHostExtendX)
{
// FIXME-TABLE: Could we remove this section?
// ColumnsAutoFitWidth may be one frame ahead here since for Fixed+NoResize is calculated from latest contents
@@ -2402,11 +2407,12 @@
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_frozen_separator = (table->FreezeColumnsCount != -1 && table->FreezeColumnsCount == order_n + 1);
-
if (column->MaxX > table->InnerClipRect.Max.x && !is_resized)
continue;
+
+ // Decide whether right-most column is visible
if (column->NextEnabledColumn == -1 && !is_resizable)
- if ((table->Flags & ImGuiTableFlags_SizingMask_) != ImGuiTableFlags_SizingFixedSame || table->IsOuterRectMinFitX)
+ if ((table->Flags & ImGuiTableFlags_SizingMask_) != ImGuiTableFlags_SizingFixedSame || (table->Flags & ImGuiTableFlags_NoHostExtendX))
continue;
if (column->MaxX <= column->ClipRect.Min.x) // FIXME-TABLE FIXME-STYLE: Assume BorderSize==1, this is problematic if we want to increase the border size..
continue;