@ -4034,132 +4034,6 @@ void ImGui::EndTooltip()
End ( ) ;
}
// Mark popup as open (toggle toward open state).
// Popups are closed when user click outside, or activate a pressable item, or CloseCurrentPopup() is called within a BeginPopup()/EndPopup() block.
// Popup identifiers are relative to the current ID-stack (so OpenPopup and BeginPopup needs to be at the same level).
// One open popup per level of the popup hierarchy (NB: when assigning we reset the Window member of ImGuiPopupRef to NULL)
void ImGui : : OpenPopupEx ( ImGuiID id )
{
ImGuiContext & g = * GImGui ;
ImGuiWindow * parent_window = g . CurrentWindow ;
int current_stack_size = g . CurrentPopupStack . Size ;
ImGuiPopupRef popup_ref ; // Tagged as new ref as Window will be set back to NULL if we write this into OpenPopupStack.
popup_ref . PopupId = id ;
popup_ref . Window = NULL ;
popup_ref . ParentWindow = parent_window ;
popup_ref . OpenFrameCount = g . FrameCount ;
popup_ref . OpenParentId = parent_window - > IDStack . back ( ) ;
popup_ref . OpenMousePos = g . IO . MousePos ;
popup_ref . OpenPopupPos = NavCalcPreferredRefPos ( ) ;
//printf("[%05d] OpenPopupEx(0x%08X)\n", g.FrameCount, id);
if ( g . OpenPopupStack . Size < current_stack_size + 1 )
{
g . OpenPopupStack . push_back ( popup_ref ) ;
}
else
{
// Gently handle the user mistakenly calling OpenPopup() every frame. It is a programming mistake! However, if we were to run the regular code path, the ui
// would become completely unusable because the popup will always be in hidden-while-calculating-size state _while_ claiming focus. Which would be a very confusing
// situation for the programmer. Instead, we silently allow the popup to proceed, it will keep reappearing and the programming error will be more obvious to understand.
if ( g . OpenPopupStack [ current_stack_size ] . PopupId = = id & & g . OpenPopupStack [ current_stack_size ] . OpenFrameCount = = g . FrameCount - 1 )
{
g . OpenPopupStack [ current_stack_size ] . OpenFrameCount = popup_ref . OpenFrameCount ;
}
else
{
// Close child popups if any, then flag popup for open/reopen
g . OpenPopupStack . resize ( current_stack_size + 1 ) ;
g . OpenPopupStack [ current_stack_size ] = popup_ref ;
}
// When reopening a popup we first refocus its parent, otherwise if its parent is itself a popup it would get closed by ClosePopupsOverWindow().
// This is equivalent to what ClosePopupToLevel() does.
//if (g.OpenPopupStack[current_stack_size].PopupId == id)
// FocusWindow(parent_window);
}
}
void ImGui : : OpenPopup ( const char * str_id )
{
ImGuiContext & g = * GImGui ;
OpenPopupEx ( g . CurrentWindow - > GetID ( str_id ) ) ;
}
void ImGui : : ClosePopupsOverWindow ( ImGuiWindow * ref_window )
{
ImGuiContext & g = * GImGui ;
if ( g . OpenPopupStack . empty ( ) )
return ;
// When popups are stacked, clicking on a lower level popups puts focus back to it and close popups above it.
// Don't close our own child popup windows.
int n = 0 ;
if ( ref_window )
{
for ( n = 0 ; n < g . OpenPopupStack . Size ; n + + )
{
ImGuiPopupRef & popup = g . OpenPopupStack [ n ] ;
if ( ! popup . Window )
continue ;
IM_ASSERT ( ( popup . Window - > Flags & ImGuiWindowFlags_Popup ) ! = 0 ) ;
if ( popup . Window - > Flags & ImGuiWindowFlags_ChildWindow )
continue ;
// Trim the stack if popups are not direct descendant of the reference window (which is often the NavWindow)
bool has_focus = false ;
for ( int m = n ; m < g . OpenPopupStack . Size & & ! has_focus ; m + + )
has_focus = ( g . OpenPopupStack [ m ] . Window & & g . OpenPopupStack [ m ] . Window - > RootWindow = = ref_window - > RootWindow ) ;
if ( ! has_focus )
break ;
}
}
if ( n < g . OpenPopupStack . Size ) // This test is not required but it allows to set a convenient breakpoint on the block below
ClosePopupToLevel ( n ) ;
}
ImGuiWindow * ImGui : : GetFrontMostPopupModal ( )
{
ImGuiContext & g = * GImGui ;
for ( int n = g . OpenPopupStack . Size - 1 ; n > = 0 ; n - - )
if ( ImGuiWindow * popup = g . OpenPopupStack . Data [ n ] . Window )
if ( popup - > Flags & ImGuiWindowFlags_Modal )
return popup ;
return NULL ;
}
void ImGui : : ClosePopupToLevel ( int remaining )
{
IM_ASSERT ( remaining > = 0 ) ;
ImGuiContext & g = * GImGui ;
ImGuiWindow * focus_window = ( remaining > 0 ) ? g . OpenPopupStack [ remaining - 1 ] . Window : g . OpenPopupStack [ 0 ] . ParentWindow ;
if ( g . NavLayer = = 0 )
focus_window = NavRestoreLastChildNavWindow ( focus_window ) ;
FocusWindow ( focus_window ) ;
focus_window - > DC . NavHideHighlightOneFrame = true ;
g . OpenPopupStack . resize ( remaining ) ;
}
void ImGui : : ClosePopup ( ImGuiID id )
{
if ( ! IsPopupOpen ( id ) )
return ;
ImGuiContext & g = * GImGui ;
ClosePopupToLevel ( g . OpenPopupStack . Size - 1 ) ;
}
// Close the popup we have begin-ed into.
void ImGui : : CloseCurrentPopup ( )
{
ImGuiContext & g = * GImGui ;
int popup_idx = g . CurrentPopupStack . Size - 1 ;
if ( popup_idx < 0 | | popup_idx > = g . OpenPopupStack . Size | | g . CurrentPopupStack [ popup_idx ] . PopupId ! = g . OpenPopupStack [ popup_idx ] . PopupId )
return ;
while ( popup_idx > 0 & & g . OpenPopupStack [ popup_idx ] . Window & & ( g . OpenPopupStack [ popup_idx ] . Window - > Flags & ImGuiWindowFlags_ChildMenu ) )
popup_idx - - ;
ClosePopupToLevel ( popup_idx ) ;
}
bool ImGui : : BeginPopupEx ( ImGuiID id , ImGuiWindowFlags extra_flags )
{
ImGuiContext & g = * GImGui ;
@ -4193,18 +4067,6 @@ bool ImGui::BeginPopup(const char* str_id, ImGuiWindowFlags flags)
return BeginPopupEx ( g . CurrentWindow - > GetID ( str_id ) , flags | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoSavedSettings ) ;
}
bool ImGui : : IsPopupOpen ( ImGuiID id )
{
ImGuiContext & g = * GImGui ;
return g . OpenPopupStack . Size > g . CurrentPopupStack . Size & & g . OpenPopupStack [ g . CurrentPopupStack . Size ] . PopupId = = id ;
}
bool ImGui : : IsPopupOpen ( const char * str_id )
{
ImGuiContext & g = * GImGui ;
return g . OpenPopupStack . Size > g . CurrentPopupStack . Size & & g . OpenPopupStack [ g . CurrentPopupStack . Size ] . PopupId = = g . CurrentWindow - > GetID ( str_id ) ;
}
bool ImGui : : BeginPopupModal ( const char * name , bool * p_open , ImGuiWindowFlags flags )
{
ImGuiContext & g = * GImGui ;
@ -4229,7 +4091,6 @@ bool ImGui::BeginPopupModal(const char* name, bool* p_open, ImGuiWindowFlags fla
ClosePopup ( id ) ;
return false ;
}
return is_open ;
}
@ -4245,19 +4106,6 @@ void ImGui::EndPopup()
End ( ) ;
}
bool ImGui : : OpenPopupOnItemClick ( const char * str_id , int mouse_button )
{
ImGuiWindow * window = GImGui - > CurrentWindow ;
if ( IsMouseReleased ( mouse_button ) & & IsItemHovered ( ImGuiHoveredFlags_AllowWhenBlockedByPopup ) )
{
ImGuiID id = str_id ? window - > GetID ( str_id ) : window - > DC . LastItemId ; // If user hasn't passed an ID, we can use the LastItemID. Using LastItemID as a Popup ID won't conflict!
IM_ASSERT ( id ! = 0 ) ; // You cannot pass a NULL str_id if the last item has no identifier (e.g. a Text() item)
OpenPopupEx ( id ) ;
return true ;
}
return false ;
}
// This is a helper to handle the simplest case of associating one named popup to one given widget.
// You may want to handle this on user side if you have specific needs (e.g. tweaking IsItemHovered() parameters).
// You can pass a NULL str_id to use the identifier of the last item.
@ -4335,7 +4183,6 @@ static bool ImGui::BeginChildEx(const char* name, ImGuiID id, const ImVec2& size
SetActiveID ( id + 1 , child_window ) ; // Steal ActiveId with a dummy id so that key-press won't activate child item
g . ActiveIdSource = ImGuiInputSource_Nav ;
}
return ret ;
}
@ -6764,6 +6611,161 @@ void ImGui::Unindent(float indent_w)
window - > DC . CursorPos . x = window - > Pos . x + window - > DC . Indent . x + window - > DC . ColumnsOffset . x ;
}
//-----------------------------------------------------------------------------
// POPUPS
//-----------------------------------------------------------------------------
bool ImGui : : IsPopupOpen ( ImGuiID id )
{
ImGuiContext & g = * GImGui ;
return g . OpenPopupStack . Size > g . CurrentPopupStack . Size & & g . OpenPopupStack [ g . CurrentPopupStack . Size ] . PopupId = = id ;
}
bool ImGui : : IsPopupOpen ( const char * str_id )
{
ImGuiContext & g = * GImGui ;
return g . OpenPopupStack . Size > g . CurrentPopupStack . Size & & g . OpenPopupStack [ g . CurrentPopupStack . Size ] . PopupId = = g . CurrentWindow - > GetID ( str_id ) ;
}
ImGuiWindow * ImGui : : GetFrontMostPopupModal ( )
{
ImGuiContext & g = * GImGui ;
for ( int n = g . OpenPopupStack . Size - 1 ; n > = 0 ; n - - )
if ( ImGuiWindow * popup = g . OpenPopupStack . Data [ n ] . Window )
if ( popup - > Flags & ImGuiWindowFlags_Modal )
return popup ;
return NULL ;
}
void ImGui : : OpenPopup ( const char * str_id )
{
ImGuiContext & g = * GImGui ;
OpenPopupEx ( g . CurrentWindow - > GetID ( str_id ) ) ;
}
// Mark popup as open (toggle toward open state).
// Popups are closed when user click outside, or activate a pressable item, or CloseCurrentPopup() is called within a BeginPopup()/EndPopup() block.
// Popup identifiers are relative to the current ID-stack (so OpenPopup and BeginPopup needs to be at the same level).
// One open popup per level of the popup hierarchy (NB: when assigning we reset the Window member of ImGuiPopupRef to NULL)
void ImGui : : OpenPopupEx ( ImGuiID id )
{
ImGuiContext & g = * GImGui ;
ImGuiWindow * parent_window = g . CurrentWindow ;
int current_stack_size = g . CurrentPopupStack . Size ;
ImGuiPopupRef popup_ref ; // Tagged as new ref as Window will be set back to NULL if we write this into OpenPopupStack.
popup_ref . PopupId = id ;
popup_ref . Window = NULL ;
popup_ref . ParentWindow = parent_window ;
popup_ref . OpenFrameCount = g . FrameCount ;
popup_ref . OpenParentId = parent_window - > IDStack . back ( ) ;
popup_ref . OpenMousePos = g . IO . MousePos ;
popup_ref . OpenPopupPos = NavCalcPreferredRefPos ( ) ;
//printf("[%05d] OpenPopupEx(0x%08X)\n", g.FrameCount, id);
if ( g . OpenPopupStack . Size < current_stack_size + 1 )
{
g . OpenPopupStack . push_back ( popup_ref ) ;
}
else
{
// Gently handle the user mistakenly calling OpenPopup() every frame. It is a programming mistake! However, if we were to run the regular code path, the ui
// would become completely unusable because the popup will always be in hidden-while-calculating-size state _while_ claiming focus. Which would be a very confusing
// situation for the programmer. Instead, we silently allow the popup to proceed, it will keep reappearing and the programming error will be more obvious to understand.
if ( g . OpenPopupStack [ current_stack_size ] . PopupId = = id & & g . OpenPopupStack [ current_stack_size ] . OpenFrameCount = = g . FrameCount - 1 )
{
g . OpenPopupStack [ current_stack_size ] . OpenFrameCount = popup_ref . OpenFrameCount ;
}
else
{
// Close child popups if any, then flag popup for open/reopen
g . OpenPopupStack . resize ( current_stack_size + 1 ) ;
g . OpenPopupStack [ current_stack_size ] = popup_ref ;
}
// When reopening a popup we first refocus its parent, otherwise if its parent is itself a popup it would get closed by ClosePopupsOverWindow().
// This is equivalent to what ClosePopupToLevel() does.
//if (g.OpenPopupStack[current_stack_size].PopupId == id)
// FocusWindow(parent_window);
}
}
bool ImGui : : OpenPopupOnItemClick ( const char * str_id , int mouse_button )
{
ImGuiWindow * window = GImGui - > CurrentWindow ;
if ( IsMouseReleased ( mouse_button ) & & IsItemHovered ( ImGuiHoveredFlags_AllowWhenBlockedByPopup ) )
{
ImGuiID id = str_id ? window - > GetID ( str_id ) : window - > DC . LastItemId ; // If user hasn't passed an ID, we can use the LastItemID. Using LastItemID as a Popup ID won't conflict!
IM_ASSERT ( id ! = 0 ) ; // You cannot pass a NULL str_id if the last item has no identifier (e.g. a Text() item)
OpenPopupEx ( id ) ;
return true ;
}
return false ;
}
void ImGui : : ClosePopupsOverWindow ( ImGuiWindow * ref_window )
{
ImGuiContext & g = * GImGui ;
if ( g . OpenPopupStack . empty ( ) )
return ;
// When popups are stacked, clicking on a lower level popups puts focus back to it and close popups above it.
// Don't close our own child popup windows.
int n = 0 ;
if ( ref_window )
{
for ( n = 0 ; n < g . OpenPopupStack . Size ; n + + )
{
ImGuiPopupRef & popup = g . OpenPopupStack [ n ] ;
if ( ! popup . Window )
continue ;
IM_ASSERT ( ( popup . Window - > Flags & ImGuiWindowFlags_Popup ) ! = 0 ) ;
if ( popup . Window - > Flags & ImGuiWindowFlags_ChildWindow )
continue ;
// Trim the stack if popups are not direct descendant of the reference window (which is often the NavWindow)
bool has_focus = false ;
for ( int m = n ; m < g . OpenPopupStack . Size & & ! has_focus ; m + + )
has_focus = ( g . OpenPopupStack [ m ] . Window & & g . OpenPopupStack [ m ] . Window - > RootWindow = = ref_window - > RootWindow ) ;
if ( ! has_focus )
break ;
}
}
if ( n < g . OpenPopupStack . Size ) // This test is not required but it allows to set a convenient breakpoint on the block below
ClosePopupToLevel ( n ) ;
}
void ImGui : : ClosePopupToLevel ( int remaining )
{
IM_ASSERT ( remaining > = 0 ) ;
ImGuiContext & g = * GImGui ;
ImGuiWindow * focus_window = ( remaining > 0 ) ? g . OpenPopupStack [ remaining - 1 ] . Window : g . OpenPopupStack [ 0 ] . ParentWindow ;
if ( g . NavLayer = = 0 )
focus_window = NavRestoreLastChildNavWindow ( focus_window ) ;
FocusWindow ( focus_window ) ;
focus_window - > DC . NavHideHighlightOneFrame = true ;
g . OpenPopupStack . resize ( remaining ) ;
}
void ImGui : : ClosePopup ( ImGuiID id )
{
if ( ! IsPopupOpen ( id ) )
return ;
ImGuiContext & g = * GImGui ;
ClosePopupToLevel ( g . OpenPopupStack . Size - 1 ) ;
}
// Close the popup we have begin-ed into.
void ImGui : : CloseCurrentPopup ( )
{
ImGuiContext & g = * GImGui ;
int popup_idx = g . CurrentPopupStack . Size - 1 ;
if ( popup_idx < 0 | | popup_idx > = g . OpenPopupStack . Size | | g . CurrentPopupStack [ popup_idx ] . PopupId ! = g . OpenPopupStack [ popup_idx ] . PopupId )
return ;
while ( popup_idx > 0 & & g . OpenPopupStack [ popup_idx ] . Window & & ( g . OpenPopupStack [ popup_idx ] . Window - > Flags & ImGuiWindowFlags_ChildMenu ) )
popup_idx - - ;
ClosePopupToLevel ( popup_idx ) ;
}
//-----------------------------------------------------------------------------
// NAVIGATION
//-----------------------------------------------------------------------------