From 9aa84f7c88c38cf80ea114aa6fd4ba18e1ee4d64 Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 11 Jun 2024 19:45:21 +0200 Subject: [PATCH] RangeSelect/MultiSelect: ImGuiSelectionBasicStorage: move function bodies to cpp file. + make ImGuiStorage::BuildSortByKey() less affected by msvc debug mode. --- imgui.cpp | 2 ++ imgui.h | 22 ++++++++++------------ imgui_widgets.cpp | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 12 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index d4dad468..09904162 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2524,6 +2524,7 @@ ImGuiStoragePair* ImLowerBound(ImGuiStoragePair* in_begin, ImGuiStoragePair* in_ } // For quicker full rebuild of a storage (instead of an incremental one), you may add all your contents and then sort once. +IM_MSVC_RUNTIME_CHECKS_OFF void ImGuiStorage::BuildSortByKey() { struct StaticFunc @@ -2538,6 +2539,7 @@ void ImGuiStorage::BuildSortByKey() }; ImQsort(Data.Data, (size_t)Data.Size, sizeof(ImGuiStoragePair), StaticFunc::PairComparerByID); } +IM_MSVC_RUNTIME_CHECKS_RESTORE int ImGuiStorage::GetInt(ImGuiID key, int default_val) const { diff --git a/imgui.h b/imgui.h index 61879195..4820b436 100644 --- a/imgui.h +++ b/imgui.h @@ -2777,16 +2777,14 @@ struct ImGuiSelectionBasicStorage ImGuiID (*AdapterIndexToStorageId)(ImGuiSelectionBasicStorage* self, int idx); // e.g. selection.AdapterIndexToStorageId = [](ImGuiSelectionBasicStorage* self, int idx) { return ((MyItems**)self->UserData)[idx]->ID; }; // Methods - IMGUI_API void ApplyRequests(ImGuiMultiSelectIO* ms_io);// Apply selection requests coming from BeginMultiSelect() and EndMultiSelect() functions. It uses 'items_count' passed to BeginMultiSelect() - IMGUI_API ImGuiID GetNextSelectedItem(void** opaque_it); // Iterate selection with 'void* it = NULL; while (ImGuiId id = selection.GetNextSelectedItem(&it)) { ... }' - bool Contains(ImGuiID id) const { return _Storage.GetInt(id, 0) != 0; } // Query if an item id is in selection. - ImGuiID GetStorageIdFromIndex(int idx) { return AdapterIndexToStorageId(this, idx); } // Convert index to item id based on provided adapter. - - // [Internal, rarely called directly by end-user] - ImGuiSelectionBasicStorage() { Size = 0; UserData = NULL; AdapterIndexToStorageId = [](ImGuiSelectionBasicStorage*, int idx) { return (ImGuiID)idx; }; } - void Clear() { _Storage.Data.resize(0); Size = 0; } - void Swap(ImGuiSelectionBasicStorage& r) { _Storage.Data.swap(r._Storage.Data); int lhs_size = Size; Size = r.Size; r.Size = lhs_size; } - void SetItemSelected(ImGuiID id, bool v) { int* p_int = _Storage.GetIntRef(id, 0); if (v && *p_int == 0) { *p_int = 1; Size++; } else if (!v && *p_int != 0) { *p_int = 0; Size--; } } + ImGuiSelectionBasicStorage(); + IMGUI_API void ApplyRequests(ImGuiMultiSelectIO* ms_io); // Apply selection requests coming from BeginMultiSelect() and EndMultiSelect() functions. It uses 'items_count' passed to BeginMultiSelect() + IMGUI_API bool Contains(ImGuiID id) const; // Query if an item id is in selection. + IMGUI_API void Clear(); // Clear selection + IMGUI_API void Swap(ImGuiSelectionBasicStorage& r); // Swap two selections + IMGUI_API void SetItemSelected(ImGuiID id, bool selected); // Add/remove an item from selection (generally done by ApplyRequests() function) + IMGUI_API ImGuiID GetNextSelectedItem(void** opaque_it); // Iterate selection with 'void* it = NULL; while (ImGuiId id = selection.GetNextSelectedItem(&it)) { ... }' + inline ImGuiID GetStorageIdFromIndex(int idx) { return AdapterIndexToStorageId(this, idx); } // Convert index to item id based on provided adapter. }; // Optional helper to apply multi-selection requests to existing randomly accessible storage. @@ -2798,8 +2796,8 @@ struct ImGuiSelectionExternalStorage void (*AdapterSetItemSelected)(ImGuiSelectionExternalStorage* self, int idx, bool selected); // e.g. AdapterSetItemSelected = [](ImGuiSelectionExternalStorage* self, int idx, bool selected) { ((MyItems**)self->UserData)[idx]->Selected = selected; } // Methods - ImGuiSelectionExternalStorage() { UserData = NULL; AdapterSetItemSelected = NULL; } - IMGUI_API void ApplyRequests(ImGuiMultiSelectIO* ms_io); // Generic function, using AdapterSetItemSelected() + IMGUI_API ImGuiSelectionExternalStorage(); + IMGUI_API void ApplyRequests(ImGuiMultiSelectIO* ms_io); // Apply selection requests by using AdapterSetItemSelected() calls }; //----------------------------------------------------------------------------- diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index a1e33f0c..0774694f 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -7704,6 +7704,30 @@ void ImGui::DebugNodeMultiSelectState(ImGuiMultiSelectState* storage) // - ImGuiSelectionExternalStorage //------------------------------------------------------------------------- +ImGuiSelectionBasicStorage::ImGuiSelectionBasicStorage() +{ + Size = 0; + UserData = NULL; + AdapterIndexToStorageId = [](ImGuiSelectionBasicStorage*, int idx) { return (ImGuiID)idx; }; +} + +void ImGuiSelectionBasicStorage::Clear() +{ + Size = 0; + _Storage.Data.resize(0); +} + +void ImGuiSelectionBasicStorage::Swap(ImGuiSelectionBasicStorage& r) +{ + ImSwap(Size, r.Size); + _Storage.Data.swap(r._Storage.Data); +} + +bool ImGuiSelectionBasicStorage::Contains(ImGuiID id) const +{ + return _Storage.GetInt(id, 0) != 0; +} + // GetNextSelectedItem() is an abstraction allowing us to change our underlying actual storage system without impacting user. // (e.g. store unselected vs compact down, compact down on demand, use raw ImVector instead of ImGuiStorage...) ImGuiID ImGuiSelectionBasicStorage::GetNextSelectedItem(void** opaque_it) @@ -7721,6 +7745,13 @@ ImGuiID ImGuiSelectionBasicStorage::GetNextSelectedItem(void** opaque_it) return has_more ? it->key : 0; } +void ImGuiSelectionBasicStorage::SetItemSelected(ImGuiID id, bool selected) +{ + int* p_int = _Storage.GetIntRef(id, 0); + if (selected && *p_int == 0) { *p_int = 1; Size++; } + else if (!selected && *p_int != 0) { *p_int = 0; Size--; } +} + // Optimized for batch edits (with same value of 'selected') static void ImGuiSelectionBasicStorage_BatchSetItemSelected(ImGuiSelectionBasicStorage* selection, ImGuiID id, bool selected, int size_before_amends) { @@ -7797,6 +7828,12 @@ void ImGuiSelectionBasicStorage::ApplyRequests(ImGuiMultiSelectIO* ms_io) //------------------------------------------------------------------------- +ImGuiSelectionExternalStorage::ImGuiSelectionExternalStorage() +{ + UserData = NULL; + AdapterSetItemSelected = NULL; +} + // Apply requests coming from BeginMultiSelect() and EndMultiSelect(). // We also pull 'ms_io->ItemsCount' as passed for BeginMultiSelect() for consistency with ImGuiSelectionBasicStorage // This makes no assumption about underlying storage.