3#include "../arcdps_structs.h"
4#include "../ExtensionTranslations.h"
5#include "../ImGui_Math.h"
6#include "../Localization.h"
15#include <nlohmann/json.hpp>
22#pragma warning(disable : 4267)
23#pragma warning(disable : 4244)
26 static constexpr int TABLE_DRAW_CHANNEL_BG0 = 0;
27 static constexpr int TABLE_DRAW_CHANNEL_BG2_FROZEN = 1;
28 static constexpr int TABLE_DRAW_CHANNEL_NOCLIP = 2;
30 static constexpr float TABLE_BORDER_SIZE = 1.0f;
31 static constexpr float TABLE_RESIZE_SEPARATOR_HALF_THICKNESS = 4.0f;
32 static constexpr float TABLE_RESIZE_SEPARATOR_FEEDBACK_TIMER = 0.06f;
68 Popup(std::move(pName)) {}
71 requires std::is_enum_v<E> && std::convertible_to<std::underlying_type_t<E>, ImU32>
73 :
MainTableColumn(std::to_underlying(pUserId), std::move(pName), std::move(pTexture), std::move(pCategory), pDefaultVisibility) {}
77 Name(std::move(pName)),
81 Popup(std::move(pPopup)) {}
84 requires std::is_enum_v<E> && std::convertible_to<std::underlying_type_t<E>, ImU32>
86 :
MainTableColumn(std::to_underlying(pUserId), std::move(pName), std::move(pTexture), std::move(pCategory), std::move(pPopup), pDefaultVisibility) {}
98 requires T < std::numeric_limits<TableColumnIdx>::max();
126 template<
size_t MaxColumnCount = 64>
150 return mSpecificColumnsActive;
164 return UserID <=> pOther.
UserID;
168 return UserID <=> pOther;
180 nlohmann_json_j[
"WidthOrWeight"] = nlohmann_json_t.
WidthOrWeight;
181 nlohmann_json_j[
"UserID"] = nlohmann_json_t.
UserID;
182 nlohmann_json_j[
"DisplayOrder"] = nlohmann_json_t.
DisplayOrder;
183 nlohmann_json_j[
"SortOrder"] = nlohmann_json_t.
SortOrder;
184 nlohmann_json_j[
"SortDirection"] = nlohmann_json_t.
SortDirection;
185 nlohmann_json_j[
"IsEnabled"] = nlohmann_json_t.
IsEnabled;
186 nlohmann_json_j[
"IsStretch"] = nlohmann_json_t.
IsStretch;
190 nlohmann_json_j.at(
"WidthOrWeight").get_to(nlohmann_json_t.
WidthOrWeight);
191 nlohmann_json_j.at(
"UserID").get_to(nlohmann_json_t.
UserID);
192 nlohmann_json_j.at(
"DisplayOrder").get_to(nlohmann_json_t.
DisplayOrder);
193 nlohmann_json_j.at(
"SortOrder").get_to(nlohmann_json_t.
SortOrder);
194 nlohmann_json_t.
SortDirection = nlohmann_json_j.at(
"SortDirection").get<ImU8>();
195 nlohmann_json_t.
IsEnabled = nlohmann_json_j.at(
"IsEnabled").get<ImU8>();
196 nlohmann_json_t.
IsStretch = nlohmann_json_j.at(
"IsStretch").get<ImU8>();
217 virtual void Sort(
const ImGuiTableColumnSortSpecs* mColumnSortSpecs) = 0;
259 const std::vector<MainTableColumn>& mColumns;
261 std::atomic_bool mSortNeeded =
false;
265 std::vector<size_t> Indices;
266 std::map<size_t, Category> Categories;
268 Category mCategories;
270 void DrawColumnSetupMenuIteratorFunc(Category pCategory, std::string pCatName =
"");
272 std::atomic_bool mSpecificColumnsUpdate =
false;
273 bool mSpecificColumnsActive =
false;
274 std::vector<size_t> mSpecificColumnCache;
276 bool mCustomColumnsActiveTemp =
false;
283 void NextRow(ImGuiTableRowFlags row_flags = 0,
float min_row_height = 0.0f);
305 void SetupColumn(std::string_view label, ImGuiTableColumnFlags flags,
float init_width_or_weight, ImGuiID user_id);
306 void ColumnHeader(std::string_view label,
bool show_label, ImTextureID texture,
Alignment alignment, std::string_view popupText);
315 template<
typename... Args>
321 bool SpinnerAligned(
const char* label,
float radius,
float thickness,
const ImU32& color);
324 bool Begin(
const char* str_id,
int columns_count, ImGuiTableFlags flags,
const ImVec2& outer_size,
float inner_width, ImGuiWindowFlags child_window_flags);
396 memset(
this, 0,
sizeof(*
this));
522 memset(
static_cast<void*
>(
this), 0,
sizeof(*
this));
531 static ImGuiTableFlags TableFixFlags(ImGuiTableFlags flags, ImGuiWindow* outer_window);
541 void BeginInitMemory(
int columns_count);
544 void ResetSettings();
545 void LoadSettingsCustom();
546 void SaveSettingsCustom();
547 void MigrateIniSettings();
550 void BeginApplyRequests();
553 ImGuiTableSettings* GetBoundSettings();
561 void SortSpecsBuild();
564 void TableSetupColumnFlags(
TableColumn* column, ImGuiTableColumnFlags flags_in);
600 void MergeDrawChannels();
606 void SetupColumnFlags(
TableColumn* column, ImGuiTableColumnFlags flags_in);
609 float GetMaxColumnWidth(
int column_n);
627 void SetupDrawChannels();
633 void UpdateBorders();
635 void SortSpecsSanitize();
640 static ImGuiSortDirection GetColumnAvailSortDirection(
TableColumn* column,
int n) {
641 IM_ASSERT(n < column->SortDirectionsAvailCount);
648 ImGuiID GetColumnResizeID(
int column_n,
int instance_no) {
656 void SetColumnWidthAutoSingle(
int column_n) {
659 if (!column->IsEnabled)
661 column->CannotSkipItemsQueue = (1 << 0);
665 void BeginCell(
int column_n);
669 void SetBgColor(ImGuiTableBgTarget target, ImU32 color,
int column_n = -1);
673 void SetColumnSortDirection(
int column_n, ImGuiSortDirection sort_direction,
bool append_to_sort_specs);
678 IM_STATIC_ASSERT(ImGuiSortDirection_None == 0 && ImGuiSortDirection_Ascending == 1 && ImGuiSortDirection_Descending == 2);
679 ImGuiSortDirection GetColumnNextSortDirection(TableColumn* column);
682 void SetColumnWidth(
int column_n,
float width);
684 void UpdateColumnsWeightFromWidth();
687 template<
size_t MaxColumnCount>
688 requires SmallerThanMaxColumnAmount<MaxColumnCount>
690 : mMainWindow(pMainWindow), mColumns(pColumns), mFlags(pFlags) {
692 IM_ASSERT(mColumns.size() < MaxColumnCount);
697 for (
size_t i = 0; i < mColumns.size(); ++i) {
698 const auto& column = mColumns[i];
699 std::string cat = column.Category;
701 std::vector<size_t> token;
703 if ((pos = cat.find(
'.')) != std::string::npos) {
704 std::string sub = cat.substr(0, pos);
706 std::from_chars(sub.data(), sub.data() + sub.size(), dat);
707 token.push_back(dat);
708 cat.erase(0, pos + 1);
711 std::from_chars(cat.data(), cat.data() + cat.size(), dat);
712 token.push_back(dat);
718 mCategories.Indices.emplace_back(i);
722 Category* category = &mCategories;
723 for (
size_t tok : token) {
724 category = &category->Categories[tok];
727 category->Indices.emplace_back(i);
731 template<
size_t MaxColumnCount>
734 ImGuiTableFlags tableFlags = ImGuiTableFlags_BordersInnerH | ImGuiTableFlags_Hideable | ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_Sortable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_PadOuterX | ImGuiTableFlags_ScrollY;
736 if (getShowAlternatingBackground()) {
737 tableFlags |= ImGuiTableFlags_RowBg;
740 ImVec2 outerSize(0.f, getMaxHeightActive() ? mMainWindow->
GetMaxCursorPos() : 0.f);
742 if (Begin(getTableId().c_str(), mColumns.size(), tableFlags, outerSize, 0,
743 getShowScrollbar() ? 0 : ImGuiWindowFlags_NoScrollbar)) {
756 for (
int i = 0; i < mColumns.size(); ++i) {
757 const auto& column = mColumns[i];
759 ImGuiTableColumnFlags columnFlags = ImGuiTableColumnFlags_PreferSortDescending;
761 columnFlags |= ImGuiTableColumnFlags_IndentEnable;
763 if (!column.DefaultVisibility) {
764 columnFlags |= ImGuiTableColumnFlags_DefaultHide;
766 SetupColumn(column.Name(), columnFlags, 0, column.UserId);
770 SetupScrollFreeze(0, 1);
772 NextRow(ImGuiTableRowFlags_Headers);
774 for (
const auto& column : mColumns) {
776 ColumnHeader(column.Name(),
false, column.Texture(), getHeaderAlignment(), column.Popup());
783 if (ImGuiTableSortSpecs* sortSpecs = GetSortSpecs()) {
784 if (sortSpecs->SpecsDirty) {
788 bool expected =
true;
789 if (mSortNeeded.compare_exchange_strong(expected,
false)) {
790 Sort(sortSpecs->Specs);
792 sortSpecs->SpecsDirty =
false;
806 template<
size_t MaxColumnCount>
809 for (
const auto& index : pCategory.Indices) {
810 MenuItemColumnVisibility(index);
813 for (
const auto& [key, value] : pCategory.Categories) {
814 std::string catName = pCatName;
815 if (!catName.empty()) catName.append(
".");
816 catName.append(std::to_string(key));
817 if (ImGui::BeginMenu(getCategoryName(catName))) {
818 DrawColumnSetupMenuIteratorFunc(value, catName);
825 template<
size_t MaxColumnCount>
826 requires SmallerThanMaxColumnAmount<MaxColumnCount>
829 DrawColumnSetupSubMenu();
835 template<
size_t MaxColumnCount>
838 if (getCustomColumnsFeatureActive()) {
840 if (getCustomColumnsActive()) {
841 mSpecificColumnsUpdate =
true;
842 mSpecificColumnsActive =
true;
847 DrawColumnSetupMenuIteratorFunc(mCategories);
850 template<
size_t MaxColumnCount>
853 mSpecificColumnsUpdate =
true;
854 mSpecificColumnsActive =
true;
856 mSpecificColumnCache = pNewColumns;
859 template<
size_t MaxColumnCount>
862 mSpecificColumnsUpdate =
true;
863 mSpecificColumnsActive =
false;
866 template<
size_t MaxColumnCount>
873 int& maxDisplayed = getMaxDisplayed();
875 if (maxDisplayed < 0) {
883 template<
size_t MaxColumnCount>
905 template<
size_t MaxColumnCount>
923 template<
size_t MaxColumnCount>
926 if (mCurrentRow < getMaxDisplayed()) {
934 template<
size_t MaxColumnCount>
938 if ((flags & ImGuiTableFlags_SizingMask_) == 0)
939 flags |= ((flags & ImGuiTableFlags_ScrollX) || (outer_window->Flags & ImGuiWindowFlags_AlwaysAutoResize)) ? ImGuiTableFlags_SizingFixedFit : ImGuiTableFlags_SizingStretchSame;
942 if ((flags & ImGuiTableFlags_SizingMask_) == ImGuiTableFlags_SizingFixedSame)
943 flags |= ImGuiTableFlags_NoKeepColumnsVisible;
946 if (flags & ImGuiTableFlags_Resizable)
947 flags |= ImGuiTableFlags_BordersInnerV;
950 if (flags & (ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY))
951 flags &= ~(ImGuiTableFlags_NoHostExtendX | ImGuiTableFlags_NoHostExtendY);
954 if (flags & ImGuiTableFlags_NoBordersInBodyUntilResize)
955 flags &= ~ImGuiTableFlags_NoBordersInBody;
958 if ((flags & (ImGuiTableFlags_Resizable | ImGuiTableFlags_Hideable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Sortable)) == 0)
959 flags |= ImGuiTableFlags_NoSavedSettings;
963 ImGuiWindow* window_for_settings = outer_window->RootWindowDockStop;
965 ImGuiWindow* window_for_settings = outer_window->RootWindow;
967 if (window_for_settings->Flags & ImGuiWindowFlags_NoSavedSettings)
968 flags |= ImGuiTableFlags_NoSavedSettings;
973 template<
size_t MaxColumnCount>
974 requires SmallerThanMaxColumnAmount<MaxColumnCount>
975 void MainTable<MaxColumnCount>::BeginInitMemory(
int columns_count) {
977 ImSpanAllocator<3> span_allocator;
978 span_allocator.ReserveBytes(0, columns_count *
sizeof(TableColumn));
979 span_allocator.ReserveBytes(1, columns_count *
sizeof(
TableColumnIdx));
980 span_allocator.ReserveBytes(2, columns_count *
sizeof(ImGuiTableCellData));
981 mTable.
RawData = IM_ALLOC(span_allocator.GetArenaSizeInBytes());
982 memset(mTable.
RawData, 0, span_allocator.GetArenaSizeInBytes());
983 span_allocator.SetArenaBasePtr(mTable.
RawData);
984 span_allocator.GetSpan(0, &mTable.
Columns);
989 template<
size_t MaxColumnCount>
990 requires SmallerThanMaxColumnAmount<MaxColumnCount>
991 void MainTable<MaxColumnCount>::ResetSettings() {
998 template<
size_t MaxColumnCount>
999 requires SmallerThanMaxColumnAmount<MaxColumnCount>
1000 void MainTable<MaxColumnCount>::LoadSettingsCustom() {
1002 if (mTable.
Flags & ImGuiTableFlags_NoSavedSettings)
1005 TableSettings& settings = getTableSettings();
1008 if (settings.Version == 0) {
1009 MigrateIniSettings();
1010 settings.Version = 1;
1016 mTable.
RefScale = settings.RefScale;
1019 ColumnBitMask display_order_mask;
1020 for (
int idx = 0; idx < mTable.
Columns.size(); ++idx) {
1021 TableColumn* column = &mTable.
Columns[idx];
1024 column->UserID = mColumns[idx].UserId;
1026 const auto& column_settings = std::find(settings.Columns.begin(), settings.Columns.end(), column->UserID);
1027 if (column_settings == settings.Columns.end()) {
1031 if (settings.SaveFlags & ImGuiTableFlags_Resizable) {
1032 if (column_settings->IsStretch)
1033 column->StretchWeight = column_settings->WidthOrWeight;
1035 column->WidthRequest = column_settings->WidthOrWeight;
1036 column->AutoFitQueue = 0x00;
1038 if (settings.SaveFlags & ImGuiTableFlags_Reorderable)
1039 column->DisplayOrder = column_settings->DisplayOrder;
1042 if (column->DisplayOrder >= 0) display_order_mask.set(column->DisplayOrder);
1043 column->IsEnabled = column->IsEnabledNextFrame = column_settings->IsEnabled;
1044 column->SortOrder = column_settings->SortOrder;
1045 column->SortDirection = column_settings->SortDirection;
1049 if (display_order_mask.count() != settings.Columns.size())
1050 for (
int column_n = 0; column_n < mTable.
ColumnsCount; column_n++)
1054 for (
int column_n = 0; column_n < mTable.
ColumnsCount; column_n++)
1058 template<
size_t MaxColumnCount>
1059 requires SmallerThanMaxColumnAmount<MaxColumnCount>
1060 void MainTable<MaxColumnCount>::BeginApplyRequests() {
1091 IM_ASSERT(reorder_dir == -1 || reorder_dir == +1);
1092 IM_ASSERT(mTable.
Flags & ImGuiTableFlags_Reorderable);
1094 TableColumn* dst_column = &mTable.
Columns[(reorder_dir == -1) ? src_column->PrevEnabledColumn : src_column->NextEnabledColumn];
1095 IM_UNUSED(dst_column);
1096 const int src_order = src_column->DisplayOrder;
1097 const int dst_order = dst_column->DisplayOrder;
1099 for (
int order_n = src_order + reorder_dir; order_n != dst_order + reorder_dir; order_n += reorder_dir)
1101 IM_ASSERT(dst_column->DisplayOrder == dst_order - reorder_dir);
1105 for (
int column_n = 0; column_n < mTable.
ColumnsCount; column_n++)
1121 template<
size_t MaxColumnCount>
1122 requires SmallerThanMaxColumnAmount<MaxColumnCount>
1123 ImGuiTableSettings* MainTable<MaxColumnCount>::GetBoundSettings() {
1125 ImGuiContext& g = *GImGui;
1126 ImGuiTableSettings* settings = g.SettingsTables.ptr_from_offset(mTable.
SettingsOffset);
1127 IM_ASSERT(settings->ID == mTable.
ID);
1135 template<
size_t MaxColumnCount>
1136 requires SmallerThanMaxColumnAmount<MaxColumnCount>
1137 void MainTable<MaxColumnCount>::UpdateLayout() {
1138 ImGuiContext& g = *GImGui;
1141 const ImGuiTableFlags table_sizing_policy = (mTable.
Flags & ImGuiTableFlags_SizingMask_);
1146 mTable.
MinColumnWidth = ImMax(1.0f, g.Style.FramePadding.x * 1.0f);
1150 int count_fixed = 0;
1151 int count_stretch = 0;
1152 int last_visible_column_idx = -1;
1153 bool has_auto_fit_request =
false;
1154 bool has_resizable =
false;
1155 float stretch_sum_width_auto = 0.0f;
1156 float fixed_max_width_auto = 0.0f;
1157 for (
int order_n = 0; order_n < mTable.
ColumnsCount; order_n++) {
1159 if (column_n != order_n)
1161 TableColumn* column = &mTable.
Columns[column_n];
1167 SetupColumnFlags(column, ImGuiTableColumnFlags_None);
1168 column->NameOffset = -1;
1170 column->InitStretchWeightOrWidth = -1.0f;
1174 if (!(mTable.
Flags & ImGuiTableFlags_Hideable) || (column->Flags & ImGuiTableColumnFlags_NoHide))
1175 column->IsEnabledNextFrame =
true;
1176 if (column->IsEnabled != column->IsEnabledNextFrame) {
1177 column->IsEnabled = column->IsEnabledNextFrame;
1179 if (!column->IsEnabled && column->SortOrder != -1)
1182 if (column->SortOrder > 0 && !(mTable.
Flags & ImGuiTableFlags_SortMulti))
1186 const bool start_auto_fit = (column->Flags & ImGuiTableColumnFlags_WidthFixed) ? (column->WidthRequest < 0.0f) : (column->StretchWeight < 0.0f);
1188 column->AutoFitQueue = column->CannotSkipItemsQueue = (1 << 3) - 1;
1190 if (!column->IsEnabled) {
1191 column->IndexWithinEnabledSet = -1;
1196 column->PrevEnabledColumn = (
TableColumnIdx) last_visible_column_idx;
1197 column->NextEnabledColumn = -1;
1198 if (last_visible_column_idx != -1)
1203 last_visible_column_idx = column_n;
1204 IM_ASSERT(column->IndexWithinEnabledSet <= column->DisplayOrder);
1208 if (!column->IsPreserveWidthAuto)
1209 column->WidthAuto = GetColumnWidthAuto(column);
1212 const bool column_is_resizable = (column->Flags & ImGuiTableColumnFlags_NoResize) == 0;
1213 if (column_is_resizable)
1214 has_resizable =
true;
1215 if ((column->Flags & ImGuiTableColumnFlags_WidthFixed) && column->InitStretchWeightOrWidth > 0.0f && !column_is_resizable)
1216 column->WidthAuto = column->InitStretchWeightOrWidth;
1218 if (column->AutoFitQueue != 0x00)
1219 has_auto_fit_request =
true;
1220 if (column->Flags & ImGuiTableColumnFlags_WidthStretch) {
1221 stretch_sum_width_auto += column->WidthAuto;
1224 fixed_max_width_auto = ImMax(fixed_max_width_auto, column->WidthAuto);
1228 if ((mTable.
Flags & ImGuiTableFlags_Sortable) && mTable.
SortSpecsCount == 0 && !(mTable.
Flags & ImGuiTableFlags_SortTristate))
1238 if (has_auto_fit_request)
1242 float sum_width_requests = 0.0f;
1243 float stretch_sum_weights = 0.0f;
1245 for (
int column_n = 0; column_n < mTable.
ColumnsCount; column_n++) {
1248 TableColumn* column = &mTable.
Columns[column_n];
1250 const bool column_is_resizable = (column->Flags & ImGuiTableColumnFlags_NoResize) == 0;
1251 if (column->Flags & ImGuiTableColumnFlags_WidthFixed) {
1253 float width_auto = column->WidthAuto;
1254 if (table_sizing_policy == ImGuiTableFlags_SizingFixedSame && (column->AutoFitQueue != 0x00 || !column_is_resizable))
1255 width_auto = fixed_max_width_auto;
1259 if (column->AutoFitQueue != 0x00)
1260 column->WidthRequest = width_auto;
1261 else if ((column->Flags & ImGuiTableColumnFlags_WidthFixed) && !column_is_resizable && mTable.
RequestOutputMaskByIndex.test(column_n))
1262 column->WidthRequest = width_auto;
1270 if (column->AutoFitQueue > 0x01 && mTable.
IsInitializing && !column->IsPreserveWidthAuto)
1271 column->WidthRequest = ImMax(column->WidthRequest, mTable.
MinColumnWidth * 4.0f);
1272 sum_width_requests += column->WidthRequest;
1275 if (column->AutoFitQueue != 0x00 || column->StretchWeight < 0.0f || !column_is_resizable) {
1276 if (column->InitStretchWeightOrWidth > 0.0f)
1277 column->StretchWeight = column->InitStretchWeightOrWidth;
1278 else if (table_sizing_policy == ImGuiTableFlags_SizingStretchProp)
1279 column->StretchWeight = (column->WidthAuto / stretch_sum_width_auto) * count_stretch;
1281 column->StretchWeight = 1.0f;
1284 stretch_sum_weights += column->StretchWeight;
1290 column->IsPreserveWidthAuto =
false;
1296 const ImRect work_rect = mTable.
WorkRect;
1298 const float width_avail = ((mTable.
Flags & ImGuiTableFlags_ScrollX) && mTable.
InnerWidth == 0.0f) ? mTable.
InnerClipRect.GetWidth() : work_rect.GetWidth();
1299 const float width_avail_for_stretched_columns = width_avail - width_spacings - sum_width_requests;
1300 float width_remaining_for_stretched_columns = width_avail_for_stretched_columns;
1302 for (
int column_n = 0; column_n < mTable.
ColumnsCount; column_n++) {
1305 TableColumn* column = &mTable.
Columns[column_n];
1308 if (column->Flags & ImGuiTableColumnFlags_WidthStretch) {
1309 float weight_ratio = column->StretchWeight / stretch_sum_weights;
1310 column->WidthRequest = IM_FLOOR(ImMax(width_avail_for_stretched_columns * weight_ratio, mTable.
MinColumnWidth) + 0.01f);
1311 width_remaining_for_stretched_columns -= column->WidthRequest;
1317 column->Flags |= ImGuiTableColumnFlags_NoDirectResize_;
1320 column->WidthGiven = ImFloor(ImMax(column->WidthRequest, mTable.
MinColumnWidth));
1326 if (width_remaining_for_stretched_columns >= 1.0f && !(mTable.
Flags & ImGuiTableFlags_PreciseWidths))
1327 for (
int order_n = mTable.
ColumnsCount - 1; stretch_sum_weights > 0.0f && width_remaining_for_stretched_columns >= 1.0f && order_n >= 0; order_n--) {
1331 if (!(column->Flags & ImGuiTableColumnFlags_WidthStretch))
1333 column->WidthRequest += 1.0f;
1334 column->WidthGiven += 1.0f;
1335 width_remaining_for_stretched_columns -= 1.0f;
1341 const bool is_hovering_table = ImGui::ItemHoverable(mouse_hit_rect, 0);
1347 float offset_x = ((mTable.
FreezeColumnsCount > 0) ? mTable.
OuterRect.Min.x : work_rect.Min.x) + mTable.OuterPaddingX - mTable.CellSpacingX1;
1352 for (
int order_n = 0; order_n < mTable.
ColumnsCount; order_n++) {
1354 TableColumn* column = &mTable.
Columns[column_n];
1359 offset_x += work_rect.Min.x - mTable.
OuterRect.Min.x;
1360 offset_x_frozen =
false;
1364 column->Flags &= ~ImGuiTableColumnFlags_StatusMask_;
1369 column->MinX = column->MaxX = column->WorkMinX = column->ClipRect.Min.x = column->ClipRect.Max.x = offset_x;
1370 column->WidthGiven = 0.0f;
1371 column->ClipRect.Min.y = work_rect.Min.y;
1372 column->ClipRect.Max.y = FLT_MAX;
1373 column->ClipRect.ClipWithFull(host_clip_rect);
1374 column->IsVisibleX = column->IsVisibleY = column->IsRequestOutput =
false;
1375 column->IsSkipItems =
true;
1376 column->ItemWidth = 1.0f;
1381 if (is_hovering_table && g.IO.MousePos.x >= column->ClipRect.Min.x && g.IO.MousePos.x < column->ClipRect.Max.x)
1385 column->MinX = offset_x;
1388 float max_width = GetMaxColumnWidth(column_n);
1389 column->WidthGiven = ImMin(column->WidthGiven, max_width);
1390 column->WidthGiven = ImMax(column->WidthGiven, ImMin(column->WidthRequest, mTable.
MinColumnWidth));
1400 column->ItemWidth = ImFloor(column->WidthGiven * 0.65f);
1401 column->ClipRect.Min.x = column->MinX;
1402 column->ClipRect.Min.y = work_rect.Min.y;
1403 column->ClipRect.Max.x = column->MaxX;
1404 column->ClipRect.Max.y = FLT_MAX;
1405 column->ClipRect.ClipWithFull(host_clip_rect);
1414 column->IsVisibleX = (column->ClipRect.Max.x > column->ClipRect.Min.x);
1415 column->IsVisibleY =
true;
1416 const bool is_visible = column->IsVisibleX;
1421 column->IsRequestOutput = is_visible || column->AutoFitQueue != 0 || column->CannotSkipItemsQueue != 0;
1422 if (column->IsRequestOutput)
1426 column->IsSkipItems = !column->IsEnabled || mTable.
HostSkipItems;
1427 if (column->IsSkipItems)
1428 IM_ASSERT(!is_visible);
1431 column->Flags |= ImGuiTableColumnFlags_IsEnabled;
1433 column->Flags |= ImGuiTableColumnFlags_IsVisible;
1434 if (column->SortOrder != -1)
1435 column->Flags |= ImGuiTableColumnFlags_IsSorted;
1437 column->Flags |= ImGuiTableColumnFlags_IsHovered;
1449 column->ContentMaxXFrozen = column->ContentMaxXUnfrozen = column->WorkMinX;
1450 column->ContentMaxXHeadersUsed = column->ContentMaxXHeadersIdeal = column->WorkMinX;
1454 column->AutoFitQueue >>= 1;
1455 column->CannotSkipItemsQueue >>= 1;
1459 host_clip_rect.Min.x = ImClamp(column->MaxX + TABLE_BORDER_SIZE, host_clip_rect.Min.x, host_clip_rect.Max.x);
1470 if (g.IO.MousePos.x >= unused_x1)
1473 if (has_resizable ==
false && (mTable.
Flags & ImGuiTableFlags_Resizable))
1474 mTable.
Flags &= ~ImGuiTableFlags_Resizable;
1480 mTable.
Flags &= ~ImGuiTableFlags_NoHostExtendX;
1481 if (mTable.
Flags & ImGuiTableFlags_NoHostExtendX) {
1490 SetupDrawChannels();
1493 if (mTable.
Flags & ImGuiTableFlags_Resizable)
1522 if (mTable.
Flags & ImGuiTableFlags_NoClip)
1523 mTable.
DrawSplitter.SetCurrentChannel(inner_window->DrawList, TABLE_DRAW_CHANNEL_NOCLIP);
1525 inner_window->DrawList->PushClipRect(inner_window->ClipRect.Min, inner_window->ClipRect.Max,
false);
1528 template<
size_t MaxColumnCount>
1529 requires SmallerThanMaxColumnAmount<MaxColumnCount>
1530 void MainTable<MaxColumnCount>::SortSpecsBuild() {
1532 SortSpecsSanitize();
1536 ImGuiTableColumnSortSpecs* sort_specs = (mTable.
SortSpecsCount == 0) ? NULL : (mTable.SortSpecsCount == 1) ? &mTable.SortSpecsSingle
1537 : mTable.SortSpecsMulti.Data;
1538 for (
int column_n = 0; column_n < mTable.
ColumnsCount; column_n++) {
1539 TableColumn* column = &mTable.
Columns[column_n];
1540 if (column->SortOrder == -1)
1543 ImGuiTableColumnSortSpecs* sort_spec = &sort_specs[column->SortOrder];
1544 sort_spec->ColumnUserID = column->UserID;
1547 sort_spec->SortDirection = column->SortDirection;
1555 template<
size_t MaxColumnCount>
1556 requires SmallerThanMaxColumnAmount<MaxColumnCount>
1557 void MainTable<MaxColumnCount>::TableSetupColumnFlags(TableColumn* column, ImGuiTableColumnFlags flags_in) {
1558 ImGuiTableColumnFlags flags = flags_in;
1561 if ((flags & ImGuiTableColumnFlags_WidthMask_) == 0) {
1562 const ImGuiTableFlags table_sizing_policy = (mTable.
Flags & ImGuiTableFlags_SizingMask_);
1563 if (table_sizing_policy == ImGuiTableFlags_SizingFixedFit || table_sizing_policy == ImGuiTableFlags_SizingFixedSame)
1564 flags |= ImGuiTableColumnFlags_WidthFixed;
1566 flags |= ImGuiTableColumnFlags_WidthStretch;
1568 IM_ASSERT(ImIsPowerOfTwo(flags & ImGuiTableColumnFlags_WidthMask_));
1572 if ((mTable.
Flags & ImGuiTableFlags_Resizable) == 0)
1573 flags |= ImGuiTableColumnFlags_NoResize;
1576 if ((flags & ImGuiTableColumnFlags_NoSortAscending) && (flags & ImGuiTableColumnFlags_NoSortDescending))
1577 flags |= ImGuiTableColumnFlags_NoSort;
1580 if ((flags & ImGuiTableColumnFlags_IndentMask_) == 0)
1581 flags |= (mTable.
Columns.index_from_ptr(column) == 0) ? ImGuiTableColumnFlags_IndentEnable : ImGuiTableColumnFlags_IndentDisable;
1589 column->Flags = flags | (column->Flags & ImGuiTableColumnFlags_StatusMask_);
1592 column->SortDirectionsAvailCount = column->SortDirectionsAvailMask = column->SortDirectionsAvailList = 0;
1593 if (mTable.
Flags & ImGuiTableFlags_Sortable) {
1594 int count = 0, mask = 0, list = 0;
1595 if ((flags & ImGuiTableColumnFlags_PreferSortAscending) != 0 && (flags & ImGuiTableColumnFlags_NoSortAscending) == 0) {
1596 mask |= 1 << ImGuiSortDirection_Ascending;
1597 list |= ImGuiSortDirection_Ascending << (count << 1);
1600 if ((flags & ImGuiTableColumnFlags_PreferSortDescending) != 0 && (flags & ImGuiTableColumnFlags_NoSortDescending) == 0) {
1601 mask |= 1 << ImGuiSortDirection_Descending;
1602 list |= ImGuiSortDirection_Descending << (count << 1);
1605 if ((flags & ImGuiTableColumnFlags_PreferSortAscending) == 0 && (flags & ImGuiTableColumnFlags_NoSortAscending) == 0) {
1606 mask |= 1 << ImGuiSortDirection_Ascending;
1607 list |= ImGuiSortDirection_Ascending << (count << 1);
1610 if ((flags & ImGuiTableColumnFlags_PreferSortDescending) == 0 && (flags & ImGuiTableColumnFlags_NoSortDescending) == 0) {
1611 mask |= 1 << ImGuiSortDirection_Descending;
1612 list |= ImGuiSortDirection_Descending << (count << 1);
1615 if ((mTable.
Flags & ImGuiTableFlags_SortTristate) || count == 0) {
1616 mask |= 1 << ImGuiSortDirection_None;
1619 column->SortDirectionsAvailList = (ImU8) list;
1620 column->SortDirectionsAvailMask = (ImU8) mask;
1621 column->SortDirectionsAvailCount = (ImU8) count;
1622 FixColumnSortDirection(column);
1626 template<
size_t MaxColumnCount>
1627 requires SmallerThanMaxColumnAmount<MaxColumnCount>
1628 void MainTable<MaxColumnCount>::EndRow() {
1629 ImGuiContext& g = *GImGui;
1630 ImGuiWindow* window = g.CurrentWindow;
1639 window->DC.CursorPos.y = mTable.
RowPosY2;
1642 const float bg_y1 = mTable.
RowPosY1;
1643 const float bg_y2 = mTable.
RowPosY2;
1654 if (mTable.
RowBgColor[0] != IM_COL32_DISABLE)
1656 else if (mTable.
Flags & ImGuiTableFlags_RowBg)
1657 bg_col0 = ImGui::GetColorU32((mTable.
RowBgColorCounter & 1) ? ImGuiCol_TableRowBgAlt : ImGuiCol_TableRowBg);
1658 if (mTable.
RowBgColor[1] != IM_COL32_DISABLE)
1662 ImRect row_rect(mTable.
WorkRect.Min.x, bg_y1, mTable.
WorkRect.Max.x, bg_y2);
1668 if (ImGui::IsWindowHovered() && ImGui::IsMouseHoveringRect(row_rect.Min, row_rect.Max,
false) && (mTable.
CurrentRow > 0 && mTable.
IsUsingHeaders)) {
1671 if (getHighlightHoveredRows()) {
1672 bg_col1 = ImGui::GetColorU32(ImGuiCol_FrameBgHovered);
1680 ImU32 border_col = 0;
1681 const float border_size = TABLE_BORDER_SIZE;
1683 if (mTable.
Flags & ImGuiTableFlags_BordersInnerH)
1687 const bool draw_strong_bottom_border = unfreeze_rows_actual;
1688 if ((bg_col0 | bg_col1 | border_col) != 0 || draw_strong_bottom_border || draw_cell_bg_color) {
1691 if ((mTable.
Flags & ImGuiTableFlags_NoClip) == 0)
1693 mTable.
DrawSplitter.SetCurrentChannel(window->DrawList, TABLE_DRAW_CHANNEL_BG0);
1698 if (bg_col0 || bg_col1) {
1699 if (bg_col0 != 0 && row_rect.Min.y < row_rect.Max.y)
1700 window->DrawList->AddRectFilled(row_rect.Min, row_rect.Max, bg_col0);
1701 if (bg_col1 != 0 && row_rect.Min.y < row_rect.Max.y)
1702 window->DrawList->AddRectFilled(row_rect.Min, row_rect.Max, bg_col1);
1706 if (draw_cell_bg_color) {
1708 for (ImGuiTableCellData* cell_data = &mTable.
RowCellData[0]; cell_data <= cell_data_end; cell_data++) {
1709 const TableColumn* column = &mTable.
Columns[cell_data->Column];
1710 ImRect cell_bg_rect = GetCellBgRect(cell_data->Column);
1712 cell_bg_rect.Min.x = ImMax(cell_bg_rect.Min.x, column->ClipRect.Min.x);
1713 cell_bg_rect.Max.x = ImMin(cell_bg_rect.Max.x, column->MaxX);
1714 window->DrawList->AddRectFilled(cell_bg_rect.Min, cell_bg_rect.Max, cell_data->BgColor);
1720 window->DrawList->AddLine(ImVec2(mTable.
BorderX1, bg_y1), ImVec2(mTable.
BorderX2, bg_y1), border_col, border_size);
1723 if (draw_strong_bottom_border && bg_y2 >= mTable.
BgClipRect.Min.y && bg_y2 < mTable.
BgClipRect.Max.y)
1730 if (unfreeze_rows_request)
1731 for (
int column_n = 0; column_n < mTable.
ColumnsCount; column_n++) {
1732 TableColumn* column = &mTable.
Columns[column_n];
1733 column->NavLayerCurrent = (ImS8) ((column_n < mTable.
FreezeColumnsCount) ? ImGuiNavLayer_Menu : ImGuiNavLayer_Main);
1735 if (unfreeze_rows_actual) {
1740 float y0 = ImMax(mTable.
RowPosY2 + 1, window->InnerClipRect.Min.y);
1749 for (
int column_n = 0; column_n < mTable.
ColumnsCount; column_n++) {
1750 TableColumn* column = &mTable.
Columns[column_n];
1751 column->DrawChannelCurrent = column->DrawChannelUnfrozen;
1756 ImGui::SetWindowClipRectBeforeSetChannel(window, mTable.
Columns[0].ClipRect);
1757 mTable.
DrawSplitter.SetCurrentChannel(window->DrawList, mTable.
Columns[0].DrawChannelCurrent);
1760 if (!(mTable.
RowFlags & ImGuiTableRowFlags_Headers))
1765 template<
size_t MaxColumnCount>
1766 requires SmallerThanMaxColumnAmount<MaxColumnCount>
1767 void MainTable<MaxColumnCount>::DrawBorders() {
1772 ImDrawList* inner_drawlist = inner_window->DrawList;
1773 mTable.
DrawSplitter.SetCurrentChannel(inner_drawlist, TABLE_DRAW_CHANNEL_BG0);
1777 const float border_size = TABLE_BORDER_SIZE;
1778 const float draw_y1 = mTable.
InnerRect.Min.y;
1779 const float draw_y2_body = mTable.
InnerRect.Max.y;
1781 if (mTable.
Flags & ImGuiTableFlags_BordersInnerV) {
1782 for (
int order_n = 0; order_n < mTable.
ColumnsCount; order_n++) {
1787 TableColumn* column = &mTable.
Columns[column_n];
1790 const bool is_resizable = (column->Flags & (ImGuiTableColumnFlags_NoResize | ImGuiTableColumnFlags_NoDirectResize_)) == 0;
1792 if (column->MaxX > mTable.
InnerClipRect.Max.x && !is_resized)
1796 if (column->NextEnabledColumn == -1 && !is_resizable)
1797 if ((mTable.
Flags & ImGuiTableFlags_SizingMask_) != ImGuiTableFlags_SizingFixedSame || (mTable.
Flags & ImGuiTableFlags_NoHostExtendX))
1799 if (column->MaxX <= column->ClipRect.Min.x)
1806 if (is_hovered || is_resized || is_frozen_separator) {
1807 draw_y2 = draw_y2_body;
1808 col = is_resized ? ImGui::GetColorU32(ImGuiCol_SeparatorActive) : is_hovered ?
ImGui::GetColorU32(ImGuiCol_SeparatorHovered)
1809 : mTable.BorderColorStrong;
1811 draw_y2 = (mTable.
Flags & (ImGuiTableFlags_NoBordersInBody | ImGuiTableFlags_NoBordersInBodyUntilResize)) ? draw_y2_head : draw_y2_body;
1815 if (draw_y2 > draw_y1)
1816 inner_drawlist->AddLine(ImVec2(column->MaxX, draw_y1), ImVec2(column->MaxX, draw_y2), col, border_size);
1822 if (mTable.
Flags & ImGuiTableFlags_BordersOuter) {
1828 const ImRect outer_border = mTable.
OuterRect;
1830 if ((mTable.
Flags & ImGuiTableFlags_BordersOuter) == ImGuiTableFlags_BordersOuter) {
1831 inner_drawlist->AddRect(outer_border.Min, outer_border.Max, outer_col, 0.0f, ~0, border_size);
1832 }
else if (mTable.
Flags & ImGuiTableFlags_BordersOuterV) {
1833 inner_drawlist->AddLine(outer_border.Min, ImVec2(outer_border.Min.x, outer_border.Max.y), outer_col, border_size);
1834 inner_drawlist->AddLine(ImVec2(outer_border.Max.x, outer_border.Min.y), outer_border.Max, outer_col, border_size);
1835 }
else if (mTable.
Flags & ImGuiTableFlags_BordersOuterH) {
1836 inner_drawlist->AddLine(outer_border.Min, ImVec2(outer_border.Max.x, outer_border.Min.y), outer_col, border_size);
1837 inner_drawlist->AddLine(ImVec2(outer_border.Min.x, outer_border.Max.y), outer_border.Max, outer_col, border_size);
1842 const float border_y = mTable.
RowPosY2;
1847 inner_drawlist->PopClipRect();
1850 template<
size_t MaxColumnCount>
1851 requires SmallerThanMaxColumnAmount<MaxColumnCount>
1852 void MainTable<MaxColumnCount>::MergeDrawChannels() {
1853 ImGuiContext& g = *GImGui;
1857 IM_ASSERT(splitter->_Current == 0);
1863 ImBitArray<IMGUI_TABLE_MAX_DRAW_CHANNELS> ChannelsMask;
1865 int merge_group_mask = 0x00;
1866 MergeGroup merge_groups[4];
1867 memset(merge_groups, 0,
sizeof(merge_groups));
1870 for (
int column_n = 0; column_n < mTable.
ColumnsCount; column_n++) {
1873 TableColumn* column = &mTable.
Columns[column_n];
1875 const int merge_group_sub_count = has_freeze_v ? 2 : 1;
1876 for (
int merge_group_sub_n = 0; merge_group_sub_n < merge_group_sub_count; merge_group_sub_n++) {
1877 const int channel_no = (merge_group_sub_n == 0) ? column->DrawChannelFrozen : column->DrawChannelUnfrozen;
1880 ImDrawChannel* src_channel = &splitter->_Channels[channel_no];
1881 if (src_channel->_CmdBuffer.Size > 0 && src_channel->_CmdBuffer.back().ElemCount == 0)
1882 src_channel->_CmdBuffer.pop_back();
1883 if (src_channel->_CmdBuffer.Size != 1)
1888 if (!(column->Flags & ImGuiTableColumnFlags_NoClip)) {
1889 float content_max_x;
1891 content_max_x = ImMax(column->ContentMaxXUnfrozen, column->ContentMaxXHeadersUsed);
1892 else if (merge_group_sub_n == 0)
1893 content_max_x = ImMax(column->ContentMaxXFrozen, column->ContentMaxXHeadersUsed);
1895 content_max_x = column->ContentMaxXUnfrozen;
1896 if (content_max_x > column->ClipRect.Max.x)
1900 const int merge_group_n = (has_freeze_h && column_n < mTable.
FreezeColumnsCount ? 0 : 1) + (has_freeze_v && merge_group_sub_n == 0 ? 0 : 2);
1901 IM_ASSERT(channel_no < IMGUI_TABLE_MAX_DRAW_CHANNELS);
1902 MergeGroup* merge_group = &merge_groups[merge_group_n];
1903 if (merge_group->ChannelsCount == 0)
1904 merge_group->ClipRect = ImRect(+FLT_MAX, +FLT_MAX, -FLT_MAX, -FLT_MAX);
1905 merge_group->ChannelsMask.SetBit(channel_no);
1906 merge_group->ChannelsCount++;
1907 merge_group->ClipRect.Add(src_channel->_CmdBuffer[0].ClipRect);
1908 merge_group_mask |= (1 << merge_group_n);
1913 column->DrawChannelCurrent = (ImGuiTableDrawChannelIdx) -1;
1917 if (merge_group_mask != 0) {
1919 const int LEADING_DRAW_CHANNELS = 2;
1920 g.DrawChannelsTempMergeBuffer.resize(splitter->_Count - LEADING_DRAW_CHANNELS);
1921 ImDrawChannel* dst_tmp = g.DrawChannelsTempMergeBuffer.Data;
1922 ImBitArray<IMGUI_TABLE_MAX_DRAW_CHANNELS> remaining_mask;
1923 remaining_mask.ClearAllBits();
1924 remaining_mask.SetBitRange(LEADING_DRAW_CHANNELS, splitter->_Count);
1927 int remaining_count = splitter->_Count - (has_freeze_v ? LEADING_DRAW_CHANNELS + 1 : LEADING_DRAW_CHANNELS);
1930 for (
int merge_group_n = 0; merge_group_n < IM_ARRAYSIZE(merge_groups); merge_group_n++) {
1931 if (
int merge_channels_count = merge_groups[merge_group_n].ChannelsCount) {
1932 MergeGroup* merge_group = &merge_groups[merge_group_n];
1933 ImRect merge_clip_rect = merge_group->ClipRect;
1942 if ((merge_group_n & 1) == 0 || !has_freeze_h)
1943 merge_clip_rect.Min.x = ImMin(merge_clip_rect.Min.x, host_rect.Min.x);
1944 if ((merge_group_n & 2) == 0 || !has_freeze_v)
1945 merge_clip_rect.Min.y = ImMin(merge_clip_rect.Min.y, host_rect.Min.y);
1946 if ((merge_group_n & 1) != 0)
1947 merge_clip_rect.Max.x = ImMax(merge_clip_rect.Max.x, host_rect.Max.x);
1948 if ((merge_group_n & 2) != 0 && (mTable.
Flags & ImGuiTableFlags_NoHostExtendY) == 0)
1949 merge_clip_rect.Max.y = ImMax(merge_clip_rect.Max.y, host_rect.Max.y);
1951 remaining_count -= merge_group->ChannelsCount;
1952 for (
int n = 0; n < IM_ARRAYSIZE(remaining_mask.Storage); n++)
1953 remaining_mask.Storage[n] &= ~merge_group->ChannelsMask.Storage[n];
1954 for (
int n = 0; n < splitter->_Count && merge_channels_count != 0; n++) {
1956 if (!merge_group->ChannelsMask.TestBit(n))
1958 merge_group->ChannelsMask.ClearBit(n);
1959 merge_channels_count--;
1961 ImDrawChannel* channel = &splitter->_Channels[n];
1962 IM_ASSERT(channel->_CmdBuffer.Size == 1 && merge_clip_rect.Contains(ImRect(channel->_CmdBuffer[0].ClipRect)));
1963 channel->_CmdBuffer[0].ClipRect = merge_clip_rect.ToVec4();
1964 memcpy(
static_cast<void*
>(dst_tmp++), channel,
sizeof(ImDrawChannel));
1969 if (merge_group_n == 1 && has_freeze_v)
1970 memcpy(
static_cast<void*
>(dst_tmp++), &splitter->_Channels[mTable.
Bg2DrawChannelUnfrozen],
sizeof(ImDrawChannel));
1974 for (
int n = 0; n < splitter->_Count && remaining_count != 0; n++) {
1975 if (!remaining_mask.TestBit(n))
1977 ImDrawChannel* channel = &splitter->_Channels[n];
1978 memcpy(
static_cast<void*
>(dst_tmp++), channel,
sizeof(ImDrawChannel));
1981 IM_ASSERT(dst_tmp == g.DrawChannelsTempMergeBuffer.Data + g.DrawChannelsTempMergeBuffer.Size);
1982 memcpy(
static_cast<void*
>(splitter->_Channels.Data + LEADING_DRAW_CHANNELS), g.DrawChannelsTempMergeBuffer.Data, (splitter->_Count - LEADING_DRAW_CHANNELS) *
sizeof(ImDrawChannel));
1986 template<
size_t MaxColumnCount>
1987 requires SmallerThanMaxColumnAmount<MaxColumnCount>
1988 float MainTable<MaxColumnCount>::GetColumnWidthAuto(TableColumn* column) {
1989 const float content_width_body = ImMax(column->ContentMaxXFrozen, column->ContentMaxXUnfrozen) - column->WorkMinX;
1990 const float content_width_headers = column->ContentMaxXHeadersIdeal - column->WorkMinX;
1991 float width_auto = content_width_body;
1992 if (!(column->Flags & ImGuiTableColumnFlags_NoHeaderWidth))
1993 width_auto = ImMax(width_auto, content_width_headers);
1996 if ((column->Flags & ImGuiTableColumnFlags_WidthFixed) && column->InitStretchWeightOrWidth > 0.0f)
1997 if (!(mTable.
Flags & ImGuiTableFlags_Resizable) || (column->Flags & ImGuiTableColumnFlags_NoResize))
1998 width_auto = column->InitStretchWeightOrWidth;
2003 template<
size_t MaxColumnCount>
2004 requires SmallerThanMaxColumnAmount<MaxColumnCount>
2005 void MainTable<MaxColumnCount>::SaveSettingsCustom() {
2007 if (mTable.
Flags & ImGuiTableFlags_NoSavedSettings || (getCustomColumnsActive() && mSpecificColumnsActive))
2011 TableSettings& settings = getTableSettings();
2016 TableColumn* column = mTable.
Columns.Data;
2019 settings.Columns.clear();
2021 bool save_ref_scale =
false;
2022 settings.SaveFlags = ImGuiTableFlags_None;
2023 for (
int n = 0; n < mTable.
ColumnsCount; n++, column++) {
2024 TableColumnSettings& column_settings = settings.Columns.emplace_back();
2025 const float width_or_weight = (column->Flags & ImGuiTableColumnFlags_WidthStretch) ? column->StretchWeight : column->WidthRequest;
2026 column_settings.WidthOrWeight = width_or_weight;
2027 column_settings.UserID = column->UserID;
2029 column_settings.DisplayOrder = column->DisplayOrder;
2030 column_settings.SortOrder = column->SortOrder;
2031 column_settings.SortDirection = column->SortDirection;
2032 column_settings.IsEnabled = column->IsEnabled;
2033 column_settings.IsStretch = (column->Flags & ImGuiTableColumnFlags_WidthStretch) ? 1 : 0;
2034 if ((column->Flags & ImGuiTableColumnFlags_WidthStretch) == 0)
2035 save_ref_scale =
true;
2040 if (width_or_weight != column->InitStretchWeightOrWidth)
2041 settings.SaveFlags |= ImGuiTableFlags_Resizable;
2042 if (column->DisplayOrder != n)
2043 settings.SaveFlags |= ImGuiTableFlags_Reorderable;
2044 if (column->SortOrder != -1)
2045 settings.SaveFlags |= ImGuiTableFlags_Sortable;
2046 if (column->IsEnabled != ((column->Flags & ImGuiTableColumnFlags_DefaultHide) == 0))
2047 settings.SaveFlags |= ImGuiTableFlags_Hideable;
2049 settings.SaveFlags &= mTable.
Flags;
2050 settings.RefScale = save_ref_scale ? mTable.
RefScale : 0.0f;
2053 template<
size_t MaxColumnCount>
2054 requires SmallerThanMaxColumnAmount<MaxColumnCount>
2055 void MainTable<MaxColumnCount>::MigrateIniSettings() {
2056 bool backup = mSpecificColumnsUpdate;
2057 mSpecificColumnsActive =
false;
2059 TableSettings& tableSettings = getTableSettings();
2062 ImGuiContext& g = *GImGui;
2065 ImGuiTableSettings* settings;
2067 settings = ImGui::TableSettingsFindByID(mTable.
ID);
2068 if (settings == NULL)
2070 mTable.
SettingsOffset = g.SettingsTables.offset_from_ptr(settings);
2072 settings = GetBoundSettings();
2075 tableSettings.SaveFlags = settings->SaveFlags;
2076 tableSettings.RefScale = settings->RefScale;
2078 tableSettings.Columns.resize(settings->ColumnsCount);
2081 ImGuiTableColumnSettings* column_settings = settings->GetColumnSettings();
2082 for (
int data_n = 0; data_n < settings->ColumnsCount; data_n++, column_settings++) {
2083 int column_n = column_settings->Index;
2087 auto& column = tableSettings.Columns[column_n];
2089 column.DisplayOrder = column_settings->DisplayOrder;
2090 column.SortOrder = column_settings->SortOrder;
2091 column.IsEnabled = column_settings->IsEnabled;
2092 column.IsStretch = column_settings->IsStretch;
2093 column.SortDirection = column_settings->SortDirection;
2094 column.UserID = column_settings->UserID;
2095 column.WidthOrWeight = column_settings->WidthOrWeight;
2098 mSpecificColumnsActive = backup;
2101 template<
size_t MaxColumnCount>
2102 requires SmallerThanMaxColumnAmount<MaxColumnCount>
2103 void MainTable<MaxColumnCount>::SetupColumnFlags(TableColumn* column, ImGuiTableColumnFlags flags_in) {
2104 ImGuiTableColumnFlags flags = flags_in;
2107 if ((flags & ImGuiTableColumnFlags_WidthMask_) == 0) {
2108 const ImGuiTableFlags table_sizing_policy = (mTable.
Flags & ImGuiTableFlags_SizingMask_);
2109 if (table_sizing_policy == ImGuiTableFlags_SizingFixedFit || table_sizing_policy == ImGuiTableFlags_SizingFixedSame)
2110 flags |= ImGuiTableColumnFlags_WidthFixed;
2112 flags |= ImGuiTableColumnFlags_WidthStretch;
2114 IM_ASSERT(ImIsPowerOfTwo(flags & ImGuiTableColumnFlags_WidthMask_));
2118 if ((mTable.
Flags & ImGuiTableFlags_Resizable) == 0)
2119 flags |= ImGuiTableColumnFlags_NoResize;
2122 if ((flags & ImGuiTableColumnFlags_NoSortAscending) && (flags & ImGuiTableColumnFlags_NoSortDescending))
2123 flags |= ImGuiTableColumnFlags_NoSort;
2126 if ((flags & ImGuiTableColumnFlags_IndentMask_) == 0)
2127 flags |= (mTable.
Columns.index_from_ptr(column) == 0) ? ImGuiTableColumnFlags_IndentEnable : ImGuiTableColumnFlags_IndentDisable;
2135 column->Flags = flags | (column->Flags & ImGuiTableColumnFlags_StatusMask_);
2138 column->SortDirectionsAvailCount = column->SortDirectionsAvailMask = column->SortDirectionsAvailList = 0;
2139 if (mTable.
Flags & ImGuiTableFlags_Sortable) {
2140 int count = 0, mask = 0, list = 0;
2141 if ((flags & ImGuiTableColumnFlags_PreferSortAscending) != 0 && (flags & ImGuiTableColumnFlags_NoSortAscending) == 0) {
2142 mask |= 1 << ImGuiSortDirection_Ascending;
2143 list |= ImGuiSortDirection_Ascending << (count << 1);
2146 if ((flags & ImGuiTableColumnFlags_PreferSortDescending) != 0 && (flags & ImGuiTableColumnFlags_NoSortDescending) == 0) {
2147 mask |= 1 << ImGuiSortDirection_Descending;
2148 list |= ImGuiSortDirection_Descending << (count << 1);
2151 if ((flags & ImGuiTableColumnFlags_PreferSortAscending) == 0 && (flags & ImGuiTableColumnFlags_NoSortAscending) == 0) {
2152 mask |= 1 << ImGuiSortDirection_Ascending;
2153 list |= ImGuiSortDirection_Ascending << (count << 1);
2156 if ((flags & ImGuiTableColumnFlags_PreferSortDescending) == 0 && (flags & ImGuiTableColumnFlags_NoSortDescending) == 0) {
2157 mask |= 1 << ImGuiSortDirection_Descending;
2158 list |= ImGuiSortDirection_Descending << (count << 1);
2161 if ((mTable.
Flags & ImGuiTableFlags_SortTristate) || count == 0) {
2162 mask |= 1 << ImGuiSortDirection_None;
2165 column->SortDirectionsAvailList = (ImU8) list;
2166 column->SortDirectionsAvailMask = (ImU8) mask;
2167 column->SortDirectionsAvailCount = (ImU8) count;
2168 FixColumnSortDirection(column);
2172 template<
size_t MaxColumnCount>
2173 requires SmallerThanMaxColumnAmount<MaxColumnCount>
2174 float MainTable<MaxColumnCount>::GetMaxColumnWidth(
int column_n) {
2175 const TableColumn* column = &mTable.
Columns[column_n];
2176 float max_width = FLT_MAX;
2178 if (mTable.
Flags & ImGuiTableFlags_ScrollX) {
2184 }
else if ((mTable.
Flags & ImGuiTableFlags_NoKeepColumnsVisible) == 0) {
2190 max_width = mTable.
WorkRect.Max.x - (mTable.
ColumnsEnabledCount - column->IndexWithinEnabledSet - 1) * min_column_distance - column->MinX;
2199 template<
size_t MaxColumnCount>
2200 requires SmallerThanMaxColumnAmount<MaxColumnCount>
2201 void MainTable<MaxColumnCount>::SetupDrawChannels() {
2202 const int freeze_row_multiplier = (mTable.
FreezeRowsCount > 0) ? 2 : 1;
2203 const int channels_for_row = (mTable.
Flags & ImGuiTableFlags_NoClip) ? 1 : mTable.ColumnsEnabledCount;
2204 const int channels_for_bg = 1 + 1 * freeze_row_multiplier;
2206 const int channels_total = channels_for_bg + (channels_for_row * freeze_row_multiplier) + channels_for_dummy;
2208 mTable.
DummyDrawChannel = (ImGuiTableDrawChannelIdx) ((channels_for_dummy > 0) ? channels_total - 1 : -1);
2212 int draw_channel_current = 2;
2213 for (
int column_n = 0; column_n < mTable.
ColumnsCount; column_n++) {
2214 TableColumn* column = &mTable.
Columns[column_n];
2215 if (column->IsVisibleX && column->IsVisibleY) {
2216 column->DrawChannelFrozen = (ImGuiTableDrawChannelIdx) (draw_channel_current);
2217 column->DrawChannelUnfrozen = (ImGuiTableDrawChannelIdx) (draw_channel_current + (mTable.
FreezeRowsCount > 0 ? channels_for_row + 1 : 0));
2218 if (!(mTable.
Flags & ImGuiTableFlags_NoClip))
2219 draw_channel_current++;
2221 column->DrawChannelFrozen = column->DrawChannelUnfrozen = mTable.
DummyDrawChannel;
2223 column->DrawChannelCurrent = column->DrawChannelFrozen;
2235 template<
size_t MaxColumnCount>
2236 requires SmallerThanMaxColumnAmount<MaxColumnCount>
2237 void MainTable<MaxColumnCount>::UpdateBorders() {
2238 ImGuiContext& g = *GImGui;
2239 IM_ASSERT(mTable.
Flags & ImGuiTableFlags_Resizable);
2245 const float hit_half_width = TABLE_RESIZE_SEPARATOR_HALF_THICKNESS;
2246 const float hit_y1 = mTable.
OuterRect.Min.y;
2250 for (
int order_n = 0; order_n < mTable.
ColumnsCount; order_n++) {
2255 TableColumn* column = &mTable.
Columns[column_n];
2256 if (column->Flags & (ImGuiTableColumnFlags_NoResize | ImGuiTableColumnFlags_NoDirectResize_))
2260 const float border_y2_hit = (mTable.
Flags & ImGuiTableFlags_NoBordersInBody) ? hit_y2_head : hit_y2_body;
2268 ImGuiID column_id = GetColumnResizeID(column_n, mTable.
InstanceCurrent);
2269 ImRect hit_rect(column->MaxX - hit_half_width, hit_y1, column->MaxX + hit_half_width, border_y2_hit);
2271 ImGui::KeepAliveID(column_id);
2273 bool hovered =
false, held =
false;
2274 bool pressed = ImGui::ButtonBehavior(hit_rect, column_id, &hovered, &held, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_AllowItemOverlap | ImGuiButtonFlags_PressedOnClick | ImGuiButtonFlags_PressedOnDoubleClick);
2275 if (pressed && ImGui::IsMouseDoubleClicked(0)) {
2276 SetColumnWidthAutoSingle(column_n);
2277 ImGui::ClearActiveID();
2278 held = hovered =
false;
2286 if ((hovered && g.HoveredIdTimer > TABLE_RESIZE_SEPARATOR_FEEDBACK_TIMER) || held) {
2288 ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW);
2293 template<
size_t MaxColumnCount>
2294 requires SmallerThanMaxColumnAmount<MaxColumnCount>
2295 void MainTable<MaxColumnCount>::SortSpecsSanitize() {
2296 IM_ASSERT(mTable.
Flags & ImGuiTableFlags_Sortable);
2299 int sort_order_count = 0;
2300 ColumnBitMask sort_order_mask;
2301 for (
int column_n = 0; column_n < mTable.
ColumnsCount; column_n++) {
2302 TableColumn* column = &mTable.
Columns[column_n];
2303 if (column->SortOrder != -1 && !column->IsEnabled)
2304 column->SortOrder = -1;
2305 if (column->SortOrder == -1)
2308 sort_order_mask.set(column->SortOrder);
2311 ColumnBitMask expected;
2312 for (
int i = 0; i < sort_order_count; ++i) {
2316 const bool need_fix_linearize = expected != sort_order_mask;
2317 const bool need_fix_single_sort_order = (sort_order_count > 1) && !(mTable.
Flags & ImGuiTableFlags_SortMulti);
2318 if (need_fix_linearize || need_fix_single_sort_order) {
2319 ColumnBitMask fixed_mask;
2320 for (
int sort_n = 0; sort_n < sort_order_count; sort_n++) {
2323 int column_with_smallest_sort_order = -1;
2324 for (
int column_n = 0; column_n < mTable.
ColumnsCount; column_n++)
2325 if (!fixed_mask.test(column_n) && mTable.
Columns[column_n].SortOrder != -1)
2326 if (column_with_smallest_sort_order == -1 || mTable.
Columns[column_n].SortOrder < mTable.
Columns[column_with_smallest_sort_order].SortOrder)
2327 column_with_smallest_sort_order = column_n;
2328 IM_ASSERT(column_with_smallest_sort_order != -1);
2329 fixed_mask.set(column_with_smallest_sort_order);
2333 if (need_fix_single_sort_order) {
2334 sort_order_count = 1;
2335 for (
int column_n = 0; column_n < mTable.
ColumnsCount; column_n++)
2336 if (column_n != column_with_smallest_sort_order)
2337 mTable.
Columns[column_n].SortOrder = -1;
2344 if (sort_order_count == 0 && !(mTable.
Flags & ImGuiTableFlags_SortTristate))
2345 for (
int column_n = 0; column_n < mTable.
ColumnsCount; column_n++) {
2346 TableColumn* column = &mTable.
Columns[column_n];
2347 if (column->IsEnabled && !(column->Flags & ImGuiTableColumnFlags_NoSort)) {
2348 sort_order_count = 1;
2349 column->SortOrder = 0;
2350 column->SortDirection = (ImU8) GetColumnAvailSortDirection(column, 0);
2358 template<
size_t MaxColumnCount>
2359 requires SmallerThanMaxColumnAmount<MaxColumnCount>
2360 void MainTable<MaxColumnCount>::FixColumnSortDirection(TableColumn* column) {
2361 if (column->SortOrder == -1 || (column->SortDirectionsAvailMask & (1 << column->SortDirection)) != 0)
2363 column->SortDirection = (ImU8) GetColumnAvailSortDirection(column, 0);
2367 template<
size_t MaxColumnCount>
2368 requires SmallerThanMaxColumnAmount<MaxColumnCount>
2369 void MainTable<MaxColumnCount>::EndCell() {
2375 if (mTable.
RowFlags & ImGuiTableRowFlags_Headers)
2376 p_max_pos_x = &column->ContentMaxXHeadersUsed;
2378 p_max_pos_x = mTable.
IsUnfrozenRows ? &column->ContentMaxXUnfrozen : &column->ContentMaxXFrozen;
2379 *p_max_pos_x = ImMax(*p_max_pos_x, window->DC.CursorMaxPos.x);
2381 column->ItemWidth = window->DC.ItemWidth;
2388 template<
size_t MaxColumnCount>
2389 requires SmallerThanMaxColumnAmount<MaxColumnCount>
2390 void MainTable<MaxColumnCount>::BeginCell(
int column_n) {
2391 TableColumn* column = &mTable.
Columns[column_n];
2396 float start_x = column->WorkMinX;
2397 if (column->Flags & ImGuiTableColumnFlags_IndentEnable)
2400 window->DC.CursorPos.x = start_x;
2402 window->DC.CursorMaxPos.x = window->DC.CursorPos.x;
2403 window->DC.ColumnsOffset.x = start_x - window->Pos.x - window->DC.Indent.x;
2405 window->DC.NavLayerCurrent = (ImGuiNavLayer) column->NavLayerCurrent;
2407 window->WorkRect.Min.y = window->DC.CursorPos.y;
2408 window->WorkRect.Min.x = column->WorkMinX;
2409 window->WorkRect.Max.x = column->WorkMaxX;
2410 window->DC.ItemWidth = column->ItemWidth;
2413 if (!column->IsEnabled)
2414 window->DC.CursorPos.y = ImMax(window->DC.CursorPos.y, mTable.
RowPosY2);
2416 window->SkipItems = column->IsSkipItems;
2417 if (column->IsSkipItems) {
2418 window->DC.LastItemId = 0;
2419 window->DC.LastItemStatusFlags = 0;
2422 if (mTable.
Flags & ImGuiTableFlags_NoClip) {
2424 mTable.
DrawSplitter.SetCurrentChannel(window->DrawList, TABLE_DRAW_CHANNEL_NOCLIP);
2428 ImGui::SetWindowClipRectBeforeSetChannel(window, column->ClipRect);
2429 mTable.
DrawSplitter.SetCurrentChannel(window->DrawList, column->DrawChannelCurrent);
2433 template<
size_t MaxColumnCount>
2434 requires SmallerThanMaxColumnAmount<MaxColumnCount>
2435 void MainTable<MaxColumnCount>::BeginRow() {
2449 next_y1 = window->DC.CursorPos.y = mTable.
OuterRect.Min.y;
2454 window->DC.PrevLineTextBaseOffset = 0.0f;
2455 window->DC.CursorMaxPos.y = next_y1;
2458 if (mTable.
RowFlags & ImGuiTableRowFlags_Headers) {
2459 SetBgColor(ImGuiTableBgTarget_RowBg0, ImGui::GetColorU32(ImGuiCol_TableHeaderBg));
2465 template<
size_t MaxColumnCount>
2466 requires SmallerThanMaxColumnAmount<MaxColumnCount>
2467 void MainTable<MaxColumnCount>::SetBgColor(ImGuiTableBgTarget target, ImU32 color,
int column_n) {
2468 IM_ASSERT(target != ImGuiTableBgTarget_None);
2470 if (color == IM_COL32_DISABLE)
2475 case ImGuiTableBgTarget_CellBg: {
2485 cell_data->BgColor = color;
2489 case ImGuiTableBgTarget_RowBg0:
2490 case ImGuiTableBgTarget_RowBg1: {
2493 IM_ASSERT(column_n == -1);
2494 int bg_idx = (target == ImGuiTableBgTarget_RowBg1) ? 1 : 0;
2503 template<
size_t MaxColumnCount>
2504 requires SmallerThanMaxColumnAmount<MaxColumnCount>
2505 void MainTable<MaxColumnCount>::SetColumnSortDirection(
int column_n, ImGuiSortDirection sort_direction,
bool append_to_sort_specs) {
2506 if (!(mTable.
Flags & ImGuiTableFlags_SortMulti))
2507 append_to_sort_specs =
false;
2508 if (!(mTable.
Flags & ImGuiTableFlags_SortTristate))
2509 IM_ASSERT(sort_direction != ImGuiSortDirection_None);
2512 if (append_to_sort_specs)
2513 for (
int other_column_n = 0; other_column_n < mTable.
ColumnsCount; other_column_n++)
2514 sort_order_max = ImMax(sort_order_max, mTable.
Columns[other_column_n].SortOrder);
2516 TableColumn* column = &mTable.
Columns[column_n];
2517 column->SortDirection = (ImU8) sort_direction;
2518 if (column->SortDirection == ImGuiSortDirection_None)
2519 column->SortOrder = -1;
2520 else if (column->SortOrder == -1 || !append_to_sort_specs)
2521 column->SortOrder = append_to_sort_specs ? sort_order_max + 1 : 0;
2523 for (
int other_column_n = 0; other_column_n < mTable.
ColumnsCount; other_column_n++) {
2524 TableColumn* other_column = &mTable.
Columns[other_column_n];
2525 if (other_column != column && !append_to_sort_specs)
2526 other_column->SortOrder = -1;
2527 FixColumnSortDirection(other_column);
2533 template<
size_t MaxColumnCount>
2534 requires SmallerThanMaxColumnAmount<MaxColumnCount>
2535 ImGuiSortDirection MainTable<MaxColumnCount>::GetColumnNextSortDirection(TableColumn* column) {
2536 IM_ASSERT(column->SortDirectionsAvailCount > 0);
2537 if (column->SortOrder == -1)
2538 return GetColumnAvailSortDirection(column, 0);
2539 for (
int n = 0; n < 3; n++)
2540 if (column->SortDirection == GetColumnAvailSortDirection(column, n))
2541 return GetColumnAvailSortDirection(column, (n + 1) % column->SortDirectionsAvailCount);
2543 return ImGuiSortDirection_None;
2546 template<
size_t MaxColumnCount>
2547 requires SmallerThanMaxColumnAmount<MaxColumnCount>
2548 void MainTable<MaxColumnCount>::SetColumnWidth(
int column_n,
float width) {
2550 IM_ASSERT(column_n >= 0 && column_n < mTable.
ColumnsCount);
2551 TableColumn* column_0 = &mTable.
Columns[column_n];
2552 float column_0_width = width;
2558 const float max_width = ImMax(min_width, GetMaxColumnWidth(column_n));
2559 column_0_width = ImClamp(column_0_width, min_width, max_width);
2560 if (column_0->WidthGiven == column_0_width || column_0->WidthRequest == column_0_width)
2564 TableColumn* column_1 = (column_0->NextEnabledColumn != -1) ? &mTable.
Columns[column_0->NextEnabledColumn] : NULL;
2600 if (column_0->Flags & ImGuiTableColumnFlags_WidthFixed)
2602 column_0->WidthRequest = column_0_width;
2608 if (column_1 == NULL)
2609 column_1 = (column_0->PrevEnabledColumn != -1) ? &mTable.
Columns[column_0->PrevEnabledColumn] : NULL;
2610 if (column_1 == NULL)
2615 float column_1_width = ImMax(column_1->WidthRequest - (column_0_width - column_0->WidthRequest), min_width);
2616 column_0_width = column_0->WidthRequest + column_1->WidthRequest - column_1_width;
2617 IM_ASSERT(column_0_width > 0.0f && column_1_width > 0.0f);
2618 column_0->WidthRequest = column_0_width;
2619 column_1->WidthRequest = column_1_width;
2620 if ((column_0->Flags | column_1->Flags) & ImGuiTableColumnFlags_WidthStretch)
2621 UpdateColumnsWeightFromWidth();
2625 template<
size_t MaxColumnCount>
2626 requires SmallerThanMaxColumnAmount<MaxColumnCount>
2627 void MainTable<MaxColumnCount>::UpdateColumnsWeightFromWidth() {
2631 float visible_weight = 0.0f;
2632 float visible_width = 0.0f;
2633 for (
int column_n = 0; column_n < mTable.
ColumnsCount; column_n++) {
2634 TableColumn* column = &mTable.
Columns[column_n];
2635 if (!column->IsEnabled || !(column->Flags & ImGuiTableColumnFlags_WidthStretch))
2637 IM_ASSERT(column->StretchWeight > 0.0f);
2638 visible_weight += column->StretchWeight;
2639 visible_width += column->WidthRequest;
2641 IM_ASSERT(visible_weight > 0.0f && visible_width > 0.0f);
2644 for (
int column_n = 0; column_n < mTable.
ColumnsCount; column_n++) {
2645 TableColumn* column = &mTable.
Columns[column_n];
2646 if (!column->IsEnabled || !(column->Flags & ImGuiTableColumnFlags_WidthStretch))
2648 column->StretchWeight = (column->WidthRequest / visible_width) * visible_weight;
2649 IM_ASSERT(column->StretchWeight > 0.0f);
2653 template<
size_t MaxColumnCount>
2654 requires SmallerThanMaxColumnAmount<MaxColumnCount>
2656 const ImRect& cellBgRect = GetCellBgRect(mTable.
CurrentColumn);
2661 return ImGui::IsWindowHovered() && ImGui::IsMouseHoveringRect(cellBgRect.Min, cellBgRect.Max);
2664 template<
size_t MaxColumnCount>
2670 template<
size_t MaxColumnCount>
2676 template<
size_t MaxColumnCount>
2678 bool MainTable<MaxColumnCount>::Begin(
const char* str_id,
int columns_count, ImGuiTableFlags flags,
const ImVec2& outer_size,
float inner_width, ImGuiWindowFlags child_window_flags) {
2679 ImGuiID
id = ImGui::GetID(str_id);
2683 flags |= ImGuiTableFlags_ScrollY;
2685 ImGuiContext& g = *GImGui;
2686 ImGuiWindow* outer_window = ImGui::GetCurrentWindow();
2687 if (outer_window->SkipItems)
2691 IM_ASSERT(columns_count > 0 && columns_count <= MaxColumnCount &&
"Only 1..MaxColumnCount columns allowed!");
2692 if (flags & ImGuiTableFlags_ScrollX)
2693 IM_ASSERT(inner_width >= 0.0f);
2696 const bool use_child_window = (flags & (ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY)) != 0;
2697 const ImVec2 avail_size = ImGui::GetContentRegionAvail();
2698 ImVec2 actual_outer_size = ImGui::CalcItemSize(outer_size, ImMax(avail_size.x, 1.0f), use_child_window ? ImMax(avail_size.y, 1.0f) : 0.0f);
2699 ImRect outer_rect(outer_window->DC.CursorPos, outer_window->DC.CursorPos + actual_outer_size);
2701 if (use_child_window && ImGui::IsClippedEx(outer_rect, 0,
false)) {
2702 ImGui::ItemSize(outer_rect);
2711 const ImGuiID instance_id =
id + instance_no;
2712 const ImGuiTableFlags table_last_flags = mTable.
Flags;
2713 if (instance_no > 0)
2714 IM_ASSERT(mTable.
ColumnsCount == columns_count &&
"BeginTable(): Cannot change columns count mid-frame while preserving same ID");
2718 flags = TableFixFlags(flags, outer_window);
2722 mTable.
Flags = flags;
2732 if (use_child_window) {
2735 ImVec2 override_content_size(FLT_MAX, FLT_MAX);
2736 if ((flags & ImGuiTableFlags_ScrollX) && !(flags & ImGuiTableFlags_ScrollY))
2737 override_content_size.y = FLT_MIN;
2743 if ((flags & ImGuiTableFlags_ScrollX) && inner_width > 0.0f)
2744 override_content_size.x = inner_width;
2746 if (override_content_size.x != FLT_MAX || override_content_size.y != FLT_MAX)
2747 ImGui::SetNextWindowContentSize(ImVec2(override_content_size.x != FLT_MAX ? override_content_size.x : 0.0f, override_content_size.y != FLT_MAX ? override_content_size.y : 0.0f));
2750 if ((table_last_flags & (ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY)) == 0)
2751 ImGui::SetNextWindowScroll(ImVec2(0.0f, 0.0f));
2754 ImGuiWindowFlags child_flags = child_window_flags;
2755 child_flags |= getShowScrollbar() ? 0 : ImGuiWindowFlags_NoScrollbar;
2756 child_flags |= (flags & ImGuiTableFlags_ScrollX) ? ImGuiWindowFlags_HorizontalScrollbar : ImGuiWindowFlags_None;
2757 ImGui::BeginChildEx(str_id, instance_id, outer_rect.GetSize(),
false, child_flags);
2770 ImGui::PushOverrideID(instance_id);
2785 inner_window->DC.PrevLineSize = inner_window->DC.CurrLineSize = ImVec2(0.0f, 0.0f);
2792 const bool pad_outer_x = (flags & ImGuiTableFlags_NoPadOuterX) ?
false : (flags & ImGuiTableFlags_PadOuterX) ?
true
2793 : (flags & ImGuiTableFlags_BordersOuterV) != 0;
2794 const bool pad_inner_x = (flags & ImGuiTableFlags_NoPadInnerX) ?
false :
true;
2795 const float inner_spacing_for_border = (flags & ImGuiTableFlags_BordersInnerV) ? TABLE_BORDER_SIZE : 0.0f;
2796 const float inner_spacing_explicit = (pad_inner_x && (flags & ImGuiTableFlags_BordersInnerV) == 0) ? g.Style.CellPadding.x : 0.0f;
2797 const float inner_padding_explicit = (pad_inner_x && (flags & ImGuiTableFlags_BordersInnerV) != 0) ? g.Style.CellPadding.x : 0.0f;
2798 mTable.
CellSpacingX1 = inner_spacing_explicit + inner_spacing_for_border;
2803 const float outer_padding_for_border = (flags & ImGuiTableFlags_BordersOuterV) ? TABLE_BORDER_SIZE : 0.0f;
2804 const float outer_padding_explicit = pad_outer_x ? g.Style.CellPadding.x : 0.0f;
2814 mTable.
InnerClipRect.Max.y = (flags & ImGuiTableFlags_NoHostExtendY) ? ImMin(mTable.
InnerClipRect.Max.y, inner_window->WorkRect.Max.y) : inner_window->ClipRect.Max.y;
2835 if ((table_last_flags & ImGuiTableFlags_Reorderable) && (flags & ImGuiTableFlags_Reorderable) == 0)
2845 const int stored_size = mTable.
Columns.size();
2846 if (stored_size != 0 && stored_size != columns_count) {
2851 BeginInitMemory(columns_count);
2865 for (
int n = 0; n < columns_count; n++) {
2878 LoadSettingsCustom();
2880 if (getCustomColumnsActive()) {
2881 bool expected =
true;
2882 if (mSpecificColumnsUpdate.compare_exchange_strong(expected,
false)) {
2883 if (mSpecificColumnsActive) {
2884 ApplySpecificColumnSetup();
2886 LoadSettingsCustom();
2889 }
else if (mSpecificColumnsActive) {
2890 LoadSettingsCustom();
2891 mSpecificColumnsActive =
false;
2899 const float new_ref_scale_unit = g.FontSize;
2901 const float scale_factor = new_ref_scale_unit / mTable.
RefScale;
2903 for (
int n = 0; n < columns_count; n++)
2904 mTable.
Columns[n].WidthRequest = mTable.
Columns[n].WidthRequest * scale_factor;
2906 mTable.
RefScale = new_ref_scale_unit;
2911 inner_window->SkipItems =
true;
2919 BeginApplyRequests();
2924 template<
size_t MaxColumnCount>
2927 ImGuiContext& g = *GImGui;
2938 const ImGuiTableFlags flags = mTable.
Flags;
2941 IM_ASSERT(inner_window == g.CurrentWindow);
2942 IM_ASSERT(outer_window == inner_window || outer_window == inner_window->ParentWindow);
2956 const float inner_content_max_y = mTable.
RowPosY2;
2957 IM_ASSERT(mTable.
RowPosY2 == inner_window->DC.CursorPos.y);
2958 if (inner_window != outer_window)
2959 inner_window->DC.CursorMaxPos.y = inner_content_max_y;
2960 else if (!(flags & ImGuiTableFlags_NoHostExtendY))
2968 if (mTable.
Flags & ImGuiTableFlags_ScrollX) {
2969 const float outer_padding_for_border = (mTable.
Flags & ImGuiTableFlags_BordersOuterV) ? TABLE_BORDER_SIZE : 0.0f;
2970 float max_pos_x = mTable.
InnerWindow->DC.CursorMaxPos.x;
2975 mTable.
InnerWindow->DC.CursorMaxPos.x = max_pos_x;
2979 if (!(flags & ImGuiTableFlags_NoClip))
2980 inner_window->DrawList->PopClipRect();
2981 inner_window->ClipRect = inner_window->DrawList->_ClipRectStack.back();
2984 if ((flags & ImGuiTableFlags_Borders) != 0)
2988 mTable.
DrawSplitter.SetCurrentChannel(inner_window->DrawList, 0);
2989 if ((mTable.
Flags & ImGuiTableFlags_NoClip) == 0)
2990 MergeDrawChannels();
2996 for (
int column_n = 0; column_n < mTable.
ColumnsCount; column_n++)
2999 if ((column->
Flags & ImGuiTableColumnFlags_WidthFixed) && !(column->
Flags & ImGuiTableColumnFlags_NoResize))
3006 if ((mTable.
Flags & ImGuiTableFlags_ScrollX) == 0 && inner_window != outer_window) {
3007 inner_window->Scroll.x = 0.0f;
3013 ImGui::SetScrollFromPosX(inner_window, column->
MaxX - inner_window->Pos.x - neighbor_width_to_keep_visible, 1.0f);
3015 ImGui::SetScrollFromPosX(inner_window, column->
MaxX - inner_window->Pos.x + neighbor_width_to_keep_visible, 1.0f);
3021 const float new_x2 = (g.IO.MousePos.x - g.ActiveIdClickOffset.x + TABLE_RESIZE_SEPARATOR_HALF_THICKNESS);
3027 IM_ASSERT_USER_ERROR(inner_window->IDStack.back() == mTable.
ID + mTable.
InstanceCurrent,
"Mismatching PushID/PopID!");
3032 const ImVec2 backup_outer_max_pos = outer_window->DC.CursorMaxPos;
3036 outer_window->DC.CursorPos = mTable.
OuterRect.Min;
3044 if (inner_window != outer_window) {
3047 ImGui::ItemSize(mTable.
OuterRect.GetSize());
3052 if (mTable.
Flags & ImGuiTableFlags_NoHostExtendX) {
3055 IM_ASSERT((mTable.
Flags & ImGuiTableFlags_ScrollX) == 0);
3058 const float decoration_size = (mTable.
Flags & ImGuiTableFlags_ScrollX) ? inner_window->ScrollbarSizes.x : 0.0f;
3062 outer_window->DC.CursorMaxPos.x = ImMax(backup_outer_max_pos.x, mTable.
OuterRect.Max.x);
3065 const float decoration_size = (mTable.
Flags & ImGuiTableFlags_ScrollY) ? inner_window->ScrollbarSizes.y : 0.0f;
3066 outer_window->DC.IdealMaxPos.y = ImMax(outer_window->DC.IdealMaxPos.y, inner_content_max_y + decoration_size - mTable.
UserOuterSize.y);
3067 outer_window->DC.CursorMaxPos.y = ImMax(backup_outer_max_pos.y, ImMin(mTable.
OuterRect.Max.y, inner_content_max_y));
3070 outer_window->DC.CursorMaxPos.y = ImMax(backup_outer_max_pos.y, mTable.
OuterRect.Max.y);
3075 SaveSettingsCustom();
3085 template<
size_t MaxColumnCount>
3091 bool menu_item_active = (column.
Flags & ImGuiTableColumnFlags_NoHide) ?
false :
true;
3093 menu_item_active =
false;
3094 if (ImGui::MenuItem(columnName, NULL, column.
IsEnabled, menu_item_active && !mSpecificColumnsActive))
3097 if (ImGui::IsItemHovered()) {
3098 ImGui::SetTooltip(
"%s", std::string(mColumns.at(
TableColumnIdx).Popup()).c_str());
3102 template<
size_t MaxColumnCount>
3113 template<
size_t MaxColumnCount>
3116 IM_ASSERT(mTable.
IsLayoutLocked ==
false &&
"Need to call TableSetupColumn() before first row!");
3117 IM_ASSERT(columns >= 0 && columns < IMGUI_TABLE_MAX_COLUMNS);
3118 IM_ASSERT(rows >= 0 && rows < 128);
3127 template<
size_t MaxColumnCount>
3131 float x1 = column->
MinX;
3132 float x2 = column->
MaxX;
3140 template<
size_t MaxColumnCount>
3143 if (!(mTable.
Flags & ImGuiTableFlags_Sortable))
3156 template<
size_t MaxColumnCount>
3159 IM_ASSERT(mTable.
IsLayoutLocked ==
false &&
"Need to call call TableSetupColumn() before first row!");
3160 IM_ASSERT((flags & ImGuiTableColumnFlags_StatusMask_) == 0 &&
"Illegal to pass StatusMask values to TableSetupColumn()");
3171 if (mTable.
IsDefaultSizingPolicy && (flags & ImGuiTableColumnFlags_WidthMask_) == 0 && (flags & ImGuiTableFlags_ScrollX) == 0)
3172 IM_ASSERT(init_width_or_weight <= 0.0f &&
"Can only specify width/weight if sizing policy is set explicitely in either Table or Column.");
3176 if ((flags & ImGuiTableColumnFlags_WidthMask_) == 0 && init_width_or_weight > 0.0f)
3177 if ((mTable.
Flags & ImGuiTableFlags_SizingMask_) == ImGuiTableFlags_SizingFixedFit || (mTable.
Flags & ImGuiTableFlags_SizingMask_) == ImGuiTableFlags_SizingFixedSame)
3178 flags |= ImGuiTableColumnFlags_WidthFixed;
3180 TableSetupColumnFlags(column, flags);
3182 column->
UserID = user_id;
3183 flags = column->
Flags;
3190 if ((flags & ImGuiTableColumnFlags_WidthFixed) && init_width_or_weight > 0.0f)
3192 if (flags & ImGuiTableColumnFlags_WidthStretch)
3193 column->
StretchWeight = (init_width_or_weight > 0.0f) ? init_width_or_weight : -1.0f;
3196 if (init_width_or_weight > 0.0f)
3201 if ((flags & ImGuiTableColumnFlags_DefaultHide) && (mTable.
SettingsLoadedFlags & ImGuiTableFlags_Hideable) == 0)
3203 if (flags & ImGuiTableColumnFlags_DefaultSort && (mTable.
SettingsLoadedFlags & ImGuiTableFlags_Sortable) == 0) {
3205 column->
SortDirection = (column->
Flags & ImGuiTableColumnFlags_PreferSortDescending) ? (ImS8) ImGuiSortDirection_Descending : (ImU8) (ImGuiSortDirection_Ascending);
3211 if (!label.empty()) {
3213 mTable.
ColumnsNames.append(label.data(), label.data() + label.size() + 1);
3217 template<
size_t MaxColumnCount>
3221 const float image_size = 16.f;
3224 if (!texture || getShowHeaderAsText()) {
3228 ImGuiContext& g = *GImGui;
3229 ImGuiWindow* window = g.CurrentWindow;
3230 if (window->SkipItems)
3238 ImVec2 label_size = ImGui::CalcTextSize(label.data(), label.data() + label.size(),
true);
3239 ImVec2 label_pos = window->DC.CursorPos;
3243 ImRect cell_r = GetCellBgRect(column_n);
3246 label_height = ImMax(label_size.y, label_height);
3248 label_height = ImMax(image_size, label_height);
3252 float w_arrow = 0.0f;
3253 float w_sort_text = 0.0f;
3254 char sort_order_suf[4] =
"";
3255 const float ARROW_SCALE = 0.65f;
3256 if ((mTable.
Flags & ImGuiTableFlags_Sortable) && !(column->
Flags & ImGuiTableColumnFlags_NoSort)) {
3258 w_arrow = ImFloor(g.FontSize * ARROW_SCALE + g.Style.FramePadding.x);
3260 ImFormatString(sort_order_suf, IM_ARRAYSIZE(sort_order_suf),
"%d", column->
SortOrder + 1);
3261 w_sort_text = g.Style.ItemInnerSpacing.x + ImGui::CalcTextSize(sort_order_suf).x;
3264 w_arrow = g.Style.ItemInnerSpacing.x;
3269 float max_pos_x = label_pos.x + w_sort_text + w_arrow;
3271 max_pos_x += label_size.x;
3273 max_pos_x += image_size;
3280 ImGuiID
id = window->GetID(label.data(), label.data() + label.size());
3281 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));
3282 ImGui::ItemSize(ImVec2(0.0f, label_height));
3283 if (!ImGui::ItemAdd(bb,
id))
3291 bool pressed = ImGui::ButtonBehavior(bb,
id, &hovered, &held, ImGuiButtonFlags_AllowItemOverlap);
3292 if (g.ActiveId !=
id)
3293 ImGui::SetItemAllowOverlap();
3294 if (held || hovered || selected) {
3295 const ImU32 col = ImGui::GetColorU32(held ? ImGuiCol_HeaderActive : hovered ? ImGuiCol_HeaderHovered
3298 SetBgColor(ImGuiTableBgTarget_CellBg, col, mTable.
CurrentColumn);
3299 ImGui::RenderNavHighlight(bb,
id, ImGuiNavHighlightFlags_TypeThin | ImGuiNavHighlightFlags_NoRounding);
3302 if ((mTable.
RowFlags & ImGuiTableRowFlags_Headers) == 0)
3303 SetBgColor(ImGuiTableBgTarget_CellBg, ImGui::GetColorU32(ImGuiCol_TableHeaderBg), mTable.
CurrentColumn);
3307 window->DC.CursorPos.y -= g.Style.ItemSpacing.y * 0.5f;
3311 if (held && (mTable.
Flags & ImGuiTableFlags_Reorderable) && ImGui::IsMouseDragging(0) && !g.DragDropActive) {
3317 if (g.IO.MouseDelta.x < 0.0f && g.IO.MousePos.x < cell_r.Min.x)
3319 if (!((column->
Flags | prev_column->Flags) & ImGuiTableColumnFlags_NoReorder))
3322 if (g.IO.MouseDelta.x > 0.0f && g.IO.MousePos.x > cell_r.Max.x)
3324 if (!((column->
Flags | next_column->Flags) & ImGuiTableColumnFlags_NoReorder))
3330 const float ellipsis_max = cell_r.Max.x - w_arrow - w_sort_text;
3331 if ((mTable.
Flags & ImGuiTableFlags_Sortable) && !(column->
Flags & ImGuiTableColumnFlags_NoSort)) {
3333 float x = ImMax(cell_r.Min.x, cell_r.Max.x - w_arrow - w_sort_text);
3334 float y = label_pos.y;
3336 ImGui::PushStyleColor(ImGuiCol_Text, ImGui::GetColorU32(ImGuiCol_Text, 0.70f));
3337 ImGui::RenderText(ImVec2(x + g.Style.ItemInnerSpacing.x, y), sort_order_suf);
3338 ImGui::PopStyleColor();
3341 ImGui::RenderArrow(window->DrawList, ImVec2(x, y), ImGui::GetColorU32(ImGuiCol_Text), column->
SortDirection == ImGuiSortDirection_Ascending ? ImGuiDir_Up : ImGuiDir_Down, ARROW_SCALE);
3346 ImGuiSortDirection sort_direction = GetColumnNextSortDirection(column);
3347 SetColumnSortDirection(column_n, sort_direction, g.IO.KeyShift);
3358 float newX = label_pos.x;
3360 switch (alignment) {
3362 newX = ellipsis_max - ((ellipsis_max - label_pos.x) / 2) - (label_size.x / 2);
3364 if (newX <= label_pos.x) newX = label_pos.x;
3367 newX = ellipsis_max - label_size.x;
3368 if (newX <= label_pos.x) newX = label_pos.x;
3375 ImGui::RenderTextEllipsis(window->DrawList, ImVec2(newX, label_pos.y), ImVec2(ellipsis_max, label_pos.y + label_height + g.Style.FramePadding.y), ellipsis_max, ellipsis_max, label.data(), label.data() + label.size(), &label_size);
3377 float newX = label_pos.x;
3379 switch (alignment) {
3381 newX = ellipsis_max - ((ellipsis_max - label_pos.x) / 2) - (image_size / 2);
3382 if (newX <= label_pos.x) newX = label_pos.x;
3385 newX = ellipsis_max - image_size;
3387 if (newX <= label_pos.x) newX = label_pos.x;
3394 ImRect ibb(ImVec2(newX, label_pos.y), ImVec2(newX, label_pos.y) + image_size);
3396 window->DrawList->AddImage(texture, ibb.Min, ibb.Max);
3402 if (ImGui::IsItemHovered()) {
3403 ImGui::SetTooltip(
"%s", std::string(popupText).c_str());
3411 template<
size_t MaxColumnCount>
3414 const float posX = ImGui::GetCursorPosX();
3416 float textWidth = ImGui::CalcTextSize(text).x;
3417 ImGuiWindow* window = ImGui::GetCurrentWindowRead();
3418 float columnWidth = window->WorkRect.Max.x - window->DC.CursorPos.x;
3420 switch (getAlignment()) {
3424 newX = posX + columnWidth / 2 - textWidth / 2;
3427 newX = posX + columnWidth - textWidth;
3438 ImGui::SetCursorPosX(newX);
3440 ImGui::TextUnformatted(text);
3443 window->DC.CursorMaxPos.x = window->Pos.x + posX + textWidth;
3446 template<
size_t MaxColumnCount>
3449 AlignedTextColumn(text.c_str());
3452 template<
size_t MaxColumnCount>
3454 template<
typename... Args>
3456 AlignedTextColumn(std::vformat(format, std::make_format_args(args...)));
3459 template<
size_t MaxColumnCount>
3462 const float posX = ImGui::GetCursorPosX();
3464 float elementWidth = radius * 2 + thickness * 2;
3465 ImGuiWindow* window = ImGui::GetCurrentWindowRead();
3466 float columnWidth = window->WorkRect.Max.x - window->DC.CursorPos.x;
3468 switch (getAlignment()) {
3472 newX = posX + columnWidth / 2 - elementWidth / 2;
3475 newX = posX + columnWidth - elementWidth;
3484 ImGui::SetCursorPosX(newX);
3489 template<
size_t MaxColumnCount>
3492 for (
int i = getCustomColumnsFirstColumn(); i < mTable.
Columns.size(); ++i) {
3493 auto& column = mTable.
Columns[i];
3494 bool enabled = std::ranges::find_if(mSpecificColumnCache, [i,
this](
const size_t& pVal) ->
bool {
return mColumns.at(i).UserId == pVal; }) != mSpecificColumnCache.end();
3495 column.IsEnabledNextFrame = enabled;
Alignment
Definition arcdps_structs.h:64
static std::string_view STranslate(Args... args)
Definition Localization.h:63
Definition MainTable.h:128
std::bitset< MaxColumnCount > ColumnBitMask
Definition MainTable.h:130
virtual void MigrateSettings()
Definition MainTable.h:249
virtual ~MainTable()=default
void ResetSpecificColumnSetup()
Definition MainTable.h:861
void Draw()
Definition MainTable.h:733
int GetColumnIndex()
Definition MainTable.h:2672
virtual bool getCustomColumnsFeatureActive()
Definition MainTable.h:239
virtual Alignment & getAlignment()=0
static size_t GetMaxColumnCount()
Definition MainTable.h:144
MainTable(MainTable &&pOther) noexcept=delete
ImRect GetCellBgRect(int column_n)
Definition MainTable.h:3129
virtual Alignment & getHeaderAlignment()=0
void AlignedTextColumn(const char *text)
Definition MainTable.h:3413
bool IsCurrentRowHovered()
Definition MainTable.h:2666
bool GetSpecificColumnsActive() const
Definition MainTable.h:149
virtual bool getMaxHeightActive()
Definition MainTable.h:226
void EndMaxHeightRow()
Definition MainTable.h:925
Table mTable
Definition MainTable.h:528
virtual void DrawStyleSubMenu()
Definition MainTable.h:868
void NextRow(ImGuiTableRowFlags row_flags=0, float min_row_height=0.0f)
Definition MainTable.h:885
virtual bool & getShowAlternatingBackground()=0
void MenuItemColumnVisibility(int TableColumnIdx)
Definition MainTable.h:3087
virtual void DrawRows(TableColumnIdx pFirstColumnIndex)=0
virtual void Sort(const ImGuiTableColumnSortSpecs *mColumnSortSpecs)=0
MainTable(const MainTable &pOther)=delete
virtual bool getShowScrollbar()
Definition MainTable.h:224
MainTable(const std::vector< MainTableColumn > &pColumns, MainWindow *pMainWindow, MainTableFlags pFlags=0)
Definition MainTable.h:689
void SetupColumn(std::string_view label, ImGuiTableColumnFlags flags, float init_width_or_weight, ImGuiID user_id)
Definition MainTable.h:3158
void SetupScrollFreeze(int columns, int rows)
Definition MainTable.h:3115
virtual bool & getHighlightHoveredRows()=0
bool Begin(const char *str_id, int columns_count, ImGuiTableFlags flags, const ImVec2 &outer_size, float inner_width, ImGuiWindowFlags child_window_flags)
Definition MainTable.h:2678
ImGuiTableSortSpecs * GetSortSpecs()
Definition MainTable.h:3142
void ApplySpecificColumnSetup()
Definition MainTable.h:3491
virtual bool & getCustomColumnsActive()
Definition MainTable.h:240
virtual std::string getTableId()=0
void RequestSort()
Definition MainTable.h:145
virtual int getCustomColumnsFirstColumn()
Definition MainTable.h:242
virtual const char * getCategoryName(const std::string &pCat)=0
void ColumnHeader(std::string_view label, bool show_label, ImTextureID texture, Alignment alignment, std::string_view popupText)
Definition MainTable.h:3219
bool IsCurrentColumnHovered()
Definition MainTable.h:2655
void DrawColumnSetupMenu()
Definition MainTable.h:827
const char * GetColumnName(int column_n)
Definition MainTable.h:3104
MainTable & operator=(MainTable &&pOther) noexcept=delete
bool NextColumn()
Definition MainTable.h:907
MainTable & operator=(const MainTable &pOther)=delete
virtual void DrawColumnSetupSubMenu()
Definition MainTable.h:837
bool SpinnerAligned(const char *label, float radius, float thickness, const ImU32 &color)
Definition MainTable.h:3461
void SetSpecificColumnSetup(const std::vector< size_t > &pNewColumns)
Definition MainTable.h:852
virtual TableSettings & getTableSettings()=0
virtual bool & getShowHeaderAsText()=0
virtual int & getMaxDisplayed()=0
void End()
Definition MainTable.h:2926
Definition MainWindow.h:23
float GetMaxCursorPos()
Definition MainWindow.cpp:175
virtual bool & GetShowScrollbar()=0
virtual void SetMaxHeightCursorPos(float pNewCursorPos=ImGui::GetCursorPosY())
Definition MainWindow.cpp:147
void RegisterDrawStyleSubMenuHook(DrawStyleSubMenuHookFunction pFun)
Definition MainWindow.cpp:171
Definition MainTable.h:97
Definition ArcdpsExtension.h:10
MainTableFlags_
Definition MainTable.h:89
@ MainTableFlags_None
Definition MainTable.h:90
@ MainTableFlags_SubWindow
Definition MainTable.h:91
@ ET_HighlightHoveredRow
Definition ExtensionTranslations.h:52
@ ET_UseCustomColumns
This is used to fix the column setup, currently used by kp.me plugin to show columns based on the cur...
Definition ExtensionTranslations.h:50
@ ET_ColumnSetup
Definition ExtensionTranslations.h:48
@ ET_AlternatingRowBg
Definition ExtensionTranslations.h:51
@ ET_HeaderAlignment
Definition ExtensionTranslations.h:54
@ ET_SettingsShowHeaderText
Definition ExtensionTranslations.h:57
@ ET_MaxDisplayed
Definition ExtensionTranslations.h:53
@ ET_ColumnAlignment
Definition ExtensionTranslations.h:55
int MainTableFlags
Definition MainTable.h:93
ImS16 TableColumnIdx
Definition MainTable.h:41
bool EnumCombo(const char *label, E &storage, const R &values, const std::map< E, std::function< std::string()> > &pPopupText={})
Definition Widgets.h:77
bool Spinner(const char *label, float radius, float thickness, const ImU32 &color)
Definition Widgets.cpp:21
Definition imgui_stdlib.h:16
Definition MainTable.h:51
MainTableColumn(ImU32 pUserId, GetTextFunc pName, GetTextureFunc pTexture, std::string pCategory, bool pDefaultVisibility=true)
Definition MainTable.h:62
GetTextFunc Popup
Definition MainTable.h:60
MainTableColumn(E pUserId, GetTextFunc pName, GetTextureFunc pTexture, std::string pCategory, bool pDefaultVisibility=true)
Definition MainTable.h:72
ImU32 UserId
Definition MainTable.h:55
MainTableColumn(E pUserId, GetTextFunc pName, GetTextureFunc pTexture, std::string pCategory, GetTextFunc pPopup, bool pDefaultVisibility=true)
Definition MainTable.h:85
std::function< std::string_view()> GetTextFunc
Definition MainTable.h:52
GetTextFunc Name
Definition MainTable.h:56
MainTableColumn(ImU32 pUserId, GetTextFunc pName, GetTextureFunc pTexture, std::string pCategory, GetTextFunc pPopup, bool pDefaultVisibility=true)
Definition MainTable.h:75
std::function< void *()> GetTextureFunc
Definition MainTable.h:53
bool DefaultVisibility
Definition MainTable.h:59
std::string Category
Definition MainTable.h:58
GetTextureFunc Texture
Definition MainTable.h:57
Definition MainTable.h:153
TableColumnIdx DisplayOrder
Definition MainTable.h:157
ImU8 SortDirection
Definition MainTable.h:159
float WidthOrWeight
Definition MainTable.h:154
std::strong_ordering operator<=>(const TableColumnSettings &pOther) const
Definition MainTable.h:163
std::strong_ordering operator<=>(const ImGuiID &pOther) const
Definition MainTable.h:167
ImU8 IsStretch
Definition MainTable.h:161
ImU8 IsEnabled
Definition MainTable.h:160
friend void from_json(const nlohmann::json &nlohmann_json_j, TableColumnSettings &nlohmann_json_t)
Definition MainTable.h:189
ImGuiID UserID
Definition MainTable.h:155
bool operator==(const ImGuiID &pOther) const
Definition MainTable.h:175
bool operator==(const TableColumnSettings &pOther) const
Definition MainTable.h:171
TableColumnIdx SortOrder
Definition MainTable.h:158
friend void to_json(nlohmann::json &nlohmann_json_j, const TableColumnSettings &nlohmann_json_t)
Definition MainTable.h:179
Definition MainTable.h:353
TableColumnIdx NextEnabledColumn
Definition MainTable.h:375
TableColumnIdx DisplayOrder
Definition MainTable.h:372
TableColumnIdx SortOrder
Definition MainTable.h:376
ImGuiTableDrawChannelIdx DrawChannelUnfrozen
Definition MainTable.h:379
ImU8 CannotSkipItemsQueue
Definition MainTable.h:389
float InitStretchWeightOrWidth
Definition MainTable.h:361
float ItemWidth
Definition MainTable.h:366
ImGuiTableDrawChannelIdx DrawChannelCurrent
Definition MainTable.h:377
float MinX
Definition MainTable.h:356
float ContentMaxXHeadersUsed
Definition MainTable.h:369
bool IsVisibleY
Definition MainTable.h:383
float ContentMaxXUnfrozen
Definition MainTable.h:368
ImU8 SortDirectionsAvailMask
Definition MainTable.h:392
bool IsRequestOutput
Definition MainTable.h:384
TableColumn()
Definition MainTable.h:395
float ContentMaxXFrozen
Definition MainTable.h:367
TableColumnIdx IndexWithinEnabledSet
Definition MainTable.h:373
ImS16 NameOffset
Definition MainTable.h:371
ImS8 NavLayerCurrent
Definition MainTable.h:387
bool IsSkipItems
Definition MainTable.h:385
ImGuiTableDrawChannelIdx DrawChannelFrozen
Definition MainTable.h:378
ImGuiID UserID
Definition MainTable.h:363
TableColumnIdx PrevEnabledColumn
Definition MainTable.h:374
bool IsEnabledNextFrame
Definition MainTable.h:381
ImU8 AutoFitQueue
Definition MainTable.h:388
ImRect ClipRect
Definition MainTable.h:362
float WidthAuto
Definition MainTable.h:359
ImU8 SortDirection
Definition MainTable.h:390
float WidthRequest
Definition MainTable.h:358
float WorkMaxX
Definition MainTable.h:365
ImU8 SortDirectionsAvailList
Definition MainTable.h:393
float StretchWeight
Definition MainTable.h:360
float WorkMinX
Definition MainTable.h:364
bool IsEnabled
Definition MainTable.h:380
float WidthGiven
Definition MainTable.h:355
bool IsVisibleX
Definition MainTable.h:382
float ContentMaxXHeadersIdeal
Definition MainTable.h:370
float MaxX
Definition MainTable.h:357
bool IsPreserveWidthAuto
Definition MainTable.h:386
ImGuiTableColumnFlags Flags
Definition MainTable.h:354
ImU8 SortDirectionsAvailCount
Definition MainTable.h:391
Definition MainTable.h:199
ImU32 Version
Definition MainTable.h:200
ImGuiTableFlags SaveFlags
Definition MainTable.h:201
float RefScale
Definition MainTable.h:202
std::vector< TableColumnSettings > Columns
Definition MainTable.h:203
Definition MainTable.h:408
ImGuiTableSortSpecs SortSpecs
Definition MainTable.h:480
TableColumnIdx DeclColumnsCount
Definition MainTable.h:484
ImVec2 HostBackupCurrLineSize
Definition MainTable.h:468
ImSpan< TableColumn > Columns
Definition MainTable.h:412
TableColumnIdx ResizedColumn
Definition MainTable.h:488
TableColumnIdx FreezeRowsRequest
Definition MainTable.h:497
ImRect InnerRect
Definition MainTable.h:457
float RowPosY1
Definition MainTable.h:428
float CellSpacingX2
Definition MainTable.h:447
ImGuiTextBuffer ColumnsNames
Definition MainTable.h:476
TableColumnIdx RightMostEnabledColumn
Definition MainTable.h:495
TableColumnIdx HeldHeaderColumn
Definition MainTable.h:490
bool IsDefaultSizingPolicy
Definition MainTable.h:517
TableColumnIdx RightMostStretchedColumn
Definition MainTable.h:494
float BorderX1
Definition MainTable.h:439
TableColumnIdx ReorderColumn
Definition MainTable.h:491
ImU32 BorderColorStrong
Definition MainTable.h:437
ImU32 RowBgColor[2]
Definition MainTable.h:436
int HostBackupItemWidthStackSize
Definition MainTable.h:473
float RowTextBaseline
Definition MainTable.h:431
float RowIndentOffsetX
Definition MainTable.h:432
bool IsInsideRow
Definition MainTable.h:506
ImGuiTableFlags Flags
Definition MainTable.h:410
float MinColumnWidth
Definition MainTable.h:442
bool IsUsingHeaders
Definition MainTable.h:509
ImSpan< ImGuiTableCellData > RowCellData
Definition MainTable.h:414
ImGuiTableColumnSortSpecs SortSpecsSingle
Definition MainTable.h:478
ImDrawListSplitter DrawSplitter
Definition MainTable.h:477
ImVector< ImGuiTableColumnSortSpecs > SortSpecsMulti
Definition MainTable.h:479
float LastFirstRowHeight
Definition MainTable.h:449
bool IsContextPopupOpen
Definition MainTable.h:510
bool IsSettingsDirty
Definition MainTable.h:512
TableColumnIdx RowCellDataCurrent
Definition MainTable.h:501
ImRect WorkRect
Definition MainTable.h:458
float ResizeLockMinContentsX2
Definition MainTable.h:454
ImVec1 HostBackupColumnsOffset
Definition MainTable.h:471
IMGUI_API Table()
Definition MainTable.h:521
float InnerWidth
Definition MainTable.h:450
bool HostSkipItems
Definition MainTable.h:519
float RowMinHeight
Definition MainTable.h:430
ImGuiWindow * OuterWindow
Definition MainTable.h:474
float CellSpacingX1
Definition MainTable.h:446
int RowBgColorCounter
Definition MainTable.h:435
ImS16 InstanceCurrent
Definition MainTable.h:426
ImGuiID ID
Definition MainTable.h:409
float CellPaddingX
Definition MainTable.h:444
ImVec2 HostBackupCursorMaxPos
Definition MainTable.h:469
TableColumnIdx ColumnsEnabledCount
Definition MainTable.h:482
TableColumnIdx ColumnsEnabledFixedCount
Definition MainTable.h:483
TableColumnIdx LastResizedColumn
Definition MainTable.h:489
bool MemoryCompacted
Definition MainTable.h:518
ImRect HostBackupWorkRect
Definition MainTable.h:464
bool IsInitializing
Definition MainTable.h:507
float RefScale
Definition MainTable.h:455
TableColumnIdx ReorderColumnDir
Definition MainTable.h:492
ImGuiTableDrawChannelIdx DummyDrawChannel
Definition MainTable.h:502
ImGuiTableDrawChannelIdx Bg2DrawChannelUnfrozen
Definition MainTable.h:504
ImRect InnerClipRect
Definition MainTable.h:459
ImSpan< TableColumnIdx > DisplayOrderToIndex
Definition MainTable.h:413
float BorderX2
Definition MainTable.h:440
ImGuiTableDrawChannelIdx Bg2DrawChannelCurrent
Definition MainTable.h:503
bool IsResetAllRequest
Definition MainTable.h:514
bool IsLayoutLocked
Definition MainTable.h:505
bool IsSortSpecsDirty
Definition MainTable.h:508
TableColumnIdx HoveredColumnBorder
Definition MainTable.h:486
ImVec2 HostBackupPrevLineSize
Definition MainTable.h:467
bool IsSettingsRequestLoad
Definition MainTable.h:511
ImRect OuterRect
Definition MainTable.h:456
IMGUI_API ~Table()
Definition MainTable.h:525
ImRect HostBackupParentWorkRect
Definition MainTable.h:465
float CellPaddingY
Definition MainTable.h:445
TableColumnIdx FreezeColumnsCount
Definition MainTable.h:500
TableColumnIdx ContextPopupColumn
Definition MainTable.h:496
float ResizedColumnNextWidth
Definition MainTable.h:453
TableColumnIdx HoveredColumnBody
Definition MainTable.h:485
int LastFrameActive
Definition MainTable.h:421
ImGuiWindow * InnerWindow
Definition MainTable.h:475
ImRect Bg2ClipRectForDrawCmd
Definition MainTable.h:462
int CurrentColumn
Definition MainTable.h:425
int CurrentRow
Definition MainTable.h:423
int SettingsOffset
Definition MainTable.h:420
ImRect HostClipRect
Definition MainTable.h:463
ColumnBitMask EnabledMaskByDisplayOrder
Definition MainTable.h:415
ImRect BgClipRect
Definition MainTable.h:460
TableColumnIdx FreezeRowsCount
Definition MainTable.h:498
int ColumnsCount
Definition MainTable.h:422
TableColumnIdx FreezeColumnsRequest
Definition MainTable.h:499
bool IsDefaultDisplayOrder
Definition MainTable.h:513
float HostBackupItemWidth
Definition MainTable.h:472
ImS16 InstanceInteracted
Definition MainTable.h:427
ImVec2 UserOuterSize
Definition MainTable.h:470
TableColumnIdx SortSpecsCount
Definition MainTable.h:481
float ColumnsAutoFitWidth
Definition MainTable.h:452
float RowPosY2
Definition MainTable.h:429
ImGuiTableRowFlags LastRowFlags
Definition MainTable.h:434
TableColumnIdx AutoFitSingleColumn
Definition MainTable.h:487
float HostIndentX
Definition MainTable.h:441
float ColumnsGivenWidth
Definition MainTable.h:451
float OuterPaddingX
Definition MainTable.h:443
ColumnBitMask VisibleMaskByIndex
Definition MainTable.h:417
ColumnBitMask RequestOutputMaskByIndex
Definition MainTable.h:418
TableColumnIdx LeftMostStretchedColumn
Definition MainTable.h:493
ColumnBitMask EnabledMaskByIndex
Definition MainTable.h:416
bool IsResetDisplayOrderRequest
Definition MainTable.h:515
void * RawData
Definition MainTable.h:411
ImGuiTableFlags SettingsLoadedFlags
Definition MainTable.h:419
int CurrentHoveredRow
Definition MainTable.h:424
ImGuiTableRowFlags RowFlags
Definition MainTable.h:433
ImRect Bg0ClipRectForDrawCmd
Definition MainTable.h:461
ImU32 BorderColorLight
Definition MainTable.h:438
ImRect HostBackupInnerClipRect
Definition MainTable.h:466
bool IsUnfrozenRows
Definition MainTable.h:516
float LastOuterHeight
Definition MainTable.h:448