mirror of
https://github.com/ocornut/imgui.git
synced 2024-11-24 15:50:25 +01:00
Nav: rework NavEnableSetMousePos application so scrolling is applied more consistently in NavCalcPreferredRefPos() + moved at end of NavUpdate() after the last SetScroll have been done.
This commit is contained in:
parent
8361ed1f54
commit
8d361c47fb
43
imgui.cpp
43
imgui.cpp
@ -9232,7 +9232,8 @@ void ImGui::NavInitWindow(ImGuiWindow* window, bool force_reinit)
|
|||||||
static ImVec2 ImGui::NavCalcPreferredRefPos()
|
static ImVec2 ImGui::NavCalcPreferredRefPos()
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
if (g.NavDisableHighlight || !g.NavDisableMouseHover || !g.NavWindow)
|
ImGuiWindow* window = g.NavWindow;
|
||||||
|
if (g.NavDisableHighlight || !g.NavDisableMouseHover || !window)
|
||||||
{
|
{
|
||||||
// Mouse (we need a fallback in case the mouse becomes invalid after being used)
|
// Mouse (we need a fallback in case the mouse becomes invalid after being used)
|
||||||
if (IsMousePosValid(&g.IO.MousePos))
|
if (IsMousePosValid(&g.IO.MousePos))
|
||||||
@ -9241,8 +9242,14 @@ static ImVec2 ImGui::NavCalcPreferredRefPos()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// When navigation is active and mouse is disabled, decide on an arbitrary position around the bottom left of the currently navigated item.
|
// When navigation is active and mouse is disabled, pick a position around the bottom left of the currently navigated item
|
||||||
ImRect rect_rel = WindowRectRelToAbs(g.NavWindow, g.NavWindow->NavRectRel[g.NavLayer]);
|
// Take account of upcoming scrolling (maybe set mouse pos should be done in EndFrame?)
|
||||||
|
ImRect rect_rel = WindowRectRelToAbs(window, window->NavRectRel[g.NavLayer]);
|
||||||
|
if (window->LastFrameActive != g.FrameCount && (window->ScrollTarget.x != FLT_MAX || window->ScrollTarget.y != FLT_MAX))
|
||||||
|
{
|
||||||
|
ImVec2 next_scroll = CalcNextScrollFromScrollTargetAndClamp(window);
|
||||||
|
rect_rel.Translate(window->Scroll - next_scroll);
|
||||||
|
}
|
||||||
ImVec2 pos = ImVec2(rect_rel.Min.x + ImMin(g.Style.FramePadding.x * 4, rect_rel.GetWidth()), rect_rel.Max.y - ImMin(g.Style.FramePadding.y, rect_rel.GetHeight()));
|
ImVec2 pos = ImVec2(rect_rel.Min.x + ImMin(g.Style.FramePadding.x * 4, rect_rel.GetWidth()), rect_rel.Max.y - ImMin(g.Style.FramePadding.y, rect_rel.GetHeight()));
|
||||||
ImGuiViewport* viewport = GetMainViewport();
|
ImGuiViewport* viewport = GetMainViewport();
|
||||||
return ImFloor(ImClamp(pos, viewport->Pos, viewport->Pos + viewport->Size)); // ImFloor() is important because non-integer mouse position application in backend might be lossy and result in undesirable non-zero delta.
|
return ImFloor(ImClamp(pos, viewport->Pos, viewport->Pos + viewport->Size)); // ImFloor() is important because non-integer mouse position application in backend might be lossy and result in undesirable non-zero delta.
|
||||||
@ -9341,19 +9348,12 @@ static void ImGui::NavUpdate()
|
|||||||
g.NavTabbingInputableRemaining = 0;
|
g.NavTabbingInputableRemaining = 0;
|
||||||
g.NavMoveSubmitted = g.NavMoveScoringItems = false;
|
g.NavMoveSubmitted = g.NavMoveScoringItems = false;
|
||||||
|
|
||||||
// Apply application mouse position movement, after we had a chance to process move request result.
|
// Schedule mouse position update (will be done at the bottom of this function, after 1) processing all move requests and 2) updating scrolling)
|
||||||
|
bool set_mouse_pos = false;
|
||||||
if (g.NavMousePosDirty && g.NavIdIsAlive)
|
if (g.NavMousePosDirty && g.NavIdIsAlive)
|
||||||
{
|
|
||||||
// Set mouse position given our knowledge of the navigated item position from last frame
|
|
||||||
if ((io.ConfigFlags & ImGuiConfigFlags_NavEnableSetMousePos) && (io.BackendFlags & ImGuiBackendFlags_HasSetMousePos))
|
|
||||||
if (!g.NavDisableHighlight && g.NavDisableMouseHover && g.NavWindow)
|
if (!g.NavDisableHighlight && g.NavDisableMouseHover && g.NavWindow)
|
||||||
{
|
set_mouse_pos = true;
|
||||||
io.MousePos = io.MousePosPrev = NavCalcPreferredRefPos();
|
|
||||||
io.WantSetMousePos = true;
|
|
||||||
//IMGUI_DEBUG_LOG("SetMousePos: (%.1f,%.1f)\n", io.MousePos.x, io.MousePos.y);
|
|
||||||
}
|
|
||||||
g.NavMousePosDirty = false;
|
g.NavMousePosDirty = false;
|
||||||
}
|
|
||||||
g.NavIdIsAlive = false;
|
g.NavIdIsAlive = false;
|
||||||
g.NavJustTabbedId = 0;
|
g.NavJustTabbedId = 0;
|
||||||
IM_ASSERT(g.NavLayer == ImGuiNavLayer_Main || g.NavLayer == ImGuiNavLayer_Menu);
|
IM_ASSERT(g.NavLayer == ImGuiNavLayer_Main || g.NavLayer == ImGuiNavLayer_Menu);
|
||||||
@ -9450,6 +9450,15 @@ static void ImGui::NavUpdate()
|
|||||||
g.NavDisableMouseHover = g.NavMousePosDirty = false;
|
g.NavDisableMouseHover = g.NavMousePosDirty = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update mouse position if requested
|
||||||
|
// (This will take into account the possibility that a Scroll was queued in the window to offset our absolute mouse position before scroll has been applied)
|
||||||
|
if (set_mouse_pos && (io.ConfigFlags & ImGuiConfigFlags_NavEnableSetMousePos) && (io.BackendFlags & ImGuiBackendFlags_HasSetMousePos))
|
||||||
|
{
|
||||||
|
io.MousePos = io.MousePosPrev = NavCalcPreferredRefPos();
|
||||||
|
io.WantSetMousePos = true;
|
||||||
|
//IMGUI_DEBUG_LOG("SetMousePos: (%.1f,%.1f)\n", io.MousePos.x, io.MousePos.y);
|
||||||
|
}
|
||||||
|
|
||||||
// [DEBUG]
|
// [DEBUG]
|
||||||
g.NavScoringDebugCount = 0;
|
g.NavScoringDebugCount = 0;
|
||||||
#if IMGUI_DEBUG_NAV_RECTS
|
#if IMGUI_DEBUG_NAV_RECTS
|
||||||
@ -9614,23 +9623,17 @@ void ImGui::NavMoveRequestApplyResult()
|
|||||||
// Scroll to keep newly navigated item fully into view.
|
// Scroll to keep newly navigated item fully into view.
|
||||||
if (g.NavLayer == ImGuiNavLayer_Main)
|
if (g.NavLayer == ImGuiNavLayer_Main)
|
||||||
{
|
{
|
||||||
ImVec2 delta_scroll;
|
|
||||||
if (g.NavMoveFlags & ImGuiNavMoveFlags_ScrollToEdgeY)
|
if (g.NavMoveFlags & ImGuiNavMoveFlags_ScrollToEdgeY)
|
||||||
{
|
{
|
||||||
// FIXME: Should remove this
|
// FIXME: Should remove this
|
||||||
float scroll_target = (g.NavMoveDir == ImGuiDir_Up) ? result->Window->ScrollMax.y : 0.0f;
|
float scroll_target = (g.NavMoveDir == ImGuiDir_Up) ? result->Window->ScrollMax.y : 0.0f;
|
||||||
delta_scroll.y = scroll_target - result->Window->Scroll.y;
|
|
||||||
SetScrollY(result->Window, scroll_target);
|
SetScrollY(result->Window, scroll_target);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ImRect rect_abs = WindowRectRelToAbs(result->Window, result->RectRel);
|
ImRect rect_abs = WindowRectRelToAbs(result->Window, result->RectRel);
|
||||||
delta_scroll = ScrollToRectEx(result->Window, rect_abs, g.NavMoveScrollFlags);
|
ScrollToRectEx(result->Window, rect_abs, g.NavMoveScrollFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Offset our result position so mouse position can be applied immediately after in NavUpdate()
|
|
||||||
result->RectRel.TranslateX(-delta_scroll.x);
|
|
||||||
result->RectRel.TranslateY(-delta_scroll.y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ClearActiveID();
|
ClearActiveID();
|
||||||
|
Loading…
Reference in New Issue
Block a user