diff --git a/imgui.cpp b/imgui.cpp index 35dc532d..c15db4d1 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -10671,7 +10671,7 @@ void ImGui::SetFocusID(ImGuiID id, ImGuiWindow* window) NavClearPreferredPosForAxis(ImGuiAxis_Y); } -ImGuiDir ImGetDirQuadrantFromDelta(float dx, float dy) +static ImGuiDir ImGetDirQuadrantFromDelta(float dx, float dy) { if (ImFabs(dx) > ImFabs(dy)) return (dx > 0.0f) ? ImGuiDir_Right : ImGuiDir_Left; @@ -11044,7 +11044,8 @@ void ImGui::NavMoveRequestTryWrapping(ImGuiWindow* window, ImGuiNavMoveFlags wra ImGuiContext& g = *GImGui; IM_ASSERT((wrap_flags & ImGuiNavMoveFlags_WrapMask_ ) != 0 && (wrap_flags & ~ImGuiNavMoveFlags_WrapMask_) == 0); // Call with _WrapX, _WrapY, _LoopX, _LoopY - // In theory we should test for NavMoveRequestButNoResultYet() but there's no point doing it, NavEndFrame() will do the same test + // In theory we should test for NavMoveRequestButNoResultYet() but there's no point doing it: + // as NavEndFrame() will do the same test. It will end up calling NavUpdateCreateWrappingRequest(). if (g.NavWindow == window && g.NavMoveScoringItems && g.NavLayer == ImGuiNavLayer_Main) g.NavMoveFlags = (g.NavMoveFlags & ~ImGuiNavMoveFlags_WrapMask_) | wrap_flags; } @@ -11369,7 +11370,7 @@ void ImGui::NavInitRequestApplyResult() } // Bias scoring rect ahead of scoring + update preferred pos (if missing) using source position -static void NavBiasScoringRect(ImRect& r, ImVec2& preferred_pos_rel, ImGuiDir move_dir) +static void NavBiasScoringRect(ImRect& r, ImVec2& preferred_pos_rel, ImGuiDir move_dir, ImGuiNavMoveFlags move_flags) { // Bias initial rect ImGuiContext& g = *GImGui; @@ -11378,15 +11379,18 @@ static void NavBiasScoringRect(ImRect& r, ImVec2& preferred_pos_rel, ImGuiDir mo // Initialize bias on departure if we don't have any. So mouse-click + arrow will record bias. // - We default to L/U bias, so moving down from a large source item into several columns will land on left-most column. // - But each successful move sets new bias on one axis, only cleared when using mouse. - if (preferred_pos_rel.x == FLT_MAX) - preferred_pos_rel.x = ImMin(r.Min.x + 1.0f, r.Max.x) - rel_to_abs_offset.x; - if (preferred_pos_rel.y == FLT_MAX) - preferred_pos_rel.y = r.GetCenter().y - rel_to_abs_offset.y; + if ((move_flags & ImGuiNavMoveFlags_Forwarded) == 0) + { + if (preferred_pos_rel.x == FLT_MAX) + preferred_pos_rel.x = ImMin(r.Min.x + 1.0f, r.Max.x) - rel_to_abs_offset.x; + if (preferred_pos_rel.y == FLT_MAX) + preferred_pos_rel.y = r.GetCenter().y - rel_to_abs_offset.y; + } // Apply general bias on the other axis - if (move_dir == ImGuiDir_Up || move_dir == ImGuiDir_Down) + if ((move_dir == ImGuiDir_Up || move_dir == ImGuiDir_Down) && preferred_pos_rel.x != FLT_MAX) r.Min.x = r.Max.x = preferred_pos_rel.x + rel_to_abs_offset.x; - else + else if ((move_dir == ImGuiDir_Left || move_dir == ImGuiDir_Right) && preferred_pos_rel.y != FLT_MAX) r.Min.y = r.Max.y = preferred_pos_rel.y + rel_to_abs_offset.y; } @@ -11497,7 +11501,7 @@ void ImGui::NavUpdateCreateMoveRequest() scoring_rect = WindowRectRelToAbs(window, nav_rect_rel); scoring_rect.TranslateY(scoring_rect_offset_y); if (g.NavMoveSubmitted) - NavBiasScoringRect(scoring_rect, window->RootWindowForNav->NavPreferredScoringPosRel[g.NavLayer], g.NavMoveDir); + NavBiasScoringRect(scoring_rect, window->RootWindowForNav->NavPreferredScoringPosRel[g.NavLayer], g.NavMoveDir, g.NavMoveFlags); IM_ASSERT(!scoring_rect.IsInverted()); // Ensure if we have a finite, non-inverted bounding box here will allow us to remove extraneous ImFabs() calls in NavScoreItem(). //GetForegroundDrawList()->AddRect(scoring_rect.Min, scoring_rect.Max, IM_COL32(255,200,0,255)); // [DEBUG] //if (!g.NavScoringNoClipRect.IsInverted()) { GetForegroundDrawList()->AddRect(g.NavScoringNoClipRect.Min, g.NavScoringNoClipRect.Max, IM_COL32(255, 200, 0, 255)); } // [DEBUG] @@ -11785,7 +11789,9 @@ static void ImGui::NavUpdateCreateWrappingRequest() bool do_forward = false; ImRect bb_rel = window->NavRectRel[g.NavLayer]; ImGuiDir clip_dir = g.NavMoveDir; + const ImGuiNavMoveFlags move_flags = g.NavMoveFlags; + //const ImGuiAxis move_axis = (g.NavMoveDir == ImGuiDir_Up || g.NavMoveDir == ImGuiDir_Down) ? ImGuiAxis_Y : ImGuiAxis_X; if (g.NavMoveDir == ImGuiDir_Left && (move_flags & (ImGuiNavMoveFlags_WrapX | ImGuiNavMoveFlags_LoopX))) { bb_rel.Min.x = bb_rel.Max.x = window->ContentSize.x + window->WindowPadding.x; diff --git a/imgui.h b/imgui.h index 672f841c..50319aa7 100644 --- a/imgui.h +++ b/imgui.h @@ -21,9 +21,9 @@ // please post in https://github.com/ocornut/imgui/discussions if you cannot find a solution in resources above. // Library Version -// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM > 12345') -#define IMGUI_VERSION "1.89.6 WIP" -#define IMGUI_VERSION_NUM 18956 +// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345') +#define IMGUI_VERSION "1.89.6 WIP" +#define IMGUI_VERSION_NUM 18957 #define IMGUI_HAS_TABLE /* diff --git a/imgui_internal.h b/imgui_internal.h index 00c762ee..f5befd33 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -479,7 +479,6 @@ IMGUI_API bool ImTriangleContainsPoint(const ImVec2& a, const ImVec2& b, c IMGUI_API ImVec2 ImTriangleClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p); IMGUI_API void ImTriangleBarycentricCoords(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p, float& out_u, float& out_v, float& out_w); inline float ImTriangleArea(const ImVec2& a, const ImVec2& b, const ImVec2& c) { return ImFabs((a.x * (b.y - c.y)) + (b.x * (c.y - a.y)) + (c.x * (a.y - b.y))) * 0.5f; } -IMGUI_API ImGuiDir ImGetDirQuadrantFromDelta(float dx, float dy); // Helper: ImVec1 (1D vector) // (this odd construct is used to facilitate the transition between 1D and 2D, and the maintenance of some branches/patches)