diff --git a/imgui.cpp b/imgui.cpp index 6502e78..b2711c4 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4476,11 +4476,28 @@ return is_open; } +static void NavProcessMoveRequestWrapAround(ImGuiWindow* window) +{ + ImGuiContext& g = *GImGui; + if (g.NavMoveRequest && g.NavWindow == window && g.NavMoveResultId == 0) + if ((g.NavMoveDir == ImGuiDir_Up || g.NavMoveDir == ImGuiDir_Down) && g.NavMoveRequestForwardStep == 0 && g.NavLayer == 0) + { + g.NavMoveRequest = false; + g.NavMoveRequestForwardStep = 1; + g.NavWindow->NavRectRel[0].Min.y = g.NavWindow->NavRectRel[0].Max.y = (g.NavMoveDir == ImGuiDir_Up) ? window->SizeFull.y : 0.0f; + } +} + void ImGui::EndPopup() { + ImGuiContext& g = *GImGui; ImGuiWindow* window = GetCurrentWindow(); IM_ASSERT(window->Flags & ImGuiWindowFlags_Popup); // Mismatched BeginPopup()/EndPopup() calls - IM_ASSERT(GImGui->CurrentPopupStack.Size > 0); + IM_ASSERT(g.CurrentPopupStack.Size > 0); + + // Make all menus and popups wrap around for now, may need to expose that policy. + NavProcessMoveRequestWrapAround(window); + End(); if (!(window->Flags & ImGuiWindowFlags_Modal)) PopStyleVar(); diff --git a/imgui.cpp b/imgui.cpp index 6502e78..b2711c4 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4476,11 +4476,28 @@ return is_open; } +static void NavProcessMoveRequestWrapAround(ImGuiWindow* window) +{ + ImGuiContext& g = *GImGui; + if (g.NavMoveRequest && g.NavWindow == window && g.NavMoveResultId == 0) + if ((g.NavMoveDir == ImGuiDir_Up || g.NavMoveDir == ImGuiDir_Down) && g.NavMoveRequestForwardStep == 0 && g.NavLayer == 0) + { + g.NavMoveRequest = false; + g.NavMoveRequestForwardStep = 1; + g.NavWindow->NavRectRel[0].Min.y = g.NavWindow->NavRectRel[0].Max.y = (g.NavMoveDir == ImGuiDir_Up) ? window->SizeFull.y : 0.0f; + } +} + void ImGui::EndPopup() { + ImGuiContext& g = *GImGui; ImGuiWindow* window = GetCurrentWindow(); IM_ASSERT(window->Flags & ImGuiWindowFlags_Popup); // Mismatched BeginPopup()/EndPopup() calls - IM_ASSERT(GImGui->CurrentPopupStack.Size > 0); + IM_ASSERT(g.CurrentPopupStack.Size > 0); + + // Make all menus and popups wrap around for now, may need to expose that policy. + NavProcessMoveRequestWrapAround(window); + End(); if (!(window->Flags & ImGuiWindowFlags_Modal)) PopStyleVar(); diff --git a/imgui_internal.h b/imgui_internal.h index d170f45..1bb4750 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -484,9 +484,9 @@ bool NavInitDefaultResultExplicit; // Whether the result was explicitly requested with SetItemDefaultFocus() bool NavMoveFromClampedRefRect; // Set by manual scrolling, if we scroll to a point where NavId isn't visible we reset navigation from visible items bool NavMoveRequest; // Move request for this frame - int NavMoveRequestForwardStep; // 0: no forward, 1: forward request, 2: forward result - ImGuiDir NavMoveDir; // West/East/North/South - ImGuiDir NavMoveDirLast; // + int NavMoveRequestForwardStep; // 0: no forward, 1: forward request, 2: forward result (this is used to navigate sibling parent menus from a child menu) + ImGuiDir NavMoveDir; // Direction of the move request (left/right/up/down) + ImGuiDir NavMoveDirLast; // Direction of the previous move request ImGuiID NavMoveResultId; // Best move request candidate ImGuiID NavMoveResultParentId; // float NavMoveResultDistBox; // Best move request candidate box distance to current NavId