mirror of https://github.com/ocornut/imgui
MultiSelect: ImGuiSelectionBasicStorage: (breaking) rework GetNextSelectedItem() api to avoid ambiguity/failure when user uses a zero id.
This commit is contained in:
parent
f472f17054
commit
3ac367ff41
6
imgui.h
6
imgui.h
|
@ -2817,7 +2817,7 @@ struct ImGuiSelectionRequest
|
||||||
|
|
||||||
// Optional helper to store multi-selection state + apply multi-selection requests.
|
// Optional helper to store multi-selection state + apply multi-selection requests.
|
||||||
// - Used by our demos and provided as a convenience to easily implement basic multi-selection.
|
// - Used by our demos and provided as a convenience to easily implement basic multi-selection.
|
||||||
// - Iterate selection with 'void* it = NULL; while (ImGuiId id = selection.GetNextSelectedItem(&it)) { ... }'
|
// - Iterate selection with 'void* it = NULL; ImGuiID id; while (selection.GetNextSelectedItem(&it, &id)) { ... }'
|
||||||
// Or you can check 'if (Contains(id)) { ... }' for each possible object if their number is not too high to iterate.
|
// Or you can check 'if (Contains(id)) { ... }' for each possible object if their number is not too high to iterate.
|
||||||
// - USING THIS IS NOT MANDATORY. This is only a helper and not a required API.
|
// - USING THIS IS NOT MANDATORY. This is only a helper and not a required API.
|
||||||
// To store a multi-selection, in your application you could:
|
// To store a multi-selection, in your application you could:
|
||||||
|
@ -2834,10 +2834,10 @@ struct ImGuiSelectionRequest
|
||||||
struct ImGuiSelectionBasicStorage
|
struct ImGuiSelectionBasicStorage
|
||||||
{
|
{
|
||||||
// Members
|
// Members
|
||||||
ImGuiStorage _Storage; // [Internal] Selection set. Think of this as similar to e.g. std::set<ImGuiID>. Prefer not accessing directly: iterate with GetNextSelectedItem().
|
|
||||||
int Size; // Number of selected items (== number of 1 in the Storage), maintained by this helper.
|
int Size; // Number of selected items (== number of 1 in the Storage), maintained by this helper.
|
||||||
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;
|
||||||
ImGuiID (*AdapterIndexToStorageId)(ImGuiSelectionBasicStorage* self, int idx); // e.g. selection.AdapterIndexToStorageId = [](ImGuiSelectionBasicStorage* self, int idx) { return ((MyItems**)self->UserData)[idx]->ID; };
|
ImGuiID (*AdapterIndexToStorageId)(ImGuiSelectionBasicStorage* self, int idx); // e.g. selection.AdapterIndexToStorageId = [](ImGuiSelectionBasicStorage* self, int idx) { return ((MyItems**)self->UserData)[idx]->ID; };
|
||||||
|
ImGuiStorage _Storage; // [Internal] Selection set. Think of this as similar to e.g. std::set<ImGuiID>. Prefer not accessing directly: iterate with GetNextSelectedItem().
|
||||||
|
|
||||||
// Methods
|
// Methods
|
||||||
ImGuiSelectionBasicStorage();
|
ImGuiSelectionBasicStorage();
|
||||||
|
@ -2846,7 +2846,7 @@ struct ImGuiSelectionBasicStorage
|
||||||
IMGUI_API void Clear(); // Clear selection
|
IMGUI_API void Clear(); // Clear selection
|
||||||
IMGUI_API void Swap(ImGuiSelectionBasicStorage& r); // Swap two selections
|
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 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)) { ... }'
|
IMGUI_API bool GetNextSelectedItem(void** opaque_it, ImGuiID* out_id); // Iterate selection with 'void* it = NULL; ImGuiId id; while (selection.GetNextSelectedItem(&it, &id)) { ... }'
|
||||||
inline ImGuiID GetStorageIdFromIndex(int idx) { return AdapterIndexToStorageId(this, idx); } // Convert index to item id based on provided adapter.
|
inline ImGuiID GetStorageIdFromIndex(int idx) { return AdapterIndexToStorageId(this, idx); } // Convert index to item id based on provided adapter.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -3447,11 +3447,12 @@ static void ShowDemoWindowMultiSelect()
|
||||||
{
|
{
|
||||||
ImVector<int> payload_items;
|
ImVector<int> payload_items;
|
||||||
void* it = NULL;
|
void* it = NULL;
|
||||||
|
ImGuiID id = 0;
|
||||||
if (!item_is_selected)
|
if (!item_is_selected)
|
||||||
payload_items.push_back(item_id);
|
payload_items.push_back(item_id);
|
||||||
else
|
else
|
||||||
while (int id = (int)selection.GetNextSelectedItem(&it))
|
while (selection.GetNextSelectedItem(&it, &id))
|
||||||
payload_items.push_back(id);
|
payload_items.push_back((int)id);
|
||||||
ImGui::SetDragDropPayload("MULTISELECT_DEMO_ITEMS", payload_items.Data, (size_t)payload_items.size_in_bytes());
|
ImGui::SetDragDropPayload("MULTISELECT_DEMO_ITEMS", payload_items.Data, (size_t)payload_items.size_in_bytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9907,10 +9908,11 @@ struct ExampleAssetsBrowser
|
||||||
{
|
{
|
||||||
ImVector<ImGuiID> payload_items;
|
ImVector<ImGuiID> payload_items;
|
||||||
void* it = NULL;
|
void* it = NULL;
|
||||||
|
ImGuiID id = 0;
|
||||||
if (!item_is_selected)
|
if (!item_is_selected)
|
||||||
payload_items.push_back(item_data->ID);
|
payload_items.push_back(item_data->ID);
|
||||||
else
|
else
|
||||||
while (ImGuiID id = Selection.GetNextSelectedItem(&it))
|
while (Selection.GetNextSelectedItem(&it, &id))
|
||||||
payload_items.push_back(id);
|
payload_items.push_back(id);
|
||||||
ImGui::SetDragDropPayload("ASSETS_BROWSER_ITEMS", payload_items.Data, (size_t)payload_items.size_in_bytes());
|
ImGui::SetDragDropPayload("ASSETS_BROWSER_ITEMS", payload_items.Data, (size_t)payload_items.size_in_bytes());
|
||||||
}
|
}
|
||||||
|
|
|
@ -7847,7 +7847,7 @@ bool ImGuiSelectionBasicStorage::Contains(ImGuiID id) const
|
||||||
|
|
||||||
// GetNextSelectedItem() is an abstraction allowing us to change our underlying actual storage system without impacting user.
|
// 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<ImGuiID> instead of ImGuiStorage...)
|
// (e.g. store unselected vs compact down, compact down on demand, use raw ImVector<ImGuiID> instead of ImGuiStorage...)
|
||||||
ImGuiID ImGuiSelectionBasicStorage::GetNextSelectedItem(void** opaque_it)
|
bool ImGuiSelectionBasicStorage::GetNextSelectedItem(void** opaque_it, ImGuiID* out_id)
|
||||||
{
|
{
|
||||||
ImGuiStoragePair* it = (ImGuiStoragePair*)*opaque_it;
|
ImGuiStoragePair* it = (ImGuiStoragePair*)*opaque_it;
|
||||||
ImGuiStoragePair* it_end = _Storage.Data.Data + _Storage.Data.Size;
|
ImGuiStoragePair* it_end = _Storage.Data.Data + _Storage.Data.Size;
|
||||||
|
@ -7859,7 +7859,8 @@ ImGuiID ImGuiSelectionBasicStorage::GetNextSelectedItem(void** opaque_it)
|
||||||
it++;
|
it++;
|
||||||
const bool has_more = (it != it_end);
|
const bool has_more = (it != it_end);
|
||||||
*opaque_it = has_more ? (void**)(it + 1) : (void**)(it);
|
*opaque_it = has_more ? (void**)(it + 1) : (void**)(it);
|
||||||
return has_more ? it->key : 0;
|
*out_id = has_more ? it->key : 0;
|
||||||
|
return has_more;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImGuiSelectionBasicStorage::SetItemSelected(ImGuiID id, bool selected)
|
void ImGuiSelectionBasicStorage::SetItemSelected(ImGuiID id, bool selected)
|
||||||
|
|
Loading…
Reference in New Issue