mirror of
https://github.com/Drezil/imgui.git
synced 2024-12-19 06:26:35 +00:00
Viewport: Handle case where host window gets moved and resized simultaneous (toggling maximized state). There's no perfect solution there, than using io.ConfigViewportsNoAutoMerge = false. (#1542)
This commit is contained in:
parent
b8d8355f10
commit
967073ba3d
52
imgui.cpp
52
imgui.cpp
@ -3472,7 +3472,7 @@ void ImGui::UpdateMouseMovingWindowNewFrame()
|
|||||||
{
|
{
|
||||||
// Try to merge the window back into the main viewport.
|
// Try to merge the window back into the main viewport.
|
||||||
// This works because MouseViewport should be != MovingWindow->Viewport on release (as per code in UpdateViewports)
|
// This works because MouseViewport should be != MovingWindow->Viewport on release (as per code in UpdateViewports)
|
||||||
if (g.ConfigFlagsForFrame & ImGuiConfigFlags_ViewportsEnable)
|
if (g.ConfigFlagsCurrFrame & ImGuiConfigFlags_ViewportsEnable)
|
||||||
UpdateTryMergeWindowIntoHostViewport(moving_window, g.MouseViewport);
|
UpdateTryMergeWindowIntoHostViewport(moving_window, g.MouseViewport);
|
||||||
|
|
||||||
// Restore the mouse viewport so that we don't hover the viewport _under_ the moved window during the frame we released the mouse button.
|
// Restore the mouse viewport so that we don't hover the viewport _under_ the moved window during the frame we released the mouse button.
|
||||||
@ -3821,10 +3821,10 @@ void ImGui::NewFrame()
|
|||||||
NewFrameSanityChecks();
|
NewFrameSanityChecks();
|
||||||
|
|
||||||
// Perform simple check: error if Docking or Viewport are enabled _exactly_ on frame 1 (instead of frame 0 or later), which is a common error leading to loss of .ini data.
|
// Perform simple check: error if Docking or Viewport are enabled _exactly_ on frame 1 (instead of frame 0 or later), which is a common error leading to loss of .ini data.
|
||||||
const ImGuiColumnsFlags prev_config_flags = g.ConfigFlagsForFrame;
|
g.ConfigFlagsLastFrame = g.ConfigFlagsCurrFrame;
|
||||||
if (g.FrameCount == 1 && (g.IO.ConfigFlags & ImGuiConfigFlags_DockingEnable) && (prev_config_flags & ImGuiConfigFlags_DockingEnable) == 0)
|
if (g.FrameCount == 1 && (g.IO.ConfigFlags & ImGuiConfigFlags_DockingEnable) && (g.ConfigFlagsLastFrame & ImGuiConfigFlags_DockingEnable) == 0)
|
||||||
IM_ASSERT(0 && "Please DockingEnable before the first call to NewFrame()! Otherwise you will lose your .ini settings!");
|
IM_ASSERT(0 && "Please DockingEnable before the first call to NewFrame()! Otherwise you will lose your .ini settings!");
|
||||||
if (g.FrameCount == 1 && (g.IO.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) && (prev_config_flags & ImGuiConfigFlags_ViewportsEnable) == 0)
|
if (g.FrameCount == 1 && (g.IO.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) && (g.ConfigFlagsLastFrame & ImGuiConfigFlags_ViewportsEnable) == 0)
|
||||||
IM_ASSERT(0 && "Please ViewportEnable before the first call to NewFrame()! Otherwise you will lose your .ini settings!");
|
IM_ASSERT(0 && "Please ViewportEnable before the first call to NewFrame()! Otherwise you will lose your .ini settings!");
|
||||||
|
|
||||||
// Perform simple checks: multi-viewport and platform windows support
|
// Perform simple checks: multi-viewport and platform windows support
|
||||||
@ -3863,6 +3863,7 @@ void ImGui::NewFrame()
|
|||||||
IM_ASSERT(mon.DpiScale != 0.0f);
|
IM_ASSERT(mon.DpiScale != 0.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
g.ConfigFlagsCurrFrame = g.IO.ConfigFlags;
|
||||||
|
|
||||||
// Load settings on first frame (if not explicitly loaded manually before)
|
// Load settings on first frame (if not explicitly loaded manually before)
|
||||||
if (!g.SettingsLoaded)
|
if (!g.SettingsLoaded)
|
||||||
@ -3892,7 +3893,6 @@ void ImGui::NewFrame()
|
|||||||
g.FrameCount += 1;
|
g.FrameCount += 1;
|
||||||
g.TooltipOverrideCount = 0;
|
g.TooltipOverrideCount = 0;
|
||||||
g.WindowsActiveCount = 0;
|
g.WindowsActiveCount = 0;
|
||||||
g.ConfigFlagsForFrame = g.IO.ConfigFlags;
|
|
||||||
|
|
||||||
UpdateViewportsNewFrame();
|
UpdateViewportsNewFrame();
|
||||||
|
|
||||||
@ -10317,7 +10317,7 @@ 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 protrude and create their own.
|
// 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 protrude and create their own.
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
if (g.IO.ConfigViewportsNoAutoMerge || (window->WindowClass.ViewportFlagsOverrideSet & ImGuiViewportFlags_NoAutoMerge))
|
if (g.IO.ConfigViewportsNoAutoMerge || (window->WindowClass.ViewportFlagsOverrideSet & ImGuiViewportFlags_NoAutoMerge))
|
||||||
if (g.ConfigFlagsForFrame & ImGuiConfigFlags_ViewportsEnable)
|
if (g.ConfigFlagsCurrFrame & ImGuiConfigFlags_ViewportsEnable)
|
||||||
if (!window->DockIsActive)
|
if (!window->DockIsActive)
|
||||||
if ((window->Flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_ChildMenu | ImGuiWindowFlags_Tooltip | ImGuiWindowFlags_Popup)) == 0)
|
if ((window->Flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_ChildMenu | ImGuiWindowFlags_Tooltip | ImGuiWindowFlags_Popup)) == 0)
|
||||||
return true;
|
return true;
|
||||||
@ -10362,6 +10362,26 @@ static bool ImGui::UpdateTryMergeWindowIntoHostViewports(ImGuiWindow* window)
|
|||||||
return UpdateTryMergeWindowIntoHostViewport(window, g.Viewports[0]);
|
return UpdateTryMergeWindowIntoHostViewport(window, g.Viewports[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Translate imgui windows when a Host Viewport has been moved
|
||||||
|
// (This additionally keeps windows at the same place when ImGuiConfigFlags_ViewportsEnable is toggled!)
|
||||||
|
void ImGui::TranslateWindowsInViewport(ImGuiViewportP* viewport, const ImVec2& old_pos, const ImVec2& new_pos)
|
||||||
|
{
|
||||||
|
ImGuiContext& g = *GImGui;
|
||||||
|
IM_ASSERT(viewport->Window == NULL && (viewport->Flags & ImGuiViewportFlags_CanHostOtherWindows));
|
||||||
|
|
||||||
|
// 1) We test if ImGuiConfigFlags_ViewportsEnable was just toggled, which allows us to conveniently
|
||||||
|
// translate imgui windows from OS-window-local to absolute coordinates or vice-versa.
|
||||||
|
// 2) If it's not going to fit into the new size, keep it at same absolute position.
|
||||||
|
// One problem with this is that most Win32 applications doesn't update their render while dragging,
|
||||||
|
// and so the window will appear to teleport when releasing the mouse.
|
||||||
|
const bool translate_all_windows = (g.ConfigFlagsCurrFrame & ImGuiConfigFlags_ViewportsEnable) != (g.ConfigFlagsLastFrame & ImGuiConfigFlags_ViewportsEnable);
|
||||||
|
ImRect test_still_fit_rect(old_pos, old_pos + viewport->Size);
|
||||||
|
ImVec2 delta_pos = new_pos - old_pos;
|
||||||
|
for (int window_n = 0; window_n < g.Windows.Size; window_n++) // FIXME-OPT
|
||||||
|
if (translate_all_windows || (g.Windows[window_n]->Viewport == viewport && test_still_fit_rect.Contains(g.Windows[window_n]->Rect())))
|
||||||
|
TranslateWindow(g.Windows[window_n], delta_pos);
|
||||||
|
}
|
||||||
|
|
||||||
// Scale all windows (position, size). Use when e.g. changing DPI. (This is a lossy operation!)
|
// Scale all windows (position, size). Use when e.g. changing DPI. (This is a lossy operation!)
|
||||||
void ImGui::ScaleWindowsInViewport(ImGuiViewportP* viewport, float scale)
|
void ImGui::ScaleWindowsInViewport(ImGuiViewportP* viewport, float scale)
|
||||||
{
|
{
|
||||||
@ -10403,7 +10423,7 @@ static void ImGui::UpdateViewportsNewFrame()
|
|||||||
IM_ASSERT(g.PlatformIO.Viewports.Size <= g.Viewports.Size);
|
IM_ASSERT(g.PlatformIO.Viewports.Size <= g.Viewports.Size);
|
||||||
|
|
||||||
// Update Minimized status (we need it first in order to decide if we'll apply Pos/Size of the main viewport)
|
// Update Minimized status (we need it first in order to decide if we'll apply Pos/Size of the main viewport)
|
||||||
if ((g.ConfigFlagsForFrame & ImGuiConfigFlags_ViewportsEnable))
|
if ((g.ConfigFlagsCurrFrame & ImGuiConfigFlags_ViewportsEnable))
|
||||||
{
|
{
|
||||||
for (int n = 0; n < g.Viewports.Size; n++)
|
for (int n = 0; n < g.Viewports.Size; n++)
|
||||||
{
|
{
|
||||||
@ -10426,7 +10446,7 @@ static void ImGui::UpdateViewportsNewFrame()
|
|||||||
IM_ASSERT(main_viewport->Window == NULL);
|
IM_ASSERT(main_viewport->Window == NULL);
|
||||||
ImVec2 main_viewport_platform_pos = ImVec2(0.0f, 0.0f);
|
ImVec2 main_viewport_platform_pos = ImVec2(0.0f, 0.0f);
|
||||||
ImVec2 main_viewport_platform_size = g.IO.DisplaySize;
|
ImVec2 main_viewport_platform_size = g.IO.DisplaySize;
|
||||||
if (g.ConfigFlagsForFrame & ImGuiConfigFlags_ViewportsEnable)
|
if (g.ConfigFlagsCurrFrame & ImGuiConfigFlags_ViewportsEnable)
|
||||||
main_viewport_platform_pos = (main_viewport->Flags & ImGuiViewportFlags_Minimized) ? main_viewport->Pos : g.PlatformIO.Platform_GetWindowPos(main_viewport);
|
main_viewport_platform_pos = (main_viewport->Flags & ImGuiViewportFlags_Minimized) ? main_viewport->Pos : g.PlatformIO.Platform_GetWindowPos(main_viewport);
|
||||||
AddUpdateViewport(NULL, IMGUI_VIEWPORT_DEFAULT_ID, main_viewport_platform_pos, main_viewport_platform_size, ImGuiViewportFlags_CanHostOtherWindows);
|
AddUpdateViewport(NULL, IMGUI_VIEWPORT_DEFAULT_ID, main_viewport_platform_pos, main_viewport_platform_size, ImGuiViewportFlags_CanHostOtherWindows);
|
||||||
|
|
||||||
@ -10461,7 +10481,7 @@ static void ImGui::UpdateViewportsNewFrame()
|
|||||||
}
|
}
|
||||||
|
|
||||||
const bool platform_funcs_available = viewport->PlatformWindowCreated;
|
const bool platform_funcs_available = viewport->PlatformWindowCreated;
|
||||||
if ((g.ConfigFlagsForFrame & ImGuiConfigFlags_ViewportsEnable))
|
if ((g.ConfigFlagsCurrFrame & ImGuiConfigFlags_ViewportsEnable))
|
||||||
{
|
{
|
||||||
// Update Position and Size (from Platform Window to ImGui) if requested.
|
// Update Position and Size (from Platform Window to ImGui) if requested.
|
||||||
// We do it early in the frame instead of waiting for UpdatePlatformWindows() to avoid a frame of lag when moving/resizing using OS facilities.
|
// We do it early in the frame instead of waiting for UpdatePlatformWindows() to avoid a frame of lag when moving/resizing using OS facilities.
|
||||||
@ -10482,11 +10502,9 @@ static void ImGui::UpdateViewportsNewFrame()
|
|||||||
|
|
||||||
// Translate imgui windows when a Host Viewport has been moved
|
// Translate imgui windows when a Host Viewport has been moved
|
||||||
// (This additionally keeps windows at the same place when ImGuiConfigFlags_ViewportsEnable is toggled!)
|
// (This additionally keeps windows at the same place when ImGuiConfigFlags_ViewportsEnable is toggled!)
|
||||||
ImVec2 viewport_delta = viewport->Pos - viewport->LastPos;
|
const ImVec2 viewport_delta_pos = viewport->Pos - viewport->LastPos;
|
||||||
if ((viewport->Flags & ImGuiViewportFlags_CanHostOtherWindows) && (viewport_delta.x != 0.0f || viewport_delta.y != 0.0f))
|
if ((viewport->Flags & ImGuiViewportFlags_CanHostOtherWindows) && (viewport_delta_pos.x != 0.0f || viewport_delta_pos.y != 0.0f))
|
||||||
for (int window_n = 0; window_n < g.Windows.Size; window_n++)
|
TranslateWindowsInViewport(viewport, viewport->LastPos, viewport->Pos);
|
||||||
if (g.Windows[window_n]->Viewport == viewport || (g.ConfigFlagsForFrame & ImGuiConfigFlags_ViewportsEnable) == 0)
|
|
||||||
TranslateWindow(g.Windows[window_n], viewport_delta);
|
|
||||||
|
|
||||||
// Update DPI scale
|
// Update DPI scale
|
||||||
float new_dpi_scale;
|
float new_dpi_scale;
|
||||||
@ -10513,7 +10531,7 @@ static void ImGui::UpdateViewportsNewFrame()
|
|||||||
viewport->DpiScale = new_dpi_scale;
|
viewport->DpiScale = new_dpi_scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(g.ConfigFlagsForFrame & ImGuiConfigFlags_ViewportsEnable))
|
if (!(g.ConfigFlagsCurrFrame & ImGuiConfigFlags_ViewportsEnable))
|
||||||
{
|
{
|
||||||
g.MouseViewport = main_viewport;
|
g.MouseViewport = main_viewport;
|
||||||
return;
|
return;
|
||||||
@ -10657,7 +10675,7 @@ static void ImGui::UpdateSelectWindowViewport(ImGuiWindow* window)
|
|||||||
|
|
||||||
// Restore main viewport if multi-viewport is not supported by the back-end
|
// Restore main viewport if multi-viewport is not supported by the back-end
|
||||||
ImGuiViewportP* main_viewport = g.Viewports[0];
|
ImGuiViewportP* main_viewport = g.Viewports[0];
|
||||||
if (!(g.ConfigFlagsForFrame & ImGuiConfigFlags_ViewportsEnable))
|
if (!(g.ConfigFlagsCurrFrame & ImGuiConfigFlags_ViewportsEnable))
|
||||||
{
|
{
|
||||||
SetWindowViewport(window, main_viewport);
|
SetWindowViewport(window, main_viewport);
|
||||||
return;
|
return;
|
||||||
@ -10783,7 +10801,7 @@ void ImGui::UpdatePlatformWindows()
|
|||||||
IM_ASSERT(g.FrameCountEnded == g.FrameCount && "Forgot to call Render() or EndFrame() before UpdatePlatformWindows()?");
|
IM_ASSERT(g.FrameCountEnded == g.FrameCount && "Forgot to call Render() or EndFrame() before UpdatePlatformWindows()?");
|
||||||
IM_ASSERT(g.FrameCountPlatformEnded < g.FrameCount);
|
IM_ASSERT(g.FrameCountPlatformEnded < g.FrameCount);
|
||||||
g.FrameCountPlatformEnded = g.FrameCount;
|
g.FrameCountPlatformEnded = g.FrameCount;
|
||||||
if (!(g.ConfigFlagsForFrame & ImGuiConfigFlags_ViewportsEnable))
|
if (!(g.ConfigFlagsCurrFrame & ImGuiConfigFlags_ViewportsEnable))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Create/resize/destroy platform windows to match each active viewport.
|
// Create/resize/destroy platform windows to match each active viewport.
|
||||||
|
@ -997,7 +997,8 @@ struct ImGuiContext
|
|||||||
ImGuiIO IO;
|
ImGuiIO IO;
|
||||||
ImGuiPlatformIO PlatformIO;
|
ImGuiPlatformIO PlatformIO;
|
||||||
ImGuiStyle Style;
|
ImGuiStyle Style;
|
||||||
ImGuiConfigFlags ConfigFlagsForFrame; // = g.IO.ConfigFlags at the time of NewFrame()
|
ImGuiConfigFlags ConfigFlagsCurrFrame; // = g.IO.ConfigFlags at the time of NewFrame()
|
||||||
|
ImGuiConfigFlags ConfigFlagsLastFrame;
|
||||||
ImFont* Font; // (Shortcut) == FontStack.empty() ? IO.Font : FontStack.back()
|
ImFont* Font; // (Shortcut) == FontStack.empty() ? IO.Font : FontStack.back()
|
||||||
float FontSize; // (Shortcut) == FontBaseSize * g.CurrentWindow->FontWindowScale == window->FontSize(). Text height for current window.
|
float FontSize; // (Shortcut) == FontBaseSize * g.CurrentWindow->FontWindowScale == window->FontSize(). Text height for current window.
|
||||||
float FontBaseSize; // (Shortcut) == IO.FontGlobalScale * Font->Scale * Font->FontSize. Base text height.
|
float FontBaseSize; // (Shortcut) == IO.FontGlobalScale * Font->Scale * Font->FontSize. Base text height.
|
||||||
@ -1209,7 +1210,7 @@ struct ImGuiContext
|
|||||||
{
|
{
|
||||||
Initialized = false;
|
Initialized = false;
|
||||||
FrameScopeActive = FrameScopePushedFallbackWindow = false;
|
FrameScopeActive = FrameScopePushedFallbackWindow = false;
|
||||||
ConfigFlagsForFrame = ImGuiConfigFlags_None;
|
ConfigFlagsCurrFrame = ImGuiConfigFlags_None;
|
||||||
Font = NULL;
|
Font = NULL;
|
||||||
FontSize = FontBaseSize = 0.0f;
|
FontSize = FontBaseSize = 0.0f;
|
||||||
FontAtlasOwnedByContext = shared_font_atlas ? false : true;
|
FontAtlasOwnedByContext = shared_font_atlas ? false : true;
|
||||||
@ -1683,6 +1684,7 @@ namespace ImGui
|
|||||||
IMGUI_API void UpdateMouseMovingWindowEndFrame();
|
IMGUI_API void UpdateMouseMovingWindowEndFrame();
|
||||||
|
|
||||||
// Viewports
|
// Viewports
|
||||||
|
IMGUI_API void TranslateWindowsInViewport(ImGuiViewportP* viewport, const ImVec2& old_pos, const ImVec2& new_pos);
|
||||||
IMGUI_API void ScaleWindowsInViewport(ImGuiViewportP* viewport, float scale);
|
IMGUI_API void ScaleWindowsInViewport(ImGuiViewportP* viewport, float scale);
|
||||||
IMGUI_API void DestroyPlatformWindow(ImGuiViewportP* viewport);
|
IMGUI_API void DestroyPlatformWindow(ImGuiViewportP* viewport);
|
||||||
IMGUI_API void ShowViewportThumbnails();
|
IMGUI_API void ShowViewportThumbnails();
|
||||||
|
Loading…
Reference in New Issue
Block a user