Apply requests coming from BeginMultiSelect() and EndMultiSelect(). - Enable 'Demo->Tools->Debug Log->Selection' to see selection requests as they happen. - Honoring SetRange requests requires that you can iterate/interpolate between RangeFirstItem and RangeLastItem. - In this demo we often submit indices to SetNextItemSelectionUserData() + store the same indices in persistent selection. - Your co
| 8684 | // if (req.Type == ImGuiSelectionRequestType_SetRange) { for (int n = (int)ms_io->RangeFirstItem; n <= (int)ms_io->RangeLastItem; n++) { SetItemSelected(n, ms_io->Selected); } } |
| 8685 | // } |
| 8686 | void ImGuiSelectionBasicStorage::ApplyRequests(ImGuiMultiSelectIO* ms_io) |
| 8687 | { |
| 8688 | // For convenience we obtain ItemsCount as passed to BeginMultiSelect(), which is optional. |
| 8689 | // It makes sense when using ImGuiSelectionBasicStorage to simply pass your items count to BeginMultiSelect(). |
| 8690 | // Other scheme may handle SetAll differently. |
| 8691 | IM_ASSERT(ms_io->ItemsCount != -1 && "Missing value for items_count in BeginMultiSelect() call!"); |
| 8692 | IM_ASSERT(AdapterIndexToStorageId != NULL); |
| 8693 | |
| 8694 | // This is optimized/specialized to cope with very large selections (e.g. 100k+ items) |
| 8695 | // - A simpler version could call SetItemSelected() directly instead of ImGuiSelectionBasicStorage_BatchSetItemSelected() + ImGuiSelectionBasicStorage_BatchFinish(). |
| 8696 | // - Optimized select can append unsorted, then sort in a second pass. Optimized unselect can clear in-place then compact in a second pass. |
| 8697 | // - A more optimal version wouldn't even use ImGuiStorage but directly a ImVector<ImGuiID> to reduce bandwidth, but this is a reasonable trade off to reuse code. |
| 8698 | // - There are many ways this could be better optimized. The worse case scenario being: using BoxSelect2d in a grid, box-select scrolling down while wiggling |
| 8699 | // left and right: it affects coarse clipping + can emit multiple SetRange with 1 item each. |
| 8700 | // FIXME-OPT: For each block of consecutive SetRange request: |
| 8701 | // - add all requests to a sorted list, store ID, selected, offset in ImGuiStorage. |
| 8702 | // - rewrite sorted storage a single time. |
| 8703 | for (ImGuiSelectionRequest& req : ms_io->Requests) |
| 8704 | { |
| 8705 | if (req.Type == ImGuiSelectionRequestType_SetAll) |
| 8706 | { |
| 8707 | Clear(); |
| 8708 | if (req.Selected) |
| 8709 | { |
| 8710 | _Storage.Data.reserve(ms_io->ItemsCount); |
| 8711 | const int size_before_amends = _Storage.Data.Size; |
| 8712 | for (int idx = 0; idx < ms_io->ItemsCount; idx++, _SelectionOrder++) |
| 8713 | ImGuiSelectionBasicStorage_BatchSetItemSelected(this, GetStorageIdFromIndex(idx), req.Selected, size_before_amends, _SelectionOrder); |
| 8714 | ImGuiSelectionBasicStorage_BatchFinish(this, req.Selected, size_before_amends); |
| 8715 | } |
| 8716 | } |
| 8717 | else if (req.Type == ImGuiSelectionRequestType_SetRange) |
| 8718 | { |
| 8719 | const int selection_changes = (int)req.RangeLastItem - (int)req.RangeFirstItem + 1; |
| 8720 | //ImGuiContext& g = *GImGui; IMGUI_DEBUG_LOG_SELECTION("Req %d/%d: set %d to %d\n", ms_io->Requests.index_from_ptr(&req), ms_io->Requests.Size, selection_changes, req.Selected); |
| 8721 | if (selection_changes == 1 || (selection_changes < Size / 100)) |
| 8722 | { |
| 8723 | // Multiple sorted insertion + copy likely to be faster. |
| 8724 | // Technically we could do a single copy with a little more work (sort sequential SetRange requests) |
| 8725 | for (int idx = (int)req.RangeFirstItem; idx <= (int)req.RangeLastItem; idx++) |
| 8726 | SetItemSelected(GetStorageIdFromIndex(idx), req.Selected); |
| 8727 | } |
| 8728 | else |
| 8729 | { |
| 8730 | // Append insertion + single sort likely be faster. |
| 8731 | // Use req.RangeDirection to set order field so that Shift+Clicking from 1 to 5 is different than Shift+Clicking from 5 to 1 |
| 8732 | const int size_before_amends = _Storage.Data.Size; |
| 8733 | int selection_order = _SelectionOrder + ((req.RangeDirection < 0) ? selection_changes - 1 : 0); |
| 8734 | for (int idx = (int)req.RangeFirstItem; idx <= (int)req.RangeLastItem; idx++, selection_order += req.RangeDirection) |
| 8735 | ImGuiSelectionBasicStorage_BatchSetItemSelected(this, GetStorageIdFromIndex(idx), req.Selected, size_before_amends, selection_order); |
| 8736 | if (req.Selected) |
| 8737 | _SelectionOrder += selection_changes; |
| 8738 | ImGuiSelectionBasicStorage_BatchFinish(this, req.Selected, size_before_amends); |
| 8739 | } |
| 8740 | } |
| 8741 | } |
| 8742 | } |
| 8743 |
no test coverage detected