Nav: relative rectangle positions are now stored relative to CursorStartPos to be independent of scrolling. Will facilitate rework of clipper (#3841)
+ Extracted code into NavUpdateCreateWrappingRequest()
+ Fix for PVS in NavUpdate() assigning g.NavMousePosDirty twice.
diff --git a/imgui.cpp b/imgui.cpp
index 0554b34..344a804 100644
--- a/imgui.cpp
+++ b/imgui.cpp
@@ -917,6 +917,7 @@
static void NavUpdateCreateMoveRequest();
static float NavUpdatePageUpPageDown();
static inline void NavUpdateAnyRequestFlag();
+static void NavUpdateCreateWrappingRequest();
static void NavEndFrame();
static bool NavScoreItem(ImGuiNavItemData* result);
static void NavApplyItemToResult(ImGuiNavItemData* result);
@@ -9447,7 +9448,7 @@
if (!nav_keyboard_active && !nav_gamepad_active)
{
g.NavDisableHighlight = true;
- g.NavDisableMouseHover = g.NavMousePosDirty = false;
+ g.NavDisableMouseHover = set_mouse_pos = false;
}
// Update mouse position if requested
@@ -9465,7 +9466,7 @@
if (g.NavWindow)
{
ImDrawList* draw_list = GetForegroundDrawList(g.NavWindow);
- if (1) { for (int layer = 0; layer < 2; layer++) { ImRect r = WindowRectRelToAbs(g.NavWindow, g.NavWindow->NavRectRel[layer]); draw_list->AddRect(r.Min, r.Max, IM_COL32(255,200,0,255)); } // [DEBUG]
+ if (1) { for (int layer = 0; layer < 2; layer++) { ImRect r = WindowRectRelToAbs(g.NavWindow, g.NavWindow->NavRectRel[layer]); draw_list->AddRect(r.Min, r.Max, IM_COL32(255,200,0,255)); } } // [DEBUG]
if (1) { ImU32 col = (!g.NavWindow->Hidden) ? IM_COL32(255,0,255,255) : IM_COL32(255,0,0,255); ImVec2 p = NavCalcPreferredRefPos(); char buf[32]; ImFormatString(buf, 32, "%d", g.NavLayer); draw_list->AddCircleFilled(p, 3.0f, col); draw_list->AddText(NULL, 13.0f, p + ImVec2(8,-4), col, buf); }
}
#endif
@@ -9775,7 +9776,7 @@
// 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_ScrollToEdgeY 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;
+ nav_rect_rel.Min.y = nav_rect_rel.Max.y = 0.0f;
if (nav_rect_rel.IsInverted())
nav_rect_rel.Min.x = nav_rect_rel.Max.x = 0.0f;
g.NavMoveDir = ImGuiDir_Down;
@@ -9784,7 +9785,7 @@
}
else if (end_pressed)
{
- nav_rect_rel.Min.y = nav_rect_rel.Max.y = window->ScrollMax.y + window->SizeFull.y - window->Scroll.y;
+ nav_rect_rel.Min.y = nav_rect_rel.Max.y = window->ContentSize.y;
if (nav_rect_rel.IsInverted())
nav_rect_rel.Min.x = nav_rect_rel.Max.x = 0.0f;
g.NavMoveDir = ImGuiDir_Up;
@@ -9805,64 +9806,66 @@
NavUpdateWindowingOverlay();
// Perform wrap-around in menus
+ // FIXME-NAV: Wrap may need to apply a weight bias on the other axis. e.g. 4x4 grid with 2 last items missing on last item won't handle LoopY/WrapY correctly.
// FIXME-NAV: Wrap (not Loop) support could be handled by the scoring function and then WrapX would function without an extra frame.
- ImGuiWindow* window = g.NavWindow;
- const ImGuiNavMoveFlags move_flags = g.NavMoveFlags;
const ImGuiNavMoveFlags wanted_flags = ImGuiNavMoveFlags_WrapX | ImGuiNavMoveFlags_LoopX | ImGuiNavMoveFlags_WrapY | ImGuiNavMoveFlags_LoopY;
- if (window && NavMoveRequestButNoResultYet() && (g.NavMoveFlags & wanted_flags) && (g.NavMoveFlags & ImGuiNavMoveFlags_Forwarded) == 0)
+ if (g.NavWindow && NavMoveRequestButNoResultYet() && (g.NavMoveFlags & wanted_flags) && (g.NavMoveFlags & ImGuiNavMoveFlags_Forwarded) == 0)
+ NavUpdateCreateWrappingRequest();
+}
+
+static void ImGui::NavUpdateCreateWrappingRequest()
+{
+ ImGuiContext& g = *GImGui;
+ ImGuiWindow* window = g.NavWindow;
+
+ bool do_forward = false;
+ ImRect bb_rel = window->NavRectRel[g.NavLayer];
+ ImGuiDir clip_dir = g.NavMoveDir;
+ const ImGuiNavMoveFlags move_flags = g.NavMoveFlags;
+ if (g.NavMoveDir == ImGuiDir_Left && (move_flags & (ImGuiNavMoveFlags_WrapX | ImGuiNavMoveFlags_LoopX)))
{
- bool do_forward = false;
- ImRect bb_rel = window->NavRectRel[g.NavLayer];
- ImGuiDir clip_dir = g.NavMoveDir;
- 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;
+ if (move_flags & ImGuiNavMoveFlags_WrapX)
{
- bb_rel.Min.x = bb_rel.Max.x =
- ImMax(window->SizeFull.x, window->ContentSize.x + window->WindowPadding.x * 2.0f) - window->Scroll.x;
- if (move_flags & ImGuiNavMoveFlags_WrapX)
- {
- bb_rel.TranslateY(-bb_rel.GetHeight());
- clip_dir = ImGuiDir_Up;
- }
- do_forward = true;
+ bb_rel.TranslateY(-bb_rel.GetHeight()); // Previous row
+ clip_dir = ImGuiDir_Up;
}
- if (g.NavMoveDir == ImGuiDir_Right && (move_flags & (ImGuiNavMoveFlags_WrapX | ImGuiNavMoveFlags_LoopX)))
- {
- bb_rel.Min.x = bb_rel.Max.x = -window->Scroll.x;
- if (move_flags & ImGuiNavMoveFlags_WrapX)
- {
- bb_rel.TranslateY(+bb_rel.GetHeight());
- clip_dir = ImGuiDir_Down;
- }
- do_forward = true;
- }
- const float decoration_up_height = window->TitleBarHeight() + window->MenuBarHeight();
- if (g.NavMoveDir == ImGuiDir_Up && (move_flags & (ImGuiNavMoveFlags_WrapY | ImGuiNavMoveFlags_LoopY)))
- {
- bb_rel.Min.y = bb_rel.Max.y =
- ImMax(window->SizeFull.y, window->ContentSize.y + window->WindowPadding.y * 2.0f) - window->Scroll.y + decoration_up_height;
- if (move_flags & ImGuiNavMoveFlags_WrapY)
- {
- bb_rel.TranslateX(-bb_rel.GetWidth());
- clip_dir = ImGuiDir_Left;
- }
- do_forward = true;
- }
- if (g.NavMoveDir == ImGuiDir_Down && (move_flags & (ImGuiNavMoveFlags_WrapY | ImGuiNavMoveFlags_LoopY)))
- {
- bb_rel.Min.y = bb_rel.Max.y = -window->Scroll.y + decoration_up_height;
- if (move_flags & ImGuiNavMoveFlags_WrapY)
- {
- bb_rel.TranslateX(+bb_rel.GetWidth());
- clip_dir = ImGuiDir_Right;
- }
- do_forward = true;
- }
- if (do_forward)
- {
- window->NavRectRel[g.NavLayer] = bb_rel;
- NavMoveRequestForward(g.NavMoveDir, clip_dir, move_flags, g.NavMoveScrollFlags);
- }
+ do_forward = true;
}
+ if (g.NavMoveDir == ImGuiDir_Right && (move_flags & (ImGuiNavMoveFlags_WrapX | ImGuiNavMoveFlags_LoopX)))
+ {
+ bb_rel.Min.x = bb_rel.Max.x = -window->WindowPadding.x;
+ if (move_flags & ImGuiNavMoveFlags_WrapX)
+ {
+ bb_rel.TranslateY(+bb_rel.GetHeight()); // Next row
+ clip_dir = ImGuiDir_Down;
+ }
+ do_forward = true;
+ }
+ if (g.NavMoveDir == ImGuiDir_Up && (move_flags & (ImGuiNavMoveFlags_WrapY | ImGuiNavMoveFlags_LoopY)))
+ {
+ bb_rel.Min.y = bb_rel.Max.y = window->ContentSize.y + window->WindowPadding.y;
+ if (move_flags & ImGuiNavMoveFlags_WrapY)
+ {
+ bb_rel.TranslateX(-bb_rel.GetWidth()); // Previous column
+ clip_dir = ImGuiDir_Left;
+ }
+ do_forward = true;
+ }
+ if (g.NavMoveDir == ImGuiDir_Down && (move_flags & (ImGuiNavMoveFlags_WrapY | ImGuiNavMoveFlags_LoopY)))
+ {
+ bb_rel.Min.y = bb_rel.Max.y = -window->WindowPadding.y;
+ if (move_flags & ImGuiNavMoveFlags_WrapY)
+ {
+ bb_rel.TranslateX(+bb_rel.GetWidth()); // Next column
+ clip_dir = ImGuiDir_Right;
+ }
+ do_forward = true;
+ }
+ if (!do_forward)
+ return;
+ window->NavRectRel[g.NavLayer] = bb_rel;
+ NavMoveRequestForward(g.NavMoveDir, clip_dir, move_flags, g.NavMoveScrollFlags);
}
static int ImGui::FindWindowFocusIndex(ImGuiWindow* window)
diff --git a/imgui.h b/imgui.h
index db1d96c..e3d2b41 100644
--- a/imgui.h
+++ b/imgui.h
@@ -64,7 +64,7 @@
// Version
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY99 then bounce up to XYY00, XYY01 etc. when release tagging happens)
#define IMGUI_VERSION "1.86 WIP"
-#define IMGUI_VERSION_NUM 18503
+#define IMGUI_VERSION_NUM 18504
#define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx))
#define IMGUI_HAS_TABLE
diff --git a/imgui_internal.h b/imgui_internal.h
index cb41487..3373db0 100644
--- a/imgui_internal.h
+++ b/imgui_internal.h
@@ -2388,8 +2388,8 @@
IMGUI_API void SetWindowSize(ImGuiWindow* window, const ImVec2& size, ImGuiCond cond = 0);
IMGUI_API void SetWindowCollapsed(ImGuiWindow* window, bool collapsed, ImGuiCond cond = 0);
IMGUI_API void SetWindowHitTestHole(ImGuiWindow* window, const ImVec2& pos, const ImVec2& size);
- inline ImRect WindowRectAbsToRel(ImGuiWindow* window, const ImRect& r) { ImVec2 off = window->Pos; return ImRect(r.Min.x - off.x, r.Min.y - off.y, r.Max.x - off.x, r.Max.y - off.y); }
- inline ImRect WindowRectRelToAbs(ImGuiWindow* window, const ImRect& r) { ImVec2 off = window->Pos; return ImRect(r.Min.x + off.x, r.Min.y + off.y, r.Max.x + off.x, r.Max.y + off.y); }
+ inline ImRect WindowRectAbsToRel(ImGuiWindow* window, const ImRect& r) { ImVec2 off = window->DC.CursorStartPos; return ImRect(r.Min.x - off.x, r.Min.y - off.y, r.Max.x - off.x, r.Max.y - off.y); }
+ inline ImRect WindowRectRelToAbs(ImGuiWindow* window, const ImRect& r) { ImVec2 off = window->DC.CursorStartPos; return ImRect(r.Min.x + off.x, r.Min.y + off.y, r.Max.x + off.x, r.Max.y + off.y); }
// Windows: Display Order and Focus Order
IMGUI_API void FocusWindow(ImGuiWindow* window);