mirror of
https://github.com/Drezil/imgui.git
synced 2024-12-19 14:36:34 +00:00
Tables: Fix TableDrawMergeChannels() mistakenly merging unfrozen columns cliprect with host cliprect. Comments, debug.
This commit is contained in:
parent
fec9d7d226
commit
e41fc7b5b0
@ -1290,11 +1290,11 @@ void ImGui::TableSetColumnWidth(ImGuiTable* table, ImGuiTableColumn* column_0, f
|
||||
|
||||
// Columns where the contents didn't stray off their local clip rectangle can be merged into a same draw command.
|
||||
// To achieve this we merge their clip rect and make them contiguous in the channel list so they can be merged.
|
||||
// So here we'll reorder the draw cmd which can be merged, by arranging them into a maximum of 4 distinct groups:
|
||||
// This function first reorder the draw cmd which can be merged, by arranging them into a maximum of 4 distinct groups:
|
||||
//
|
||||
// 1 group: 2 groups: 2 groups: 4 groups:
|
||||
// [ 0. ] no freeze [ 0. ] row freeze [ 01 ] col freeze [ 01 ] row+col freeze
|
||||
// [ .. ] or no scroll [ 1. ] and v-scroll [ .. ] and h-scroll [ 23 ] and v+h-scroll
|
||||
// [ 0. ] no freeze [ 0. ] row freeze [ 01 ] col freeze [ 02 ] row+col freeze
|
||||
// [ .. ] or no scroll [ 1. ] and v-scroll [ .. ] and h-scroll [ 13 ] and v+h-scroll
|
||||
//
|
||||
// Each column itself can use 1 channel (row freeze disabled) or 2 channels (row freeze enabled).
|
||||
// When the contents of a column didn't stray off its limit, we move its channels into the corresponding group
|
||||
@ -1306,8 +1306,9 @@ void ImGui::TableSetColumnWidth(ImGuiTable* table, ImGuiTableColumn* column_0, f
|
||||
// - The contents stray off its clipping rectangle (we only compare the MaxX value, not the MinX value).
|
||||
// Direct ImDrawList calls won't be taken into account by default, if you use them make sure the ImGui:: bounds
|
||||
// matches, by e.g. calling SetCursorScreenPos().
|
||||
// - The channel uses more than one draw command itself. We drop all our merging stuff here.. we could do better
|
||||
// but it's going to be rare.
|
||||
// - The channel uses more than one draw command itself. We drop all our attempt at merging stuff here..
|
||||
// we could do better but it's going to be rare and probably not worth the hassle.
|
||||
// Columns for which the draw chnanel(s) haven't been merged with other will use their own ImDrawCmd.
|
||||
//
|
||||
// This function is particularly tricky to understand.. take a breath.
|
||||
void ImGui::TableDrawMergeChannels(ImGuiTable* table)
|
||||
@ -1350,15 +1351,18 @@ void ImGui::TableDrawMergeChannels(ImGuiTable* table)
|
||||
continue;
|
||||
|
||||
// Find out the width of this merge group and check if it will fit in our column.
|
||||
float width_contents;
|
||||
if (merge_group_sub_count == 1) // No row freeze (same as testing !is_frozen_v)
|
||||
width_contents = ImMax(column->ContentWidthRowsUnfrozen, column->ContentWidthHeadersUsed);
|
||||
else if (merge_group_sub_n == 0) // Row freeze: use width before freeze
|
||||
width_contents = ImMax(column->ContentWidthRowsFrozen, column->ContentWidthHeadersUsed);
|
||||
else // Row freeze: use width after freeze
|
||||
width_contents = column->ContentWidthRowsUnfrozen;
|
||||
if (width_contents > column->WidthGiven && !(column->Flags & ImGuiTableColumnFlags_NoClipX))
|
||||
continue;
|
||||
if (!(column->Flags & ImGuiTableColumnFlags_NoClipX))
|
||||
{
|
||||
float width_contents;
|
||||
if (merge_group_sub_count == 1) // No row freeze (same as testing !is_frozen_v)
|
||||
width_contents = ImMax(column->ContentWidthRowsUnfrozen, column->ContentWidthHeadersUsed);
|
||||
else if (merge_group_sub_n == 0) // Row freeze: use width before freeze
|
||||
width_contents = ImMax(column->ContentWidthRowsFrozen, column->ContentWidthHeadersUsed);
|
||||
else // Row freeze: use width after freeze
|
||||
width_contents = column->ContentWidthRowsUnfrozen;
|
||||
if (width_contents > column->WidthGiven)
|
||||
continue;
|
||||
}
|
||||
|
||||
const int merge_group_dst_n = (is_frozen_h && column_n < table->FreezeColumnsCount ? 0 : 2) + (is_frozen_v ? merge_group_sub_n : 1);
|
||||
IM_ASSERT(channel_no < IMGUI_TABLE_MAX_DRAW_CHANNELS);
|
||||
@ -1385,28 +1389,50 @@ void ImGui::TableDrawMergeChannels(ImGuiTable* table)
|
||||
}
|
||||
|
||||
// Invalidate current draw channel
|
||||
// (we don't clear DrawChannelBeforeRowFreeze/DrawChannelAfterRowFreeze solely to facilitate debugging)
|
||||
// (we don't clear DrawChannelBeforeRowFreeze/DrawChannelAfterRowFreeze solely to facilitate debugging/later inspection of data)
|
||||
column->DrawChannelCurrent = -1;
|
||||
}
|
||||
|
||||
// [DEBUG] Display merge groups
|
||||
#if 0
|
||||
if (g.IO.KeyShift)
|
||||
for (int merge_group_n = 0; merge_group_n < IM_ARRAYSIZE(merge_groups); merge_group_n++)
|
||||
{
|
||||
MergeGroup* merge_group = &merge_groups[merge_group_n];
|
||||
if (merge_group->ChannelsCount == 0)
|
||||
continue;
|
||||
char buf[32];
|
||||
ImFormatString(buf, 32, "MG%d:%d", merge_group_n, merge_group->ChannelsCount);
|
||||
ImVec2 text_pos = merge_group->ClipRect.Min + ImVec2(4, 4);
|
||||
ImVec2 text_size = CalcTextSize(buf, NULL);
|
||||
GetForegroundDrawList()->AddRectFilled(text_pos, text_pos + text_size, IM_COL32(0, 0, 0, 255));
|
||||
GetForegroundDrawList()->AddText(text_pos, IM_COL32(255, 255, 0, 255), buf, NULL);
|
||||
GetForegroundDrawList()->AddRect(merge_group->ClipRect.Min, merge_group->ClipRect.Max, IM_COL32(255, 255, 0, 255));
|
||||
}
|
||||
#endif
|
||||
|
||||
// 2. Rewrite channel list in our preferred order
|
||||
if (merge_group_mask != 0)
|
||||
{
|
||||
// Conceptually we want to test if only 1 bit of merge_group_mask is set, but with no freezing we know it's always going to be group 3.
|
||||
// We need to test for !is_frozen because any unfitting column will not be part of a merge group, so testing for merge_group_mask isn't enough.
|
||||
const bool may_extend_clip_rect_to_host_rect = (merge_group_mask == (1 << 3)) && !is_frozen_v && !is_frozen_h;
|
||||
|
||||
// Use shared temporary storage so the allocation gets amortized
|
||||
g.DrawChannelsTempMergeBuffer.resize(splitter->_Count - 1);
|
||||
ImDrawChannel* dst_tmp = g.DrawChannelsTempMergeBuffer.Data;
|
||||
ImBitArray<IMGUI_TABLE_MAX_DRAW_CHANNELS> remaining_mask;
|
||||
ImBitArray<IMGUI_TABLE_MAX_DRAW_CHANNELS> remaining_mask; // We need 130-bit of storage
|
||||
remaining_mask.ClearBits();
|
||||
remaining_mask.SetBitRange(1, splitter->_Count - 1); // Background channel 0 not part of the merge (see channel allocation in TableUpdateDrawChannels)
|
||||
int remaining_count = splitter->_Count - 1;
|
||||
const bool may_extend_clip_rect_to_host_rect = ImIsPowerOfTwo(merge_group_mask);
|
||||
for (int merge_group_n = 0; merge_group_n < 4; merge_group_n++)
|
||||
for (int merge_group_n = 0; merge_group_n < IM_ARRAYSIZE(merge_groups); merge_group_n++)
|
||||
if (int merge_channels_count = merge_groups[merge_group_n].ChannelsCount)
|
||||
{
|
||||
MergeGroup* merge_group = &merge_groups[merge_group_n];
|
||||
ImRect merge_clip_rect = merge_groups[merge_group_n].ClipRect;
|
||||
if (may_extend_clip_rect_to_host_rect)
|
||||
{
|
||||
IM_ASSERT(merge_group_n == 3);
|
||||
//GetOverlayDrawList()->AddRect(table->HostClipRect.Min, table->HostClipRect.Max, IM_COL32(255, 0, 0, 200), 0.0f, ~0, 3.0f);
|
||||
//GetOverlayDrawList()->AddRect(table->InnerClipRect.Min, table->InnerClipRect.Max, IM_COL32(0, 255, 0, 200), 0.0f, ~0, 1.0f);
|
||||
//GetOverlayDrawList()->AddRect(merge_clip_rect.Min, merge_clip_rect.Max, IM_COL32(255, 0, 0, 200), 0.0f, ~0, 2.0f);
|
||||
|
Loading…
Reference in New Issue
Block a user