3#ifndef IMGUI_DEFINE_MATH_OPERATORS
4#define IMGUI_DEFINE_MATH_OPERATORS
9#include "../arcdps_structs.h"
10#include "../ExtensionTranslations.h"
11#include "../ImGui_Math.h"
12#include "../Localization.h"
13#include "../Widgets.h"
22#include <nlohmann/json.hpp>
26#pragma warning(disable : 4267)
27#pragma warning(disable : 4244)
30 static constexpr int TABLE_DRAW_CHANNEL_BG0 = 0;
31 static constexpr int TABLE_DRAW_CHANNEL_BG2_FROZEN = 1;
32 static constexpr int TABLE_DRAW_CHANNEL_NOCLIP = 2;
34 static constexpr float TABLE_BORDER_SIZE = 1.0f;
35 static constexpr float TABLE_RESIZE_SEPARATOR_HALF_THICKNESS = 4.0f;
36 static constexpr float TABLE_RESIZE_SEPARATOR_FEEDBACK_TIMER = 0.06f;
57 std::function<std::string()>
Name;
61 std::function<std::string()>
Popup;
63 MainTableColumn(ImU32 pUserId,
const std::function<std::string()>& pName,
const std::function<
void*()>& pTexture, std::string pCategory,
bool pDefaultVisibility =
true)
72 requires std::is_enum_v<E> && std::convertible_to<std::underlying_type_t<E>, ImU32>
73 MainTableColumn(E pUserId,
const std::function<std::string()>& pName,
const std::function<
void*()>& pTexture, std::string pCategory,
bool pDefaultVisibility =
true)
74 :
MainTableColumn(std::to_underlying(pUserId), pName, pTexture, pCategory, pDefaultVisibility) {}
76 MainTableColumn(ImU32 pUserId,
const std::function<std::string()>& pName,
const std::function<
void*()>& pTexture, std::string pCategory,
const std::function<std::string()>& pPopup,
bool pDefaultVisibility =
true)
85 requires std::is_enum_v<E> && std::convertible_to<std::underlying_type_t<E>, ImU32>
86 MainTableColumn(E pUserId,
const std::function<std::string()>& pName,
const std::function<
void*()>& pTexture, std::string pCategory,
const std::function<std::string()>& pPopup,
bool pDefaultVisibility =
true)
87 :
MainTableColumn(std::to_underlying(pUserId), pName, pTexture, pCategory, pPopup, pDefaultVisibility) {}
99 requires T < std::numeric_limits<TableColumnIdx>::max();
127 template<
size_t MaxColumnCount = 64>
151 return mSpecificColumnsActive;
165 return UserID <=> pOther.
UserID;
169 return UserID <=> pOther;
181 nlohmann_json_j[
"WidthOrWeight"] = nlohmann_json_t.
WidthOrWeight;
182 nlohmann_json_j[
"UserID"] = nlohmann_json_t.
UserID;
183 nlohmann_json_j[
"DisplayOrder"] = nlohmann_json_t.
DisplayOrder;
184 nlohmann_json_j[
"SortOrder"] = nlohmann_json_t.
SortOrder;
185 nlohmann_json_j[
"SortDirection"] = nlohmann_json_t.
SortDirection;
186 nlohmann_json_j[
"IsEnabled"] = nlohmann_json_t.
IsEnabled;
187 nlohmann_json_j[
"IsStretch"] = nlohmann_json_t.
IsStretch;
191 nlohmann_json_j.at(
"WidthOrWeight").get_to(nlohmann_json_t.
WidthOrWeight);
192 nlohmann_json_j.at(
"UserID").get_to(nlohmann_json_t.
UserID);
193 nlohmann_json_j.at(
"DisplayOrder").get_to(nlohmann_json_t.
DisplayOrder);
194 nlohmann_json_j.at(
"SortOrder").get_to(nlohmann_json_t.
SortOrder);
195 nlohmann_json_t.
SortDirection = nlohmann_json_j.at(
"SortDirection").get<ImU8>();
196 nlohmann_json_t.
IsEnabled = nlohmann_json_j.at(
"IsEnabled").get<ImU8>();
197 nlohmann_json_t.
IsStretch = nlohmann_json_j.at(
"IsStretch").get<ImU8>();
218 virtual void Sort(
const ImGuiTableColumnSortSpecs* mColumnSortSpecs) = 0;
260 const std::vector<MainTableColumn>& mColumns;
262 std::atomic_bool mSortNeeded =
false;
266 std::vector<size_t> Indices;
267 std::map<size_t, Category> Categories;
269 Category mCategories;
271 void DrawColumnSetupMenuIteratorFunc(Category pCategory, std::string pCatName =
"");
273 std::atomic_bool mSpecificColumnsUpdate =
false;
274 bool mSpecificColumnsActive =
false;
275 std::vector<size_t> mSpecificColumnCache;
277 bool mCustomColumnsActiveTemp =
false;
284 void NextRow(ImGuiTableRowFlags row_flags = 0,
float min_row_height = 0.0f);
306 void SetupColumn(
const char* label, ImGuiTableColumnFlags flags,
float init_width_or_weight, ImGuiID user_id);
307 void ColumnHeader(
const char* label,
bool show_label, ImTextureID texture,
Alignment alignment,
const char* popupText);
316 template<
typename... Args>
322 bool SpinnerAligned(
const char* label,
float radius,
float thickness,
const ImU32& color);
325 bool Begin(
const char* str_id,
int columns_count, ImGuiTableFlags flags,
const ImVec2& outer_size,
float inner_width, ImGuiWindowFlags child_window_flags);
397 memset(
this, 0,
sizeof(*
this));
523 memset(
this, 0,
sizeof(*
this));
532 static ImGuiTableFlags TableFixFlags(ImGuiTableFlags flags, ImGuiWindow* outer_window);
542 void BeginInitMemory(
int columns_count);
545 void ResetSettings();
546 void LoadSettingsCustom();
547 void SaveSettingsCustom();
548 void MigrateIniSettings();
551 void BeginApplyRequests();
554 ImGuiTableSettings* GetBoundSettings();
562 void SortSpecsBuild();
565 void TableSetupColumnFlags(
TableColumn* column, ImGuiTableColumnFlags flags_in);
601 void MergeDrawChannels();
607 void SetupColumnFlags(
TableColumn* column, ImGuiTableColumnFlags flags_in);
610 float GetMaxColumnWidth(
int column_n);
628 void SetupDrawChannels();
634 void UpdateBorders();
636 void SortSpecsSanitize();
641 static ImGuiSortDirection GetColumnAvailSortDirection(
TableColumn* column,
int n) {
642 IM_ASSERT(n < column->SortDirectionsAvailCount);
649 ImGuiID GetColumnResizeID(
int column_n,
int instance_no) {
657 void SetColumnWidthAutoSingle(
int column_n) {
660 if (!column->IsEnabled)
662 column->CannotSkipItemsQueue = (1 << 0);
666 void BeginCell(
int column_n);
670 void SetBgColor(ImGuiTableBgTarget target, ImU32 color,
int column_n = -1);
674 void SetColumnSortDirection(
int column_n, ImGuiSortDirection sort_direction,
bool append_to_sort_specs);
679 IM_STATIC_ASSERT(ImGuiSortDirection_None == 0 && ImGuiSortDirection_Ascending == 1 && ImGuiSortDirection_Descending == 2);
680 ImGuiSortDirection GetColumnNextSortDirection(TableColumn* column);
683 void SetColumnWidth(
int column_n,
float width);
685 void UpdateColumnsWeightFromWidth();
688 template<
size_t MaxColumnCount>
689 requires SmallerThanMaxColumnAmount<MaxColumnCount>
691 : mMainWindow(pMainWindow), mColumns(pColumns), mFlags(pFlags) {
693 IM_ASSERT(mColumns.size() < MaxColumnCount);
698 for (
size_t i = 0; i < mColumns.size(); ++i) {
699 const auto& column = mColumns[i];
700 std::string cat = column.Category;
702 std::vector<size_t> token;
704 if ((pos = cat.find(
'.')) != std::string::npos) {
705 std::string sub = cat.substr(0, pos);
707 std::from_chars(sub.data(), sub.data() + sub.size(), dat);
708 token.push_back(dat);
709 cat.erase(0, pos + 1);
712 std::from_chars(cat.data(), cat.data() + cat.size(), dat);
713 token.push_back(dat);
719 mCategories.Indices.emplace_back(i);
723 Category* category = &mCategories;
724 for (
size_t tok : token) {
725 category = &category->Categories[tok];
728 category->Indices.emplace_back(i);
732 template<
size_t MaxColumnCount>
735 ImGuiTableFlags tableFlags = ImGuiTableFlags_BordersInnerH | ImGuiTableFlags_Hideable | ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_Sortable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_PadOuterX | ImGuiTableFlags_ScrollY;
737 if (getShowAlternatingBackground()) {
738 tableFlags |= ImGuiTableFlags_RowBg;
741 ImVec2 outerSize(0.f, getMaxHeightActive() ? mMainWindow->
GetMaxCursorPos() : 0.f);
743 if (Begin(getTableId().c_str(), mColumns.size(), tableFlags, outerSize, 0,
744 getShowScrollbar() ? 0 : ImGuiWindowFlags_NoScrollbar)) {
757 for (
int i = 0; i < mColumns.size(); ++i) {
758 const auto& column = mColumns[i];
760 ImGuiTableColumnFlags columnFlags = ImGuiTableColumnFlags_PreferSortDescending;
762 columnFlags |= ImGuiTableColumnFlags_IndentEnable;
764 if (!column.DefaultVisibility) {
765 columnFlags |= ImGuiTableColumnFlags_DefaultHide;
767 SetupColumn(column.Name().c_str(), columnFlags, 0, column.UserId);
771 SetupScrollFreeze(0, 1);
773 NextRow(ImGuiTableRowFlags_Headers);
775 for (
const auto& column : mColumns) {
777 ColumnHeader(column.Name().c_str(),
false, column.Texture(), getHeaderAlignment(), column.Popup().c_str());
784 if (ImGuiTableSortSpecs* sortSpecs = GetSortSpecs()) {
785 if (sortSpecs->SpecsDirty) {
789 bool expected =
true;
790 if (mSortNeeded.compare_exchange_strong(expected,
false)) {
791 Sort(sortSpecs->Specs);
793 sortSpecs->SpecsDirty =
false;
807 template<
size_t MaxColumnCount>
810 for (
const auto& index : pCategory.Indices) {
811 MenuItemColumnVisibility(index);
814 for (
const auto& [key, value] : pCategory.Categories) {
815 std::string catName = pCatName;
816 if (!catName.empty()) catName.append(
".");
817 catName.append(std::to_string(key));
818 if (ImGui::BeginMenu(getCategoryName(catName))) {
819 DrawColumnSetupMenuIteratorFunc(value, catName);
826 template<
size_t MaxColumnCount>
827 requires SmallerThanMaxColumnAmount<MaxColumnCount>
830 DrawColumnSetupSubMenu();
836 template<
size_t MaxColumnCount>
839 if (getCustomColumnsFeatureActive()) {
841 if (getCustomColumnsActive()) {
842 mSpecificColumnsUpdate =
true;
843 mSpecificColumnsActive =
true;
848 DrawColumnSetupMenuIteratorFunc(mCategories);
851 template<
size_t MaxColumnCount>
854 mSpecificColumnsUpdate =
true;
855 mSpecificColumnsActive =
true;
857 mSpecificColumnCache = pNewColumns;
860 template<
size_t MaxColumnCount>
863 mSpecificColumnsUpdate =
true;
864 mSpecificColumnsActive =
false;
867 template<
size_t MaxColumnCount>
874 int& maxDisplayed = getMaxDisplayed();
876 if (maxDisplayed < 0) {
884 template<
size_t MaxColumnCount>
906 template<
size_t MaxColumnCount>
924 template<
size_t MaxColumnCount>
927 if (mCurrentRow < getMaxDisplayed()) {
935 template<
size_t MaxColumnCount>
939 if ((flags & ImGuiTableFlags_SizingMask_) == 0)
940 flags |= ((flags & ImGuiTableFlags_ScrollX) || (outer_window->Flags & ImGuiWindowFlags_AlwaysAutoResize)) ? ImGuiTableFlags_SizingFixedFit : ImGuiTableFlags_SizingStretchSame;
943 if ((flags & ImGuiTableFlags_SizingMask_) == ImGuiTableFlags_SizingFixedSame)
944 flags |= ImGuiTableFlags_NoKeepColumnsVisible;
947 if (flags & ImGuiTableFlags_Resizable)
948 flags |= ImGuiTableFlags_BordersInnerV;
951 if (flags & (ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY))
952 flags &= ~(ImGuiTableFlags_NoHostExtendX | ImGuiTableFlags_NoHostExtendY);
955 if (flags & ImGuiTableFlags_NoBordersInBodyUntilResize)
956 flags &= ~ImGuiTableFlags_NoBordersInBody;
959 if ((flags & (ImGuiTableFlags_Resizable | ImGuiTableFlags_Hideable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Sortable)) == 0)
960 flags |= ImGuiTableFlags_NoSavedSettings;
964 ImGuiWindow* window_for_settings = outer_window->RootWindowDockStop;
966 ImGuiWindow* window_for_settings = outer_window->RootWindow;
968 if (window_for_settings->Flags & ImGuiWindowFlags_NoSavedSettings)
969 flags |= ImGuiTableFlags_NoSavedSettings;
974 template<
size_t MaxColumnCount>
975 requires SmallerThanMaxColumnAmount<MaxColumnCount>
976 void MainTable<MaxColumnCount>::BeginInitMemory(
int columns_count) {
978 ImSpanAllocator<3> span_allocator;
979 span_allocator.ReserveBytes(0, columns_count *
sizeof(TableColumn));
980 span_allocator.ReserveBytes(1, columns_count *
sizeof(
TableColumnIdx));
981 span_allocator.ReserveBytes(2, columns_count *
sizeof(ImGuiTableCellData));
982 mTable.
RawData = IM_ALLOC(span_allocator.GetArenaSizeInBytes());
983 memset(mTable.
RawData, 0, span_allocator.GetArenaSizeInBytes());
984 span_allocator.SetArenaBasePtr(mTable.
RawData);
985 span_allocator.GetSpan(0, &mTable.
Columns);
990 template<
size_t MaxColumnCount>
991 requires SmallerThanMaxColumnAmount<MaxColumnCount>
992 void MainTable<MaxColumnCount>::ResetSettings() {
999 template<
size_t MaxColumnCount>
1000 requires SmallerThanMaxColumnAmount<MaxColumnCount>
1001 void MainTable<MaxColumnCount>::LoadSettingsCustom() {
1003 if (mTable.
Flags & ImGuiTableFlags_NoSavedSettings)
1006 TableSettings& settings = getTableSettings();
1009 if (settings.Version == 0) {
1010 MigrateIniSettings();
1011 settings.Version = 1;
1017 mTable.
RefScale = settings.RefScale;
1020 ColumnBitMask display_order_mask;
1021 for (
int idx = 0; idx < mTable.
Columns.size(); ++idx) {
1022 TableColumn* column = &mTable.
Columns[idx];
1025 column->UserID = mColumns[idx].UserId;
1027 const auto& column_settings = std::find(settings.Columns.begin(), settings.Columns.end(), column->UserID);
1028 if (column_settings == settings.Columns.end()) {
1032 if (settings.SaveFlags & ImGuiTableFlags_Resizable) {
1033 if (column_settings->IsStretch)
1034 column->StretchWeight = column_settings->WidthOrWeight;
1036 column->WidthRequest = column_settings->WidthOrWeight;
1037 column->AutoFitQueue = 0x00;
1039 if (settings.SaveFlags & ImGuiTableFlags_Reorderable)
1040 column->DisplayOrder = column_settings->DisplayOrder;
1043 if (column->DisplayOrder >= 0) display_order_mask.set(column->DisplayOrder);
1044 column->IsEnabled = column->IsEnabledNextFrame = column_settings->IsEnabled;
1045 column->SortOrder = column_settings->SortOrder;
1046 column->SortDirection = column_settings->SortDirection;
1050 if (display_order_mask.count() != settings.Columns.size())
1051 for (
int column_n = 0; column_n < mTable.
ColumnsCount; column_n++)
1055 for (
int column_n = 0; column_n < mTable.
ColumnsCount; column_n++)
1059 template<
size_t MaxColumnCount>
1060 requires SmallerThanMaxColumnAmount<MaxColumnCount>
1061 void MainTable<MaxColumnCount>::BeginApplyRequests() {
1092 IM_ASSERT(reorder_dir == -1 || reorder_dir == +1);
1093 IM_ASSERT(mTable.
Flags & ImGuiTableFlags_Reorderable);
1095 TableColumn* dst_column = &mTable.
Columns[(reorder_dir == -1) ? src_column->PrevEnabledColumn : src_column->NextEnabledColumn];
1096 IM_UNUSED(dst_column);
1097 const int src_order = src_column->DisplayOrder;
1098 const int dst_order = dst_column->DisplayOrder;
1100 for (
int order_n = src_order + reorder_dir; order_n != dst_order + reorder_dir; order_n += reorder_dir)
1102 IM_ASSERT(dst_column->DisplayOrder == dst_order - reorder_dir);
1106 for (
int column_n = 0; column_n < mTable.
ColumnsCount; column_n++)
1122 template<
size_t MaxColumnCount>
1123 requires SmallerThanMaxColumnAmount<MaxColumnCount>
1124 ImGuiTableSettings* MainTable<MaxColumnCount>::GetBoundSettings() {
1126 ImGuiContext& g = *GImGui;
1127 ImGuiTableSettings* settings = g.SettingsTables.ptr_from_offset(mTable.
SettingsOffset);
1128 IM_ASSERT(settings->ID == mTable.
ID);
1136 template<
size_t MaxColumnCount>
1137 requires SmallerThanMaxColumnAmount<MaxColumnCount>
1138 void MainTable<MaxColumnCount>::UpdateLayout() {
1139 ImGuiContext& g = *GImGui;
1142 const ImGuiTableFlags table_sizing_policy = (mTable.
Flags & ImGuiTableFlags_SizingMask_);
1147 mTable.
MinColumnWidth = ImMax(1.0f, g.Style.FramePadding.x * 1.0f);
1151 int count_fixed = 0;
1152 int count_stretch = 0;
1153 int last_visible_column_idx = -1;
1154 bool has_auto_fit_request =
false;
1155 bool has_resizable =
false;
1156 float stretch_sum_width_auto = 0.0f;
1157 float fixed_max_width_auto = 0.0f;
1158 for (
int order_n = 0; order_n < mTable.
ColumnsCount; order_n++) {
1160 if (column_n != order_n)
1162 TableColumn* column = &mTable.
Columns[column_n];
1168 SetupColumnFlags(column, ImGuiTableColumnFlags_None);
1169 column->NameOffset = -1;
1171 column->InitStretchWeightOrWidth = -1.0f;
1175 if (!(mTable.
Flags & ImGuiTableFlags_Hideable) || (column->Flags & ImGuiTableColumnFlags_NoHide))
1176 column->IsEnabledNextFrame =
true;
1177 if (column->IsEnabled != column->IsEnabledNextFrame) {
1178 column->IsEnabled = column->IsEnabledNextFrame;
1180 if (!column->IsEnabled && column->SortOrder != -1)
1183 if (column->SortOrder > 0 && !(mTable.
Flags & ImGuiTableFlags_SortMulti))
1187 const bool start_auto_fit = (column->Flags & ImGuiTableColumnFlags_WidthFixed) ? (column->WidthRequest < 0.0f) : (column->StretchWeight < 0.0f);
1189 column->AutoFitQueue = column->CannotSkipItemsQueue = (1 << 3) - 1;
1191 if (!column->IsEnabled) {
1192 column->IndexWithinEnabledSet = -1;
1197 column->PrevEnabledColumn = (
TableColumnIdx) last_visible_column_idx;
1198 column->NextEnabledColumn = -1;
1199 if (last_visible_column_idx != -1)
1204 last_visible_column_idx = column_n;
1205 IM_ASSERT(column->IndexWithinEnabledSet <= column->DisplayOrder);
1209 if (!column->IsPreserveWidthAuto)
1210 column->WidthAuto = GetColumnWidthAuto(column);
1213 const bool column_is_resizable = (column->Flags & ImGuiTableColumnFlags_NoResize) == 0;
1214 if (column_is_resizable)
1215 has_resizable =
true;
1216 if ((column->Flags & ImGuiTableColumnFlags_WidthFixed) && column->InitStretchWeightOrWidth > 0.0f && !column_is_resizable)
1217 column->WidthAuto = column->InitStretchWeightOrWidth;
1219 if (column->AutoFitQueue != 0x00)
1220 has_auto_fit_request =
true;
1221 if (column->Flags & ImGuiTableColumnFlags_WidthStretch) {
1222 stretch_sum_width_auto += column->WidthAuto;
1225 fixed_max_width_auto = ImMax(fixed_max_width_auto, column->WidthAuto);
1229 if ((mTable.
Flags & ImGuiTableFlags_Sortable) && mTable.
SortSpecsCount == 0 && !(mTable.
Flags & ImGuiTableFlags_SortTristate))
1239 if (has_auto_fit_request)
1243 float sum_width_requests = 0.0f;
1244 float stretch_sum_weights = 0.0f;
1246 for (
int column_n = 0; column_n < mTable.
ColumnsCount; column_n++) {
1249 TableColumn* column = &mTable.
Columns[column_n];
1251 const bool column_is_resizable = (column->Flags & ImGuiTableColumnFlags_NoResize) == 0;
1252 if (column->Flags & ImGuiTableColumnFlags_WidthFixed) {
1254 float width_auto = column->WidthAuto;
1255 if (table_sizing_policy == ImGuiTableFlags_SizingFixedSame && (column->AutoFitQueue != 0x00 || !column_is_resizable))
1256 width_auto = fixed_max_width_auto;
1260 if (column->AutoFitQueue != 0x00)
1261 column->WidthRequest = width_auto;
1262 else if ((column->Flags & ImGuiTableColumnFlags_WidthFixed) && !column_is_resizable && mTable.
RequestOutputMaskByIndex.test(column_n))
1263 column->WidthRequest = width_auto;
1271 if (column->AutoFitQueue > 0x01 && mTable.
IsInitializing && !column->IsPreserveWidthAuto)
1272 column->WidthRequest = ImMax(column->WidthRequest, mTable.
MinColumnWidth * 4.0f);
1273 sum_width_requests += column->WidthRequest;
1276 if (column->AutoFitQueue != 0x00 || column->StretchWeight < 0.0f || !column_is_resizable) {
1277 if (column->InitStretchWeightOrWidth > 0.0f)
1278 column->StretchWeight = column->InitStretchWeightOrWidth;
1279 else if (table_sizing_policy == ImGuiTableFlags_SizingStretchProp)
1280 column->StretchWeight = (column->WidthAuto / stretch_sum_width_auto) * count_stretch;
1282 column->StretchWeight = 1.0f;
1285 stretch_sum_weights += column->StretchWeight;
1291 column->IsPreserveWidthAuto =
false;
1297 const ImRect work_rect = mTable.
WorkRect;
1299 const float width_avail = ((mTable.
Flags & ImGuiTableFlags_ScrollX) && mTable.
InnerWidth == 0.0f) ? mTable.
InnerClipRect.GetWidth() : work_rect.GetWidth();
1300 const float width_avail_for_stretched_columns = width_avail - width_spacings - sum_width_requests;
1301 float width_remaining_for_stretched_columns = width_avail_for_stretched_columns;
1303 for (
int column_n = 0; column_n < mTable.
ColumnsCount; column_n++) {
1306 TableColumn* column = &mTable.
Columns[column_n];
1309 if (column->Flags & ImGuiTableColumnFlags_WidthStretch) {
1310 float weight_ratio = column->StretchWeight / stretch_sum_weights;
1311 column->WidthRequest = IM_FLOOR(ImMax(width_avail_for_stretched_columns * weight_ratio, mTable.
MinColumnWidth) + 0.01f);
1312 width_remaining_for_stretched_columns -= column->WidthRequest;
1318 column->Flags |= ImGuiTableColumnFlags_NoDirectResize_;
1321 column->WidthGiven = ImFloor(ImMax(column->WidthRequest, mTable.
MinColumnWidth));
1327 if (width_remaining_for_stretched_columns >= 1.0f && !(mTable.
Flags & ImGuiTableFlags_PreciseWidths))
1328 for (
int order_n = mTable.
ColumnsCount - 1; stretch_sum_weights > 0.0f && width_remaining_for_stretched_columns >= 1.0f && order_n >= 0; order_n--) {
1332 if (!(column->Flags & ImGuiTableColumnFlags_WidthStretch))
1334 column->WidthRequest += 1.0f;
1335 column->WidthGiven += 1.0f;
1336 width_remaining_for_stretched_columns -= 1.0f;
1342 const bool is_hovering_table = ImGui::ItemHoverable(mouse_hit_rect, 0);
1348 float offset_x = ((mTable.
FreezeColumnsCount > 0) ? mTable.
OuterRect.Min.x : work_rect.Min.x) + mTable.OuterPaddingX - mTable.CellSpacingX1;
1353 for (
int order_n = 0; order_n < mTable.
ColumnsCount; order_n++) {
1355 TableColumn* column = &mTable.
Columns[column_n];
1360 offset_x += work_rect.Min.x - mTable.
OuterRect.Min.x;
1361 offset_x_frozen =
false;
1365 column->Flags &= ~ImGuiTableColumnFlags_StatusMask_;
1370 column->MinX = column->MaxX = column->WorkMinX = column->ClipRect.Min.x = column->ClipRect.Max.x = offset_x;
1371 column->WidthGiven = 0.0f;
1372 column->ClipRect.Min.y = work_rect.Min.y;
1373 column->ClipRect.Max.y = FLT_MAX;
1374 column->ClipRect.ClipWithFull(host_clip_rect);
1375 column->IsVisibleX = column->IsVisibleY = column->IsRequestOutput =
false;
1376 column->IsSkipItems =
true;
1377 column->ItemWidth = 1.0f;
1382 if (is_hovering_table && g.IO.MousePos.x >= column->ClipRect.Min.x && g.IO.MousePos.x < column->ClipRect.Max.x)
1386 column->MinX = offset_x;
1389 float max_width = GetMaxColumnWidth(column_n);
1390 column->WidthGiven = ImMin(column->WidthGiven, max_width);
1391 column->WidthGiven = ImMax(column->WidthGiven, ImMin(column->WidthRequest, mTable.
MinColumnWidth));
1401 column->ItemWidth = ImFloor(column->WidthGiven * 0.65f);
1402 column->ClipRect.Min.x = column->MinX;
1403 column->ClipRect.Min.y = work_rect.Min.y;
1404 column->ClipRect.Max.x = column->MaxX;
1405 column->ClipRect.Max.y = FLT_MAX;
1406 column->ClipRect.ClipWithFull(host_clip_rect);
1415 column->IsVisibleX = (column->ClipRect.Max.x > column->ClipRect.Min.x);
1416 column->IsVisibleY =
true;
1417 const bool is_visible = column->IsVisibleX;
1422 column->IsRequestOutput = is_visible || column->AutoFitQueue != 0 || column->CannotSkipItemsQueue != 0;
1423 if (column->IsRequestOutput)
1427 column->IsSkipItems = !column->IsEnabled || mTable.
HostSkipItems;
1428 if (column->IsSkipItems)
1429 IM_ASSERT(!is_visible);
1432 column->Flags |= ImGuiTableColumnFlags_IsEnabled;
1434 column->Flags |= ImGuiTableColumnFlags_IsVisible;
1435 if (column->SortOrder != -1)
1436 column->Flags |= ImGuiTableColumnFlags_IsSorted;
1438 column->Flags |= ImGuiTableColumnFlags_IsHovered;
1450 column->ContentMaxXFrozen = column->ContentMaxXUnfrozen = column->WorkMinX;
1451 column->ContentMaxXHeadersUsed = column->ContentMaxXHeadersIdeal = column->WorkMinX;
1455 column->AutoFitQueue >>= 1;
1456 column->CannotSkipItemsQueue >>= 1;
1460 host_clip_rect.Min.x = ImClamp(column->MaxX + TABLE_BORDER_SIZE, host_clip_rect.Min.x, host_clip_rect.Max.x);
1471 if (g.IO.MousePos.x >= unused_x1)
1474 if (has_resizable ==
false && (mTable.
Flags & ImGuiTableFlags_Resizable))
1475 mTable.
Flags &= ~ImGuiTableFlags_Resizable;
1481 mTable.
Flags &= ~ImGuiTableFlags_NoHostExtendX;
1482 if (mTable.
Flags & ImGuiTableFlags_NoHostExtendX) {
1491 SetupDrawChannels();
1494 if (mTable.
Flags & ImGuiTableFlags_Resizable)
1523 if (mTable.
Flags & ImGuiTableFlags_NoClip)
1524 mTable.
DrawSplitter.SetCurrentChannel(inner_window->DrawList, TABLE_DRAW_CHANNEL_NOCLIP);
1526 inner_window->DrawList->PushClipRect(inner_window->ClipRect.Min, inner_window->ClipRect.Max,
false);
1529 template<
size_t MaxColumnCount>
1530 requires SmallerThanMaxColumnAmount<MaxColumnCount>
1531 void MainTable<MaxColumnCount>::SortSpecsBuild() {
1533 SortSpecsSanitize();
1537 ImGuiTableColumnSortSpecs* sort_specs = (mTable.
SortSpecsCount == 0) ? NULL : (mTable.SortSpecsCount == 1) ? &mTable.SortSpecsSingle
1538 : mTable.SortSpecsMulti.Data;
1539 for (
int column_n = 0; column_n < mTable.
ColumnsCount; column_n++) {
1540 TableColumn* column = &mTable.
Columns[column_n];
1541 if (column->SortOrder == -1)
1544 ImGuiTableColumnSortSpecs* sort_spec = &sort_specs[column->SortOrder];
1545 sort_spec->ColumnUserID = column->UserID;
1548 sort_spec->SortDirection = column->SortDirection;
1556 template<
size_t MaxColumnCount>
1557 requires SmallerThanMaxColumnAmount<MaxColumnCount>
1558 void MainTable<MaxColumnCount>::TableSetupColumnFlags(TableColumn* column, ImGuiTableColumnFlags flags_in) {
1559 ImGuiTableColumnFlags flags = flags_in;
1562 if ((flags & ImGuiTableColumnFlags_WidthMask_) == 0) {
1563 const ImGuiTableFlags table_sizing_policy = (mTable.
Flags & ImGuiTableFlags_SizingMask_);
1564 if (table_sizing_policy == ImGuiTableFlags_SizingFixedFit || table_sizing_policy == ImGuiTableFlags_SizingFixedSame)
1565 flags |= ImGuiTableColumnFlags_WidthFixed;
1567 flags |= ImGuiTableColumnFlags_WidthStretch;
1569 IM_ASSERT(ImIsPowerOfTwo(flags & ImGuiTableColumnFlags_WidthMask_));
1573 if ((mTable.
Flags & ImGuiTableFlags_Resizable) == 0)
1574 flags |= ImGuiTableColumnFlags_NoResize;
1577 if ((flags & ImGuiTableColumnFlags_NoSortAscending) && (flags & ImGuiTableColumnFlags_NoSortDescending))
1578 flags |= ImGuiTableColumnFlags_NoSort;
1581 if ((flags & ImGuiTableColumnFlags_IndentMask_) == 0)
1582 flags |= (mTable.
Columns.index_from_ptr(column) == 0) ? ImGuiTableColumnFlags_IndentEnable : ImGuiTableColumnFlags_IndentDisable;
1590 column->Flags = flags | (column->Flags & ImGuiTableColumnFlags_StatusMask_);
1593 column->SortDirectionsAvailCount = column->SortDirectionsAvailMask = column->SortDirectionsAvailList = 0;
1594 if (mTable.
Flags & ImGuiTableFlags_Sortable) {
1595 int count = 0, mask = 0, list = 0;
1596 if ((flags & ImGuiTableColumnFlags_PreferSortAscending) != 0 && (flags & ImGuiTableColumnFlags_NoSortAscending) == 0) {
1597 mask |= 1 << ImGuiSortDirection_Ascending;
1598 list |= ImGuiSortDirection_Ascending << (count << 1);
1601 if ((flags & ImGuiTableColumnFlags_PreferSortDescending) != 0 && (flags & ImGuiTableColumnFlags_NoSortDescending) == 0) {
1602 mask |= 1 << ImGuiSortDirection_Descending;
1603 list |= ImGuiSortDirection_Descending << (count << 1);
1606 if ((flags & ImGuiTableColumnFlags_PreferSortAscending) == 0 && (flags & ImGuiTableColumnFlags_NoSortAscending) == 0) {
1607 mask |= 1 << ImGuiSortDirection_Ascending;
1608 list |= ImGuiSortDirection_Ascending << (count << 1);
1611 if ((flags & ImGuiTableColumnFlags_PreferSortDescending) == 0 && (flags & ImGuiTableColumnFlags_NoSortDescending) == 0) {
1612 mask |= 1 << ImGuiSortDirection_Descending;
1613 list |= ImGuiSortDirection_Descending << (count << 1);
1616 if ((mTable.
Flags & ImGuiTableFlags_SortTristate) || count == 0) {
1617 mask |= 1 << ImGuiSortDirection_None;
1620 column->SortDirectionsAvailList = (ImU8) list;
1621 column->SortDirectionsAvailMask = (ImU8) mask;
1622 column->SortDirectionsAvailCount = (ImU8) count;
1623 FixColumnSortDirection(column);
1627 template<
size_t MaxColumnCount>
1628 requires SmallerThanMaxColumnAmount<MaxColumnCount>
1629 void MainTable<MaxColumnCount>::EndRow() {
1630 ImGuiContext& g = *GImGui;
1631 ImGuiWindow* window = g.CurrentWindow;
1640 window->DC.CursorPos.y = mTable.
RowPosY2;
1643 const float bg_y1 = mTable.
RowPosY1;
1644 const float bg_y2 = mTable.
RowPosY2;
1655 if (mTable.
RowBgColor[0] != IM_COL32_DISABLE)
1657 else if (mTable.
Flags & ImGuiTableFlags_RowBg)
1658 bg_col0 = ImGui::GetColorU32((mTable.
RowBgColorCounter & 1) ? ImGuiCol_TableRowBgAlt : ImGuiCol_TableRowBg);
1659 if (mTable.
RowBgColor[1] != IM_COL32_DISABLE)
1663 ImRect row_rect(mTable.
WorkRect.Min.x, bg_y1, mTable.
WorkRect.Max.x, bg_y2);
1669 if (ImGui::IsWindowHovered() && ImGui::IsMouseHoveringRect(row_rect.Min, row_rect.Max,
false) && (mTable.
CurrentRow > 0 && mTable.
IsUsingHeaders)) {
1672 if (getHighlightHoveredRows()) {
1673 bg_col1 = ImGui::GetColorU32(ImGuiCol_FrameBgHovered);
1681 ImU32 border_col = 0;
1682 const float border_size = TABLE_BORDER_SIZE;
1684 if (mTable.
Flags & ImGuiTableFlags_BordersInnerH)
1688 const bool draw_strong_bottom_border = unfreeze_rows_actual;
1689 if ((bg_col0 | bg_col1 | border_col) != 0 || draw_strong_bottom_border || draw_cell_bg_color) {
1692 if ((mTable.
Flags & ImGuiTableFlags_NoClip) == 0)
1694 mTable.
DrawSplitter.SetCurrentChannel(window->DrawList, TABLE_DRAW_CHANNEL_BG0);
1699 if (bg_col0 || bg_col1) {
1700 if (bg_col0 != 0 && row_rect.Min.y < row_rect.Max.y)
1701 window->DrawList->AddRectFilled(row_rect.Min, row_rect.Max, bg_col0);
1702 if (bg_col1 != 0 && row_rect.Min.y < row_rect.Max.y)
1703 window->DrawList->AddRectFilled(row_rect.Min, row_rect.Max, bg_col1);
1707 if (draw_cell_bg_color) {
1709 for (ImGuiTableCellData* cell_data = &mTable.
RowCellData[0]; cell_data <= cell_data_end; cell_data++) {
1710 const TableColumn* column = &mTable.
Columns[cell_data->Column];
1711 ImRect cell_bg_rect = GetCellBgRect(cell_data->Column);
1713 cell_bg_rect.Min.x = ImMax(cell_bg_rect.Min.x, column->ClipRect.Min.x);
1714 cell_bg_rect.Max.x = ImMin(cell_bg_rect.Max.x, column->MaxX);
1715 window->DrawList->AddRectFilled(cell_bg_rect.Min, cell_bg_rect.Max, cell_data->BgColor);
1721 window->DrawList->AddLine(ImVec2(mTable.
BorderX1, bg_y1), ImVec2(mTable.
BorderX2, bg_y1), border_col, border_size);
1724 if (draw_strong_bottom_border && bg_y2 >= mTable.
BgClipRect.Min.y && bg_y2 < mTable.
BgClipRect.Max.y)
1731 if (unfreeze_rows_request)
1732 for (
int column_n = 0; column_n < mTable.
ColumnsCount; column_n++) {
1733 TableColumn* column = &mTable.
Columns[column_n];
1734 column->NavLayerCurrent = (ImS8) ((column_n < mTable.
FreezeColumnsCount) ? ImGuiNavLayer_Menu : ImGuiNavLayer_Main);
1736 if (unfreeze_rows_actual) {
1741 float y0 = ImMax(mTable.
RowPosY2 + 1, window->InnerClipRect.Min.y);
1750 for (
int column_n = 0; column_n < mTable.
ColumnsCount; column_n++) {
1751 TableColumn* column = &mTable.
Columns[column_n];
1752 column->DrawChannelCurrent = column->DrawChannelUnfrozen;
1757 ImGui::SetWindowClipRectBeforeSetChannel(window, mTable.
Columns[0].ClipRect);
1758 mTable.
DrawSplitter.SetCurrentChannel(window->DrawList, mTable.
Columns[0].DrawChannelCurrent);
1761 if (!(mTable.
RowFlags & ImGuiTableRowFlags_Headers))
1766 template<
size_t MaxColumnCount>
1767 requires SmallerThanMaxColumnAmount<MaxColumnCount>
1768 void MainTable<MaxColumnCount>::DrawBorders() {
1773 ImDrawList* inner_drawlist = inner_window->DrawList;
1774 mTable.
DrawSplitter.SetCurrentChannel(inner_drawlist, TABLE_DRAW_CHANNEL_BG0);
1778 const float border_size = TABLE_BORDER_SIZE;
1779 const float draw_y1 = mTable.
InnerRect.Min.y;
1780 const float draw_y2_body = mTable.
InnerRect.Max.y;
1782 if (mTable.
Flags & ImGuiTableFlags_BordersInnerV) {
1783 for (
int order_n = 0; order_n < mTable.
ColumnsCount; order_n++) {
1788 TableColumn* column = &mTable.
Columns[column_n];
1791 const bool is_resizable = (column->Flags & (ImGuiTableColumnFlags_NoResize | ImGuiTableColumnFlags_NoDirectResize_)) == 0;
1793 if (column->MaxX > mTable.
InnerClipRect.Max.x && !is_resized)
1797 if (column->NextEnabledColumn == -1 && !is_resizable)
1798 if ((mTable.
Flags & ImGuiTableFlags_SizingMask_) != ImGuiTableFlags_SizingFixedSame || (mTable.
Flags & ImGuiTableFlags_NoHostExtendX))
1800 if (column->MaxX <= column->ClipRect.Min.x)
1807 if (is_hovered || is_resized || is_frozen_separator) {
1808 draw_y2 = draw_y2_body;
1809 col = is_resized ? ImGui::GetColorU32(ImGuiCol_SeparatorActive) : is_hovered ?
ImGui::GetColorU32(ImGuiCol_SeparatorHovered)
1810 : mTable.BorderColorStrong;
1812 draw_y2 = (mTable.
Flags & (ImGuiTableFlags_NoBordersInBody | ImGuiTableFlags_NoBordersInBodyUntilResize)) ? draw_y2_head : draw_y2_body;
1816 if (draw_y2 > draw_y1)
1817 inner_drawlist->AddLine(ImVec2(column->MaxX, draw_y1), ImVec2(column->MaxX, draw_y2), col, border_size);
1823 if (mTable.
Flags & ImGuiTableFlags_BordersOuter) {
1829 const ImRect outer_border = mTable.
OuterRect;
1831 if ((mTable.
Flags & ImGuiTableFlags_BordersOuter) == ImGuiTableFlags_BordersOuter) {
1832 inner_drawlist->AddRect(outer_border.Min, outer_border.Max, outer_col, 0.0f, ~0, border_size);
1833 }
else if (mTable.
Flags & ImGuiTableFlags_BordersOuterV) {
1834 inner_drawlist->AddLine(outer_border.Min, ImVec2(outer_border.Min.x, outer_border.Max.y), outer_col, border_size);
1835 inner_drawlist->AddLine(ImVec2(outer_border.Max.x, outer_border.Min.y), outer_border.Max, outer_col, border_size);
1836 }
else if (mTable.
Flags & ImGuiTableFlags_BordersOuterH) {
1837 inner_drawlist->AddLine(outer_border.Min, ImVec2(outer_border.Max.x, outer_border.Min.y), outer_col, border_size);
1838 inner_drawlist->AddLine(ImVec2(outer_border.Min.x, outer_border.Max.y), outer_border.Max, outer_col, border_size);
1843 const float border_y = mTable.
RowPosY2;
1848 inner_drawlist->PopClipRect();
1851 template<
size_t MaxColumnCount>
1852 requires SmallerThanMaxColumnAmount<MaxColumnCount>
1853 void MainTable<MaxColumnCount>::MergeDrawChannels() {
1854 ImGuiContext& g = *GImGui;
1858 IM_ASSERT(splitter->_Current == 0);
1864 ImBitArray<IMGUI_TABLE_MAX_DRAW_CHANNELS> ChannelsMask;
1866 int merge_group_mask = 0x00;
1867 MergeGroup merge_groups[4];
1868 memset(merge_groups, 0,
sizeof(merge_groups));
1871 for (
int column_n = 0; column_n < mTable.
ColumnsCount; column_n++) {
1874 TableColumn* column = &mTable.
Columns[column_n];
1876 const int merge_group_sub_count = has_freeze_v ? 2 : 1;
1877 for (
int merge_group_sub_n = 0; merge_group_sub_n < merge_group_sub_count; merge_group_sub_n++) {
1878 const int channel_no = (merge_group_sub_n == 0) ? column->DrawChannelFrozen : column->DrawChannelUnfrozen;
1881 ImDrawChannel* src_channel = &splitter->_Channels[channel_no];
1882 if (src_channel->_CmdBuffer.Size > 0 && src_channel->_CmdBuffer.back().ElemCount == 0)
1883 src_channel->_CmdBuffer.pop_back();
1884 if (src_channel->_CmdBuffer.Size != 1)
1889 if (!(column->Flags & ImGuiTableColumnFlags_NoClip)) {
1890 float content_max_x;
1892 content_max_x = ImMax(column->ContentMaxXUnfrozen, column->ContentMaxXHeadersUsed);
1893 else if (merge_group_sub_n == 0)
1894 content_max_x = ImMax(column->ContentMaxXFrozen, column->ContentMaxXHeadersUsed);
1896 content_max_x = column->ContentMaxXUnfrozen;
1897 if (content_max_x > column->ClipRect.Max.x)
1901 const int merge_group_n = (has_freeze_h && column_n < mTable.
FreezeColumnsCount ? 0 : 1) + (has_freeze_v && merge_group_sub_n == 0 ? 0 : 2);
1902 IM_ASSERT(channel_no < IMGUI_TABLE_MAX_DRAW_CHANNELS);
1903 MergeGroup* merge_group = &merge_groups[merge_group_n];
1904 if (merge_group->ChannelsCount == 0)
1905 merge_group->ClipRect = ImRect(+FLT_MAX, +FLT_MAX, -FLT_MAX, -FLT_MAX);
1906 merge_group->ChannelsMask.SetBit(channel_no);
1907 merge_group->ChannelsCount++;
1908 merge_group->ClipRect.Add(src_channel->_CmdBuffer[0].ClipRect);
1909 merge_group_mask |= (1 << merge_group_n);
1914 column->DrawChannelCurrent = (ImGuiTableDrawChannelIdx) -1;
1918 if (merge_group_mask != 0) {
1920 const int LEADING_DRAW_CHANNELS = 2;
1921 g.DrawChannelsTempMergeBuffer.resize(splitter->_Count - LEADING_DRAW_CHANNELS);
1922 ImDrawChannel* dst_tmp = g.DrawChannelsTempMergeBuffer.Data;
1923 ImBitArray<IMGUI_TABLE_MAX_DRAW_CHANNELS> remaining_mask;
1924 remaining_mask.ClearAllBits();
1925 remaining_mask.SetBitRange(LEADING_DRAW_CHANNELS, splitter->_Count);
1928 int remaining_count = splitter->_Count - (has_freeze_v ? LEADING_DRAW_CHANNELS + 1 : LEADING_DRAW_CHANNELS);
1931 for (
int merge_group_n = 0; merge_group_n < IM_ARRAYSIZE(merge_groups); merge_group_n++) {
1932 if (
int merge_channels_count = merge_groups[merge_group_n].ChannelsCount) {
1933 MergeGroup* merge_group = &merge_groups[merge_group_n];
1934 ImRect merge_clip_rect = merge_group->ClipRect;
1943 if ((merge_group_n & 1) == 0 || !has_freeze_h)
1944 merge_clip_rect.Min.x = ImMin(merge_clip_rect.Min.x, host_rect.Min.x);
1945 if ((merge_group_n & 2) == 0 || !has_freeze_v)
1946 merge_clip_rect.Min.y = ImMin(merge_clip_rect.Min.y, host_rect.Min.y);
1947 if ((merge_group_n & 1) != 0)
1948 merge_clip_rect.Max.x = ImMax(merge_clip_rect.Max.x, host_rect.Max.x);
1949 if ((merge_group_n & 2) != 0 && (mTable.
Flags & ImGuiTableFlags_NoHostExtendY) == 0)
1950 merge_clip_rect.Max.y = ImMax(merge_clip_rect.Max.y, host_rect.Max.y);
1952 remaining_count -= merge_group->ChannelsCount;
1953 for (
int n = 0; n < IM_ARRAYSIZE(remaining_mask.Storage); n++)
1954 remaining_mask.Storage[n] &= ~merge_group->ChannelsMask.Storage[n];
1955 for (
int n = 0; n < splitter->_Count && merge_channels_count != 0; n++) {
1957 if (!merge_group->ChannelsMask.TestBit(n))
1959 merge_group->ChannelsMask.ClearBit(n);
1960 merge_channels_count--;
1962 ImDrawChannel* channel = &splitter->_Channels[n];
1963 IM_ASSERT(channel->_CmdBuffer.Size == 1 && merge_clip_rect.Contains(ImRect(channel->_CmdBuffer[0].ClipRect)));
1964 channel->_CmdBuffer[0].ClipRect = merge_clip_rect.ToVec4();
1965 memcpy(dst_tmp++, channel,
sizeof(ImDrawChannel));
1970 if (merge_group_n == 1 && has_freeze_v)
1975 for (
int n = 0; n < splitter->_Count && remaining_count != 0; n++) {
1976 if (!remaining_mask.TestBit(n))
1978 ImDrawChannel* channel = &splitter->_Channels[n];
1979 memcpy(dst_tmp++, channel,
sizeof(ImDrawChannel));
1982 IM_ASSERT(dst_tmp == g.DrawChannelsTempMergeBuffer.Data + g.DrawChannelsTempMergeBuffer.Size);
1983 memcpy(splitter->_Channels.Data + LEADING_DRAW_CHANNELS, g.DrawChannelsTempMergeBuffer.Data, (splitter->_Count - LEADING_DRAW_CHANNELS) *
sizeof(ImDrawChannel));
1987 template<
size_t MaxColumnCount>
1988 requires SmallerThanMaxColumnAmount<MaxColumnCount>
1989 float MainTable<MaxColumnCount>::GetColumnWidthAuto(TableColumn* column) {
1990 const float content_width_body = ImMax(column->ContentMaxXFrozen, column->ContentMaxXUnfrozen) - column->WorkMinX;
1991 const float content_width_headers = column->ContentMaxXHeadersIdeal - column->WorkMinX;
1992 float width_auto = content_width_body;
1993 if (!(column->Flags & ImGuiTableColumnFlags_NoHeaderWidth))
1994 width_auto = ImMax(width_auto, content_width_headers);
1997 if ((column->Flags & ImGuiTableColumnFlags_WidthFixed) && column->InitStretchWeightOrWidth > 0.0f)
1998 if (!(mTable.
Flags & ImGuiTableFlags_Resizable) || (column->Flags & ImGuiTableColumnFlags_NoResize))
1999 width_auto = column->InitStretchWeightOrWidth;
2004 template<
size_t MaxColumnCount>
2005 requires SmallerThanMaxColumnAmount<MaxColumnCount>
2006 void MainTable<MaxColumnCount>::SaveSettingsCustom() {
2008 if (mTable.
Flags & ImGuiTableFlags_NoSavedSettings || (getCustomColumnsActive() && mSpecificColumnsActive))
2012 TableSettings& settings = getTableSettings();
2017 TableColumn* column = mTable.
Columns.Data;
2020 settings.Columns.clear();
2022 bool save_ref_scale =
false;
2023 settings.SaveFlags = ImGuiTableFlags_None;
2024 for (
int n = 0; n < mTable.
ColumnsCount; n++, column++) {
2025 TableColumnSettings& column_settings = settings.Columns.emplace_back();
2026 const float width_or_weight = (column->Flags & ImGuiTableColumnFlags_WidthStretch) ? column->StretchWeight : column->WidthRequest;
2027 column_settings.WidthOrWeight = width_or_weight;
2028 column_settings.UserID = column->UserID;
2030 column_settings.DisplayOrder = column->DisplayOrder;
2031 column_settings.SortOrder = column->SortOrder;
2032 column_settings.SortDirection = column->SortDirection;
2033 column_settings.IsEnabled = column->IsEnabled;
2034 column_settings.IsStretch = (column->Flags & ImGuiTableColumnFlags_WidthStretch) ? 1 : 0;
2035 if ((column->Flags & ImGuiTableColumnFlags_WidthStretch) == 0)
2036 save_ref_scale =
true;
2041 if (width_or_weight != column->InitStretchWeightOrWidth)
2042 settings.SaveFlags |= ImGuiTableFlags_Resizable;
2043 if (column->DisplayOrder != n)
2044 settings.SaveFlags |= ImGuiTableFlags_Reorderable;
2045 if (column->SortOrder != -1)
2046 settings.SaveFlags |= ImGuiTableFlags_Sortable;
2047 if (column->IsEnabled != ((column->Flags & ImGuiTableColumnFlags_DefaultHide) == 0))
2048 settings.SaveFlags |= ImGuiTableFlags_Hideable;
2050 settings.SaveFlags &= mTable.
Flags;
2051 settings.RefScale = save_ref_scale ? mTable.
RefScale : 0.0f;
2054 template<
size_t MaxColumnCount>
2055 requires SmallerThanMaxColumnAmount<MaxColumnCount>
2056 void MainTable<MaxColumnCount>::MigrateIniSettings() {
2057 bool backup = mSpecificColumnsUpdate;
2058 mSpecificColumnsActive =
false;
2060 TableSettings& tableSettings = getTableSettings();
2063 ImGuiContext& g = *GImGui;
2066 ImGuiTableSettings* settings;
2068 settings = ImGui::TableSettingsFindByID(mTable.
ID);
2069 if (settings == NULL)
2071 mTable.
SettingsOffset = g.SettingsTables.offset_from_ptr(settings);
2073 settings = GetBoundSettings();
2076 tableSettings.SaveFlags = settings->SaveFlags;
2077 tableSettings.RefScale = settings->RefScale;
2079 tableSettings.Columns.resize(settings->ColumnsCount);
2082 ImGuiTableColumnSettings* column_settings = settings->GetColumnSettings();
2083 for (
int data_n = 0; data_n < settings->ColumnsCount; data_n++, column_settings++) {
2084 int column_n = column_settings->Index;
2088 auto& column = tableSettings.Columns[column_n];
2090 column.DisplayOrder = column_settings->DisplayOrder;
2091 column.SortOrder = column_settings->SortOrder;
2092 column.IsEnabled = column_settings->IsEnabled;
2093 column.IsStretch = column_settings->IsStretch;
2094 column.SortDirection = column_settings->SortDirection;
2095 column.UserID = column_settings->UserID;
2096 column.WidthOrWeight = column_settings->WidthOrWeight;
2099 mSpecificColumnsActive = backup;
2102 template<
size_t MaxColumnCount>
2103 requires SmallerThanMaxColumnAmount<MaxColumnCount>
2104 void MainTable<MaxColumnCount>::SetupColumnFlags(TableColumn* column, ImGuiTableColumnFlags flags_in) {
2105 ImGuiTableColumnFlags flags = flags_in;
2108 if ((flags & ImGuiTableColumnFlags_WidthMask_) == 0) {
2109 const ImGuiTableFlags table_sizing_policy = (mTable.
Flags & ImGuiTableFlags_SizingMask_);
2110 if (table_sizing_policy == ImGuiTableFlags_SizingFixedFit || table_sizing_policy == ImGuiTableFlags_SizingFixedSame)
2111 flags |= ImGuiTableColumnFlags_WidthFixed;
2113 flags |= ImGuiTableColumnFlags_WidthStretch;
2115 IM_ASSERT(ImIsPowerOfTwo(flags & ImGuiTableColumnFlags_WidthMask_));
2119 if ((mTable.
Flags & ImGuiTableFlags_Resizable) == 0)
2120 flags |= ImGuiTableColumnFlags_NoResize;
2123 if ((flags & ImGuiTableColumnFlags_NoSortAscending) && (flags & ImGuiTableColumnFlags_NoSortDescending))
2124 flags |= ImGuiTableColumnFlags_NoSort;
2127 if ((flags & ImGuiTableColumnFlags_IndentMask_) == 0)
2128 flags |= (mTable.
Columns.index_from_ptr(column) == 0) ? ImGuiTableColumnFlags_IndentEnable : ImGuiTableColumnFlags_IndentDisable;
2136 column->Flags = flags | (column->Flags & ImGuiTableColumnFlags_StatusMask_);
2139 column->SortDirectionsAvailCount = column->SortDirectionsAvailMask = column->SortDirectionsAvailList = 0;
2140 if (mTable.
Flags & ImGuiTableFlags_Sortable) {
2141 int count = 0, mask = 0, list = 0;
2142 if ((flags & ImGuiTableColumnFlags_PreferSortAscending) != 0 && (flags & ImGuiTableColumnFlags_NoSortAscending) == 0) {
2143 mask |= 1 << ImGuiSortDirection_Ascending;
2144 list |= ImGuiSortDirection_Ascending << (count << 1);
2147 if ((flags & ImGuiTableColumnFlags_PreferSortDescending) != 0 && (flags & ImGuiTableColumnFlags_NoSortDescending) == 0) {
2148 mask |= 1 << ImGuiSortDirection_Descending;
2149 list |= ImGuiSortDirection_Descending << (count << 1);
2152 if ((flags & ImGuiTableColumnFlags_PreferSortAscending) == 0 && (flags & ImGuiTableColumnFlags_NoSortAscending) == 0) {
2153 mask |= 1 << ImGuiSortDirection_Ascending;
2154 list |= ImGuiSortDirection_Ascending << (count << 1);
2157 if ((flags & ImGuiTableColumnFlags_PreferSortDescending) == 0 && (flags & ImGuiTableColumnFlags_NoSortDescending) == 0) {
2158 mask |= 1 << ImGuiSortDirection_Descending;
2159 list |= ImGuiSortDirection_Descending << (count << 1);
2162 if ((mTable.
Flags & ImGuiTableFlags_SortTristate) || count == 0) {
2163 mask |= 1 << ImGuiSortDirection_None;
2166 column->SortDirectionsAvailList = (ImU8) list;
2167 column->SortDirectionsAvailMask = (ImU8) mask;
2168 column->SortDirectionsAvailCount = (ImU8) count;
2169 FixColumnSortDirection(column);
2173 template<
size_t MaxColumnCount>
2174 requires SmallerThanMaxColumnAmount<MaxColumnCount>
2175 float MainTable<MaxColumnCount>::GetMaxColumnWidth(
int column_n) {
2176 const TableColumn* column = &mTable.
Columns[column_n];
2177 float max_width = FLT_MAX;
2179 if (mTable.
Flags & ImGuiTableFlags_ScrollX) {
2185 }
else if ((mTable.
Flags & ImGuiTableFlags_NoKeepColumnsVisible) == 0) {
2191 max_width = mTable.
WorkRect.Max.x - (mTable.
ColumnsEnabledCount - column->IndexWithinEnabledSet - 1) * min_column_distance - column->MinX;
2200 template<
size_t MaxColumnCount>
2201 requires SmallerThanMaxColumnAmount<MaxColumnCount>
2202 void MainTable<MaxColumnCount>::SetupDrawChannels() {
2203 const int freeze_row_multiplier = (mTable.
FreezeRowsCount > 0) ? 2 : 1;
2204 const int channels_for_row = (mTable.
Flags & ImGuiTableFlags_NoClip) ? 1 : mTable.ColumnsEnabledCount;
2205 const int channels_for_bg = 1 + 1 * freeze_row_multiplier;
2207 const int channels_total = channels_for_bg + (channels_for_row * freeze_row_multiplier) + channels_for_dummy;
2209 mTable.
DummyDrawChannel = (ImGuiTableDrawChannelIdx) ((channels_for_dummy > 0) ? channels_total - 1 : -1);
2213 int draw_channel_current = 2;
2214 for (
int column_n = 0; column_n < mTable.
ColumnsCount; column_n++) {
2215 TableColumn* column = &mTable.
Columns[column_n];
2216 if (column->IsVisibleX && column->IsVisibleY) {
2217 column->DrawChannelFrozen = (ImGuiTableDrawChannelIdx) (draw_channel_current);
2218 column->DrawChannelUnfrozen = (ImGuiTableDrawChannelIdx) (draw_channel_current + (mTable.
FreezeRowsCount > 0 ? channels_for_row + 1 : 0));
2219 if (!(mTable.
Flags & ImGuiTableFlags_NoClip))
2220 draw_channel_current++;
2222 column->DrawChannelFrozen = column->DrawChannelUnfrozen = mTable.
DummyDrawChannel;
2224 column->DrawChannelCurrent = column->DrawChannelFrozen;
2236 template<
size_t MaxColumnCount>
2237 requires SmallerThanMaxColumnAmount<MaxColumnCount>
2238 void MainTable<MaxColumnCount>::UpdateBorders() {
2239 ImGuiContext& g = *GImGui;
2240 IM_ASSERT(mTable.
Flags & ImGuiTableFlags_Resizable);
2246 const float hit_half_width = TABLE_RESIZE_SEPARATOR_HALF_THICKNESS;
2247 const float hit_y1 = mTable.
OuterRect.Min.y;
2251 for (
int order_n = 0; order_n < mTable.
ColumnsCount; order_n++) {
2256 TableColumn* column = &mTable.
Columns[column_n];
2257 if (column->Flags & (ImGuiTableColumnFlags_NoResize | ImGuiTableColumnFlags_NoDirectResize_))
2261 const float border_y2_hit = (mTable.
Flags & ImGuiTableFlags_NoBordersInBody) ? hit_y2_head : hit_y2_body;
2269 ImGuiID column_id = GetColumnResizeID(column_n, mTable.
InstanceCurrent);
2270 ImRect hit_rect(column->MaxX - hit_half_width, hit_y1, column->MaxX + hit_half_width, border_y2_hit);
2272 ImGui::KeepAliveID(column_id);
2274 bool hovered =
false, held =
false;
2275 bool pressed = ImGui::ButtonBehavior(hit_rect, column_id, &hovered, &held, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_AllowItemOverlap | ImGuiButtonFlags_PressedOnClick | ImGuiButtonFlags_PressedOnDoubleClick);
2276 if (pressed && ImGui::IsMouseDoubleClicked(0)) {
2277 SetColumnWidthAutoSingle(column_n);
2278 ImGui::ClearActiveID();
2279 held = hovered =
false;
2287 if ((hovered && g.HoveredIdTimer > TABLE_RESIZE_SEPARATOR_FEEDBACK_TIMER) || held) {
2289 ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW);
2294 template<
size_t MaxColumnCount>
2295 requires SmallerThanMaxColumnAmount<MaxColumnCount>
2296 void MainTable<MaxColumnCount>::SortSpecsSanitize() {
2297 IM_ASSERT(mTable.
Flags & ImGuiTableFlags_Sortable);
2300 int sort_order_count = 0;
2301 ColumnBitMask sort_order_mask;
2302 for (
int column_n = 0; column_n < mTable.
ColumnsCount; column_n++) {
2303 TableColumn* column = &mTable.
Columns[column_n];
2304 if (column->SortOrder != -1 && !column->IsEnabled)
2305 column->SortOrder = -1;
2306 if (column->SortOrder == -1)
2309 sort_order_mask.set(column->SortOrder);
2312 ColumnBitMask expected;
2313 for (
int i = 0; i < sort_order_count; ++i) {
2317 const bool need_fix_linearize = expected != sort_order_mask;
2318 const bool need_fix_single_sort_order = (sort_order_count > 1) && !(mTable.
Flags & ImGuiTableFlags_SortMulti);
2319 if (need_fix_linearize || need_fix_single_sort_order) {
2320 ColumnBitMask fixed_mask;
2321 for (
int sort_n = 0; sort_n < sort_order_count; sort_n++) {
2324 int column_with_smallest_sort_order = -1;
2325 for (
int column_n = 0; column_n < mTable.
ColumnsCount; column_n++)
2326 if (!fixed_mask.test(column_n) && mTable.
Columns[column_n].SortOrder != -1)
2327 if (column_with_smallest_sort_order == -1 || mTable.
Columns[column_n].SortOrder < mTable.
Columns[column_with_smallest_sort_order].SortOrder)
2328 column_with_smallest_sort_order = column_n;
2329 IM_ASSERT(column_with_smallest_sort_order != -1);
2330 fixed_mask.set(column_with_smallest_sort_order);
2334 if (need_fix_single_sort_order) {
2335 sort_order_count = 1;
2336 for (
int column_n = 0; column_n < mTable.
ColumnsCount; column_n++)
2337 if (column_n != column_with_smallest_sort_order)
2338 mTable.
Columns[column_n].SortOrder = -1;
2345 if (sort_order_count == 0 && !(mTable.
Flags & ImGuiTableFlags_SortTristate))
2346 for (
int column_n = 0; column_n < mTable.
ColumnsCount; column_n++) {
2347 TableColumn* column = &mTable.
Columns[column_n];
2348 if (column->IsEnabled && !(column->Flags & ImGuiTableColumnFlags_NoSort)) {
2349 sort_order_count = 1;
2350 column->SortOrder = 0;
2351 column->SortDirection = (ImU8) GetColumnAvailSortDirection(column, 0);
2359 template<
size_t MaxColumnCount>
2360 requires SmallerThanMaxColumnAmount<MaxColumnCount>
2361 void MainTable<MaxColumnCount>::FixColumnSortDirection(TableColumn* column) {
2362 if (column->SortOrder == -1 || (column->SortDirectionsAvailMask & (1 << column->SortDirection)) != 0)
2364 column->SortDirection = (ImU8) GetColumnAvailSortDirection(column, 0);
2368 template<
size_t MaxColumnCount>
2369 requires SmallerThanMaxColumnAmount<MaxColumnCount>
2370 void MainTable<MaxColumnCount>::EndCell() {
2376 if (mTable.
RowFlags & ImGuiTableRowFlags_Headers)
2377 p_max_pos_x = &column->ContentMaxXHeadersUsed;
2379 p_max_pos_x = mTable.
IsUnfrozenRows ? &column->ContentMaxXUnfrozen : &column->ContentMaxXFrozen;
2380 *p_max_pos_x = ImMax(*p_max_pos_x, window->DC.CursorMaxPos.x);
2382 column->ItemWidth = window->DC.ItemWidth;
2389 template<
size_t MaxColumnCount>
2390 requires SmallerThanMaxColumnAmount<MaxColumnCount>
2391 void MainTable<MaxColumnCount>::BeginCell(
int column_n) {
2392 TableColumn* column = &mTable.
Columns[column_n];
2397 float start_x = column->WorkMinX;
2398 if (column->Flags & ImGuiTableColumnFlags_IndentEnable)
2401 window->DC.CursorPos.x = start_x;
2403 window->DC.CursorMaxPos.x = window->DC.CursorPos.x;
2404 window->DC.ColumnsOffset.x = start_x - window->Pos.x - window->DC.Indent.x;
2406 window->DC.NavLayerCurrent = (ImGuiNavLayer) column->NavLayerCurrent;
2408 window->WorkRect.Min.y = window->DC.CursorPos.y;
2409 window->WorkRect.Min.x = column->WorkMinX;
2410 window->WorkRect.Max.x = column->WorkMaxX;
2411 window->DC.ItemWidth = column->ItemWidth;
2414 if (!column->IsEnabled)
2415 window->DC.CursorPos.y = ImMax(window->DC.CursorPos.y, mTable.
RowPosY2);
2417 window->SkipItems = column->IsSkipItems;
2418 if (column->IsSkipItems) {
2419 window->DC.LastItemId = 0;
2420 window->DC.LastItemStatusFlags = 0;
2423 if (mTable.
Flags & ImGuiTableFlags_NoClip) {
2425 mTable.
DrawSplitter.SetCurrentChannel(window->DrawList, TABLE_DRAW_CHANNEL_NOCLIP);
2429 ImGui::SetWindowClipRectBeforeSetChannel(window, column->ClipRect);
2430 mTable.
DrawSplitter.SetCurrentChannel(window->DrawList, column->DrawChannelCurrent);
2434 template<
size_t MaxColumnCount>
2435 requires SmallerThanMaxColumnAmount<MaxColumnCount>
2436 void MainTable<MaxColumnCount>::BeginRow() {
2450 next_y1 = window->DC.CursorPos.y = mTable.
OuterRect.Min.y;
2455 window->DC.PrevLineTextBaseOffset = 0.0f;
2456 window->DC.CursorMaxPos.y = next_y1;
2459 if (mTable.
RowFlags & ImGuiTableRowFlags_Headers) {
2460 SetBgColor(ImGuiTableBgTarget_RowBg0, ImGui::GetColorU32(ImGuiCol_TableHeaderBg));
2466 template<
size_t MaxColumnCount>
2467 requires SmallerThanMaxColumnAmount<MaxColumnCount>
2468 void MainTable<MaxColumnCount>::SetBgColor(ImGuiTableBgTarget target, ImU32 color,
int column_n) {
2469 IM_ASSERT(target != ImGuiTableBgTarget_None);
2471 if (color == IM_COL32_DISABLE)
2476 case ImGuiTableBgTarget_CellBg: {
2486 cell_data->BgColor = color;
2490 case ImGuiTableBgTarget_RowBg0:
2491 case ImGuiTableBgTarget_RowBg1: {
2494 IM_ASSERT(column_n == -1);
2495 int bg_idx = (target == ImGuiTableBgTarget_RowBg1) ? 1 : 0;
2504 template<
size_t MaxColumnCount>
2505 requires SmallerThanMaxColumnAmount<MaxColumnCount>
2506 void MainTable<MaxColumnCount>::SetColumnSortDirection(
int column_n, ImGuiSortDirection sort_direction,
bool append_to_sort_specs) {
2507 if (!(mTable.
Flags & ImGuiTableFlags_SortMulti))
2508 append_to_sort_specs =
false;
2509 if (!(mTable.
Flags & ImGuiTableFlags_SortTristate))
2510 IM_ASSERT(sort_direction != ImGuiSortDirection_None);
2513 if (append_to_sort_specs)
2514 for (
int other_column_n = 0; other_column_n < mTable.
ColumnsCount; other_column_n++)
2515 sort_order_max = ImMax(sort_order_max, mTable.
Columns[other_column_n].SortOrder);
2517 TableColumn* column = &mTable.
Columns[column_n];
2518 column->SortDirection = (ImU8) sort_direction;
2519 if (column->SortDirection == ImGuiSortDirection_None)
2520 column->SortOrder = -1;
2521 else if (column->SortOrder == -1 || !append_to_sort_specs)
2522 column->SortOrder = append_to_sort_specs ? sort_order_max + 1 : 0;
2524 for (
int other_column_n = 0; other_column_n < mTable.
ColumnsCount; other_column_n++) {
2525 TableColumn* other_column = &mTable.
Columns[other_column_n];
2526 if (other_column != column && !append_to_sort_specs)
2527 other_column->SortOrder = -1;
2528 FixColumnSortDirection(other_column);
2534 template<
size_t MaxColumnCount>
2535 requires SmallerThanMaxColumnAmount<MaxColumnCount>
2536 ImGuiSortDirection MainTable<MaxColumnCount>::GetColumnNextSortDirection(TableColumn* column) {
2537 IM_ASSERT(column->SortDirectionsAvailCount > 0);
2538 if (column->SortOrder == -1)
2539 return GetColumnAvailSortDirection(column, 0);
2540 for (
int n = 0; n < 3; n++)
2541 if (column->SortDirection == GetColumnAvailSortDirection(column, n))
2542 return GetColumnAvailSortDirection(column, (n + 1) % column->SortDirectionsAvailCount);
2544 return ImGuiSortDirection_None;
2547 template<
size_t MaxColumnCount>
2548 requires SmallerThanMaxColumnAmount<MaxColumnCount>
2549 void MainTable<MaxColumnCount>::SetColumnWidth(
int column_n,
float width) {
2551 IM_ASSERT(column_n >= 0 && column_n < mTable.
ColumnsCount);
2552 TableColumn* column_0 = &mTable.
Columns[column_n];
2553 float column_0_width = width;
2559 const float max_width = ImMax(min_width, GetMaxColumnWidth(column_n));
2560 column_0_width = ImClamp(column_0_width, min_width, max_width);
2561 if (column_0->WidthGiven == column_0_width || column_0->WidthRequest == column_0_width)
2565 TableColumn* column_1 = (column_0->NextEnabledColumn != -1) ? &mTable.
Columns[column_0->NextEnabledColumn] : NULL;
2601 if (column_0->Flags & ImGuiTableColumnFlags_WidthFixed)
2603 column_0->WidthRequest = column_0_width;
2609 if (column_1 == NULL)
2610 column_1 = (column_0->PrevEnabledColumn != -1) ? &mTable.
Columns[column_0->PrevEnabledColumn] : NULL;
2611 if (column_1 == NULL)
2616 float column_1_width = ImMax(column_1->WidthRequest - (column_0_width - column_0->WidthRequest), min_width);
2617 column_0_width = column_0->WidthRequest + column_1->WidthRequest - column_1_width;
2618 IM_ASSERT(column_0_width > 0.0f && column_1_width > 0.0f);
2619 column_0->WidthRequest = column_0_width;
2620 column_1->WidthRequest = column_1_width;
2621 if ((column_0->Flags | column_1->Flags) & ImGuiTableColumnFlags_WidthStretch)
2622 UpdateColumnsWeightFromWidth();
2626 template<
size_t MaxColumnCount>
2627 requires SmallerThanMaxColumnAmount<MaxColumnCount>
2628 void MainTable<MaxColumnCount>::UpdateColumnsWeightFromWidth() {
2632 float visible_weight = 0.0f;
2633 float visible_width = 0.0f;
2634 for (
int column_n = 0; column_n < mTable.
ColumnsCount; column_n++) {
2635 TableColumn* column = &mTable.
Columns[column_n];
2636 if (!column->IsEnabled || !(column->Flags & ImGuiTableColumnFlags_WidthStretch))
2638 IM_ASSERT(column->StretchWeight > 0.0f);
2639 visible_weight += column->StretchWeight;
2640 visible_width += column->WidthRequest;
2642 IM_ASSERT(visible_weight > 0.0f && visible_width > 0.0f);
2645 for (
int column_n = 0; column_n < mTable.
ColumnsCount; column_n++) {
2646 TableColumn* column = &mTable.
Columns[column_n];
2647 if (!column->IsEnabled || !(column->Flags & ImGuiTableColumnFlags_WidthStretch))
2649 column->StretchWeight = (column->WidthRequest / visible_width) * visible_weight;
2650 IM_ASSERT(column->StretchWeight > 0.0f);
2654 template<
size_t MaxColumnCount>
2655 requires SmallerThanMaxColumnAmount<MaxColumnCount>
2657 const ImRect& cellBgRect = GetCellBgRect(mTable.
CurrentColumn);
2662 return ImGui::IsWindowHovered() && ImGui::IsMouseHoveringRect(cellBgRect.Min, cellBgRect.Max);
2665 template<
size_t MaxColumnCount>
2671 template<
size_t MaxColumnCount>
2677 template<
size_t MaxColumnCount>
2679 bool MainTable<MaxColumnCount>::Begin(
const char* str_id,
int columns_count, ImGuiTableFlags flags,
const ImVec2& outer_size,
float inner_width, ImGuiWindowFlags child_window_flags) {
2680 ImGuiID
id = ImGui::GetID(str_id);
2684 flags |= ImGuiTableFlags_ScrollY;
2686 ImGuiContext& g = *GImGui;
2687 ImGuiWindow* outer_window = ImGui::GetCurrentWindow();
2688 if (outer_window->SkipItems)
2692 IM_ASSERT(columns_count > 0 && columns_count <= MaxColumnCount &&
"Only 1..MaxColumnCount columns allowed!");
2693 if (flags & ImGuiTableFlags_ScrollX)
2694 IM_ASSERT(inner_width >= 0.0f);
2697 const bool use_child_window = (flags & (ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY)) != 0;
2698 const ImVec2 avail_size = ImGui::GetContentRegionAvail();
2699 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);
2700 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);
2708 const ImGuiID instance_id =
id + instance_no;
2709 const ImGuiTableFlags table_last_flags = mTable.
Flags;
2710 if (instance_no > 0)
2711 IM_ASSERT(mTable.
ColumnsCount == columns_count &&
"BeginTable(): Cannot change columns count mid-frame while preserving same ID");
2715 flags = TableFixFlags(flags, outer_window);
2719 mTable.
Flags = flags;
2729 if (use_child_window) {
2732 ImVec2 override_content_size(FLT_MAX, FLT_MAX);
2733 if ((flags & ImGuiTableFlags_ScrollX) && !(flags & ImGuiTableFlags_ScrollY))
2734 override_content_size.y = FLT_MIN;
2740 if ((flags & ImGuiTableFlags_ScrollX) && inner_width > 0.0f)
2741 override_content_size.x = inner_width;
2743 if (override_content_size.x != FLT_MAX || override_content_size.y != FLT_MAX)
2744 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));
2747 if ((table_last_flags & (ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY)) == 0)
2748 ImGui::SetNextWindowScroll(ImVec2(0.0f, 0.0f));
2751 ImGuiWindowFlags child_flags = child_window_flags;
2752 child_flags |= getShowScrollbar() ? 0 : ImGuiWindowFlags_NoScrollbar;
2753 child_flags |= (flags & ImGuiTableFlags_ScrollX) ? ImGuiWindowFlags_HorizontalScrollbar : ImGuiWindowFlags_None;
2754 ImGui::BeginChildEx(str_id, instance_id, outer_rect.GetSize(),
false, child_flags);
2767 ImGui::PushOverrideID(instance_id);
2782 inner_window->DC.PrevLineSize = inner_window->DC.CurrLineSize = ImVec2(0.0f, 0.0f);
2789 const bool pad_outer_x = (flags & ImGuiTableFlags_NoPadOuterX) ?
false : (flags & ImGuiTableFlags_PadOuterX) ?
true
2790 : (flags & ImGuiTableFlags_BordersOuterV) != 0;
2791 const bool pad_inner_x = (flags & ImGuiTableFlags_NoPadInnerX) ?
false :
true;
2792 const float inner_spacing_for_border = (flags & ImGuiTableFlags_BordersInnerV) ? TABLE_BORDER_SIZE : 0.0f;
2793 const float inner_spacing_explicit = (pad_inner_x && (flags & ImGuiTableFlags_BordersInnerV) == 0) ? g.Style.CellPadding.x : 0.0f;
2794 const float inner_padding_explicit = (pad_inner_x && (flags & ImGuiTableFlags_BordersInnerV) != 0) ? g.Style.CellPadding.x : 0.0f;
2795 mTable.
CellSpacingX1 = inner_spacing_explicit + inner_spacing_for_border;
2800 const float outer_padding_for_border = (flags & ImGuiTableFlags_BordersOuterV) ? TABLE_BORDER_SIZE : 0.0f;
2801 const float outer_padding_explicit = pad_outer_x ? g.Style.CellPadding.x : 0.0f;
2811 mTable.
InnerClipRect.Max.y = (flags & ImGuiTableFlags_NoHostExtendY) ? ImMin(mTable.
InnerClipRect.Max.y, inner_window->WorkRect.Max.y) : inner_window->ClipRect.Max.y;
2832 if ((table_last_flags & ImGuiTableFlags_Reorderable) && (flags & ImGuiTableFlags_Reorderable) == 0)
2842 const int stored_size = mTable.
Columns.size();
2843 if (stored_size != 0 && stored_size != columns_count) {
2848 BeginInitMemory(columns_count);
2862 for (
int n = 0; n < columns_count; n++) {
2875 LoadSettingsCustom();
2877 if (getCustomColumnsActive()) {
2878 bool expected =
true;
2879 if (mSpecificColumnsUpdate.compare_exchange_strong(expected,
false)) {
2880 if (mSpecificColumnsActive) {
2881 ApplySpecificColumnSetup();
2883 LoadSettingsCustom();
2886 }
else if (mSpecificColumnsActive) {
2887 LoadSettingsCustom();
2888 mSpecificColumnsActive =
false;
2896 const float new_ref_scale_unit = g.FontSize;
2898 const float scale_factor = new_ref_scale_unit / mTable.
RefScale;
2900 for (
int n = 0; n < columns_count; n++)
2901 mTable.
Columns[n].WidthRequest = mTable.
Columns[n].WidthRequest * scale_factor;
2903 mTable.
RefScale = new_ref_scale_unit;
2908 inner_window->SkipItems =
true;
2916 BeginApplyRequests();
2921 template<
size_t MaxColumnCount>
2924 ImGuiContext& g = *GImGui;
2935 const ImGuiTableFlags flags = mTable.
Flags;
2938 IM_ASSERT(inner_window == g.CurrentWindow);
2939 IM_ASSERT(outer_window == inner_window || outer_window == inner_window->ParentWindow);
2953 const float inner_content_max_y = mTable.
RowPosY2;
2954 IM_ASSERT(mTable.
RowPosY2 == inner_window->DC.CursorPos.y);
2955 if (inner_window != outer_window)
2956 inner_window->DC.CursorMaxPos.y = inner_content_max_y;
2957 else if (!(flags & ImGuiTableFlags_NoHostExtendY))
2965 if (mTable.
Flags & ImGuiTableFlags_ScrollX) {
2966 const float outer_padding_for_border = (mTable.
Flags & ImGuiTableFlags_BordersOuterV) ? TABLE_BORDER_SIZE : 0.0f;
2967 float max_pos_x = mTable.
InnerWindow->DC.CursorMaxPos.x;
2972 mTable.
InnerWindow->DC.CursorMaxPos.x = max_pos_x;
2976 if (!(flags & ImGuiTableFlags_NoClip))
2977 inner_window->DrawList->PopClipRect();
2978 inner_window->ClipRect = inner_window->DrawList->_ClipRectStack.back();
2981 if ((flags & ImGuiTableFlags_Borders) != 0)
2985 mTable.
DrawSplitter.SetCurrentChannel(inner_window->DrawList, 0);
2986 if ((mTable.
Flags & ImGuiTableFlags_NoClip) == 0)
2987 MergeDrawChannels();
2993 for (
int column_n = 0; column_n < mTable.
ColumnsCount; column_n++)
2996 if ((column->
Flags & ImGuiTableColumnFlags_WidthFixed) && !(column->
Flags & ImGuiTableColumnFlags_NoResize))
3003 if ((mTable.
Flags & ImGuiTableFlags_ScrollX) == 0 && inner_window != outer_window) {
3004 inner_window->Scroll.x = 0.0f;
3010 ImGui::SetScrollFromPosX(inner_window, column->
MaxX - inner_window->Pos.x - neighbor_width_to_keep_visible, 1.0f);
3012 ImGui::SetScrollFromPosX(inner_window, column->
MaxX - inner_window->Pos.x + neighbor_width_to_keep_visible, 1.0f);
3018 const float new_x2 = (g.IO.MousePos.x - g.ActiveIdClickOffset.x + TABLE_RESIZE_SEPARATOR_HALF_THICKNESS);
3024 IM_ASSERT_USER_ERROR(inner_window->IDStack.back() == mTable.
ID + mTable.
InstanceCurrent,
"Mismatching PushID/PopID!");
3029 const ImVec2 backup_outer_max_pos = outer_window->DC.CursorMaxPos;
3033 outer_window->DC.CursorPos = mTable.
OuterRect.Min;
3041 if (inner_window != outer_window) {
3044 ImGui::ItemSize(mTable.
OuterRect.GetSize());
3049 if (mTable.
Flags & ImGuiTableFlags_NoHostExtendX) {
3052 IM_ASSERT((mTable.
Flags & ImGuiTableFlags_ScrollX) == 0);
3055 const float decoration_size = (mTable.
Flags & ImGuiTableFlags_ScrollX) ? inner_window->ScrollbarSizes.x : 0.0f;
3059 outer_window->DC.CursorMaxPos.x = ImMax(backup_outer_max_pos.x, mTable.
OuterRect.Max.x);
3062 const float decoration_size = (mTable.
Flags & ImGuiTableFlags_ScrollY) ? inner_window->ScrollbarSizes.y : 0.0f;
3063 outer_window->DC.IdealMaxPos.y = ImMax(outer_window->DC.IdealMaxPos.y, inner_content_max_y + decoration_size - mTable.
UserOuterSize.y);
3064 outer_window->DC.CursorMaxPos.y = ImMax(backup_outer_max_pos.y, ImMin(mTable.
OuterRect.Max.y, inner_content_max_y));
3067 outer_window->DC.CursorMaxPos.y = ImMax(backup_outer_max_pos.y, mTable.
OuterRect.Max.y);
3072 SaveSettingsCustom();
3082 template<
size_t MaxColumnCount>
3088 bool menu_item_active = (column.
Flags & ImGuiTableColumnFlags_NoHide) ?
false :
true;
3090 menu_item_active =
false;
3091 if (ImGui::MenuItem(columnName, NULL, column.
IsEnabled, menu_item_active && !mSpecificColumnsActive))
3094 if (ImGui::IsItemHovered()) {
3095 ImGui::SetTooltip(
"%s", mColumns.at(
TableColumnIdx).Popup().c_str());
3099 template<
size_t MaxColumnCount>
3110 template<
size_t MaxColumnCount>
3113 IM_ASSERT(mTable.
IsLayoutLocked ==
false &&
"Need to call TableSetupColumn() before first row!");
3114 IM_ASSERT(columns >= 0 && columns < IMGUI_TABLE_MAX_COLUMNS);
3115 IM_ASSERT(rows >= 0 && rows < 128);
3124 template<
size_t MaxColumnCount>
3128 float x1 = column->
MinX;
3129 float x2 = column->
MaxX;
3137 template<
size_t MaxColumnCount>
3140 if (!(mTable.
Flags & ImGuiTableFlags_Sortable))
3153 template<
size_t MaxColumnCount>
3156 IM_ASSERT(mTable.
IsLayoutLocked ==
false &&
"Need to call call TableSetupColumn() before first row!");
3157 IM_ASSERT((flags & ImGuiTableColumnFlags_StatusMask_) == 0 &&
"Illegal to pass StatusMask values to TableSetupColumn()");
3168 if (mTable.
IsDefaultSizingPolicy && (flags & ImGuiTableColumnFlags_WidthMask_) == 0 && (flags & ImGuiTableFlags_ScrollX) == 0)
3169 IM_ASSERT(init_width_or_weight <= 0.0f &&
"Can only specify width/weight if sizing policy is set explicitely in either Table or Column.");
3173 if ((flags & ImGuiTableColumnFlags_WidthMask_) == 0 && init_width_or_weight > 0.0f)
3174 if ((mTable.
Flags & ImGuiTableFlags_SizingMask_) == ImGuiTableFlags_SizingFixedFit || (mTable.
Flags & ImGuiTableFlags_SizingMask_) == ImGuiTableFlags_SizingFixedSame)
3175 flags |= ImGuiTableColumnFlags_WidthFixed;
3177 TableSetupColumnFlags(column, flags);
3179 column->
UserID = user_id;
3180 flags = column->
Flags;
3187 if ((flags & ImGuiTableColumnFlags_WidthFixed) && init_width_or_weight > 0.0f)
3189 if (flags & ImGuiTableColumnFlags_WidthStretch)
3190 column->
StretchWeight = (init_width_or_weight > 0.0f) ? init_width_or_weight : -1.0f;
3193 if (init_width_or_weight > 0.0f)
3198 if ((flags & ImGuiTableColumnFlags_DefaultHide) && (mTable.
SettingsLoadedFlags & ImGuiTableFlags_Hideable) == 0)
3200 if (flags & ImGuiTableColumnFlags_DefaultSort && (mTable.
SettingsLoadedFlags & ImGuiTableFlags_Sortable) == 0) {
3202 column->
SortDirection = (column->
Flags & ImGuiTableColumnFlags_PreferSortDescending) ? (ImS8) ImGuiSortDirection_Descending : (ImU8) (ImGuiSortDirection_Ascending);
3208 if (label != NULL && label[0] != 0) {
3210 mTable.
ColumnsNames.append(label, label + strlen(label) + 1);
3214 template<
size_t MaxColumnCount>
3218 const float image_size = 16.f;
3221 if (!texture || getShowHeaderAsText()) {
3225 ImGuiContext& g = *GImGui;
3226 ImGuiWindow* window = g.CurrentWindow;
3227 if (window->SkipItems)
3237 const char* label_end = ImGui::FindRenderedTextEnd(label);
3238 ImVec2 label_size = ImGui::CalcTextSize(label, label_end,
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);
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, label_end, &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", popupText);
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 const std::string & STranslate(T pId)
Definition Localization.h:43
Definition MainTable.h:129
std::bitset< MaxColumnCount > ColumnBitMask
Definition MainTable.h:131
virtual void MigrateSettings()
Definition MainTable.h:250
virtual ~MainTable()=default
void ResetSpecificColumnSetup()
Definition MainTable.h:862
void Draw()
Definition MainTable.h:734
int GetColumnIndex()
Definition MainTable.h:2673
virtual bool getCustomColumnsFeatureActive()
Definition MainTable.h:240
virtual Alignment & getAlignment()=0
static size_t GetMaxColumnCount()
Definition MainTable.h:145
MainTable(MainTable &&pOther) noexcept=delete
ImRect GetCellBgRect(int column_n)
Definition MainTable.h:3126
virtual Alignment & getHeaderAlignment()=0
void AlignedTextColumn(const char *text)
Definition MainTable.h:3413
bool IsCurrentRowHovered()
Definition MainTable.h:2667
bool GetSpecificColumnsActive() const
Definition MainTable.h:150
virtual bool getMaxHeightActive()
Definition MainTable.h:227
void EndMaxHeightRow()
Definition MainTable.h:926
Table mTable
Definition MainTable.h:529
virtual void DrawStyleSubMenu()
Definition MainTable.h:869
void NextRow(ImGuiTableRowFlags row_flags=0, float min_row_height=0.0f)
Definition MainTable.h:886
virtual bool & getShowAlternatingBackground()=0
void MenuItemColumnVisibility(int TableColumnIdx)
Definition MainTable.h:3084
virtual void DrawRows(TableColumnIdx pFirstColumnIndex)=0
virtual void Sort(const ImGuiTableColumnSortSpecs *mColumnSortSpecs)=0
MainTable(const MainTable &pOther)=delete
virtual bool getShowScrollbar()
Definition MainTable.h:225
MainTable(const std::vector< MainTableColumn > &pColumns, MainWindow *pMainWindow, MainTableFlags pFlags=0)
Definition MainTable.h:690
void SetupScrollFreeze(int columns, int rows)
Definition MainTable.h:3112
void ColumnHeader(const char *label, bool show_label, ImTextureID texture, Alignment alignment, const char *popupText)
Definition MainTable.h:3216
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:2679
ImGuiTableSortSpecs * GetSortSpecs()
Definition MainTable.h:3139
void ApplySpecificColumnSetup()
Definition MainTable.h:3491
virtual bool & getCustomColumnsActive()
Definition MainTable.h:241
virtual std::string getTableId()=0
void RequestSort()
Definition MainTable.h:146
void SetupColumn(const char *label, ImGuiTableColumnFlags flags, float init_width_or_weight, ImGuiID user_id)
Definition MainTable.h:3155
virtual int getCustomColumnsFirstColumn()
Definition MainTable.h:243
virtual const char * getCategoryName(const std::string &pCat)=0
bool IsCurrentColumnHovered()
Definition MainTable.h:2656
void DrawColumnSetupMenu()
Definition MainTable.h:828
const char * GetColumnName(int column_n)
Definition MainTable.h:3101
MainTable & operator=(MainTable &&pOther) noexcept=delete
bool NextColumn()
Definition MainTable.h:908
MainTable & operator=(const MainTable &pOther)=delete
virtual void DrawColumnSetupSubMenu()
Definition MainTable.h:838
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:853
virtual TableSettings & getTableSettings()=0
virtual bool & getShowHeaderAsText()=0
virtual int & getMaxDisplayed()=0
void End()
Definition MainTable.h:2923
Definition MainWindow.h:22
float GetMaxCursorPos()
Definition MainWindow.cpp:164
virtual bool & GetShowScrollbar()=0
virtual void SetMaxHeightCursorPos(float pNewCursorPos=ImGui::GetCursorPosY())
Definition MainWindow.cpp:136
void RegisterDrawStyleSubMenuHook(DrawStyleSubMenuHookFunction pFun)
Definition MainWindow.cpp:160
Definition MainTable.h:98
Definition ArcdpsExtension.h:10
MainTableFlags_
Definition MainTable.h:90
@ MainTableFlags_None
Definition MainTable.h:91
@ MainTableFlags_SubWindow
Definition MainTable.h:92
@ ET_ShowBasedOnMap
Definition ExtensionTranslations.h:49
@ ET_HighlightHoveredRow
Definition ExtensionTranslations.h:51
@ ET_ColumnSetup
Definition ExtensionTranslations.h:48
@ ET_AlternatingRowBg
Definition ExtensionTranslations.h:50
@ ET_HeaderAlignment
Definition ExtensionTranslations.h:53
@ ET_SettingsShowHeaderText
Definition ExtensionTranslations.h:56
@ ET_MaxDisplayed
Definition ExtensionTranslations.h:52
@ ET_ColumnAlignment
Definition ExtensionTranslations.h:54
int MainTableFlags
Definition MainTable.h:94
ImS16 TableColumnIdx
Definition MainTable.h:45
bool EnumCombo(const char *label, E &storage, const R &values, const std::map< E, std::function< const std::string &()> > &pPopupText={})
Definition Widgets.h:64
bool Spinner(const char *label, float radius, float thickness, const ImU32 &color)
Definition Widgets.cpp:19
Definition imgui_stdlib.h:16
Definition MainTable.h:55
MainTableColumn(ImU32 pUserId, const std::function< std::string()> &pName, const std::function< void *()> &pTexture, std::string pCategory, const std::function< std::string()> &pPopup, bool pDefaultVisibility=true)
Definition MainTable.h:76
ImU32 UserId
Definition MainTable.h:56
std::function< void *()> Texture
Definition MainTable.h:58
MainTableColumn(E pUserId, const std::function< std::string()> &pName, const std::function< void *()> &pTexture, std::string pCategory, const std::function< std::string()> &pPopup, bool pDefaultVisibility=true)
Definition MainTable.h:86
MainTableColumn(ImU32 pUserId, const std::function< std::string()> &pName, const std::function< void *()> &pTexture, std::string pCategory, bool pDefaultVisibility=true)
Definition MainTable.h:63
std::function< std::string()> Name
Definition MainTable.h:57
bool DefaultVisibility
Definition MainTable.h:60
std::function< std::string()> Popup
Definition MainTable.h:61
std::string Category
Definition MainTable.h:59
MainTableColumn(E pUserId, const std::function< std::string()> &pName, const std::function< void *()> &pTexture, std::string pCategory, bool pDefaultVisibility=true)
Definition MainTable.h:73
Definition MainTable.h:154
TableColumnIdx DisplayOrder
Definition MainTable.h:158
ImU8 SortDirection
Definition MainTable.h:160
float WidthOrWeight
Definition MainTable.h:155
std::strong_ordering operator<=>(const TableColumnSettings &pOther) const
Definition MainTable.h:164
std::strong_ordering operator<=>(const ImGuiID &pOther) const
Definition MainTable.h:168
ImU8 IsStretch
Definition MainTable.h:162
ImU8 IsEnabled
Definition MainTable.h:161
friend void from_json(const nlohmann::json &nlohmann_json_j, TableColumnSettings &nlohmann_json_t)
Definition MainTable.h:190
ImGuiID UserID
Definition MainTable.h:156
bool operator==(const ImGuiID &pOther) const
Definition MainTable.h:176
bool operator==(const TableColumnSettings &pOther) const
Definition MainTable.h:172
TableColumnIdx SortOrder
Definition MainTable.h:159
friend void to_json(nlohmann::json &nlohmann_json_j, const TableColumnSettings &nlohmann_json_t)
Definition MainTable.h:180
Definition MainTable.h:354
TableColumnIdx NextEnabledColumn
Definition MainTable.h:376
TableColumnIdx DisplayOrder
Definition MainTable.h:373
TableColumnIdx SortOrder
Definition MainTable.h:377
ImGuiTableDrawChannelIdx DrawChannelUnfrozen
Definition MainTable.h:380
ImU8 CannotSkipItemsQueue
Definition MainTable.h:390
float InitStretchWeightOrWidth
Definition MainTable.h:362
float ItemWidth
Definition MainTable.h:367
ImGuiTableDrawChannelIdx DrawChannelCurrent
Definition MainTable.h:378
float MinX
Definition MainTable.h:357
float ContentMaxXHeadersUsed
Definition MainTable.h:370
bool IsVisibleY
Definition MainTable.h:384
float ContentMaxXUnfrozen
Definition MainTable.h:369
ImU8 SortDirectionsAvailMask
Definition MainTable.h:393
bool IsRequestOutput
Definition MainTable.h:385
TableColumn()
Definition MainTable.h:396
float ContentMaxXFrozen
Definition MainTable.h:368
TableColumnIdx IndexWithinEnabledSet
Definition MainTable.h:374
ImS16 NameOffset
Definition MainTable.h:372
ImS8 NavLayerCurrent
Definition MainTable.h:388
bool IsSkipItems
Definition MainTable.h:386
ImGuiTableDrawChannelIdx DrawChannelFrozen
Definition MainTable.h:379
ImGuiID UserID
Definition MainTable.h:364
TableColumnIdx PrevEnabledColumn
Definition MainTable.h:375
bool IsEnabledNextFrame
Definition MainTable.h:382
ImU8 AutoFitQueue
Definition MainTable.h:389
ImRect ClipRect
Definition MainTable.h:363
float WidthAuto
Definition MainTable.h:360
ImU8 SortDirection
Definition MainTable.h:391
float WidthRequest
Definition MainTable.h:359
float WorkMaxX
Definition MainTable.h:366
ImU8 SortDirectionsAvailList
Definition MainTable.h:394
float StretchWeight
Definition MainTable.h:361
float WorkMinX
Definition MainTable.h:365
bool IsEnabled
Definition MainTable.h:381
float WidthGiven
Definition MainTable.h:356
bool IsVisibleX
Definition MainTable.h:383
float ContentMaxXHeadersIdeal
Definition MainTable.h:371
float MaxX
Definition MainTable.h:358
bool IsPreserveWidthAuto
Definition MainTable.h:387
ImGuiTableColumnFlags Flags
Definition MainTable.h:355
ImU8 SortDirectionsAvailCount
Definition MainTable.h:392
Definition MainTable.h:200
ImU32 Version
Definition MainTable.h:201
ImGuiTableFlags SaveFlags
Definition MainTable.h:202
float RefScale
Definition MainTable.h:203
std::vector< TableColumnSettings > Columns
Definition MainTable.h:204
Definition MainTable.h:409
ImGuiTableSortSpecs SortSpecs
Definition MainTable.h:481
TableColumnIdx DeclColumnsCount
Definition MainTable.h:485
ImVec2 HostBackupCurrLineSize
Definition MainTable.h:469
ImSpan< TableColumn > Columns
Definition MainTable.h:413
TableColumnIdx ResizedColumn
Definition MainTable.h:489
TableColumnIdx FreezeRowsRequest
Definition MainTable.h:498
ImRect InnerRect
Definition MainTable.h:458
float RowPosY1
Definition MainTable.h:429
float CellSpacingX2
Definition MainTable.h:448
ImGuiTextBuffer ColumnsNames
Definition MainTable.h:477
TableColumnIdx RightMostEnabledColumn
Definition MainTable.h:496
TableColumnIdx HeldHeaderColumn
Definition MainTable.h:491
bool IsDefaultSizingPolicy
Definition MainTable.h:518
TableColumnIdx RightMostStretchedColumn
Definition MainTable.h:495
float BorderX1
Definition MainTable.h:440
TableColumnIdx ReorderColumn
Definition MainTable.h:492
ImU32 BorderColorStrong
Definition MainTable.h:438
ImU32 RowBgColor[2]
Definition MainTable.h:437
int HostBackupItemWidthStackSize
Definition MainTable.h:474
float RowTextBaseline
Definition MainTable.h:432
float RowIndentOffsetX
Definition MainTable.h:433
bool IsInsideRow
Definition MainTable.h:507
ImGuiTableFlags Flags
Definition MainTable.h:411
float MinColumnWidth
Definition MainTable.h:443
bool IsUsingHeaders
Definition MainTable.h:510
ImSpan< ImGuiTableCellData > RowCellData
Definition MainTable.h:415
ImGuiTableColumnSortSpecs SortSpecsSingle
Definition MainTable.h:479
ImDrawListSplitter DrawSplitter
Definition MainTable.h:478
ImVector< ImGuiTableColumnSortSpecs > SortSpecsMulti
Definition MainTable.h:480
float LastFirstRowHeight
Definition MainTable.h:450
bool IsContextPopupOpen
Definition MainTable.h:511
bool IsSettingsDirty
Definition MainTable.h:513
TableColumnIdx RowCellDataCurrent
Definition MainTable.h:502
ImRect WorkRect
Definition MainTable.h:459
float ResizeLockMinContentsX2
Definition MainTable.h:455
ImVec1 HostBackupColumnsOffset
Definition MainTable.h:472
IMGUI_API Table()
Definition MainTable.h:522
float InnerWidth
Definition MainTable.h:451
bool HostSkipItems
Definition MainTable.h:520
float RowMinHeight
Definition MainTable.h:431
ImGuiWindow * OuterWindow
Definition MainTable.h:475
float CellSpacingX1
Definition MainTable.h:447
int RowBgColorCounter
Definition MainTable.h:436
ImS16 InstanceCurrent
Definition MainTable.h:427
ImGuiID ID
Definition MainTable.h:410
float CellPaddingX
Definition MainTable.h:445
ImVec2 HostBackupCursorMaxPos
Definition MainTable.h:470
TableColumnIdx ColumnsEnabledCount
Definition MainTable.h:483
TableColumnIdx ColumnsEnabledFixedCount
Definition MainTable.h:484
TableColumnIdx LastResizedColumn
Definition MainTable.h:490
bool MemoryCompacted
Definition MainTable.h:519
ImRect HostBackupWorkRect
Definition MainTable.h:465
bool IsInitializing
Definition MainTable.h:508
float RefScale
Definition MainTable.h:456
TableColumnIdx ReorderColumnDir
Definition MainTable.h:493
ImGuiTableDrawChannelIdx DummyDrawChannel
Definition MainTable.h:503
ImGuiTableDrawChannelIdx Bg2DrawChannelUnfrozen
Definition MainTable.h:505
ImRect InnerClipRect
Definition MainTable.h:460
ImSpan< TableColumnIdx > DisplayOrderToIndex
Definition MainTable.h:414
float BorderX2
Definition MainTable.h:441
ImGuiTableDrawChannelIdx Bg2DrawChannelCurrent
Definition MainTable.h:504
bool IsResetAllRequest
Definition MainTable.h:515
bool IsLayoutLocked
Definition MainTable.h:506
bool IsSortSpecsDirty
Definition MainTable.h:509
TableColumnIdx HoveredColumnBorder
Definition MainTable.h:487
ImVec2 HostBackupPrevLineSize
Definition MainTable.h:468
bool IsSettingsRequestLoad
Definition MainTable.h:512
ImRect OuterRect
Definition MainTable.h:457
IMGUI_API ~Table()
Definition MainTable.h:526
ImRect HostBackupParentWorkRect
Definition MainTable.h:466
float CellPaddingY
Definition MainTable.h:446
TableColumnIdx FreezeColumnsCount
Definition MainTable.h:501
TableColumnIdx ContextPopupColumn
Definition MainTable.h:497
float ResizedColumnNextWidth
Definition MainTable.h:454
TableColumnIdx HoveredColumnBody
Definition MainTable.h:486
int LastFrameActive
Definition MainTable.h:422
ImGuiWindow * InnerWindow
Definition MainTable.h:476
ImRect Bg2ClipRectForDrawCmd
Definition MainTable.h:463
int CurrentColumn
Definition MainTable.h:426
int CurrentRow
Definition MainTable.h:424
int SettingsOffset
Definition MainTable.h:421
ImRect HostClipRect
Definition MainTable.h:464
ColumnBitMask EnabledMaskByDisplayOrder
Definition MainTable.h:416
ImRect BgClipRect
Definition MainTable.h:461
TableColumnIdx FreezeRowsCount
Definition MainTable.h:499
int ColumnsCount
Definition MainTable.h:423
TableColumnIdx FreezeColumnsRequest
Definition MainTable.h:500
bool IsDefaultDisplayOrder
Definition MainTable.h:514
float HostBackupItemWidth
Definition MainTable.h:473
ImS16 InstanceInteracted
Definition MainTable.h:428
ImVec2 UserOuterSize
Definition MainTable.h:471
TableColumnIdx SortSpecsCount
Definition MainTable.h:482
float ColumnsAutoFitWidth
Definition MainTable.h:453
float RowPosY2
Definition MainTable.h:430
ImGuiTableRowFlags LastRowFlags
Definition MainTable.h:435
TableColumnIdx AutoFitSingleColumn
Definition MainTable.h:488
float HostIndentX
Definition MainTable.h:442
float ColumnsGivenWidth
Definition MainTable.h:452
float OuterPaddingX
Definition MainTable.h:444
ColumnBitMask VisibleMaskByIndex
Definition MainTable.h:418
ColumnBitMask RequestOutputMaskByIndex
Definition MainTable.h:419
TableColumnIdx LeftMostStretchedColumn
Definition MainTable.h:494
ColumnBitMask EnabledMaskByIndex
Definition MainTable.h:417
bool IsResetDisplayOrderRequest
Definition MainTable.h:516
void * RawData
Definition MainTable.h:412
ImGuiTableFlags SettingsLoadedFlags
Definition MainTable.h:420
int CurrentHoveredRow
Definition MainTable.h:425
ImGuiTableRowFlags RowFlags
Definition MainTable.h:434
ImRect Bg0ClipRectForDrawCmd
Definition MainTable.h:462
ImU32 BorderColorLight
Definition MainTable.h:439
ImRect HostBackupInnerClipRect
Definition MainTable.h:467
bool IsUnfrozenRows
Definition MainTable.h:517
float LastOuterHeight
Definition MainTable.h:449