The Tables System provides a comprehensive multi-column layout and data presentation API in Dear ImGui. It handles column management, resizing, sorting, scrolling, freezing, clipping, and context menus for tabular data displays. Tables support both fixed and stretch column sizing policies, row/column visibility, and persistent settings storage.
For information about the legacy single-table Columns API, see the Columns section in imgui_tables.cpp. For widget rendering within table cells, see Widget System. For drawing primitives used by tables, see Drawing System.
Sources: imgui_tables.cpp1-185
The tables system is implemented primarily in imgui_tables.cpp with approximately 4,400 lines of code. It provides a flexible framework for creating feature-rich tables with automatic layout, user interaction, and rendering optimization through draw channel splitting.
Sources: imgui_tables.cpp32-185 imgui.h2079-2150
Call Flow Diagram: Standard table construction sequence
Sources: imgui_tables.cpp36-71 imgui.h765-789
The table system follows a complex initialization and layout process:
Internal Flow Diagram: Complete table lifecycle showing initialization and rendering phases
Sources: imgui_tables.cpp36-71 imgui_tables.cpp312-468
The main table state container, stored in ImGuiContext::Tables pool:
ImGuiTable Structure Relationships
Key fields in ImGuiTable:
ID: Unique table identifierFlags: ImGuiTableFlags configurationColumns: Dynamic array of column dataColumnsCount: Total number of columnsCurrentRow, CurrentColumn: Current position during submissionInnerWidth, OuterRect: Size and layout boundsInstanceCurrent: Instance index for multiple tables with same IDSources: imgui_internal.h2669-2796 imgui_tables.cpp354-379
Per-column state and configuration:
| Field | Type | Purpose |
|---|---|---|
Flags | ImGuiTableColumnFlags | Column behavior flags |
WidthGiven | float | Current width after sizing |
MinX, MaxX | float | Column boundaries |
WidthRequest | float | Requested width or weight |
WidthAuto | float | Automatic width from contents |
StretchWeight | float | Normalized weight for stretch columns |
InitStretchWeightOrWidth | float | Initial value from TableSetupColumn() |
ClipRect | ImRect | Clipping rectangle for this column |
UserID | ImGuiID | User-provided ID from TableSetupColumn() |
WorkMinX, WorkMaxX | float | Content region bounds |
ItemWidth | float | Current item width for widgets |
ContentMaxXFrozen, ContentMaxXUnfrozen | float | Rightmost content edge (for width auto) |
ContentMaxXHeadersUsed, ContentMaxXHeadersIdeal | float | Header content tracking |
NameOffset | ImS16 | Offset into table's name buffer |
DisplayOrder | ImGuiTableColumnIdx | Display order (after reordering) |
IndexWithinEnabledSet | ImGuiTableColumnIdx | Index among visible columns |
PrevEnabledColumn, NextEnabledColumn | ImGuiTableColumnIdx | Linked list of visible columns |
SortOrder | ImGuiTableColumnIdx | Sorting order index |
DrawChannelCurrent | ImGuiTableDrawChannelIdx | Current draw channel |
DrawChannelFrozen, DrawChannelUnfrozen | ImGuiTableDrawChannelIdx | Split channel assignments |
IsEnabled, IsUserEnabled | bool | Visibility flags |
IsUserEnabledNextFrame | bool | Deferred visibility change |
IsVisibleX, IsVisibleY | bool | Clipping visibility |
IsRequestOutput | bool | Whether to process column output |
IsSkipItems | bool | Whether widgets should skip |
IsPreserveWidthAuto | bool | Preserve width during hide/show |
NavLayerCurrent | ImS8 | Current navigation layer |
AutoFitQueue | ImU8 | Auto-fit request queue |
CannotSkipItemsQueue | ImU8 | Cannot skip items queue |
SortDirection | ImGuiSortDirection | ImGuiSortDirection_Ascending or Descending |
SortDirectionsAvailCount, SortDirectionsAvailMask, SortDirectionsAvailList | Various | Available sort directions |
Sources: imgui_internal.h2618-2667
Temporary per-table data stored in ImGuiContext::TablesTempData stack:
ImGuiTableTempData Components
Sources: imgui_internal.h2798-2830 imgui_tables.cpp357-364
The tables system uses ImDrawListSplitter to enable efficient rendering with multiple draw layers:
Draw Channel Architecture
The system allocates draw channels based on table configuration:
| Channel Type | Index | Purpose |
|---|---|---|
TABLE_DRAW_CHANNEL_BG0 | 0 | Background layer 0 (alternating row colors) |
TABLE_DRAW_CHANNEL_BG2_FROZEN | 1 | Background for frozen rows/columns |
TABLE_DRAW_CHANNEL_NOCLIP | 2 | Unclipped layer (when ImGuiTableFlags_NoClip) |
| Column-specific | 3+ | One or two channels per column (frozen/unfrozen split) |
Key functions:
TableSetupDrawChannels(): Allocates and initializes channels imgui_tables.cpp1467-1555TableMergeDrawChannels(): Merges channels back to main draw list imgui_tables.cpp1557-1672TableBeginCell(): Selects appropriate channel for current column imgui_tables.cpp2116-2183Sources: imgui_tables.cpp264-269 imgui_tables.cpp1467-1672 imgui_internal.h1237-1262
Tables support four sizing policies specified via ImGuiTableFlags_SizingXXX:
Table Sizing Policy Options
Sources: imgui_tables.cpp115-151 imgui_tables.cpp272-303
The layout system in TableUpdateLayout() calculates final column widths:
Column Width Calculation Flow
Key width-related functions:
TableUpdateLayout(): Main layout calculation imgui_tables.cpp944-1172TableUpdateColumnsWeightFromWidth(): Recomputes weights from widths after resize imgui_tables.cpp1390-1426TableSetColumnWidth(): Applies column resize imgui_tables.cpp1301-1388Sources: imgui_tables.cpp944-1172 imgui_tables.cpp1301-1426
Row Transition Process
Cell Navigation and Visibility Logic
Key functions:
TableNextRow(): Advances to next row imgui_tables.cpp2035-2061TableNextColumn(): Advances to next column imgui_tables.cpp2063-2070TableSetColumnIndex(): Jumps to specific column imgui_tables.cpp2072-2099TableBeginCell(): Initializes cell state imgui_tables.cpp2116-2183TableEndCell(): Finalizes cell state imgui_tables.cpp2185-2202Sources: imgui_tables.cpp2035-2202
Tables support single or multi-column sorting:
Sorting Workflow
Sorting structures:
ImGuiTableSortSpecs: Contains array of ImGuiTableColumnSortSpecs imgui.h2165-2172ImGuiTableColumnSortSpecs: Per-column sort specification imgui.h2151-2163Key flags:
ImGuiTableFlags_SortMulti: Enable multi-column sortingImGuiTableFlags_SortTristate: Allow no-sort stateImGuiTableColumnFlags_NoSort: Disable sorting for columnImGuiTableColumnFlags_PreferSortAscending / Descending: Default directionSources: imgui_tables.cpp1734-1880 imgui.h2151-2172
Freezing keeps specific rows/columns visible during scrolling:
Freeze Implementation Flow
Key fields in ImGuiTable:
FreezeColumnsRequest, FreezeColumnsCount: Number of frozen columnsFreezeRowsRequest, FreezeRowsCount: Number of frozen rowsFreezeRowsHeight: Total height of frozen rowsSources: imgui_tables.cpp923-942 imgui_tables.cpp1467-1555 imgui.h787-789
Column resizing is handled through border interaction:
Column Resize Interaction
Configuration constants:
TABLE_RESIZE_SEPARATOR_HALF_THICKNESS: 4.0f - Hit test width imgui_tables.cpp268TABLE_RESIZE_SEPARATOR_FEEDBACK_TIMER: 0.06f - Visual feedback delay imgui_tables.cpp269Sources: imgui_tables.cpp1174-1299 imgui_tables.cpp1301-1426
Table settings are automatically saved to .ini files:
Settings Persistence Lifecycle
Key structures:
ImGuiTableSettings: Persistent table settings imgui_internal.h2832-2841ImGuiTableColumnsSettings: Per-column persistent settings imgui_internal.h2843-2854Settings handler functions:
TableSettingsCreate(): Allocates settings imgui_tables.cpp3399-3421TableSettingsFindByID(): Looks up settings imgui_tables.cpp3423-3431TableLoadSettings(): Applies settings to table imgui_tables.cpp3267-3321TableSaveSettings(): Captures current state imgui_tables.cpp3323-3363TableSettingsHandler_ReadLine(): Parses .ini data imgui_tables.cpp3438-3501TableSettingsHandler_WriteAll(): Serializes to .ini imgui_tables.cpp3503-3542Flags affecting settings:
ImGuiTableFlags_NoSavedSettings: Disables persistence imgui.h2090Sources: imgui_tables.cpp3257-3542 imgui_internal.h2832-2854
Right-clicking table headers opens a context menu:
Context Menu Flow
Context menu functions:
TableOpenContextMenu(): Opens popup imgui_tables.cpp2320-2349TableBeginContextMenuPopup(): Checks for popup imgui_tables.cpp2351-2361TableDrawDefaultContextMenu(): Renders menu contents imgui_tables.cpp2363-2425Menu contents include:
Sources: imgui_tables.cpp2320-2425
Tables support row clipping through ImGuiListClipper:
Row Clipping with ImGuiListClipper
Columns are clipped based on ImGuiTableColumn::IsVisibleX and IsVisibleY:
| Case | TableNextColumn() Return | SkipItems | ClipRect | Draw Output |
|---|---|---|---|---|
| A: Visible, in view | true | false | Normal | Normal |
| B: Clipped, out of scroll view | false | false | Zero-width | Dummy channel |
| C: Hidden by user | false | true | Zero-width | Dummy channel |
Key points:
SkipItems to skip widget processing entirelyTableSetColumnIndex() and TableNextColumn() return visibility statusSources: imgui_tables.cpp156-185 imgui_tables.cpp2116-2183
Constants defined in imgui_tables.cpp264-269:
| Constant | Value | Purpose |
|---|---|---|
TABLE_DRAW_CHANNEL_BG0 | 0 | Background layer 0 channel index |
TABLE_DRAW_CHANNEL_BG2_FROZEN | 1 | Frozen area background channel |
TABLE_DRAW_CHANNEL_NOCLIP | 2 | Unclipped layer channel |
TABLE_BORDER_SIZE | 1.0f | Border line thickness |
TABLE_RESIZE_SEPARATOR_HALF_THICKNESS | 4.0f | Resize hit test area |
TABLE_RESIZE_SEPARATOR_FEEDBACK_TIMER | 0.06f | Delay before showing resize cursor |
Sources: imgui_tables.cpp264-269
| Function | Purpose |
|---|---|
BeginTable() | Start a table with specified columns and flags |
EndTable() | Finalize and render the table |
TableNextRow() | Advance to next row |
TableNextColumn() | Advance to next column, returns visibility |
TableSetColumnIndex() | Jump to specific column, returns visibility |
TableSetupColumn() | Configure column properties (must call before TableHeadersRow()) |
TableSetupScrollFreeze() | Set number of frozen rows/columns |
TableHeadersRow() | Submit a row of clickable column headers |
TableHeader() | Submit a single column header |
TableGetSortSpecs() | Get sorting specifications after header interaction |
TableGetColumnCount() | Get total number of columns |
TableGetColumnIndex() | Get current column index |
TableGetRowIndex() | Get current row index |
TableGetColumnName() | Get column name by index |
TableGetColumnFlags() | Get column flags by index |
TableSetBgColor() | Set background color for cell, row, or column |
TableAngledHeadersRow() | Submit angled headers row (advanced) |
Sources: imgui.h765-820
ImGuiTableFlags (table-level configuration) imgui.h2079-2120:
_SizingFixedFit, _SizingFixedSame, _SizingStretchSame, _SizingStretchWeight_Resizable, _Reorderable, _Hideable, _Sortable, _SortMulti, _SortTristate_ScrollX, _ScrollY_Borders, _BordersInner, _BordersOuter, _BordersH, _BordersV, etc._NoHostExtendX, _NoHostExtendY, _NoKeepColumnsVisible, _PreciseWidths_RowBg, _ContextMenuInBody, _HighlightHoveredColumn_NoClip, _PadOuterX, _NoPadOuterX, _NoPadInnerXImGuiTableColumnFlags (column-level configuration) imgui.h2122-2144:
_WidthFixed, _WidthStretch, _NoResize_DefaultHide, _DefaultSort, _NoHide_NoSort, _PreferSortAscending, _PreferSortDescending, _IndentEnable, _IndentDisable_NoHeaderLabel, _NoHeaderWidth, _NoReorder, _NoClip_AngledHeaderImGuiTableRowFlags (row-level flags) imgui.h2146-2148:
_Headers: Identify header row, will be scrolled to stay visible if table has _ScrollYImGuiTableBgTarget (background color target) imgui.h2174-2179:
_None, _RowBg0, _RowBg1, _CellBg: Target for TableSetBgColor()Sources: imgui.h2079-2179
The Tables System provides a comprehensive solution for tabular data presentation in Dear ImGui. Its architecture separates concerns across:
ImGuiTable, ImGuiTableColumn, ImGuiTableTempDataThe system is designed for flexibility, supporting everything from simple data grids to complex interactive tables with frozen headers, scrolling, and multi-column sorting. Its integration with ImDrawListSplitter enables efficient rendering even with many columns, and the clipping system ensures good performance with large datasets when used with ImGuiListClipper.
Sources: imgui_tables.cpp1-4400 imgui.h765-820 imgui_internal.h2618-2854
Refresh this wiki