|
@@ -8943,12 +8943,12 @@ void ImGui::NavMoveRequestCancel()
|
|
|
void ImGui::NavMoveRequestForward(ImGuiDir move_dir, ImGuiDir clip_dir, ImGuiNavMoveFlags move_flags)
|
|
|
{
|
|
|
ImGuiContext& g = *GImGui;
|
|
|
- IM_ASSERT(g.NavMoveRequestForward == ImGuiNavForward_None);
|
|
|
+ IM_ASSERT(g.NavMoveRequestForwardToNextFrame == false);
|
|
|
NavMoveRequestCancel();
|
|
|
+ g.NavMoveRequestForwardToNextFrame = true;
|
|
|
g.NavMoveDir = move_dir;
|
|
|
g.NavMoveClipDir = clip_dir;
|
|
|
- g.NavMoveRequestForward = ImGuiNavForward_ForwardQueued;
|
|
|
- g.NavMoveRequestFlags = move_flags;
|
|
|
+ g.NavMoveRequestFlags = move_flags | ImGuiNavMoveFlags_Forwarded;
|
|
|
}
|
|
|
|
|
|
// Navigation wrap-around logic is delayed to the end of the frame because this operation is only valid after entire
|
|
@@ -9151,6 +9151,7 @@ static void ImGui::NavUpdate()
|
|
|
// Process navigation move request
|
|
|
if (g.NavMoveRequest)
|
|
|
NavMoveRequestApplyResult();
|
|
|
+ g.NavMoveRequest = false;
|
|
|
|
|
|
// Apply application mouse position movement, after we had a chance to process move request result.
|
|
|
if (g.NavMousePosDirty && g.NavIdIsAlive)
|
|
@@ -9203,16 +9204,24 @@ static void ImGui::NavUpdate()
|
|
|
g.NavDisableHighlight = true;
|
|
|
if (g.NavActivateId != 0)
|
|
|
IM_ASSERT(g.NavActivateDownId == g.NavActivateId);
|
|
|
- g.NavMoveRequest = false;
|
|
|
|
|
|
// Process programmatic activation request
|
|
|
if (g.NavNextActivateId != 0)
|
|
|
g.NavActivateId = g.NavActivateDownId = g.NavActivatePressedId = g.NavInputId = g.NavNextActivateId;
|
|
|
g.NavNextActivateId = 0;
|
|
|
|
|
|
- // Initiate directional inputs request
|
|
|
- if (g.NavMoveRequestForward == ImGuiNavForward_None)
|
|
|
+ if (g.NavMoveRequestForwardToNextFrame)
|
|
|
+ {
|
|
|
+ // Forwarding previous request (which has been modified, e.g. wrap around menus rewrite the requests with a starting rectangle at the other side of the window)
|
|
|
+ // (Preserve g.NavMoveRequestFlags, g.NavMoveClipDir which were set by the NavMoveRequestForward() function)
|
|
|
+ IM_ASSERT(g.NavMoveDir != ImGuiDir_None && g.NavMoveClipDir != ImGuiDir_None);
|
|
|
+ IM_ASSERT(g.NavMoveRequestFlags & ImGuiNavMoveFlags_Forwarded);
|
|
|
+ IMGUI_DEBUG_LOG_NAV("[nav] NavMoveRequestForward %d\n", g.NavMoveDir);
|
|
|
+ g.NavMoveRequestForwardToNextFrame = false;
|
|
|
+ }
|
|
|
+ else
|
|
|
{
|
|
|
+ // Initiate directional inputs request
|
|
|
g.NavMoveDir = ImGuiDir_None;
|
|
|
g.NavMoveRequestFlags = ImGuiNavMoveFlags_None;
|
|
|
if (g.NavWindow && !g.NavWindowingTarget && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs))
|
|
@@ -9225,14 +9234,6 @@ static void ImGui::NavUpdate()
|
|
|
}
|
|
|
g.NavMoveClipDir = g.NavMoveDir;
|
|
|
}
|
|
|
- else if (g.NavMoveRequestForward == ImGuiNavForward_ForwardQueued)
|
|
|
- {
|
|
|
- // Forwarding previous request (which has been modified, e.g. wrap around menus rewrite the requests with a starting rectangle at the other side of the window)
|
|
|
- // (Preserve g.NavMoveRequestFlags, g.NavMoveClipDir which were set by the NavMoveRequestForward() function)
|
|
|
- IM_ASSERT(g.NavMoveDir != ImGuiDir_None && g.NavMoveClipDir != ImGuiDir_None);
|
|
|
- IMGUI_DEBUG_LOG_NAV("[nav] NavMoveRequestForward %d\n", g.NavMoveDir);
|
|
|
- g.NavMoveRequestForward = ImGuiNavForward_ForwardActive;
|
|
|
- }
|
|
|
|
|
|
// Update PageUp/PageDown/Home/End scroll
|
|
|
// FIXME-NAV: Consider enabling those keys even without the master ImGuiConfigFlags_NavEnableKeyboard flag?
|
|
@@ -9256,6 +9257,8 @@ static void ImGui::NavUpdate()
|
|
|
g.NavDisableHighlight = false;
|
|
|
}
|
|
|
NavUpdateAnyRequestFlag();
|
|
|
+ if (g.NavMoveDir != ImGuiDir_None)
|
|
|
+ IM_ASSERT(g.NavMoveRequest);
|
|
|
|
|
|
// Scrolling
|
|
|
if (g.NavWindow && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs) && !g.NavWindowingTarget)
|
|
@@ -9344,9 +9347,6 @@ void ImGui::NavMoveRequestApplyResult()
|
|
|
{
|
|
|
ImGuiContext& g = *GImGui;
|
|
|
|
|
|
- if (g.NavMoveRequestForward == ImGuiNavForward_ForwardActive)
|
|
|
- g.NavMoveRequestForward = ImGuiNavForward_None;
|
|
|
-
|
|
|
if (g.NavMoveResultLocal.ID == 0 && g.NavMoveResultOther.ID == 0)
|
|
|
{
|
|
|
// In a situation when there is no results but NavId != 0, re-enable the Navigation highlight (because g.NavId is not considered as a possible result)
|
|
@@ -9471,60 +9471,60 @@ static float ImGui::NavUpdatePageUpPageDown()
|
|
|
const bool page_down_held = IsKeyDown(io.KeyMap[ImGuiKey_PageDown]) && !IsActiveIdUsingKey(ImGuiKey_PageDown);
|
|
|
const bool home_pressed = IsKeyPressed(io.KeyMap[ImGuiKey_Home]) && !IsActiveIdUsingKey(ImGuiKey_Home);
|
|
|
const bool end_pressed = IsKeyPressed(io.KeyMap[ImGuiKey_End]) && !IsActiveIdUsingKey(ImGuiKey_End);
|
|
|
- if (page_up_held != page_down_held || home_pressed != end_pressed) // If either (not both) are pressed
|
|
|
+ if (page_up_held == page_down_held && home_pressed == end_pressed) // Proceed if either (not both) are pressed, otherwise early out
|
|
|
+ return 0.0f;
|
|
|
+
|
|
|
+ if (window->DC.NavLayersActiveMask == 0x00 && window->DC.NavHasScroll)
|
|
|
{
|
|
|
- if (window->DC.NavLayersActiveMask == 0x00 && window->DC.NavHasScroll)
|
|
|
+ // Fallback manual-scroll when window has no navigable item
|
|
|
+ if (IsKeyPressed(io.KeyMap[ImGuiKey_PageUp], true))
|
|
|
+ SetScrollY(window, window->Scroll.y - window->InnerRect.GetHeight());
|
|
|
+ else if (IsKeyPressed(io.KeyMap[ImGuiKey_PageDown], true))
|
|
|
+ SetScrollY(window, window->Scroll.y + window->InnerRect.GetHeight());
|
|
|
+ else if (home_pressed)
|
|
|
+ SetScrollY(window, 0.0f);
|
|
|
+ else if (end_pressed)
|
|
|
+ SetScrollY(window, window->ScrollMax.y);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ ImRect& nav_rect_rel = window->NavRectRel[g.NavLayer];
|
|
|
+ const float page_offset_y = ImMax(0.0f, window->InnerRect.GetHeight() - window->CalcFontSize() * 1.0f + nav_rect_rel.GetHeight());
|
|
|
+ float nav_scoring_rect_offset_y = 0.0f;
|
|
|
+ if (IsKeyPressed(io.KeyMap[ImGuiKey_PageUp], true))
|
|
|
{
|
|
|
- // Fallback manual-scroll when window has no navigable item
|
|
|
- if (IsKeyPressed(io.KeyMap[ImGuiKey_PageUp], true))
|
|
|
- SetScrollY(window, window->Scroll.y - window->InnerRect.GetHeight());
|
|
|
- else if (IsKeyPressed(io.KeyMap[ImGuiKey_PageDown], true))
|
|
|
- SetScrollY(window, window->Scroll.y + window->InnerRect.GetHeight());
|
|
|
- else if (home_pressed)
|
|
|
- SetScrollY(window, 0.0f);
|
|
|
- else if (end_pressed)
|
|
|
- SetScrollY(window, window->ScrollMax.y);
|
|
|
+ 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.NavMoveRequestFlags = ImGuiNavMoveFlags_AllowCurrentNavId | ImGuiNavMoveFlags_AlsoScoreVisibleSet;
|
|
|
}
|
|
|
- else
|
|
|
+ else if (IsKeyPressed(io.KeyMap[ImGuiKey_PageDown], true))
|
|
|
{
|
|
|
- ImRect& nav_rect_rel = window->NavRectRel[g.NavLayer];
|
|
|
- const float page_offset_y = ImMax(0.0f, window->InnerRect.GetHeight() - window->CalcFontSize() * 1.0f + nav_rect_rel.GetHeight());
|
|
|
- float nav_scoring_rect_offset_y = 0.0f;
|
|
|
- if (IsKeyPressed(io.KeyMap[ImGuiKey_PageUp], true))
|
|
|
- {
|
|
|
- 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.NavMoveRequestFlags = ImGuiNavMoveFlags_AllowCurrentNavId | ImGuiNavMoveFlags_AlsoScoreVisibleSet;
|
|
|
- }
|
|
|
- else if (IsKeyPressed(io.KeyMap[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.NavMoveRequestFlags = ImGuiNavMoveFlags_AllowCurrentNavId | ImGuiNavMoveFlags_AlsoScoreVisibleSet;
|
|
|
- }
|
|
|
- else if (home_pressed)
|
|
|
- {
|
|
|
- // FIXME-NAV: handling of Home/End is assuming that the top/bottom most item will be visible with Scroll.y == 0/ScrollMax.y
|
|
|
- // Scrolling will be handled via the ImGuiNavMoveFlags_ScrollToEdge flag, we don't scroll immediately to avoid scrolling happening before nav result.
|
|
|
- // Preserve current horizontal position if we have any.
|
|
|
- nav_rect_rel.Min.y = nav_rect_rel.Max.y = -window->Scroll.y;
|
|
|
- if (nav_rect_rel.IsInverted())
|
|
|
- nav_rect_rel.Min.x = nav_rect_rel.Max.x = 0.0f;
|
|
|
- g.NavMoveDir = ImGuiDir_Down;
|
|
|
- g.NavMoveRequestFlags = ImGuiNavMoveFlags_AllowCurrentNavId | ImGuiNavMoveFlags_ScrollToEdge;
|
|
|
- }
|
|
|
- else if (end_pressed)
|
|
|
- {
|
|
|
- nav_rect_rel.Min.y = nav_rect_rel.Max.y = window->ScrollMax.y + window->SizeFull.y - window->Scroll.y;
|
|
|
- if (nav_rect_rel.IsInverted())
|
|
|
- nav_rect_rel.Min.x = nav_rect_rel.Max.x = 0.0f;
|
|
|
- g.NavMoveDir = ImGuiDir_Up;
|
|
|
- g.NavMoveRequestFlags = ImGuiNavMoveFlags_AllowCurrentNavId | ImGuiNavMoveFlags_ScrollToEdge;
|
|
|
- }
|
|
|
- return nav_scoring_rect_offset_y;
|
|
|
+ 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.NavMoveRequestFlags = ImGuiNavMoveFlags_AllowCurrentNavId | ImGuiNavMoveFlags_AlsoScoreVisibleSet;
|
|
|
+ }
|
|
|
+ else if (home_pressed)
|
|
|
+ {
|
|
|
+ // FIXME-NAV: handling of Home/End is assuming that the top/bottom most item will be visible with Scroll.y == 0/ScrollMax.y
|
|
|
+ // Scrolling will be handled via the ImGuiNavMoveFlags_ScrollToEdge flag, we don't scroll immediately to avoid scrolling happening before nav result.
|
|
|
+ // Preserve current horizontal position if we have any.
|
|
|
+ nav_rect_rel.Min.y = nav_rect_rel.Max.y = -window->Scroll.y;
|
|
|
+ if (nav_rect_rel.IsInverted())
|
|
|
+ nav_rect_rel.Min.x = nav_rect_rel.Max.x = 0.0f;
|
|
|
+ g.NavMoveDir = ImGuiDir_Down;
|
|
|
+ g.NavMoveRequestFlags = ImGuiNavMoveFlags_AllowCurrentNavId | ImGuiNavMoveFlags_ScrollToEdge;
|
|
|
+ }
|
|
|
+ else if (end_pressed)
|
|
|
+ {
|
|
|
+ nav_rect_rel.Min.y = nav_rect_rel.Max.y = window->ScrollMax.y + window->SizeFull.y - window->Scroll.y;
|
|
|
+ if (nav_rect_rel.IsInverted())
|
|
|
+ nav_rect_rel.Min.x = nav_rect_rel.Max.x = 0.0f;
|
|
|
+ g.NavMoveDir = ImGuiDir_Up;
|
|
|
+ g.NavMoveRequestFlags = ImGuiNavMoveFlags_AllowCurrentNavId | ImGuiNavMoveFlags_ScrollToEdge;
|
|
|
}
|
|
|
+ return nav_scoring_rect_offset_y;
|
|
|
}
|
|
|
return 0.0f;
|
|
|
}
|
|
@@ -9542,7 +9542,7 @@ static void ImGui::NavEndFrame()
|
|
|
ImGuiWindow* window = g.NavWindow;
|
|
|
const ImGuiNavMoveFlags move_flags = g.NavMoveRequestFlags;
|
|
|
const ImGuiNavMoveFlags wanted_flags = ImGuiNavMoveFlags_WrapX | ImGuiNavMoveFlags_LoopX | ImGuiNavMoveFlags_WrapY | ImGuiNavMoveFlags_LoopY;
|
|
|
- if (window && NavMoveRequestButNoResultYet() && (g.NavMoveRequestFlags & wanted_flags) && g.NavMoveRequestForward == ImGuiNavForward_None)
|
|
|
+ if (window && NavMoveRequestButNoResultYet() && (g.NavMoveRequestFlags & wanted_flags) && (g.NavMoveRequestFlags & ImGuiNavMoveFlags_Forwarded) == 0)
|
|
|
{
|
|
|
bool do_forward = false;
|
|
|
ImRect bb_rel = window->NavRectRel[g.NavLayer];
|