diff --git a/imgui.cpp b/imgui.cpp index 516cd044..f75354a4 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -12200,6 +12200,7 @@ static void ImGui::NavUpdate() // Process navigation init request (select first/default focus) g.NavJustMovedToId = 0; + g.NavJustMovedToFocusScopeId = g.NavJustMovedFromFocusScopeId = 0; if (g.NavInitResult.ID != 0) NavInitRequestApplyResult(); g.NavInitRequest = false; @@ -12352,6 +12353,7 @@ void ImGui::NavInitRequestApplyResult() ImGuiNavItemData* result = &g.NavInitResult; if (g.NavId != result->ID) { + g.NavJustMovedFromFocusScopeId = g.NavFocusScopeId; g.NavJustMovedToId = result->ID; g.NavJustMovedToFocusScopeId = result->FocusScopeId; g.NavJustMovedToKeyMods = 0; @@ -12609,10 +12611,12 @@ void ImGui::NavMoveRequestApplyResult() // PageUp/PageDown however sets always set NavJustMovedTo (vs Home/End which doesn't) mimicking Windows behavior. if ((g.NavId != result->ID || (g.NavMoveFlags & ImGuiNavMoveFlags_IsPageMove)) && (g.NavMoveFlags & ImGuiNavMoveFlags_NoSelect) == 0) { + g.NavJustMovedFromFocusScopeId = g.NavFocusScopeId; g.NavJustMovedToId = result->ID; g.NavJustMovedToFocusScopeId = result->FocusScopeId; g.NavJustMovedToKeyMods = g.NavMoveKeyMods; g.NavJustMovedToHasSelectionData = (result->InFlags & ImGuiItemFlags_HasSelectionUserData) != 0; + //IMGUI_DEBUG_LOG_NAV("[nav] NavJustMovedFromFocusScopeId = 0x%08X, NavJustMovedToFocusScopeId = 0x%08X\n", g.NavJustMovedFromFocusScopeId, g.NavJustMovedToFocusScopeId); } // Apply new NavID/Focus diff --git a/imgui_internal.h b/imgui_internal.h index 711c7ea4..e3d2aa09 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -2084,6 +2084,7 @@ struct ImGuiContext ImGuiID NavHighlightActivatedId; float NavHighlightActivatedTimer; ImGuiID NavJustMovedToId; // Just navigated to this id (result of a successfully MoveRequest). + ImGuiID NavJustMovedFromFocusScopeId; // Just navigated from this focus scope id (result of a successfully MoveRequest). ImGuiID NavJustMovedToFocusScopeId; // Just navigated to this focus scope id (result of a successfully MoveRequest). ImGuiKeyChord NavJustMovedToKeyMods; bool NavJustMovedToHasSelectionData; // " (FIXME-NAV: We should maybe just store ImGuiNavMoveResult) @@ -2360,7 +2361,7 @@ struct ImGuiContext NavWindow = NULL; NavId = NavFocusScopeId = NavActivateId = NavActivateDownId = NavActivatePressedId = 0; - NavJustMovedToId = NavJustMovedToFocusScopeId = NavNextActivateId = 0; + NavJustMovedToId = NavJustMovedToFocusScopeId = NavJustMovedFromFocusScopeId = NavNextActivateId = 0; NavActivateFlags = NavNextActivateFlags = ImGuiActivateFlags_None; NavHighlightActivatedId = 0; NavHighlightActivatedTimer = 0.0f; diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index a468e7a3..2bb07718 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -7048,10 +7048,7 @@ ImGuiMultiSelectIO* ImGui::BeginMultiSelect(ImGuiMultiSelectFlags flags) ms->BeginIO.NavIdItem = ms->EndIO.NavIdItem = storage->NavIdItem; ms->BeginIO.NavIdSelected = ms->EndIO.NavIdSelected = (storage->NavIdSelected == 1) ? true : false; - if (!ms->IsFocused) - return &ms->BeginIO; // This is cleared at this point. - - // Auto clear when using Navigation to move within the selection + // Clear when using Navigation to move within the scope // (we compare FocusScopeId so it possible to use multiple selections inside a same window) if (g.NavJustMovedToId != 0 && g.NavJustMovedToFocusScopeId == ms->FocusScopeId && g.NavJustMovedToHasSelectionData) { @@ -7062,18 +7059,27 @@ ImGuiMultiSelectIO* ImGui::BeginMultiSelect(ImGuiMultiSelectFlags flags) if ((ms->KeyMods & (ImGuiMod_Ctrl | ImGuiMod_Shift)) == 0) ms->BeginIO.RequestClear = true; } + else if (g.NavJustMovedFromFocusScopeId == ms->FocusScopeId) + { + // Also clear on leaving scope (may be optional?) + if ((ms->KeyMods & (ImGuiMod_Ctrl | ImGuiMod_Shift)) == 0) + ms->BeginIO.RequestClear = true; + } - // Shortcut: Select all (CTRL+A) - if (!(flags & ImGuiMultiSelectFlags_SingleSelect) && !(flags & ImGuiMultiSelectFlags_NoSelectAll)) - if (Shortcut(ImGuiMod_Ctrl | ImGuiKey_A)) - ms->BeginIO.RequestSelectAll = true; + if (ms->IsFocused) + { + // Shortcut: Select all (CTRL+A) + if (!(flags & ImGuiMultiSelectFlags_SingleSelect) && !(flags & ImGuiMultiSelectFlags_NoSelectAll)) + if (Shortcut(ImGuiMod_Ctrl | ImGuiKey_A)) + ms->BeginIO.RequestSelectAll = true; - // Shortcut: Clear selection (Escape) - // FIXME-MULTISELECT: Only hog shortcut if selection is not null, meaning we need "has selection or "selection size" data here. - // Otherwise may be done by caller but it means Shortcut() needs to be exposed. - if (flags & ImGuiMultiSelectFlags_ClearOnEscape) - if (Shortcut(ImGuiKey_Escape)) - ms->BeginIO.RequestClear = true; + // Shortcut: Clear selection (Escape) + // FIXME-MULTISELECT: Only hog shortcut if selection is not null, meaning we need "has selection or "selection size" data here. + // Otherwise may be done by caller but it means Shortcut() needs to be exposed. + if (flags & ImGuiMultiSelectFlags_ClearOnEscape) + if (Shortcut(ImGuiKey_Escape)) + ms->BeginIO.RequestClear = true; + } if (g.DebugLogFlags & ImGuiDebugLogFlags_EventSelection) DebugLogMultiSelectRequests("BeginMultiSelect", &ms->BeginIO);