mirror of
https://github.com/Drezil/imgui.git
synced 2024-11-15 09:27:00 +00:00
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)
|
- Main Code (most of the code! lots of stuff, needs tidying up)
|
||||||
- Tooltips
|
- Tooltips
|
||||||
- Popups
|
- Popups
|
||||||
|
- Viewports, Platform Windows
|
||||||
- Navigation
|
- Navigation
|
||||||
- Columns
|
- Columns
|
||||||
- Drag and Drop
|
- Drag and Drop
|
||||||
@ -911,7 +912,6 @@ static void SettingsHandlerWindow_WriteAll(ImGuiContext* imgui_ctx,
|
|||||||
// Platform Dependents default implementation for IO functions
|
// Platform Dependents default implementation for IO functions
|
||||||
static const char* GetClipboardTextFn_DefaultImpl(void* user_data);
|
static const char* GetClipboardTextFn_DefaultImpl(void* user_data);
|
||||||
static void SetClipboardTextFn_DefaultImpl(void* user_data, const char* text);
|
static void SetClipboardTextFn_DefaultImpl(void* user_data, const char* text);
|
||||||
static void ImeSetInputScreenPosFn_DefaultImpl(int x, int y);
|
|
||||||
|
|
||||||
namespace ImGui
|
namespace ImGui
|
||||||
{
|
{
|
||||||
@ -3582,53 +3582,6 @@ void ImGui::Render()
|
|||||||
#endif
|
#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* ImGui::FindRenderedTextEnd(const char* text, const char* text_end)
|
||||||
{
|
{
|
||||||
const char* text_display_end = text;
|
const char* text_display_end = text;
|
||||||
@ -4636,118 +4589,6 @@ static int ImGui::FindPlatformMonitorForRect(const ImRect& rect)
|
|||||||
return best_monitor_n;
|
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
|
struct ImGuiResizeGripDef
|
||||||
{
|
{
|
||||||
ImVec2 CornerPos;
|
ImVec2 CornerPos;
|
||||||
@ -7619,6 +7460,165 @@ static void ImGui::UpdateViewports()
|
|||||||
IM_ASSERT(g.MouseViewport != NULL);
|
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()
|
void ImGui::UpdatePlatformWindows()
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
|
Loading…
Reference in New Issue
Block a user