diff --git a/imgui_internal.h b/imgui_internal.h index 8d84aa1a..4b8b1ea4 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1721,6 +1721,7 @@ struct ImGuiContext bool MultiSelectEnabled; ImGuiMultiSelectFlags MultiSelectFlags; ImGuiMultiSelectState MultiSelectState; // We currently don't support recursing/stacking multi-select + ImGuiKeyModFlags MultiSelectKeyMods; // Render float DimBgRatio; // 0.0..1.0 animation when fading in a dimming background (for modal window and CTRL+TAB list) @@ -1920,6 +1921,7 @@ struct ImGuiContext MultiSelectEnabled = false; MultiSelectFlags = ImGuiMultiSelectFlags_None; + MultiSelectKeyMods = ImGuiKeyModFlags_None; DimBgRatio = 0.0f; MouseCursor = ImGuiMouseCursor_Arrow; diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 18d4bf8a..65d778d4 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -6387,6 +6387,9 @@ ImGuiMultiSelectData* ImGui::BeginMultiSelect(ImGuiMultiSelectFlags flags, void* g.MultiSelectEnabled = true; g.MultiSelectFlags = flags; + // Use copy of keyboard mods at the time of the request, otherwise we would requires mods to be held for an extra frame. + g.MultiSelectKeyMods = g.NavJustMovedToId ? g.NavJustMovedToKeyMods : g.IO.KeyMods; + if ((flags & ImGuiMultiSelectFlags_NoMultiSelect) == 0) { state->In.RangeSrc = state->Out.RangeSrc = range_ref; @@ -6397,9 +6400,9 @@ ImGuiMultiSelectData* ImGui::BeginMultiSelect(ImGuiMultiSelectFlags flags, void* // FIXME: Polling key mods after the fact (frame following the move request) is incorrect, but latching it would requires non-trivial change in MultiSelectItemFooter() if (g.NavJustMovedToId != 0 && g.NavJustMovedToFocusScopeId == state->FocusScopeId && g.NavJustMovedToHasSelectionData) { - if (g.IO.KeyShift) + if (g.MultiSelectKeyMods & ImGuiKeyModFlags_Shift) state->InRequestSetRangeNav = true; - if (!g.IO.KeyCtrl && !g.IO.KeyShift) + if ((g.MultiSelectKeyMods & (ImGuiKeyModFlags_Ctrl | ImGuiKeyModFlags_Shift)) == 0) state->In.RequestClear = true; } @@ -6484,13 +6487,13 @@ void ImGui::MultiSelectItemHeader(ImGuiID id, bool* p_selected) if (state->InRequestSetRangeNav) { IM_ASSERT(id != 0); - IM_ASSERT(g.IO.KeyShift); + IM_ASSERT((g.MultiSelectKeyMods & ImGuiKeyModFlags_Shift) != 0); const bool is_range_dst = !state->InRangeDstPassedBy && g.NavJustMovedToId == id; // Assume that g.NavJustMovedToId is not clipped. if (is_range_dst) state->InRangeDstPassedBy = true; if (is_range_src || is_range_dst || state->In.RangeSrcPassedBy != state->InRangeDstPassedBy) selected = state->In.RangeValue; - else if (!g.IO.KeyCtrl) + else if ((g.MultiSelectKeyMods & ImGuiKeyModFlags_Ctrl) == 0) selected = false; } @@ -6508,9 +6511,9 @@ void ImGui::MultiSelectItemFooter(ImGuiID id, bool* p_selected, bool* p_pressed) bool selected = *p_selected; bool pressed = *p_pressed; - bool is_ctrl = g.IO.KeyCtrl; - bool is_shift = g.IO.KeyShift; const bool is_multiselect = (g.MultiSelectFlags & ImGuiMultiSelectFlags_NoMultiSelect) == 0; + bool is_ctrl = (g.MultiSelectKeyMods & ImGuiKeyModFlags_Ctrl) != 0; + bool is_shift = (g.MultiSelectKeyMods & ImGuiKeyModFlags_Shift) != 0; // Auto-select as you navigate a list if (g.NavJustMovedToId == id)