From f4120e20d5256bd4e985b5192ee883df778cb9dc Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 4 Jun 2018 16:30:42 +0200 Subject: [PATCH] Nav: NavFlattened: Fixed navigation miscrolling parent window when the current window is scrolling enough to keep the item in view. Fix feature added in e11610d6, typically affect large navigation steps (used by PageUp/PageDown). + comments (#787) --- TODO.txt | 4 +++- imgui.cpp | 16 ++++++++++------ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/TODO.txt b/TODO.txt index 0ad2c630..904e6611 100644 --- a/TODO.txt +++ b/TODO.txt @@ -253,7 +253,9 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - nav: allow input system to be be more tolerant of io.DeltaTime=0.0f - nav: ESC within a menu of a child window seems to exit the child window. - nav: ESC on a flattened child - - nav: init request doesn't select items that are part of a NavFlattened child + - nav: NavFlattened: broken: in typical usage scenario, the items of a fully clipped child wouldn't be considered to enter into a NavFlattened child. + - nav: NavFlattened: broken: can accidentally enter a NavFlattened child as child items are scored outside of child visible bounds. + - nav: NavFlattened: init request doesn't select items that are part of a NavFlattened child - nav: Left within a tree node block as a fallback (ImGuiTreeNodeFlags_NavLeftJumpsBackHere by default?) - nav: menus: pressing left-right on a vertically clipped menu bar tends to jump to the collapse/close buttons. - nav: menus: allow pressing Menu to leave a sub-menu. diff --git a/imgui.cpp b/imgui.cpp index f227fbd3..65dd64b7 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3182,23 +3182,27 @@ static void ImGui::NavUpdate() { // Select which result to use ImGuiNavMoveResult* result = (g.NavMoveResultLocal.ID != 0) ? &g.NavMoveResultLocal : &g.NavMoveResultOther; - if (g.NavMoveResultOther.ID != 0 && g.NavMoveResultOther.Window->ParentWindow == g.NavWindow) // Maybe entering a flattened child? In this case solve the tie using the regular scoring rules + + // Maybe entering a flattened child from the outside? In this case solve the tie using the regular scoring rules + if (g.NavMoveResultOther.ID != 0 && g.NavMoveResultOther.Window->ParentWindow == g.NavWindow) if ((g.NavMoveResultOther.DistBox < g.NavMoveResultLocal.DistBox) || (g.NavMoveResultOther.DistBox == g.NavMoveResultLocal.DistBox && g.NavMoveResultOther.DistCenter < g.NavMoveResultLocal.DistCenter)) result = &g.NavMoveResultOther; - IM_ASSERT(g.NavWindow && result->Window); - // Scroll to keep newly navigated item fully into view. Also scroll parent window if necessary. + // Scroll to keep newly navigated item fully into view. if (g.NavLayer == 0) { ImRect rect_abs = ImRect(result->RectRel.Min + result->Window->Pos, result->RectRel.Max + result->Window->Pos); NavScrollToBringItemIntoView(result->Window, rect_abs); - if (result->Window->Flags & ImGuiWindowFlags_ChildWindow) - NavScrollToBringItemIntoView(result->Window->ParentWindow, rect_abs); // Estimate upcoming scroll so we can offset our result position so mouse position can be applied immediately after in NavUpdate() ImVec2 next_scroll = CalcNextScrollFromScrollTargetAndClamp(result->Window, false); - result->RectRel.Translate(result->Window->Scroll - next_scroll); + ImVec2 delta_scroll = result->Window->Scroll - next_scroll; + result->RectRel.Translate(delta_scroll); + + // Also scroll parent window to keep us into view if necessary (we could/should technically recurse back the whole the parent hierarchy). + if (result->Window->Flags & ImGuiWindowFlags_ChildWindow) + NavScrollToBringItemIntoView(result->Window->ParentWindow, ImRect(rect_abs.Min + delta_scroll, rect_abs.Max + delta_scroll)); } // Apply result from previous frame navigation directional move request