目录

ImGui表格

ImGui表格用法

https://github.com/ocornut/imgui/issues/3740

典型流程:

  1. 调用BeginTable()。
  2. 可选择调用TableSetupColumn()提交列名/标志/默认值。
  3. 可选地调用TableSetupScrollFreeze()来请求对列/行进行滚动冻结。
  4. 可选择调用TableHeadersRow()提交标题行。名称从TableSetupColumn()数据中提取。
  5. 填充内容:
  • 在大多数情况下,您可以使用TableNextRow() + TableSetColumnIndex(N)开始附加到列中。
  • 如果您使用表格作为一种网格,其中每列都包含相同类型的内容, 您可能更喜欢使用 TableNextColumn() 而不是 TableNextRow() + TableSetColumnIndex()。 如果需要,TableNextColumn()将自动包裹到下一行中。
  • 重要信息:与旧的Colums() API相比,我们需要为第一列调用TableNextColumn()!
  • 可能的呼叫流程摘要:

TableNextRow() -> TableSetColumnIndex(0) -> Text(“Hello 0”) -> TableSetColumnIndex(1) -> Text(“Hello 1”) // OK TableNextRow() -> TableNextColumn() -> Text(“Hello 0”) -> TableNextColumn() -> Text(“Hello 1”) // OK TableNextColumn() -> Text(“Hello 0”) -> TableNextColumn() -> Text(“Hello 1”) // OK:TableNextColumn()会自动进入下一行!

TableNextRow() -> Text(“Hello 0”) // 不行!缺少TableSetColumnIndex()或TableNextColumn()!文本不会出现!

  1. 呼叫EndTable()

简易实例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
				//在这里,我们将展示三种不同的输出表的方法。
				//它们是同样事物的非常简单的变体!

				// [方法1]使用TableNextRow()创建新行,使用TableSetColumnIndex()选择列。
				// 在许多情况下,这是最灵活、最易于使用的模式
				if (ImGui::BeginTable("table1", 3))
				{
					for (int row = 0; row < 4; row++)
					{
						ImGui::TableNextRow();
						for (int column = 0; column < 3; column++)
						{
							ImGui::TableSetColumnIndex(column);
							ImGui::Text("Row %d Column %d", row, column);
						}
					}
					ImGui::EndTable();
				}

				// [方法2]使用多次调用的TableNextColumn(),而不是使用for循环+ TableSetColumnIndex()。
				// 当您有代码手动提交每列的内容时,这通常更方便。
				if (ImGui::BeginTable("table2", 3))
				{
					for (int row = 0; row < 4; row++)
					{
						ImGui::TableNextRow();
						ImGui::TableNextColumn();
						ImGui::Text("Row %d", row);
						ImGui::TableNextColumn();
						ImGui::Text("Some contents");
						ImGui::TableNextColumn();
						ImGui::Text("123.456");
					}
					ImGui::EndTable();
				}

				// [方法3]我们调用TableNextColumn() _before_每个单元格。我们从不调用TableNextRow()
				// 因为TableNextColumn()将自动包裹并根据需要创建新的鱼子。
				// 当您的单元格都包含相同类型的数据时,这通常更方便。
				if (ImGui::BeginTable("table3", 3))
				{
					for (int item = 0; item < 14; item++)
					{
						ImGui::TableNextColumn();
						ImGui::Text("Item %d", item);
					}
					ImGui::EndTable();
				}

API (as of January 2021)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
// 开始附加到表格中。仅当BeginTable()返回true时调用EndTable()!
bool BeginTable(const char* str_id, int columns, ImGuiTableFlags flags = 0, const ImVec2& outer_size = ImVec2(0.0f, 0.0f), float inner_width = 0.0f);
void EndTable();
  
// 附加到新行的第一个单元格中。
void TableNextRow(ImGuiTableRowFlags row_flags = 0, float min_row_height = 0.0f);

// 附加到下一列(如果当前在最后一列,则附加到下一行的第一列)。当
bool TableNextColumn();//列可见。
  
// 附加到指定的列中。当列可见时返回true。
bool TableSetColumnIndex(int column_n);

//表格:标题和列声明
// - 使用TableSetupColumn()指定标签、调整大小策略、默认宽度/重量、ID、各种其他标志等。
// - 使用 TableHeadersRow() 创建一个标题行,并自动为每列提交 TableHeader()。
// 需要标头才能执行:重新排序、排序和打开上下文菜单。
// 上下文菜单也可以使用ImGuiTableFlags_ContextMenuInBody在列正文中提供。
// - 您可以使用TableNextRow() + TableHeader()调用手动提交标头,但这仅在
//一些高级用例(例如,在标题行中添加自定义小部件)。
// - 使用TableSetupScrollFreeze()锁定列/行,以便它们在滚动时保持可见。
void TableSetupColumn(const char* label, ImGuiTableColumnFlags flags = 0, float init_width_or_weight = 0.0f, ImU32 user_id = 0);
void TableSetupScrollFreeze(int cols, int rows); //锁定列/行,以便它们在滚动时保持可见。
void TableHeadersRow(); // 根据提供给 TableSetupColumn() + 提交上下文菜单的数据提交所有标头单元格
void TableHeader(const char* label); //手动提交一个标题单元格(很少使用)

//表格:排序
// - 调用TableGetSortSpecs()来检索表的最新排序规范。不排序时为空。
// - 当'SpecsDirty == true'时,您应该对数据进行排序。当分类规格发生变化时,情况确实如此
// 自上次通话以来,或第一次。排序后,请务必设置“SpecsDirty = false”,否则您可以
// 浪费地对每一帧的数据进行排序!
// - 终身:不要在多个帧上按住此指针,也不要超过对BeginTable()的任何后续调用。
ImGuiTableSortSpecs* TableGetSortSpecs(); // 获取表的最新排序规范(如果不排序,则为NULL)。

//表格:杂项函数
// - 函数args 'int column_n'将-1的默认值视为传递当前列索引。
int TableGetColumnCount(); // 返回列数(值传递给 BeginTable)
int TableGetColumnIndex(); // 返回当前列索引。
int TableGetRowIndex(); // 返回当前行索引。
const char* TableGetColumnName(int column_n = -1); // 如果列没有TableSetupColumn()声明的名称,则返回"。通过-1使用当前列
ImGuiTableColumnFlags TableGetColumnFlags(int column_n = -1); // 返回列标志,以便您可以查询其启用/可见/排序/悬停状态标志。通过-1使用当前列。
void TableSetBgColor(ImGuiTableBgTarget target, ImU32 color, int column_n = -1); // 更改单元格、行或列的颜色。有关详细信息,请参阅ImGuiTableBgTarget_标志。

ImGuiTableFlags

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
// ImGui::BeginTable()的标志
// [BETA API] API可能会略有演变!如果您使用此功能,请在发布时更新到下一个版本!
// - 重要!尺寸政策具有复杂而微妙的副作用,比你想象的要多。
//仔细阅读评论/演示+尝试现场演示以熟悉它们。
// - 默认大小策略是:
// - 如果 ScrollX 已打开,或者主机窗口具有 ImGuiWindowFlags_AlwaysAutoResize,则默认为 ImGuiTableFlags_SizingFixedFit。
// - 如果 ScrollX 关闭,则默认为 ImGuiTableFlags_SizingStretchSame。
// - 当ScrollX关闭时:
// - 表默认为ImGuiTableFlags_SizingStretchSame ->所有列默认为相同重量的ImGuiTableColumnFlags_WidthStretch。
// - 允许列大小策略:拉伸(默认),固定/自动。
// - 固定列通常会获得其要求的宽度(除非表不能全部匹配)。
// - 拉伸列将共享剩余宽度。
// - 混合固定/拉伸列是可能的,但对调整大小行为有各种副作用。
//混合大小策略的典型用途是:任意数量的领先固定列,后跟一两个跟踪拉伸列。
//(这是因为列的可见顺序对它们对手动调整大小的反应有微妙但必要的影响)。
// - 当ScrollX打开时:
// - 表默认为ImGuiTableFlags_SizingFixedFit ->所有列默认为ImGuiTableColumnFlags_WidthFixed
// - 允许列大小策略:主要修复/自动。
// - 固定列可以根据需要放大。如果需要,表格将显示水平滚动条。
// - 使用自动调整大小(不可调整大小)固定列时,查询内容宽度以使用项目对齐,例如SetNextItemWidth(-FLT_MIN)没有意义,会创建一个反馈循环。
// - 如果 ScrollX 处于打开,使用拉伸列通常没有意义,除非您在 BeginTable() 中指定了“inner_width”的值。
// 如果您为“inner_width”指定一个值,那么实际上,滚动空间是已知的,拉伸或混合固定/拉伸列再次变得有意义。
// - 有关详细信息,请阅读imgui_tables.cpp顶部的文档。
enum ImGuiTableFlags_
{
  // 特征
    ImGuiTableFlags_None = 0,
    ImGuiTableFlags_Resizable = 1 << 0, // 启用调整列大小。
    ImGuiTableFlags_Reorderable = 1 << 1, // 在标题行中启用重新排序列(需要调用 TableSetupColumn() + TableHeadersRow() 来显示标题)
    ImGuiTableFlags_Hideable = 1 << 2, // 在上下文菜单中启用隐藏/禁用列。
    ImGuiTableFlags_Sortable = 1 << 3, // 启用排序。调用 TableGetSortSpecs() 以获取排序规范。另请参阅 ImGuiTableFlags_SortMulti 和 ImGuiTableFlags_SortTristate。
    ImGuiTableFlags_NoSavedSettings = 1 << 4, // 禁用 .ini 文件中的持久列顺序、宽度和排序设置。
    ImGuiTableFlags_ContextMenuInBody = 1 << 5, // 右键单击​​列 body/contents 将显示表上下文菜单。默认情况下,它在 TableHeadersRow() 中可用。

    // 装饰
    ImGuiTableFlags_RowBg = 1 << 6, // 使用 ImGuiCol_TableRowBg 或 ImGuiCol_TableRowBgAlt 设置每个 RowBg 颜色(相当于手动在每行上使用 ImGuiTableBgFlags_RowBg0 调用 TableSetBgColor)
    ImGuiTableFlags_BordersInnerH = 1 << 7, // 在行之间绘制水平边框。
    ImGuiTableFlags_BordersOuterH = 1 << 8, // 在顶部和底部绘制水平边框。
    ImGuiTableFlags_BordersInnerV = 1 << 9, // 在列之间绘制垂直边框。
    ImGuiTableFlags_BordersOuterV = 1 << 10, // 在左右两侧绘制垂直边框。
    ImGuiTableFlags_BordersH = ImGuiTableFlags_BordersInnerH | ImGuiTableFlags_BordersOuterH, // 绘制水平边框。
    ImGuiTableFlags_BordersV = ImGuiTableFlags_BordersInnerV | ImGuiTableFlags_BordersOuterV, // 绘制垂直边框。
    ImGuiTableFlags_BordersInner = ImGuiTableFlags_BordersInnerV | ImGuiTableFlags_BordersInnerH, // 绘制内边框。
    ImGuiTableFlags_BordersOuter = ImGuiTableFlags_BordersOuterV | ImGuiTableFlags_BordersOuterH, // 绘制外边框。
    ImGuiTableFlags_Borders = ImGuiTableFlags_BordersInner | ImGuiTableFlags_BordersOuter, // 绘制所有边框。
    ImGuiTableFlags_NoBordersInBody = 1 << 11, // [ALPHA] 在列 Body 中禁用垂直边框(边框将始终出现在 Headers 中)。 -> 可能会转向风格
    ImGuiTableFlags_NoBordersInBodyUntilResize = 1 << 12, // [ALPHA] 禁用列 Body 中的垂直边框,直到悬停以调整大小(边框将始终出现在标题中)。 -> 可能会转向风格

    // 大小调整策略(阅读上面的默认值)
    ImGuiTableFlags_SizingFixedFit = 1 << 13, // 列默认为 _WidthFixed 或 _WidthAuto(如果可调整大小或不可调整大小),匹配内容宽度。
    ImGuiTableFlags_SizingFixedSame = 2 << 13, // 列默认为 _WidthFixed 或 _WidthAuto(如果可调整大小或不可调整大小),匹配所有列的最大内容宽度。隐式启用 ImGuiTableFlags_NoKeepColumnsVisible。
    ImGuiTableFlags_SizingStretchProp = 3 << 13, // 列默认为 _WidthStretch,默认权重与每列内容宽度成比例。
    ImGuiTableFlags_SizingStretchSame = 4 << 13, // 列默认为 _WidthStretch,默认权重都相等,除非被 TableSetupColumn() 覆盖。

    // 调整额外选项的大小
    ImGuiTableFlags_NoHostExtendX = 1 << 16, // 使外部宽度自动适应列,覆盖 outer_size.x 值。仅在禁用 ScrollX/ScrollY 且未使用 Stretch 列时可用。
    ImGuiTableFlags_NoHostExtendY = 1 << 17, // 使外部高度正好停在 outer_size.y 处(防止自动扩展表超出限制)。仅在禁用 ScrollX/ScrollY 时可用。低于限制的数据将被剪裁且不可见。
    ImGuiTableFlags_NoKeepColumnsVisible = 1 << 18, // 当 ScrollX 关闭且表格变得太小时时,禁用保持列始终最低限度可见。如果列可调整大小,则不推荐。
    ImGuiTableFlags_PreciseWidths = 1 << 19, // 禁用将剩余宽度分配给拉伸列(在具有 3 列的 100 宽表上分配宽度:没有此标志:33,33,34。使用此标志:33,33,33)。随着列数的增加,调整大小会显得不那么平滑。

    // 剪裁
    ImGuiTableFlags_NoClip = 1 << 20, // 为每个单独的列禁用剪切矩形(减少绘制命令计数,项目将能够溢出到其他列)。通常与 TableSetupScrollFreeze() 不兼容。

    // 填充
    ImGuiTableFlags_PadOuterX = 1 << 21, // 如果 BordersOuterV 开启则默认。启用最外边距。如果您有标题,通常是可取的。
    ImGuiTableFlags_NoPadOuterX = 1 << 22, //如果 BordersOuterV 关闭,则为默认值。禁用最外面的填充。
    ImGuiTableFlags_NoPadInnerX = 1 << 23, // 禁用列之间的内部填充(如果 BordersOuterV 开启,则双内部填充,如果 BordersOuterV 关闭,则单内部填充)。

    // 滚动
    ImGuiTableFlags_ScrollX = 1 << 24, // 启用水平滚动。需要 BeginTable() 的“outer_size”参数来指定容器大小。更改默认大小调整策略。因为这样会创建一个子窗口,所以目前使用 ScrollX 时一般推荐使用 ScrollY。
    ImGuiTableFlags_ScrollY = 1 << 25, // 启用垂直滚动。需要 BeginTable() 的“outer_size”参数来指定容器大小。

    // 排序
    ImGuiTableFlags_SortMulti = 1 << 26, // 单击标题以对多列进行排序时按住 shift。 TableGetSortSpecs() 可能会返回规范,其中 (SpecsCount > 1)。
    ImGuiTableFlags_SortTristate = 1 << 27, // 不允许排序,禁用默认排序。 TableGetSortSpecs() 可能会返回规范,其中 (SpecsCount == 0)。
};

ImGuiTableColumnFlags

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// ImGui::TableSetupColumn() 的标志
enum ImGuiTableColumnFlags_
{
    // 输入配置标志
    ImGuiTableColumnFlags_None = 0,
    ImGuiTableColumnFlags_DefaultHide = 1 << 0, // 默认为隐藏/禁用列。
    ImGuiTableColumnFlags_DefaultSort = 1 << 1, // 默认为排序列。
    ImGuiTableColumnFlags_WidthStretch = 1 << 2, // 列将拉伸。最好禁用水平滚动(如果表大小调整策略为 _SizingStretchSame 或 _SizingStretchProp,则为默认值)。
    ImGuiTableColumnFlags_WidthFixed = 1 << 3, // 列不会拉伸。最好启用水平滚动(如果表大小策略为 _SizingFixedFit 并且表可调整大小,则默认为)。
    ImGuiTableColumnFlags_NoResize = 1 << 4, // 禁用手动调整大小。
    ImGuiTableColumnFlags_NoReorder = 1 << 5, // 禁用手动重新排序此列,这也将防止其他列跨越此列。
    ImGuiTableColumnFlags_NoHide = 1 << 6, // 禁用隐藏/禁用此列的功能。
    ImGuiTableColumnFlags_NoClip = 1 << 7, // 禁用此列的剪辑(所有 NoClip 列将在同一个绘制命令中呈现)。
    ImGuiTableColumnFlags_NoSort = 1 << 8, // 禁用对该字段进行排序的能力(即使在表上设置了 ImGuiTableFlags_Sortable)。
    ImGuiTableColumnFlags_NoSortAscending = 1 << 9, // 禁用升序排序功能。
    ImGuiTableColumnFlags_NoSortDescending = 1 << 10, // 禁用降序排序功能。
    ImGuiTableColumnFlags_NoHeaderWidth = 1 << 11, // 禁用标题文本宽度对自动列宽的贡献。
    ImGuiTableColumnFlags_PreferSortAscending = 1 << 12, // 首次对该列排序时使初始排序方向为升序(默认)。
    ImGuiTableColumnFlags_PreferSortDescending = 1 << 13, // 首次对该列排序时,初始排序方向为降序。
    ImGuiTableColumnFlags_IndentEnable = 1 << 14, // 输入单元格时使用当前缩进值(默认为第 0 列)。
    ImGuiTableColumnFlags_IndentDisable = 1 << 15, // 输入单元格时忽略当前缩进值(列 > 0 的默认值)。 _within_ 单元格内的缩进变化仍将得到尊重。

    // 输出状态标志,通过 TableGetColumnFlags() 只读
    ImGuiTableColumnFlags_IsEnabled = 1 << 20, // 状态:已启用 == 未被用户/api 隐藏(在 _DefaultHide 和 _NoHide 中称为“隐藏”)标志。
    ImGuiTableColumnFlags_IsVisible = 1 << 21, // 状态:可见 == 已启用且未被滚动剪切。
    ImGuiTableColumnFlags_IsSorted = 1 << 22, // 状态:当前是排序规范的一部分
    ImGuiTableColumnFlags_IsHovered = 1 << 23, // 状态:被鼠标悬停
};

ImGuiTableRowFlags

1
2
3
4
5
6
// ImGui::TableNextRow() 的标志
enum ImGuiTableRowFlags_
{
     ImGuiTableRowFlags_None = 0,
     ImGuiTableRowFlags_Headers = 1 << 0 // 识别标题行(设置默认背景颜色 + 其内容的宽度占自动列宽不同)
};