@ -10330,6 +10330,17 @@ static void ImeSetInputScreenPosFn_DefaultImpl(int, int) {}
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// [SECTION] METRICS/DEBUGGER WINDOW
// [SECTION] METRICS/DEBUGGER WINDOW
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// - MetricsHelpMarker() [Internal]
// - ShowMetricsWindow()
// - DebugNodeColumns() [Internal]
// - DebugNodeDrawList() [Internal]
// - DebugNodeDrawCmdShowMeshAndBoundingBox() [Internal]
// - DebugNodeStorage() [Internal]
// - DebugNodeTabBar() [Internal]
// - DebugNodeWindow() [Internal]
// - DebugNodeWindowSettings() [Internal]
// - DebugNodeWindowsList() [Internal]
//-----------------------------------------------------------------------------
# ifndef IMGUI_DISABLE_METRICS_WINDOW
# ifndef IMGUI_DISABLE_METRICS_WINDOW
@ -10349,30 +10360,17 @@ static void MetricsHelpMarker(const char* desc)
void ImGui : : ShowMetricsWindow ( bool * p_open )
void ImGui : : ShowMetricsWindow ( bool * p_open )
{
{
if ( ! ImGui: : Begin( " Dear ImGui Metrics " , p_open ) )
if ( ! Begin( " Dear ImGui Metrics " , p_open ) )
{
{
ImGui: : End( ) ;
End( ) ;
return ;
return ;
}
}
// Debugging enums
ImGuiContext & g = * GImGui ;
enum { WRT_OuterRect , WRT_OuterRectClipped , WRT_InnerRect , WRT_InnerClipRect , WRT_WorkRect , WRT_Content , WRT_ContentRegionRect , WRT_Count } ; // Windows Rect Type
ImGuiIO & io = g . IO ;
const char * wrt_rects_names [ WRT_Count ] = { " OuterRect " , " OuterRectClipped " , " InnerRect " , " InnerClipRect " , " WorkRect " , " Content " , " ContentRegionRect " } ;
ImGuiMetricsConfig * cfg = & g . DebugMetricsConfig ;
enum { TRT_OuterRect , TRT_WorkRect , TRT_HostClipRect , TRT_InnerClipRect , TRT_BackgroundClipRect , TRT_ColumnsRect , TRT_ColumnsClipRect , TRT_ColumnsContentHeadersUsed , TRT_ColumnsContentHeadersIdeal , TRT_ColumnsContentRowsFrozen , TRT_ColumnsContentRowsUnfrozen , TRT_Count } ; // Tables Rect Type
const char * trt_rects_names [ TRT_Count ] = { " OuterRect " , " WorkRect " , " HostClipRect " , " InnerClipRect " , " BackgroundClipRect " , " ColumnsRect " , " ColumnsClipRect " , " ColumnsContentHeadersUsed " , " ColumnsContentHeadersIdeal " , " ColumnsContentRowsFrozen " , " ColumnsContentRowsUnfrozen " } ;
// State
static bool show_windows_rects = false ;
static int show_windows_rect_type = WRT_WorkRect ;
static bool show_windows_begin_order = false ;
static bool show_tables_rects = false ;
static int show_tables_rect_type = TRT_WorkRect ;
static bool show_drawcmd_mesh = true ;
static bool show_drawcmd_aabb = true ;
// Basic info
// Basic info
ImGuiContext & g = * GImGui ;
ImGuiIO & io = ImGui : : GetIO ( ) ;
ImGui : : Text ( " Dear ImGui %s " , ImGui : : GetVersion ( ) ) ;
ImGui : : Text ( " Dear ImGui %s " , ImGui : : GetVersion ( ) ) ;
ImGui : : Text ( " Application average %.3f ms/frame (%.1f FPS) " , 1000.0f / io . Framerate , io . Framerate ) ;
ImGui : : Text ( " Application average %.3f ms/frame (%.1f FPS) " , 1000.0f / io . Framerate , io . Framerate ) ;
ImGui : : Text ( " %d vertices, %d indices (%d triangles) " , io . MetricsRenderVertices , io . MetricsRenderIndices , io . MetricsRenderIndices / 3 ) ;
ImGui : : Text ( " %d vertices, %d indices (%d triangles) " , io . MetricsRenderVertices , io . MetricsRenderIndices , io . MetricsRenderIndices / 3 ) ;
@ -10380,13 +10378,16 @@ void ImGui::ShowMetricsWindow(bool* p_open)
ImGui : : Text ( " %d active allocations " , io . MetricsActiveAllocations ) ;
ImGui : : Text ( " %d active allocations " , io . MetricsActiveAllocations ) ;
ImGui : : Separator ( ) ;
ImGui : : Separator ( ) ;
// Helper functions to display common structures:
// Debugging enums
// - NodeDrawList()
enum { WRT_OuterRect , WRT_OuterRectClipped , WRT_InnerRect , WRT_InnerClipRect , WRT_WorkRect , WRT_Content , WRT_ContentRegionRect , WRT_Count } ; // Windows Rect Type
// - NodeColumns()
const char * wrt_rects_names [ WRT_Count ] = { " OuterRect " , " OuterRectClipped " , " InnerRect " , " InnerClipRect " , " WorkRect " , " Content " , " ContentRegionRect " } ;
// - NodeWindow()
enum { TRT_OuterRect , TRT_WorkRect , TRT_HostClipRect , TRT_InnerClipRect , TRT_BackgroundClipRect , TRT_ColumnsRect , TRT_ColumnsClipRect , TRT_ColumnsContentHeadersUsed , TRT_ColumnsContentHeadersIdeal , TRT_ColumnsContentRowsFrozen , TRT_ColumnsContentRowsUnfrozen , TRT_Count } ; // Tables Rect Type
// - NodeWindows()
const char * trt_rects_names [ TRT_Count ] = { " OuterRect " , " WorkRect " , " HostClipRect " , " InnerClipRect " , " BackgroundClipRect " , " ColumnsRect " , " ColumnsClipRect " , " ColumnsContentHeadersUsed " , " ColumnsContentHeadersIdeal " , " ColumnsContentRowsFrozen " , " ColumnsContentRowsUnfrozen " } ;
// - NodeTabBar()
if ( cfg - > ShowWindowsRectsType < 0 )
// - NodeStorage()
cfg - > ShowWindowsRectsType = WRT_WorkRect ;
if ( cfg - > ShowTablesRectsType < 0 )
cfg - > ShowWindowsRectsType = TRT_WorkRect ;
struct Funcs
struct Funcs
{
{
static ImRect GetWindowRect ( ImGuiWindow * window , int rect_type )
static ImRect GetWindowRect ( ImGuiWindow * window , int rect_type )
@ -10401,47 +10402,244 @@ void ImGui::ShowMetricsWindow(bool* p_open)
IM_ASSERT ( 0 ) ;
IM_ASSERT ( 0 ) ;
return ImRect ( ) ;
return ImRect ( ) ;
}
}
} ;
static void NodeDrawCmdShowMeshAndBoundingBox ( ImGuiWindow * window , const ImDrawList * draw_list , const ImDrawCmd * draw_cmd , bool show_mesh , bool show_aabb )
// Tools
if ( TreeNode ( " Tools " ) )
{
{
IM_ASSERT ( show_mesh | | show_aabb ) ;
// The Item Picker tool is super useful to visually select an item and break into the call-stack of where it was submitted.
ImDrawList * fg_draw_list = GetForegroundDrawList ( window ) ; // Render additional visuals into the top-most draw list
if ( Button ( " Item Picker.. " ) )
ImDrawIdx * idx_buffer = ( draw_list - > IdxBuffer . Size > 0 ) ? draw_list - > IdxBuffer . Data : NULL ;
DebugStartItemPicker ( ) ;
ImDrawVert * vtx_buffer = draw_list - > VtxBuffer . Data + draw_cmd - > VtxOffset ;
SameLine ( ) ;
MetricsHelpMarker ( " Will call the IM_DEBUG_BREAK() macro to break in debugger. \n Warning: If you don't have a debugger attached, this will probably crash. " ) ;
// Draw wire-frame version of all triangles
Checkbox ( " Show windows begin order " , & cfg - > ShowWindowsBeginOrder ) ;
ImRect clip_rect = draw_cmd - > ClipRect ;
ImGui : : Checkbox ( " Show windows rectangles " , & cfg - > ShowWindowsRects ) ;
ImRect vtxs_rect ( FLT_MAX , FLT_MAX , - FLT_MAX , - FLT_MAX ) ;
SameLine ( ) ;
ImDrawListFlags backup_flags = fg_draw_list - > Flags ;
SetNextItemWidth ( GetFontSize ( ) * 12 ) ;
fg_draw_list - > Flags & = ~ ImDrawListFlags_AntiAliasedLines ; // Disable AA on triangle outlines is more readable for very large and thin triangles.
cfg - > ShowWindowsRects | = Combo ( " ##show_windows_rect_type " , & cfg - > ShowWindowsRectsType , wrt_rects_names , WRT_Count , WRT_Count ) ;
for ( unsigned int idx_n = draw_cmd - > IdxOffset ; idx_n < draw_cmd - > IdxOffset + draw_cmd - > ElemCount ; )
if ( cfg - > ShowWindowsRects & & g . NavWindow ! = NULL )
{
{
ImVec2 triangle [ 3 ] ;
BulletText ( " '%s': " , g . NavWindow - > Name ) ;
for ( int n = 0 ; n < 3 ; n + + , idx_n + + )
Indent ( ) ;
vtxs_rect . Add ( ( triangle [ n ] = vtx_buffer [ idx_buffer ? idx_buffer [ idx_n ] : idx_n ] . pos ) ) ;
for ( int rect_n = 0 ; rect_n < WRT_Count ; rect_n + + )
if ( show_mesh )
{
fg_draw_list - > AddPolyline ( triangle , 3 , IM_COL32 ( 255 , 255 , 0 , 255 ) , true , 1.0f ) ; // In yellow: mesh triangles
ImRect r = Funcs : : GetWindowRect ( g . NavWindow , rect_n ) ;
Text ( " (%6.1f,%6.1f) (%6.1f,%6.1f) Size (%6.1f,%6.1f) %s " , r . Min . x , r . Min . y , r . Max . x , r . Max . y , r . GetWidth ( ) , r . GetHeight ( ) , wrt_rects_names [ rect_n ] ) ;
}
}
// Draw bounding boxes
Unindent ( ) ;
if ( show_aabb )
}
Checkbox ( " Show ImDrawCmd mesh when hovering " , & cfg - > ShowDrawCmdMesh ) ;
Checkbox ( " Show ImDrawCmd bounding boxes when hovering " , & cfg - > ShowDrawCmdBoundingBoxes ) ;
TreePop ( ) ;
}
// Contents
DebugNodeWindowsList ( & g . Windows , " Windows " ) ;
//DebugNodeWindowList(&g.WindowsFocusOrder, "WindowsFocusOrder");
if ( TreeNode ( " DrawLists " , " Active DrawLists (%d) " , g . DrawDataBuilder . Layers [ 0 ] . Size ) )
{
{
fg_draw_list - > AddRect ( ImFloor ( clip_rect . Min ) , ImFloor ( clip_rect . Max ) , IM_COL32 ( 255 , 0 , 255 , 255 ) ) ; // In pink: clipping rectangle submitted to GPU
for ( int i = 0 ; i < g . DrawDataBuilder . Layers [ 0 ] . Size ; i + + )
fg_draw_list - > AddRect ( ImFloor ( vtxs_rect . Min ) , ImFloor ( vtxs_rect . Max ) , IM_COL32 ( 0 , 255 , 255 , 255 ) ) ; // In cyan: bounding box of triangles
DebugNodeDrawList ( NULL , g . DrawDataBuilder . Layers [ 0 ] [ i ] , " DrawList " ) ;
TreePop ( ) ;
}
}
fg_draw_list - > Flags = backup_flags ;
// Details for Popups
if ( TreeNode ( " Popups " , " Popups (%d) " , g . OpenPopupStack . Size ) )
{
for ( int i = 0 ; i < g . OpenPopupStack . Size ; i + + )
{
ImGuiWindow * window = g . OpenPopupStack [ i ] . Window ;
BulletText ( " PopupID: %08x, Window: '%s'%s%s " , g . OpenPopupStack [ i ] . PopupId , window ? window - > Name : " NULL " , window & & ( window - > Flags & ImGuiWindowFlags_ChildWindow ) ? " ChildWindow " : " " , window & & ( window - > Flags & ImGuiWindowFlags_ChildMenu ) ? " ChildMenu " : " " ) ;
}
TreePop ( ) ;
}
}
static void NodeDrawList ( ImGuiWindow * window , ImDrawList * draw_list , const char * label )
// Details for TabBars
if ( TreeNode ( " TabBars " , " Tab Bars (%d) " , g . TabBars . GetSize ( ) ) )
{
for ( int n = 0 ; n < g . TabBars . GetSize ( ) ; n + + )
DebugNodeTabBar ( g . TabBars . GetByIndex ( n ) , " TabBar " ) ;
TreePop ( ) ;
}
// Details for Tables
IM_UNUSED ( trt_rects_names ) ;
# ifdef IMGUI_HAS_TABLE
if ( TreeNode ( " Tables " , " Tables (%d) " , g . Tables . GetSize ( ) ) )
{
for ( int n = 0 ; n < g . Tables . GetSize ( ) ; n + + )
DebugNodeTable ( g . Tables . GetByIndex ( n ) ) ;
TreePop ( ) ;
}
# endif // #ifdef IMGUI_HAS_TABLE
// Details for Docking
# ifdef IMGUI_HAS_DOCK
if ( TreeNode ( " Docking " ) )
{
TreePop ( ) ;
}
# endif // #ifdef IMGUI_HAS_DOCK
// Settings
if ( TreeNode ( " Settings " ) )
{
if ( SmallButton ( " Clear " ) )
ClearIniSettings ( ) ;
SameLine ( ) ;
if ( SmallButton ( " Save to memory " ) )
SaveIniSettingsToMemory ( ) ;
SameLine ( ) ;
if ( SmallButton ( " Save to disk " ) )
SaveIniSettingsToDisk ( g . IO . IniFilename ) ;
SameLine ( ) ;
if ( g . IO . IniFilename )
Text ( " \" %s \" " , g . IO . IniFilename ) ;
else
TextUnformatted ( " <NULL> " ) ;
Text ( " SettingsDirtyTimer %.2f " , g . SettingsDirtyTimer ) ;
if ( TreeNode ( " SettingsHandlers " , " Settings handlers: (%d) " , g . SettingsHandlers . Size ) )
{
for ( int n = 0 ; n < g . SettingsHandlers . Size ; n + + )
BulletText ( " %s " , g . SettingsHandlers [ n ] . TypeName ) ;
TreePop ( ) ;
}
if ( TreeNode ( " SettingsWindows " , " Settings packed data: Windows: %d bytes " , g . SettingsWindows . size ( ) ) )
{
{
for ( ImGuiWindowSettings * settings = g . SettingsWindows . begin ( ) ; settings ! = NULL ; settings = g . SettingsWindows . next_chunk ( settings ) )
DebugNodeWindowSettings ( settings ) ;
TreePop ( ) ;
}
# ifdef IMGUI_HAS_TABLE
if ( TreeNode ( " SettingsTables " , " Settings packed data: Tables: %d bytes " , g . SettingsTables . size ( ) ) )
{
for ( ImGuiTableSettings * settings = g . SettingsTables . begin ( ) ; settings ! = NULL ; settings = g . SettingsTables . next_chunk ( settings ) )
DebugNodeTableSettings ( settings ) ;
TreePop ( ) ;
}
# endif // #ifdef IMGUI_HAS_TABLE
# ifdef IMGUI_HAS_DOCK
# endif // #ifdef IMGUI_HAS_DOCK
if ( TreeNode ( " SettingsIniData " , " Settings unpacked data (.ini): %d bytes " , g . SettingsIniData . size ( ) ) )
{
InputTextMultiline ( " ##Ini " , ( char * ) ( void * ) g . SettingsIniData . c_str ( ) , g . SettingsIniData . Buf . Size , ImVec2 ( - FLT_MIN , GetTextLineHeight ( ) * 20 ) , ImGuiInputTextFlags_ReadOnly ) ;
TreePop ( ) ;
}
TreePop ( ) ;
}
// Misc Details
if ( TreeNode ( " Internal state " ) )
{
const char * input_source_names [ ] = { " None " , " Mouse " , " Nav " , " NavKeyboard " , " NavGamepad " } ; IM_ASSERT ( IM_ARRAYSIZE ( input_source_names ) = = ImGuiInputSource_COUNT ) ;
Text ( " WINDOWING " ) ;
Indent ( ) ;
Text ( " HoveredWindow: '%s' " , g . HoveredWindow ? g . HoveredWindow - > Name : " NULL " ) ;
Text ( " HoveredRootWindow: '%s' " , g . HoveredRootWindow ? g . HoveredRootWindow - > Name : " NULL " ) ;
Text ( " HoveredWindowUnderMovingWindow: '%s' " , g . HoveredWindowUnderMovingWindow ? g . HoveredWindowUnderMovingWindow - > Name : " NULL " ) ;
Text ( " MovingWindow: '%s' " , g . MovingWindow ? g . MovingWindow - > Name : " NULL " ) ;
Unindent ( ) ;
Text ( " ITEMS " ) ;
Indent ( ) ;
Text ( " ActiveId: 0x%08X/0x%08X (%.2f sec), AllowOverlap: %d, Source: %s " , g . ActiveId , g . ActiveIdPreviousFrame , g . ActiveIdTimer , g . ActiveIdAllowOverlap , input_source_names [ g . ActiveIdSource ] ) ;
Text ( " ActiveIdWindow: '%s' " , g . ActiveIdWindow ? g . ActiveIdWindow - > Name : " NULL " ) ;
Text ( " HoveredId: 0x%08X/0x%08X (%.2f sec), AllowOverlap: %d " , g . HoveredId , g . HoveredIdPreviousFrame , g . HoveredIdTimer , g . HoveredIdAllowOverlap ) ; // Data is "in-flight" so depending on when the Metrics window is called we may see current frame information or not
Text ( " DragDrop: %d, SourceId = 0x%08X, Payload \" %s \" (%d bytes) " , g . DragDropActive , g . DragDropPayload . SourceId , g . DragDropPayload . DataType , g . DragDropPayload . DataSize ) ;
Unindent ( ) ;
Text ( " NAV,FOCUS " ) ;
Indent ( ) ;
Text ( " NavWindow: '%s' " , g . NavWindow ? g . NavWindow - > Name : " NULL " ) ;
Text ( " NavId: 0x%08X, NavLayer: %d " , g . NavId , g . NavLayer ) ;
Text ( " NavInputSource: %s " , input_source_names [ g . NavInputSource ] ) ;
Text ( " NavActive: %d, NavVisible: %d " , g . IO . NavActive , g . IO . NavVisible ) ;
Text ( " NavActivateId: 0x%08X, NavInputId: 0x%08X " , g . NavActivateId , g . NavInputId ) ;
Text ( " NavDisableHighlight: %d, NavDisableMouseHover: %d " , g . NavDisableHighlight , g . NavDisableMouseHover ) ;
Text ( " NavFocusScopeId = 0x%08X " , g . NavFocusScopeId ) ;
Text ( " NavWindowingTarget: '%s' " , g . NavWindowingTarget ? g . NavWindowingTarget - > Name : " NULL " ) ;
Unindent ( ) ;
TreePop ( ) ;
}
// Overlay: Display windows Rectangles and Begin Order
if ( cfg - > ShowWindowsRects | | cfg - > ShowWindowsBeginOrder )
{
for ( int n = 0 ; n < g . Windows . Size ; n + + )
{
ImGuiWindow * window = g . Windows [ n ] ;
if ( ! window - > WasActive )
continue ;
ImDrawList * draw_list = GetForegroundDrawList ( window ) ;
if ( cfg - > ShowWindowsRects )
{
ImRect r = Funcs : : GetWindowRect ( window , cfg - > ShowWindowsRectsType ) ;
draw_list - > AddRect ( r . Min , r . Max , IM_COL32 ( 255 , 0 , 128 , 255 ) ) ;
}
if ( cfg - > ShowWindowsBeginOrder & & ! ( window - > Flags & ImGuiWindowFlags_ChildWindow ) )
{
char buf [ 32 ] ;
ImFormatString ( buf , IM_ARRAYSIZE ( buf ) , " %d " , window - > BeginOrderWithinContext ) ;
float font_size = GetFontSize ( ) ;
draw_list - > AddRectFilled ( window - > Pos , window - > Pos + ImVec2 ( font_size , font_size ) , IM_COL32 ( 200 , 100 , 100 , 255 ) ) ;
draw_list - > AddText ( window - > Pos , IM_COL32 ( 255 , 255 , 255 , 255 ) , buf ) ;
}
}
}
# ifdef IMGUI_HAS_TABLE
// Overlay: Display Tables Rectangles
if ( show_tables_rects )
{
for ( int table_n = 0 ; table_n < g . Tables . GetSize ( ) ; table_n + + )
{
ImGuiTable * table = g . Tables . GetByIndex ( table_n ) ;
}
}
# endif // #ifdef IMGUI_HAS_TABLE
# ifdef IMGUI_HAS_DOCK
// Overlay: Display Docking info
if ( show_docking_nodes & & g . IO . KeyCtrl )
{
}
# endif // #ifdef IMGUI_HAS_DOCK
ImGui : : End ( ) ;
}
// [DEBUG] Display contents of Columns
void ImGui : : DebugNodeColumns ( ImGuiColumns * columns )
{
if ( ! TreeNode ( ( void * ) ( uintptr_t ) columns - > ID , " Columns Id: 0x%08X, Count: %d, Flags: 0x%04X " , columns - > ID , columns - > Count , columns - > Flags ) )
return ;
BulletText ( " Width: %.1f (MinX: %.1f, MaxX: %.1f) " , columns - > OffMaxX - columns - > OffMinX , columns - > OffMinX , columns - > OffMaxX ) ;
for ( int column_n = 0 ; column_n < columns - > Columns . Size ; column_n + + )
BulletText ( " Column %02d: OffsetNorm %.3f (= %.1f px) " , column_n , columns - > Columns [ column_n ] . OffsetNorm , GetColumnOffsetFromNorm ( columns , columns - > Columns [ column_n ] . OffsetNorm ) ) ;
TreePop ( ) ;
}
// [DEBUG] Display contents of ImDrawList
void ImGui : : DebugNodeDrawList ( ImGuiWindow * window , const ImDrawList * draw_list , const char * label )
{
ImGuiContext & g = * GImGui ;
ImGuiMetricsConfig * cfg = & g . DebugMetricsConfig ;
int cmd_count = draw_list - > CmdBuffer . Size ;
int cmd_count = draw_list - > CmdBuffer . Size ;
if ( cmd_count > 0 & & draw_list - > CmdBuffer . back ( ) . ElemCount = = 0 & & draw_list - > CmdBuffer . back ( ) . UserCallback = = NULL )
if ( cmd_count > 0 & & draw_list - > CmdBuffer . back ( ) . ElemCount = = 0 & & draw_list - > CmdBuffer . back ( ) . UserCallback = = NULL )
cmd_count - - ;
cmd_count - - ;
bool node_open = ImGui : : TreeNode ( draw_list , " %s: '%s' %d vtx, %d indices, %d cmds " , label , draw_list - > _OwnerName ? draw_list - > _OwnerName : " " , draw_list - > VtxBuffer . Size , draw_list - > IdxBuffer . Size , cmd_count ) ;
bool node_open = TreeNode ( draw_list , " %s: '%s' %d vtx, %d indices, %d cmds " , label , draw_list - > _OwnerName ? draw_list - > _OwnerName : " " , draw_list - > VtxBuffer . Size , draw_list - > IdxBuffer . Size , cmd_count ) ;
if ( draw_list = = ImGui : : GetWindowDrawList ( ) )
if ( draw_list = = GetWindowDrawList ( ) )
{
{
ImGui : : SameLine ( ) ;
SameLine ( ) ;
ImGui : : TextColored ( ImVec4 ( 1.0f , 0.4f , 0.4f , 1.0f ) , " CURRENTLY APPENDING " ) ; // Can't display stats for active draw list! (we don't have the data double-buffered)
TextColored ( ImVec4 ( 1.0f , 0.4f , 0.4f , 1.0f ) , " CURRENTLY APPENDING " ) ; // Can't display stats for active draw list! (we don't have the data double-buffered)
if ( node_open ) ImGui : : TreePop ( ) ;
if ( node_open )
TreePop ( ) ;
return ;
return ;
}
}
@ -10452,13 +10650,13 @@ void ImGui::ShowMetricsWindow(bool* p_open)
return ;
return ;
if ( window & & ! window - > WasActive )
if ( window & & ! window - > WasActive )
ImGui : : TextDisabled ( " Warning: owning Window is inactive. This DrawList is not being rendered! " ) ;
TextDisabled ( " Warning: owning Window is inactive. This DrawList is not being rendered! " ) ;
for ( const ImDrawCmd * pcmd = draw_list - > CmdBuffer . Data ; pcmd < draw_list - > CmdBuffer . Data + cmd_count ; pcmd + + )
for ( const ImDrawCmd * pcmd = draw_list - > CmdBuffer . Data ; pcmd < draw_list - > CmdBuffer . Data + cmd_count ; pcmd + + )
{
{
if ( pcmd - > UserCallback )
if ( pcmd - > UserCallback )
{
{
ImGui : : BulletText ( " Callback %p, user_data %p " , pcmd - > UserCallback , pcmd - > UserCallbackData ) ;
BulletText ( " Callback %p, user_data %p " , pcmd - > UserCallback , pcmd - > UserCallbackData ) ;
continue ;
continue ;
}
}
@ -10466,9 +10664,9 @@ void ImGui::ShowMetricsWindow(bool* p_open)
ImFormatString ( buf , IM_ARRAYSIZE ( buf ) , " DrawCmd:%5d tris, Tex 0x%p, ClipRect (%4.0f,%4.0f)-(%4.0f,%4.0f) " ,
ImFormatString ( buf , IM_ARRAYSIZE ( buf ) , " DrawCmd:%5d tris, Tex 0x%p, ClipRect (%4.0f,%4.0f)-(%4.0f,%4.0f) " ,
pcmd - > ElemCount / 3 , ( void * ) ( intptr_t ) pcmd - > TextureId ,
pcmd - > ElemCount / 3 , ( void * ) ( intptr_t ) pcmd - > TextureId ,
pcmd - > ClipRect . x , pcmd - > ClipRect . y , pcmd - > ClipRect . z , pcmd - > ClipRect . w ) ;
pcmd - > ClipRect . x , pcmd - > ClipRect . y , pcmd - > ClipRect . z , pcmd - > ClipRect . w ) ;
bool pcmd_node_open = ImGui : : TreeNode ( ( void * ) ( pcmd - draw_list - > CmdBuffer . begin ( ) ) , " %s " , buf ) ;
bool pcmd_node_open = TreeNode ( ( void * ) ( pcmd - draw_list - > CmdBuffer . begin ( ) ) , " %s " , buf ) ;
if ( I mGui: : I sItemHovered( ) & & ( show_drawcmd_mesh | | show_drawcmd_aabb ) & & fg_draw_list )
if ( I sItemHovered( ) & & ( cfg- > ShowDrawCmdMesh | | cfg - > ShowDrawCmdBoundingBoxes ) & & fg_draw_list )
NodeDrawCmdShowMeshAndBoundingBox( window , draw_list , pcmd , show_drawcmd_mesh, show_drawcmd_aabb ) ;
Debug NodeDrawCmdShowMeshAndBoundingBox( window , draw_list , pcmd , cfg- > ShowDrawCmdMesh , cfg - > ShowDrawCmdBoundingBoxes ) ;
if ( ! pcmd_node_open )
if ( ! pcmd_node_open )
continue ;
continue ;
@ -10487,9 +10685,9 @@ void ImGui::ShowMetricsWindow(bool* p_open)
// Display vertex information summary. Hover to get all triangles drawn in wire-frame
// Display vertex information summary. Hover to get all triangles drawn in wire-frame
ImFormatString ( buf , IM_ARRAYSIZE ( buf ) , " Mesh: ElemCount: %d, VtxOffset: +%d, IdxOffset: +%d, Area: ~%0.f px " , pcmd - > ElemCount , pcmd - > VtxOffset , pcmd - > IdxOffset , total_area ) ;
ImFormatString ( buf , IM_ARRAYSIZE ( buf ) , " Mesh: ElemCount: %d, VtxOffset: +%d, IdxOffset: +%d, Area: ~%0.f px " , pcmd - > ElemCount , pcmd - > VtxOffset , pcmd - > IdxOffset , total_area ) ;
ImGui : : Selectable ( buf ) ;
Selectable ( buf ) ;
if ( ImGui : : IsItemHovered ( ) & & fg_draw_list )
if ( IsItemHovered ( ) & & fg_draw_list )
NodeDrawCmdShowMeshAndBoundingBox( window , draw_list , pcmd , true , false ) ;
Debug NodeDrawCmdShowMeshAndBoundingBox( window , draw_list , pcmd , true , false ) ;
// Display individual triangles/vertices. Hover on to get the corresponding triangle highlighted.
// Display individual triangles/vertices. Hover on to get the corresponding triangle highlighted.
ImGuiListClipper clipper ;
ImGuiListClipper clipper ;
@ -10497,7 +10695,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
while ( clipper . Step ( ) )
while ( clipper . Step ( ) )
for ( int prim = clipper . DisplayStart , idx_i = pcmd - > IdxOffset + clipper . DisplayStart * 3 ; prim < clipper . DisplayEnd ; prim + + )
for ( int prim = clipper . DisplayStart , idx_i = pcmd - > IdxOffset + clipper . DisplayStart * 3 ; prim < clipper . DisplayEnd ; prim + + )
{
{
char * buf_p = buf , * buf_end = buf + IM_ARRAYSIZE ( buf ) ;
char * buf_p = buf , * buf_end = buf + IM_ARRAYSIZE ( buf ) ;
ImVec2 triangle [ 3 ] ;
ImVec2 triangle [ 3 ] ;
for ( int n = 0 ; n < 3 ; n + + , idx_i + + )
for ( int n = 0 ; n < 3 ; n + + , idx_i + + )
{
{
@ -10507,116 +10705,79 @@ void ImGui::ShowMetricsWindow(bool* p_open)
( n = = 0 ) ? " Vert: " : " " , idx_i , v . pos . x , v . pos . y , v . uv . x , v . uv . y , v . col ) ;
( n = = 0 ) ? " Vert: " : " " , idx_i , v . pos . x , v . pos . y , v . uv . x , v . uv . y , v . col ) ;
}
}
ImGui : : Selectable ( buf , false ) ;
Selectable ( buf , false ) ;
if ( fg_draw_list & & ImGui : : IsItemHovered ( ) )
if ( fg_draw_list & & IsItemHovered ( ) )
{
{
ImDrawListFlags backup_flags = fg_draw_list - > Flags ;
ImDrawListFlags backup_flags = fg_draw_list - > Flags ;
fg_draw_list - > Flags & = ~ ImDrawListFlags_AntiAliasedLines ; // Disable AA on triangle outlines is more readable for very large and thin triangles.
fg_draw_list - > Flags & = ~ ImDrawListFlags_AntiAliasedLines ; // Disable AA on triangle outlines is more readable for very large and thin triangles.
fg_draw_list - > AddPolyline ( triangle , 3 , IM_COL32 ( 255 , 255 , 0 , 255 ) , true , 1.0f ) ;
fg_draw_list - > AddPolyline ( triangle , 3 , IM_COL32 ( 255 , 255 , 0 , 255 ) , true , 1.0f ) ;
fg_draw_list - > Flags = backup_flags ;
fg_draw_list - > Flags = backup_flags ;
}
}
}
}
ImGui : : TreePop ( ) ;
TreePop ( ) ;
}
ImGui : : TreePop ( ) ;
}
}
TreePop ( ) ;
}
static void NodeColumns ( const ImGuiColumns * columns )
// [DEBUG] Display mesh/aabb of a ImDrawCmd
{
void ImGui : : DebugNodeDrawCmdShowMeshAndBoundingBox ( ImGuiWindow * window , const ImDrawList * draw_list , const ImDrawCmd * draw_cmd , bool show_mesh , bool show_aabb )
if ( ! ImGui : : TreeNode ( ( void * ) ( uintptr_t ) columns - > ID , " Columns Id: 0x%08X, Count: %d, Flags: 0x%04X " , columns - > ID , columns - > Count , columns - > Flags ) )
{
return ;
IM_ASSERT ( show_mesh | | show_aabb ) ;
ImGui : : BulletText ( " Width: %.1f (MinX: %.1f, MaxX: %.1f) " , columns - > OffMaxX - columns - > OffMinX , columns - > OffMinX , columns - > OffMaxX ) ;
ImDrawList * fg_draw_list = GetForegroundDrawList ( window ) ; // Render additional visuals into the top-most draw list
for ( int column_n = 0 ; column_n < columns - > Columns . Size ; column_n + + )
ImDrawIdx * idx_buffer = ( draw_list - > IdxBuffer . Size > 0 ) ? draw_list - > IdxBuffer . Data : NULL ;
ImGui : : BulletText ( " Column %02d: OffsetNorm %.3f (= %.1f px) " , column_n , columns - > Columns [ column_n ] . OffsetNorm , GetColumnOffsetFromNorm ( columns , columns - > Columns [ column_n ] . OffsetNorm ) ) ;
ImDrawVert * vtx_buffer = draw_list - > VtxBuffer . Data + draw_cmd - > VtxOffset ;
ImGui : : TreePop ( ) ;
}
static void NodeWindows ( ImVector < ImGuiWindow * > & windows , const char * label )
// Draw wire-frame version of all triangles
{
ImRect clip_rect = draw_cmd - > ClipRect ;
if ( ! ImGui : : TreeNode ( label , " %s (%d) " , label , windows . Size ) )
ImRect vtxs_rect ( FLT_MAX , FLT_MAX , - FLT_MAX , - FLT_MAX ) ;
return ;
ImDrawListFlags backup_flags = fg_draw_list - > Flags ;
ImGui : : Text ( " (In front-to-back order:) " ) ;
fg_draw_list - > Flags & = ~ ImDrawListFlags_AntiAliasedLines ; // Disable AA on triangle outlines is more readable for very large and thin triangles.
for ( int i = windows . Size - 1 ; i > = 0 ; i - - ) // Iterate front to back
for ( unsigned int idx_n = draw_cmd - > IdxOffset ; idx_n < draw_cmd - > IdxOffset + draw_cmd - > ElemCount ; )
{
{
ImGui : : PushID ( windows [ i ] ) ;
ImVec2 triangle [ 3 ] ;
Funcs : : NodeWindow ( windows [ i ] , " Window " ) ;
for ( int n = 0 ; n < 3 ; n + + , idx_n + + )
ImGui : : PopID ( ) ;
vtxs_rect . Add ( ( triangle [ n ] = vtx_buffer [ idx_buffer ? idx_buffer [ idx_n ] : idx_n ] . pos ) ) ;
}
if ( show_mesh )
ImGui: : TreePop ( ) ;
fg_draw_list- > AddPolyline ( triangle , 3 , IM_COL32 ( 255 , 255 , 0 , 255 ) , true , 1.0f ) ; // In yellow: mesh triangles
}
}
// Draw bounding boxes
static void NodeWindow ( ImGuiWindow * window , const char * label )
if ( show_aabb )
{
if ( window = = NULL )
{
{
ImGui : : BulletText ( " %s: NULL " , label ) ;
fg_draw_list - > AddRect ( ImFloor ( clip_rect . Min ) , ImFloor ( clip_rect . Max ) , IM_COL32 ( 255 , 0 , 255 , 255 ) ) ; // In pink: clipping rectangle submitted to GPU
return ;
fg_draw_list - > AddRect ( ImFloor ( vtxs_rect . Min ) , ImFloor ( vtxs_rect . Max ) , IM_COL32 ( 0 , 255 , 255 , 255 ) ) ; // In cyan: bounding box of triangles
}
}
fg_draw_list - > Flags = backup_flags ;
}
ImGuiContext & g = * GImGui ;
// [DEBUG] Display contents of ImGuiStorage
const bool is_active = window - > WasActive ;
void ImGui : : DebugNodeStorage ( ImGuiStorage * storage , const char * label )
ImGuiTreeNodeFlags tree_node_flags = ( window = = g . NavWindow ) ? ImGuiTreeNodeFlags_Selected : ImGuiTreeNodeFlags_None ;
{
if ( ! is_active ) { PushStyleColor ( ImGuiCol_Text , GetStyleColorVec4 ( ImGuiCol_TextDisabled ) ) ; }
if ( ! TreeNode ( label , " %s: %d entries, %d bytes " , label , storage - > Data . Size , storage - > Data . size_in_bytes ( ) ) )
const bool open = ImGui : : TreeNodeEx ( label , tree_node_flags , " %s '%s'%s " , label , window - > Name , is_active ? " " : " *Inactive* " ) ;
if ( ! is_active ) { PopStyleColor ( ) ; }
if ( ImGui : : IsItemHovered ( ) & & is_active )
ImGui : : GetForegroundDrawList ( window ) - > AddRect ( window - > Pos , window - > Pos + window - > Size , IM_COL32 ( 255 , 255 , 0 , 255 ) ) ;
if ( ! open )
return ;
return ;
for ( int n = 0 ; n < storage - > Data . Size ; n + + )
if ( window - > MemoryCompacted )
ImGui : : TextDisabled ( " Note: some memory buffers have been compacted/freed. " ) ;
ImGuiWindowFlags flags = window - > Flags ;
NodeDrawList ( window , window - > DrawList , " DrawList " ) ;
ImGui : : BulletText ( " Pos: (%.1f,%.1f), Size: (%.1f,%.1f), ContentSize (%.1f,%.1f) " , window - > Pos . x , window - > Pos . y , window - > Size . x , window - > Size . y , window - > ContentSize . x , window - > ContentSize . y ) ;
ImGui : : BulletText ( " Flags: 0x%08X (%s%s%s%s%s%s%s%s%s..) " , flags ,
( flags & ImGuiWindowFlags_ChildWindow ) ? " Child " : " " , ( flags & ImGuiWindowFlags_Tooltip ) ? " Tooltip " : " " , ( flags & ImGuiWindowFlags_Popup ) ? " Popup " : " " ,
( flags & ImGuiWindowFlags_Modal ) ? " Modal " : " " , ( flags & ImGuiWindowFlags_ChildMenu ) ? " ChildMenu " : " " , ( flags & ImGuiWindowFlags_NoSavedSettings ) ? " NoSavedSettings " : " " ,
( flags & ImGuiWindowFlags_NoMouseInputs ) ? " NoMouseInputs " : " " , ( flags & ImGuiWindowFlags_NoNavInputs ) ? " NoNavInputs " : " " , ( flags & ImGuiWindowFlags_AlwaysAutoResize ) ? " AlwaysAutoResize " : " " ) ;
ImGui : : BulletText ( " Scroll: (%.2f/%.2f,%.2f/%.2f) Scrollbar:%s%s " , window - > Scroll . x , window - > ScrollMax . x , window - > Scroll . y , window - > ScrollMax . y , window - > ScrollbarX ? " X " : " " , window - > ScrollbarY ? " Y " : " " ) ;
ImGui : : BulletText ( " Active: %d/%d, WriteAccessed: %d, BeginOrderWithinContext: %d " , window - > Active , window - > WasActive , window - > WriteAccessed , ( window - > Active | | window - > WasActive ) ? window - > BeginOrderWithinContext : - 1 ) ;
ImGui : : BulletText ( " Appearing: %d, Hidden: %d (CanSkip %d Cannot %d), SkipItems: %d " , window - > Appearing , window - > Hidden , window - > HiddenFramesCanSkipItems , window - > HiddenFramesCannotSkipItems , window - > SkipItems ) ;
ImGui : : BulletText ( " NavLastIds: 0x%08X,0x%08X, NavLayerActiveMask: %X " , window - > NavLastIds [ 0 ] , window - > NavLastIds [ 1 ] , window - > DC . NavLayerActiveMask ) ;
ImGui : : BulletText ( " NavLastChildNavWindow: %s " , window - > NavLastChildNavWindow ? window - > NavLastChildNavWindow - > Name : " NULL " ) ;
if ( ! window - > NavRectRel [ 0 ] . IsInverted ( ) )
ImGui : : BulletText ( " NavRectRel[0]: (%.1f,%.1f)(%.1f,%.1f) " , window - > NavRectRel [ 0 ] . Min . x , window - > NavRectRel [ 0 ] . Min . y , window - > NavRectRel [ 0 ] . Max . x , window - > NavRectRel [ 0 ] . Max . y ) ;
else
ImGui : : BulletText ( " NavRectRel[0]: <None> " ) ;
if ( window - > RootWindow ! = window ) NodeWindow ( window - > RootWindow , " RootWindow " ) ;
if ( window - > ParentWindow ! = NULL ) NodeWindow ( window - > ParentWindow , " ParentWindow " ) ;
if ( window - > DC . ChildWindows . Size > 0 ) NodeWindows ( window - > DC . ChildWindows , " ChildWindows " ) ;
if ( window - > ColumnsStorage . Size > 0 & & ImGui : : TreeNode ( " Columns " , " Columns sets (%d) " , window - > ColumnsStorage . Size ) )
{
for ( int n = 0 ; n < window - > ColumnsStorage . Size ; n + + )
NodeColumns ( & window - > ColumnsStorage [ n ] ) ;
ImGui : : TreePop ( ) ;
}
NodeStorage ( & window - > StateStorage , " Storage " ) ;
ImGui : : TreePop ( ) ;
}
static void NodeWindowSettings ( ImGuiWindowSettings * settings )
{
{
ImGui : : Text ( " 0x%08X \" %s \" Pos (%d,%d) Size (%d,%d) Collapsed=%d " ,
const ImGuiStorage : : ImGuiStoragePair & p = storage - > Data [ n ] ;
settings - > ID , settings - > GetName ( ) , settings - > Pos . x , settings - > Pos . y , settings - > Size . x , settings - > Size . y , settings - > Collapsed ) ;
BulletText ( " Key 0x%08X Value { i: %d } " , p . key , p . val_i ) ; // Important: we currently don't store a type, real value may not be integer.
}
}
TreePop ( ) ;
}
static void NodeTabBar ( ImGuiTabBar * tab_bar )
// [DEBUG] Display contents of ImGuiTabBar
{
void ImGui : : DebugNodeTabBar ( ImGuiTabBar * tab_bar , const char * label )
{
// Standalone tab bars (not associated to docking/windows functionality) currently hold no discernible strings.
// Standalone tab bars (not associated to docking/windows functionality) currently hold no discernible strings.
char buf [ 256 ] ;
char buf [ 256 ] ;
char * p = buf ;
char * p = buf ;
const char * buf_end = buf + IM_ARRAYSIZE ( buf ) ;
const char * buf_end = buf + IM_ARRAYSIZE ( buf ) ;
const bool is_active = ( tab_bar - > PrevFrameVisible > = ImGui : : GetFrameCount ( ) - 2 ) ;
const bool is_active = ( tab_bar - > PrevFrameVisible > = GetFrameCount ( ) - 2 ) ;
p + = ImFormatString ( p , buf_end - p , " Tab Bar 0x%08X (%d tabs)%s" , tab_bar - > ID , tab_bar - > Tabs . Size , is_active ? " " : " *Inactive* " ) ;
p + = ImFormatString ( p , buf_end - p , " %s 0x%08X (%d tabs)%s " , label , tab_bar - > ID , tab_bar - > Tabs . Size , is_active ? " " : " *Inactive* " ) ;
IM_UNUSED ( p ) ;
IM_UNUSED ( p ) ;
if ( ! is_active ) { PushStyleColor ( ImGuiCol_Text , GetStyleColorVec4 ( ImGuiCol_TextDisabled ) ) ; }
if ( ! is_active ) { PushStyleColor ( ImGuiCol_Text , GetStyleColorVec4 ( ImGuiCol_TextDisabled ) ) ; }
bool open = ImGui : : TreeNode ( tab_bar , " %s " , buf ) ;
bool open = TreeNode ( tab_bar , " %s " , buf ) ;
if ( ! is_active ) { PopStyleColor ( ) ; }
if ( ! is_active ) { PopStyleColor ( ) ; }
if ( is_active & & ImGui : : IsItemHovered ( ) )
if ( is_active & & IsItemHovered ( ) )
{
{
ImDrawList * draw_list = ImGui : : GetForegroundDrawList ( ) ;
ImDrawList * draw_list = GetForegroundDrawList ( ) ;
draw_list - > AddRect ( tab_bar - > BarRect . Min , tab_bar - > BarRect . Max , IM_COL32 ( 255 , 255 , 0 , 255 ) ) ;
draw_list - > AddRect ( tab_bar - > BarRect . Min , tab_bar - > BarRect . Max , IM_COL32 ( 255 , 255 , 0 , 255 ) ) ;
draw_list - > AddLine ( ImVec2 ( tab_bar - > ScrollingRectMinX , tab_bar - > BarRect . Min . y ) , ImVec2 ( tab_bar - > ScrollingRectMinX , tab_bar - > BarRect . Max . y ) , IM_COL32 ( 0 , 255 , 0 , 255 ) ) ;
draw_list - > AddLine ( ImVec2 ( tab_bar - > ScrollingRectMinX , tab_bar - > BarRect . Min . y ) , ImVec2 ( tab_bar - > ScrollingRectMinX , tab_bar - > BarRect . Max . y ) , IM_COL32 ( 0 , 255 , 0 , 255 ) ) ;
draw_list - > AddLine ( ImVec2 ( tab_bar - > ScrollingRectMaxX , tab_bar - > BarRect . Min . y ) , ImVec2 ( tab_bar - > ScrollingRectMaxX , tab_bar - > BarRect . Max . y ) , IM_COL32 ( 0 , 255 , 0 , 255 ) ) ;
draw_list - > AddLine ( ImVec2 ( tab_bar - > ScrollingRectMaxX , tab_bar - > BarRect . Min . y ) , ImVec2 ( tab_bar - > ScrollingRectMaxX , tab_bar - > BarRect . Max . y ) , IM_COL32 ( 0 , 255 , 0 , 255 ) ) ;
@ -10626,244 +10787,100 @@ void ImGui::ShowMetricsWindow(bool* p_open)
for ( int tab_n = 0 ; tab_n < tab_bar - > Tabs . Size ; tab_n + + )
for ( int tab_n = 0 ; tab_n < tab_bar - > Tabs . Size ; tab_n + + )
{
{
const ImGuiTabItem * tab = & tab_bar - > Tabs [ tab_n ] ;
const ImGuiTabItem * tab = & tab_bar - > Tabs [ tab_n ] ;
ImGui : : PushID ( tab ) ;
PushID ( tab ) ;
if ( ImGui : : SmallButton ( " < " ) ) { TabBarQueueReorder ( tab_bar , tab , - 1 ) ; } ImGui : : SameLine ( 0 , 2 ) ;
if ( SmallButton ( " < " ) ) { TabBarQueueReorder ( tab_bar , tab , - 1 ) ; } SameLine ( 0 , 2 ) ;
if ( ImGui : : SmallButton ( " > " ) ) { TabBarQueueReorder ( tab_bar , tab , + 1 ) ; } ImGui : : SameLine ( ) ;
if ( SmallButton ( " > " ) ) { TabBarQueueReorder ( tab_bar , tab , + 1 ) ; } SameLine ( ) ;
ImGui : : Text ( " %02d%c Tab 0x%08X '%s' Offset: %.1f, Width: %.1f/%.1f " , tab_n , ( tab - > ID = = tab_bar - > SelectedTabId ) ? ' * ' : ' ' , tab - > ID , ( tab - > NameOffset ! = - 1 ) ? tab_bar - > GetTabName ( tab ) : " " , tab - > Offset , tab - > Width , tab - > ContentWidth ) ;
Text ( " %02d%c Tab 0x%08X '%s' Offset: %.1f, Width: %.1f/%.1f " ,
ImGui : : PopID ( ) ;
tab_n , ( tab - > ID = = tab_bar - > SelectedTabId ) ? ' * ' : ' ' , tab - > ID , ( tab - > NameOffset ! = - 1 ) ? tab_bar - > GetTabName ( tab ) : " " , tab - > Offset , tab - > Width , tab - > ContentWidth ) ;
}
PopID ( ) ;
ImGui : : TreePop ( ) ;
}
}
TreePop ( ) ;
}
}
}
static void NodeStorage ( ImGuiStorage * storage , const char * label )
void ImGui : : DebugNodeWindow ( ImGuiWindow * window , const char * label )
{
if ( window = = NULL )
{
{
if ( ! ImGui : : TreeNode ( label , " %s: %d entries, %d bytes " , label , storage - > Data . Size , storage - > Data . size_in_bytes ( ) ) )
BulletText ( " %s: NULL " , label ) ;
return ;
return ;
for ( int n = 0 ; n < storage - > Data . Size ; n + + )
{
const ImGuiStorage : : ImGuiStoragePair & p = storage - > Data [ n ] ;
ImGui : : BulletText ( " Key 0x%08X Value { i: %d } " , p . key , p . val_i ) ; // Important: we currently don't store a type, real value may not be integer.
}
ImGui : : TreePop ( ) ;
}
} ;
// Tools
if ( ImGui : : TreeNode ( " Tools " ) )
{
// The Item Picker tool is super useful to visually select an item and break into the call-stack of where it was submitted.
if ( ImGui : : Button ( " Item Picker.. " ) )
ImGui : : DebugStartItemPicker ( ) ;
ImGui : : SameLine ( ) ;
MetricsHelpMarker ( " Will call the IM_DEBUG_BREAK() macro to break in debugger. \n Warning: If you don't have a debugger attached, this will probably crash. " ) ;
ImGui : : Checkbox ( " Show windows begin order " , & show_windows_begin_order ) ;
ImGui : : Checkbox ( " Show windows rectangles " , & show_windows_rects ) ;
ImGui : : SameLine ( ) ;
ImGui : : SetNextItemWidth ( ImGui : : GetFontSize ( ) * 12 ) ;
show_windows_rects | = ImGui : : Combo ( " ##show_windows_rect_type " , & show_windows_rect_type , wrt_rects_names , WRT_Count , WRT_Count ) ;
if ( show_windows_rects & & g . NavWindow )
{
ImGui : : BulletText ( " '%s': " , g . NavWindow - > Name ) ;
ImGui : : Indent ( ) ;
for ( int rect_n = 0 ; rect_n < WRT_Count ; rect_n + + )
{
ImRect r = Funcs : : GetWindowRect ( g . NavWindow , rect_n ) ;
ImGui : : Text ( " (%6.1f,%6.1f) (%6.1f,%6.1f) Size (%6.1f,%6.1f) %s " , r . Min . x , r . Min . y , r . Max . x , r . Max . y , r . GetWidth ( ) , r . GetHeight ( ) , wrt_rects_names [ rect_n ] ) ;
}
ImGui : : Unindent ( ) ;
}
ImGui : : Checkbox ( " Show mesh when hovering ImDrawCmd " , & show_drawcmd_mesh ) ;
ImGui : : Checkbox ( " Show bounding boxes when hovering ImDrawCmd " , & show_drawcmd_aabb ) ;
ImGui : : TreePop ( ) ;
}
}
// Contents
ImGuiContext & g = * GImGui ;
Funcs : : NodeWindows ( g . Windows , " Windows " ) ;
const bool is_active = window - > WasActive ;
//Funcs::NodeWindows(g.WindowsFocusOrder, "WindowsFocusOrder");
ImGuiTreeNodeFlags tree_node_flags = ( window = = g . NavWindow ) ? ImGuiTreeNodeFlags_Selected : ImGuiTreeNodeFlags_None ;
if ( ImGui : : TreeNode ( " DrawLists " , " Active DrawLists (%d) " , g . DrawDataBuilder . Layers [ 0 ] . Size ) )
if ( ! is_active ) { PushStyleColor ( ImGuiCol_Text , GetStyleColorVec4 ( ImGuiCol_TextDisabled ) ) ; }
{
const bool open = TreeNodeEx ( label , tree_node_flags , " %s '%s'%s " , label , window - > Name , is_active ? " " : " *Inactive* " ) ;
for ( int i = 0 ; i < g . DrawDataBuilder . Layers [ 0 ] . Size ; i + + )
if ( ! is_active ) { PopStyleColor ( ) ; }
Funcs : : NodeDrawList ( NULL , g . DrawDataBuilder . Layers [ 0 ] [ i ] , " DrawList " ) ;
if ( IsItemHovered ( ) & & is_active )
ImGui : : TreePop ( ) ;
GetForegroundDrawList ( window ) - > AddRect ( window - > Pos , window - > Pos + window - > Size , IM_COL32 ( 255 , 255 , 0 , 255 ) ) ;
}
if ( ! open )
return ;
// Details for Popups
if ( ImGui : : TreeNode ( " Popups " , " Popups (%d) " , g . OpenPopupStack . Size ) )
{
for ( int i = 0 ; i < g . OpenPopupStack . Size ; i + + )
{
ImGuiWindow * window = g . OpenPopupStack [ i ] . Window ;
ImGui : : BulletText ( " PopupID: %08x, Window: '%s'%s%s " , g . OpenPopupStack [ i ] . PopupId , window ? window - > Name : " NULL " , window & & ( window - > Flags & ImGuiWindowFlags_ChildWindow ) ? " ChildWindow " : " " , window & & ( window - > Flags & ImGuiWindowFlags_ChildMenu ) ? " ChildMenu " : " " ) ;
}
ImGui : : TreePop ( ) ;
}
// Details for TabBars
if ( ImGui : : TreeNode ( " TabBars " , " Tab Bars (%d) " , g . TabBars . GetSize ( ) ) )
{
for ( int n = 0 ; n < g . TabBars . GetSize ( ) ; n + + )
Funcs : : NodeTabBar ( g . TabBars . GetByIndex ( n ) ) ;
ImGui : : TreePop ( ) ;
}
// Details for Tables
IM_UNUSED ( trt_rects_names ) ;
IM_UNUSED ( show_tables_rects ) ;
IM_UNUSED ( show_tables_rect_type ) ;
# ifdef IMGUI_HAS_TABLE
if ( ImGui : : TreeNode ( " Tables " , " Tables (%d) " , g . Tables . GetSize ( ) ) )
{
for ( int n = 0 ; n < g . Tables . GetSize ( ) ; n + + )
Funcs : : NodeTable ( g . Tables . GetByIndex ( n ) ) ;
ImGui : : TreePop ( ) ;
}
# endif // #ifdef IMGUI_HAS_TABLE
// Details for Docking
if ( window - > MemoryCompacted )
# ifdef IMGUI_HAS_DOCK
TextDisabled ( " Note: some memory buffers have been compacted/freed. " ) ;
if ( ImGui : : TreeNode ( " Dock nodes " ) )
{
ImGui : : TreePop ( ) ;
}
# endif // #ifdef IMGUI_HAS_DOCK
// Settings
ImGuiWindowFlags flags = window - > Flags ;
if ( ImGui : : TreeNode ( " Settings " ) )
DebugNodeDrawList ( window , window - > DrawList , " DrawList " ) ;
{
BulletText ( " Pos: (%.1f,%.1f), Size: (%.1f,%.1f), ContentSize (%.1f,%.1f) " , window - > Pos . x , window - > Pos . y , window - > Size . x , window - > Size . y , window - > ContentSize . x , window - > ContentSize . y ) ;
if ( ImGui : : SmallButton ( " Clear " ) )
BulletText ( " Flags: 0x%08X (%s%s%s%s%s%s%s%s%s..) " , flags ,
ImGui : : ClearIniSettings ( ) ;
( flags & ImGuiWindowFlags_ChildWindow ) ? " Child " : " " , ( flags & ImGuiWindowFlags_Tooltip ) ? " Tooltip " : " " , ( flags & ImGuiWindowFlags_Popup ) ? " Popup " : " " ,
ImGui : : SameLine ( ) ;
( flags & ImGuiWindowFlags_Modal ) ? " Modal " : " " , ( flags & ImGuiWindowFlags_ChildMenu ) ? " ChildMenu " : " " , ( flags & ImGuiWindowFlags_NoSavedSettings ) ? " NoSavedSettings " : " " ,
if ( ImGui : : SmallButton ( " Save to memory " ) )
( flags & ImGuiWindowFlags_NoMouseInputs ) ? " NoMouseInputs " : " " , ( flags & ImGuiWindowFlags_NoNavInputs ) ? " NoNavInputs " : " " , ( flags & ImGuiWindowFlags_AlwaysAutoResize ) ? " AlwaysAutoResize " : " " ) ;
ImGui : : SaveIniSettingsToMemory ( ) ;
BulletText ( " Scroll: (%.2f/%.2f,%.2f/%.2f) Scrollbar:%s%s " , window - > Scroll . x , window - > ScrollMax . x , window - > Scroll . y , window - > ScrollMax . y , window - > ScrollbarX ? " X " : " " , window - > ScrollbarY ? " Y " : " " ) ;
ImGui : : SameLine ( ) ;
BulletText ( " Active: %d/%d, WriteAccessed: %d, BeginOrderWithinContext: %d " , window - > Active , window - > WasActive , window - > WriteAccessed , ( window - > Active | | window - > WasActive ) ? window - > BeginOrderWithinContext : - 1 ) ;
if ( ImGui : : SmallButton ( " Save to disk " ) )
BulletText ( " Appearing: %d, Hidden: %d (CanSkip %d Cannot %d), SkipItems: %d " , window - > Appearing , window - > Hidden , window - > HiddenFramesCanSkipItems , window - > HiddenFramesCannotSkipItems , window - > SkipItems ) ;
ImGui : : SaveIniSettingsToDisk ( g . IO . IniFilename ) ;
BulletText ( " NavLastIds: 0x%08X,0x%08X, NavLayerActiveMask: %X " , window - > NavLastIds [ 0 ] , window - > NavLastIds [ 1 ] , window - > DC . NavLayerActiveMask ) ;
ImGui : : SameLine ( ) ;
BulletText ( " NavLastChildNavWindow: %s " , window - > NavLastChildNavWindow ? window - > NavLastChildNavWindow - > Name : " NULL " ) ;
if ( g . IO . IniFilename )
if ( ! window - > NavRectRel [ 0 ] . IsInverted ( ) )
ImGui : : Text ( " \" %s \" " , g . IO . IniFilename ) ;
BulletText ( " NavRectRel[0]: (%.1f,%.1f)(%.1f,%.1f) " , window - > NavRectRel [ 0 ] . Min . x , window - > NavRectRel [ 0 ] . Min . y , window - > NavRectRel [ 0 ] . Max . x , window - > NavRectRel [ 0 ] . Max . y ) ;
else
else
ImGui : : TextUnformatted ( " <NULL> " ) ;
BulletText ( " NavRectRel[0]: <None> " ) ;
ImGui : : Text ( " SettingsDirtyTimer %.2f " , g . SettingsDirtyTimer ) ;
if ( window - > RootWindow ! = window ) { DebugNodeWindow ( window - > RootWindow , " RootWindow " ) ; }
if ( ImGui : : TreeNode ( " SettingsHandlers " , " Settings handlers: (%d) " , g . SettingsHandlers . Size ) )
if ( window - > ParentWindow ! = NULL ) { DebugNodeWindow ( window - > ParentWindow , " ParentWindow " ) ; }
if ( window - > DC . ChildWindows . Size > 0 ) { DebugNodeWindowsList ( & window - > DC . ChildWindows , " ChildWindows " ) ; }
if ( window - > ColumnsStorage . Size > 0 & & TreeNode ( " Columns " , " Columns sets (%d) " , window - > ColumnsStorage . Size ) )
{
{
for ( int n = 0 ; n < g . SettingsHandlers . Size ; n + + )
for ( int n = 0 ; n < window - > ColumnsStorage . Size ; n + + )
ImGui : : BulletText ( " %s " , g . SettingsHandlers [ n ] . TypeName ) ;
DebugNodeColumns ( & window - > ColumnsStorage [ n ] ) ;
ImGui : : TreePop ( ) ;
TreePop ( ) ;
}
if ( ImGui : : TreeNode ( " SettingsWindows " , " Settings packed data: Windows: %d bytes " , g . SettingsWindows . size ( ) ) )
{
for ( ImGuiWindowSettings * settings = g . SettingsWindows . begin ( ) ; settings ! = NULL ; settings = g . SettingsWindows . next_chunk ( settings ) )
Funcs : : NodeWindowSettings ( settings ) ;
ImGui : : TreePop ( ) ;
}
# ifdef IMGUI_HAS_TABLE
if ( ImGui : : TreeNode ( " SettingsTables " , " Settings packed data: Tables: %d bytes " , g . SettingsTables . size ( ) ) )
{
for ( ImGuiTableSettings * settings = g . SettingsTables . begin ( ) ; settings ! = NULL ; settings = g . SettingsTables . next_chunk ( settings ) )
Funcs : : NodeTableSettings ( settings ) ;
ImGui : : TreePop ( ) ;
}
# endif // #ifdef IMGUI_HAS_TABLE
# ifdef IMGUI_HAS_DOCK
# endif // #ifdef IMGUI_HAS_DOCK
if ( ImGui : : TreeNode ( " SettingsIniData " , " Settings unpacked data (.ini): %d bytes " , g . SettingsIniData . size ( ) ) )
{
ImGui : : InputTextMultiline ( " ##Ini " , ( char * ) ( void * ) g . SettingsIniData . c_str ( ) , g . SettingsIniData . Buf . Size , ImVec2 ( - FLT_MIN , ImGui : : GetTextLineHeight ( ) * 20 ) , ImGuiInputTextFlags_ReadOnly ) ;
ImGui : : TreePop ( ) ;
}
ImGui : : TreePop ( ) ;
}
// Misc Details
if ( ImGui : : TreeNode ( " Internal state " ) )
{
const char * input_source_names [ ] = { " None " , " Mouse " , " Nav " , " NavKeyboard " , " NavGamepad " } ; IM_ASSERT ( IM_ARRAYSIZE ( input_source_names ) = = ImGuiInputSource_COUNT ) ;
ImGui : : Text ( " WINDOWING " ) ;
ImGui : : Indent ( ) ;
ImGui : : Text ( " HoveredWindow: '%s' " , g . HoveredWindow ? g . HoveredWindow - > Name : " NULL " ) ;
ImGui : : Text ( " HoveredRootWindow: '%s' " , g . HoveredRootWindow ? g . HoveredRootWindow - > Name : " NULL " ) ;
ImGui : : Text ( " HoveredWindowUnderMovingWindow: '%s' " , g . HoveredWindowUnderMovingWindow ? g . HoveredWindowUnderMovingWindow - > Name : " NULL " ) ;
ImGui : : Text ( " MovingWindow: '%s' " , g . MovingWindow ? g . MovingWindow - > Name : " NULL " ) ;
ImGui : : Unindent ( ) ;
ImGui : : Text ( " ITEMS " ) ;
ImGui : : Indent ( ) ;
ImGui : : Text ( " ActiveId: 0x%08X/0x%08X (%.2f sec), AllowOverlap: %d, Source: %s " , g . ActiveId , g . ActiveIdPreviousFrame , g . ActiveIdTimer , g . ActiveIdAllowOverlap , input_source_names [ g . ActiveIdSource ] ) ;
ImGui : : Text ( " ActiveIdWindow: '%s' " , g . ActiveIdWindow ? g . ActiveIdWindow - > Name : " NULL " ) ;
ImGui : : Text ( " HoveredId: 0x%08X/0x%08X (%.2f sec), AllowOverlap: %d " , g . HoveredId , g . HoveredIdPreviousFrame , g . HoveredIdTimer , g . HoveredIdAllowOverlap ) ; // Data is "in-flight" so depending on when the Metrics window is called we may see current frame information or not
ImGui : : Text ( " DragDrop: %d, SourceId = 0x%08X, Payload \" %s \" (%d bytes) " , g . DragDropActive , g . DragDropPayload . SourceId , g . DragDropPayload . DataType , g . DragDropPayload . DataSize ) ;
ImGui : : Unindent ( ) ;
ImGui : : Text ( " NAV,FOCUS " ) ;
ImGui : : Indent ( ) ;
ImGui : : Text ( " NavWindow: '%s' " , g . NavWindow ? g . NavWindow - > Name : " NULL " ) ;
ImGui : : Text ( " NavId: 0x%08X, NavLayer: %d " , g . NavId , g . NavLayer ) ;
ImGui : : Text ( " NavInputSource: %s " , input_source_names [ g . NavInputSource ] ) ;
ImGui : : Text ( " NavActive: %d, NavVisible: %d " , g . IO . NavActive , g . IO . NavVisible ) ;
ImGui : : Text ( " NavActivateId: 0x%08X, NavInputId: 0x%08X " , g . NavActivateId , g . NavInputId ) ;
ImGui : : Text ( " NavDisableHighlight: %d, NavDisableMouseHover: %d " , g . NavDisableHighlight , g . NavDisableMouseHover ) ;
ImGui : : Text ( " NavFocusScopeId = 0x%08X " , g . NavFocusScopeId ) ;
ImGui : : Text ( " NavWindowingTarget: '%s' " , g . NavWindowingTarget ? g . NavWindowingTarget - > Name : " NULL " ) ;
ImGui : : Unindent ( ) ;
ImGui : : TreePop ( ) ;
}
}
DebugNodeStorage ( & window - > StateStorage , " Storage " ) ;
TreePop ( ) ;
}
// Overlay: Display windows Rectangles and Begin Order
void ImGui : : DebugNodeWindowSettings ( ImGuiWindowSettings * settings )
if ( show_windows_rects | | show_windows_begin_order )
{
{
Text ( " 0x%08X \" %s \" Pos (%d,%d) Size (%d,%d) Collapsed=%d " ,
for ( int n = 0 ; n < g . Windows . Size ; n + + )
settings - > ID , settings - > GetName ( ) , settings - > Pos . x , settings - > Pos . y , settings - > Size . x , settings - > Size . y , settings - > Collapsed ) ;
{
}
ImGuiWindow * window = g . Windows [ n ] ;
if ( ! window - > WasActive )
continue ;
ImDrawList * draw_list = GetForegroundDrawList ( window ) ;
if ( show_windows_rects )
{
ImRect r = Funcs : : GetWindowRect ( window , show_windows_rect_type ) ;
draw_list - > AddRect ( r . Min , r . Max , IM_COL32 ( 255 , 0 , 128 , 255 ) ) ;
}
if ( show_windows_begin_order & & ! ( window - > Flags & ImGuiWindowFlags_ChildWindow ) )
{
char buf [ 32 ] ;
ImFormatString ( buf , IM_ARRAYSIZE ( buf ) , " %d " , window - > BeginOrderWithinContext ) ;
float font_size = ImGui : : GetFontSize ( ) ;
draw_list - > AddRectFilled ( window - > Pos , window - > Pos + ImVec2 ( font_size , font_size ) , IM_COL32 ( 200 , 100 , 100 , 255 ) ) ;
draw_list - > AddText ( window - > Pos , IM_COL32 ( 255 , 255 , 255 , 255 ) , buf ) ;
}
}
}
# ifdef IMGUI_HAS_TABLE
// Overlay: Display Tables Rectangles
if ( show_tables_rects )
{
for ( int table_n = 0 ; table_n < g . Tables . GetSize ( ) ; table_n + + )
{
ImGuiTable * table = g . Tables . GetByIndex ( table_n ) ;
}
}
# endif // #ifdef IMGUI_HAS_TABLE
# ifdef IMGUI_HAS_DOCK
void ImGui : : DebugNodeWindowsList ( ImVector < ImGuiWindow * > * windows , const char * label )
// Overlay: Display Docking info
{
if ( show_docking_nodes & & g . IO . KeyCtrl )
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 ] ) ;
DebugNodeWindow ( ( * windows ) [ i ] , " Window " ) ;
PopID ( ) ;
}
}
# endif // #ifdef IMGUI_HAS_DOCK
TreePop ( ) ;
ImGui : : End ( ) ;
}
}
# else
# else
void ImGui : : ShowMetricsWindow ( bool * ) { }
void ImGui : : ShowMetricsWindow ( bool * ) { }
void ImGui : : DebugNodeColumns ( ImGuiColumns * ) { }
void ImGui : : DebugNodeDrawList ( ImGuiWindow * , ImDrawList * , const char * ) { }
void ImGui : : DebugNodeDrawCmdShowMeshAndBoundingBox ( ImGuiWindow * , const ImDrawList * , const ImDrawCmd * , bool , bool ) { }
void ImGui : : DebugNodeStorage ( ImGuiStorage * , const char * ) { }
void ImGui : : DebugNodeTabBar ( ImGuiTabBar * , const char * ) { }
void ImGui : : DebugNodeWindow ( ImGuiWindow * , const char * ) { }
void ImGui : : DebugNodeWindowSettings ( ImGuiWindowSettings * ) { }
void ImGui : : DebugNodeWindowsList ( ImVector < ImGuiWindow * > * , const char * ) { }
# endif
# endif