Skip to content

Commit

Permalink
Viewport: Merging/Extracting to/from main host viewport is now perfor…
Browse files Browse the repository at this point in the history
…med 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)
  • Loading branch information
ocornut committed Nov 22, 2018
1 parent 1f78e08 commit cae4d02
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 42 deletions.
62 changes: 22 additions & 40 deletions imgui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2369,7 +2369,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;
Expand Down Expand Up @@ -4762,10 +4761,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)
Expand Down Expand Up @@ -5082,10 +5077,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
Expand All @@ -5098,15 +5090,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;
Expand All @@ -5127,7 +5113,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
{
Expand Down Expand Up @@ -7385,11 +7370,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)
{
Expand All @@ -7407,9 +7403,6 @@ ImGuiViewportP* ImGui::AddUpdateViewport(ImGuiWindow* window, ImGuiID id, const
viewport->PlatformMonitor = FindPlatformMonitorForRect(viewport->GetRect());
g.Viewports.push_back(viewport);

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);
Expand Down Expand Up @@ -7447,12 +7440,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
Expand Down Expand Up @@ -7492,23 +7482,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.
Expand All @@ -7522,14 +7504,14 @@ static void ImGui::UpdateSelectWindowViewport(ImGuiWindow* window)
else
window->ViewportAllowPlatformMonitorExtend = window->Viewport->PlatformMonitor;
}
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);

Expand Down
2 changes: 0 additions & 2 deletions imgui_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -1074,8 +1074,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
Expand Down

0 comments on commit cae4d02

Please sign in to comment.