Tables: more consistent use of CellPadding.x*2 and clip-rect on right-most side of non-bordered column + fix cellbg for standalone TableHeader call.

Using CellPadding.x on both sides when BorderV is off, generally most consistent and with default value (4,2) promotes at-glance visible spacing between non-bordered columns. Effectively double horizontal padding on non-bordered columns.
Made ClipRect.Max.x matches WorkMaxX which is where we'd like to go for windows themselves.
TableHeader() submit single cell bg color if not already submitted as a full header row.
Misc comments/docs updates.
This commit is contained in:
ocornut 2020-12-08 16:26:18 +01:00
parent 9874077fc0
commit 17536f9add
7 changed files with 25 additions and 35 deletions

View File

@ -214,8 +214,6 @@ Button("OK"); // Label = "OK", ID = hash of ("MyOtherWindow", "OK")
End(); End();
``` ```
We used "..." above to signify whatever was already pushed to the ID stack previously:
- If you have a same ID twice in the same location, you'll have a conflict: - If you have a same ID twice in the same location, you'll have a conflict:
```cpp ```cpp
Button("OK"); Button("OK");

View File

@ -132,7 +132,7 @@ Also see [Wiki](https://github.com/ocornut/imgui/wiki) for more links and ideas.
### Upcoming Changes ### Upcoming Changes
Some of the goals for 2020 are: Some of the goals for 2020 are:
- Work on new Tables API (to replace Columns). (see [#2957](https://github.com/ocornut/imgui/issues/2957), in public [tables](https://github.com/ocornut/imgui/tree/tables) branch looking for feedback) - Work on Tables (see [#2957](https://github.com/ocornut/imgui/issues/2957), now merged in master.
- Work on Docking (see [#2109](https://github.com/ocornut/imgui/issues/2109), in public [docking](https://github.com/ocornut/imgui/tree/docking) branch) - Work on Docking (see [#2109](https://github.com/ocornut/imgui/issues/2109), in public [docking](https://github.com/ocornut/imgui/tree/docking) branch)
- Work on Multi-Viewport / Multiple OS windows. (see [#1542](https://github.com/ocornut/imgui/issues/1542), in public [docking](https://github.com/ocornut/imgui/tree/docking) branch looking for feedback) - Work on Multi-Viewport / Multiple OS windows. (see [#1542](https://github.com/ocornut/imgui/issues/1542), in public [docking](https://github.com/ocornut/imgui/tree/docking) branch looking for feedback)
- Work on gamepad/keyboard controls. (see [#787](https://github.com/ocornut/imgui/issues/787)) - Work on gamepad/keyboard controls. (see [#787](https://github.com/ocornut/imgui/issues/787))

View File

@ -129,18 +129,6 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- group: IsHovered() after EndGroup() covers whole aabb rather than the intersection of individual items. Is that desirable? - group: IsHovered() after EndGroup() covers whole aabb rather than the intersection of individual items. Is that desirable?
- group: merge deactivation/activation within same group (fwd WasEdited flag). (#2550) - group: merge deactivation/activation within same group (fwd WasEdited flag). (#2550)
- columns: sizing policy (e.g. for each column: fixed size, %, fill, distribute default size among fills) (#513, #125)
- columns: add a conditional parameter to SetColumnOffset() (#513, #125)
- columns: headers. re-orderable. (#513, #125)
- columns: optional sorting modifiers (up/down), sort list so sorting can be done multi-criteria. notify user when sort order changed.
- columns: option to alternate background colors on odd/even scanlines.
- columns: allow columns to recurse.
- columns: allow a same columns set to be interrupted by e.g. CollapsingHeader and resume with columns in sync when moving them.
- columns: sizing is lossy when columns width is very small (default width may turn negative etc.)
- columns: separator function or parameter that works within the column (currently Separator() bypass all columns) (#125)
- columns: flag to add horizontal separator above/below)
- columns/layout: setup minimum line height (equivalent of automatically calling AlignFirstTextHeightToWidgets)
!- color: the color conversion helpers/types are a mess and needs sorting out. !- color: the color conversion helpers/types are a mess and needs sorting out.
- color: (api breaking) ImGui::ColorConvertXXX functions should be loose ImColorConvertXX to match imgui_internals.h - color: (api breaking) ImGui::ColorConvertXXX functions should be loose ImColorConvertXX to match imgui_internals.h

16
imgui.h
View File

@ -27,14 +27,12 @@ Index of this file:
// ImVector<> // ImVector<>
// ImGuiStyle // ImGuiStyle
// ImGuiIO // ImGuiIO
// Misc data structures (ImGuiInputTextCallbackData, ImGuiSizeCallbackData, ImGuiPayload) // Misc data structures (ImGuiInputTextCallbackData, ImGuiSizeCallbackData, ImGuiPayload, ImGuiTableSortSpecs, ImGuiTableColumnSortSpecs)
// Obsolete functions // Obsolete functions
// Helpers (ImGuiOnceUponAFrame, ImGuiTextFilter, ImGuiTextBuffer, ImGuiStorage, ImGuiListClipper, ImColor) // Helpers (ImGuiOnceUponAFrame, ImGuiTextFilter, ImGuiTextBuffer, ImGuiStorage, ImGuiListClipper, ImColor)
// Draw List API (ImDrawCallback, ImDrawCmd, ImDrawIdx, ImDrawVert, ImDrawChannel, ImDrawListSplitter, ImDrawListFlags, ImDrawList, ImDrawData) // Draw List API (ImDrawCallback, ImDrawCmd, ImDrawIdx, ImDrawVert, ImDrawChannel, ImDrawListSplitter, ImDrawListFlags, ImDrawList, ImDrawData)
// Font API (ImFontConfig, ImFontGlyph, ImFontGlyphRangesBuilder, ImFontAtlasFlags, ImFontAtlas, ImFont) // Font API (ImFontConfig, ImFontGlyph, ImFontGlyphRangesBuilder, ImFontAtlasFlags, ImFontAtlas, ImFont)
// FIXME-TABLE: Add ImGuiTableSortSpecs and ImGuiTableColumnSortSpecs in "Misc data structures" section above (we don't do it right now to facilitate merging various branches)
*/ */
#pragma once #pragma once
@ -64,6 +62,7 @@ Index of this file:
#define IMGUI_VERSION "1.80 WIP" #define IMGUI_VERSION "1.80 WIP"
#define IMGUI_VERSION_NUM 17906 #define IMGUI_VERSION_NUM 17906
#define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx)) #define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx))
#define IMGUI_HAS_TABLE
// Define attributes of all API symbols declarations (e.g. for DLL under Windows) // Define attributes of all API symbols declarations (e.g. for DLL under Windows)
// IMGUI_API is used for core imgui functions, IMGUI_IMPL_API is used for the default backends files (imgui_impl_xxx.h) // IMGUI_API is used for core imgui functions, IMGUI_IMPL_API is used for the default backends files (imgui_impl_xxx.h)
@ -680,7 +679,6 @@ namespace ImGui
// TableNextRow() -> Text("Hello 0") // Not OK! Missing TableSetColumnIndex() or TableNextColumn()! Text will not appear! // TableNextRow() -> Text("Hello 0") // Not OK! Missing TableSetColumnIndex() or TableNextColumn()! Text will not appear!
// ---------------------------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------------------------
// - 5. Call EndTable() // - 5. Call EndTable()
#define IMGUI_HAS_TABLE 1
IMGUI_API bool BeginTable(const char* str_id, int columns_count, ImGuiTableFlags flags = 0, const ImVec2& outer_size = ImVec2(0, 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, 0), float inner_width = 0.0f);
IMGUI_API void EndTable(); // only call EndTable() if BeginTable() returns true! 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 void TableNextRow(ImGuiTableRowFlags row_flags = 0, float min_row_height = 0.0f); // append into the first cell of a new row.
@ -1108,7 +1106,7 @@ enum ImGuiTableColumnFlags_
ImGuiTableColumnFlags_NoSort = 1 << 9, // Disable ability to sort on this field (even if ImGuiTableFlags_Sortable is set on the table). ImGuiTableColumnFlags_NoSort = 1 << 9, // Disable ability to sort on this field (even if ImGuiTableFlags_Sortable is set on the table).
ImGuiTableColumnFlags_NoSortAscending = 1 << 10, // Disable ability to sort in the ascending direction. ImGuiTableColumnFlags_NoSortAscending = 1 << 10, // Disable ability to sort in the ascending direction.
ImGuiTableColumnFlags_NoSortDescending = 1 << 11, // Disable ability to sort in the descending direction. ImGuiTableColumnFlags_NoSortDescending = 1 << 11, // Disable ability to sort in the descending direction.
ImGuiTableColumnFlags_NoHeaderWidth = 1 << 12, // Header width don't contribute to automatic column width. ImGuiTableColumnFlags_NoHeaderWidth = 1 << 12, // Disable header text width contribution to automatic column width.
ImGuiTableColumnFlags_PreferSortAscending = 1 << 13, // Make the initial sort direction Ascending when first sorting on this column (default). ImGuiTableColumnFlags_PreferSortAscending = 1 << 13, // Make the initial sort direction Ascending when first sorting on this column (default).
ImGuiTableColumnFlags_PreferSortDescending = 1 << 14, // Make the initial sort direction Descending when first sorting on this column. ImGuiTableColumnFlags_PreferSortDescending = 1 << 14, // Make the initial sort direction Descending when first sorting on this column.
ImGuiTableColumnFlags_IndentEnable = 1 << 15, // Use current Indent value when entering cell (default for column 0). ImGuiTableColumnFlags_IndentEnable = 1 << 15, // Use current Indent value when entering cell (default for column 0).
@ -1146,11 +1144,9 @@ enum ImGuiTableRowFlags_
enum ImGuiTableBgTarget_ enum ImGuiTableBgTarget_
{ {
ImGuiTableBgTarget_None = 0, ImGuiTableBgTarget_None = 0,
//ImGuiTableBgTarget_ColumnBg0 = 1, // FIXME-TABLE: Todo. Set column background color 0 (generally used for background ImGuiTableBgTarget_RowBg0 = 1, // Set row background color 0 (generally used for background, automatically set when ImGuiTableFlags_RowBg is used)
//ImGuiTableBgTarget_ColumnBg1 = 2, // FIXME-TABLE: Todo. Set column background color 1 (generally used for selection marking) ImGuiTableBgTarget_RowBg1 = 2, // Set row background color 1 (generally used for selection marking)
ImGuiTableBgTarget_RowBg0 = 3, // Set row background color 0 (generally used for background, automatically set when ImGuiTableFlags_RowBg is used) ImGuiTableBgTarget_CellBg = 3 // Set cell background color (top-most color)
ImGuiTableBgTarget_RowBg1 = 4, // Set row background color 1 (generally used for selection marking)
ImGuiTableBgTarget_CellBg = 5 // Set cell background color (top-most color)
}; };
// Flags for ImGui::IsWindowFocused() // Flags for ImGui::IsWindowFocused()

View File

@ -3590,7 +3590,7 @@ static void ShowDemoWindowTables()
// If there is not enough available width to fit all columns, they will however be resized down. // 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 // FIXME-TABLE: Providing a stretch-on-init would make sense especially for tables which don't have saved settings
HelpMarker( HelpMarker(
"Using _Resizable + _ColumnsWidthFixedX flags.\n" "Using _Resizable + _ColumnsWidthFixed flags.\n"
"Fixed-width columns generally makes more sense if you want to use horizontal scrolling.\n\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."); "Double-click a column border to auto-fit the column to its contents.");
static ImGuiTableFlags flags = ImGuiTableFlags_Resizable | ImGuiTableFlags_ColumnsWidthFixed | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV | ImGuiTableFlags_ContextMenuInBody; static ImGuiTableFlags flags = ImGuiTableFlags_Resizable | ImGuiTableFlags_ColumnsWidthFixed | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV | ImGuiTableFlags_ContextMenuInBody;
@ -3723,7 +3723,8 @@ static void ShowDemoWindowTables()
"e.g.:\n" "e.g.:\n"
"- BorderOuterV\n" "- BorderOuterV\n"
"- any form of row selection\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"); "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.");
PushStyleCompact(); PushStyleCompact();
ImGui::CheckboxFlags("ImGuiTableFlags_PadOuterX", &flags, ImGuiTableFlags_PadOuterX); ImGui::CheckboxFlags("ImGuiTableFlags_PadOuterX", &flags, ImGuiTableFlags_PadOuterX);
@ -4025,7 +4026,7 @@ static void ShowDemoWindowTables()
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."); 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 }; enum ContentsType { CT_ShortText, CT_LongText, CT_Button, CT_FillButton, CT_InputText };
static ImGuiTableFlags flags = ImGuiTableFlags_ScrollY | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_RowBg; static ImGuiTableFlags flags = ImGuiTableFlags_ScrollY | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_RowBg;
static int contents_type = CT_Button; static int contents_type = CT_LongText;
static int column_count = 3; static int column_count = 3;
PushStyleCompact(); PushStyleCompact();

View File

@ -1963,7 +1963,7 @@ struct ImGuiTableCellData
ImGuiTableColumnIdx Column; // Column number ImGuiTableColumnIdx Column; // Column number
}; };
// FIXME-TABLES: transient data could be stored in a per-stacked table structure: DrawSplitter, SortSpecs, incoming RowData // FIXME-TABLE: transient data could be stored in a per-stacked table structure: DrawSplitter, SortSpecs, incoming RowData
struct ImGuiTable struct ImGuiTable
{ {
ImGuiID ID; ImGuiID ID;

View File

@ -350,9 +350,8 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
const float inner_spacing_for_border = (flags & ImGuiTableFlags_BordersInnerV) ? TABLE_BORDER_SIZE : 0.0f; const float inner_spacing_for_border = (flags & ImGuiTableFlags_BordersInnerV) ? TABLE_BORDER_SIZE : 0.0f;
const float inner_spacing_explicit = (pad_inner_x && (flags & ImGuiTableFlags_BordersInnerV) == 0) ? g.Style.CellPadding.x : 0.0f; const float inner_spacing_explicit = (pad_inner_x && (flags & ImGuiTableFlags_BordersInnerV) == 0) ? g.Style.CellPadding.x : 0.0f;
const float inner_padding_explicit = (pad_inner_x && (flags & ImGuiTableFlags_BordersInnerV) != 0) ? g.Style.CellPadding.x : 0.0f; const float inner_padding_explicit = (pad_inner_x && (flags & ImGuiTableFlags_BordersInnerV) != 0) ? g.Style.CellPadding.x : 0.0f;
const float inner_spacing = inner_spacing_for_border + inner_spacing_explicit; table->CellSpacingX1 = inner_spacing_explicit + inner_spacing_for_border;
table->CellSpacingX1 = ImCeil(inner_spacing * 0.5f); table->CellSpacingX2 = inner_spacing_explicit;
table->CellSpacingX2 = inner_spacing - table->CellSpacingX1;
table->CellPaddingX = inner_padding_explicit; table->CellPaddingX = inner_padding_explicit;
table->CellPaddingY = g.Style.CellPadding.y; table->CellPaddingY = g.Style.CellPadding.y;
@ -463,7 +462,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
inner_window->SkipItems = true; inner_window->SkipItems = true;
// Clear names // Clear names
// FIXME-TABLES: probably could be done differently... // FIXME-TABLE: probably could be done differently...
if (table->ColumnsNames.Buf.Size > 0) if (table->ColumnsNames.Buf.Size > 0)
{ {
table->ColumnsNames.Buf.resize(0); table->ColumnsNames.Buf.resize(0);
@ -925,7 +924,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
// Lock all our positions // Lock all our positions
// - ClipRect.Min.x: Because merging draw commands doesn't compare min boundaries, we make ClipRect.Min.x match left bounds to be consistent regardless of merging. // - ClipRect.Min.x: Because merging draw commands doesn't compare min boundaries, we make ClipRect.Min.x match left bounds to be consistent regardless of merging.
// - ClipRect.Max.x: using WorkMaxX instead of MaxX (aka including padding) is detrimental to visibility in very-small column. // - ClipRect.Max.x: using WorkMaxX instead of MaxX (aka including padding) makes things more consistent when resizing down, tho slightly detrimental to visibility in very-small column.
// - FIXME-TABLE: We want equal width columns to have equal (ClipRect.Max.x - WorkMinX) width, which means ClipRect.max.x cannot stray off host_clip_rect.Max.x else right-most column may appear shorter. // - FIXME-TABLE: We want equal width columns to have equal (ClipRect.Max.x - WorkMinX) width, which means ClipRect.max.x cannot stray off host_clip_rect.Max.x else right-most column may appear shorter.
column->MinX = offset_x; column->MinX = offset_x;
column->MaxX = offset_x + column->WidthGiven + table->CellSpacingX1 + table->CellSpacingX2 + table->CellPaddingX * 2.0f; column->MaxX = offset_x + column->WidthGiven + table->CellSpacingX1 + table->CellSpacingX2 + table->CellPaddingX * 2.0f;
@ -934,7 +933,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
column->ItemWidth = ImFloor(column->WidthGiven * 0.65f); column->ItemWidth = ImFloor(column->WidthGiven * 0.65f);
column->ClipRect.Min.x = column->MinX; column->ClipRect.Min.x = column->MinX;
column->ClipRect.Min.y = work_rect.Min.y; column->ClipRect.Min.y = work_rect.Min.y;
column->ClipRect.Max.x = column->MaxX; // column->WorkMaxX; column->ClipRect.Max.x = column->WorkMaxX; //column->MaxX;
column->ClipRect.Max.y = FLT_MAX; column->ClipRect.Max.y = FLT_MAX;
column->ClipRect.ClipWithFull(host_clip_rect); column->ClipRect.ClipWithFull(host_clip_rect);
@ -2593,6 +2592,12 @@ void ImGui::TableHeader(const char* label)
TableSetBgColor(ImGuiTableBgTarget_CellBg, col, table->CurrentColumn); TableSetBgColor(ImGuiTableBgTarget_CellBg, col, table->CurrentColumn);
RenderNavHighlight(bb, id, ImGuiNavHighlightFlags_TypeThin | ImGuiNavHighlightFlags_NoRounding); RenderNavHighlight(bb, id, ImGuiNavHighlightFlags_TypeThin | ImGuiNavHighlightFlags_NoRounding);
} }
else
{
// Submit single cell bg color in the case we didn't submit a full header row
if ((table->RowFlags & ImGuiTableRowFlags_Headers) == 0)
TableSetBgColor(ImGuiTableBgTarget_CellBg, GetColorU32(ImGuiCol_TableHeaderBg), table->CurrentColumn);
}
if (held) if (held)
table->HeldHeaderColumn = (ImGuiTableColumnIdx)column_n; table->HeldHeaderColumn = (ImGuiTableColumnIdx)column_n;
window->DC.CursorPos.y -= g.Style.ItemSpacing.y * 0.5f; window->DC.CursorPos.y -= g.Style.ItemSpacing.y * 0.5f;
@ -3269,6 +3274,8 @@ void ImGui::DebugNodeTableSettings(ImGuiTableSettings*) {}
// [SECTION] Columns, BeginColumns, EndColumns, etc. // [SECTION] Columns, BeginColumns, EndColumns, etc.
// (This is a legacy API, prefer using BeginTable/EndTable!) // (This is a legacy API, prefer using BeginTable/EndTable!)
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
// FIXME: sizing is lossy when columns width is very small (default width may turn negative etc.)
//-------------------------------------------------------------------------
// - SetWindowClipRectBeforeSetChannel() [Internal] // - SetWindowClipRectBeforeSetChannel() [Internal]
// - GetColumnIndex() // - GetColumnIndex()
// - GetColumnsCount() // - GetColumnsCount()