Internals: slight refactor FindHoveredWindow() -> FindHoveredWindowEx() toward reducing far-away code duplication.

This commit is contained in:
ocornut 2024-05-14 15:47:38 +02:00
parent f806c76e97
commit d0524df887
3 changed files with 28 additions and 16 deletions

View File

@ -4488,7 +4488,7 @@ void ImGui::UpdateHoveredWindowAndCaptureFlags()
// - When moving a window we can skip the search, which also conveniently bypasses the fact that window->WindowRectClipped is lagging as this point of the frame.
// - We also support the moved window toggling the NoInputs flag after moving has started in order to be able to detect windows below it, which is useful for e.g. docking mechanisms.
bool clear_hovered_windows = false;
FindHoveredWindow();
FindHoveredWindowEx(g.IO.MousePos, false, &g.HoveredWindow, &g.HoveredWindowUnderMovingWindow);
// Modal windows prevents mouse from hovering behind them.
ImGuiWindow* modal_window = GetTopMostPopupModal();
@ -5215,15 +5215,17 @@ ImVec2 ImGui::CalcTextSize(const char* text, const char* text_end, bool hide_tex
}
// Find window given position, search front-to-back
// FIXME: Note that we have an inconsequential lag here: OuterRectClipped is updated in Begin(), so windows moved programmatically
// with SetWindowPos() and not SetNextWindowPos() will have that rectangle lagging by a frame at the time FindHoveredWindow() is
// called, aka before the next Begin(). Moving window isn't affected.
static void FindHoveredWindow()
// - Typically write output back to g.HoveredWindow and g.HoveredWindowUnderMovingWindow.
// - FIXME: Note that we have an inconsequential lag here: OuterRectClipped is updated in Begin(), so windows moved programmatically
// with SetWindowPos() and not SetNextWindowPos() will have that rectangle lagging by a frame at the time FindHoveredWindow() is
// called, aka before the next Begin(). Moving window isn't affected.
// - The 'find_first_and_in_any_viewport = true' mode is only used by TestEngine. It is simpler to maintain here.
void ImGui::FindHoveredWindowEx(const ImVec2& pos, bool find_first_and_in_any_viewport, ImGuiWindow** out_hovered_window, ImGuiWindow** out_hovered_window_under_moving_window)
{
ImGuiContext& g = *GImGui;
ImGuiWindow* hovered_window = NULL;
ImGuiWindow* hovered_window_ignoring_moving_window = NULL;
ImGuiWindow* hovered_window_under_moving_window = NULL;
if (g.MovingWindow && !(g.MovingWindow->Flags & ImGuiWindowFlags_NoMouseInputs))
hovered_window = g.MovingWindow;
@ -5240,7 +5242,7 @@ static void FindHoveredWindow()
// Using the clipped AABB, a child window will typically be clipped by its parent (not always)
ImVec2 hit_padding = (window->Flags & (ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize)) ? padding_regular : padding_for_resize;
if (!window->OuterRectClipped.ContainsWithPad(g.IO.MousePos, hit_padding))
if (!window->OuterRectClipped.ContainsWithPad(pos, hit_padding))
continue;
// Support for one rectangular hole in any given window
@ -5249,21 +5251,30 @@ static void FindHoveredWindow()
{
ImVec2 hole_pos(window->Pos.x + (float)window->HitTestHoleOffset.x, window->Pos.y + (float)window->HitTestHoleOffset.y);
ImVec2 hole_size((float)window->HitTestHoleSize.x, (float)window->HitTestHoleSize.y);
if (ImRect(hole_pos, hole_pos + hole_size).Contains(g.IO.MousePos))
if (ImRect(hole_pos, hole_pos + hole_size).Contains(pos))
continue;
}
if (hovered_window == NULL)
if (find_first_and_in_any_viewport)
{
hovered_window = window;
IM_MSVC_WARNING_SUPPRESS(28182); // [Static Analyzer] Dereferencing NULL pointer.
if (hovered_window_ignoring_moving_window == NULL && (!g.MovingWindow || window->RootWindow != g.MovingWindow->RootWindow))
hovered_window_ignoring_moving_window = window;
if (hovered_window && hovered_window_ignoring_moving_window)
break;
}
else
{
if (hovered_window == NULL)
hovered_window = window;
IM_MSVC_WARNING_SUPPRESS(28182); // [Static Analyzer] Dereferencing NULL pointer.
if (hovered_window_under_moving_window == NULL && (!g.MovingWindow || window->RootWindow != g.MovingWindow->RootWindow))
hovered_window_under_moving_window = window;
if (hovered_window && hovered_window_under_moving_window)
break;
}
}
g.HoveredWindow = hovered_window;
g.HoveredWindowUnderMovingWindow = hovered_window_ignoring_moving_window;
*out_hovered_window = hovered_window;
if (out_hovered_window_under_moving_window != NULL)
*out_hovered_window_under_moving_window = hovered_window_under_moving_window;
}
bool ImGui::IsItemActive()

View File

@ -28,7 +28,7 @@
// Library Version
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345')
#define IMGUI_VERSION "1.90.7 WIP"
#define IMGUI_VERSION_NUM 19061
#define IMGUI_VERSION_NUM 19062
#define IMGUI_HAS_TABLE
/*

View File

@ -3065,6 +3065,7 @@ namespace ImGui
// NewFrame
IMGUI_API void UpdateInputEvents(bool trickle_fast_inputs);
IMGUI_API void UpdateHoveredWindowAndCaptureFlags();
IMGUI_API void FindHoveredWindowEx(const ImVec2& pos, bool find_first_and_in_any_viewport, ImGuiWindow** out_hovered_window, ImGuiWindow** out_hovered_window_under_moving_window);
IMGUI_API void StartMouseMovingWindow(ImGuiWindow* window);
IMGUI_API void UpdateMouseMovingWindowNewFrame();
IMGUI_API void UpdateMouseMovingWindowEndFrame();