93
93
// -----------------------------------------------------------------------------
94
94
95
95
// Configuration
96
+ static const int TABLE_DRAW_CHANNEL_BG0 = 0 ;
97
+ static const int TABLE_DRAW_CHANNEL_BG1_FROZEN = 1 ;
98
+ static const int TABLE_DRAW_CHANNEL_UNCLIPPED = 2 ; // When using ImGuiTableFlags_NoClip
96
99
static const float TABLE_BORDER_SIZE = 1 .0f ; // FIXME-TABLE: Currently hard-coded.
97
100
static const float TABLE_RESIZE_SEPARATOR_HALF_THICKNESS = 4 .0f ; // Extend outside inner borders.
98
101
static const float TABLE_RESIZE_SEPARATOR_FEEDBACK_TIMER = 0 .06f ; // Delay/timer before making the hover feedback (color+cursor) visible because tables/columns tends to be more cramped.
@@ -894,7 +897,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
894
897
// Initial state
895
898
ImGuiWindow* inner_window = table->InnerWindow ;
896
899
if (table->Flags & ImGuiTableFlags_NoClip)
897
- table->DrawSplitter .SetCurrentChannel (inner_window->DrawList , 1 );
900
+ table->DrawSplitter .SetCurrentChannel (inner_window->DrawList , TABLE_DRAW_CHANNEL_UNCLIPPED );
898
901
else
899
902
inner_window->DrawList ->PushClipRect (inner_window->ClipRect .Min , inner_window->ClipRect .Max , false );
900
903
@@ -1015,6 +1018,7 @@ void ImGui::EndTable()
1015
1018
// Draw borders
1016
1019
if ((flags & ImGuiTableFlags_Borders) != 0 )
1017
1020
TableDrawBorders (table);
1021
+ table->DrawSplitter .SetCurrentChannel (inner_window->DrawList , 0 );
1018
1022
1019
1023
// Store content width reference for each column (before attempting to merge draw calls)
1020
1024
const float backup_outer_cursor_pos_x = outer_window->DC .CursorPos .x ;
@@ -1024,8 +1028,19 @@ void ImGui::EndTable()
1024
1028
if (table->RightMostVisibleColumn != -1 )
1025
1029
max_pos_x = ImMax (max_pos_x, table->Columns [table->RightMostVisibleColumn ].MaxX );
1026
1030
1031
+ #if 0
1032
+ // Strip out dummy channel draw calls
1033
+ // We have no way to prevent user submitting direct ImDrawList calls into a hidden column (but ImGui:: calls will be clipped out)
1034
+ // FIXME-TABLE: The problem with this approach is we are effectively making it harder for users watching metrics to spot wasted vertices.
1035
+ if (table->DummyDrawChannel != (ImU8)-1)
1036
+ {
1037
+ ImDrawChannel* dummy_channel = &table->DrawSplitter._Channels[table->DummyDrawChannel];
1038
+ dummy_channel->_CmdBuffer.resize(0);
1039
+ dummy_channel->_IdxBuffer.resize(0);
1040
+ }
1041
+ #endif
1042
+
1027
1043
// Flatten channels and merge draw calls
1028
- table->DrawSplitter .SetCurrentChannel (inner_window->DrawList , 0 );
1029
1044
if ((table->Flags & ImGuiTableFlags_NoClip) == 0 )
1030
1045
TableReorderDrawChannelsForMerge (table);
1031
1046
table->DrawSplitter .Merge (inner_window->DrawList );
@@ -1101,7 +1116,7 @@ void ImGui::TableDrawBorders(ImGuiTable* table)
1101
1116
{
1102
1117
ImGuiWindow* inner_window = table->InnerWindow ;
1103
1118
ImGuiWindow* outer_window = table->OuterWindow ;
1104
- table->DrawSplitter .SetCurrentChannel (inner_window->DrawList , 0 );
1119
+ table->DrawSplitter .SetCurrentChannel (inner_window->DrawList , TABLE_DRAW_CHANNEL_BG0 );
1105
1120
if (inner_window->Hidden || !table->HostClipRect .Overlaps (table->InnerClipRect ))
1106
1121
return ;
1107
1122
ImDrawList* inner_drawlist = inner_window->DrawList ;
@@ -1322,23 +1337,24 @@ void ImGui::TableSetColumnVisible(int column_n, bool visible)
1322
1337
// - We allocate 1 or 2 background draw channels. This is because we know PushTableBackground() is only used for
1323
1338
// horizontal spanning. If we allowed vertical spanning we'd need one background draw channel per merge group (1-4).
1324
1339
// Draw channel allocation (before merging):
1325
- // - NoClip --> 1 +D+1 channels: background + foreground (same clip rect == 1 draw call)
1326
- // - Clip --> 1 +D+N channels
1327
- // - FreezeRows --> 1 +D+N*2 (unless scrolling value is zero)
1328
- // - FreezeRows || FreezeColunns --> 2 +D+N*2 (unless scrolling value is zero)
1340
+ // - NoClip --> 2 +D+1 channels: bg0 + bg1 + foreground (same clip rect == 1 draw call) (FIXME-TABLE: could merge bg1 and foreground? )
1341
+ // - Clip --> 2 +D+N channels
1342
+ // - FreezeRows --> 2 +D+N*2 (unless scrolling value is zero)
1343
+ // - FreezeRows || FreezeColunns --> 3 +D+N*2 (unless scrolling value is zero)
1329
1344
// Where D is 1 if any column is clipped or hidden (dummy channel) otherwise 0.
1330
1345
void ImGui::TableUpdateDrawChannels (ImGuiTable* table)
1331
1346
{
1332
1347
const int freeze_row_multiplier = (table->FreezeRowsCount > 0 ) ? 2 : 1 ;
1333
1348
const int channels_for_row = (table->Flags & ImGuiTableFlags_NoClip) ? 1 : table->ColumnsVisibleCount ;
1334
- const int channels_for_bg = 1 * freeze_row_multiplier;
1349
+ const int channels_for_bg = 1 + 1 * freeze_row_multiplier;
1335
1350
const int channels_for_dummy = (table->ColumnsVisibleCount < table->ColumnsCount || table->VisibleUnclippedMaskByIndex != table->VisibleMaskByIndex ) ? +1 : 0 ;
1336
1351
const int channels_total = channels_for_bg + (channels_for_row * freeze_row_multiplier) + channels_for_dummy;
1337
1352
table->DrawSplitter .Split (table->InnerWindow ->DrawList , channels_total);
1338
1353
table->DummyDrawChannel = (ImU8)((channels_for_dummy > 0 ) ? channels_total - 1 : -1 );
1339
- table->BgDrawChannelUnfrozen = (ImU8)((table->FreezeRowsCount > 0 ) ? channels_for_row + 1 : 0 );
1354
+ table->Bg1DrawChannelCurrent = TABLE_DRAW_CHANNEL_BG1_FROZEN;
1355
+ table->Bg1DrawChannelUnfrozen = (ImU8)((table->FreezeRowsCount > 0 ) ? 2 + channels_for_row : TABLE_DRAW_CHANNEL_BG1_FROZEN);
1340
1356
1341
- int draw_channel_current = 1 ;
1357
+ int draw_channel_current = 2 ;
1342
1358
for (int column_n = 0 ; column_n < table->ColumnsCount ; column_n++)
1343
1359
{
1344
1360
ImGuiTableColumn* column = &table->Columns [column_n];
@@ -1475,15 +1491,16 @@ void ImGui::TableReorderDrawChannelsForMerge(ImGuiTable* table)
1475
1491
// 2. Rewrite channel list in our preferred order
1476
1492
if (merge_group_mask != 0 )
1477
1493
{
1478
- // We skip background channel 0 from the shuffling since it won't move ( see channels allocation in TableUpdateDrawChannels() ).
1479
- const int LEADING_DRAW_CHANNELS = 1 ;
1494
+ // We skip channel 0 (Bg0) and 1 (Bg1 frozen) from the shuffling since they won't move - see channels allocation in TableUpdateDrawChannels().
1495
+ const int LEADING_DRAW_CHANNELS = 2 ;
1480
1496
g.DrawChannelsTempMergeBuffer .resize (splitter->_Count - LEADING_DRAW_CHANNELS); // Use shared temporary storage so the allocation gets amortized
1481
1497
ImDrawChannel* dst_tmp = g.DrawChannelsTempMergeBuffer .Data ;
1482
- ImBitArray<IMGUI_TABLE_MAX_DRAW_CHANNELS> remaining_mask; // We need 131 -bit of storage
1498
+ ImBitArray<IMGUI_TABLE_MAX_DRAW_CHANNELS> remaining_mask; // We need 132 -bit of storage
1483
1499
remaining_mask.ClearBits ();
1484
1500
remaining_mask.SetBitRange (LEADING_DRAW_CHANNELS, splitter->_Count - 1 );
1485
- remaining_mask.ClearBit (table->BgDrawChannelUnfrozen );
1486
- int remaining_count = splitter->_Count - ((table->BgDrawChannelUnfrozen == 0 ) ? 1 : 2 );
1501
+ remaining_mask.ClearBit (table->Bg1DrawChannelUnfrozen );
1502
+ IM_ASSERT (has_freeze_v == false || table->Bg1DrawChannelUnfrozen != TABLE_DRAW_CHANNEL_BG1_FROZEN);
1503
+ int remaining_count = splitter->_Count - (has_freeze_v ? LEADING_DRAW_CHANNELS + 1 : LEADING_DRAW_CHANNELS);
1487
1504
// ImRect host_rect = (table->InnerWindow == table->OuterWindow) ? table->InnerClipRect : table->HostClipRect;
1488
1505
ImRect host_rect = table->HostClipRect ;
1489
1506
for (int merge_group_n = 0 ; merge_group_n < IM_ARRAYSIZE (merge_groups); merge_group_n++)
@@ -1531,9 +1548,9 @@ void ImGui::TableReorderDrawChannelsForMerge(ImGuiTable* table)
1531
1548
}
1532
1549
}
1533
1550
1534
- // BgDrawChannelFrozen is always channel 0, but make sure BgDrawChannelUnfrozen appears in the middle of our groups
1535
- if (merge_group_n == 1 && table-> BgDrawChannelUnfrozen != 0 )
1536
- memcpy (dst_tmp++, &splitter->_Channels [table->BgDrawChannelUnfrozen ], sizeof (ImDrawChannel));
1551
+ // Make sure Bg1DrawChannelUnfrozen appears in the middle of our groups (whereas Bg0 and Bg1 frozen are fixed to 0 and 1)
1552
+ if (merge_group_n == 1 && has_freeze_v )
1553
+ memcpy (dst_tmp++, &splitter->_Channels [table->Bg1DrawChannelUnfrozen ], sizeof (ImDrawChannel));
1537
1554
}
1538
1555
1539
1556
// Append unmergeable channels that we didn't reorder at the end of the list
@@ -1748,7 +1765,7 @@ void ImGui::TableEndRow(ImGuiTable* table)
1748
1765
// always followed by a change of clipping rectangle we perform the smallest overwrite possible here.
1749
1766
if ((table->Flags & ImGuiTableFlags_NoClip) == 0 )
1750
1767
window->DrawList ->_CmdHeader .ClipRect = table->BgClipRectForDrawCmd .ToVec4 ();
1751
- table->DrawSplitter .SetCurrentChannel (window->DrawList , table-> IsUnfrozen ? table-> BgDrawChannelUnfrozen : 0 );
1768
+ table->DrawSplitter .SetCurrentChannel (window->DrawList , TABLE_DRAW_CHANNEL_BG0 );
1752
1769
}
1753
1770
1754
1771
// Draw row background
@@ -1805,6 +1822,7 @@ void ImGui::TableEndRow(ImGuiTable* table)
1805
1822
float y0 = ImMax (table->RowPosY2 + 1 , window->InnerClipRect .Min .y );
1806
1823
table->BgClipRect .Min .y = table->BgClipRectForDrawCmd .Min .y = ImMin (y0, window->InnerClipRect .Max .y );
1807
1824
table->BgClipRect .Max .y = table->BgClipRectForDrawCmd .Max .y = window->InnerClipRect .Max .y ;
1825
+ table->Bg1DrawChannelCurrent = table->Bg1DrawChannelUnfrozen ;
1808
1826
IM_ASSERT (table->BgClipRectForDrawCmd .Min .y <= table->BgClipRectForDrawCmd .Max .y );
1809
1827
1810
1828
float row_height = table->RowPosY2 - table->RowPosY1 ;
@@ -1860,7 +1878,9 @@ void ImGui::TableBeginCell(ImGuiTable* table, int column_n)
1860
1878
window->SkipItems = column->IsSkipItems ;
1861
1879
if (table->Flags & ImGuiTableFlags_NoClip)
1862
1880
{
1863
- table->DrawSplitter .SetCurrentChannel (window->DrawList , 1 );
1881
+ // FIXME: if we end up drawing all borders/bg in EndTable, could remove this and just assert that channel hasn't changed.
1882
+ table->DrawSplitter .SetCurrentChannel (window->DrawList , TABLE_DRAW_CHANNEL_UNCLIPPED);
1883
+ // IM_ASSERT(table->DrawSplitter._Current == TABLE_DRAW_CHANNEL_UNCLIPPED);
1864
1884
}
1865
1885
else
1866
1886
{
@@ -2025,7 +2045,7 @@ void ImGui::PushTableBackground()
2025
2045
// Optimization: avoid SetCurrentChannel() + PushClipRect()
2026
2046
table->HostBackupClipRect = window->ClipRect ;
2027
2047
SetWindowClipRectBeforeSetChannel (window, table->BgClipRectForDrawCmd );
2028
- table->DrawSplitter .SetCurrentChannel (window->DrawList , table->IsUnfrozen ? table-> BgDrawChannelUnfrozen : 0 );
2048
+ table->DrawSplitter .SetCurrentChannel (window->DrawList , table->Bg1DrawChannelCurrent );
2029
2049
}
2030
2050
2031
2051
void ImGui::PopTableBackground ()
0 commit comments