From 7b4fbf43013989af3af9875284be5dd71fa3bd7a Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 17 Jul 2018 16:37:10 +0200 Subject: [PATCH] Viewport: Removed the need for the back-end to fill io.MousePosViewport, it seems unnecessary at this point. (#1542) --- examples/imgui_impl_glfw.cpp | 2 -- examples/imgui_impl_sdl.cpp | 4 ---- examples/imgui_impl_win32.cpp | 5 +---- imgui.cpp | 6 ++++-- imgui.h | 1 - imgui_demo.cpp | 1 - imgui_internal.h | 2 +- 7 files changed, 6 insertions(+), 15 deletions(-) diff --git a/examples/imgui_impl_glfw.cpp b/examples/imgui_impl_glfw.cpp index 1acccd0c..bb72dfb7 100644 --- a/examples/imgui_impl_glfw.cpp +++ b/examples/imgui_impl_glfw.cpp @@ -207,7 +207,6 @@ static void ImGui_ImplGlfw_UpdateMousePosAndButtons() ImGuiIO& io = ImGui::GetIO(); const ImVec2 mouse_pos_backup = io.MousePos; io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); - io.MousePosViewport = 0; io.MouseHoveredViewport = 0; // Update buttons @@ -236,7 +235,6 @@ static void ImGui_ImplGlfw_UpdateMousePosAndButtons() glfwGetCursorPos(window, &mouse_x, &mouse_y); io.MousePos = ImVec2((float)mouse_x + viewport->Pos.x, (float)mouse_y + viewport->Pos.y); } - io.MousePosViewport = viewport->ID; for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) io.MouseDown[i] |= glfwGetMouseButton(window, i) != 0; } diff --git a/examples/imgui_impl_sdl.cpp b/examples/imgui_impl_sdl.cpp index c9e81ead..1fd766ab 100644 --- a/examples/imgui_impl_sdl.cpp +++ b/examples/imgui_impl_sdl.cpp @@ -233,7 +233,6 @@ static void ImGui_ImplSDL2_UpdateMousePosAndButtons() ImGuiIO& io = ImGui::GetIO(); const ImVec2 mouse_pos_backup = io.MousePos; io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); - io.MousePosViewport = 0; io.MouseHoveredViewport = 0; // Set OS mouse position if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user) @@ -268,10 +267,7 @@ static void ImGui_ImplSDL2_UpdateMousePosAndButtons() my -= wy; } if (ImGuiViewport* viewport = ImGui::FindViewportByPlatformHandle((void*)focused_window)) - { io.MousePos = ImVec2(viewport->Pos.x + (float)mx, viewport->Pos.y + (float)my); - io.MousePosViewport = viewport->ID; - } // We already retrieve global mouse position, SDL_CaptureMouse() also let the OS know e.g. that our imgui drag outside the SDL window boundaries shouldn't trigger the OS window resize cursor // The function is only supported from SDL 2.0.4 (released Jan 2016) diff --git a/examples/imgui_impl_win32.cpp b/examples/imgui_impl_win32.cpp index cdcd751f..60785639 100644 --- a/examples/imgui_impl_win32.cpp +++ b/examples/imgui_impl_win32.cpp @@ -137,8 +137,7 @@ static bool ImGui_ImplWin32_UpdateMouseCursor() // B) In Multi-viewport mode imgui needs: (when ImGuiConfigFlags_ViewportsEnable is set) // - io.MousePos ............... mouse position, in OS absolute coordinates (what you'd get from GetCursorPos(), or from WM_MOUSEMOVE+viewport->Pos). // io.MousePos is (0,0) when the mouse is on the upper-left of the primary monitor. -// - io.MousePosViewport ....... viewport which mouse position is based from (generally the focused/active/capturing viewport) -// - io.MouseHoveredViewport ... [optional] viewport which mouse is hovering, with _very_ specific/strict conditions (Read comments next to io.MouseHoveredViewport. This is _NOT_ easy to provide in many high-level engine because of how we handle the ImGuiViewportFlags_NoInputs flag) +// - io.MouseHoveredViewport ... [optional] viewport which mouse is hovering, with _VERY_ specific and strict conditions (Read comments next to io.MouseHoveredViewport. This is _NOT_ easy to provide in many high-level engine because of how we use the ImGuiViewportFlags_NoInputs flag) static void ImGui_ImplWin32_UpdateMousePos() { ImGuiIO& io = ImGui::GetIO(); @@ -154,7 +153,6 @@ static void ImGui_ImplWin32_UpdateMousePos() } io.MousePos = ImVec2(-FLT_MAX, -FLT_MAX); - io.MousePosViewport = 0; io.MouseHoveredViewport = 0; // Set mouse position and viewport @@ -168,7 +166,6 @@ static void ImGui_ImplWin32_UpdateMousePos() POINT client_pos = pos; ::ScreenToClient(focused_hwnd, &client_pos); io.MousePos = ImVec2(viewport->Pos.x + (float)client_pos.x, viewport->Pos.y + (float)client_pos.y); - io.MousePosViewport = viewport->ID; } // Our back-end can tell which window is under the mouse cursor (not every back-end can), so pass that info to imgui diff --git a/imgui.cpp b/imgui.cpp index 4fae6cd4..d6ab51b2 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3912,13 +3912,15 @@ static void ImGui::UpdateViewports() } if (viewport_hovered != NULL) g.MouseLastHoveredViewport = viewport_hovered; + else if (g.MouseLastHoveredViewport == NULL) + g.MouseLastHoveredViewport = g.Viewports[0]; // Update mouse reference viewport // (when moving a window we aim at its viewport, but this will be overwritten below if we go in drag and drop mode) if (g.MovingWindow) g.MouseViewport = g.MovingWindow->Viewport; else - g.MouseViewport = g.IO.MousePosViewport ? FindViewportByID(g.IO.MousePosViewport) : g.Viewports[0]; + g.MouseViewport = g.MouseLastHoveredViewport; // When dragging something, always refer to the last hovered viewport. // - when releasing a moving window we will revert to aiming behind (at viewport_hovered) @@ -15165,7 +15167,7 @@ void ImGui::ShowMetricsWindow(bool* p_open) ImGui::Text("NavDisableHighlight: %d, NavDisableMouseHover: %d", g.NavDisableHighlight, g.NavDisableMouseHover); ImGui::Text("NavWindowingTarget: '%s'", g.NavWindowingTarget ? g.NavWindowingTarget->Name : "NULL"); ImGui::Text("DragDrop: %d, SourceId = 0x%08X, Payload \"%s\" (%d bytes)", g.DragDropActive, g.DragDropPayload.SourceId, g.DragDropPayload.DataType, g.DragDropPayload.DataSize); - ImGui::Text("MousePosViewport: 0x%08X, Hovered: 0x%08X -> Ref 0x%08X", g.IO.MousePosViewport, g.IO.MouseHoveredViewport, g.MouseViewport->ID); + ImGui::Text("MouseViewport: 0x%08X (UserHovered 0x%08X, LastHovered 0x%08X)", g.MouseViewport->ID, g.IO.MouseHoveredViewport, g.MouseLastHoveredViewport->ID); ImGui::TreePop(); } diff --git a/imgui.h b/imgui.h index 69f1b631..458e6c87 100644 --- a/imgui.h +++ b/imgui.h @@ -1144,7 +1144,6 @@ struct ImGuiIO bool MouseDown[5]; // Mouse buttons: 0=left, 1=right, 2=middle + extras. ImGui itself mostly only uses left button (BeginPopupContext** are using right button). Others buttons allows us to track if the mouse is being used by your application + available to user as a convenience via IsMouse** API. float MouseWheel; // Mouse wheel Vertical: 1 unit scrolls about 5 lines text. float MouseWheelH; // Mouse wheel Horizontal. Most users don't have a mouse with an horizontal wheel, may not be filled by all back-ends. - ImGuiID MousePosViewport; // (Optional) When using multiple viewports: viewport from which io.MousePos is based from (when dragging this is generally the captured/focused viewport, even though we can drag outside of it and then it's not hovered anymore). (0 == default viewport) ImGuiID MouseHoveredViewport; // (Optional) When using multiple viewports: viewport the OS mouse cursor is hovering _IGNORING_ viewports with the ImGuiViewportFlags_NoInputs flag, and _REGARDLESS_ of whether another viewport is focused. Set io.BackendFlags |= ImGuiBackendFlags_HasMouseHoveredViewport if you can provide this info. If you don't imgui will use a decent heuristic instead. bool MouseDrawCursor; // Request ImGui to draw a mouse cursor for you (if you are on a platform without a mouse cursor). bool KeyCtrl; // Keyboard modifier pressed: Control diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 6f1da63e..277841b0 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -2133,7 +2133,6 @@ void ImGui::ShowDemoWindow(bool* p_open) ImGui::Text("Mouse dbl-clicked:"); for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) if (ImGui::IsMouseDoubleClicked(i)) { ImGui::SameLine(); ImGui::Text("b%d", i); } ImGui::Text("Mouse released:"); for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) if (ImGui::IsMouseReleased(i)) { ImGui::SameLine(); ImGui::Text("b%d", i); } ImGui::Text("Mouse wheel: %.1f", io.MouseWheel); - ImGui::Text("Mouse viewport: Ref 0x%08X Hovered 0x%08X", io.MousePosViewport, io.MouseHoveredViewport); ImGui::Text("Keys down:"); for (int i = 0; i < IM_ARRAYSIZE(io.KeysDown); i++) if (io.KeysDownDuration[i] >= 0.0f) { ImGui::SameLine(); ImGui::Text("%d (%.02f secs)", i, io.KeysDownDuration[i]); } ImGui::Text("Keys pressed:"); for (int i = 0; i < IM_ARRAYSIZE(io.KeysDown); i++) if (ImGui::IsKeyPressed(i)) { ImGui::SameLine(); ImGui::Text("%d", i); } diff --git a/imgui_internal.h b/imgui_internal.h index 73765345..7c7bc76a 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -701,7 +701,7 @@ struct ImGuiContext ImVector Viewports; // Active viewports (always 1+, and generally 1 unless multi-viewports are enabled). Each viewports hold their copy of ImDrawData. ImGuiViewportP* CurrentViewport; // We track changes of viewport (happening in Begin) so we can call Platform_OnChangedViewport() ImGuiViewportP* MouseViewport; - ImGuiViewportP* MouseLastHoveredViewport; // Last known viewport that was hovered by mouse (even if we are not hovering any viewport any more) + ImGuiViewportP* MouseLastHoveredViewport; // Last known viewport that was hovered by mouse (even if we are not hovering any viewport any more) + honoring the _NoInputs flag. ImGuiID PlatformLastFocusedViewport; // Record of last focused platform window/viewport, when this changes we stamp the viewport as front-most // Navigation data (for gamepad/keyboard)