From 002ba1a69fe28d3a40c8e4cde7a929b87391edb2 Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 12 Jan 2021 14:43:48 +0100 Subject: [PATCH] Tables: comments, tweak. CollapsingHeader: comments. (#3715) --- docs/CHANGELOG.txt | 2 +- imgui.h | 34 ++++++++++++++++------------------ imgui_tables.cpp | 22 ++++++++++++++++++---- imgui_widgets.cpp | 14 +++++++++----- 4 files changed, 44 insertions(+), 28 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index b67f3334..6b1616c3 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -74,7 +74,7 @@ Other Changes: TableGetColumnCount(), TableGetColumnName(), TableGetColumnFlags(). - Added 2 structures: ImGuiTableSortSpecs, ImGuiTableColumnSortSpecs. - Added 2 enums: ImGuiSortDirection, ImGuiTableBgTarget. - - Added 3 flags sets: ImGuiTableFlags (27 flags), ImGuiTableColumnFlags (24 flags), ImGuiTableRowFlags (1 flags). + - Added 3 flags sets: ImGuiTableFlags (27 flags), ImGuiTableColumnFlags (24 flags), ImGuiTableRowFlags (1 flag). - Added 5 colors: ImGuiCol_TableHeaderBg, ImGuiCol_TableBorderStrong, ImGuiCol_TableBorderLight, ImGuiCol_TableRowBg, ImGuiCol_TableRowBgAlt. - Added 1 style var: ImGuiStyleVar_CellPadding. - Tab Bar: Made it possible to append to an existing tab bar by calling BeginTabBar()/EndTabBar() again. diff --git a/imgui.h b/imgui.h index a94f58f2..7dfc9954 100644 --- a/imgui.h +++ b/imgui.h @@ -568,7 +568,7 @@ namespace ImGui IMGUI_API void TreePop(); // ~ Unindent()+PopId() IMGUI_API float GetTreeNodeToLabelSpacing(); // horizontal distance preceding label when using TreeNode*() or Bullet() == (g.FontSize + style.FramePadding.x*2) for a regular unframed TreeNode IMGUI_API bool CollapsingHeader(const char* label, ImGuiTreeNodeFlags flags = 0); // if returning 'true' the header is open. doesn't indent nor push on ID stack. user doesn't have to call TreePop(). - IMGUI_API bool CollapsingHeader(const char* label, bool* p_open, ImGuiTreeNodeFlags flags = 0); // when 'p_open' isn't NULL, display an additional small close button on upper right of the header + IMGUI_API bool CollapsingHeader(const char* label, bool* p_visible, ImGuiTreeNodeFlags flags = 0); // when 'p_visible != NULL': if '*p_visible==true' display an additional small close button on upper right of the header which will set the bool to false when clicked, if '*p_visible==false' don't display the header. IMGUI_API void SetNextItemOpen(bool is_open, ImGuiCond cond = 0); // set next TreeNode/CollapsingHeader open state. // Widgets: Selectables @@ -656,9 +656,10 @@ namespace ImGui IMGUI_API bool IsPopupOpen(const char* str_id, ImGuiPopupFlags flags = 0); // return true if the popup is open. // Tables - // [BETA API] API may evolve! + // [BETA API] API may evolve slightly! If you use this, please update to the next version when it comes out! // - Full-featured replacement for old Columns API. - // - See Demo->Tables for details. + // - See Demo->Tables for demo code. + // - See top of imgui_tables.cpp for general commentary. // - See ImGuiTableFlags_ and ImGuiTableColumnFlags_ enums for a description of available flags. // The typical call flow is: // - 1. Call BeginTable() @@ -671,25 +672,19 @@ namespace ImGui // you may prefer using TableNextColumn() instead of TableNextRow() + TableSetColumnIndex(). // TableNextColumn() will automatically wrap-around into the next row if needed. // - IMPORTANT: Comparatively to the old Columns() API, we need to call TableNextColumn() for the first column! - // - Both TableSetColumnIndex() and TableNextColumn() return true when the column is visible or performing - // width measurements. Otherwise, you may skip submitting the contents of a cell/column, BUT ONLY if you know - // it is not going to contribute to row height. - // In many situations, you may skip submitting contents for every columns but one (e.g. the first one). // - Summary of possible call flow: - // ---------------------------------------------------------------------------------------------------------- - // 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() automatically gets to next row! - // TableNextRow() -> Text("Hello 0") // Not OK! Missing TableSetColumnIndex() or TableNextColumn()! Text will not appear! - // ---------------------------------------------------------------------------------------------------------- + // -------------------------------------------------------------------------------------------------------- + // 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() automatically gets to next row! + // 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 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. IMGUI_API bool TableSetColumnIndex(int column_n); // append into the specified column. Return true when column is visible. - IMGUI_API int TableGetColumnIndex(); // return current column index. - IMGUI_API int TableGetRowIndex(); // return current row index. // Tables: Headers & Columns declaration // - Use TableSetupColumn() to specify label, resizing policy, default width/weight, id, various other flags etc. // Important: this will not display anything! The name passed to TableSetupColumn() is used by TableHeadersRow() and context-menus. @@ -708,10 +703,12 @@ namespace ImGui // Make sure to set 'SpecsDirty = false' after sorting, else you may wastefully sort your data every frame! // Lifetime: don't hold on this pointer over multiple frames or past any subsequent call to BeginTable(). IMGUI_API int TableGetColumnCount(); // return number of columns (value passed to BeginTable) + IMGUI_API int TableGetColumnIndex(); // return current column index. + IMGUI_API int TableGetRowIndex(); // return current row index. IMGUI_API const char* TableGetColumnName(int column_n = -1); // return "" if column didn't have a name declared by TableSetupColumn(). Pass -1 to use current column. - IMGUI_API ImGuiTableColumnFlags TableGetColumnFlags(int column_n = -1); // return column flags so you can query their Enabled/Visible/Sorted/Hovered status flags. + IMGUI_API ImGuiTableColumnFlags TableGetColumnFlags(int column_n = -1); // return column flags so you can query their Enabled/Visible/Sorted/Hovered status flags. Pass -1 to use current column. IMGUI_API ImGuiTableSortSpecs* TableGetSortSpecs(); // get latest sort specs for the table (NULL if not sorting). - IMGUI_API void TableSetBgColor(ImGuiTableBgTarget bg_target, ImU32 color, int column_n = -1); // change the color of a cell, row, or column. See ImGuiTableBgTarget_ flags for details. + IMGUI_API void TableSetBgColor(ImGuiTableBgTarget target, ImU32 color, int column_n = -1); // change the color of a cell, row, or column. See ImGuiTableBgTarget_ flags for details. // Legacy Columns API (2020: prefer using Tables!) // - You can also use SameLine(pos_x) to mimic simplified columns. @@ -1035,6 +1032,7 @@ enum ImGuiTabItemFlags_ }; // Flags for ImGui::BeginTable() +// [BETA API] API may evolve slightly! If you use this, please update to the next version when it comes out! // - Important! Sizing policies have complex and subtle side effects, more so than you would expect. // Read comments/demos carefully + experiment with live demos to get acquainted with them. // - The DEFAULT sizing policies are: @@ -1091,7 +1089,7 @@ enum ImGuiTableFlags_ // 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(). // Padding - ImGuiTableFlags_PadOuterX = 1 << 20, // Default if BordersOuterV is on. Enable outer-most 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). // Scrolling diff --git a/imgui_tables.cpp b/imgui_tables.cpp index 0b3c722b..119fa3e7 100644 --- a/imgui_tables.cpp +++ b/imgui_tables.cpp @@ -130,6 +130,16 @@ Index of this file: // - when using ImGuiTableFlags_SizingFixedSame with mixed columns, only the Fixed/Auto columns will match their widths to the maximum contents width. // - when using ImGuiTableFlags_SizingStretchSame with mixed columns, only the Stretch columns will match their weight/widths. //----------------------------------------------------------------------------- +// About using column width: +// If a column is manual resizable or has a width specified with TableSetupColumn(): +// - you may use GetContentRegionAvail().x to query the width available in a given column. +// - right-side alignment features such as SetNextItemWidth(-x) or PushItemWidth(-x) will rely on this width. +// If the column is not resizable and has no width specified with TableSetupColumn(): +// - its width will be automatic and be the set to the max of items submitted. +// - therefore you generally cannot have ALL items of the columns use e.g. SetNextItemWidth(-FLT_MIN). +// - but if the column has one or more item of known/fixed size, this will become the reference width used by SetNextItemWidth(-FLT_MIN). +//----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- // TABLES CLIPPING/CULLING @@ -143,6 +153,10 @@ Index of this file: // So, if you want to use the clipper, make sure to either enable _Resizable, either setup columns explicitly with _WidthFixed. //----------------------------------------------------------------------------- // About clipping/culling of Columns in Tables: +// - Both TableSetColumnIndex() and TableNextColumn() return true when the column is visible or performing +// width measurements. Otherwise, you may skip submitting the contents of a cell/column, BUT ONLY if you know +// it is not going to contribute to row height. +// In many situations, you may skip submitting contents for every columns but one (e.g. the first one). // - Case A: column is not hidden by user, and at least partially in sight (most common case). // - Case B: column is clipped / out of sight (because of scrolling or parent ClipRect): TableNextColumn() return false as a hint but we still allow layout output. // - Case C: column is hidden explicitly by the user (e.g. via the context menu, or _DefaultHide column flag, etc.). @@ -1455,17 +1469,17 @@ int ImGui::TableGetHoveredColumn() return (int)table->HoveredColumnBody; } -void ImGui::TableSetBgColor(ImGuiTableBgTarget bg_target, ImU32 color, int column_n) +void ImGui::TableSetBgColor(ImGuiTableBgTarget target, ImU32 color, int column_n) { ImGuiContext& g = *GImGui; ImGuiTable* table = g.CurrentTable; - IM_ASSERT(bg_target != ImGuiTableBgTarget_None); + IM_ASSERT(target != ImGuiTableBgTarget_None); if (color == IM_COL32_DISABLE) color = 0; // We cannot draw neither the cell or row background immediately as we don't know the row height at this point in time. - switch (bg_target) + switch (target) { case ImGuiTableBgTarget_CellBg: { @@ -1488,7 +1502,7 @@ void ImGui::TableSetBgColor(ImGuiTableBgTarget bg_target, ImU32 color, int colum if (table->RowPosY1 > table->InnerClipRect.Max.y) // Discard return; IM_ASSERT(column_n == -1); - int bg_idx = (bg_target == ImGuiTableBgTarget_RowBg1) ? 1 : 0; + int bg_idx = (target == ImGuiTableBgTarget_RowBg1) ? 1 : 0; table->RowBgColor[bg_idx] = color; break; } diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 1f71fa51..e365886b 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -5898,21 +5898,25 @@ bool ImGui::CollapsingHeader(const char* label, ImGuiTreeNodeFlags flags) return TreeNodeBehavior(window->GetID(label), flags | ImGuiTreeNodeFlags_CollapsingHeader, label); } -bool ImGui::CollapsingHeader(const char* label, bool* p_open, ImGuiTreeNodeFlags flags) +// p_visible == NULL : regular collapsing header +// p_visible != NULL && *p_visible == true : show a small close button on the corner of the header, clicking the button will set *p_visible = false +// p_visible != NULL && *p_visible == false : do not show the header at all +// Do not mistake this with the Open state of the header itself, which you can adjust with SetNextItemOpen() or ImGuiTreeNodeFlags_DefaultOpen. +bool ImGui::CollapsingHeader(const char* label, bool* p_visible, ImGuiTreeNodeFlags flags) { ImGuiWindow* window = GetCurrentWindow(); if (window->SkipItems) return false; - if (p_open && !*p_open) + if (p_visible && !*p_visible) return false; ImGuiID id = window->GetID(label); flags |= ImGuiTreeNodeFlags_CollapsingHeader; - if (p_open) + if (p_visible) flags |= ImGuiTreeNodeFlags_AllowItemOverlap | ImGuiTreeNodeFlags_ClipLabelForTrailingButton; bool is_open = TreeNodeBehavior(id, flags, label); - if (p_open != NULL) + if (p_visible != NULL) { // Create a small overlapping close button // FIXME: We can evolve this into user accessible helpers to add extra buttons on title bars, headers, etc. @@ -5924,7 +5928,7 @@ bool ImGui::CollapsingHeader(const char* label, bool* p_open, ImGuiTreeNodeFlags float button_y = window->DC.LastItemRect.Min.y; ImGuiID close_button_id = GetIDWithSeed("#CLOSE", NULL, id); if (CloseButton(close_button_id, ImVec2(button_x, button_y))) - *p_open = false; + *p_visible = false; last_item_backup.Restore(); }