Refactor: Internals: Moved Viewport functions in imgui.cpp in their own section. (part 3) (#2036, #1542)
This commit is contained in:
parent
5207afa0dd
commit
fd90afef43
320
imgui.cpp
320
imgui.cpp
@ -56,6 +56,7 @@ CODE
|
||||
- Main Code (most of the code! lots of stuff, needs tidying up)
|
||||
- Tooltips
|
||||
- Popups
|
||||
- Viewports, Platform Windows
|
||||
- Navigation
|
||||
- Columns
|
||||
- Drag and Drop
|
||||
@ -911,7 +912,6 @@ static void SettingsHandlerWindow_WriteAll(ImGuiContext* imgui_ctx,
|
||||
// Platform Dependents default implementation for IO functions
|
||||
static const char* GetClipboardTextFn_DefaultImpl(void* user_data);
|
||||
static void SetClipboardTextFn_DefaultImpl(void* user_data, const char* text);
|
||||
static void ImeSetInputScreenPosFn_DefaultImpl(int x, int y);
|
||||
|
||||
namespace ImGui
|
||||
{
|
||||
@ -3582,53 +3582,6 @@ void ImGui::Render()
|
||||
#endif
|
||||
}
|
||||
|
||||
ImGuiViewportP* ImGui::AddUpdateViewport(ImGuiWindow* window, ImGuiID id, const ImVec2& pos, const ImVec2& size, ImGuiViewportFlags flags)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
IM_ASSERT(id != 0);
|
||||
|
||||
ImGuiViewportP* viewport = (ImGuiViewportP*)FindViewportByID(id);
|
||||
if (viewport)
|
||||
{
|
||||
viewport->Pos = pos;
|
||||
viewport->Size = size;
|
||||
}
|
||||
else
|
||||
{
|
||||
// New viewport
|
||||
viewport = IM_NEW(ImGuiViewportP)();
|
||||
viewport->ID = id;
|
||||
viewport->Idx = g.Viewports.Size;
|
||||
viewport->Pos = viewport->LastPos = pos;
|
||||
viewport->Size = size;
|
||||
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);
|
||||
g.DrawListSharedData.ClipRectFullscreen.w = ImMax(g.DrawListSharedData.ClipRectFullscreen.w, viewport->Pos.y + viewport->Size.y);
|
||||
|
||||
// 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)
|
||||
viewport->DpiScale = g.PlatformIO.Platform_GetWindowDpiScale(viewport);
|
||||
}
|
||||
|
||||
viewport->Window = window;
|
||||
viewport->Flags = flags;
|
||||
viewport->LastFrameActive = g.FrameCount;
|
||||
IM_ASSERT(window == NULL || viewport->ID == window->ID);
|
||||
|
||||
if (window != NULL)
|
||||
window->ViewportOwned = true;
|
||||
|
||||
return viewport;
|
||||
}
|
||||
|
||||
const char* ImGui::FindRenderedTextEnd(const char* text, const char* text_end)
|
||||
{
|
||||
const char* text_display_end = text;
|
||||
@ -4636,118 +4589,6 @@ static int ImGui::FindPlatformMonitorForRect(const ImRect& rect)
|
||||
return best_monitor_n;
|
||||
}
|
||||
|
||||
// FIXME-VIEWPORT: This is all super messy and ought to be clarified or rewritten.
|
||||
static void ImGui::UpdateSelectWindowViewport(ImGuiWindow* window)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindowFlags flags = window->Flags;
|
||||
window->ViewportAllowPlatformMonitorExtend = -1;
|
||||
|
||||
// Restore main viewport if multi-viewport is not supported by the back-end
|
||||
ImGuiViewportP* main_viewport = g.Viewports[0];
|
||||
if (!(g.IO.ConfigFlags & ImGuiConfigFlags_ViewportsEnable))
|
||||
{
|
||||
window->Viewport = main_viewport;
|
||||
window->ViewportId = main_viewport->ID;
|
||||
window->ViewportOwned = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// Merge into host viewports (after moving, resizing)
|
||||
if (window->ViewportOwned && window->ViewportTryMerge && g.ActiveId == 0)
|
||||
{
|
||||
UpdateTryMergeWindowIntoHostViewport(window, g.Viewports[0]);
|
||||
window->ViewportTryMerge = false;
|
||||
}
|
||||
window->ViewportOwned = false;
|
||||
|
||||
// Appearing popups reset their viewport so they can inherit again
|
||||
if ((flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_Tooltip)) && window->Appearing)
|
||||
{
|
||||
window->Viewport = NULL;
|
||||
window->ViewportId = 0;
|
||||
}
|
||||
|
||||
if (!g.NextWindowData.ViewportCond)
|
||||
{
|
||||
// By default inherit from parent window
|
||||
if (window->Viewport == NULL && window->ParentWindow)
|
||||
window->Viewport = window->ParentWindow->Viewport;
|
||||
|
||||
// Attempt to restore saved viewport id (= window that hasn't been activated yet), try to restore the viewport based on saved 'window->ViewportPos' restored from .ini file
|
||||
if (window->Viewport == NULL && window->ViewportId != 0)
|
||||
{
|
||||
window->Viewport = FindViewportByID(window->ViewportId);
|
||||
if (window->Viewport == NULL && window->ViewportPos.x != FLT_MAX && window->ViewportPos.y != FLT_MAX)
|
||||
window->Viewport = AddUpdateViewport(window, window->ID, window->ViewportPos, window->Size, ImGuiViewportFlags_NoDecoration);
|
||||
}
|
||||
}
|
||||
|
||||
if (g.NextWindowData.ViewportCond)
|
||||
{
|
||||
// Code explicitly request a viewport
|
||||
window->Viewport = FindViewportByID(g.NextWindowData.ViewportId);
|
||||
window->ViewportId = g.NextWindowData.ViewportId; // Store ID even if Viewport isn't resolved yet.
|
||||
}
|
||||
else if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_ChildMenu))
|
||||
{
|
||||
// Always inherit viewport from parent window
|
||||
window->Viewport = window->ParentWindow->Viewport;
|
||||
}
|
||||
else if (flags & ImGuiWindowFlags_Tooltip)
|
||||
{
|
||||
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 (which will be cleared in UpdateMovingWindow when releasing the 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_NoDecoration | ImGuiViewportFlags_NoFocusOnAppearing | ImGuiViewportFlags_NoInputs);
|
||||
}
|
||||
else if (GetWindowAlwaysWantOwnViewport(window))
|
||||
{
|
||||
window->Viewport = AddUpdateViewport(window, window->ID, window->Pos, window->Size, ImGuiViewportFlags_NoDecoration);
|
||||
}
|
||||
|
||||
// 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.
|
||||
const bool use_mouse_ref = (g.NavDisableHighlight || !g.NavDisableMouseHover || !g.NavWindow);
|
||||
if (flags & (ImGuiWindowFlags_Tooltip | ImGuiWindowFlags_Popup))
|
||||
{
|
||||
ImVec2 mouse_ref = (flags & ImGuiWindowFlags_Tooltip) ? g.IO.MousePos : g.CurrentPopupStack.back().OpenMousePos;
|
||||
bool mouse_valid = IsMousePosValid(&mouse_ref);
|
||||
if ((window->Appearing || (flags & ImGuiWindowFlags_Tooltip)) && (!use_mouse_ref || mouse_valid))
|
||||
window->ViewportAllowPlatformMonitorExtend = FindPlatformMonitorForPos((use_mouse_ref && mouse_valid) ? mouse_ref : NavCalcPreferredRefPos());
|
||||
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;
|
||||
|
||||
// Update flags
|
||||
window->ViewportOwned = (window == window->Viewport->Window);
|
||||
if (window->ViewportOwned)
|
||||
window->Viewport->Flags |= ImGuiViewportFlags_NoDecoration;
|
||||
|
||||
// If the OS window has a title bar, hide our imgui title bar
|
||||
if (window->ViewportOwned && !(window->Viewport->Flags & ImGuiViewportFlags_NoDecoration))
|
||||
window->Flags |= ImGuiWindowFlags_NoTitleBar;
|
||||
|
||||
window->ViewportId = window->Viewport->ID;
|
||||
}
|
||||
|
||||
struct ImGuiResizeGripDef
|
||||
{
|
||||
ImVec2 CornerPos;
|
||||
@ -7619,6 +7460,165 @@ static void ImGui::UpdateViewports()
|
||||
IM_ASSERT(g.MouseViewport != NULL);
|
||||
}
|
||||
|
||||
ImGuiViewportP* ImGui::AddUpdateViewport(ImGuiWindow* window, ImGuiID id, const ImVec2& pos, const ImVec2& size, ImGuiViewportFlags flags)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
IM_ASSERT(id != 0);
|
||||
|
||||
ImGuiViewportP* viewport = (ImGuiViewportP*)FindViewportByID(id);
|
||||
if (viewport)
|
||||
{
|
||||
viewport->Pos = pos;
|
||||
viewport->Size = size;
|
||||
}
|
||||
else
|
||||
{
|
||||
// New viewport
|
||||
viewport = IM_NEW(ImGuiViewportP)();
|
||||
viewport->ID = id;
|
||||
viewport->Idx = g.Viewports.Size;
|
||||
viewport->Pos = viewport->LastPos = pos;
|
||||
viewport->Size = size;
|
||||
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);
|
||||
g.DrawListSharedData.ClipRectFullscreen.w = ImMax(g.DrawListSharedData.ClipRectFullscreen.w, viewport->Pos.y + viewport->Size.y);
|
||||
|
||||
// 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)
|
||||
viewport->DpiScale = g.PlatformIO.Platform_GetWindowDpiScale(viewport);
|
||||
}
|
||||
|
||||
viewport->Window = window;
|
||||
viewport->Flags = flags;
|
||||
viewport->LastFrameActive = g.FrameCount;
|
||||
IM_ASSERT(window == NULL || viewport->ID == window->ID);
|
||||
|
||||
if (window != NULL)
|
||||
window->ViewportOwned = true;
|
||||
|
||||
return viewport;
|
||||
}
|
||||
|
||||
// FIXME-VIEWPORT: This is all super messy and ought to be clarified or rewritten.
|
||||
static void ImGui::UpdateSelectWindowViewport(ImGuiWindow* window)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiWindowFlags flags = window->Flags;
|
||||
window->ViewportAllowPlatformMonitorExtend = -1;
|
||||
|
||||
// Restore main viewport if multi-viewport is not supported by the back-end
|
||||
ImGuiViewportP* main_viewport = g.Viewports[0];
|
||||
if (!(g.IO.ConfigFlags & ImGuiConfigFlags_ViewportsEnable))
|
||||
{
|
||||
window->Viewport = main_viewport;
|
||||
window->ViewportId = main_viewport->ID;
|
||||
window->ViewportOwned = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// Merge into host viewports (after moving, resizing)
|
||||
if (window->ViewportOwned && window->ViewportTryMerge && g.ActiveId == 0)
|
||||
{
|
||||
UpdateTryMergeWindowIntoHostViewport(window, g.Viewports[0]);
|
||||
window->ViewportTryMerge = false;
|
||||
}
|
||||
window->ViewportOwned = false;
|
||||
|
||||
// Appearing popups reset their viewport so they can inherit again
|
||||
if ((flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_Tooltip)) && window->Appearing)
|
||||
{
|
||||
window->Viewport = NULL;
|
||||
window->ViewportId = 0;
|
||||
}
|
||||
|
||||
if (!g.NextWindowData.ViewportCond)
|
||||
{
|
||||
// By default inherit from parent window
|
||||
if (window->Viewport == NULL && window->ParentWindow)
|
||||
window->Viewport = window->ParentWindow->Viewport;
|
||||
|
||||
// Attempt to restore saved viewport id (= window that hasn't been activated yet), try to restore the viewport based on saved 'window->ViewportPos' restored from .ini file
|
||||
if (window->Viewport == NULL && window->ViewportId != 0)
|
||||
{
|
||||
window->Viewport = FindViewportByID(window->ViewportId);
|
||||
if (window->Viewport == NULL && window->ViewportPos.x != FLT_MAX && window->ViewportPos.y != FLT_MAX)
|
||||
window->Viewport = AddUpdateViewport(window, window->ID, window->ViewportPos, window->Size, ImGuiViewportFlags_NoDecoration);
|
||||
}
|
||||
}
|
||||
|
||||
if (g.NextWindowData.ViewportCond)
|
||||
{
|
||||
// Code explicitly request a viewport
|
||||
window->Viewport = FindViewportByID(g.NextWindowData.ViewportId);
|
||||
window->ViewportId = g.NextWindowData.ViewportId; // Store ID even if Viewport isn't resolved yet.
|
||||
}
|
||||
else if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_ChildMenu))
|
||||
{
|
||||
// Always inherit viewport from parent window
|
||||
window->Viewport = window->ParentWindow->Viewport;
|
||||
}
|
||||
else if (flags & ImGuiWindowFlags_Tooltip)
|
||||
{
|
||||
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 (which will be cleared in UpdateMovingWindow when releasing the 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_NoDecoration | ImGuiViewportFlags_NoFocusOnAppearing | ImGuiViewportFlags_NoInputs);
|
||||
}
|
||||
else if (GetWindowAlwaysWantOwnViewport(window))
|
||||
{
|
||||
window->Viewport = AddUpdateViewport(window, window->ID, window->Pos, window->Size, ImGuiViewportFlags_NoDecoration);
|
||||
}
|
||||
|
||||
// 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.
|
||||
const bool use_mouse_ref = (g.NavDisableHighlight || !g.NavDisableMouseHover || !g.NavWindow);
|
||||
if (flags & (ImGuiWindowFlags_Tooltip | ImGuiWindowFlags_Popup))
|
||||
{
|
||||
ImVec2 mouse_ref = (flags & ImGuiWindowFlags_Tooltip) ? g.IO.MousePos : g.CurrentPopupStack.back().OpenMousePos;
|
||||
bool mouse_valid = IsMousePosValid(&mouse_ref);
|
||||
if ((window->Appearing || (flags & ImGuiWindowFlags_Tooltip)) && (!use_mouse_ref || mouse_valid))
|
||||
window->ViewportAllowPlatformMonitorExtend = FindPlatformMonitorForPos((use_mouse_ref && mouse_valid) ? mouse_ref : NavCalcPreferredRefPos());
|
||||
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;
|
||||
|
||||
// Update flags
|
||||
window->ViewportOwned = (window == window->Viewport->Window);
|
||||
if (window->ViewportOwned)
|
||||
window->Viewport->Flags |= ImGuiViewportFlags_NoDecoration;
|
||||
|
||||
// If the OS window has a title bar, hide our imgui title bar
|
||||
if (window->ViewportOwned && !(window->Viewport->Flags & ImGuiViewportFlags_NoDecoration))
|
||||
window->Flags |= ImGuiWindowFlags_NoTitleBar;
|
||||
|
||||
window->ViewportId = window->Viewport->ID;
|
||||
}
|
||||
|
||||
void ImGui::UpdatePlatformWindows()
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
|
Loading…
Reference in New Issue
Block a user