From 0d16492eb787db77e9609a549af7c1cc1ea4d9d4 Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 16 Apr 2018 10:47:33 +0200 Subject: [PATCH] Viewport: Moved ImGuiWindowFlags_FullViewport to an internal ViewportOwned flag. Renamed AddViewport to AddUpdateViewport. (#Viewport: Shuffled code in Begin to reset size of reappearing popups prior to selecting viewport, to avoid mistakenly using an old size. Moved code out of UpdateSelectWindowViewport() to the section of Begin where positions is being locked down, to avoid code in-between duplicating this. (#1542)) --- imgui.cpp | 57 +++++++++++++++++++++++++----------------------- imgui.h | 3 +-- imgui_internal.h | 3 ++- 3 files changed, 33 insertions(+), 30 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index e3321ef8..8cea73d5 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -766,7 +766,7 @@ const ImGuiID IMGUI_VIEWPORT_DEFAULT_ID = 0x11111111; // Using an arbi static inline ImRect GetViewportRect(ImGuiWindow* window) { return window->Viewport->GetRect(); } static inline ImVec2 ConvertViewportPosToPlatformPos(const ImVec2& imgui_pos, ImGuiViewport* viewport) { return imgui_pos - viewport->Pos + viewport->PlatformPos; } static inline ImVec2 ConvertPlatformPosToViewportPos(const ImVec2& platform_pos, ImGuiViewport* viewport) { return platform_pos - viewport->PlatformPos + viewport->Pos; } -static ImGuiViewportP* AddViewport(ImGuiWindow* window, ImGuiID id, ImGuiViewportFlags flags, const ImVec2& platform_pos, const ImVec2& size); +static ImGuiViewportP* AddUpdateViewport(ImGuiWindow* window, ImGuiID id, ImGuiViewportFlags flags, const ImVec2& platform_pos, const ImVec2& size); static void UpdateViewports(); static void UpdateSelectWindowViewport(ImGuiWindow* window); static void SetCurrentViewport(ImGuiViewportP* viewport); @@ -1948,8 +1948,9 @@ ImGuiWindow::ImGuiWindow(ImGuiContext* context, const char* name) Scroll = ImVec2(0.0f, 0.0f); ScrollTarget = ImVec2(FLT_MAX, FLT_MAX); ScrollTargetCenterRatio = ImVec2(0.5f, 0.5f); - ScrollbarX = ScrollbarY = false; ScrollbarSizes = ImVec2(0.0f, 0.0f); + ScrollbarX = ScrollbarY = false; + ViewportOwned = false; Active = WasActive = false; WriteAccessed = false; Collapsed = false; @@ -3313,24 +3314,25 @@ static void ImGui::NewFrameUpdateMovingWindowDropViewport(ImGuiWindow* window) ImRect mouse_viewport_rect = g.MousePosViewport->GetRect(); ImVec2 window_pos_in_mouse_viewport = ConvertPlatformPosToViewportPos(ConvertViewportPosToPlatformPos(window->Pos, window->Viewport), g.MousePosViewport); ImRect window_rect_in_mouse_viewport = ImRect(window_pos_in_mouse_viewport, window_pos_in_mouse_viewport + window->Size); - if ((g.MousePosViewport->Flags & ImGuiViewportFlags_CanHostOtherWindows) && mouse_viewport_rect.Contains(window_rect_in_mouse_viewport)) + if ((g.MousePosViewport->Flags & ImGuiViewportFlags_CanHostOtherWindows) && mouse_viewport_rect.Contains(window_rect_in_mouse_viewport)) { // Drop on an existing viewport ImGuiViewportP* old_viewport = window->Viewport; SetWindowViewportTranslateToPreservePlatformPos(window, window->Viewport, g.MousePosViewport); - // Our current scheme allow any window to land on a viewport, so when that viewport merges, move other windows as well - // FIXME-OPT - if (window->Flags & ImGuiWindowFlags_FullViewport) + // Move child/hosted windows as well (FIXME-OPT) + if (window->ViewportOwned) for (int n = 0; n < g.Windows.Size; n++) if (g.Windows[n]->Viewport == old_viewport) SetWindowViewportTranslateToPreservePlatformPos(g.Windows[n], old_viewport, g.MousePosViewport); + window->ViewportOwned = false; } else { // Create/persist new viewport ImVec2 platform_pos = ConvertViewportPosToPlatformPos(window->Pos, window->Viewport); - ImGuiViewportP* viewport = AddViewport(window, window->ID, 0, platform_pos, window->Size); + ImGuiViewportP* viewport = AddUpdateViewport(window, window->ID, 0, platform_pos, window->Size); + IM_ASSERT(viewport == window->Viewport); SetWindowViewportTranslateToPreservePlatformPos(window, window->Viewport, viewport); } } @@ -3476,7 +3478,7 @@ static void ImGui::UpdateViewports() ImVec2 main_viewport_platform_pos = ImVec2(0.0f, 0.0f); if ((g.IO.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)) main_viewport_platform_pos = g.PlatformIO.Platform_GetWindowPos(main_viewport); - AddViewport(NULL, IMGUI_VIEWPORT_DEFAULT_ID, ImGuiViewportFlags_CanHostOtherWindows, main_viewport_platform_pos, g.IO.DisplaySize); + AddUpdateViewport(NULL, IMGUI_VIEWPORT_DEFAULT_ID, ImGuiViewportFlags_CanHostOtherWindows, main_viewport_platform_pos, g.IO.DisplaySize); if (!(g.IO.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)) { @@ -4699,7 +4701,7 @@ void ImGui::SetCurrentViewport(ImGuiViewportP* viewport) g.PlatformIO.Platform_OnChangedViewport(g.CurrentViewport); } -ImGuiViewportP* ImGui::AddViewport(ImGuiWindow* window, ImGuiID id, ImGuiViewportFlags flags, const ImVec2& platform_pos, const ImVec2& size) +ImGuiViewportP* ImGui::AddUpdateViewport(ImGuiWindow* window, ImGuiID id, ImGuiViewportFlags flags, const ImVec2& platform_pos, const ImVec2& size) { ImGuiContext& g = *GImGui; IM_ASSERT(id != 0); @@ -4733,6 +4735,9 @@ ImGuiViewportP* ImGui::AddViewport(ImGuiWindow* window, ImGuiID id, ImGuiViewpor viewport->PlatformPos = platform_pos; viewport->LastFrameActive = g.FrameCount; + if (window != NULL) + window->ViewportOwned = true; + // Request an initial DpiScale before the OS platform window creation // This is so we can select an appropriate font size on the first frame of our window lifetime if (g.PlatformIO.Platform_GetWindowDpiScale) @@ -6070,7 +6075,7 @@ static ImVec2 CalcSizeAutoFit(ImGuiWindow* window, const ImVec2& size_contents) else { // When the window cannot fit all contents (either because of constraints, either because screen is too small): we are growing the size on the other axis to compensate for expected scrollbar. FIXME: Might turn bigger than ViewportSize-WindowPadding. - ImVec2 viewport_size = (window->Flags & ImGuiWindowFlags_FullViewport) ? ImVec2(FLT_MAX, FLT_MAX) : window->Viewport->Size; + ImVec2 viewport_size = window->ViewportOwned ? ImVec2(FLT_MAX, FLT_MAX) : window->Viewport->Size; size_auto_fit = ImClamp(size_contents, style.WindowMinSize, ImMax(style.WindowMinSize, viewport_size - g.Style.DisplaySafeAreaPadding)); ImVec2 size_auto_fit_after_constraint = CalcSizeAfterConstraint(window, size_auto_fit); if (size_auto_fit_after_constraint.x < size_contents.x && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar)) @@ -6156,6 +6161,7 @@ static void ImGui::UpdateSelectWindowViewport(ImGuiWindow* window) { ImGuiContext& g = *GImGui; ImGuiWindowFlags flags = window->Flags; + window->ViewportOwned = false; // Restore main viewport if multi-viewport is not supported by the back-end ImGuiViewportP* main_viewport = g.Viewports[0]; @@ -6186,8 +6192,7 @@ static void ImGui::UpdateSelectWindowViewport(ImGuiWindow* window) window->Viewport = FindViewportByID(window->ViewportId); if (window->Viewport == NULL && window->ViewportPlatformPos.x != FLT_MAX && window->ViewportPlatformPos.y != FLT_MAX) { - ImGuiViewportP* viewport = AddViewport(window, window->ID, ImGuiViewportFlags_NoDecoration, window->ViewportPlatformPos, window->Size); - window->Flags |= ImGuiWindowFlags_FullViewport; + ImGuiViewportP* viewport = AddUpdateViewport(window, window->ID, ImGuiViewportFlags_NoDecoration, window->ViewportPlatformPos, window->Size); window->Viewport = viewport; created_viewport = true; } @@ -6213,8 +6218,7 @@ static void ImGui::UpdateSelectWindowViewport(ImGuiWindow* window) // Calculate mouse position in OS/platform coordinates, create a Viewport at this position. ImVec2 platform_pos = ConvertViewportPosToPlatformPos(g.IO.MousePos - g.ActiveIdClickOffset, g.MousePosViewport); ImGuiViewportFlags viewport_flags = ImGuiViewportFlags_NoDecoration | ImGuiViewportFlags_NoFocusOnAppearing | ImGuiViewportFlags_NoInputs; - ImGuiViewportP* viewport = AddViewport(window, window->ID, viewport_flags, platform_pos, window->Size); - window->Flags |= ImGuiWindowFlags_FullViewport; + ImGuiViewportP* viewport = AddUpdateViewport(window, window->ID, viewport_flags, platform_pos, window->Size); window->Viewport = viewport; created_viewport = true; } @@ -6239,14 +6243,14 @@ static void ImGui::UpdateSelectWindowViewport(ImGuiWindow* window) if (!window->Viewport->PlatformRequestResize) window->Viewport->Size = window->Size; window->Viewport->PlatformPos = ConvertViewportPosToPlatformPos(window->Pos, window->Viewport); - window->Flags |= ImGuiWindowFlags_FullViewport; + window->ViewportOwned = true; } // If the OS window has a title bar, hide our imgui title bar - if ((window->Flags & ImGuiWindowFlags_FullViewport) && !(window->Viewport->Flags & ImGuiViewportFlags_NoDecoration)) + if (window->ViewportOwned && !(window->Viewport->Flags & ImGuiViewportFlags_NoDecoration)) window->Flags |= ImGuiWindowFlags_NoTitleBar; - if (window->Flags & ImGuiWindowFlags_FullViewport) + if (window->ViewportOwned) { // We currently have window fully covering a viewport and we disable WindowBg alpha, so clearing is not necessary window->Viewport->Flags |= ImGuiViewportFlags_NoRendererClear; @@ -6386,7 +6390,7 @@ static void ImGui::UpdateManualResize(ImGuiWindow* window, const ImVec2& size_au } if (pos_target.x != FLT_MAX) { - if (window->Flags & ImGuiWindowFlags_FullViewport) + if (window->ViewportOwned) window->Viewport->PlatformPos = ConvertViewportPosToPlatformPos(ImFloor(pos_target), window->Viewport); else window->Pos = window->PosFloat = ImFloor(pos_target); @@ -6557,7 +6561,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Lock window rounding, border size and padding for the frame (so that altering them doesn't cause inconsistencies) window->WindowRounding = (flags & ImGuiWindowFlags_ChildWindow) ? style.ChildRounding : ((flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiWindowFlags_Modal)) ? style.PopupRounding : style.WindowRounding; - if (window->Flags & ImGuiWindowFlags_FullViewport) + if (window->ViewportOwned) window->WindowRounding = 0.0f; window->WindowBorderSize = (flags & ImGuiWindowFlags_ChildWindow) ? style.ChildBorderSize : ((flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_Tooltip)) && !(flags & ImGuiWindowFlags_Modal)) ? style.PopupBorderSize : style.WindowBorderSize; window->WindowPadding = style.WindowPadding; @@ -6683,7 +6687,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // Clamp position so window stays visible within its viewport // Ignore zero-sized display explicitly to avoid losing positions if a window manager reports zero-sized window when initializing or minimizing. ImRect viewport_rect(GetViewportRect(window)); - if (!window_pos_set_by_api && !(flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Tooltip | ImGuiWindowFlags_FullViewport)) && window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0) + if (!window_pos_set_by_api && !(flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Tooltip)) && !window->ViewportOwned && window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0) if (viewport_rect.GetWidth() > 0 && viewport_rect.GetHeight() > 0.0f) { ImVec2 padding = ImMax(style.DisplayWindowPadding, style.DisplaySafeAreaPadding); @@ -6724,12 +6728,11 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // When a window is marked as owning its viewport, we immediately update the viewport after a resize window->ViewportPlatformPos = window->Viewport->PlatformPos; - if (flags & ImGuiWindowFlags_FullViewport) - if (window->Size.x != window->Viewport->Size.x || window->Size.y != window->Viewport->Size.y) - { - window->Viewport->Size = window->SizeFull; - viewport_rect = GetViewportRect(window); - } + if (window->ViewportOwned && (window->Size.x != window->Viewport->Size.x || window->Size.y != window->Viewport->Size.y)) + { + window->Viewport->Size = window->SizeFull; + viewport_rect = GetViewportRect(window); + } // DRAWING @@ -6780,7 +6783,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) ImU32 bg_col = GetColorU32(GetWindowBgColorIdxFromFlags(flags)); if (g.NextWindowData.BgAlphaCond != 0) bg_col = (bg_col & ~IM_COL32_A_MASK) | (IM_F32_TO_INT8_SAT(g.NextWindowData.BgAlphaVal) << IM_COL32_A_SHIFT); - if (window->Flags & ImGuiWindowFlags_FullViewport) + if (window->ViewportOwned) bg_col = (bg_col | IM_COL32_A_MASK); window->DrawList->AddRectFilled(window->Pos+ImVec2(0,window->TitleBarHeight()), window->Pos+window->Size, bg_col, window_rounding, (flags & ImGuiWindowFlags_NoTitleBar) ? ImDrawCornerFlags_All : ImDrawCornerFlags_Bot); diff --git a/imgui.h b/imgui.h index 2b4d8871..9b9a3d98 100644 --- a/imgui.h +++ b/imgui.h @@ -593,8 +593,7 @@ enum ImGuiWindowFlags_ ImGuiWindowFlags_Tooltip = 1 << 25, // Don't use! For internal use by BeginTooltip() ImGuiWindowFlags_Popup = 1 << 26, // Don't use! For internal use by BeginPopup() ImGuiWindowFlags_Modal = 1 << 27, // Don't use! For internal use by BeginPopupModal() - ImGuiWindowFlags_ChildMenu = 1 << 28, // Don't use! For internal use by BeginMenu() - ImGuiWindowFlags_FullViewport = 1 << 29 // Don't use! For internal use by Begin() and viewports. + ImGuiWindowFlags_ChildMenu = 1 << 28 // Don't use! For internal use by BeginMenu() }; // Flags for ImGui::InputText() diff --git a/imgui_internal.h b/imgui_internal.h index a210592d..e7141765 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -955,8 +955,9 @@ struct IMGUI_API ImGuiWindow ImVec2 Scroll; ImVec2 ScrollTarget; // target scroll position. stored as cursor position with scrolling canceled out, so the highest point is always 0.0f. (FLT_MAX for no change) ImVec2 ScrollTargetCenterRatio; // 0.0f = scroll so that target position is at top, 0.5f = scroll so that target position is centered - bool ScrollbarX, ScrollbarY; ImVec2 ScrollbarSizes; + bool ScrollbarX, ScrollbarY; + bool ViewportOwned; bool Active; // Set to true on Begin(), unless Collapsed bool WasActive; bool WriteAccessed; // Set to true when any widget access the current window