From 8601c39571e4fccc66205e6d9e14f97ea4f93397 Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 5 Sep 2018 17:50:55 +0200 Subject: [PATCH] Viewport: Making the code a little more sturdy (flag changes) + added descriptions. (#1542) --- imgui.cpp | 37 +++++++++++++++++++------------------ imgui.h | 2 +- imgui_demo.cpp | 3 +++ imgui_internal.h | 1 + 4 files changed, 24 insertions(+), 19 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 5e96c68d..59d5eb03 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -7328,11 +7328,12 @@ static void ImGui::UpdateViewports() 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; + if (viewport == g.MouseLastHoveredViewport) + g.MouseLastHoveredViewport = NULL; g.Viewports.erase(g.Viewports.Data + n); // Destroy - if (viewport == g.MouseLastHoveredViewport) g.MouseLastHoveredViewport = NULL; - IM_ASSERT(viewport->RendererUserData == NULL && viewport->PlatformUserData == NULL && viewport->PlatformHandle == NULL); + DestroyPlatformWindow(viewport); // In most circumstances the platform window will already be destroyed here. IM_ASSERT(g.PlatformIO.Viewports.contains(viewport) == false); IM_DELETE(viewport); n--; @@ -7616,13 +7617,7 @@ void ImGui::UpdatePlatformWindows() destroy_platform_window |= (viewport->Window && !IsWindowActiveAndVisible(viewport->Window)); if (destroy_platform_window) { - if (viewport->CreatedPlatformWindow && g.PlatformIO.Renderer_DestroyWindow) - g.PlatformIO.Renderer_DestroyWindow(viewport); - if (viewport->CreatedPlatformWindow && g.PlatformIO.Platform_DestroyWindow) - g.PlatformIO.Platform_DestroyWindow(viewport); - viewport->CreatedPlatformWindow = false; - IM_ASSERT(viewport->RendererUserData == NULL); - IM_ASSERT(viewport->PlatformUserData == NULL && viewport->PlatformHandle == NULL); + DestroyPlatformWindow(viewport); continue; } if (viewport->LastFrameActive < g.FrameCount) @@ -7782,22 +7777,28 @@ void ImGui::RenderPlatformWindowsDefault(void* platform_render_arg, void* render } } +void ImGui::DestroyPlatformWindow(ImGuiViewportP* viewport) +{ + ImGuiContext& g = *GImGui; + if (viewport->CreatedPlatformWindow && g.PlatformIO.Renderer_DestroyWindow) + g.PlatformIO.Renderer_DestroyWindow(viewport); + if (viewport->CreatedPlatformWindow && g.PlatformIO.Platform_DestroyWindow) + g.PlatformIO.Platform_DestroyWindow(viewport); + viewport->CreatedPlatformWindow = false; + IM_ASSERT(viewport->RendererUserData == NULL); + IM_ASSERT(viewport->PlatformUserData == NULL && viewport->PlatformHandle == NULL); +} + void ImGui::DestroyPlatformWindows() { // We call the destroy window on the main viewport (index 0) to give a chance to the back-end to clear any data // have stored in e.g. PlatformHandle. - // It is expected that the back-end stored a flag to remember that it doesn't own the window created for the main viewport, - // and won't destroy the underlying platform/renderer data (e.g. + // It is expected that the back-end stored a flag to remember that it doesn't own the window created for the + // main viewport, and won't destroy the underlying platform/renderer data. ImGuiContext& g = *GImGui; for (int i = 0; i < g.Viewports.Size; i++) if (g.Viewports[i]->CreatedPlatformWindow) - { - if (g.PlatformIO.Renderer_DestroyWindow) - g.PlatformIO.Renderer_DestroyWindow(g.Viewports[i]); - if (g.PlatformIO.Platform_DestroyWindow) - g.PlatformIO.Platform_DestroyWindow(g.Viewports[i]); - g.Viewports[i]->CreatedPlatformWindow = false; - } + DestroyPlatformWindow(g.Viewports[i]); } //----------------------------------------------------------------------------- diff --git a/imgui.h b/imgui.h index eabf00d0..4fc2e05a 100644 --- a/imgui.h +++ b/imgui.h @@ -880,7 +880,7 @@ enum ImGuiConfigFlags_ // [BETA] Viewports ImGuiConfigFlags_ViewportsEnable = 1 << 10, // Viewport enable flags (require both ImGuiConfigFlags_PlatformHasViewports + ImGuiConfigFlags_RendererHasViewports set by the respective back-ends) ImGuiConfigFlags_ViewportsNoTaskBarIcons= 1 << 11, // Disable task bars icons for all secondary viewports (will set ImGuiViewportFlags_NoTaskBarIcon on them) - ImGuiConfigFlags_ViewportsNoMerge = 1 << 12, // All floating windows _always_ have create their own viewport and platform window. + ImGuiConfigFlags_ViewportsNoMerge = 1 << 12, // All floating windows will always create their own viewport and platform window. ImGuiConfigFlags_DpiEnableScaleViewports= 1 << 13, // FIXME-DPI: Reposition and resize imgui windows when the DpiScale of a viewport changed (mostly useful for the main viewport hosting other window). Note that resizing the main window itself is up to your application. ImGuiConfigFlags_DpiEnableScaleFonts = 1 << 14, // FIXME-DPI: Request bitmap-scaled fonts to match DpiScale. This is a very low-quality workaround. The correct way to handle DPI is _currently_ to replace the atlas and/or fonts in the Platform_OnChangedViewport callback, but this is all early work in progress. diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 29eef928..28ae9561 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -284,8 +284,11 @@ void ImGui::ShowDemoWindow(bool* p_open) ImGui::CheckboxFlags("io.ConfigFlags: NoMouseCursorChange", (unsigned int *)&io.ConfigFlags, ImGuiConfigFlags_NoMouseCursorChange); ImGui::SameLine(); ShowHelpMarker("Instruct back-end to not alter mouse cursor shape and visibility."); ImGui::CheckboxFlags("io.ConfigFlags: ViewportsEnable", (unsigned int *)&io.ConfigFlags, ImGuiConfigFlags_ViewportsEnable); + ImGui::SameLine(); ShowHelpMarker("Toggling this at runtime is normally unsupported (it will offset your windows)."); ImGui::CheckboxFlags("io.ConfigFlags: ViewportsNoTaskBarIcons", (unsigned int *)&io.ConfigFlags, ImGuiConfigFlags_ViewportsNoTaskBarIcons); + ImGui::SameLine(); ShowHelpMarker("Toggling this at runtime is normally unsupported (most platform back-ends won't refresh the task bar icon state right away)."); ImGui::CheckboxFlags("io.ConfigFlags: ViewportsNoMerge", (unsigned int *)&io.ConfigFlags, ImGuiConfigFlags_ViewportsNoMerge); + ImGui::SameLine(); ShowHelpMarker("All floating windows will always create their own viewport and platform window."); ImGui::Checkbox("io.ConfigInputTextCursorBlink", &io.ConfigInputTextCursorBlink); ImGui::SameLine(); ShowHelpMarker("Set to false to disable blinking cursor, for users who consider it distracting"); ImGui::Checkbox("io.ConfigResizeWindowsFromEdges [beta]", &io.ConfigResizeWindowsFromEdges); diff --git a/imgui_internal.h b/imgui_internal.h index f742896f..a524bca0 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1199,6 +1199,7 @@ namespace ImGui // Viewports IMGUI_API ImGuiViewportP* FindViewportByID(ImGuiID id); IMGUI_API void ScaleWindowsInViewport(ImGuiViewportP* viewport, float scale); + IMGUI_API void DestroyPlatformWindow(ImGuiViewportP* viewport); IMGUI_API void ShowViewportThumbnails(); // Settings