Return ImGuiMultiSelectIO structure. Lifetime: don't hold on ImGuiMultiSelectIO* pointers over multiple frames or past any subsequent call to BeginMultiSelect() or EndMultiSelect(). Passing 'selection_size' and 'items_count' parameters is currently optional. - 'selection_size' is useful to disable some shortcut routing: e.g. ImGuiMultiSelectFlags_ClearOnEscape won't claim Escape key when selection
| 7926 | // - If they are costly for you to compute (e.g. external intrusive selection without maintaining size), you may avoid them and pass -1. |
| 7927 | // - 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. |
| 7928 | ImGuiMultiSelectIO* ImGui::BeginMultiSelect(ImGuiMultiSelectFlags flags, int selection_size, int items_count) |
| 7929 | { |
| 7930 | ImGuiContext& g = *GImGui; |
| 7931 | ImGuiWindow* window = g.CurrentWindow; |
| 7932 | |
| 7933 | if (++g.MultiSelectTempDataStacked > g.MultiSelectTempData.Size) |
| 7934 | g.MultiSelectTempData.resize(g.MultiSelectTempDataStacked, ImGuiMultiSelectTempData()); |
| 7935 | ImGuiMultiSelectTempData* ms = &g.MultiSelectTempData[g.MultiSelectTempDataStacked - 1]; |
| 7936 | IM_STATIC_ASSERT(offsetof(ImGuiMultiSelectTempData, IO) == 0); // Clear() relies on that. |
| 7937 | g.CurrentMultiSelect = ms; |
| 7938 | if ((flags & (ImGuiMultiSelectFlags_ScopeWindow | ImGuiMultiSelectFlags_ScopeRect)) == 0) |
| 7939 | flags |= ImGuiMultiSelectFlags_ScopeWindow; |
| 7940 | if (flags & ImGuiMultiSelectFlags_SingleSelect) |
| 7941 | flags &= ~(ImGuiMultiSelectFlags_BoxSelect2d | ImGuiMultiSelectFlags_BoxSelect1d); |
| 7942 | if (flags & ImGuiMultiSelectFlags_BoxSelect2d) |
| 7943 | flags &= ~ImGuiMultiSelectFlags_BoxSelect1d; |
| 7944 | |
| 7945 | // FIXME: Workaround to the fact we override CursorMaxPos, meaning size measurement are lost. (#8250) |
| 7946 | // They should perhaps be stacked properly? |
| 7947 | if (ImGuiTable* table = g.CurrentTable) |
| 7948 | if (table->CurrentColumn != -1) |
| 7949 | TableEndCell(table); // This is currently safe to call multiple time. If that properly is lost we can extract the "save measurement" part of it. |
| 7950 | |
| 7951 | // FIXME: BeginFocusScope() |
| 7952 | const ImGuiID id = window->IDStack.back(); |
| 7953 | ms->Clear(); |
| 7954 | ms->FocusScopeId = id; |
| 7955 | ms->Flags = flags; |
| 7956 | ms->IsFocused = (ms->FocusScopeId == g.NavFocusScopeId); |
| 7957 | ms->BackupCursorMaxPos = window->DC.CursorMaxPos; |
| 7958 | ms->ScopeRectMin = window->DC.CursorMaxPos = window->DC.CursorPos; |
| 7959 | PushFocusScope(ms->FocusScopeId); |
| 7960 | if (flags & ImGuiMultiSelectFlags_ScopeWindow) // Mark parent child window as navigable into, with highlight. Assume user will always submit interactive items. |
| 7961 | window->DC.NavLayersActiveMask |= 1 << ImGuiNavLayer_Main; |
| 7962 | |
| 7963 | // Use copy of keyboard mods at the time of the request, otherwise we would requires mods to be held for an extra frame. |
| 7964 | ms->KeyMods = g.NavJustMovedToId ? (g.NavJustMovedToIsTabbing ? 0 : g.NavJustMovedToKeyMods) : g.IO.KeyMods; |
| 7965 | if (flags & ImGuiMultiSelectFlags_NoRangeSelect) |
| 7966 | ms->KeyMods &= ~ImGuiMod_Shift; |
| 7967 | |
| 7968 | // Bind storage |
| 7969 | ImGuiMultiSelectState* storage = g.MultiSelectStorage.GetOrAddByKey(id); |
| 7970 | storage->ID = id; |
| 7971 | storage->LastFrameActive = g.FrameCount; |
| 7972 | storage->LastSelectionSize = selection_size; |
| 7973 | storage->Window = window; |
| 7974 | ms->Storage = storage; |
| 7975 | |
| 7976 | // Output to user |
| 7977 | ms->IO.Requests.resize(0); |
| 7978 | ms->IO.RangeSrcItem = storage->RangeSrcItem; |
| 7979 | ms->IO.NavIdItem = storage->NavIdItem; |
| 7980 | ms->IO.NavIdSelected = (storage->NavIdSelected == 1) ? true : false; |
| 7981 | ms->IO.ItemsCount = items_count; |
| 7982 | |
| 7983 | // Clear when using Navigation to move within the scope |
| 7984 | // (we compare FocusScopeId so it possible to use multiple selections inside a same window) |
| 7985 | bool request_clear = false; |
nothing calls this directly
no test coverage detected