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:
parent
28d8eb220b
commit
bbb543fc16
258
imgui.cpp
258
imgui.cpp
@ -69,12 +69,12 @@ CODE
|
||||
// [SECTION] MAIN CODE (most of the code! lots of stuff, needs tidying up!)
|
||||
// [SECTION] TOOLTIPS
|
||||
// [SECTION] POPUPS
|
||||
// [SECTION] VIEWPORTS, PLATFORM WINDOWS
|
||||
// [SECTION] KEYBOARD/GAMEPAD NAVIGATION
|
||||
// [SECTION] COLUMNS
|
||||
// [SECTION] DRAG AND DROP
|
||||
// [SECTION] LOGGING/CAPTURING
|
||||
// [SECTION] SETTINGS
|
||||
// [SECTION] VIEWPORTS, PLATFORM WINDOWS
|
||||
// [SECTION] DOCKING
|
||||
// [SECTION] PLATFORM DEPENDENT HELPERS
|
||||
// [SECTION] METRICS/DEBUG WINDOW
|
||||
@ -7786,135 +7786,11 @@ ImVec2 ImGui::FindBestWindowPosForPopup(ImGuiWindow* window)
|
||||
return window->Pos;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// [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()
|
||||
{
|
||||
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
|
||||
//-----------------------------------------------------------------------------
|
||||
|
Loading…
Reference in New Issue
Block a user