Emit a column header (text + optional sort order) We cpu-clip text here so that all columns headers can be merged into a same draw call. Note that because of how we cpu-clip and display sorting indicators, you _cannot_ use SameLine() after a TableHeader()
| 2835 | // We cpu-clip text here so that all columns headers can be merged into a same draw call. |
| 2836 | // Note that because of how we cpu-clip and display sorting indicators, you _cannot_ use SameLine() after a TableHeader() |
| 2837 | void ImGui::TableHeader(const char* label) |
| 2838 | { |
| 2839 | ImGuiContext& g = *GImGui; |
| 2840 | ImGuiWindow* window = g.CurrentWindow; |
| 2841 | if (window->SkipItems) |
| 2842 | return; |
| 2843 | |
| 2844 | ImGuiTable* table = g.CurrentTable; |
| 2845 | IM_ASSERT(table != NULL && "Need to call TableHeader() after BeginTable()!"); |
| 2846 | IM_ASSERT(table->CurrentColumn != -1); |
| 2847 | const int column_n = table->CurrentColumn; |
| 2848 | ImGuiTableColumn* column = &table->Columns[column_n]; |
| 2849 | |
| 2850 | // Label |
| 2851 | if (label == NULL) |
| 2852 | label = ""; |
| 2853 | const char* label_end = FindRenderedTextEnd(label); |
| 2854 | ImVec2 label_size = CalcTextSize(label, label_end, true); |
| 2855 | ImVec2 label_pos = window->DC.CursorPos; |
| 2856 | |
| 2857 | // If we already got a row height, there's use that. |
| 2858 | // FIXME-TABLE: Padding problem if the correct outer-padding CellBgRect strays off our ClipRect? |
| 2859 | ImRect cell_r = TableGetCellBgRect(table, column_n); |
| 2860 | float label_height = ImMax(label_size.y, table->RowMinHeight - table->CellPaddingY * 2.0f); |
| 2861 | |
| 2862 | // Calculate ideal size for sort order arrow |
| 2863 | float w_arrow = 0.0f; |
| 2864 | float w_sort_text = 0.0f; |
| 2865 | char sort_order_suf[4] = ""; |
| 2866 | const float ARROW_SCALE = 0.65f; |
| 2867 | if ((table->Flags & ImGuiTableFlags_Sortable) && !(column->Flags & ImGuiTableColumnFlags_NoSort)) |
| 2868 | { |
| 2869 | w_arrow = ImFloor(g.FontSize * ARROW_SCALE + g.Style.FramePadding.x); |
| 2870 | if (column->SortOrder > 0) |
| 2871 | { |
| 2872 | ImFormatString(sort_order_suf, IM_ARRAYSIZE(sort_order_suf), "%d", column->SortOrder + 1); |
| 2873 | w_sort_text = g.Style.ItemInnerSpacing.x + CalcTextSize(sort_order_suf).x; |
| 2874 | } |
| 2875 | } |
| 2876 | |
| 2877 | // We feed our unclipped width to the column without writing on CursorMaxPos, so that column is still considering for merging. |
| 2878 | float max_pos_x = label_pos.x + label_size.x + w_sort_text + w_arrow; |
| 2879 | column->ContentMaxXHeadersUsed = ImMax(column->ContentMaxXHeadersUsed, column->WorkMaxX); |
| 2880 | column->ContentMaxXHeadersIdeal = ImMax(column->ContentMaxXHeadersIdeal, max_pos_x); |
| 2881 | |
| 2882 | // Keep header highlighted when context menu is open. |
| 2883 | const bool selected = (table->IsContextPopupOpen && table->ContextPopupColumn == column_n && table->InstanceInteracted == table->InstanceCurrent); |
| 2884 | ImGuiID id = window->GetID(label); |
| 2885 | ImRect bb(cell_r.Min.x, cell_r.Min.y, cell_r.Max.x, ImMax(cell_r.Max.y, cell_r.Min.y + label_height + g.Style.CellPadding.y * 2.0f)); |
| 2886 | ItemSize(ImVec2(0.0f, label_height)); // Don't declare unclipped width, it'll be fed ContentMaxPosHeadersIdeal |
| 2887 | if (!ItemAdd(bb, id)) |
| 2888 | return; |
| 2889 | |
| 2890 | //GetForegroundDrawList()->AddRect(cell_r.Min, cell_r.Max, IM_COL32(255, 0, 0, 255)); // [DEBUG] |
| 2891 | //GetForegroundDrawList()->AddRect(bb.Min, bb.Max, IM_COL32(255, 0, 0, 255)); // [DEBUG] |
| 2892 | |
| 2893 | // Using AllowItemOverlap mode because we cover the whole cell, and we want user to be able to submit subsequent items. |
| 2894 | bool hovered, held; |
nothing calls this directly
no test coverage detected