@ -1006,6 +1006,7 @@ static ImGuiWindow* NavRestoreLastChildNavWindow(ImGuiWindow* window);
static void UpdateMouseInputs ( ) ;
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 EndFrameDrawDimmedBackgrounds ( ) ;
// 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.
@ -3022,7 +3023,7 @@ void ImGui::StartMouseMovingWindow(ImGuiWindow* window)
// Handle mouse moving window
// Note: moving window with the navigation keys (Square + d-pad / CTRL+TAB + Arrows) are processed in NavUpdateWindowing()
void ImGui : : UpdateMouseMovingWindow ( )
void ImGui : : UpdateMouseMovingWindow NewFrame ( )
{
ImGuiContext & g = * GImGui ;
if ( g . MovingWindow ! = NULL )
@ -3074,6 +3075,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 ) )
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 )
{
window - > Pos + = delta ;
@ -3432,7 +3483,8 @@ void ImGui::NewFrame()
UpdateHoveredWindowAndCaptureFlags ( ) ;
// Handle user moving window with mouse (at the beginning of the frame to avoid input lag or sheering)
UpdateMouseMovingWindow ( ) ;
UpdateMouseMovingWindowNewFrame ( ) ;
UpdateHoveredWindowAndCaptureFlags ( ) ;
// Background darkening/whitening
if ( GetFrontMostPopupModal ( ) ! = NULL | | ( g . NavWindowingTarget ! = NULL & & g . NavWindowingHighlightAlpha > 0.0f ) )
@ -3484,6 +3536,7 @@ void ImGui::NewFrame()
// This fallback is particularly important as it avoid ImGui:: calls from crashing.
SetNextWindowSize ( ImVec2 ( 400 , 400 ) , ImGuiCond_FirstUseEver ) ;
Begin ( " Debug##Default " ) ;
g . FrameScopePushedImplicitWindow = true ;
# ifdef IMGUI_ENABLE_TEST_ENGINE
ImGuiTestEngineHook_PostNewFrame ( ) ;
@ -3720,6 +3773,29 @@ void ImGui::PopClipRect()
window - > ClipRect = window - > DrawList - > _ClipRectStack . back ( ) ;
}
// Draw modal whitening background on _other_ viewports than the one the modal is one
static void ImGui : : EndFrameDrawDimmedBackgrounds ( )
{
ImGuiContext & g = * GImGui ;
ImGuiWindow * modal_window = GetFrontMostPopupModal ( ) ;
const bool dim_bg_for_modal = ( modal_window ! = NULL ) ;
const bool dim_bg_for_window_list = ( g . NavWindowingTargetAnim ! = NULL ) ;
if ( dim_bg_for_modal | | dim_bg_for_window_list )
for ( int viewport_n = 0 ; viewport_n < g . Viewports . Size ; viewport_n + + )
{
ImGuiViewportP * viewport = g . Viewports [ viewport_n ] ;
if ( modal_window & & viewport = = modal_window - > Viewport )
continue ;
if ( g . NavWindowingList & & viewport = = g . NavWindowingList - > Viewport )
continue ;
if ( g . NavWindowingTargetAnim & & viewport = = g . NavWindowingTargetAnim - > Viewport )
continue ;
ImDrawList * draw_list = GetOverlayDrawList ( viewport ) ;
const ImU32 dim_bg_col = GetColorU32 ( dim_bg_for_modal ? ImGuiCol_ModalWindowDimBg : ImGuiCol_NavWindowingDimBg , g . DimBgRatio ) ;
draw_list - > AddRectFilled ( viewport - > Pos , viewport - > Pos + viewport - > Size , dim_bg_col ) ;
}
}
// 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 ( )
{
@ -3729,9 +3805,6 @@ void ImGui::EndFrame()
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 )
{
@ -3757,30 +3830,15 @@ void ImGui::EndFrame()
}
// 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
ImGuiWindow * modal_window = GetFrontMostPopupModal ( ) ;
const bool dim_bg_for_modal = ( modal_window ! = NULL ) ;
const bool dim_bg_for_window_list = ( g . NavWindowingTargetAnim ! = NULL ) ;
if ( dim_bg_for_modal | | dim_bg_for_window_list )
for ( int viewport_n = 0 ; viewport_n < g . Viewports . Size ; viewport_n + + )
{
ImGuiViewportP * viewport = g . Viewports [ viewport_n ] ;
if ( modal_window & & viewport = = modal_window - > Viewport )
continue ;
if ( g . NavWindowingList & & viewport = = g . NavWindowingList - > Viewport )
continue ;
if ( g . NavWindowingTargetAnim & & viewport = = g . NavWindowingTargetAnim - > Viewport )
continue ;
ImDrawList * draw_list = GetOverlayDrawList ( viewport ) ;
const ImU32 dim_bg_col = GetColorU32 ( dim_bg_for_modal ? ImGuiCol_ModalWindowDimBg : ImGuiCol_NavWindowingDimBg , g . DimBgRatio ) ;
draw_list - > AddRectFilled ( viewport - > Pos , viewport - > Pos + viewport - > Size , dim_bg_col ) ;
}
EndFrameDrawDimmedBackgrounds ( ) ;
// Show CTRL+TAB list
// Show CTRL+TAB list window
if ( g . NavWindowingTarget )
NavUpdateWindowingList ( ) ;
@ -3803,49 +3861,12 @@ void ImGui::EndFrame()
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 ) )
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)
UpdateViewportsEndFrame ( ) ;
@ -5608,11 +5629,12 @@ void ImGui::End()
{
ImGuiContext & g = * GImGui ;
if ( g . CurrentWindowStack . Size < = 1 & & g . FrameScope Active )
if ( g . CurrentWindowStack . Size < = 1 & & g . FrameScope PushedImplicitWindow )
{
IM_ASSERT ( g . CurrentWindowStack . Size > 1 & & " Calling End() too many times! " ) ;
return ; // FIXME-ERRORHANDLING
}
IM_ASSERT ( g . CurrentWindowStack . Size > 0 ) ;
ImGuiWindow * window = g . CurrentWindow ;