MultiSelect: added ImGuiSelectionExternalStorage helper. Simplify bool demo.
This commit is contained in:
parent
f9caf4447a
commit
db4898cb91
16
imgui.h
16
imgui.h
@ -44,7 +44,7 @@ Index of this file:
|
|||||||
// [SECTION] ImGuiIO
|
// [SECTION] ImGuiIO
|
||||||
// [SECTION] Misc data structures (ImGuiInputTextCallbackData, ImGuiSizeCallbackData, ImGuiPayload)
|
// [SECTION] Misc data structures (ImGuiInputTextCallbackData, ImGuiSizeCallbackData, ImGuiPayload)
|
||||||
// [SECTION] Helpers (ImGuiOnceUponAFrame, ImGuiTextFilter, ImGuiTextBuffer, ImGuiStorage, ImGuiListClipper, Math Operators, ImColor)
|
// [SECTION] Helpers (ImGuiOnceUponAFrame, ImGuiTextFilter, ImGuiTextBuffer, ImGuiStorage, ImGuiListClipper, Math Operators, ImColor)
|
||||||
// [SECTION] Multi-Select API flags and structures (ImGuiMultiSelectFlags, ImGuiMultiSelectIO, ImGuiSelectionRequest, ImGuiSelectionBasicStorage)
|
// [SECTION] Multi-Select API flags and structures (ImGuiMultiSelectFlags, ImGuiMultiSelectIO, ImGuiSelectionRequest, ImGuiSelectionBasicStorage, ImGuiSelectionExternalStorage)
|
||||||
// [SECTION] Drawing API (ImDrawCallback, ImDrawCmd, ImDrawIdx, ImDrawVert, ImDrawChannel, ImDrawListSplitter, ImDrawFlags, ImDrawListFlags, ImDrawList, ImDrawData)
|
// [SECTION] Drawing API (ImDrawCallback, ImDrawCmd, ImDrawIdx, ImDrawVert, ImDrawChannel, ImDrawListSplitter, ImDrawFlags, ImDrawListFlags, ImDrawList, ImDrawData)
|
||||||
// [SECTION] Font API (ImFontConfig, ImFontGlyph, ImFontGlyphRangesBuilder, ImFontAtlasFlags, ImFontAtlas, ImFont)
|
// [SECTION] Font API (ImFontConfig, ImFontGlyph, ImFontGlyphRangesBuilder, ImFontAtlasFlags, ImFontAtlas, ImFont)
|
||||||
// [SECTION] Viewports (ImGuiViewportFlags, ImGuiViewport)
|
// [SECTION] Viewports (ImGuiViewportFlags, ImGuiViewport)
|
||||||
@ -180,6 +180,7 @@ struct ImGuiOnceUponAFrame; // Helper for running a block of code not mo
|
|||||||
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; // Optional helper to store multi-selection state + apply multi-selection requests.
|
struct ImGuiSelectionBasicStorage; // Optional helper to store multi-selection state + apply multi-selection requests.
|
||||||
|
struct ImGuiSelectionExternalStorage;//Optional helper to apply multi-selection requests to existing randomly accessible storage.
|
||||||
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)
|
||||||
@ -2860,6 +2861,19 @@ struct ImGuiSelectionBasicStorage
|
|||||||
ImGuiID GetStorageIdFromIndex(int idx) { return AdapterIndexToStorageId(this, idx); }
|
ImGuiID GetStorageIdFromIndex(int idx) { return AdapterIndexToStorageId(this, idx); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Optional helper to apply multi-selection requests to existing randomly accessible storage.
|
||||||
|
// Convenient if you want to quickly wire multi-select API on e.g. an array of bool or items storing their own selection state.
|
||||||
|
struct ImGuiSelectionExternalStorage
|
||||||
|
{
|
||||||
|
// Members
|
||||||
|
void (*AdapterSetItemSelected)(ImGuiSelectionExternalStorage* self, int idx, bool selected); // e.g. AdapterSetItemSelected = [](ImGuiSelectionExternalStorage* self, int idx, bool selected) { ((MyItems**)self->UserData)[idx]->Selected = selected; }
|
||||||
|
void* UserData; // User data for use by adapter function // e.g. selection.UserData = (void*)my_items;
|
||||||
|
|
||||||
|
// Methods
|
||||||
|
ImGuiSelectionExternalStorage() { memset(this, 0, sizeof(*this)); }
|
||||||
|
IMGUI_API void ApplyRequests(ImGuiMultiSelectIO* ms_io); // Generic function, using AdapterSetItemSelected()
|
||||||
|
};
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// [SECTION] Drawing API (ImDrawCmd, ImDrawIdx, ImDrawVert, ImDrawChannel, ImDrawListSplitter, ImDrawListFlags, ImDrawList, ImDrawData)
|
// [SECTION] Drawing API (ImDrawCmd, ImDrawIdx, ImDrawVert, ImDrawChannel, ImDrawListSplitter, ImDrawListFlags, ImDrawList, ImDrawData)
|
||||||
// Hold a series of drawing commands. The user provides a renderer for ImDrawData which essentially contains an array of ImDrawList.
|
// Hold a series of drawing commands. The user provides a renderer for ImDrawData which essentially contains an array of ImDrawList.
|
||||||
|
@ -3212,41 +3212,28 @@ static void ShowDemoWindowMultiSelect()
|
|||||||
ImGui::BulletText("Shift+Keyboard to copy current value to other boxes.");
|
ImGui::BulletText("Shift+Keyboard to copy current value to other boxes.");
|
||||||
|
|
||||||
// If you have an array of checkboxes, you may want to use NoAutoSelect + NoAutoClear and the ImGuiSelectionExternalStorage helper.
|
// If you have an array of checkboxes, you may want to use NoAutoSelect + NoAutoClear and the ImGuiSelectionExternalStorage helper.
|
||||||
static bool values[20] = {};
|
static bool items[20] = {};
|
||||||
static ImGuiMultiSelectFlags flags = ImGuiMultiSelectFlags_NoAutoSelect | ImGuiMultiSelectFlags_NoAutoClear | ImGuiMultiSelectFlags_ClearOnEscape;
|
static ImGuiMultiSelectFlags flags = ImGuiMultiSelectFlags_NoAutoSelect | ImGuiMultiSelectFlags_NoAutoClear | ImGuiMultiSelectFlags_ClearOnEscape;
|
||||||
ImGui::CheckboxFlags("ImGuiMultiSelectFlags_NoAutoSelect", &flags, ImGuiMultiSelectFlags_NoAutoSelect);
|
ImGui::CheckboxFlags("ImGuiMultiSelectFlags_NoAutoSelect", &flags, ImGuiMultiSelectFlags_NoAutoSelect);
|
||||||
ImGui::CheckboxFlags("ImGuiMultiSelectFlags_NoAutoClear", &flags, ImGuiMultiSelectFlags_NoAutoClear);
|
ImGui::CheckboxFlags("ImGuiMultiSelectFlags_NoAutoClear", &flags, ImGuiMultiSelectFlags_NoAutoClear);
|
||||||
ImGui::CheckboxFlags("ImGuiMultiSelectFlags_BoxSelect", &flags, ImGuiMultiSelectFlags_BoxSelect); // Cannot use ImGuiMultiSelectFlags_BoxSelect1d as checkboxes are varying width.
|
ImGui::CheckboxFlags("ImGuiMultiSelectFlags_BoxSelect", &flags, ImGuiMultiSelectFlags_BoxSelect); // Cannot use ImGuiMultiSelectFlags_BoxSelect1d as checkboxes are varying width.
|
||||||
|
|
||||||
struct Funcs
|
|
||||||
{
|
|
||||||
static void ApplyMultiSelectRequestsToBoolArray(ImGuiMultiSelectIO* ms_io, bool items[], int items_count)
|
|
||||||
{
|
|
||||||
for (ImGuiSelectionRequest& req : ms_io->Requests)
|
|
||||||
{
|
|
||||||
if (req.Type == ImGuiSelectionRequestType_SetAll)
|
|
||||||
for (int n = 0; n < items_count; n++)
|
|
||||||
items[n] = req.Selected;
|
|
||||||
else if (req.Type == ImGuiSelectionRequestType_SetRange)
|
|
||||||
for (int n = (int)req.RangeFirstItem; n <= (int)req.RangeLastItem; n++)
|
|
||||||
items[n] = req.Selected;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
if (ImGui::BeginChild("##Basket", ImVec2(-FLT_MIN, ImGui::GetFontSize() * 20), ImGuiChildFlags_Border | ImGuiChildFlags_ResizeY))
|
if (ImGui::BeginChild("##Basket", ImVec2(-FLT_MIN, ImGui::GetFontSize() * 20), ImGuiChildFlags_Border | ImGuiChildFlags_ResizeY))
|
||||||
{
|
{
|
||||||
ImGuiMultiSelectIO* ms_io = ImGui::BeginMultiSelect(flags);
|
ImGuiMultiSelectIO* ms_io = ImGui::BeginMultiSelect(flags, -1, IM_ARRAYSIZE(items));
|
||||||
Funcs::ApplyMultiSelectRequestsToBoolArray(ms_io, values, IM_ARRAYSIZE(values)); //// By specs, it could be optional to apply requests from BeginMultiSelect() if not using a clipper.
|
ImGuiSelectionExternalStorage storage_wrapper;
|
||||||
|
storage_wrapper.UserData = (void*)items;
|
||||||
|
storage_wrapper.AdapterSetItemSelected = [](ImGuiSelectionExternalStorage* self, int n, bool selected) { bool* array = (bool*)self->UserData; array[n] = selected; };
|
||||||
|
storage_wrapper.ApplyRequests(ms_io);
|
||||||
for (int n = 0; n < 20; n++)
|
for (int n = 0; n < 20; n++)
|
||||||
{
|
{
|
||||||
char label[32];
|
char label[32];
|
||||||
sprintf(label, "Item %d", n);
|
sprintf(label, "Item %d", n);
|
||||||
ImGui::SetNextItemSelectionUserData(n);
|
ImGui::SetNextItemSelectionUserData(n);
|
||||||
ImGui::Checkbox(label, &values[n]);
|
ImGui::Checkbox(label, &items[n]);
|
||||||
}
|
}
|
||||||
ms_io = ImGui::EndMultiSelect();
|
ms_io = ImGui::EndMultiSelect();
|
||||||
Funcs::ApplyMultiSelectRequestsToBoolArray(ms_io, values, IM_ARRAYSIZE(values));
|
storage_wrapper.ApplyRequests(ms_io);
|
||||||
}
|
}
|
||||||
ImGui::EndChild();
|
ImGui::EndChild();
|
||||||
|
|
||||||
|
@ -7854,6 +7854,22 @@ void ImGuiSelectionBasicStorage::ApplyRequests(ImGuiMultiSelectIO* ms_io)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
void ImGuiSelectionExternalStorage::ApplyRequests(ImGuiMultiSelectIO* ms_io)
|
||||||
|
{
|
||||||
|
IM_ASSERT(AdapterSetItemSelected);
|
||||||
|
for (ImGuiSelectionRequest& req : ms_io->Requests)
|
||||||
|
{
|
||||||
|
if (req.Type == ImGuiSelectionRequestType_SetAll)
|
||||||
|
for (int idx = 0; idx < ms_io->ItemsCount; idx++)
|
||||||
|
AdapterSetItemSelected(this, idx, req.Selected);
|
||||||
|
if (req.Type == ImGuiSelectionRequestType_SetRange)
|
||||||
|
for (int idx = (int)req.RangeFirstItem; idx <= (int)req.RangeLastItem; idx++)
|
||||||
|
AdapterSetItemSelected(this, idx, req.Selected);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
// [SECTION] Widgets: ListBox
|
// [SECTION] Widgets: ListBox
|
||||||
|
Loading…
Reference in New Issue
Block a user