Refactor: Move viewport code under other subsystem to simplify merging (1) (moving in multiple commits to make diff/patch behave nicely)

This commit is contained in:
omar 2019-03-07 18:33:45 +01:00
parent 28d8eb220b
commit bbb543fc16

258
imgui.cpp
View File

@ -69,12 +69,12 @@ CODE
// [SECTION] MAIN CODE (most of the code! lots of stuff, needs tidying up!) // [SECTION] MAIN CODE (most of the code! lots of stuff, needs tidying up!)
// [SECTION] TOOLTIPS // [SECTION] TOOLTIPS
// [SECTION] POPUPS // [SECTION] POPUPS
// [SECTION] VIEWPORTS, PLATFORM WINDOWS
// [SECTION] KEYBOARD/GAMEPAD NAVIGATION // [SECTION] KEYBOARD/GAMEPAD NAVIGATION
// [SECTION] COLUMNS // [SECTION] COLUMNS
// [SECTION] DRAG AND DROP // [SECTION] DRAG AND DROP
// [SECTION] LOGGING/CAPTURING // [SECTION] LOGGING/CAPTURING
// [SECTION] SETTINGS // [SECTION] SETTINGS
// [SECTION] VIEWPORTS, PLATFORM WINDOWS
// [SECTION] DOCKING // [SECTION] DOCKING
// [SECTION] PLATFORM DEPENDENT HELPERS // [SECTION] PLATFORM DEPENDENT HELPERS
// [SECTION] METRICS/DEBUG WINDOW // [SECTION] METRICS/DEBUG WINDOW
@ -7786,135 +7786,11 @@ ImVec2 ImGui::FindBestWindowPosForPopup(ImGuiWindow* window)
return window->Pos; return window->Pos;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// [SECTION] VIEWPORTS, PLATFORM WINDOWS // [SECTION] VIEWPORTS, PLATFORM WINDOWS
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
ImGuiViewport* ImGui::GetMainViewport()
{
ImGuiContext& g = *GImGui;
return g.Viewports[0];
}
ImGuiViewport* ImGui::FindViewportByID(ImGuiID id)
{
ImGuiContext& g = *GImGui;
for (int n = 0; n < g.Viewports.Size; n++)
if (g.Viewports[n]->ID == id)
return g.Viewports[n];
return NULL;
}
ImGuiViewport* ImGui::FindViewportByPlatformHandle(void* platform_handle)
{
ImGuiContext& g = *GImGui;
for (int i = 0; i != g.Viewports.Size; i++)
if (g.Viewports[i]->PlatformHandle == platform_handle)
return g.Viewports[i];
return NULL;
}
void ImGui::SetCurrentViewport(ImGuiWindow* current_window, ImGuiViewportP* viewport)
{
ImGuiContext& g = *GImGui;
(void)current_window;
if (viewport)
viewport->LastFrameActive = g.FrameCount;
if (g.CurrentViewport == viewport)
return;
g.CurrentViewport = viewport;
//IMGUI_DEBUG_LOG("SetCurrentViewport changed '%s' 0x%08X\n", current_window ? current_window->Name : NULL, viewport ? viewport->ID : 0);
// Notify platform layer of viewport changes
// FIXME-DPI: This is only currently used for experimenting with handling of multiple DPI
if (g.CurrentViewport && g.PlatformIO.Platform_OnChangedViewport)
g.PlatformIO.Platform_OnChangedViewport(g.CurrentViewport);
}
static void SetWindowViewport(ImGuiWindow* window, ImGuiViewportP* viewport)
{
window->Viewport = viewport;
window->ViewportId = viewport->ID;
window->ViewportOwned = (viewport->Window == window);
}
static bool ImGui::GetWindowAlwaysWantOwnViewport(ImGuiWindow* window)
{
// Tooltips and menus are not automatically forced into their own viewport when the NoMerge flag is set, however the multiplication of viewports makes them more likely to protude and create their own.
ImGuiContext& g = *GImGui;
if (g.IO.ConfigViewportsNoAutoMerge && (g.ConfigFlagsForFrame & ImGuiConfigFlags_ViewportsEnable))
if (!window->DockIsActive)
if ((window->Flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_ChildMenu | ImGuiWindowFlags_Tooltip | ImGuiWindowFlags_Popup)) == 0)
return true;
return false;
}
static bool ImGui::UpdateTryMergeWindowIntoHostViewport(ImGuiWindow* window, ImGuiViewportP* viewport)
{
ImGuiContext& g = *GImGui;
if (!(viewport->Flags & ImGuiViewportFlags_CanHostOtherWindows) || window->Viewport == viewport || viewport->PlatformWindowMinimized)
return false;
if (!viewport->GetRect().Contains(window->Rect()))
return false;
if (GetWindowAlwaysWantOwnViewport(window))
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;
if (window->ViewportOwned)
for (int n = 0; n < g.Windows.Size; n++)
if (g.Windows[n]->Viewport == old_viewport)
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!)
void ImGui::ScaleWindowsInViewport(ImGuiViewportP* viewport, float scale)
{
ImGuiContext& g = *GImGui;
if (viewport->Window)
{
ScaleWindow(viewport->Window, scale);
}
else
{
for (int i = 0; i != g.Windows.Size; i++)
if (g.Windows[i]->Viewport == viewport)
ScaleWindow(g.Windows[i], scale);
}
}
// If the back-end doesn't set MouseLastHoveredViewport or doesn't honor ImGuiViewportFlags_NoInputs, we do a search ourselves.
// A) It won't take account of the possibility that non-imgui windows may be in-between our dragged window and our target window.
// B) It requires Platform_GetWindowFocus to be implemented by back-end.
static ImGuiViewportP* FindViewportHoveredFromPlatformWindowStack(const ImVec2 mouse_platform_pos)
{
ImGuiContext& g = *GImGui;
ImGuiViewportP* best_candidate = NULL;
for (int n = 0; n < g.Viewports.Size; n++)
{
ImGuiViewportP* viewport = g.Viewports[n];
if (!(viewport->Flags & ImGuiViewportFlags_NoInputs) && !viewport->PlatformWindowMinimized && viewport->GetRect().Contains(mouse_platform_pos))
if (best_candidate == NULL || best_candidate->LastFrontMostStampCount < viewport->LastFrontMostStampCount)
best_candidate = viewport;
}
return best_candidate;
}
static void ImGui::UpdateViewportsNewFrame() static void ImGui::UpdateViewportsNewFrame()
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
@ -10611,6 +10487,136 @@ static void SettingsHandlerWindow_WriteAll(ImGuiContext* imgui_ctx, ImGuiSetting
} }
//-----------------------------------------------------------------------------
// [SECTION] VIEWPORTS, PLATFORM WINDOWS
//-----------------------------------------------------------------------------
ImGuiViewport* ImGui::GetMainViewport()
{
ImGuiContext& g = *GImGui;
return g.Viewports[0];
}
ImGuiViewport* ImGui::FindViewportByID(ImGuiID id)
{
ImGuiContext& g = *GImGui;
for (int n = 0; n < g.Viewports.Size; n++)
if (g.Viewports[n]->ID == id)
return g.Viewports[n];
return NULL;
}
ImGuiViewport* ImGui::FindViewportByPlatformHandle(void* platform_handle)
{
ImGuiContext& g = *GImGui;
for (int i = 0; i != g.Viewports.Size; i++)
if (g.Viewports[i]->PlatformHandle == platform_handle)
return g.Viewports[i];
return NULL;
}
void ImGui::SetCurrentViewport(ImGuiWindow* current_window, ImGuiViewportP* viewport)
{
ImGuiContext& g = *GImGui;
(void)current_window;
if (viewport)
viewport->LastFrameActive = g.FrameCount;
if (g.CurrentViewport == viewport)
return;
g.CurrentViewport = viewport;
//IMGUI_DEBUG_LOG("SetCurrentViewport changed '%s' 0x%08X\n", current_window ? current_window->Name : NULL, viewport ? viewport->ID : 0);
// Notify platform layer of viewport changes
// FIXME-DPI: This is only currently used for experimenting with handling of multiple DPI
if (g.CurrentViewport && g.PlatformIO.Platform_OnChangedViewport)
g.PlatformIO.Platform_OnChangedViewport(g.CurrentViewport);
}
static void SetWindowViewport(ImGuiWindow* window, ImGuiViewportP* viewport)
{
window->Viewport = viewport;
window->ViewportId = viewport->ID;
window->ViewportOwned = (viewport->Window == window);
}
static bool ImGui::GetWindowAlwaysWantOwnViewport(ImGuiWindow* window)
{
// Tooltips and menus are not automatically forced into their own viewport when the NoMerge flag is set, however the multiplication of viewports makes them more likely to protude and create their own.
ImGuiContext& g = *GImGui;
if (g.IO.ConfigViewportsNoAutoMerge && (g.ConfigFlagsForFrame & ImGuiConfigFlags_ViewportsEnable))
if (!window->DockIsActive)
if ((window->Flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_ChildMenu | ImGuiWindowFlags_Tooltip | ImGuiWindowFlags_Popup)) == 0)
return true;
return false;
}
static bool ImGui::UpdateTryMergeWindowIntoHostViewport(ImGuiWindow* window, ImGuiViewportP* viewport)
{
ImGuiContext& g = *GImGui;
if (!(viewport->Flags & ImGuiViewportFlags_CanHostOtherWindows) || window->Viewport == viewport || viewport->PlatformWindowMinimized)
return false;
if (!viewport->GetRect().Contains(window->Rect()))
return false;
if (GetWindowAlwaysWantOwnViewport(window))
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;
if (window->ViewportOwned)
for (int n = 0; n < g.Windows.Size; n++)
if (g.Windows[n]->Viewport == old_viewport)
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!)
void ImGui::ScaleWindowsInViewport(ImGuiViewportP* viewport, float scale)
{
ImGuiContext& g = *GImGui;
if (viewport->Window)
{
ScaleWindow(viewport->Window, scale);
}
else
{
for (int i = 0; i != g.Windows.Size; i++)
if (g.Windows[i]->Viewport == viewport)
ScaleWindow(g.Windows[i], scale);
}
}
// If the back-end doesn't set MouseLastHoveredViewport or doesn't honor ImGuiViewportFlags_NoInputs, we do a search ourselves.
// A) It won't take account of the possibility that non-imgui windows may be in-between our dragged window and our target window.
// B) It requires Platform_GetWindowFocus to be implemented by back-end.
static ImGuiViewportP* FindViewportHoveredFromPlatformWindowStack(const ImVec2 mouse_platform_pos)
{
ImGuiContext& g = *GImGui;
ImGuiViewportP* best_candidate = NULL;
for (int n = 0; n < g.Viewports.Size; n++)
{
ImGuiViewportP* viewport = g.Viewports[n];
if (!(viewport->Flags & ImGuiViewportFlags_NoInputs) && !viewport->PlatformWindowMinimized && viewport->GetRect().Contains(mouse_platform_pos))
if (best_candidate == NULL || best_candidate->LastFrontMostStampCount < viewport->LastFrontMostStampCount)
best_candidate = viewport;
}
return best_candidate;
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// [SECTION] DOCKING // [SECTION] DOCKING
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------