|
@@ -1012,6 +1012,7 @@ static ImGuiWindow* NavRestoreLastChildNavWindow(ImGuiWindow* window);
|
|
static void UpdateMouseInputs();
|
|
static void UpdateMouseInputs();
|
|
static void UpdateMouseWheel();
|
|
static void UpdateMouseWheel();
|
|
static void UpdateManualResize(ImGuiWindow* window, const ImVec2& size_auto_fit, int* border_held, int resize_grip_count, ImU32 resize_grip_col[4]);
|
|
static void UpdateManualResize(ImGuiWindow* window, const ImVec2& size_auto_fit, int* border_held, int resize_grip_count, ImU32 resize_grip_col[4]);
|
|
|
|
+static void EndFrameDrawDimmedBackgrounds();
|
|
|
|
|
|
// Viewports
|
|
// Viewports
|
|
const ImGuiID IMGUI_VIEWPORT_DEFAULT_ID = 0x11111111; // Using an arbitrary constant instead of e.g. ImHash("ViewportDefault", 0); so it's easier to spot in the debugger. The exact value doesn't matter.
|
|
const ImGuiID IMGUI_VIEWPORT_DEFAULT_ID = 0x11111111; // Using an arbitrary constant instead of e.g. ImHash("ViewportDefault", 0); so it's easier to spot in the debugger. The exact value doesn't matter.
|
|
@@ -3045,7 +3046,7 @@ void ImGui::StartMouseMovingWindow(ImGuiWindow* window)
|
|
|
|
|
|
// Handle mouse moving window
|
|
// Handle mouse moving window
|
|
// Note: moving window with the navigation keys (Square + d-pad / CTRL+TAB + Arrows) are processed in NavUpdateWindowing()
|
|
// Note: moving window with the navigation keys (Square + d-pad / CTRL+TAB + Arrows) are processed in NavUpdateWindowing()
|
|
-void ImGui::UpdateMouseMovingWindow()
|
|
|
|
|
|
+void ImGui::UpdateMouseMovingWindowNewFrame()
|
|
{
|
|
{
|
|
ImGuiContext& g = *GImGui;
|
|
ImGuiContext& g = *GImGui;
|
|
if (g.MovingWindow != NULL)
|
|
if (g.MovingWindow != NULL)
|
|
@@ -3097,6 +3098,56 @@ void ImGui::UpdateMouseMovingWindow()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+// Initiate moving window, handle left-click and right-click focus
|
|
|
|
+void ImGui::UpdateMouseMovingWindowEndFrame()
|
|
|
|
+{
|
|
|
|
+ // Initiate moving window
|
|
|
|
+ ImGuiContext& g = *GImGui;
|
|
|
|
+ if (g.ActiveId != 0 || g.HoveredId != 0)
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ // Unless we just made a window/popup appear
|
|
|
|
+ if (g.NavWindow && g.NavWindow->Appearing)
|
|
|
|
+ return;
|
|
|
|
+
|
|
|
|
+ // Click to focus window and start moving (after we're done with all our widgets)
|
|
|
|
+ if (g.IO.MouseClicked[0])
|
|
|
|
+ {
|
|
|
|
+ if (g.HoveredRootWindow != NULL)
|
|
|
|
+ {
|
|
|
|
+ StartMouseMovingWindow(g.HoveredWindow);
|
|
|
|
+ if (g.IO.ConfigWindowsMoveFromTitleBarOnly && (!(g.HoveredRootWindow->Flags & ImGuiWindowFlags_NoTitleBar) || g.HoveredWindow->RootWindowDockStop->DockIsActive))
|
|
|
|
+ if (!g.HoveredRootWindow->TitleBarRect().Contains(g.IO.MouseClickedPos[0]))
|
|
|
|
+ g.MovingWindow = NULL;
|
|
|
|
+ }
|
|
|
|
+ else if (g.NavWindow != NULL && GetFrontMostPopupModal() == NULL)
|
|
|
|
+ {
|
|
|
|
+ FocusWindow(NULL); // Clicking on void disable focus
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // With right mouse button we close popups without changing focus
|
|
|
|
+ // (The left mouse button path calls FocusWindow which will lead NewFrame->ClosePopupsOverWindow to trigger)
|
|
|
|
+ if (g.IO.MouseClicked[1])
|
|
|
|
+ {
|
|
|
|
+ // Find the top-most window between HoveredWindow and the front most Modal Window.
|
|
|
|
+ // This is where we can trim the popup stack.
|
|
|
|
+ ImGuiWindow* modal = GetFrontMostPopupModal();
|
|
|
|
+ bool hovered_window_above_modal = false;
|
|
|
|
+ if (modal == NULL)
|
|
|
|
+ hovered_window_above_modal = true;
|
|
|
|
+ for (int i = g.Windows.Size - 1; i >= 0 && hovered_window_above_modal == false; i--)
|
|
|
|
+ {
|
|
|
|
+ ImGuiWindow* window = g.Windows[i];
|
|
|
|
+ if (window == modal)
|
|
|
|
+ break;
|
|
|
|
+ if (window == g.HoveredWindow)
|
|
|
|
+ hovered_window_above_modal = true;
|
|
|
|
+ }
|
|
|
|
+ ClosePopupsOverWindow(hovered_window_above_modal ? g.HoveredWindow : modal);
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
static void TranslateWindow(ImGuiWindow* window, const ImVec2& delta)
|
|
static void TranslateWindow(ImGuiWindow* window, const ImVec2& delta)
|
|
{
|
|
{
|
|
window->Pos += delta;
|
|
window->Pos += delta;
|
|
@@ -3461,7 +3512,8 @@ void ImGui::NewFrame()
|
|
UpdateHoveredWindowAndCaptureFlags();
|
|
UpdateHoveredWindowAndCaptureFlags();
|
|
|
|
|
|
// Handle user moving window with mouse (at the beginning of the frame to avoid input lag or sheering)
|
|
// Handle user moving window with mouse (at the beginning of the frame to avoid input lag or sheering)
|
|
- UpdateMouseMovingWindow();
|
|
|
|
|
|
+ UpdateMouseMovingWindowNewFrame();
|
|
|
|
+ UpdateHoveredWindowAndCaptureFlags();
|
|
|
|
|
|
// Background darkening/whitening
|
|
// Background darkening/whitening
|
|
if (GetFrontMostPopupModal() != NULL || (g.NavWindowingTarget != NULL && g.NavWindowingHighlightAlpha > 0.0f))
|
|
if (GetFrontMostPopupModal() != NULL || (g.NavWindowingTarget != NULL && g.NavWindowingHighlightAlpha > 0.0f))
|
|
@@ -3516,6 +3568,7 @@ void ImGui::NewFrame()
|
|
// This fallback is particularly important as it avoid ImGui:: calls from crashing.
|
|
// This fallback is particularly important as it avoid ImGui:: calls from crashing.
|
|
SetNextWindowSize(ImVec2(400,400), ImGuiCond_FirstUseEver);
|
|
SetNextWindowSize(ImVec2(400,400), ImGuiCond_FirstUseEver);
|
|
Begin("Debug##Default");
|
|
Begin("Debug##Default");
|
|
|
|
+ g.FrameScopePushedImplicitWindow = true;
|
|
|
|
|
|
#ifdef IMGUI_ENABLE_TEST_ENGINE
|
|
#ifdef IMGUI_ENABLE_TEST_ENGINE
|
|
ImGuiTestEngineHook_PostNewFrame();
|
|
ImGuiTestEngineHook_PostNewFrame();
|
|
@@ -3768,51 +3821,11 @@ static ImGuiWindow* FindFrontMostVisibleChildWindow(ImGuiWindow* window)
|
|
return window;
|
|
return window;
|
|
}
|
|
}
|
|
|
|
|
|
-// This is normally called by Render(). You may want to call it directly if you want to avoid calling Render() but the gain will be very minimal.
|
|
|
|
-void ImGui::EndFrame()
|
|
|
|
|
|
+static void ImGui::EndFrameDrawDimmedBackgrounds()
|
|
{
|
|
{
|
|
ImGuiContext& g = *GImGui;
|
|
ImGuiContext& g = *GImGui;
|
|
- IM_ASSERT(g.Initialized);
|
|
|
|
- if (g.FrameCountEnded == g.FrameCount) // Don't process EndFrame() multiple times.
|
|
|
|
- return;
|
|
|
|
- IM_ASSERT(g.FrameScopeActive && "Forgot to call ImGui::NewFrame()?");
|
|
|
|
-
|
|
|
|
- g.FrameScopeActive = false;
|
|
|
|
- g.FrameCountEnded = g.FrameCount;
|
|
|
|
-
|
|
|
|
- // Notify OS when our Input Method Editor cursor has moved (e.g. CJK inputs using Microsoft IME)
|
|
|
|
- if (g.PlatformIO.Platform_SetImeInputPos && ImLengthSqr(g.PlatformImePos - g.PlatformImeLastPos) > 0.0001f && g.PlatformImePosViewport && g.PlatformImePosViewport->PlatformWindowCreated)
|
|
|
|
- {
|
|
|
|
- g.PlatformIO.Platform_SetImeInputPos(g.PlatformImePosViewport, g.PlatformImePos);
|
|
|
|
- g.PlatformImeLastPos = g.PlatformImePos;
|
|
|
|
- g.PlatformImePosViewport = NULL;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Report when there is a mismatch of Begin/BeginChild vs End/EndChild calls. Important: Remember that the Begin/BeginChild API requires you
|
|
|
|
- // to always call End/EndChild even if Begin/BeginChild returns false! (this is unfortunately inconsistent with most other Begin* API).
|
|
|
|
- if (g.CurrentWindowStack.Size != 1)
|
|
|
|
- {
|
|
|
|
- if (g.CurrentWindowStack.Size > 1)
|
|
|
|
- {
|
|
|
|
- IM_ASSERT(g.CurrentWindowStack.Size == 1 && "Mismatched Begin/BeginChild vs End/EndChild calls: did you forget to call End/EndChild?");
|
|
|
|
- while (g.CurrentWindowStack.Size > 1) // FIXME-ERRORHANDLING
|
|
|
|
- End();
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- IM_ASSERT(g.CurrentWindowStack.Size == 1 && "Mismatched Begin/BeginChild vs End/EndChild calls: did you call End/EndChild too much?");
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // Hide implicit/fallback "Debug" window if it hasn't been used
|
|
|
|
- if (g.CurrentWindow && !g.CurrentWindow->WriteAccessed)
|
|
|
|
- g.CurrentWindow->Active = false;
|
|
|
|
- End();
|
|
|
|
-
|
|
|
|
- // Docking
|
|
|
|
- DockContextEndFrame(&g);
|
|
|
|
|
|
|
|
- // Draw modal whitening background on _other_ viewports than the one the modal or target are on
|
|
|
|
|
|
+ // Draw modal whitening background on _other_ viewports than the one the modal is one
|
|
ImGuiWindow* modal_window = GetFrontMostPopupModal();
|
|
ImGuiWindow* modal_window = GetFrontMostPopupModal();
|
|
const bool dim_bg_for_modal = (modal_window != NULL);
|
|
const bool dim_bg_for_modal = (modal_window != NULL);
|
|
const bool dim_bg_for_window_list = (g.NavWindowingTargetAnim != NULL);
|
|
const bool dim_bg_for_window_list = (g.NavWindowingTargetAnim != NULL);
|
|
@@ -3831,7 +3844,7 @@ void ImGui::EndFrame()
|
|
draw_list->AddRectFilled(viewport->Pos, viewport->Pos + viewport->Size, dim_bg_col);
|
|
draw_list->AddRectFilled(viewport->Pos, viewport->Pos + viewport->Size, dim_bg_col);
|
|
}
|
|
}
|
|
|
|
|
|
- // CTRL-TAB
|
|
|
|
|
|
+ // Draw modal whitening background between CTRL-TAB list
|
|
if (dim_bg_for_window_list)
|
|
if (dim_bg_for_window_list)
|
|
{
|
|
{
|
|
// Choose a draw list that will be front-most across all our children
|
|
// Choose a draw list that will be front-most across all our children
|
|
@@ -3856,8 +3869,51 @@ void ImGui::EndFrame()
|
|
draw_list->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_NavWindowingHighlight, g.NavWindowingHighlightAlpha), rounding, ~0, 3.0f);
|
|
draw_list->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_NavWindowingHighlight, g.NavWindowingHighlightAlpha), rounding, ~0, 3.0f);
|
|
draw_list->PopClipRect();
|
|
draw_list->PopClipRect();
|
|
}
|
|
}
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// This is normally called by Render(). You may want to call it directly if you want to avoid calling Render() but the gain will be very minimal.
|
|
|
|
+void ImGui::EndFrame()
|
|
|
|
+{
|
|
|
|
+ ImGuiContext& g = *GImGui;
|
|
|
|
+ IM_ASSERT(g.Initialized);
|
|
|
|
+ if (g.FrameCountEnded == g.FrameCount) // Don't process EndFrame() multiple times.
|
|
|
|
+ return;
|
|
|
|
+ IM_ASSERT(g.FrameScopeActive && "Forgot to call ImGui::NewFrame()?");
|
|
|
|
|
|
- // Show CTRL+TAB list
|
|
|
|
|
|
+ // Notify OS when our Input Method Editor cursor has moved (e.g. CJK inputs using Microsoft IME)
|
|
|
|
+ if (g.PlatformIO.Platform_SetImeInputPos && ImLengthSqr(g.PlatformImePos - g.PlatformImeLastPos) > 0.0001f && g.PlatformImePosViewport && g.PlatformImePosViewport->PlatformWindowCreated)
|
|
|
|
+ {
|
|
|
|
+ g.PlatformIO.Platform_SetImeInputPos(g.PlatformImePosViewport, g.PlatformImePos);
|
|
|
|
+ g.PlatformImeLastPos = g.PlatformImePos;
|
|
|
|
+ g.PlatformImePosViewport = NULL;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Report when there is a mismatch of Begin/BeginChild vs End/EndChild calls. Important: Remember that the Begin/BeginChild API requires you
|
|
|
|
+ // to always call End/EndChild even if Begin/BeginChild returns false! (this is unfortunately inconsistent with most other Begin* API).
|
|
|
|
+ if (g.CurrentWindowStack.Size != 1)
|
|
|
|
+ {
|
|
|
|
+ if (g.CurrentWindowStack.Size > 1)
|
|
|
|
+ {
|
|
|
|
+ IM_ASSERT(g.CurrentWindowStack.Size == 1 && "Mismatched Begin/BeginChild vs End/EndChild calls: did you forget to call End/EndChild?");
|
|
|
|
+ while (g.CurrentWindowStack.Size > 1) // FIXME-ERRORHANDLING
|
|
|
|
+ End();
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ IM_ASSERT(g.CurrentWindowStack.Size == 1 && "Mismatched Begin/BeginChild vs End/EndChild calls: did you call End/EndChild too much?");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Hide implicit/fallback "Debug" window if it hasn't been used
|
|
|
|
+ g.FrameScopePushedImplicitWindow = false;
|
|
|
|
+ if (g.CurrentWindow && !g.CurrentWindow->WriteAccessed)
|
|
|
|
+ g.CurrentWindow->Active = false;
|
|
|
|
+ End();
|
|
|
|
+
|
|
|
|
+ // Draw modal whitening background on _other_ viewports than the one the modal is one
|
|
|
|
+ EndFrameDrawDimmedBackgrounds();
|
|
|
|
+
|
|
|
|
+ // Show CTRL+TAB list window
|
|
if (g.NavWindowingTarget)
|
|
if (g.NavWindowingTarget)
|
|
NavUpdateWindowingList();
|
|
NavUpdateWindowingList();
|
|
|
|
|
|
@@ -3880,49 +3936,12 @@ void ImGui::EndFrame()
|
|
g.DragDropWithinSourceOrTarget = false;
|
|
g.DragDropWithinSourceOrTarget = false;
|
|
}
|
|
}
|
|
|
|
|
|
- // Initiate moving window
|
|
|
|
- if (g.ActiveId == 0 && g.HoveredId == 0)
|
|
|
|
- {
|
|
|
|
- if (!g.NavWindow || !g.NavWindow->Appearing) // Unless we just made a window/popup appear
|
|
|
|
- {
|
|
|
|
- // Click to focus window and start moving (after we're done with all our widgets)
|
|
|
|
- if (g.IO.MouseClicked[0])
|
|
|
|
- {
|
|
|
|
- if (g.HoveredRootWindow != NULL)
|
|
|
|
- {
|
|
|
|
- StartMouseMovingWindow(g.HoveredWindow);
|
|
|
|
- if (g.IO.ConfigWindowsMoveFromTitleBarOnly && (!(g.HoveredRootWindow->Flags & ImGuiWindowFlags_NoTitleBar) || g.HoveredWindow->RootWindowDockStop->DockIsActive))
|
|
|
|
- if (!g.HoveredRootWindow->TitleBarRect().Contains(g.IO.MouseClickedPos[0]))
|
|
|
|
- g.MovingWindow = NULL;
|
|
|
|
- }
|
|
|
|
- else if (g.NavWindow != NULL && GetFrontMostPopupModal() == NULL)
|
|
|
|
- {
|
|
|
|
- FocusWindow(NULL); // Clicking on void disable focus
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+ // End frame
|
|
|
|
+ g.FrameScopeActive = false;
|
|
|
|
+ g.FrameCountEnded = g.FrameCount;
|
|
|
|
|
|
- // With right mouse button we close popups without changing focus
|
|
|
|
- // (The left mouse button path calls FocusWindow which will lead NewFrame->ClosePopupsOverWindow to trigger)
|
|
|
|
- if (g.IO.MouseClicked[1])
|
|
|
|
- {
|
|
|
|
- // Find the top-most window between HoveredWindow and the front most Modal Window.
|
|
|
|
- // This is where we can trim the popup stack.
|
|
|
|
- ImGuiWindow* modal = GetFrontMostPopupModal();
|
|
|
|
- bool hovered_window_above_modal = false;
|
|
|
|
- if (modal == NULL)
|
|
|
|
- hovered_window_above_modal = true;
|
|
|
|
- for (int i = g.Windows.Size - 1; i >= 0 && hovered_window_above_modal == false; i--)
|
|
|
|
- {
|
|
|
|
- ImGuiWindow* window = g.Windows[i];
|
|
|
|
- if (window == modal)
|
|
|
|
- break;
|
|
|
|
- if (window == g.HoveredWindow)
|
|
|
|
- hovered_window_above_modal = true;
|
|
|
|
- }
|
|
|
|
- ClosePopupsOverWindow(hovered_window_above_modal ? g.HoveredWindow : modal);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+ // Initiate moving window + handle left-click and right-click focus
|
|
|
|
+ UpdateMouseMovingWindowEndFrame();
|
|
|
|
|
|
// Update user-facing viewport list (g.Viewports -> g.PlatformIO.Viewports after filtering out some)
|
|
// Update user-facing viewport list (g.Viewports -> g.PlatformIO.Viewports after filtering out some)
|
|
UpdateViewportsEndFrame();
|
|
UpdateViewportsEndFrame();
|
|
@@ -5800,11 +5819,12 @@ void ImGui::End()
|
|
{
|
|
{
|
|
ImGuiContext& g = *GImGui;
|
|
ImGuiContext& g = *GImGui;
|
|
|
|
|
|
- if (g.CurrentWindowStack.Size <= 1 && g.FrameScopeActive)
|
|
|
|
|
|
+ if (g.CurrentWindowStack.Size <= 1 && g.FrameScopePushedImplicitWindow)
|
|
{
|
|
{
|
|
IM_ASSERT(g.CurrentWindowStack.Size > 1 && "Calling End() too many times!");
|
|
IM_ASSERT(g.CurrentWindowStack.Size > 1 && "Calling End() too many times!");
|
|
return; // FIXME-ERRORHANDLING
|
|
return; // FIXME-ERRORHANDLING
|
|
}
|
|
}
|
|
|
|
+ IM_ASSERT(g.CurrentWindowStack.Size > 0);
|
|
|
|
|
|
ImGuiWindow* window = g.CurrentWindow;
|
|
ImGuiWindow* window = g.CurrentWindow;
|
|
|
|
|
|
@@ -10115,12 +10135,6 @@ void ImGui::DockContextNewFrameUpdateDocking(ImGuiContext* ctx)
|
|
DockNodeUpdate(node);
|
|
DockNodeUpdate(node);
|
|
}
|
|
}
|
|
|
|
|
|
-// Docking context update function, called by EndFrame()
|
|
|
|
-void ImGui::DockContextEndFrame(ImGuiContext* ctx)
|
|
|
|
-{
|
|
|
|
- (void)ctx;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
static ImGuiDockNode* ImGui::DockContextFindNodeByID(ImGuiContext* ctx, ImGuiID id)
|
|
static ImGuiDockNode* ImGui::DockContextFindNodeByID(ImGuiContext* ctx, ImGuiID id)
|
|
{
|
|
{
|
|
return (ImGuiDockNode*)ctx->DockContext->Nodes.GetVoidPtr(id);
|
|
return (ImGuiDockNode*)ctx->DockContext->Nodes.GetVoidPtr(id);
|