MultiSelect: (breaking) Added 'items_count' parameter to BeginMultiSelect(). Will enable extra features, and remove equivalent param from ImGuiSelectionBasicStorage::ApplyRequests(.
This commit is contained in:
@@ -179,7 +179,7 @@ struct ImGuiMultiSelectIO; // Structure to interact with a BeginMultiSe
|
|||||||
struct ImGuiOnceUponAFrame; // Helper for running a block of code not more than once a frame
|
struct ImGuiOnceUponAFrame; // Helper for running a block of code not more than once a frame
|
||||||
struct ImGuiPayload; // User data payload for drag and drop operations
|
struct ImGuiPayload; // User data payload for drag and drop operations
|
||||||
struct ImGuiPlatformImeData; // Platform IME data for io.PlatformSetImeDataFn() function.
|
struct ImGuiPlatformImeData; // Platform IME data for io.PlatformSetImeDataFn() function.
|
||||||
struct ImGuiSelectionBasicStorage; // Helper struct to store multi-selection state + apply multi-selection requests.
|
struct ImGuiSelectionBasicStorage; // Optional helper to store multi-selection state + apply multi-selection requests.
|
||||||
struct ImGuiSelectionRequest; // A selection request (stored in ImGuiMultiSelectIO)
|
struct ImGuiSelectionRequest; // A selection request (stored in ImGuiMultiSelectIO)
|
||||||
struct ImGuiSizeCallbackData; // Callback data when using SetNextWindowSizeConstraints() (rare/advanced use)
|
struct ImGuiSizeCallbackData; // Callback data when using SetNextWindowSizeConstraints() (rare/advanced use)
|
||||||
struct ImGuiStorage; // Helper for key->value storage (container sorted by key)
|
struct ImGuiStorage; // Helper for key->value storage (container sorted by key)
|
||||||
@@ -673,9 +673,10 @@ namespace ImGui
|
|||||||
|
|
||||||
// Multi-selection system for Selectable() and TreeNode() functions.
|
// Multi-selection system for Selectable() and TreeNode() functions.
|
||||||
// - This enables standard multi-selection/range-selection idioms (CTRL+Mouse/Keyboard, SHIFT+Mouse/Keyboard, etc.) in a way that also allow a clipper to be used.
|
// - This enables standard multi-selection/range-selection idioms (CTRL+Mouse/Keyboard, SHIFT+Mouse/Keyboard, etc.) in a way that also allow a clipper to be used.
|
||||||
// - ImGuiSelectionUserData is often used to store your item index.
|
// - ImGuiSelectionUserData is often used to store your item index within the current view (but may store something else).
|
||||||
// - Read comments near ImGuiMultiSelectIO for instructions/details and see 'Demo->Widgets->Selection State & Multi-Select' for demo.
|
// - Read comments near ImGuiMultiSelectIO for instructions/details and see 'Demo->Widgets->Selection State & Multi-Select' for demo.
|
||||||
IMGUI_API ImGuiMultiSelectIO* BeginMultiSelect(ImGuiMultiSelectFlags flags, int current_selection_size = -1);
|
// - 'selection_size' and 'items_count' parameters are optional and used by a few features. If they are costly for you to compute, you may avoid them.
|
||||||
|
IMGUI_API ImGuiMultiSelectIO* BeginMultiSelect(ImGuiMultiSelectFlags flags, int selection_size = -1, int items_count = -1);
|
||||||
IMGUI_API ImGuiMultiSelectIO* EndMultiSelect();
|
IMGUI_API ImGuiMultiSelectIO* EndMultiSelect();
|
||||||
IMGUI_API void SetNextItemSelectionUserData(ImGuiSelectionUserData selection_user_data);
|
IMGUI_API void SetNextItemSelectionUserData(ImGuiSelectionUserData selection_user_data);
|
||||||
IMGUI_API bool IsItemToggledSelection(); // Was the last item selection state toggled? Useful if you need the per-item information _before_ reaching EndMultiSelect(). We only returns toggle _event_ in order to handle clipping correctly.
|
IMGUI_API bool IsItemToggledSelection(); // Was the last item selection state toggled? Useful if you need the per-item information _before_ reaching EndMultiSelect(). We only returns toggle _event_ in order to handle clipping correctly.
|
||||||
@@ -2799,6 +2800,7 @@ struct ImGuiMultiSelectIO
|
|||||||
ImGuiSelectionUserData NavIdItem; // ms:w, app:r / // (If using deletion) Last known SetNextItemSelectionUserData() value for NavId (if part of submitted items).
|
ImGuiSelectionUserData NavIdItem; // ms:w, app:r / // (If using deletion) Last known SetNextItemSelectionUserData() value for NavId (if part of submitted items).
|
||||||
bool NavIdSelected; // ms:w, app:r / app:r // (If using deletion) Last known selection state for NavId (if part of submitted items).
|
bool NavIdSelected; // ms:w, app:r / app:r // (If using deletion) Last known selection state for NavId (if part of submitted items).
|
||||||
bool RangeSrcReset; // app:w / ms:r // (If using deletion) Set before EndMultiSelect() to reset ResetSrcItem (e.g. if deleted selection).
|
bool RangeSrcReset; // app:w / ms:r // (If using deletion) Set before EndMultiSelect() to reset ResetSrcItem (e.g. if deleted selection).
|
||||||
|
int ItemsCount; // ms:w, app:r / app:r // 'int items_count' parameter to BeginMultiSelect() is copied here for convenience, allowing simpler calls to your ApplyRequests handler. Not used internally.
|
||||||
};
|
};
|
||||||
|
|
||||||
// Selection request type
|
// Selection request type
|
||||||
@@ -2846,8 +2848,8 @@ struct ImGuiSelectionBasicStorage
|
|||||||
ImGuiID (*AdapterIndexToStorageId)(ImGuiSelectionBasicStorage* self, int idx); // e.g. selection.AdapterIndexToStorageId = [](ImGuiSelectionBasicStorage* self, int idx) { return ((MyItems**)self->AdapterData)[idx]->ID; };
|
ImGuiID (*AdapterIndexToStorageId)(ImGuiSelectionBasicStorage* self, int idx); // e.g. selection.AdapterIndexToStorageId = [](ImGuiSelectionBasicStorage* self, int idx) { return ((MyItems**)self->AdapterData)[idx]->ID; };
|
||||||
void* UserData; // User data for use by adapter function // e.g. selection.UserData = (void*)my_items;
|
void* UserData; // User data for use by adapter function // e.g. selection.UserData = (void*)my_items;
|
||||||
|
|
||||||
// Methods: apply selection requests coming from BeginMultiSelect() and EndMultiSelect() functions
|
// Methods: apply selection requests coming from BeginMultiSelect() and EndMultiSelect() functions. Uses 'items_count' based to BeginMultiSelect()
|
||||||
IMGUI_API void ApplyRequests(ImGuiMultiSelectIO* ms_io, int items_count);
|
IMGUI_API void ApplyRequests(ImGuiMultiSelectIO* ms_io);
|
||||||
|
|
||||||
// Methods: selection storage
|
// Methods: selection storage
|
||||||
ImGuiSelectionBasicStorage() { Clear(); UserData = NULL; AdapterIndexToStorageId = [](ImGuiSelectionBasicStorage*, int idx) { return (ImGuiID)idx; }; }
|
ImGuiSelectionBasicStorage() { Clear(); UserData = NULL; AdapterIndexToStorageId = [](ImGuiSelectionBasicStorage*, int idx) { return (ImGuiID)idx; }; }
|
||||||
|
|||||||
+20
-20
@@ -2874,7 +2874,7 @@ struct ExampleDualListBox
|
|||||||
// In this example we store item id in selection (instead of item index)
|
// In this example we store item id in selection (instead of item index)
|
||||||
Selections[side].UserData = Items[side].Data;
|
Selections[side].UserData = Items[side].Data;
|
||||||
Selections[side].AdapterIndexToStorageId = [](ImGuiSelectionBasicStorage* self, int idx) { ImGuiID* items = (ImGuiID*)self->UserData; return items[idx]; };
|
Selections[side].AdapterIndexToStorageId = [](ImGuiSelectionBasicStorage* self, int idx) { ImGuiID* items = (ImGuiID*)self->UserData; return items[idx]; };
|
||||||
Selections[side].ApplyRequests(ms_io, Items[side].Size);
|
Selections[side].ApplyRequests(ms_io);
|
||||||
}
|
}
|
||||||
static int IMGUI_CDECL CompareItemsByValue(const void* lhs, const void* rhs)
|
static int IMGUI_CDECL CompareItemsByValue(const void* lhs, const void* rhs)
|
||||||
{
|
{
|
||||||
@@ -2929,7 +2929,7 @@ struct ExampleDualListBox
|
|||||||
if (child_visible)
|
if (child_visible)
|
||||||
{
|
{
|
||||||
ImGuiMultiSelectFlags flags = ImGuiMultiSelectFlags_None;
|
ImGuiMultiSelectFlags flags = ImGuiMultiSelectFlags_None;
|
||||||
ImGuiMultiSelectIO* ms_io = ImGui::BeginMultiSelect(flags, selection.Size);
|
ImGuiMultiSelectIO* ms_io = ImGui::BeginMultiSelect(flags, selection.Size, items.Size);
|
||||||
ApplySelectionRequests(ms_io, side);
|
ApplySelectionRequests(ms_io, side);
|
||||||
|
|
||||||
for (int item_n = 0; item_n < items.Size; item_n++)
|
for (int item_n = 0; item_n < items.Size; item_n++)
|
||||||
@@ -3060,8 +3060,8 @@ static void ShowDemoWindowMultiSelect()
|
|||||||
if (ImGui::BeginChild("##Basket", ImVec2(-FLT_MIN, ImGui::GetFontSize() * 20), ImGuiChildFlags_FrameStyle | ImGuiChildFlags_ResizeY))
|
if (ImGui::BeginChild("##Basket", ImVec2(-FLT_MIN, ImGui::GetFontSize() * 20), ImGuiChildFlags_FrameStyle | ImGuiChildFlags_ResizeY))
|
||||||
{
|
{
|
||||||
ImGuiMultiSelectFlags flags = ImGuiMultiSelectFlags_ClearOnEscape | ImGuiMultiSelectFlags_BoxSelect1d;
|
ImGuiMultiSelectFlags flags = ImGuiMultiSelectFlags_ClearOnEscape | ImGuiMultiSelectFlags_BoxSelect1d;
|
||||||
ImGuiMultiSelectIO* ms_io = ImGui::BeginMultiSelect(flags, selection.Size);
|
ImGuiMultiSelectIO* ms_io = ImGui::BeginMultiSelect(flags, selection.Size, ITEMS_COUNT);
|
||||||
selection.ApplyRequests(ms_io, ITEMS_COUNT);
|
selection.ApplyRequests(ms_io);
|
||||||
|
|
||||||
for (int n = 0; n < ITEMS_COUNT; n++)
|
for (int n = 0; n < ITEMS_COUNT; n++)
|
||||||
{
|
{
|
||||||
@@ -3073,7 +3073,7 @@ static void ShowDemoWindowMultiSelect()
|
|||||||
}
|
}
|
||||||
|
|
||||||
ms_io = ImGui::EndMultiSelect();
|
ms_io = ImGui::EndMultiSelect();
|
||||||
selection.ApplyRequests(ms_io, ITEMS_COUNT);
|
selection.ApplyRequests(ms_io);
|
||||||
}
|
}
|
||||||
ImGui::EndChild();
|
ImGui::EndChild();
|
||||||
ImGui::TreePop();
|
ImGui::TreePop();
|
||||||
@@ -3094,8 +3094,8 @@ static void ShowDemoWindowMultiSelect()
|
|||||||
if (ImGui::BeginChild("##Basket", ImVec2(-FLT_MIN, ImGui::GetFontSize() * 20), ImGuiChildFlags_FrameStyle | ImGuiChildFlags_ResizeY))
|
if (ImGui::BeginChild("##Basket", ImVec2(-FLT_MIN, ImGui::GetFontSize() * 20), ImGuiChildFlags_FrameStyle | ImGuiChildFlags_ResizeY))
|
||||||
{
|
{
|
||||||
ImGuiMultiSelectFlags flags = ImGuiMultiSelectFlags_ClearOnEscape | ImGuiMultiSelectFlags_BoxSelect1d;
|
ImGuiMultiSelectFlags flags = ImGuiMultiSelectFlags_ClearOnEscape | ImGuiMultiSelectFlags_BoxSelect1d;
|
||||||
ImGuiMultiSelectIO* ms_io = ImGui::BeginMultiSelect(flags, selection.Size);
|
ImGuiMultiSelectIO* ms_io = ImGui::BeginMultiSelect(flags, selection.Size, ITEMS_COUNT);
|
||||||
selection.ApplyRequests(ms_io, ITEMS_COUNT);
|
selection.ApplyRequests(ms_io);
|
||||||
|
|
||||||
ImGuiListClipper clipper;
|
ImGuiListClipper clipper;
|
||||||
clipper.Begin(ITEMS_COUNT);
|
clipper.Begin(ITEMS_COUNT);
|
||||||
@@ -3114,7 +3114,7 @@ static void ShowDemoWindowMultiSelect()
|
|||||||
}
|
}
|
||||||
|
|
||||||
ms_io = ImGui::EndMultiSelect();
|
ms_io = ImGui::EndMultiSelect();
|
||||||
selection.ApplyRequests(ms_io, ITEMS_COUNT);
|
selection.ApplyRequests(ms_io);
|
||||||
}
|
}
|
||||||
ImGui::EndChild();
|
ImGui::EndChild();
|
||||||
ImGui::TreePop();
|
ImGui::TreePop();
|
||||||
@@ -3158,8 +3158,8 @@ static void ShowDemoWindowMultiSelect()
|
|||||||
if (ImGui::BeginChild("##Basket", ImVec2(-FLT_MIN, ImGui::GetFontSize() * 20), ImGuiChildFlags_FrameStyle | ImGuiChildFlags_ResizeY))
|
if (ImGui::BeginChild("##Basket", ImVec2(-FLT_MIN, ImGui::GetFontSize() * 20), ImGuiChildFlags_FrameStyle | ImGuiChildFlags_ResizeY))
|
||||||
{
|
{
|
||||||
ImGuiMultiSelectFlags flags = ImGuiMultiSelectFlags_ClearOnEscape | ImGuiMultiSelectFlags_BoxSelect1d;
|
ImGuiMultiSelectFlags flags = ImGuiMultiSelectFlags_ClearOnEscape | ImGuiMultiSelectFlags_BoxSelect1d;
|
||||||
ImGuiMultiSelectIO* ms_io = ImGui::BeginMultiSelect(flags, selection.Size);
|
ImGuiMultiSelectIO* ms_io = ImGui::BeginMultiSelect(flags, selection.Size, items.Size);
|
||||||
selection.ApplyRequests(ms_io, items.Size);
|
selection.ApplyRequests(ms_io);
|
||||||
|
|
||||||
const bool want_delete = ImGui::Shortcut(ImGuiKey_Delete, ImGuiInputFlags_Repeat) && (selection.Size > 0);
|
const bool want_delete = ImGui::Shortcut(ImGuiKey_Delete, ImGuiInputFlags_Repeat) && (selection.Size > 0);
|
||||||
const int item_curr_idx_to_focus = want_delete ? selection.ApplyDeletionPreLoop(ms_io, items.Size) : -1;
|
const int item_curr_idx_to_focus = want_delete ? selection.ApplyDeletionPreLoop(ms_io, items.Size) : -1;
|
||||||
@@ -3179,7 +3179,7 @@ static void ShowDemoWindowMultiSelect()
|
|||||||
|
|
||||||
// Apply multi-select requests
|
// Apply multi-select requests
|
||||||
ms_io = ImGui::EndMultiSelect();
|
ms_io = ImGui::EndMultiSelect();
|
||||||
selection.ApplyRequests(ms_io, items.Size);
|
selection.ApplyRequests(ms_io);
|
||||||
if (want_delete)
|
if (want_delete)
|
||||||
selection.ApplyDeletionPostLoop(ms_io, items, item_curr_idx_to_focus);
|
selection.ApplyDeletionPostLoop(ms_io, items, item_curr_idx_to_focus);
|
||||||
}
|
}
|
||||||
@@ -3275,8 +3275,8 @@ static void ShowDemoWindowMultiSelect()
|
|||||||
{
|
{
|
||||||
ImGui::PushID(selection_scope_n);
|
ImGui::PushID(selection_scope_n);
|
||||||
ImGuiSelectionBasicStorage* selection = &selections_data[selection_scope_n];
|
ImGuiSelectionBasicStorage* selection = &selections_data[selection_scope_n];
|
||||||
ImGuiMultiSelectIO* ms_io = ImGui::BeginMultiSelect(flags, selection->Size);
|
ImGuiMultiSelectIO* ms_io = ImGui::BeginMultiSelect(flags, selection->Size, ITEMS_COUNT);
|
||||||
selection->ApplyRequests(ms_io, ITEMS_COUNT);
|
selection->ApplyRequests(ms_io);
|
||||||
|
|
||||||
ImGui::SeparatorText("Selection scope");
|
ImGui::SeparatorText("Selection scope");
|
||||||
ImGui::Text("Selection size: %d/%d", selection->Size, ITEMS_COUNT);
|
ImGui::Text("Selection size: %d/%d", selection->Size, ITEMS_COUNT);
|
||||||
@@ -3292,7 +3292,7 @@ static void ShowDemoWindowMultiSelect()
|
|||||||
|
|
||||||
// Apply multi-select requests
|
// Apply multi-select requests
|
||||||
ms_io = ImGui::EndMultiSelect();
|
ms_io = ImGui::EndMultiSelect();
|
||||||
selection->ApplyRequests(ms_io, ITEMS_COUNT);
|
selection->ApplyRequests(ms_io);
|
||||||
ImGui::PopID();
|
ImGui::PopID();
|
||||||
}
|
}
|
||||||
ImGui::TreePop();
|
ImGui::TreePop();
|
||||||
@@ -3375,8 +3375,8 @@ static void ShowDemoWindowMultiSelect()
|
|||||||
if (widget_type == WidgetType_TreeNode)
|
if (widget_type == WidgetType_TreeNode)
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(ImGui::GetStyle().ItemSpacing.x, 0.0f));
|
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(ImGui::GetStyle().ItemSpacing.x, 0.0f));
|
||||||
|
|
||||||
ImGuiMultiSelectIO* ms_io = ImGui::BeginMultiSelect(flags, selection.Size);
|
ImGuiMultiSelectIO* ms_io = ImGui::BeginMultiSelect(flags, selection.Size, items.Size);
|
||||||
selection.ApplyRequests(ms_io, items.Size);
|
selection.ApplyRequests(ms_io);
|
||||||
|
|
||||||
const bool want_delete = (ImGui::Shortcut(ImGuiKey_Delete, ImGuiInputFlags_Repeat) && (selection.Size > 0)) || request_deletion_from_menu;
|
const bool want_delete = (ImGui::Shortcut(ImGuiKey_Delete, ImGuiInputFlags_Repeat) && (selection.Size > 0)) || request_deletion_from_menu;
|
||||||
const int item_curr_idx_to_focus = want_delete ? selection.ApplyDeletionPreLoop(ms_io, items.Size) : -1;
|
const int item_curr_idx_to_focus = want_delete ? selection.ApplyDeletionPreLoop(ms_io, items.Size) : -1;
|
||||||
@@ -3520,7 +3520,7 @@ static void ShowDemoWindowMultiSelect()
|
|||||||
|
|
||||||
// Apply multi-select requests
|
// Apply multi-select requests
|
||||||
ms_io = ImGui::EndMultiSelect();
|
ms_io = ImGui::EndMultiSelect();
|
||||||
selection.ApplyRequests(ms_io, items.Size);
|
selection.ApplyRequests(ms_io);
|
||||||
if (want_delete)
|
if (want_delete)
|
||||||
selection.ApplyDeletionPostLoop(ms_io, items, item_curr_idx_to_focus);
|
selection.ApplyDeletionPostLoop(ms_io, items, item_curr_idx_to_focus);
|
||||||
|
|
||||||
@@ -9846,12 +9846,12 @@ struct ExampleAssetsBrowser
|
|||||||
ms_flags |= ImGuiMultiSelectFlags_SelectOnClickRelease; // To allow dragging an unselected item without altering selection.
|
ms_flags |= ImGuiMultiSelectFlags_SelectOnClickRelease; // To allow dragging an unselected item without altering selection.
|
||||||
if (AllowBoxSelect)
|
if (AllowBoxSelect)
|
||||||
ms_flags |= ImGuiMultiSelectFlags_BoxSelect; // Enable box-select in 2D mode.
|
ms_flags |= ImGuiMultiSelectFlags_BoxSelect; // Enable box-select in 2D mode.
|
||||||
ImGuiMultiSelectIO* ms_io = ImGui::BeginMultiSelect(ms_flags, Selection.Size);
|
ImGuiMultiSelectIO* ms_io = ImGui::BeginMultiSelect(ms_flags, Selection.Size, Items.Size);
|
||||||
|
|
||||||
// Use custom selection adapter: store ID in selection (recommended)
|
// Use custom selection adapter: store ID in selection (recommended)
|
||||||
Selection.UserData = this;
|
Selection.UserData = this;
|
||||||
Selection.AdapterIndexToStorageId = [](ImGuiSelectionBasicStorage* self_, int idx) { ExampleAssetsBrowser* self = (ExampleAssetsBrowser*)self_->UserData; return self->Items[idx].ID; };
|
Selection.AdapterIndexToStorageId = [](ImGuiSelectionBasicStorage* self_, int idx) { ExampleAssetsBrowser* self = (ExampleAssetsBrowser*)self_->UserData; return self->Items[idx].ID; };
|
||||||
Selection.ApplyRequests(ms_io, Items.Size);
|
Selection.ApplyRequests(ms_io);
|
||||||
|
|
||||||
const bool want_delete = (ImGui::Shortcut(ImGuiKey_Delete, ImGuiInputFlags_Repeat) && (Selection.Size > 0)) || RequestDelete;
|
const bool want_delete = (ImGui::Shortcut(ImGuiKey_Delete, ImGuiInputFlags_Repeat) && (Selection.Size > 0)) || RequestDelete;
|
||||||
const int item_curr_idx_to_focus = want_delete ? Selection.ApplyDeletionPreLoop(ms_io, Items.Size) : -1;
|
const int item_curr_idx_to_focus = want_delete ? Selection.ApplyDeletionPreLoop(ms_io, Items.Size) : -1;
|
||||||
@@ -9959,7 +9959,7 @@ struct ExampleAssetsBrowser
|
|||||||
}
|
}
|
||||||
|
|
||||||
ms_io = ImGui::EndMultiSelect();
|
ms_io = ImGui::EndMultiSelect();
|
||||||
Selection.ApplyRequests(ms_io, Items.Size);
|
Selection.ApplyRequests(ms_io);
|
||||||
if (want_delete)
|
if (want_delete)
|
||||||
Selection.ApplyDeletionPostLoop(ms_io, Items, item_curr_idx_to_focus);
|
Selection.ApplyDeletionPostLoop(ms_io, Items, item_curr_idx_to_focus);
|
||||||
|
|
||||||
|
|||||||
+19
-10
@@ -7300,10 +7300,13 @@ static void DebugLogMultiSelectRequests(const char* function, const ImGuiMultiSe
|
|||||||
|
|
||||||
// Return ImGuiMultiSelectIO structure.
|
// Return ImGuiMultiSelectIO structure.
|
||||||
// Lifetime: don't hold on ImGuiMultiSelectIO* pointers over multiple frames or past any subsequent call to BeginMultiSelect() or EndMultiSelect().
|
// Lifetime: don't hold on ImGuiMultiSelectIO* pointers over multiple frames or past any subsequent call to BeginMultiSelect() or EndMultiSelect().
|
||||||
// Passing 'current_selection_size' is currently optional:
|
// Passing 'selection_size' and 'items_count' parameters is currently optional.
|
||||||
// - it is useful for shortcut routing with ImGuiMultiSelectFlags_ClearOnEscape: so we can have Escape be used to clear selection THEN to exit child window.
|
// - 'selection_size' is useful to disable some shortcut routing: e.g. ImGuiMultiSelectFlags_ClearOnEscape won't claim Escape key when selection_size 0,
|
||||||
// - if it is costly for you to compute, but can easily tell if your selection is empty or not, you may pass 1, or use the ImGuiMultiSelectFlags_ClearOnEscape flag dynamically.
|
// allowing a first press to clear selection THEN the second press to leave child window and return to parent.
|
||||||
ImGuiMultiSelectIO* ImGui::BeginMultiSelect(ImGuiMultiSelectFlags flags, int current_selection_size)
|
// - 'items_count' is stored in ImGuiMultiSelectIO which makes it a convenient way to pass the information to your ApplyRequest() handler (but you may pass it differently).
|
||||||
|
// - If they are costly for you to compute (e.g. external intrusive selection without maintaining size), you may avoid them and pass -1.
|
||||||
|
// - If you can easily tell if your selection is empty or not, you may pass 0/1, or you may enable ImGuiMultiSelectFlags_ClearOnEscape flag dynamically.
|
||||||
|
ImGuiMultiSelectIO* ImGui::BeginMultiSelect(ImGuiMultiSelectFlags flags, int selection_size, int items_count)
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
ImGuiWindow* window = g.CurrentWindow;
|
ImGuiWindow* window = g.CurrentWindow;
|
||||||
@@ -7341,15 +7344,16 @@ ImGuiMultiSelectIO* ImGui::BeginMultiSelect(ImGuiMultiSelectFlags flags, int cur
|
|||||||
ImGuiMultiSelectState* storage = g.MultiSelectStorage.GetOrAddByKey(id);
|
ImGuiMultiSelectState* storage = g.MultiSelectStorage.GetOrAddByKey(id);
|
||||||
storage->ID = id;
|
storage->ID = id;
|
||||||
storage->LastFrameActive = g.FrameCount;
|
storage->LastFrameActive = g.FrameCount;
|
||||||
storage->LastSelectionSize = current_selection_size;
|
storage->LastSelectionSize = selection_size;
|
||||||
storage->Window = window;
|
storage->Window = window;
|
||||||
ms->Storage = storage;
|
ms->Storage = storage;
|
||||||
|
|
||||||
// Output to user
|
// Output to user
|
||||||
|
ms->IO.Requests.resize(0);
|
||||||
ms->IO.RangeSrcItem = storage->RangeSrcItem;
|
ms->IO.RangeSrcItem = storage->RangeSrcItem;
|
||||||
ms->IO.NavIdItem = storage->NavIdItem;
|
ms->IO.NavIdItem = storage->NavIdItem;
|
||||||
ms->IO.NavIdSelected = (storage->NavIdSelected == 1) ? true : false;
|
ms->IO.NavIdSelected = (storage->NavIdSelected == 1) ? true : false;
|
||||||
ms->IO.Requests.resize(0);
|
ms->IO.ItemsCount = items_count;
|
||||||
|
|
||||||
// Clear when using Navigation to move within the scope
|
// Clear when using Navigation to move within the scope
|
||||||
// (we compare FocusScopeId so it possible to use multiple selections inside a same window)
|
// (we compare FocusScopeId so it possible to use multiple selections inside a same window)
|
||||||
@@ -7375,7 +7379,7 @@ ImGuiMultiSelectIO* ImGui::BeginMultiSelect(ImGuiMultiSelectFlags flags, int cur
|
|||||||
{
|
{
|
||||||
// Shortcut: Clear selection (Escape)
|
// Shortcut: Clear selection (Escape)
|
||||||
// Only claim shortcut if selection is not empty, allowing further presses on Escape to e.g. leave current child window.
|
// Only claim shortcut if selection is not empty, allowing further presses on Escape to e.g. leave current child window.
|
||||||
if ((flags & ImGuiMultiSelectFlags_ClearOnEscape) && (current_selection_size != 0))
|
if ((flags & ImGuiMultiSelectFlags_ClearOnEscape) && (selection_size != 0))
|
||||||
if (Shortcut(ImGuiKey_Escape))
|
if (Shortcut(ImGuiKey_Escape))
|
||||||
request_clear = true;
|
request_clear = true;
|
||||||
|
|
||||||
@@ -7826,17 +7830,22 @@ void ImGui::DebugNodeMultiSelectState(ImGuiMultiSelectState* storage)
|
|||||||
// if (req.Type == ImGuiSelectionRequestType_SetAll) { Clear(); if (req.Selected) { for (int n = 0; n < items_count; n++) { AddItem(n); } }
|
// if (req.Type == ImGuiSelectionRequestType_SetAll) { Clear(); if (req.Selected) { for (int n = 0; n < items_count; n++) { AddItem(n); } }
|
||||||
// if (req.Type == ImGuiSelectionRequestType_SetRange) { for (int n = (int)ms_io->RangeFirstItem; n <= (int)ms_io->RangeLastItem; n++) { UpdateItem(n, ms_io->Selected); } }
|
// if (req.Type == ImGuiSelectionRequestType_SetRange) { for (int n = (int)ms_io->RangeFirstItem; n <= (int)ms_io->RangeLastItem; n++) { UpdateItem(n, ms_io->Selected); } }
|
||||||
// }
|
// }
|
||||||
void ImGuiSelectionBasicStorage::ApplyRequests(ImGuiMultiSelectIO* ms_io, int items_count)
|
void ImGuiSelectionBasicStorage::ApplyRequests(ImGuiMultiSelectIO* ms_io)
|
||||||
{
|
{
|
||||||
|
// For convenience we obtain ItemsCount as passed to BeginMultiSelect(), which is optional.
|
||||||
|
// It makes sense when using ImGuiSelectionBasicStorage to simply pass your items count to BeginMultiSelect().
|
||||||
|
// Other scheme may handle SetAll differently.
|
||||||
|
IM_ASSERT(ms_io->ItemsCount != -1 && "Missing value for items_count in BeginMultiSelect() call!");
|
||||||
IM_ASSERT(AdapterIndexToStorageId != NULL);
|
IM_ASSERT(AdapterIndexToStorageId != NULL);
|
||||||
|
|
||||||
for (ImGuiSelectionRequest& req : ms_io->Requests)
|
for (ImGuiSelectionRequest& req : ms_io->Requests)
|
||||||
{
|
{
|
||||||
if (req.Type == ImGuiSelectionRequestType_SetAll)
|
if (req.Type == ImGuiSelectionRequestType_SetAll)
|
||||||
Clear();
|
Clear();
|
||||||
if (req.Type == ImGuiSelectionRequestType_SetAll && req.Selected)
|
if (req.Type == ImGuiSelectionRequestType_SetAll && req.Selected)
|
||||||
{
|
{
|
||||||
Storage.Data.reserve(items_count);
|
Storage.Data.reserve(ms_io->ItemsCount);
|
||||||
for (int idx = 0; idx < items_count; idx++)
|
for (int idx = 0; idx < ms_io->ItemsCount; idx++)
|
||||||
SetItemSelected(AdapterIndexToStorageId(this, idx), true);
|
SetItemSelected(AdapterIndexToStorageId(this, idx), true);
|
||||||
}
|
}
|
||||||
if (req.Type == ImGuiSelectionRequestType_SetRange)
|
if (req.Type == ImGuiSelectionRequestType_SetRange)
|
||||||
|
|||||||
Reference in New Issue
Block a user