From cc4c37dbac16897383cd1c5ae41a632ba833470a Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 11 Jul 2023 16:46:35 +0200 Subject: [PATCH] Nav: PageUp/PageDown always set NavJustMovedTo even when landing on same spot (which can trigger a selection). This is mostly expected for range-select. + Rename ImGuiNavMoveFlags_Tabbing -> ImGuiNavMoveFlags_IsTabbing --- imgui.cpp | 32 +++++++++++++++++--------------- imgui_internal.h | 9 +++++---- 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 066c5c7a4..9858255c2 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2918,7 +2918,7 @@ static bool ImGuiListClipper_StepInternal(ImGuiListClipper* clipper) const bool is_nav_request = (g.NavMoveScoringItems && g.NavWindow && g.NavWindow->RootWindowForNav == window->RootWindowForNav); if (is_nav_request) data->Ranges.push_back(ImGuiListClipperRange::FromPositions(g.NavScoringNoClipRect.Min.y, g.NavScoringNoClipRect.Max.y, 0, 0)); - if (is_nav_request && (g.NavMoveFlags & ImGuiNavMoveFlags_Tabbing) && g.NavTabbingDir == -1) + if (is_nav_request && (g.NavMoveFlags & ImGuiNavMoveFlags_IsTabbing) && g.NavTabbingDir == -1) data->Ranges.push_back(ImGuiListClipperRange::FromIndices(clipper->ItemsCount - 1, clipper->ItemsCount)); // Add focused/active item @@ -7665,7 +7665,7 @@ void ImGui::FocusItem() return; } - ImGuiNavMoveFlags move_flags = ImGuiNavMoveFlags_Tabbing | ImGuiNavMoveFlags_FocusApi | ImGuiNavMoveFlags_NoSelect; + ImGuiNavMoveFlags move_flags = ImGuiNavMoveFlags_IsTabbing | ImGuiNavMoveFlags_FocusApi | ImGuiNavMoveFlags_NoSelect; ImGuiScrollFlags scroll_flags = window->Appearing ? ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_AlwaysCenterY : ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_KeepVisibleEdgeY; SetNavWindow(window); NavMoveRequestSubmit(ImGuiDir_None, ImGuiDir_Up, move_flags, scroll_flags); @@ -7700,7 +7700,7 @@ void ImGui::SetKeyboardFocusHere(int offset) SetNavWindow(window); - ImGuiNavMoveFlags move_flags = ImGuiNavMoveFlags_Tabbing | ImGuiNavMoveFlags_Activate | ImGuiNavMoveFlags_FocusApi; + ImGuiNavMoveFlags move_flags = ImGuiNavMoveFlags_IsTabbing | ImGuiNavMoveFlags_Activate | ImGuiNavMoveFlags_FocusApi; ImGuiScrollFlags scroll_flags = window->Appearing ? ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_AlwaysCenterY : ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_KeepVisibleEdgeY; NavMoveRequestSubmit(ImGuiDir_None, offset < 0 ? ImGuiDir_Up : ImGuiDir_Down, move_flags, scroll_flags); // FIXME-NAV: Once we refactor tabbing, add LegacyApi flag to not activate non-inputable. if (offset == -1) @@ -11070,7 +11070,7 @@ static void ImGui::NavProcessItem() // FIXME-NAV: Consider policy for double scoring (scoring from NavScoringRect + scoring from a rect wrapped according to current wrapping policy) if (g.NavMoveScoringItems && (item_flags & ImGuiItemFlags_Disabled) == 0) { - const bool is_tabbing = (g.NavMoveFlags & ImGuiNavMoveFlags_Tabbing) != 0; + const bool is_tabbing = (g.NavMoveFlags & ImGuiNavMoveFlags_IsTabbing) != 0; if (is_tabbing) { NavProcessItemForTabbingRequest(id, item_flags, g.NavMoveFlags); @@ -11176,7 +11176,7 @@ void ImGui::NavMoveRequestSubmit(ImGuiDir move_dir, ImGuiDir clip_dir, ImGuiNavM ImGuiContext& g = *GImGui; IM_ASSERT(g.NavWindow != NULL); - if (move_flags & ImGuiNavMoveFlags_Tabbing) + if (move_flags & ImGuiNavMoveFlags_IsTabbing) move_flags |= ImGuiNavMoveFlags_AllowCurrentNavId; g.NavMoveSubmitted = g.NavMoveScoringItems = true; @@ -11724,7 +11724,7 @@ void ImGui::NavUpdateCreateTabbingRequest() g.NavTabbingDir = g.IO.KeyShift ? -1 : (g.NavDisableHighlight == true && g.ActiveId == 0) ? 0 : +1; else g.NavTabbingDir = g.IO.KeyShift ? -1 : (g.ActiveId == 0) ? 0 : +1; - ImGuiNavMoveFlags move_flags = ImGuiNavMoveFlags_Tabbing | ImGuiNavMoveFlags_Activate; + ImGuiNavMoveFlags move_flags = ImGuiNavMoveFlags_IsTabbing | ImGuiNavMoveFlags_Activate; ImGuiScrollFlags scroll_flags = window->Appearing ? ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_AlwaysCenterY : ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_KeepVisibleEdgeY; ImGuiDir clip_dir = (g.NavTabbingDir < 0) ? ImGuiDir_Up : ImGuiDir_Down; NavMoveRequestSubmit(ImGuiDir_None, clip_dir, move_flags, scroll_flags); // FIXME-NAV: Once we refactor tabbing, add LegacyApi flag to not activate non-inputable. @@ -11744,7 +11744,7 @@ void ImGui::NavMoveRequestApplyResult() ImGuiNavItemData* result = (g.NavMoveResultLocal.ID != 0) ? &g.NavMoveResultLocal : (g.NavMoveResultOther.ID != 0) ? &g.NavMoveResultOther : NULL; // Tabbing forward wrap - if ((g.NavMoveFlags & ImGuiNavMoveFlags_Tabbing) && result == NULL) + if ((g.NavMoveFlags & ImGuiNavMoveFlags_IsTabbing) && result == NULL) if ((g.NavTabbingCounter == 1 || g.NavTabbingDir == 0) && g.NavTabbingResultFirst.ID) result = &g.NavTabbingResultFirst; @@ -11752,7 +11752,7 @@ void ImGui::NavMoveRequestApplyResult() const ImGuiAxis axis = (g.NavMoveDir == ImGuiDir_Up || g.NavMoveDir == ImGuiDir_Down) ? ImGuiAxis_Y : ImGuiAxis_X; if (result == NULL) { - if (g.NavMoveFlags & ImGuiNavMoveFlags_Tabbing) + if (g.NavMoveFlags & ImGuiNavMoveFlags_IsTabbing) g.NavMoveFlags |= ImGuiNavMoveFlags_NoSetNavHighlight; if (g.NavId != 0 && (g.NavMoveFlags & ImGuiNavMoveFlags_NoSetNavHighlight) == 0) NavRestoreHighlightAfterMove(); @@ -11793,9 +11793,11 @@ void ImGui::NavMoveRequestApplyResult() } if (g.ActiveId != result->ID) ClearActiveID(); - if (g.NavId != result->ID && (g.NavMoveFlags & ImGuiNavMoveFlags_NoSelect) == 0) + + // Don't set NavJustMovedToId if just landed on the same spot (which may happen with ImGuiNavMoveFlags_AllowCurrentNavId) + // 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) { - // Don't set NavJustMovedToId if just landed on the same spot (which may happen with ImGuiNavMoveFlags_AllowCurrentNavId) g.NavJustMovedToId = result->ID; g.NavJustMovedToFocusScopeId = result->FocusScopeId; g.NavJustMovedToKeyMods = g.NavMoveKeyMods; @@ -11808,14 +11810,14 @@ void ImGui::NavMoveRequestApplyResult() // Restore last preferred position for current axis // (storing in RootWindowForNav-> as the info is desirable at the beginning of a Move Request. In theory all storage should use RootWindowForNav..) - if ((g.NavMoveFlags & ImGuiNavMoveFlags_Tabbing) == 0) + if ((g.NavMoveFlags & ImGuiNavMoveFlags_IsTabbing) == 0) { preferred_scoring_pos_rel[axis] = result->RectRel.GetCenter()[axis]; g.NavWindow->RootWindowForNav->NavPreferredScoringPosRel[g.NavLayer] = preferred_scoring_pos_rel; } // Tabbing: Activates Inputable, otherwise only Focus - if ((g.NavMoveFlags & ImGuiNavMoveFlags_Tabbing) && (result->InFlags & ImGuiItemFlags_Inputable) == 0) + if ((g.NavMoveFlags & ImGuiNavMoveFlags_IsTabbing) && (result->InFlags & ImGuiItemFlags_Inputable) == 0) g.NavMoveFlags &= ~ImGuiNavMoveFlags_Activate; // Activate @@ -11824,7 +11826,7 @@ void ImGui::NavMoveRequestApplyResult() g.NavNextActivateId = result->ID; g.NavNextActivateFlags = ImGuiActivateFlags_None; g.NavMoveFlags |= ImGuiNavMoveFlags_NoSetNavHighlight; - if (g.NavMoveFlags & ImGuiNavMoveFlags_Tabbing) + if (g.NavMoveFlags & ImGuiNavMoveFlags_IsTabbing) g.NavNextActivateFlags |= ImGuiActivateFlags_PreferInput | ImGuiActivateFlags_TryToPreserveState; } @@ -11924,14 +11926,14 @@ static float ImGui::NavUpdatePageUpPageDown() nav_scoring_rect_offset_y = -page_offset_y; g.NavMoveDir = ImGuiDir_Down; // Because our scoring rect is offset up, we request the down direction (so we can always land on the last item) g.NavMoveClipDir = ImGuiDir_Up; - g.NavMoveFlags = ImGuiNavMoveFlags_AllowCurrentNavId | ImGuiNavMoveFlags_AlsoScoreVisibleSet; + g.NavMoveFlags = ImGuiNavMoveFlags_AllowCurrentNavId | ImGuiNavMoveFlags_AlsoScoreVisibleSet | ImGuiNavMoveFlags_IsPageMove; } else if (IsKeyPressed(ImGuiKey_PageDown, true)) { nav_scoring_rect_offset_y = +page_offset_y; g.NavMoveDir = ImGuiDir_Up; // Because our scoring rect is offset down, we request the up direction (so we can always land on the last item) g.NavMoveClipDir = ImGuiDir_Down; - g.NavMoveFlags = ImGuiNavMoveFlags_AllowCurrentNavId | ImGuiNavMoveFlags_AlsoScoreVisibleSet; + g.NavMoveFlags = ImGuiNavMoveFlags_AllowCurrentNavId | ImGuiNavMoveFlags_AlsoScoreVisibleSet | ImGuiNavMoveFlags_IsPageMove; } else if (home_pressed) { diff --git a/imgui_internal.h b/imgui_internal.h index 0b4ec8dfb..71e6daf67 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1493,10 +1493,11 @@ enum ImGuiNavMoveFlags_ ImGuiNavMoveFlags_Forwarded = 1 << 7, ImGuiNavMoveFlags_DebugNoResult = 1 << 8, // Dummy scoring for debug purpose, don't apply result ImGuiNavMoveFlags_FocusApi = 1 << 9, // Requests from focus API can land/focus/activate items even if they are marked with _NoTabStop (see NavProcessItemForTabbingRequest() for details) - ImGuiNavMoveFlags_Tabbing = 1 << 10, // == Focus + Activate if item is Inputable + DontChangeNavHighlight - ImGuiNavMoveFlags_Activate = 1 << 11, // Activate/select target item. - ImGuiNavMoveFlags_NoSelect = 1 << 12, // Don't trigger selection by not setting g.NavJustMovedTo - ImGuiNavMoveFlags_NoSetNavHighlight = 1 << 13, // Do not alter the visible state of keyboard vs mouse nav highlight + ImGuiNavMoveFlags_IsTabbing = 1 << 10, // == Focus + Activate if item is Inputable + DontChangeNavHighlight + ImGuiNavMoveFlags_IsPageMove = 1 << 11, // Identify a PageDown/PageUp request. + ImGuiNavMoveFlags_Activate = 1 << 12, // Activate/select target item. + ImGuiNavMoveFlags_NoSelect = 1 << 13, // Don't trigger selection by not setting g.NavJustMovedTo + ImGuiNavMoveFlags_NoSetNavHighlight = 1 << 14, // Do not alter the visible state of keyboard vs mouse nav highlight }; enum ImGuiNavLayer