MultiSelect: using ImGuiMultiSelectFlags_NoRangeSelect ensure never having to interpolate between two ImGuiSelectionUserData.

This commit is contained in:
ocornut 2024-07-19 16:42:06 +02:00
parent 168ef39984
commit b6e313bc05
2 changed files with 7 additions and 4 deletions

View File

@ -2760,6 +2760,8 @@ struct ImColor
// SetRange requests will give you two end-points and you will need to iterate/interpolate between them to update your selection. // SetRange requests will give you two end-points and you will need to iterate/interpolate between them to update your selection.
// - However it is perfectly possible to store a POINTER or another IDENTIFIER inside ImGuiSelectionUserData. // - However it is perfectly possible to store a POINTER or another IDENTIFIER inside ImGuiSelectionUserData.
// Our system never assume that you identify items by indices, it never attempts to interpolate between two values. // Our system never assume that you identify items by indices, it never attempts to interpolate between two values.
// - If you enable ImGuiMultiSelectFlags_NoRangeSelect then it is guaranteed that you will never have to interpolate
// between two ImGuiSelectionUserData, which may be a convenient way to use part of the feature with less code work.
// - As most users will want to store an index, for convenience and to reduce confusion we use ImS64 instead of void*, // - As most users will want to store an index, for convenience and to reduce confusion we use ImS64 instead of void*,
// being syntactically easier to downcast. Feel free to reinterpret_cast and store a pointer inside. // being syntactically easier to downcast. Feel free to reinterpret_cast and store a pointer inside.
@ -2769,7 +2771,7 @@ enum ImGuiMultiSelectFlags_
ImGuiMultiSelectFlags_None = 0, ImGuiMultiSelectFlags_None = 0,
ImGuiMultiSelectFlags_SingleSelect = 1 << 0, // Disable selecting more than one item. This is available to allow single-selection code to share same code/logic if desired. It essentially disables the main purpose of BeginMultiSelect() tho! ImGuiMultiSelectFlags_SingleSelect = 1 << 0, // Disable selecting more than one item. This is available to allow single-selection code to share same code/logic if desired. It essentially disables the main purpose of BeginMultiSelect() tho!
ImGuiMultiSelectFlags_NoSelectAll = 1 << 1, // Disable CTRL+A shortcut to select all. ImGuiMultiSelectFlags_NoSelectAll = 1 << 1, // Disable CTRL+A shortcut to select all.
ImGuiMultiSelectFlags_NoRangeSelect = 1 << 2, // Disable Shift+selection mouse/keyboard support (useful for unordered 2D selection). ImGuiMultiSelectFlags_NoRangeSelect = 1 << 2, // Disable Shift+selection mouse/keyboard support (useful for unordered 2D selection). With BoxSelect is also ensure contiguous SetRange requests are not combined into one. This allows not handling interpolation in SetRange requests.
ImGuiMultiSelectFlags_NoAutoSelect = 1 << 3, // Disable selecting items when navigating (useful for e.g. supporting range-select in a list of checkboxes) ImGuiMultiSelectFlags_NoAutoSelect = 1 << 3, // Disable selecting items when navigating (useful for e.g. supporting range-select in a list of checkboxes)
ImGuiMultiSelectFlags_NoAutoClear = 1 << 4, // Disable clearing selection when navigating or selecting another one (generally used with ImGuiMultiSelectFlags_NoAutoSelect. useful for e.g. supporting range-select in a list of checkboxes) ImGuiMultiSelectFlags_NoAutoClear = 1 << 4, // Disable clearing selection when navigating or selecting another one (generally used with ImGuiMultiSelectFlags_NoAutoSelect. useful for e.g. supporting range-select in a list of checkboxes)
ImGuiMultiSelectFlags_NoAutoClearOnReselect = 1 << 5, // Disable clearing selection when clicking/selecting an already selected item ImGuiMultiSelectFlags_NoAutoClearOnReselect = 1 << 5, // Disable clearing selection when clicking/selecting an already selected item

View File

@ -7680,9 +7680,10 @@ void ImGui::MultiSelectItemFooter(ImGuiID id, bool* p_selected, bool* p_pressed)
{ {
selected = !selected; selected = !selected;
ImGuiSelectionRequest req = { ImGuiSelectionRequestType_SetRange, selected, +1, item_data, item_data }; ImGuiSelectionRequest req = { ImGuiSelectionRequestType_SetRange, selected, +1, item_data, item_data };
ImGuiSelectionRequest* prev_req = (ms->IO.Requests.Size > 0) ? &ms->IO.Requests.Data[ms->IO.Requests.Size - 1] : NULL; // Merge continuous ranges (unless NoRangeSelect is set)
if (prev_req && prev_req->Type == ImGuiSelectionRequestType_SetRange && prev_req->RangeLastItem == ms->BoxSelectLastitem && prev_req->Selected == selected) ImGuiSelectionRequest* prev = ms->IO.Requests.Size > 0 ? &ms->IO.Requests.Data[ms->IO.Requests.Size - 1] : NULL;
prev_req->RangeLastItem = item_data; // Merge span into same request if (prev && prev->Type == ImGuiSelectionRequestType_SetRange && prev->RangeLastItem == ms->BoxSelectLastitem && prev->Selected == selected && (ms->Flags & ImGuiMultiSelectFlags_NoRangeSelect) == 0)
prev->RangeLastItem = item_data; // Merge span into same request
else else
ms->IO.Requests.push_back(req); ms->IO.Requests.push_back(req);
} }