RangeSelect/MultiSelect: clear selection when leaving a scope with a nav directional request.

May need to clarify how to depends on actions being performed (e.g. click doesn't).
May become optional?
features/range_select
ocornut ago%!(EXTRA string=2 years)
parent 17b1bf2c5c
commit 4db4912d35
  1. 4
      imgui.cpp
  2. 3
      imgui_internal.h
  3. 34
      imgui_widgets.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

@ -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;

@ -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);

Loading…
Cancel
Save