mirror of
https://github.com/Drezil/imgui.git
synced 2024-11-15 01:17:00 +00:00
Tables: distinguishing per-column IsVisible from IsRequestOutput which is returned to user. Clarified clipping rules/requirements. Comments.
This commit is contained in:
parent
f70bf69e3b
commit
984c4cb5f8
8
imgui.h
8
imgui.h
@ -669,7 +669,7 @@ namespace ImGui
|
|||||||
// TableNextColumn() will automatically wrap-around into the next row if needed.
|
// 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!
|
// - IMPORTANT: Comparatively to the old Columns() API, we need to call TableNextColumn() for the first column!
|
||||||
// - Both TableSetColumnIndex() and TableNextColumn() return false when the column is not visible, so you can
|
// - Both TableSetColumnIndex() and TableNextColumn() return false when the column is not visible, so you can
|
||||||
// skip submitting the contents of a cell BUT ONLY if you know the contents is not going to alter row height.
|
// skip submitting the contents of a cell 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).
|
// In many situations, you may skip submitting contents for every columns but one (e.g. the first one).
|
||||||
// - Summary of possible call flow:
|
// - Summary of possible call flow:
|
||||||
// ----------------------------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------------------------
|
||||||
@ -1055,7 +1055,7 @@ enum ImGuiTableFlags_
|
|||||||
ImGuiTableFlags_None = 0,
|
ImGuiTableFlags_None = 0,
|
||||||
ImGuiTableFlags_Resizable = 1 << 0, // Allow resizing columns.
|
ImGuiTableFlags_Resizable = 1 << 0, // Allow resizing columns.
|
||||||
ImGuiTableFlags_Reorderable = 1 << 1, // Allow reordering columns in header row (need calling TableSetupColumn() + TableHeadersRow() to display headers)
|
ImGuiTableFlags_Reorderable = 1 << 1, // Allow reordering columns in header row (need calling TableSetupColumn() + TableHeadersRow() to display headers)
|
||||||
ImGuiTableFlags_Hideable = 1 << 2, // Allow hiding columns in context menu.
|
ImGuiTableFlags_Hideable = 1 << 2, // Allow hiding/disabling columns in context menu.
|
||||||
ImGuiTableFlags_Sortable = 1 << 3, // Allow sorting on one column (sort_specs_count will always be == 1). Call TableGetSortSpecs() to obtain sort specs.
|
ImGuiTableFlags_Sortable = 1 << 3, // Allow sorting on one column (sort_specs_count will always be == 1). Call TableGetSortSpecs() to obtain sort specs.
|
||||||
ImGuiTableFlags_MultiSortable = 1 << 4, // Allow sorting on multiple columns by holding Shift (sort_specs_count may be > 1). Call TableGetSortSpecs() to obtain sort specs.
|
ImGuiTableFlags_MultiSortable = 1 << 4, // Allow sorting on multiple columns by holding Shift (sort_specs_count may be > 1). Call TableGetSortSpecs() to obtain sort specs.
|
||||||
ImGuiTableFlags_NoSavedSettings = 1 << 5, // Disable persisting columns order, width and sort settings in the .ini file.
|
ImGuiTableFlags_NoSavedSettings = 1 << 5, // Disable persisting columns order, width and sort settings in the .ini file.
|
||||||
@ -1095,14 +1095,14 @@ enum ImGuiTableFlags_
|
|||||||
enum ImGuiTableColumnFlags_
|
enum ImGuiTableColumnFlags_
|
||||||
{
|
{
|
||||||
ImGuiTableColumnFlags_None = 0,
|
ImGuiTableColumnFlags_None = 0,
|
||||||
ImGuiTableColumnFlags_DefaultHide = 1 << 0, // Default as a hidden column.
|
ImGuiTableColumnFlags_DefaultHide = 1 << 0, // Default as a hidden/disabled column.
|
||||||
ImGuiTableColumnFlags_DefaultSort = 1 << 1, // Default as a sorting column.
|
ImGuiTableColumnFlags_DefaultSort = 1 << 1, // Default as a sorting column.
|
||||||
ImGuiTableColumnFlags_WidthStretch = 1 << 2, // Column will stretch. Preferable with horizontal scrolling disabled (default if table sizing policy is _ColumnsWidthStretch).
|
ImGuiTableColumnFlags_WidthStretch = 1 << 2, // Column will stretch. Preferable with horizontal scrolling disabled (default if table sizing policy is _ColumnsWidthStretch).
|
||||||
ImGuiTableColumnFlags_WidthFixed = 1 << 3, // Column will not stretch. Preferable with horizontal scrolling enabled (default if table sizing policy is _ColumnsWidthFixed and table is resizable).
|
ImGuiTableColumnFlags_WidthFixed = 1 << 3, // Column will not stretch. Preferable with horizontal scrolling enabled (default if table sizing policy is _ColumnsWidthFixed and table is resizable).
|
||||||
ImGuiTableColumnFlags_WidthAutoResize = 1 << 4, // Column will not stretch and keep resizing based on submitted contents (default if table sizing policy is _ColumnsWidthFixed and table is not resizable).
|
ImGuiTableColumnFlags_WidthAutoResize = 1 << 4, // Column will not stretch and keep resizing based on submitted contents (default if table sizing policy is _ColumnsWidthFixed and table is not resizable).
|
||||||
ImGuiTableColumnFlags_NoResize = 1 << 5, // Disable manual resizing.
|
ImGuiTableColumnFlags_NoResize = 1 << 5, // Disable manual resizing.
|
||||||
ImGuiTableColumnFlags_NoReorder = 1 << 6, // Disable manual reordering this column, this will also prevent other columns from crossing over this column.
|
ImGuiTableColumnFlags_NoReorder = 1 << 6, // Disable manual reordering this column, this will also prevent other columns from crossing over this column.
|
||||||
ImGuiTableColumnFlags_NoHide = 1 << 7, // Disable ability to hide this column.
|
ImGuiTableColumnFlags_NoHide = 1 << 7, // Disable ability to hide/disable this column.
|
||||||
ImGuiTableColumnFlags_NoClip = 1 << 8, // Disable clipping for this column (all NoClip columns will render in a same draw command).
|
ImGuiTableColumnFlags_NoClip = 1 << 8, // Disable clipping for this column (all NoClip columns will render in a same draw command).
|
||||||
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.
|
||||||
|
@ -3518,9 +3518,7 @@ static void ShowDemoWindowTables()
|
|||||||
ImGui::TableNextRow();
|
ImGui::TableNextRow();
|
||||||
for (int column = 0; column < 3; column++)
|
for (int column = 0; column < 3; column++)
|
||||||
{
|
{
|
||||||
if (!ImGui::TableSetColumnIndex(column))
|
ImGui::TableSetColumnIndex(column);
|
||||||
continue;
|
|
||||||
|
|
||||||
char buf[32];
|
char buf[32];
|
||||||
sprintf(buf, "Hello %d,%d", column, row);
|
sprintf(buf, "Hello %d,%d", column, row);
|
||||||
if (contents_type == CT_Text)
|
if (contents_type == CT_Text)
|
||||||
@ -3861,20 +3859,22 @@ static void ShowDemoWindowTables()
|
|||||||
{
|
{
|
||||||
ImGui::TableSetupScrollFreeze(freeze_cols, freeze_rows);
|
ImGui::TableSetupScrollFreeze(freeze_cols, freeze_rows);
|
||||||
ImGui::TableSetupColumn("Line #", ImGuiTableColumnFlags_NoHide); // Make the first column not hideable to match our use of TableSetupScrollFreeze()
|
ImGui::TableSetupColumn("Line #", ImGuiTableColumnFlags_NoHide); // Make the first column not hideable to match our use of TableSetupScrollFreeze()
|
||||||
ImGui::TableSetupColumn("One", ImGuiTableColumnFlags_None);
|
ImGui::TableSetupColumn("One");
|
||||||
ImGui::TableSetupColumn("Two", ImGuiTableColumnFlags_None);
|
ImGui::TableSetupColumn("Two");
|
||||||
ImGui::TableSetupColumn("Three", ImGuiTableColumnFlags_None);
|
ImGui::TableSetupColumn("Three");
|
||||||
ImGui::TableSetupColumn("Four", ImGuiTableColumnFlags_None);
|
ImGui::TableSetupColumn("Four");
|
||||||
ImGui::TableSetupColumn("Five", ImGuiTableColumnFlags_None);
|
ImGui::TableSetupColumn("Five");
|
||||||
ImGui::TableSetupColumn("Six", ImGuiTableColumnFlags_None);
|
ImGui::TableSetupColumn("Six");
|
||||||
ImGui::TableHeadersRow();
|
ImGui::TableHeadersRow();
|
||||||
for (int row = 0; row < 20; row++)
|
for (int row = 0; row < 20; row++)
|
||||||
{
|
{
|
||||||
ImGui::TableNextRow();
|
ImGui::TableNextRow();
|
||||||
for (int column = 0; column < 7; column++)
|
for (int column = 0; column < 7; column++)
|
||||||
{
|
{
|
||||||
// Both TableNextColumn() and TableSetColumnIndex() return false when a column is not visible, which can be used for clipping.
|
// Both TableNextColumn() and TableSetColumnIndex() return false when a column is not visible.
|
||||||
if (!ImGui::TableSetColumnIndex(column))
|
// Because here we know that A) all our columns are contributing the same to row height and B) column 0 is always visible,
|
||||||
|
// we only always submit this one column.
|
||||||
|
if (!ImGui::TableSetColumnIndex(column) && column > 0)
|
||||||
continue;
|
continue;
|
||||||
if (column == 0)
|
if (column == 0)
|
||||||
ImGui::Text("Line %d", row);
|
ImGui::Text("Line %d", row);
|
||||||
@ -4809,8 +4809,8 @@ static void ShowDemoWindowTables()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::TableNextColumn();
|
if (ImGui::TableNextColumn())
|
||||||
ImGui::TextUnformatted(item->Name);
|
ImGui::TextUnformatted(item->Name);
|
||||||
|
|
||||||
// Here we demonstrate marking our data set as needing to be sorted again if we modified a quantity,
|
// Here we demonstrate marking our data set as needing to be sorted again if we modified a quantity,
|
||||||
// and we are currently sorting on the column showing the Quantity.
|
// and we are currently sorting on the column showing the Quantity.
|
||||||
@ -4825,8 +4825,8 @@ static void ShowDemoWindowTables()
|
|||||||
if (sorts_specs_using_quantity && ImGui::IsItemDeactivated()) { items_need_sort = true; }
|
if (sorts_specs_using_quantity && ImGui::IsItemDeactivated()) { items_need_sort = true; }
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui::TableNextColumn();
|
if (ImGui::TableNextColumn())
|
||||||
ImGui::Text("%d", item->Quantity);
|
ImGui::Text("%d", item->Quantity);
|
||||||
|
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
if (show_wrapped_text)
|
if (show_wrapped_text)
|
||||||
@ -4834,8 +4834,8 @@ static void ShowDemoWindowTables()
|
|||||||
else
|
else
|
||||||
ImGui::Text("Lorem ipsum dolor sit amet");
|
ImGui::Text("Lorem ipsum dolor sit amet");
|
||||||
|
|
||||||
ImGui::TableNextColumn();
|
if (ImGui::TableNextColumn())
|
||||||
ImGui::Text("1234");
|
ImGui::Text("1234");
|
||||||
|
|
||||||
ImGui::PopID();
|
ImGui::PopID();
|
||||||
}
|
}
|
||||||
|
@ -1932,7 +1932,9 @@ struct ImGuiTableColumn
|
|||||||
ImGuiTableDrawChannelIdx DrawChannelUnfrozen;
|
ImGuiTableDrawChannelIdx DrawChannelUnfrozen;
|
||||||
bool IsEnabled; // Is the column not marked Hidden by the user? (even if off view, e.g. clipped by scrolling).
|
bool IsEnabled; // Is the column not marked Hidden by the user? (even if off view, e.g. clipped by scrolling).
|
||||||
bool IsEnabledNextFrame;
|
bool IsEnabledNextFrame;
|
||||||
bool IsClipped; // Is not actually in view (e.g. not overlapping the host window clipping rectangle).
|
bool IsVisibleX; // Is actually in view (e.g. overlapping the host window clipping rectangle, not scrolled).
|
||||||
|
bool IsVisibleY;
|
||||||
|
bool IsRequestOutput; // Return value for TableSetColumnIndex() / TableNextColumn(): whether we request user to output contents or not.
|
||||||
bool IsSkipItems; // Do we want item submissions to this column to be completely ignored (no layout will happen).
|
bool IsSkipItems; // Do we want item submissions to this column to be completely ignored (no layout will happen).
|
||||||
ImS8 NavLayerCurrent; // ImGuiNavLayer in 1 byte
|
ImS8 NavLayerCurrent; // ImGuiNavLayer in 1 byte
|
||||||
ImS8 SortDirection; // ImGuiSortDirection_Ascending or ImGuiSortDirection_Descending
|
ImS8 SortDirection; // ImGuiSortDirection_Ascending or ImGuiSortDirection_Descending
|
||||||
@ -1971,8 +1973,9 @@ struct ImGuiTable
|
|||||||
ImSpan<ImGuiTableColumnIdx> DisplayOrderToIndex; // Point within RawData[]. Store display order of columns (when not reordered, the values are 0...Count-1)
|
ImSpan<ImGuiTableColumnIdx> DisplayOrderToIndex; // Point within RawData[]. Store display order of columns (when not reordered, the values are 0...Count-1)
|
||||||
ImSpan<ImGuiTableCellData> RowCellData; // Point within RawData[]. Store cells background requests for current row.
|
ImSpan<ImGuiTableCellData> RowCellData; // Point within RawData[]. Store cells background requests for current row.
|
||||||
ImU64 EnabledMaskByDisplayOrder; // Column DisplayOrder -> IsEnabled map
|
ImU64 EnabledMaskByDisplayOrder; // Column DisplayOrder -> IsEnabled map
|
||||||
ImU64 EnabledUnclippedMaskByIndex;// Enabled and not Clipped, aka "actually visible" "not hidden by some scrolling"
|
|
||||||
ImU64 EnabledMaskByIndex; // Column Index -> IsEnabled map (== not hidden by user/api) in a format adequate for iterating column without touching cold data
|
ImU64 EnabledMaskByIndex; // Column Index -> IsEnabled map (== not hidden by user/api) in a format adequate for iterating column without touching cold data
|
||||||
|
ImU64 VisibleMaskByIndex; // Column Index -> IsVisibleX|IsVisibleY map (== not hidden by user/api && not hidden by scrolling/cliprect)
|
||||||
|
ImU64 RequestOutputMaskByIndex; // Column Index -> IsVisible || AutoFit (== expect user to submit items)
|
||||||
ImGuiTableFlags SettingsLoadedFlags; // Which data were loaded from the .ini file (e.g. when order is not altered we won't save order)
|
ImGuiTableFlags SettingsLoadedFlags; // Which data were loaded from the .ini file (e.g. when order is not altered we won't save order)
|
||||||
int SettingsOffset; // Offset in g.SettingsTables
|
int SettingsOffset; // Offset in g.SettingsTables
|
||||||
int LastFrameActive;
|
int LastFrameActive;
|
||||||
@ -2280,7 +2283,7 @@ namespace ImGui
|
|||||||
// Tables: Candidates for public api
|
// Tables: Candidates for public api
|
||||||
IMGUI_API void TableOpenContextMenu(int column_n = -1);
|
IMGUI_API void TableOpenContextMenu(int column_n = -1);
|
||||||
IMGUI_API void TableSetColumnWidth(int column_n, float width);
|
IMGUI_API void TableSetColumnWidth(int column_n, float width);
|
||||||
IMGUI_API bool TableGetColumnIsEnabled(int column_n = -1); // Return false when column is disabled (hidden) by user (e.g. via context menu, or _DefaultHide flag)
|
IMGUI_API bool TableGetColumnIsEnabled(int column_n = -1); // Return false when column is disabled (hidden by user/api, e.g. via context menu, or _DefaultHide flag)
|
||||||
IMGUI_API void TableSetColumnIsEnabled(int column_n, bool enabled);
|
IMGUI_API void TableSetColumnIsEnabled(int column_n, bool enabled);
|
||||||
IMGUI_API void TableSetColumnSortDirection(int column_n, ImGuiSortDirection sort_direction, bool append_to_sort_specs);
|
IMGUI_API void TableSetColumnSortDirection(int column_n, ImGuiSortDirection sort_direction, bool append_to_sort_specs);
|
||||||
IMGUI_API float TableGetHeaderRowHeight();
|
IMGUI_API float TableGetHeaderRowHeight();
|
||||||
|
139
imgui_tables.cpp
139
imgui_tables.cpp
@ -50,6 +50,63 @@ Index of this file:
|
|||||||
// | EndChild() - (if ScrollX/ScrollY is set)
|
// | EndChild() - (if ScrollX/ScrollY is set)
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// TABLE SIZING
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// (Read carefully because this is subtle but it does make sense!)
|
||||||
|
// About 'outer_size', its meaning needs to differ slightly depending of if we are using ScrollX/ScrollY flags:
|
||||||
|
// X:
|
||||||
|
// - outer_size.x < 0.0f -> right align from window/work-rect maximum x edge.
|
||||||
|
// - outer_size.x = 0.0f -> auto enlarge, use all available space.
|
||||||
|
// - outer_size.x > 0.0f -> fixed width
|
||||||
|
// Y with ScrollX/ScrollY: using a child window for scrolling:
|
||||||
|
// - outer_size.y < 0.0f -> bottom align
|
||||||
|
// - 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 -> fixed child height. recommended when using Scrolling on any axis.
|
||||||
|
// Y without scrolling, we output table directly in parent window:
|
||||||
|
// - outer_size.y < 0.0f -> bottom align (will auto extend, unless NoHostExtendV is set)
|
||||||
|
// - outer_size.y = 0.0f -> zero minimum height (will auto extend, unless NoHostExtendV is set)
|
||||||
|
// - outer_size.y > 0.0f -> minimum height (will auto extend, unless NoHostExtendV is set)
|
||||||
|
// About 'inner_width':
|
||||||
|
// With ScrollX:
|
||||||
|
// - inner_width < 0.0f -> *illegal* fit in known width (right align from outer_size.x) <-- weird
|
||||||
|
// - inner_width = 0.0f -> fit in outer_width: Fixed size columns will take space they need (if avail, otherwise shrink down), Stretch columns becomes Fixed columns.
|
||||||
|
// - inner_width > 0.0f -> override scrolling width, generally to be larger than outer_size.x. Fixed column take space they need (if avail, otherwise shrink down), Stretch columns share remaining space!
|
||||||
|
// Without ScrollX:
|
||||||
|
// - inner_width -> *ignored*
|
||||||
|
// Details:
|
||||||
|
// - If you want to use Stretch columns with ScrollX, you generally need to specify 'inner_width' otherwise the concept
|
||||||
|
// of "available space" doesn't make sense.
|
||||||
|
// - Even if not really useful, we allow 'inner_width < outer_size.x' for consistency and to facilitate understanding
|
||||||
|
// of what the value does.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// TABLES CULLING
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// About clipping/culling of Rows in Tables:
|
||||||
|
// - For large numbers of rows, it is recommended you use ImGuiListClipper to only submit visible rows.
|
||||||
|
// ImGuiListClipper is reliant on the fact that rows are of equal height.
|
||||||
|
// See 'Demo->Tables->Vertical Scrolling' or 'Demo->Tables->Advanced' for a demo of using the clipper.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// About clipping/culling of Columns in Tables:
|
||||||
|
// - 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.).
|
||||||
|
//
|
||||||
|
// [A] [B] [C]
|
||||||
|
// TableNextColumn(): true false false -> [userland] when TableNextColumn() / TableSetColumnIndex() return false, user can skip submitting items but only if the column doesn't contribute to row height.
|
||||||
|
// SkipItems: false false true -> [internal] when SkipItems is true, most widgets will early out if submitted, resulting is no layout output.
|
||||||
|
// ClipRect: normal zero-width zero-width -> [internal] when ClipRect is zero, ItemAdd() will return false and most widgets will early out mid-way.
|
||||||
|
// ImDrawList output: normal dummy dummy -> [internal] when using the dummy channel, ImDrawList submissions (if any) will be wasted (because cliprect is zero-width anyway).
|
||||||
|
//
|
||||||
|
// - We need distinguish those cases because non-hidden columns that are clipped outside of scrolling bounds should still contribute their height to the row.
|
||||||
|
// However, in the majority of cases, the contribution to row height is the same for all columns, or the tallest cells are known by the programmer.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// About clipping/culling of whole Tables:
|
||||||
|
// - Scrolling tables with a known outer size can be clipped earlier as BeginTable() will return false.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
|
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
|
||||||
#define _CRT_SECURE_NO_WARNINGS
|
#define _CRT_SECURE_NO_WARNINGS
|
||||||
#endif
|
#endif
|
||||||
@ -183,32 +240,6 @@ ImGuiTable* ImGui::TableFindByID(ImGuiID id)
|
|||||||
return g.Tables.GetByKey(id);
|
return g.Tables.GetByKey(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
// (Read carefully because this is subtle but it does make sense!)
|
|
||||||
// About 'outer_size', its meaning needs to differ slightly depending of if we are using ScrollX/ScrollY flags:
|
|
||||||
// X:
|
|
||||||
// - outer_size.x < 0.0f -> right align from window/work-rect maximum x edge.
|
|
||||||
// - outer_size.x = 0.0f -> auto enlarge, use all available space.
|
|
||||||
// - outer_size.x > 0.0f -> fixed width
|
|
||||||
// Y with ScrollX/ScrollY: using a child window for scrolling:
|
|
||||||
// - outer_size.y < 0.0f -> bottom align
|
|
||||||
// - 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 -> fixed child height. recommended when using Scrolling on any axis.
|
|
||||||
// Y without scrolling, we output table directly in parent window:
|
|
||||||
// - outer_size.y < 0.0f -> bottom align (will auto extend, unless NoHostExtendV is set)
|
|
||||||
// - outer_size.y = 0.0f -> zero minimum height (will auto extend, unless NoHostExtendV is set)
|
|
||||||
// - outer_size.y > 0.0f -> minimum height (will auto extend, unless NoHostExtendV is set)
|
|
||||||
// About 'inner_width':
|
|
||||||
// With ScrollX:
|
|
||||||
// - inner_width < 0.0f -> *illegal* fit in known width (right align from outer_size.x) <-- weird
|
|
||||||
// - inner_width = 0.0f -> fit in outer_width: Fixed size columns will take space they need (if avail, otherwise shrink down), Stretch columns becomes Fixed columns.
|
|
||||||
// - inner_width > 0.0f -> override scrolling width, generally to be larger than outer_size.x. Fixed column take space they need (if avail, otherwise shrink down), Stretch columns share remaining space!
|
|
||||||
// Without ScrollX:
|
|
||||||
// - inner_width -> *ignored*
|
|
||||||
// Details:
|
|
||||||
// - If you want to use Stretch columns with ScrollX, you generally need to specify 'inner_width' otherwise the concept
|
|
||||||
// of "available space" doesn't make sense.
|
|
||||||
// - Even if not really useful, we allow 'inner_width < outer_size.x' for consistency and to facilitate understanding
|
|
||||||
// of what the value does.
|
|
||||||
bool ImGui::BeginTable(const char* str_id, int columns_count, ImGuiTableFlags flags, const ImVec2& outer_size, float inner_width)
|
bool ImGui::BeginTable(const char* str_id, int columns_count, ImGuiTableFlags flags, const ImVec2& outer_size, float inner_width)
|
||||||
{
|
{
|
||||||
ImGuiID id = GetID(str_id);
|
ImGuiID id = GetID(str_id);
|
||||||
@ -627,7 +658,6 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
|||||||
}
|
}
|
||||||
IM_ASSERT(column->IndexWithinEnabledSet <= column->DisplayOrder);
|
IM_ASSERT(column->IndexWithinEnabledSet <= column->DisplayOrder);
|
||||||
}
|
}
|
||||||
table->EnabledUnclippedMaskByIndex = table->EnabledMaskByIndex; // Columns will be masked out below when Clipped
|
|
||||||
table->RightMostEnabledColumn = (ImGuiTableColumnIdx)last_visible_column_idx;
|
table->RightMostEnabledColumn = (ImGuiTableColumnIdx)last_visible_column_idx;
|
||||||
|
|
||||||
// [Part 2] Disable child window clipping while fitting columns. This is not strictly necessary but makes it possible
|
// [Part 2] Disable child window clipping while fitting columns. This is not strictly necessary but makes it possible
|
||||||
@ -685,7 +715,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
|||||||
{
|
{
|
||||||
// Process auto-fit for non-stretched columns
|
// Process auto-fit for non-stretched columns
|
||||||
// Latch initial size for fixed columns and update it constantly for auto-resizing column (unless clipped!)
|
// Latch initial size for fixed columns and update it constantly for auto-resizing column (unless clipped!)
|
||||||
if ((column->AutoFitQueue != 0x00) || ((column->Flags & ImGuiTableColumnFlags_WidthAutoResize) && !column->IsClipped))
|
if ((column->AutoFitQueue != 0x00) || ((column->Flags & ImGuiTableColumnFlags_WidthAutoResize) && column->IsVisibleX))
|
||||||
column->WidthRequest = width_auto;
|
column->WidthRequest = width_auto;
|
||||||
|
|
||||||
// FIXME-TABLE: Increase minimum size during init frame to avoid biasing auto-fitting widgets
|
// FIXME-TABLE: Increase minimum size during init frame to avoid biasing auto-fitting widgets
|
||||||
@ -809,6 +839,8 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
|||||||
float offset_x = ((table->FreezeColumnsCount > 0) ? table->OuterRect.Min.x : work_rect.Min.x) + table->OuterPaddingX - table->CellSpacingX1;
|
float offset_x = ((table->FreezeColumnsCount > 0) ? table->OuterRect.Min.x : work_rect.Min.x) + table->OuterPaddingX - table->CellSpacingX1;
|
||||||
ImRect host_clip_rect = table->InnerClipRect;
|
ImRect host_clip_rect = table->InnerClipRect;
|
||||||
//host_clip_rect.Max.x += table->CellPaddingX + table->CellSpacingX2;
|
//host_clip_rect.Max.x += table->CellPaddingX + table->CellSpacingX2;
|
||||||
|
table->VisibleMaskByIndex = 0x00;
|
||||||
|
table->RequestOutputMaskByIndex = 0x00;
|
||||||
for (int order_n = 0; order_n < table->ColumnsCount; order_n++)
|
for (int order_n = 0; order_n < table->ColumnsCount; order_n++)
|
||||||
{
|
{
|
||||||
const int column_n = table->DisplayOrderToIndex[order_n];
|
const int column_n = table->DisplayOrderToIndex[order_n];
|
||||||
@ -828,7 +860,8 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
|||||||
column->ClipRect.Min.y = work_rect.Min.y;
|
column->ClipRect.Min.y = work_rect.Min.y;
|
||||||
column->ClipRect.Max.y = FLT_MAX;
|
column->ClipRect.Max.y = FLT_MAX;
|
||||||
column->ClipRect.ClipWithFull(host_clip_rect);
|
column->ClipRect.ClipWithFull(host_clip_rect);
|
||||||
column->IsClipped = column->IsSkipItems = true;
|
column->IsVisibleX = column->IsVisibleY = column->IsRequestOutput = false;
|
||||||
|
column->IsSkipItems = true;
|
||||||
column->ItemWidth = 1.0f;
|
column->ItemWidth = 1.0f;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -877,11 +910,31 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
|||||||
column->ClipRect.Max.y = FLT_MAX;
|
column->ClipRect.Max.y = FLT_MAX;
|
||||||
column->ClipRect.ClipWithFull(host_clip_rect);
|
column->ClipRect.ClipWithFull(host_clip_rect);
|
||||||
|
|
||||||
column->IsClipped = (column->ClipRect.Max.x <= column->ClipRect.Min.x) && (column->AutoFitQueue & 1) == 0 && (column->CannotSkipItemsQueue & 1) == 0;
|
// Mark column as Clipped (not in sight)
|
||||||
if (column->IsClipped)
|
// Note that scrolling tables (where inner_window != outer_window) handle Y clipped earlier in BeginTable() so IsVisibleY really only applies to non-scrolling tables.
|
||||||
table->EnabledUnclippedMaskByIndex &= ~((ImU64)1 << column_n); // Columns with the _WidthAutoResize sizing policy will never be updated then.
|
// FIXME-TABLE: Because InnerClipRect.Max.y is conservatively ==outer_window->ClipRect.Max.y, we never can mark columns _Above_ the scroll line as not IsVisibleY.
|
||||||
|
// Taking advantage of LastOuterHeight would yield good results there...
|
||||||
|
// FIXME-TABLE: IsVisible == false is disabled because it effectively means not submitting will reduces contents width which is fed to outer_window->DC.CursorMaxPos.x,
|
||||||
|
// and this may be used (e.g. typically by outer_window using AlwaysAutoResize or outer_window's horizontal scrollbar, but could be something else).
|
||||||
|
// Possible solution to preserve last known content width for clipped column. Test 'table_reported_size' fails when enabling Y clipping and window is resized small.
|
||||||
|
column->IsVisibleX = (column->ClipRect.Max.x > column->ClipRect.Min.x);
|
||||||
|
column->IsVisibleY = true; // (column->ClipRect.Max.y > column->ClipRect.Min.y);
|
||||||
|
const bool is_visible = column->IsVisibleX; //&& column->IsVisibleY;
|
||||||
|
if (is_visible)
|
||||||
|
table->VisibleMaskByIndex |= ((ImU64)1 << column_n);
|
||||||
|
|
||||||
|
// Mark column as requesting output from user. Note that fixed + non-resizable sets are auto-fitting at all times and therefore always request output.
|
||||||
|
column->IsRequestOutput = is_visible || column->AutoFitQueue != 0 || column->CannotSkipItemsQueue != 0;
|
||||||
|
if (column->IsRequestOutput)
|
||||||
|
table->RequestOutputMaskByIndex |= ((ImU64)1 << column_n);
|
||||||
|
|
||||||
|
// Mark column as SkipItems (ignoring all items/layout)
|
||||||
column->IsSkipItems = !column->IsEnabled || table->HostSkipItems;
|
column->IsSkipItems = !column->IsEnabled || table->HostSkipItems;
|
||||||
|
//if (!is_visible && (column->Flags & ImGuiTableColumnFlags_AutoCull))
|
||||||
|
// if ((column->AutoFitQueue & 1) == 0 && (column->CannotSkipItemsQueue & 1) == 0)
|
||||||
|
// column->IsSkipItems = true;
|
||||||
|
if (column->IsSkipItems)
|
||||||
|
IM_ASSERT(!is_visible);
|
||||||
|
|
||||||
// Detect hovered column
|
// Detect hovered column
|
||||||
if (is_hovering_table && g.IO.MousePos.x >= column->ClipRect.Min.x && g.IO.MousePos.x < column->ClipRect.Max.x)
|
if (is_hovering_table && g.IO.MousePos.x >= column->ClipRect.Min.x && g.IO.MousePos.x < column->ClipRect.Max.x)
|
||||||
@ -1649,9 +1702,10 @@ bool ImGui::TableNextColumn()
|
|||||||
TableBeginCell(table, 0);
|
TableBeginCell(table, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME-TABLE: it is likely to alter layout if user skips a columns contents based on clipping.
|
// Return whether the column is visible. User may choose to skip submitting items based on this return value,
|
||||||
|
// however they shouldn't skip submitting for columns that may have the tallest contribution to row height.
|
||||||
int column_n = table->CurrentColumn;
|
int column_n = table->CurrentColumn;
|
||||||
return (table->EnabledUnclippedMaskByIndex & ((ImU64)1 << column_n)) != 0;
|
return (table->RequestOutputMaskByIndex & ((ImU64)1 << column_n)) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// [Public] Append into a specific column
|
// [Public] Append into a specific column
|
||||||
@ -1670,8 +1724,9 @@ bool ImGui::TableSetColumnIndex(int column_n)
|
|||||||
TableBeginCell(table, column_n);
|
TableBeginCell(table, column_n);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME-TABLE: it is likely to alter layout if user skips a columns contents based on clipping.
|
// Return whether the column is visible. User may choose to skip submitting items based on this return value,
|
||||||
return (table->EnabledUnclippedMaskByIndex & ((ImU64)1 << column_n)) != 0;
|
// however they shouldn't skip submitting for columns that may have the tallest contribution to row height.
|
||||||
|
return (table->RequestOutputMaskByIndex & ((ImU64)1 << column_n)) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ImGui::TableGetColumnCount()
|
int ImGui::TableGetColumnCount()
|
||||||
@ -1820,7 +1875,7 @@ void ImGui::TableSetBgColor(ImGuiTableBgTarget bg_target, ImU32 color, int colum
|
|||||||
return;
|
return;
|
||||||
if (column_n == -1)
|
if (column_n == -1)
|
||||||
column_n = table->CurrentColumn;
|
column_n = table->CurrentColumn;
|
||||||
if ((table->EnabledUnclippedMaskByIndex & ((ImU64)1 << column_n)) == 0)
|
if ((table->VisibleMaskByIndex & ((ImU64)1 << column_n)) == 0)
|
||||||
return;
|
return;
|
||||||
if (table->RowCellDataCurrent < 0 || table->RowCellData[table->RowCellDataCurrent].Column != column_n)
|
if (table->RowCellDataCurrent < 0 || table->RowCellData[table->RowCellDataCurrent].Column != column_n)
|
||||||
table->RowCellDataCurrent++;
|
table->RowCellDataCurrent++;
|
||||||
@ -1899,7 +1954,7 @@ void ImGui::TableSetupDrawChannels(ImGuiTable* table)
|
|||||||
const int freeze_row_multiplier = (table->FreezeRowsCount > 0) ? 2 : 1;
|
const int freeze_row_multiplier = (table->FreezeRowsCount > 0) ? 2 : 1;
|
||||||
const int channels_for_row = (table->Flags & ImGuiTableFlags_NoClip) ? 1 : table->ColumnsEnabledCount;
|
const int channels_for_row = (table->Flags & ImGuiTableFlags_NoClip) ? 1 : table->ColumnsEnabledCount;
|
||||||
const int channels_for_bg = 1 + 1 * freeze_row_multiplier;
|
const int channels_for_bg = 1 + 1 * freeze_row_multiplier;
|
||||||
const int channels_for_dummy = (table->ColumnsEnabledCount < table->ColumnsCount || table->EnabledUnclippedMaskByIndex != table->EnabledMaskByIndex) ? +1 : 0;
|
const int channels_for_dummy = (table->ColumnsEnabledCount < table->ColumnsCount || table->VisibleMaskByIndex != table->EnabledMaskByIndex) ? +1 : 0;
|
||||||
const int channels_total = channels_for_bg + (channels_for_row * freeze_row_multiplier) + channels_for_dummy;
|
const int channels_total = channels_for_bg + (channels_for_row * freeze_row_multiplier) + channels_for_dummy;
|
||||||
table->DrawSplitter.Split(table->InnerWindow->DrawList, channels_total);
|
table->DrawSplitter.Split(table->InnerWindow->DrawList, channels_total);
|
||||||
table->DummyDrawChannel = (ImGuiTableDrawChannelIdx)((channels_for_dummy > 0) ? channels_total - 1 : -1);
|
table->DummyDrawChannel = (ImGuiTableDrawChannelIdx)((channels_for_dummy > 0) ? channels_total - 1 : -1);
|
||||||
@ -1910,7 +1965,7 @@ void ImGui::TableSetupDrawChannels(ImGuiTable* table)
|
|||||||
for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
|
for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
|
||||||
{
|
{
|
||||||
ImGuiTableColumn* column = &table->Columns[column_n];
|
ImGuiTableColumn* column = &table->Columns[column_n];
|
||||||
if (!column->IsClipped)
|
if (column->IsVisibleX && column->IsVisibleY)
|
||||||
{
|
{
|
||||||
column->DrawChannelFrozen = (ImGuiTableDrawChannelIdx)(draw_channel_current);
|
column->DrawChannelFrozen = (ImGuiTableDrawChannelIdx)(draw_channel_current);
|
||||||
column->DrawChannelUnfrozen = (ImGuiTableDrawChannelIdx)(draw_channel_current + (table->FreezeRowsCount > 0 ? channels_for_row + 1 : 0));
|
column->DrawChannelUnfrozen = (ImGuiTableDrawChannelIdx)(draw_channel_current + (table->FreezeRowsCount > 0 ? channels_for_row + 1 : 0));
|
||||||
@ -1975,7 +2030,7 @@ void ImGui::TableMergeDrawChannels(ImGuiTable* table)
|
|||||||
// 1. Scan channels and take note of those which can be merged
|
// 1. Scan channels and take note of those which can be merged
|
||||||
for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
|
for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
|
||||||
{
|
{
|
||||||
if (!(table->EnabledUnclippedMaskByIndex & ((ImU64)1 << column_n)))
|
if ((table->VisibleMaskByIndex & ((ImU64)1 << column_n)) == 0)
|
||||||
continue;
|
continue;
|
||||||
ImGuiTableColumn* column = &table->Columns[column_n];
|
ImGuiTableColumn* column = &table->Columns[column_n];
|
||||||
|
|
||||||
@ -3116,13 +3171,13 @@ void ImGui::DebugNodeTable(ImGuiTable* table)
|
|||||||
const char* name = TableGetColumnName(table, n);
|
const char* name = TableGetColumnName(table, n);
|
||||||
ImFormatString(buf, IM_ARRAYSIZE(buf),
|
ImFormatString(buf, IM_ARRAYSIZE(buf),
|
||||||
"Column %d order %d name '%s': offset %+.2f to %+.2f\n"
|
"Column %d order %d name '%s': offset %+.2f to %+.2f\n"
|
||||||
"Visible: %d, Clipped: %d, SkipItems: %d, DrawChannels: %d,%d\n"
|
"Enabled: %d, VisibleX/Y: %d/%d, RequestOutput: %d, SkipItems: %d, DrawChannels: %d,%d\n"
|
||||||
"WidthGiven: %.1f, Request/Auto: %.1f/%.1f, StretchWeight: %.3f\n"
|
"WidthGiven: %.1f, Request/Auto: %.1f/%.1f, StretchWeight: %.3f\n"
|
||||||
"MinX: %.1f, MaxX: %.1f (%+.1f), ClipRect: %.1f to %.1f (+%.1f)\n"
|
"MinX: %.1f, MaxX: %.1f (%+.1f), ClipRect: %.1f to %.1f (+%.1f)\n"
|
||||||
"ContentWidth: %.1f,%.1f, HeadersUsed/Ideal %.1f/%.1f\n"
|
"ContentWidth: %.1f,%.1f, HeadersUsed/Ideal %.1f/%.1f\n"
|
||||||
"Sort: %d%s, UserID: 0x%08X, Flags: 0x%04X: %s%s%s%s..",
|
"Sort: %d%s, UserID: 0x%08X, Flags: 0x%04X: %s%s%s%s..",
|
||||||
n, column->DisplayOrder, name, column->MinX - table->WorkRect.Min.x, column->MaxX - table->WorkRect.Min.x,
|
n, column->DisplayOrder, name, column->MinX - table->WorkRect.Min.x, column->MaxX - table->WorkRect.Min.x,
|
||||||
column->IsEnabled, column->IsClipped, column->IsSkipItems, column->DrawChannelFrozen, column->DrawChannelUnfrozen,
|
column->IsEnabled, column->IsVisibleX, column->IsVisibleY, column->IsRequestOutput, column->IsSkipItems, column->DrawChannelFrozen, column->DrawChannelUnfrozen,
|
||||||
column->WidthGiven, column->WidthRequest, column->WidthAuto, column->StretchWeight,
|
column->WidthGiven, column->WidthRequest, column->WidthAuto, column->StretchWeight,
|
||||||
column->MinX, column->MaxX, column->MaxX - column->MinX, column->ClipRect.Min.x, column->ClipRect.Max.x, column->ClipRect.Max.x - column->ClipRect.Min.x,
|
column->MinX, column->MaxX, column->MaxX - column->MinX, column->ClipRect.Min.x, column->ClipRect.Max.x, column->ClipRect.Max.x - column->ClipRect.Min.x,
|
||||||
column->ContentMaxXFrozen - column->WorkMinX, column->ContentMaxXUnfrozen - column->WorkMinX, column->ContentMaxXHeadersUsed - column->WorkMinX, column->ContentMaxXHeadersIdeal - column->WorkMinX,
|
column->ContentMaxXFrozen - column->WorkMinX, column->ContentMaxXUnfrozen - column->WorkMinX, column->ContentMaxXHeadersUsed - column->WorkMinX, column->ContentMaxXHeadersIdeal - column->WorkMinX,
|
||||||
|
Loading…
Reference in New Issue
Block a user