@ -1012,6 +1012,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.
@ -3045,7 +3046,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 )
@ -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 )
{
window - > Pos + = delta ;
@ -3461,7 +3512,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 ) )
@ -3516,6 +3568,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 ( ) ;
@ -3768,51 +3821,11 @@ static ImGuiWindow* FindFrontMostVisibleChildWindow(ImGuiWindow* 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 ;
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 ( ) ;
const bool dim_bg_for_modal = ( modal_window ! = 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 ) ;
}
// CTRL-TAB
// Draw modal whitening background between CTRL-TAB list
if ( dim_bg_for_window_list )
{
// 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 - > 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 )
NavUpdateWindowingList ( ) ;
@ -3880,49 +3936,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 ) | | 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)
UpdateViewportsEndFrame ( ) ;
@ -5800,11 +5819,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 ;
@ -10115,12 +10135,6 @@ void ImGui::DockContextNewFrameUpdateDocking(ImGuiContext* ctx)
DockNodeUpdate ( node ) ;
}
// Docking context update function, called by EndFrame()
void ImGui : : DockContextEndFrame ( ImGuiContext * ctx )
{
( void ) ctx ;
}
static ImGuiDockNode * ImGui : : DockContextFindNodeByID ( ImGuiContext * ctx , ImGuiID id )
{
return ( ImGuiDockNode * ) ctx - > DockContext - > Nodes . GetVoidPtr ( id ) ;