From c93e92671a796d5957ee81ff1efdc1627b1356d6 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 26 Nov 2018 16:55:40 +0100 Subject: [PATCH 1/3] Viewport: Fixes moving child menu viewport (fix 379733a). --- imgui.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 7b672a2d..ddacebe4 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -7503,16 +7503,22 @@ static void ImGui::UpdateSelectWindowViewport(ImGuiWindow* window) window->Viewport = main_viewport; // Mark window as allowed to protrude outside of its viewport and into the current monitor - // We need to take account of the possibility that mouse may become invalid. if (flags & (ImGuiWindowFlags_Tooltip | ImGuiWindowFlags_Popup)) { + // We need to take account of the possibility that mouse may become invalid. + // Popups/Tooltip always set ViewportAllowPlatformMonitorExtend so GetWindowAllowedExtentRect() will return full monitor bounds. ImVec2 mouse_ref = (flags & ImGuiWindowFlags_Tooltip) ? g.IO.MousePos : g.CurrentPopupStack.back().OpenMousePos; bool use_mouse_ref = (g.NavDisableHighlight || !g.NavDisableMouseHover || !g.NavWindow); bool mouse_valid = IsMousePosValid(&mouse_ref); if ((window->Appearing || (flags & ImGuiWindowFlags_Tooltip)) && (!use_mouse_ref || mouse_valid)) window->ViewportAllowPlatformMonitorExtend = FindPlatformMonitorForPos((use_mouse_ref && mouse_valid) ? mouse_ref : NavCalcPreferredRefPos()); + else + window->ViewportAllowPlatformMonitorExtend = window->Viewport->PlatformMonitor; } - if (window->ViewportAllowPlatformMonitorExtend < 0 && (flags & ImGuiWindowFlags_ChildWindow) == 0) + + // Regular (non-child, non-popup) windows by default are also allowed to protrude + // Child windows are kept contained within their parent. + else if (window->ViewportAllowPlatformMonitorExtend < 0 && (flags & ImGuiWindowFlags_ChildWindow) == 0) window->ViewportAllowPlatformMonitorExtend = window->Viewport->PlatformMonitor; // Update flags From 12a1e7d04ecc758c4e44515d1887b964e795d652 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 26 Nov 2018 19:20:37 +0100 Subject: [PATCH 2/3] Viewport: Comment to suggest making WindowBg opaque when viewports are enabled. --- examples/example_glfw_opengl3/main.cpp | 5 ++++- examples/example_sdl_opengl3/main.cpp | 4 ++++ examples/example_win32_directx11/main.cpp | 5 ++++- imgui.h | 1 + 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/examples/example_glfw_opengl3/main.cpp b/examples/example_glfw_opengl3/main.cpp index 325c46b8..93dcead5 100644 --- a/examples/example_glfw_opengl3/main.cpp +++ b/examples/example_glfw_opengl3/main.cpp @@ -97,10 +97,13 @@ int main(int, char**) ImGui_ImplOpenGL3_Init(glsl_version); // Setup Style - ImGui::GetStyle().WindowRounding = 0.0f; ImGui::StyleColorsDark(); //ImGui::StyleColorsClassic(); + ImGuiStyle& style = ImGui::GetStyle(); + style.WindowRounding = 0.0f; // When viewports are enabled it is preferable to disable WinodwRounding + style.Colors[ImGuiCol_WindowBg].w = 1.0f; // When viewports are enabled it is preferable to disable WindowBg alpha + // Load Fonts // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. diff --git a/examples/example_sdl_opengl3/main.cpp b/examples/example_sdl_opengl3/main.cpp index 2a9ccec9..93a49a10 100644 --- a/examples/example_sdl_opengl3/main.cpp +++ b/examples/example_sdl_opengl3/main.cpp @@ -91,6 +91,10 @@ int main(int, char**) ImGui::StyleColorsDark(); //ImGui::StyleColorsClassic(); + ImGuiStyle& style = ImGui::GetStyle(); + style.WindowRounding = 0.0f; // When viewports are enabled it is preferable to disable WinodwRounding + style.Colors[ImGuiCol_WindowBg].w = 1.0f; // When viewports are enabled it is preferable to disable WindowBg alpha + // Load Fonts // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. diff --git a/examples/example_win32_directx11/main.cpp b/examples/example_win32_directx11/main.cpp index 93cb137f..6346885d 100644 --- a/examples/example_win32_directx11/main.cpp +++ b/examples/example_win32_directx11/main.cpp @@ -145,10 +145,13 @@ int main(int, char**) ImGui_ImplDX11_Init(g_pd3dDevice, g_pd3dDeviceContext); // Setup Style - ImGui::GetStyle().WindowRounding = 0.0f; ImGui::StyleColorsDark(); //ImGui::StyleColorsClassic(); + ImGuiStyle& style = ImGui::GetStyle(); + style.WindowRounding = 0.0f; // When viewports are enabled it is preferable to disable WinodwRounding + style.Colors[ImGuiCol_WindowBg].w = 1.0f; // When viewports are enabled it is preferable to disable WindowBg alpha + // Load Fonts // - If no fonts are loaded, dear imgui will use the default font. You can also load multiple fonts and use ImGui::PushFont()/PopFont() to select them. // - AddFontFromFileTTF() will return the ImFont* so you can store it if you need to select the font among multiple. diff --git a/imgui.h b/imgui.h index 594f5720..a2ee80fe 100644 --- a/imgui.h +++ b/imgui.h @@ -891,6 +891,7 @@ enum ImGuiConfigFlags_ ImGuiConfigFlags_NoMouseCursorChange = 1 << 5, // Instruct back-end to not alter mouse cursor shape and visibility. Use if the back-end cursor changes are interfering with yours and you don't want to use SetMouseCursor() to change mouse cursor. You may want to honor requests from imgui by reading GetMouseCursor() yourself instead. // [BETA] Viewports + // When using viewports it is recommended that your default value for ImGuiCol_WindowBg is opaque (Alpha=1.0) so transition to a viewport won't be noticeable. ImGuiConfigFlags_ViewportsEnable = 1 << 10, // Viewport enable flags (require both ImGuiConfigFlags_PlatformHasViewports + ImGuiConfigFlags_RendererHasViewports set by the respective back-ends) ImGuiConfigFlags_ViewportsNoTaskBarIcon = 1 << 11, // Disable task bars icons for all secondary viewports (will set ImGuiViewportFlags_NoTaskBarIcon on them) ImGuiConfigFlags_ViewportsNoMerge = 1 << 12, // All floating windows will always create their own viewport and platform window. From 1a0d2578a1776366b124227172c894f8d6ec99e2 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 26 Nov 2018 21:35:44 +0100 Subject: [PATCH 3/3] Viewport: Merging fixes + relying on multiple viewport overlaps. Follow-up to previous attempts are reworking the split/merge mechanisms. (#1542) --- imgui.cpp | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index ddacebe4..a7b9faf2 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -969,7 +969,7 @@ const ImGuiID IMGUI_VIEWPORT_DEFAULT_ID = 0x11111111; // Using an arbi static ImGuiViewportP* AddUpdateViewport(ImGuiWindow* window, ImGuiID id, const ImVec2& platform_pos, const ImVec2& size, ImGuiViewportFlags flags); static void UpdateViewports(); static void UpdateSelectWindowViewport(ImGuiWindow* window); -static void UpdateTryMergeWindowIntoHostViewport(ImGuiWindow* window, ImGuiViewportP* host_viewport); +static bool UpdateTryMergeWindowIntoHostViewport(ImGuiWindow* window, ImGuiViewportP* host_viewport); static void SetCurrentViewport(ImGuiWindow* window, ImGuiViewportP* viewport); static bool GetWindowAlwaysWantOwnViewport(ImGuiWindow* window); static int FindPlatformMonitorForPos(const ImVec2& pos); @@ -7182,15 +7182,25 @@ static bool ImGui::GetWindowAlwaysWantOwnViewport(ImGuiWindow* window) return false; } -static void ImGui::UpdateTryMergeWindowIntoHostViewport(ImGuiWindow* window, ImGuiViewportP* viewport) +static bool ImGui::UpdateTryMergeWindowIntoHostViewport(ImGuiWindow* window, ImGuiViewportP* viewport) { ImGuiContext& g = *GImGui; if (!(viewport->Flags & ImGuiViewportFlags_CanHostOtherWindows) || window->Viewport == viewport || viewport->PlatformIsMinimized) - return; + return false; if (!viewport->GetRect().Contains(window->Rect())) - return; + return false; if (GetWindowAlwaysWantOwnViewport(window)) - return; + return false; + + for (int n = 0; n < g.Windows.Size; n++) + { + ImGuiWindow* window_behind = g.Windows[n]; + if (window_behind == window) + break; + if (window_behind->WasActive && window_behind->ViewportOwned && !(window_behind->Flags & ImGuiWindowFlags_ChildWindow)) + if (window_behind->Viewport->GetRect().Overlaps(window->Rect())) + return false; + } // Move to the existing viewport, Move child/hosted windows as well (FIXME-OPT: iterate child) ImGuiViewportP* old_viewport = window->Viewport; @@ -7200,6 +7210,8 @@ static void ImGui::UpdateTryMergeWindowIntoHostViewport(ImGuiWindow* window, ImG SetWindowViewport(g.Windows[n], viewport); SetWindowViewport(window, viewport); BringWindowToDisplayFront(window); + + return true; } // Scale all windows (position, size). Use when e.g. changing DPI. (This is a lossy operation!) @@ -7262,7 +7274,10 @@ static void ImGui::UpdateViewports() // Clear references to this viewport in windows (window->ViewportId becomes the master data) for (int window_n = 0; window_n < g.Windows.Size; window_n++) if (g.Windows[window_n]->Viewport == viewport) + { g.Windows[window_n]->Viewport = NULL; + g.Windows[window_n]->ViewportOwned = false; + } if (viewport == g.MouseLastHoveredViewport) g.MouseLastHoveredViewport = NULL; g.Viewports.erase(g.Viewports.Data + n); @@ -7447,8 +7462,9 @@ static void ImGui::UpdateSelectWindowViewport(ImGuiWindow* window) } // Merge into host viewport + bool try_to_merge_into_host_viewport = false; if (window->ViewportOwned && g.ActiveId == 0) - UpdateTryMergeWindowIntoHostViewport(window, g.Viewports[0]); + try_to_merge_into_host_viewport = true; window->ViewportOwned = false; // Appearing popups reset their viewport so they can inherit again @@ -7479,7 +7495,7 @@ static void ImGui::UpdateSelectWindowViewport(ImGuiWindow* window) window->Viewport = FindViewportByID(g.NextWindowData.ViewportId); window->ViewportId = g.NextWindowData.ViewportId; // Store ID even if Viewport isn't resolved yet. } - else if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_ChildMenu)) + else if ((flags & ImGuiWindowFlags_ChildWindow) || (flags & ImGuiWindowFlags_ChildMenu)) { // Always inherit viewport from parent window window->Viewport = window->ParentWindow->Viewport; @@ -7497,6 +7513,11 @@ static void ImGui::UpdateSelectWindowViewport(ImGuiWindow* window) if (window->Viewport != NULL && window->Viewport->Window == window) window->Viewport = AddUpdateViewport(window, window->ID, window->Pos, window->Size, ImGuiViewportFlags_None); } + else + { + if (try_to_merge_into_host_viewport) + UpdateTryMergeWindowIntoHostViewport(window, g.Viewports[0]); + } // Fallback to default viewport if (window->Viewport == NULL)