Viewport: Merging/Extracting to/from main host viewport is now performed based on current state rather than triggers. Windows which don't fit in host window are now consistently in their own viewport. Toward simplifying the UpdateSelectWindowViewport() function. Probably broke something.. (#1542)

This commit is contained in:
omar 2018-11-22 21:13:07 +01:00
parent 510f0e505c
commit 760c1d95b9
2 changed files with 22 additions and 47 deletions

View File

@ -2387,7 +2387,6 @@ ImGuiWindow::ImGuiWindow(ImGuiContext* context, const char* name)
ScrollbarSizes = ImVec2(0.0f, 0.0f);
ScrollbarX = ScrollbarY = false;
ViewportOwned = false;
ViewportTryMerge = ViewportTrySplit = false;
Active = WasActive = false;
WriteAccessed = false;
Collapsed = false;
@ -4878,10 +4877,6 @@ static void ImGui::UpdateManualResize(ImGuiWindow* window, const ImVec2& size_au
if (size_target.x != FLT_MAX && (size_target.x != window->SizeFull.x || size_target.y != window->SizeFull.y))
{
window->SizeFull = size_target;
if (window->ViewportOwned)
window->ViewportTryMerge = true;
else
window->ViewportTrySplit = true;
MarkIniSettingsDirty(window);
}
if (pos_target.x != FLT_MAX)
@ -5224,10 +5219,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
{
// Late create viewport, based on the assumption that with our calculations, the DPI will be known ahead (same as the DPI of the selection done in UpdateSelectWindowViewport)
//ImGuiViewport* old_viewport = window->Viewport;
ImGuiViewportFlags viewport_flags = ImGuiViewportFlags_NoFocusOnAppearing;
if ((window->Flags & ImGuiWindowFlags_NoMouseInputs) && (window->Flags & ImGuiWindowFlags_NoNavInputs))
viewport_flags |= ImGuiViewportFlags_NoInputs;
window->Viewport = AddUpdateViewport(window, window->ID, window->Pos, window->Size, viewport_flags);
window->Viewport = AddUpdateViewport(window, window->ID, window->Pos, window->Size, ImGuiViewportFlags_NoFocusOnAppearing);
// FIXME-DPI
//IM_ASSERT(old_viewport->DpiScale == window->Viewport->DpiScale); // FIXME-DPI: Something went wrong
@ -5240,15 +5232,9 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
if (window->ViewportOwned)
{
if (window->Viewport->PlatformRequestMove)
{
window->Pos = window->Viewport->Pos;
window->ViewportTryMerge = true;
}
if (window->Viewport->PlatformRequestResize)
{
window->Size = window->SizeFull = window->Viewport->Size;
window->ViewportTryMerge = true;
}
// We also tell the back-end that clearing the platform window won't be necessary, as our window is filling the viewport and we have disabled BgAlpha
window->Viewport->Flags |= ImGuiViewportFlags_NoRendererClear;
@ -5269,7 +5255,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
{
// Fallback for "lost" window (e.g. a monitor disconnected): we move the window back over the main viewport
SetWindowPos(window, g.Viewports[0]->Pos + style.DisplayWindowPadding, ImGuiCond_Always);
window->ViewportTryMerge = true;
}
else
{
@ -7610,11 +7595,22 @@ static void ImGui::UpdateViewports()
IM_ASSERT(g.MouseViewport != NULL);
}
// FIXME: We should ideally refactor the system to call this everyframe (we currently don't)
ImGuiViewportP* ImGui::AddUpdateViewport(ImGuiWindow* window, ImGuiID id, const ImVec2& pos, const ImVec2& size, ImGuiViewportFlags flags)
{
ImGuiContext& g = *GImGui;
IM_ASSERT(id != 0);
if (window != NULL)
{
if (g.MovingWindow && g.MovingWindow->RootWindow == window)
flags |= ImGuiViewportFlags_NoInputs | ImGuiViewportFlags_NoFocusOnAppearing;
if ((window->Flags & ImGuiWindowFlags_NoMouseInputs) && (window->Flags & ImGuiWindowFlags_NoNavInputs))
flags |= ImGuiViewportFlags_NoInputs;
if (window->Flags & ImGuiWindowFlags_NoFocusOnAppearing)
flags |= ImGuiViewportFlags_NoFocusOnAppearing;
}
ImGuiViewportP* viewport = (ImGuiViewportP*)FindViewportByID(id);
if (viewport)
{
@ -7633,9 +7629,6 @@ ImGuiViewportP* ImGui::AddUpdateViewport(ImGuiWindow* window, ImGuiID id, const
g.Viewports.push_back(viewport);
//IMGUI_DEBUG_LOG("Add Viewport %08X (%s)\n", id, window->Name);
if (window && (window->Flags & ImGuiWindowFlags_NoFocusOnAppearing))
flags |= ImGuiViewportFlags_NoFocusOnAppearing;
// We normally setup for all viewports in NewFrame() but here need to handle the mid-frame creation of a new viewport.
// We need to extend the fullscreen clip rect so the OverlayDrawList clip is correct for that the first frame
g.DrawListSharedData.ClipRectFullscreen.z = ImMax(g.DrawListSharedData.ClipRectFullscreen.z, viewport->Pos.x + viewport->Size.x);
@ -7673,12 +7666,9 @@ static void ImGui::UpdateSelectWindowViewport(ImGuiWindow* window)
return;
}
// Merge into host viewports (after moving, resizing)
if (window->ViewportOwned && window->ViewportTryMerge && g.ActiveId == 0)
{
// Merge into host viewport
if (window->ViewportOwned && g.ActiveId == 0)
UpdateTryMergeWindowIntoHostViewport(window, g.Viewports[0]);
window->ViewportTryMerge = false;
}
window->ViewportOwned = false;
// Appearing popups reset their viewport so they can inherit again
@ -7718,23 +7708,15 @@ static void ImGui::UpdateSelectWindowViewport(ImGuiWindow* window)
{
window->Viewport = g.MouseViewport;
}
else if (g.MovingWindow && g.MovingWindow->RootWindow == window && IsMousePosValid())
{
// Transition to our own viewport when leaving our host boundaries + set the NoInputs flag (will be cleared in UpdateMouseMovingWindow() when releasing mouse)
// If we are already in our own viewport, if need to set the NoInputs flag.
// If we have no viewport (which happens when detaching a docked node) immediately create one.
// We test for 'window->Viewport->Window == window' instead of 'window->ViewportOwned' because ViewportOwned is not valid during this function.
bool has_viewport = (window->Viewport != NULL);
bool own_viewport = has_viewport && (window->Viewport->Window == window);
bool leave_host_viewport = has_viewport && !own_viewport && !window->Viewport->GetRect().Contains(window->Rect());
bool move_from_own_viewport = has_viewport && own_viewport && !(window->Viewport->Flags & ImGuiViewportFlags_NoInputs);
if (!has_viewport || leave_host_viewport || move_from_own_viewport)
window->Viewport = AddUpdateViewport(window, window->ID, window->Pos, window->Size, ImGuiViewportFlags_NoFocusOnAppearing | ImGuiViewportFlags_NoInputs);
}
else if (GetWindowAlwaysWantOwnViewport(window))
{
window->Viewport = AddUpdateViewport(window, window->ID, window->Pos, window->Size, ImGuiViewportFlags_None);
}
else if (g.MovingWindow && g.MovingWindow->RootWindow == window && IsMousePosValid())
{
if (window->Viewport != NULL && window->Viewport->Window == window)
window->Viewport = AddUpdateViewport(window, window->ID, window->Pos, window->Size, ImGuiViewportFlags_None);
}
// 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.
@ -7766,19 +7748,14 @@ static void ImGui::UpdateSelectWindowViewport(ImGuiWindow* window)
window->Viewport = AddUpdateViewport(window, window->ID, window->Pos, window->Size, ImGuiViewportFlags_NoFocusOnAppearing);
}
}
else if ((flags & ImGuiWindowFlags_DockNodeHost) && (window->Appearing))
{
// Mark so the dock host can be on its own viewport
window->ViewportAllowPlatformMonitorExtend = FindPlatformMonitorForRect(window->Rect());
}
if (window->ViewportTrySplit && window->ViewportAllowPlatformMonitorExtend < 0)
window->ViewportAllowPlatformMonitorExtend = window->Viewport->PlatformMonitor;
window->ViewportTrySplit = false;
// Fallback to default viewport
if (window->Viewport == NULL)
window->Viewport = main_viewport;
if (window->ViewportAllowPlatformMonitorExtend < 0)
window->ViewportAllowPlatformMonitorExtend = window->Viewport->PlatformMonitor;
// Update flags
window->ViewportOwned = (window == window->Viewport->Window);

View File

@ -1195,8 +1195,6 @@ struct IMGUI_API ImGuiWindow
ImVec2 ScrollbarSizes; // Size taken by scrollbars on each axis
bool ScrollbarX, ScrollbarY;
bool ViewportOwned;
bool ViewportTryMerge; // Request attempt to merge into a host viewport and destroy our owned viewport
bool ViewportTrySplit; // Request attempt to split out of a host viewport and create our owned viewport
bool Active; // Set to true on Begin(), unless Collapsed
bool WasActive;
bool WriteAccessed; // Set to true when any widget access the current window