Merge branch 'master' into docking

This commit is contained in:
ocornut
2021-01-08 18:55:16 +01:00
4 changed files with 475 additions and 349 deletions

View File

@ -3403,8 +3403,8 @@ const ImGuiTableSortSpecs* MyItem::s_current_sort_specs = NULL;
static void PushStyleCompact()
{
ImGuiStyle& style = ImGui::GetStyle();
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(style.FramePadding.x, (float)(int)(style.FramePadding.y * 0.70f)));
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(style.ItemSpacing.x, (float)(int)(style.ItemSpacing.y * 0.70f)));
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(style.FramePadding.x, (float)(int)(style.FramePadding.y * 0.60f)));
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(style.ItemSpacing.x, (float)(int)(style.ItemSpacing.y * 0.60f)));
}
static void PopStyleCompact()
@ -3412,6 +3412,49 @@ static void PopStyleCompact()
ImGui::PopStyleVar(2);
}
// Show a combo box with a choice of sizing policies
static void EditTableSizingFlags(ImGuiTableFlags* p_flags)
{
struct EnumDesc { ImGuiTableFlags Value; const char* Name; const char* Tooltip; };
static const EnumDesc policies[] =
{
{ ImGuiTableFlags_None, "Default", "Use default sizing policy:\n- ImGuiTableFlags_SizingFixedFit if ScrollX is on or if host window has ImGuiWindowFlags_AlwaysAutoResize.\n- ImGuiTableFlags_SizingStretchSame otherwise." },
{ ImGuiTableFlags_SizingFixedFit, "ImGuiTableFlags_SizingFixedFit", "Columns default to _WidthFixed (if resizable) or _WidthAuto (if not resizable), matching contents width." },
{ ImGuiTableFlags_SizingFixedSame, "ImGuiTableFlags_SizingFixedSame", "Columns are all the same width, matching the maximum contents width.\nImplicitly disable ImGuiTableFlags_Resizable and enable ImGuiTableFlags_NoKeepColumnsVisible." },
{ ImGuiTableFlags_SizingStretchProp, "ImGuiTableFlags_SizingStretchProp", "Columns default to _WidthStretch with weights proportional to their widths." },
{ ImGuiTableFlags_SizingStretchSame, "ImGuiTableFlags_SizingStretchSame", "Columns default to _WidthStretch with same weights." }
};
int idx;
for (idx = 0; idx < IM_ARRAYSIZE(policies); idx++)
if (policies[idx].Value == (*p_flags & ImGuiTableFlags_SizingMask_))
break;
const char* preview_text = (idx < IM_ARRAYSIZE(policies)) ? policies[idx].Name + (idx > 0 ? strlen("ImGuiTableFlags") : 0) : "";
if (ImGui::BeginCombo("Sizing Policy", preview_text))
{
for (int n = 0; n < IM_ARRAYSIZE(policies); n++)
if (ImGui::Selectable(policies[n].Name, idx == n))
*p_flags = (*p_flags & ~ImGuiTableFlags_SizingMask_) | policies[n].Value;
ImGui::EndCombo();
}
ImGui::SameLine();
ImGui::TextDisabled("(?)");
if (ImGui::IsItemHovered())
{
ImGui::BeginTooltip();
ImGui::PushTextWrapPos(ImGui::GetFontSize() * 50.0f);
for (int m = 0; m < IM_ARRAYSIZE(policies); m++)
{
ImGui::Separator();
ImGui::Text("%s:", policies[m].Name);
ImGui::Separator();
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + ImGui::GetStyle().IndentSpacing * 0.5f);
ImGui::TextUnformatted(policies[m].Tooltip);
}
ImGui::PopTextWrapPos();
ImGui::EndTooltip();
}
}
static void EditTableColumnsFlags(ImGuiTableColumnFlags* p_flags)
{
ImGui::CheckboxFlags("_DefaultHide", p_flags, ImGuiTableColumnFlags_DefaultHide);
@ -3576,12 +3619,12 @@ static void ShowDemoWindowTables()
ImGui::CheckboxFlags("ImGuiTableFlags_BordersOuter", &flags, ImGuiTableFlags_BordersOuter);
ImGui::CheckboxFlags("ImGuiTableFlags_BordersInner", &flags, ImGuiTableFlags_BordersInner);
ImGui::Unindent();
ImGui::CheckboxFlags("ImGuiTableFlags_NoBordersInBody", &flags, ImGuiTableFlags_NoBordersInBody); ImGui::SameLine(); HelpMarker("Disable vertical borders in columns Body (borders will always appears in Headers");
ImGui::AlignTextToFramePadding(); ImGui::Text("Cell contents:");
ImGui::SameLine(); ImGui::RadioButton("Text", &contents_type, CT_Text);
ImGui::SameLine(); ImGui::RadioButton("FillButton", &contents_type, CT_FillButton);
ImGui::Checkbox("Display headers", &display_headers);
ImGui::CheckboxFlags("ImGuiTableFlags_NoBordersInBody", &flags, ImGuiTableFlags_NoBordersInBody); ImGui::SameLine(); HelpMarker("Disable vertical borders in columns Body (borders will always appears in Headers");
PopStyleCompact();
if (ImGui::BeginTable("##table1", 3, flags))
@ -3621,11 +3664,11 @@ static void ShowDemoWindowTables()
{
// By default, if we don't enable ScrollX the sizing policy for each columns is "Stretch"
// Each columns maintain a sizing weight, and they will occupy all available width.
static ImGuiTableFlags flags = ImGuiTableFlags_Resizable | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV | ImGuiTableFlags_ContextMenuInBody;
static ImGuiTableFlags flags = ImGuiTableFlags_SizingStretchSame | ImGuiTableFlags_Resizable | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV | ImGuiTableFlags_ContextMenuInBody;
PushStyleCompact();
ImGui::CheckboxFlags("ImGuiTableFlags_Resizable", &flags, ImGuiTableFlags_Resizable);
ImGui::CheckboxFlags("ImGuiTableFlags_BordersV", &flags, ImGuiTableFlags_BordersV);
ImGui::SameLine(); HelpMarker("Using the _Resizable flag automatically enables the _BordersV flag as well.");
ImGui::SameLine(); HelpMarker("Using the _Resizable flag automatically enables the _BordersInnerV flag as well, this is why the resize borders are still showing when unchecking this.");
PopStyleCompact();
if (ImGui::BeginTable("##table1", 3, flags))
@ -3648,21 +3691,22 @@ static void ShowDemoWindowTables()
ImGui::SetNextItemOpen(open_action != 0);
if (ImGui::TreeNode("Resizable, fixed"))
{
// Here we use ImGuiTableFlags_SizingPolicyFixed (even though _ScrollX is not set)
// Here we use ImGuiTableFlags_SizingFixedFit (even though _ScrollX is not set)
// So columns will adopt the "Fixed" policy and will maintain a fixed width regardless of the whole available width (unless table is small)
// If there is not enough available width to fit all columns, they will however be resized down.
// FIXME-TABLE: Providing a stretch-on-init would make sense especially for tables which don't have saved settings
HelpMarker(
"Using _Resizable + _SizingPolicyFixed flags.\n"
"Using _Resizable + _SizingFixedFit flags.\n"
"Fixed-width columns generally makes more sense if you want to use horizontal scrolling.\n\n"
"Double-click a column border to auto-fit the column to its contents.");
static ImGuiTableFlags flags = ImGuiTableFlags_Resizable | ImGuiTableFlags_SizingPolicyFixed | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV | ImGuiTableFlags_ContextMenuInBody;
static bool use_all_width = true;
if (ImGui::RadioButton("fit", use_all_width == false)) { use_all_width = false; }
ImGui::SameLine();
if (ImGui::RadioButton("right-most edge", use_all_width == true)) { use_all_width = true; }
PushStyleCompact();
static ImGuiTableFlags flags = ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_Resizable | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV | ImGuiTableFlags_ContextMenuInBody;
static bool fixed_fill = true;
ImGui::Checkbox("fill", &fixed_fill);
PopStyleCompact();
if (ImGui::BeginTable("##table1", 3, flags, ImVec2(use_all_width ? -FLT_MIN : 0.0f, 0.0f)))
ImVec2 outer_size(fixed_fill ? -FLT_MIN : 0.0f, 0.0f);
if (ImGui::BeginTable("##table1", 3, flags, outer_size))
{
for (int row = 0; row < 5; row++)
{
@ -3682,8 +3726,10 @@ static void ShowDemoWindowTables()
ImGui::SetNextItemOpen(open_action != 0);
if (ImGui::TreeNode("Resizable, mixed"))
{
HelpMarker("Using columns flag to alter resizing policy on a per-column basis.");
static ImGuiTableFlags flags = ImGuiTableFlags_SizingPolicyFixed | ImGuiTableFlags_RowBg | ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable;
HelpMarker(
"Using TableSetupColumn() to alter resizing policy on a per-column basis.\n\n"
"When combining Fixed and Stretch columns, generally you only want one, maybe two trailing columns to use _WidthStretch.");
static ImGuiTableFlags flags = ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_RowBg | ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable;
if (ImGui::BeginTable("##table1", 3, flags))
{
@ -3729,7 +3775,9 @@ static void ShowDemoWindowTables()
ImGui::SetNextItemOpen(open_action != 0);
if (ImGui::TreeNode("Reorderable, hideable, with headers"))
{
HelpMarker("Click and drag column headers to reorder columns.\n\nYou can also right-click on a header to open a context menu.");
HelpMarker(
"Click and drag column headers to reorder columns.\n\n"
"Right-click on a header to open a context menu.");
static ImGuiTableFlags flags = ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV;
PushStyleCompact();
ImGui::CheckboxFlags("ImGuiTableFlags_Resizable", &flags, ImGuiTableFlags_Resizable);
@ -3760,7 +3808,7 @@ static void ShowDemoWindowTables()
}
// Use outer_size.x == 0.0f instead of default to make the table as tight as possible (only valid when no scrolling and no stretch column)
if (ImGui::BeginTable("##table2", 3, flags | ImGuiTableFlags_SizingPolicyFixed, ImVec2(0.0f, 0.0f)))
if (ImGui::BeginTable("##table2", 3, flags | ImGuiTableFlags_SizingFixedFit, ImVec2(0.0f, 0.0f)))
{
ImGui::TableSetupColumn("One");
ImGui::TableSetupColumn("Two");
@ -3792,7 +3840,8 @@ static void ShowDemoWindowTables()
"- BorderOuterV\n"
"- any form of row selection\n"
"Because of this, activating BorderOuterV sets the default to PadOuterX. Using PadOuterX or NoPadOuterX you can override the default.\n\n"
"Actual padding values are using style.CellPadding.");
"Actual padding values are using style.CellPadding.\n\n"
"In this demo we don't show horizontal borders to emphasis how they don't affect default horizontal padding.");
static ImGuiTableFlags flags1 = ImGuiTableFlags_BordersV;
PushStyleCompact();
@ -3846,7 +3895,7 @@ static void ShowDemoWindowTables()
HelpMarker("Setting style.CellPadding to (0,0) or a custom value.");
static ImGuiTableFlags flags2 = ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg;
static ImVec2 cell_padding(0.0f, 0.0f);
static bool show_widget_frame_bg = false;
static bool show_widget_frame_bg = true;
PushStyleCompact();
ImGui::CheckboxFlags("ImGuiTableFlags_Borders", &flags2, ImGuiTableFlags_Borders);
@ -3889,32 +3938,108 @@ static void ShowDemoWindowTables()
if (open_action != -1)
ImGui::SetNextItemOpen(open_action != 0);
if (ImGui::TreeNode("Explicit widths"))
if (ImGui::TreeNode("Sizing policies"))
{
static ImGuiTableFlags flags = ImGuiTableFlags_None;
static bool fixed_fill = true;
static ImGuiTableFlags flags1 = ImGuiTableFlags_BordersV | ImGuiTableFlags_BordersOuterH | ImGuiTableFlags_RowBg | ImGuiTableFlags_ContextMenuInBody;
PushStyleCompact();
ImGui::CheckboxFlags("ImGuiTableFlags_NoKeepColumnsVisible", &flags, ImGuiTableFlags_NoKeepColumnsVisible);
ImGui::CheckboxFlags("ImGuiTableFlags_BordersInnerV", &flags, ImGuiTableFlags_BordersInnerV);
ImGui::CheckboxFlags("ImGuiTableFlags_BordersOuterV", &flags, ImGuiTableFlags_BordersOuterV);
ImGui::Checkbox("fill", &fixed_fill);
ImGui::SameLine(); HelpMarker(
"Value passed to outer_size only affects tables with _SizingFixedFit or _SizingFixedSame sizing policies.\n\n"
" - outer_size.x == 0: table fit to columns total contents.\n"
" - outer_size.x == -FLT_MIN: table fill until right-most edge.");
ImGui::CheckboxFlags("ImGuiTableFlags_Resizable", &flags1, ImGuiTableFlags_Resizable);
PopStyleCompact();
if (ImGui::BeginTable("##table1", 4, flags))
ImVec2 outer_size = ImVec2(fixed_fill ? -FLT_MIN : 0.0f, 0.0f);
static ImGuiTableFlags sizing_policy_flags[4] = { ImGuiTableFlags_SizingFixedFit, ImGuiTableFlags_SizingFixedSame, ImGuiTableFlags_SizingStretchProp, ImGuiTableFlags_SizingStretchSame };
for (int table_n = 0; table_n < 4; table_n++)
{
// We could also set ImGuiTableFlags_SizingPolicyFixed on the table and all columns will default to ImGuiTableColumnFlags_WidthFixed.
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed, 100.0f);
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed, TEXT_BASE_WIDTH * 15.0f);
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed, TEXT_BASE_WIDTH * 30.0f);
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed, TEXT_BASE_WIDTH * 15.0f);
for (int row = 0; row < 5; row++)
ImGui::PushID(table_n);
ImGui::SetNextItemWidth(TEXT_BASE_WIDTH * 30);
EditTableSizingFlags(&sizing_policy_flags[table_n]);
// To make it easier to understand the different sizing policy,
// For each policy: we display one table where the columns have equal contents width, and one where the columns have different contents width.
if (ImGui::BeginTable("##table1", 3, sizing_policy_flags[table_n] | flags1, outer_size))
{
ImGui::TableNextRow();
for (int column = 0; column < 4; column++)
for (int row = 0; row < 3; row++)
{
ImGui::TableSetColumnIndex(column);
if (row == 0)
ImGui::Text("(%.2f)", ImGui::GetContentRegionAvail().x);
ImGui::Text("Hello %d,%d", column, row);
ImGui::TableNextRow();
ImGui::TableNextColumn(); ImGui::Text("Oh dear");
ImGui::TableNextColumn(); ImGui::Text("Oh dear");
ImGui::TableNextColumn(); ImGui::Text("Oh dear");
}
ImGui::EndTable();
}
if (ImGui::BeginTable("##table2", 3, sizing_policy_flags[table_n] | flags1, outer_size))
{
for (int row = 0; row < 3; row++)
{
ImGui::TableNextRow();
ImGui::TableNextColumn(); ImGui::Text("AAAA");
ImGui::TableNextColumn(); ImGui::Text("BBBBBBBB");
ImGui::TableNextColumn(); ImGui::Text("CCCCCCCCCCCC");
}
ImGui::EndTable();
}
ImGui::PopID();
}
ImGui::Spacing();
ImGui::TextUnformatted("Advanced");
ImGui::SameLine();
HelpMarker("This section allows you to interact and see the effect of various sizing policies depending on whether Scroll is enabled and the contents of your columns.");
enum ContentsType { CT_ShowWidth, CT_ShortText, CT_LongText, CT_Button, CT_FillButton, CT_InputText };
static ImGuiTableFlags flags = ImGuiTableFlags_ScrollY | ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg | ImGuiTableFlags_Resizable;
static int contents_type = CT_ShowWidth;
static int column_count = 3;
PushStyleCompact();
ImGui::PushID("Advanced");
ImGui::PushItemWidth(TEXT_BASE_WIDTH * 30);
EditTableSizingFlags(&flags);
ImGui::Combo("Contents", &contents_type, "Show width\0Short Text\0Long Text\0Button\0Fill Button\0InputText\0");
if (contents_type == CT_FillButton)
{
ImGui::SameLine();
HelpMarker("Be mindful that using right-alignment (e.g. size.x = -FLT_MIN) creates a feedback loop where contents width can feed into auto-column width can feed into contents width.");
}
ImGui::DragInt("Columns", &column_count, 0.1f, 1, 64, "%d", ImGuiSliderFlags_AlwaysClamp);
ImGui::CheckboxFlags("ImGuiTableFlags_Resizable", &flags, ImGuiTableFlags_Resizable);
ImGui::CheckboxFlags("ImGuiTableFlags_PreciseWidths", &flags, ImGuiTableFlags_PreciseWidths);
ImGui::SameLine(); HelpMarker("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.");
ImGui::CheckboxFlags("ImGuiTableFlags_ScrollX", &flags, ImGuiTableFlags_ScrollX);
ImGui::CheckboxFlags("ImGuiTableFlags_ScrollY", &flags, ImGuiTableFlags_ScrollY);
ImGui::CheckboxFlags("ImGuiTableFlags_NoClip", &flags, ImGuiTableFlags_NoClip);
ImGui::PopItemWidth();
ImGui::PopID();
PopStyleCompact();
outer_size = ImVec2(-FLT_MIN, TEXT_BASE_HEIGHT * 7);
if (ImGui::BeginTable("##table2", column_count, flags, outer_size))
{
for (int cell = 0; cell < 10 * column_count; cell++)
{
ImGui::TableNextColumn();
int column = ImGui::TableGetColumnIndex();
int row = ImGui::TableGetRowIndex();
ImGui::PushID(cell);
char label[32];
static char text_buf[32] = "";
sprintf(label, "Hello %d,%d", column, row);
switch (contents_type)
{
case CT_ShortText: ImGui::TextUnformatted(label); break;
case CT_LongText: ImGui::Text("Some %s text %d,%d\nOver two lines..", column == 0 ? "long" : "longeeer", column, row); break;
case CT_ShowWidth: ImGui::Text("W: %.1f", ImGui::GetContentRegionAvail().x); break;
case CT_Button: ImGui::Button(label); break;
case CT_FillButton: ImGui::Button(label, ImVec2(-FLT_MIN, 0.0f)); break;
case CT_InputText: ImGui::SetNextItemWidth(-FLT_MIN); ImGui::InputText("##", text_buf, IM_ARRAYSIZE(text_buf)); break;
}
ImGui::PopID();
}
ImGui::EndTable();
}
@ -3968,7 +4093,7 @@ static void ShowDemoWindowTables()
if (ImGui::TreeNode("Horizontal scrolling"))
{
HelpMarker(
"When ScrollX is enabled, the default sizing policy becomes ImGuiTableFlags_SizingPolicyFixed,"
"When ScrollX is enabled, the default sizing policy becomes ImGuiTableFlags_SizingFixedFit, "
"as automatically stretching columns doesn't make much sense with horizontal scrolling.\n\n"
"Also note that as of the current version, you will almost always want to enable ScrollY along with ScrollX,"
"because the container window won't automatically extend vertically to fix contents (this may be improved in future versions).");
@ -4021,6 +4146,33 @@ static void ShowDemoWindowTables()
}
ImGui::EndTable();
}
ImGui::Spacing();
ImGui::TextUnformatted("Stretch + ScrollX");
ImGui::SameLine();
HelpMarker(
"Showcase using Stretch columns + ScrollX together: "
"this is rather unusual and only makes sense when specifying an 'inner_width' for the table!\n"
"Without an explicit value, inner_width is == outer_size.x and therefore using Stretch columns + ScrollX together doesn't make sense.");
static ImGuiTableFlags flags2 = ImGuiTableFlags_SizingStretchSame | ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_RowBg | ImGuiTableFlags_ContextMenuInBody;
static float inner_width = 1000.0f;
PushStyleCompact();
ImGui::PushID("flags3");
ImGui::PushItemWidth(TEXT_BASE_WIDTH * 30);
ImGui::CheckboxFlags("ImGuiTableFlags_ScrollX", &flags2, ImGuiTableFlags_ScrollX);
ImGui::DragFloat("inner_width", &inner_width, 1.0f, 0.0f, FLT_MAX, "%.1f");
ImGui::PopItemWidth();
ImGui::PopID();
PopStyleCompact();
if (ImGui::BeginTable("##table2", 7, flags2, outer_size, inner_width))
{
for (int cell = 0; cell < 20 * 7; cell++)
{
ImGui::TableNextColumn();
ImGui::Text("Hello world %d,%d", ImGui::TableGetColumnIndex(), ImGui::TableGetRowIndex());
}
ImGui::EndTable();
}
ImGui::TreePop();
}
@ -4059,7 +4211,7 @@ static void ShowDemoWindowTables()
// We use a scrolling table to be able to showcase the difference between the _IsEnabled and _IsVisible flags above, otherwise in
// a non-scrolling table columns are always visible (unless using ImGuiTableFlags_NoKeepColumnsVisible + resizing the parent window down)
const ImGuiTableFlags flags
= ImGuiTableFlags_SizingPolicyFixed | ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY
= 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);
@ -4090,7 +4242,43 @@ static void ShowDemoWindowTables()
if (open_action != -1)
ImGui::SetNextItemOpen(open_action != 0);
if (ImGui::TreeNode("Nested"))
if (ImGui::TreeNode("Columns widths"))
{
HelpMarker("Using TableSetupColumn() to setup explicit width.");
static ImGuiTableFlags flags = ImGuiTableFlags_None;
PushStyleCompact();
ImGui::CheckboxFlags("ImGuiTableFlags_NoKeepColumnsVisible", &flags, ImGuiTableFlags_NoKeepColumnsVisible);
ImGui::CheckboxFlags("ImGuiTableFlags_BordersInnerV", &flags, ImGuiTableFlags_BordersInnerV);
ImGui::CheckboxFlags("ImGuiTableFlags_BordersOuterV", &flags, ImGuiTableFlags_BordersOuterV);
PopStyleCompact();
if (ImGui::BeginTable("##table1", 4, flags))
{
// We could also set ImGuiTableFlags_SizingFixedFit on the table and all columns will default to ImGuiTableColumnFlags_WidthFixed.
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed, 100.0f);
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed, TEXT_BASE_WIDTH * 15.0f);
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed, TEXT_BASE_WIDTH * 30.0f);
ImGui::TableSetupColumn("", ImGuiTableColumnFlags_WidthFixed, TEXT_BASE_WIDTH * 15.0f);
for (int row = 0; row < 5; row++)
{
ImGui::TableNextRow();
for (int column = 0; column < 4; column++)
{
ImGui::TableSetColumnIndex(column);
if (row == 0)
ImGui::Text("(%.2f)", ImGui::GetContentRegionAvail().x);
ImGui::Text("Hello %d,%d", column, row);
}
}
ImGui::EndTable();
}
ImGui::TreePop();
}
if (open_action != -1)
ImGui::SetNextItemOpen(open_action != 0);
if (ImGui::TreeNode("Nested tables"))
{
HelpMarker("This demonstrate embedding a table into another table cell.");
@ -4132,141 +4320,6 @@ static void ShowDemoWindowTables()
ImGui::TreePop();
}
if (open_action != -1)
ImGui::SetNextItemOpen(open_action != 0);
if (ImGui::TreeNode("Sizing policies, cell contents"))
{
HelpMarker("This section allows you to interact and see the effect of StretchX vs FixedX sizing policies depending on whether Scroll is enabled and the contents of your columns.");
enum ContentsType { CT_ShortText, CT_LongText, CT_Button, CT_FillButton, CT_InputText };
static ImGuiTableFlags flags = ImGuiTableFlags_ScrollY | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_RowBg;
static int contents_type = CT_LongText;
static int column_count = 3;
PushStyleCompact();
ImGui::PushItemWidth(TEXT_BASE_WIDTH * 30);
ImGui::Combo("Contents", &contents_type, "Short Text\0Long Text\0Button\0Fill Button\0InputText\0");
if (contents_type == CT_FillButton)
{
ImGui::SameLine();
HelpMarker("Be mindful that using right-alignment (e.g. size.x = -FLT_MIN) creates a feedback loop where contents width can feed into auto-column width can feed into contents width.");
}
ImGui::DragInt("Columns", &column_count, 0.1f, 1, 64, "%d", ImGuiSliderFlags_AlwaysClamp);
ImGui::PopItemWidth();
ImGui::CheckboxFlags("ImGuiTableFlags_BordersInnerH", &flags, ImGuiTableFlags_BordersInnerH);
ImGui::CheckboxFlags("ImGuiTableFlags_BordersOuterH", &flags, ImGuiTableFlags_BordersOuterH);
ImGui::CheckboxFlags("ImGuiTableFlags_BordersInnerV", &flags, ImGuiTableFlags_BordersInnerV);
ImGui::CheckboxFlags("ImGuiTableFlags_BordersOuterV", &flags, ImGuiTableFlags_BordersOuterV);
ImGui::CheckboxFlags("ImGuiTableFlags_ScrollX", &flags, ImGuiTableFlags_ScrollX);
ImGui::CheckboxFlags("ImGuiTableFlags_ScrollY", &flags, ImGuiTableFlags_ScrollY);
if (ImGui::CheckboxFlags("ImGuiTableFlags_SizingPolicyStretch", &flags, ImGuiTableFlags_SizingPolicyStretch))
flags &= ~ImGuiTableFlags_SizingPolicyFixed; // Can't specify both sizing polices so we clear the other
ImGui::SameLine(); HelpMarker("Default if _ScrollX if disabled. Makes columns use _WidthStretch policy by default.");
if (ImGui::CheckboxFlags("ImGuiTableFlags_SizingPolicyFixed", &flags, ImGuiTableFlags_SizingPolicyFixed))
flags &= ~ImGuiTableFlags_SizingPolicyStretch; // Can't specify both sizing polices so we clear the other
ImGui::SameLine(); HelpMarker("Default if _ScrollX if enabled. Makes columns use _WidthFixed by default, or _WidthFixedResize if _Resizable is not set.");
ImGui::CheckboxFlags("ImGuiTableFlags_PreciseWidths", &flags, ImGuiTableFlags_PreciseWidths);
ImGui::SameLine(); HelpMarker("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.");
ImGui::CheckboxFlags("ImGuiTableFlags_Resizable", &flags, ImGuiTableFlags_Resizable);
ImGui::CheckboxFlags("ImGuiTableFlags_NoClip", &flags, ImGuiTableFlags_NoClip);
PopStyleCompact();
ImVec2 outer_size(-FLT_MIN, TEXT_BASE_HEIGHT * 7);
if (ImGui::BeginTable("##nways", column_count, flags, outer_size))
{
for (int cell = 0; cell < 10 * column_count; cell++)
{
ImGui::TableNextColumn();
int column = ImGui::TableGetColumnIndex();
int row = ImGui::TableGetRowIndex();
ImGui::PushID(cell);
char label[32];
static char text_buf[32] = "";
sprintf(label, "Hello %d,%d", column, row);
switch (contents_type)
{
case CT_ShortText: ImGui::TextUnformatted(label); break;
case CT_LongText: ImGui::Text("Some longer text %d,%d\nOver two lines..", column, row); break;
case CT_Button: ImGui::Button(label); break;
case CT_FillButton: ImGui::Button(label, ImVec2(-FLT_MIN, 0.0f)); break;
case CT_InputText: ImGui::SetNextItemWidth(-FLT_MIN); ImGui::InputText("##", text_buf, IM_ARRAYSIZE(text_buf)); break;
}
ImGui::PopID();
}
ImGui::EndTable();
}
ImGui::TextUnformatted("Item Widths");
ImGui::SameLine();
HelpMarker("Showcase using PushItemWidth() and how it is preserved on a per-column basis");
if (ImGui::BeginTable("##table2", 3, ImGuiTableFlags_Borders))
{
ImGui::TableSetupColumn("small");
ImGui::TableSetupColumn("half");
ImGui::TableSetupColumn("right-align");
ImGui::TableHeadersRow();
for (int row = 0; row < 3; row++)
{
ImGui::TableNextRow();
if (row == 0)
{
// Setup ItemWidth once (instead of setting up every time, which is also possible but less efficient)
ImGui::TableSetColumnIndex(0);
ImGui::PushItemWidth(TEXT_BASE_WIDTH * 3.0f); // Small
ImGui::TableSetColumnIndex(1);
ImGui::PushItemWidth(-ImGui::GetContentRegionAvail().x * 0.5f);
ImGui::TableSetColumnIndex(2);
ImGui::PushItemWidth(-FLT_MIN); // Right-aligned
}
// Draw our contents
static float dummy_f = 0.0f;
ImGui::PushID(row);
ImGui::TableSetColumnIndex(0);
ImGui::SliderFloat("float0", &dummy_f, 0.0f, 1.0f);
ImGui::TableSetColumnIndex(1);
ImGui::SliderFloat("float1", &dummy_f, 0.0f, 1.0f);
ImGui::TableSetColumnIndex(2);
ImGui::SliderFloat("float2", &dummy_f, 0.0f, 1.0f);
ImGui::PopID();
}
ImGui::EndTable();
}
ImGui::TextUnformatted("Stretch + ScrollX");
ImGui::SameLine();
HelpMarker(
"Showcase using Stretch columns + ScrollX together: "
"this is rather unusual and only makes sense when specifying an 'inner_width' for the table!\n"
"Without an explicit value, inner_width is == outer_size.x and therefore using Stretch columns + ScrollX together doesn't make sense.");
static ImGuiTableFlags flags3 = ImGuiTableFlags_SizingPolicyStretch | ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_RowBg;
static float inner_width = 1000.0f;
PushStyleCompact();
ImGui::PushID("flags3");
ImGui::PushItemWidth(TEXT_BASE_WIDTH * 30);
ImGui::CheckboxFlags("ImGuiTableFlags_ScrollX", &flags3, ImGuiTableFlags_ScrollX);
if (ImGui::CheckboxFlags("ImGuiTableFlags_SizingPolicyStretch", &flags3, ImGuiTableFlags_SizingPolicyStretch))
flags3 &= ~ImGuiTableFlags_SizingPolicyFixed; // Can't specify both sizing polices so we clear the other
if (ImGui::CheckboxFlags("ImGuiTableFlags_SizingPolicyFixed", &flags3, ImGuiTableFlags_SizingPolicyFixed))
flags3 &= ~ImGuiTableFlags_SizingPolicyStretch; // Can't specify both sizing polices so we clear the other
ImGui::DragFloat("inner_width", &inner_width, 1.0f, 0.0f, FLT_MAX, "%.1f");
ImGui::PopItemWidth();
ImGui::PopID();
PopStyleCompact();
if (ImGui::BeginTable("##table3", 7, flags3 | ImGuiTableFlags_SizingPolicyStretch | ImGuiTableFlags_ContextMenuInBody, outer_size, inner_width))
{
for (int cell = 0; cell < 20 * 7; cell++)
{
ImGui::TableNextColumn();
ImGui::Text("Hello world %d,%d", ImGui::TableGetColumnIndex(), ImGui::TableGetRowIndex());
}
ImGui::EndTable();
}
ImGui::TreePop();
}
if (open_action != -1)
ImGui::SetNextItemOpen(open_action != 0);
if (ImGui::TreeNode("Row height"))
@ -4294,11 +4347,15 @@ static void ShowDemoWindowTables()
// 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:");
static ImGuiTableFlags flags = ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_ContextMenuInBody | ImGuiTableFlags_RowBg | ImGuiTableFlags_SizingPolicyFixed;
static bool use_all_width = false;
ImGui::Checkbox("Use all width", &use_all_width);
PushStyleCompact();
static ImGuiTableFlags flags = ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_ContextMenuInBody | ImGuiTableFlags_RowBg | ImGuiTableFlags_SizingFixedFit;
static bool fixed_fill = false;
ImGui::Checkbox("fill", &fixed_fill);
ImGui::CheckboxFlags("ImGuiTableFlags_NoHostExtendY", &flags, ImGuiTableFlags_NoHostExtendY);
if (ImGui::BeginTable("##table3", 3, flags, ImVec2(use_all_width ? -FLT_MIN : 0.0f, TEXT_BASE_HEIGHT * 5.5f)))
PopStyleCompact();
ImVec2 outer_size = ImVec2(fixed_fill ? -FLT_MIN : 0.0f, TEXT_BASE_HEIGHT * 5.5f);
if (ImGui::BeginTable("##table3", 3, flags, outer_size))
{
for (int row = 0; row < 10; row++)
{
@ -4476,6 +4533,50 @@ static void ShowDemoWindowTables()
ImGui::TreePop();
}
if (open_action != -1)
ImGui::SetNextItemOpen(open_action != 0);
if (ImGui::TreeNode("Item width"))
{
HelpMarker(
"Showcase using PushItemWidth() and how it is preserved on a per-column basis.\n\n"
"Note that on auto-resizing non-resizable fixed columns, querying the content width for e.g. right-alignment doesn't make sense.");
if (ImGui::BeginTable("##table2", 3, ImGuiTableFlags_Borders))
{
ImGui::TableSetupColumn("small");
ImGui::TableSetupColumn("half");
ImGui::TableSetupColumn("right-align");
ImGui::TableHeadersRow();
for (int row = 0; row < 3; row++)
{
ImGui::TableNextRow();
if (row == 0)
{
// Setup ItemWidth once (instead of setting up every time, which is also possible but less efficient)
ImGui::TableSetColumnIndex(0);
ImGui::PushItemWidth(TEXT_BASE_WIDTH * 3.0f); // Small
ImGui::TableSetColumnIndex(1);
ImGui::PushItemWidth(-ImGui::GetContentRegionAvail().x * 0.5f);
ImGui::TableSetColumnIndex(2);
ImGui::PushItemWidth(-FLT_MIN); // Right-aligned
}
// Draw our contents
static float dummy_f = 0.0f;
ImGui::PushID(row);
ImGui::TableSetColumnIndex(0);
ImGui::SliderFloat("float0", &dummy_f, 0.0f, 1.0f);
ImGui::TableSetColumnIndex(1);
ImGui::SliderFloat("float1", &dummy_f, 0.0f, 1.0f);
ImGui::TableSetColumnIndex(2);
ImGui::SliderFloat("float2", &dummy_f, 0.0f, 1.0f);
ImGui::PopID();
}
ImGui::EndTable();
}
ImGui::TreePop();
}
// Demonstrate using TableHeader() calls instead of TableHeadersRow()
if (open_action != -1)
ImGui::SetNextItemOpen(open_action != 0);
@ -4566,7 +4667,7 @@ static void ShowDemoWindowTables()
// [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_SizingPolicyFixed | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable | ImGuiTableFlags_Borders;
ImGuiTableFlags flags2 = ImGuiTableFlags_Resizable | ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable | ImGuiTableFlags_Borders;
if (ImGui::BeginTable("##table2", COLUMNS_COUNT, flags2))
{
ImGui::TableSetupColumn("One");
@ -4640,7 +4741,7 @@ static void ShowDemoWindowTables()
char buf[32];
sprintf(buf, "Synced Table %d", n);
bool open = ImGui::CollapsingHeader(buf, ImGuiTreeNodeFlags_DefaultOpen);
if (open && ImGui::BeginTable("Table", 3, ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable | ImGuiTableFlags_Borders | ImGuiTableFlags_SizingPolicyFixed | ImGuiTableFlags_NoSavedSettings))
if (open && ImGui::BeginTable("Table", 3, ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable | ImGuiTableFlags_Borders | ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_NoSavedSettings))
{
ImGui::TableSetupColumn("One");
ImGui::TableSetupColumn("Two");
@ -4689,10 +4790,12 @@ static void ShowDemoWindowTables()
ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable | ImGuiTableFlags_Sortable | ImGuiTableFlags_SortMulti
| ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV | ImGuiTableFlags_NoBordersInBody
| ImGuiTableFlags_ScrollY;
PushStyleCompact();
ImGui::CheckboxFlags("ImGuiTableFlags_SortMulti", &flags, ImGuiTableFlags_SortMulti);
ImGui::SameLine(); HelpMarker("When sorting is enabled: hold shift when clicking headers to sort on multiple column. TableGetSortSpecs() may return specs where (SpecsCount > 1).");
ImGui::CheckboxFlags("ImGuiTableFlags_SortTristate", &flags, ImGuiTableFlags_SortTristate);
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))
{
@ -4756,7 +4859,7 @@ static void ShowDemoWindowTables()
| ImGuiTableFlags_Sortable | ImGuiTableFlags_SortMulti
| ImGuiTableFlags_RowBg | ImGuiTableFlags_Borders | ImGuiTableFlags_NoBordersInBody
| ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY
| ImGuiTableFlags_SizingPolicyFixed;
| ImGuiTableFlags_SizingFixedFit;
enum ContentsType { CT_Text, CT_Button, CT_SmallButton, CT_FillButton, CT_Selectable, CT_SelectableSpanRow };
static int contents_type = CT_SelectableSpanRow;
@ -4805,18 +4908,13 @@ static void ShowDemoWindowTables()
if (ImGui::TreeNodeEx("Sizing:", ImGuiTreeNodeFlags_DefaultOpen))
{
if (ImGui::CheckboxFlags("ImGuiTableFlags_SizingPolicyStretch", &flags, ImGuiTableFlags_SizingPolicyStretch))
flags &= ~ImGuiTableFlags_SizingPolicyFixed; // Can't specify both sizing polices so we clear the other
ImGui::SameLine(); HelpMarker("[Default if ScrollX is off]\nFit all columns within available width (or specified inner_width). Fixed and Stretch columns allowed.");
if (ImGui::CheckboxFlags("ImGuiTableFlags_SizingPolicyFixed", &flags, ImGuiTableFlags_SizingPolicyFixed))
flags &= ~ImGuiTableFlags_SizingPolicyStretch; // Can't specify both sizing polices so we clear the other
ImGui::SameLine(); HelpMarker("[Default if ScrollX is on]\nEnlarge as needed: enable scrollbar if ScrollX is enabled, otherwise extend parent window's contents rectangle. Only Fixed columns allowed. Stretched columns will calculate their width assuming no scrolling.");
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_NoHostExtendY", &flags, ImGuiTableFlags_NoHostExtendY);
ImGui::CheckboxFlags("ImGuiTableFlags_NoKeepColumnsVisible", &flags, ImGuiTableFlags_NoKeepColumnsVisible);
ImGui::SameLine(); HelpMarker("Only available if ScrollX is disabled.");
ImGui::CheckboxFlags("ImGuiTableFlags_PreciseWidths", &flags, ImGuiTableFlags_PreciseWidths);
ImGui::SameLine(); HelpMarker("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.");
ImGui::CheckboxFlags("ImGuiTableFlags_SameWidths", &flags, ImGuiTableFlags_SameWidths);
ImGui::CheckboxFlags("ImGuiTableFlags_NoClip", &flags, ImGuiTableFlags_NoClip);
ImGui::SameLine(); HelpMarker("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.");
ImGui::TreePop();