@ -1982,7 +1982,7 @@ void ImGuiStorage::BuildSortByKey()
{
struct StaticFunc
{
static int IMGUI_CDECL PairCompare ByID( const void * lhs , const void * rhs )
static int IMGUI_CDECL PairCompare r ByID( const void * lhs , const void * rhs )
{
// We can't just do a subtraction because qsort uses signed integers and subtracting our ID doesn't play well with that.
if ( ( ( const ImGuiStoragePair * ) lhs ) - > key > ( ( const ImGuiStoragePair * ) rhs ) - > key ) return + 1 ;
@ -1990,8 +1990,7 @@ void ImGuiStorage::BuildSortByKey()
return 0 ;
}
} ;
if ( Data . Size > 1 )
ImQsort ( Data . Data , ( size_t ) Data . Size , sizeof ( ImGuiStoragePair ) , StaticFunc : : PairCompareByID ) ;
ImQsort ( Data . Data , ( size_t ) Data . Size , sizeof ( ImGuiStoragePair ) , StaticFunc : : PairComparerByID ) ;
}
int ImGuiStorage : : GetInt ( ImGuiID key , int default_val ) const
@ -3169,7 +3168,7 @@ ImGuiID ImGuiWindow::GetIDNoKeepAlive(int n)
ImGuiID ImGuiWindow : : GetIDFromRectangle ( const ImRect & r_abs )
{
ImGuiID seed = IDStack . back ( ) ;
const int r_rel [ 4 ] = { ( int ) ( r_abs . Min . x - Pos . x ) , ( int ) ( r_abs . Min . y - Pos . y ) , ( int ) ( r_abs . Max . x - Pos . x ) , ( int ) ( r_abs . Max . y - Pos . y ) } ;
ImRect r_rel = ImGui : : WindowRectAbsToRel ( this , r_abs ) ;
ImGuiID id = ImHashData ( & r_rel , sizeof ( r_rel ) , seed ) ;
ImGui : : KeepAliveID ( id ) ;
return id ;
@ -3332,9 +3331,11 @@ bool ImGui::IsItemHovered(ImGuiHoveredFlags flags)
{
if ( ( g . LastItemData . InFlags & ImGuiItemFlags_Disabled ) & & ! ( flags & ImGuiHoveredFlags_AllowWhenDisabled ) )
return false ;
return IsItemFocused ( ) ;
if ( ! IsItemFocused ( ) )
return false ;
}
else
{
// Test for bounding box overlap, as updated as ItemAdd()
ImGuiItemStatusFlags status_flags = g . LastItemData . StatusFlags ;
if ( ! ( status_flags & ImGuiItemStatusFlags_HoveredRect ) )
@ -3368,6 +3369,8 @@ bool ImGui::IsItemHovered(ImGuiHoveredFlags flags)
// When the window is collapsed (SkipItems==true) that last item will never be overwritten so we need to detect the case.
if ( ( g . LastItemData . ID = = window - > ID | | g . LastItemData . ID = = window - > MoveId ) & & window - > WriteAccessed )
return false ;
}
return true ;
}
@ -4474,7 +4477,6 @@ static void AddWindowToSortBuffer(ImVector<ImGuiWindow*>* out_sorted_windows, Im
if ( window - > Active )
{
int count = window - > DC . ChildWindows . Size ;
if ( count > 1 )
ImQsort ( window - > DC . ChildWindows . Data , ( size_t ) count , sizeof ( ImGuiWindow * ) , ChildWindowComparer ) ;
for ( int i = 0 ; i < count ; i + + )
{
@ -6276,7 +6278,10 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
// Update ->RootWindow and others pointers (before any possible call to FocusWindow)
if ( first_begin_of_the_frame )
{
UpdateWindowParentAndRootLinks ( window , flags , parent_window ) ;
window - > ParentWindowInBeginStack = parent_window_in_stack ;
}
// Process SetNextWindow***() calls
// (FIXME: Consider splitting the HasXXX flags into X/Y components
@ -8562,7 +8567,7 @@ void ImGui::EndGroup()
window - > DC . CurrLineTextBaseOffset = ImMax ( window - > DC . PrevLineTextBaseOffset , group_data . BackupCurrLineTextBaseOffset ) ; // FIXME: Incorrect, we should grab the base offset from the *first line* of the group but it is hard to obtain now.
ItemSize ( group_bb . GetSize ( ) ) ;
ItemAdd ( group_bb , 0 );
ItemAdd ( group_bb , 0 , NULL , ImGuiItemFlags_NoTabStop );
// If the current ActiveId was declared within the boundary of our group, we copy it to LastItemId so IsItemActive(), IsItemDeactivated() etc. will be functional on the entire group.
// It would be be neater if we replaced window.DC.LastItemId by e.g. 'bool LastItemIsActive', but would put a little more burden on individual widgets.
@ -8851,10 +8856,10 @@ void ImGui::SetScrollHereY(float center_y_ratio)
void ImGui : : BeginTooltip ( )
{
BeginTooltipEx ( ImGui WindowFlags_None, ImGuiTooltip Flags_None) ;
BeginTooltipEx ( ImGui TooltipFlags_None, ImGuiWindow Flags_None) ;
}
void ImGui : : BeginTooltipEx ( ImGui WindowFlags extra_flags , ImGuiTooltipFlags tooltip _flags)
void ImGui : : BeginTooltipEx ( ImGui TooltipFlags tooltip_flags , ImGuiWindowFlags extra_window _flags)
{
ImGuiContext & g = * GImGui ;
@ -8883,7 +8888,7 @@ void ImGui::BeginTooltipEx(ImGuiWindowFlags extra_flags, ImGuiTooltipFlags toolt
ImFormatString ( window_name , IM_ARRAYSIZE ( window_name ) , " ##Tooltip_%02d " , + + g . TooltipOverrideCount ) ;
}
ImGuiWindowFlags flags = ImGuiWindowFlags_Tooltip | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoDocking ;
Begin ( window_name , NULL , flags | extra_ flags) ;
Begin ( window_name , NULL , flags | extra_ window_ flags) ;
}
void ImGui : : EndTooltip ( )
@ -8894,7 +8899,7 @@ void ImGui::EndTooltip()
void ImGui : : SetTooltipV ( const char * fmt , va_list args )
{
BeginTooltipEx ( 0 , ImGuiTooltipFlags_OverridePreviousTooltip ) ;
BeginTooltipEx ( ImGuiTooltipFlags_OverridePreviousTooltip , ImGuiWindowFlags_None ) ;
TextV ( fmt , args ) ;
EndTooltip ( ) ;
}
@ -10930,16 +10935,16 @@ bool ImGui::BeginDragDropSource(ImGuiDragDropFlags flags)
return false ;
// If you want to use BeginDragDropSource() on an item with no unique identifier for interaction, such as Text() or Image(), you need to:
// A) Read the explanation below, B) Use the ImGuiDragDropFlags_SourceAllowNullID flag , C) Swallow your programmer pride .
// A) Read the explanation below, B) Use the ImGuiDragDropFlags_SourceAllowNullID flag .
if ( ! ( flags & ImGuiDragDropFlags_SourceAllowNullID ) )
{
IM_ASSERT ( 0 ) ;
return false ;
}
// Magic fallback (=somehow reprehensible) to handle items with no assigned ID, e.g. Text(), Image()
// Magic fallback to handle items with no assigned ID, e.g. Text(), Image()
// We build a throwaway ID based on current ID stack + relative AABB of items in window.
// THE IDENTIFIER WON'T SURVIVE ANY REPOSITIONING OF THE WIDGET, so if your widget moves your dragging operation will be canceled.
// THE IDENTIFIER WON'T SURVIVE ANY REPOSITIONING /RESIZINGG OF THE WIDGET, so if your widget moves your dragging operation will be canceled.
// We don't need to maintain/call ClearActiveID() as releasing the button will early out this function and trigger !ActiveIdIsAlive.
// Rely on keeping other window->LastItemXXX fields intact.
source_id = g . LastItemData . ID = window - > GetIDFromRectangle ( g . LastItemData . Rect ) ;
@ -16659,6 +16664,7 @@ static void SetClipboardTextFn_DefaultImpl(void*, const char* text)
// - DebugNodeWindow() [Internal]
// - DebugNodeWindowSettings() [Internal]
// - DebugNodeWindowsList() [Internal]
// - DebugNodeWindowsListByBeginStackParent() [Internal]
//-----------------------------------------------------------------------------
# ifndef IMGUI_DISABLE_METRICS_WINDOW
@ -16890,8 +16896,27 @@ void ImGui::ShowMetricsWindow(bool* p_open)
}
// Windows
DebugNodeWindowsList ( & g . Windows , " Windows " ) ;
//DebugNodeWindowsList(&g.WindowsFocusOrder, "WindowsFocusOrder");
if ( TreeNode ( " Windows " , " Windows (%d) " , g . Windows . Size ) )
{
//SetNextItemOpen(true, ImGuiCond_Once);
DebugNodeWindowsList ( & g . Windows , " By display order " ) ;
DebugNodeWindowsList ( & g . WindowsFocusOrder , " By focus order (root windows) " ) ;
if ( TreeNode ( " By submission order (begin stack) " ) )
{
// Here we display windows in their submitted order/hierarchy, however note that the Begin stack doesn't constitute a Parent<>Child relationship!
ImVector < ImGuiWindow * > & temp_buffer = g . WindowsTempSortBuffer ;
temp_buffer . resize ( 0 ) ;
for ( int i = 0 ; i < g . Windows . Size ; i + + )
if ( g . Windows [ i ] - > LastFrameActive + 1 > = g . FrameCount )
temp_buffer . push_back ( g . Windows [ i ] ) ;
struct Func { static int IMGUI_CDECL WindowComparerByBeginOrder ( const void * lhs , const void * rhs ) { return ( ( int ) ( * ( const ImGuiWindow * const * ) lhs ) - > BeginOrderWithinContext - ( * ( const ImGuiWindow * const * ) rhs ) - > BeginOrderWithinContext ) ; } } ;
ImQsort ( temp_buffer . Data , ( size_t ) temp_buffer . Size , sizeof ( ImGuiWindow * ) , Func : : WindowComparerByBeginOrder ) ;
DebugNodeWindowsListByBeginStackParent ( temp_buffer . Data , temp_buffer . Size , NULL ) ;
TreePop ( ) ;
}
TreePop ( ) ;
}
// DrawLists
int drawlist_count = 0 ;
@ -17704,7 +17729,6 @@ void ImGui::DebugNodeWindowsList(ImVector<ImGuiWindow*>* windows, const char* la
{
if ( ! TreeNode ( label , " %s (%d) " , label , windows - > Size ) )
return ;
Text ( " (In front-to-back order:) " ) ;
for ( int i = windows - > Size - 1 ; i > = 0 ; i - - ) // Iterate front to back
{
PushID ( ( * windows ) [ i ] ) ;
@ -17714,6 +17738,24 @@ void ImGui::DebugNodeWindowsList(ImVector<ImGuiWindow*>* windows, const char* la
TreePop ( ) ;
}
// FIXME-OPT: This is technically suboptimal, but it is simpler this way.
void ImGui : : DebugNodeWindowsListByBeginStackParent ( ImGuiWindow * * windows , int windows_size , ImGuiWindow * parent_in_begin_stack )
{
for ( int i = 0 ; i < windows_size ; i + + )
{
ImGuiWindow * window = windows [ i ] ;
if ( window - > ParentWindowInBeginStack ! = parent_in_begin_stack )
continue ;
char buf [ 20 ] ;
ImFormatString ( buf , IM_ARRAYSIZE ( buf ) , " [%04d] Window " , window - > BeginOrderWithinContext ) ;
//BulletText("[%04d] Window '%s'", window->BeginOrderWithinContext, window->Name);
DebugNodeWindow ( window , buf ) ;
Indent ( ) ;
DebugNodeWindowsListByBeginStackParent ( windows + i + 1 , windows_size - i - 1 , window ) ;
Unindent ( ) ;
}
}
//-----------------------------------------------------------------------------
// [SECTION] OTHER DEBUG TOOLS (ITEM PICKER, STACK TOOL)
//-----------------------------------------------------------------------------