diff --git a/imgui_internal.h b/imgui_internal.h index b4c2a429e..070a75e6f 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -206,6 +206,10 @@ typedef int ImGuiTooltipFlags; // -> enum ImGuiTooltipFlags_ // F typedef int ImGuiTypingSelectFlags; // -> enum ImGuiTypingSelectFlags_ // Flags: for GetTypingSelectRequest() typedef int ImGuiWindowRefreshFlags; // -> enum ImGuiWindowRefreshFlags_ // Flags: for SetNextWindowRefreshPolicy() +// Table column indexing +typedef ImS16 ImGuiTableColumnIdx; +typedef ImU16 ImGuiTableDrawChannelIdx; + //----------------------------------------------------------------------------- // [SECTION] Context pointer // See implementation of this variable in imgui.cpp for comments and details. @@ -1296,6 +1300,7 @@ struct ImGuiTreeNodeStackData ImRect NavRect; // Used for nav landing float DrawLinesX1; float DrawLinesY2; + ImGuiTableColumnIdx DrawLinesTableColumn; }; // sizeof() = 20 @@ -2704,11 +2709,7 @@ struct IMGUI_API ImGuiTabBar //----------------------------------------------------------------------------- #define IM_COL32_DISABLE IM_COL32(0,0,0,1) // Special sentinel code which cannot be used as a regular color. -#define IMGUI_TABLE_MAX_COLUMNS 512 // May be further lifted - -// Our current column maximum is 64 but we may raise that in the future. -typedef ImS16 ImGuiTableColumnIdx; -typedef ImU16 ImGuiTableDrawChannelIdx; +#define IMGUI_TABLE_MAX_COLUMNS 512 // Arbitrary "safety" maximum, may be lifted in the future if needed. Must fit in ImGuiTableColumnIdx/ImGuiTableDrawChannelIdx. // [Internal] sizeof() ~ 112 // We use the terminology "Enabled" to refer to a column that is not Hidden by user/api. @@ -3344,6 +3345,8 @@ namespace ImGui IMGUI_API float TableGetHeaderAngledMaxLabelWidth(); IMGUI_API void TablePushBackgroundChannel(); IMGUI_API void TablePopBackgroundChannel(); + IMGUI_API void TablePushColumnChannel(int column_n); + IMGUI_API void TablePopColumnChannel(); IMGUI_API void TableAngledHeadersRowEx(ImGuiID row_id, float angle, float max_label_width, const ImGuiTableHeaderData* data, int data_count); // Tables: Internals diff --git a/imgui_tables.cpp b/imgui_tables.cpp index a3d4a886b..6d4d673a1 100644 --- a/imgui_tables.cpp +++ b/imgui_tables.cpp @@ -2193,6 +2193,7 @@ void ImGui::TableBeginCell(ImGuiTable* table, int column_n) g.LastItemData.StatusFlags = 0; } + // Also see TablePushColumnChannel() if (table->Flags & ImGuiTableFlags_NoClip) { // FIXME: if we end up drawing all borders/bg in EndTable, could remove this and just assert that channel hasn't changed. @@ -2466,10 +2467,38 @@ void ImGui::TablePopBackgroundChannel() ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; ImGuiTable* table = g.CurrentTable; - ImGuiTableColumn* column = &table->Columns[table->CurrentColumn]; // Optimization: avoid PopClipRect() + SetCurrentChannel() SetWindowClipRectBeforeSetChannel(window, table->HostBackupInnerClipRect); + table->DrawSplitter->SetCurrentChannel(window->DrawList, table->Columns[table->CurrentColumn].DrawChannelCurrent); +} + +// Also see TableBeginCell() +void ImGui::TablePushColumnChannel(int column_n) +{ + ImGuiContext& g = *GImGui; + ImGuiTable* table = g.CurrentTable; + + // Optimization: avoid SetCurrentChannel() + PushClipRect() + if (table->Flags & ImGuiTableFlags_NoClip) + return; + ImGuiWindow* window = g.CurrentWindow; + const ImGuiTableColumn* column = &table->Columns[column_n]; + SetWindowClipRectBeforeSetChannel(window, column->ClipRect); + table->DrawSplitter->SetCurrentChannel(window->DrawList, column->DrawChannelCurrent); +} + +void ImGui::TablePopColumnChannel() +{ + ImGuiContext& g = *GImGui; + ImGuiTable* table = g.CurrentTable; + + // Optimization: avoid PopClipRect() + SetCurrentChannel() + if (table->Flags & ImGuiTableFlags_NoClip) + return; + ImGuiWindow* window = g.CurrentWindow; + const ImGuiTableColumn* column = &table->Columns[table->CurrentColumn]; + SetWindowClipRectBeforeSetChannel(window, column->ClipRect); table->DrawSplitter->SetCurrentChannel(window->DrawList, column->DrawChannelCurrent); } diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index bd56f509b..8d98dab6e 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -6562,7 +6562,9 @@ static void TreeNodeStoreStackData(ImGuiTreeNodeFlags flags, float x1) tree_node_data->NavRect = g.LastItemData.NavRect; // Initially I tried to latch value for GetColorU32(ImGuiCol_TreeLines) but it's not a good trade-off for very large trees. - tree_node_data->DrawLinesX1 = (flags & (ImGuiTreeNodeFlags_DrawLinesFull | ImGuiTreeNodeFlags_DrawLinesToNodes)) ? (x1 + g.FontSize * 0.5f + g.Style.FramePadding.x) : +FLT_MAX; + const bool draw_lines = (flags & (ImGuiTreeNodeFlags_DrawLinesFull | ImGuiTreeNodeFlags_DrawLinesToNodes)) != 0; + tree_node_data->DrawLinesX1 = draw_lines ? (x1 + g.FontSize * 0.5f + g.Style.FramePadding.x) : +FLT_MAX; + tree_node_data->DrawLinesTableColumn = draw_lines && g.CurrentTable ? (ImGuiTableColumnIdx)g.CurrentTable->CurrentColumn : -1; tree_node_data->DrawLinesY2 = -FLT_MAX; window->DC.TreeHasStackDataDepthMask |= (1 << window->DC.TreeDepth); } @@ -6919,7 +6921,11 @@ void ImGui::TreePop() if (y1 < y2) { float x = ImTrunc(data->DrawLinesX1); + if (data->DrawLinesTableColumn != -1) + TablePushColumnChannel(data->DrawLinesTableColumn); window->DrawList->AddLine(ImVec2(x, y1), ImVec2(x, y2), GetColorU32(ImGuiCol_TreeLines), g.Style.TreeLinesSize); + if (data->DrawLinesTableColumn != -1) + TablePopColumnChannel(); } } g.TreeNodeStack.pop_back();