mirror of
				https://github.com/Drezil/imgui.git
				synced 2025-10-31 13:11:05 +01:00 
			
		
		
		
	Metrics: Extracted most functions.
+ avoid using full namesapce prefix
This commit is contained in:
		
							
								
								
									
										747
									
								
								imgui.cpp
									
									
									
									
									
								
							
							
						
						
									
										747
									
								
								imgui.cpp
									
									
									
									
									
								
							| @@ -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,422 +10402,174 @@ 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) |  | ||||||
|         { |  | ||||||
|             IM_ASSERT(show_mesh || show_aabb); |  | ||||||
|             ImDrawList* fg_draw_list = GetForegroundDrawList(window); // Render additional visuals into the top-most draw list |  | ||||||
|             ImDrawIdx* idx_buffer = (draw_list->IdxBuffer.Size > 0) ? draw_list->IdxBuffer.Data : NULL; |  | ||||||
|             ImDrawVert* vtx_buffer = draw_list->VtxBuffer.Data + draw_cmd->VtxOffset; |  | ||||||
|  |  | ||||||
|             // Draw wire-frame version of all triangles |  | ||||||
|             ImRect clip_rect = draw_cmd->ClipRect; |  | ||||||
|             ImRect vtxs_rect(FLT_MAX, FLT_MAX, -FLT_MAX, -FLT_MAX); |  | ||||||
|             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. |  | ||||||
|             for (unsigned int idx_n = draw_cmd->IdxOffset; idx_n < draw_cmd->IdxOffset + draw_cmd->ElemCount; ) |  | ||||||
|             { |  | ||||||
|                 ImVec2 triangle[3]; |  | ||||||
|                 for (int n = 0; n < 3; n++, idx_n++) |  | ||||||
|                     vtxs_rect.Add((triangle[n] = vtx_buffer[idx_buffer ? idx_buffer[idx_n] : idx_n].pos)); |  | ||||||
|                 if (show_mesh) |  | ||||||
|                     fg_draw_list->AddPolyline(triangle, 3, IM_COL32(255, 255, 0, 255), true, 1.0f); // In yellow: mesh triangles |  | ||||||
|             } |  | ||||||
|             // Draw bounding boxes |  | ||||||
|             if (show_aabb) |  | ||||||
|             { |  | ||||||
|                 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 |  | ||||||
|                 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; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         static void NodeDrawList(ImGuiWindow* window, ImDrawList* draw_list, const char* label) |  | ||||||
|         { |  | ||||||
|             int cmd_count = draw_list->CmdBuffer.Size; |  | ||||||
|             if (cmd_count > 0 && draw_list->CmdBuffer.back().ElemCount == 0 && draw_list->CmdBuffer.back().UserCallback == NULL) |  | ||||||
|                 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); |  | ||||||
|             if (draw_list == ImGui::GetWindowDrawList()) |  | ||||||
|             { |  | ||||||
|                 ImGui::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) |  | ||||||
|                 if (node_open) ImGui::TreePop(); |  | ||||||
|                 return; |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             ImDrawList* fg_draw_list = GetForegroundDrawList(window); // Render additional visuals into the top-most draw list |  | ||||||
|             if (window && IsItemHovered()) |  | ||||||
|                 fg_draw_list->AddRect(window->Pos, window->Pos + window->Size, IM_COL32(255, 255, 0, 255)); |  | ||||||
|             if (!node_open) |  | ||||||
|                 return; |  | ||||||
|  |  | ||||||
|             if (window && !window->WasActive) |  | ||||||
|                 ImGui::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++) |  | ||||||
|             { |  | ||||||
|                 if (pcmd->UserCallback) |  | ||||||
|                 { |  | ||||||
|                     ImGui::BulletText("Callback %p, user_data %p", pcmd->UserCallback, pcmd->UserCallbackData); |  | ||||||
|                     continue; |  | ||||||
|                 } |  | ||||||
|  |  | ||||||
|                 char buf[300]; |  | ||||||
|                 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->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); |  | ||||||
|                 if (ImGui::IsItemHovered() && (show_drawcmd_mesh || show_drawcmd_aabb) && fg_draw_list) |  | ||||||
|                     NodeDrawCmdShowMeshAndBoundingBox(window, draw_list, pcmd, show_drawcmd_mesh, show_drawcmd_aabb); |  | ||||||
|                 if (!pcmd_node_open) |  | ||||||
|                     continue; |  | ||||||
|  |  | ||||||
|                 // Calculate approximate coverage area (touched pixel count) |  | ||||||
|                 // This will be in pixels squared as long there's no post-scaling happening to the renderer output. |  | ||||||
|                 const ImDrawIdx* idx_buffer = (draw_list->IdxBuffer.Size > 0) ? draw_list->IdxBuffer.Data : NULL; |  | ||||||
|                 const ImDrawVert* vtx_buffer = draw_list->VtxBuffer.Data + pcmd->VtxOffset; |  | ||||||
|                 float total_area = 0.0f; |  | ||||||
|                 for (unsigned int idx_n = pcmd->IdxOffset; idx_n < pcmd->IdxOffset + pcmd->ElemCount; ) |  | ||||||
|                 { |  | ||||||
|                     ImVec2 triangle[3]; |  | ||||||
|                     for (int n = 0; n < 3; n++, idx_n++) |  | ||||||
|                         triangle[n] = vtx_buffer[idx_buffer ? idx_buffer[idx_n] : idx_n].pos; |  | ||||||
|                     total_area += ImTriangleArea(triangle[0], triangle[1], triangle[2]); |  | ||||||
|                 } |  | ||||||
|  |  | ||||||
|                 // 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); |  | ||||||
|                 ImGui::Selectable(buf); |  | ||||||
|                 if (ImGui::IsItemHovered() && fg_draw_list) |  | ||||||
|                     NodeDrawCmdShowMeshAndBoundingBox(window, draw_list, pcmd, true, false); |  | ||||||
|  |  | ||||||
|                 // Display individual triangles/vertices. Hover on to get the corresponding triangle highlighted. |  | ||||||
|                 ImGuiListClipper clipper; |  | ||||||
|                 clipper.Begin(pcmd->ElemCount / 3); // Manually coarse clip our print out of individual vertices to save CPU, only items that may be visible. |  | ||||||
|                 while (clipper.Step()) |  | ||||||
|                     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); |  | ||||||
|                         ImVec2 triangle[3]; |  | ||||||
|                         for (int n = 0; n < 3; n++, idx_i++) |  | ||||||
|                         { |  | ||||||
|                             const ImDrawVert& v = vtx_buffer[idx_buffer ? idx_buffer[idx_i] : idx_i]; |  | ||||||
|                             triangle[n] = v.pos; |  | ||||||
|                             buf_p += ImFormatString(buf_p, buf_end - buf_p, "%s %04d: pos (%8.2f,%8.2f), uv (%.6f,%.6f), col %08X\n", |  | ||||||
|                                 (n == 0) ? "Vert:" : "     ", idx_i, v.pos.x, v.pos.y, v.uv.x, v.uv.y, v.col); |  | ||||||
|                         } |  | ||||||
|  |  | ||||||
|                         ImGui::Selectable(buf, false); |  | ||||||
|                         if (fg_draw_list && ImGui::IsItemHovered()) |  | ||||||
|                         { |  | ||||||
|                             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->AddPolyline(triangle, 3, IM_COL32(255,255,0,255), true, 1.0f); |  | ||||||
|                             fg_draw_list->Flags = backup_flags; |  | ||||||
|                         } |  | ||||||
|                     } |  | ||||||
|                 ImGui::TreePop(); |  | ||||||
|             } |  | ||||||
|             ImGui::TreePop(); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         static void NodeColumns(const ImGuiColumns* columns) |  | ||||||
|         { |  | ||||||
|             if (!ImGui::TreeNode((void*)(uintptr_t)columns->ID, "Columns Id: 0x%08X, Count: %d, Flags: 0x%04X", columns->ID, columns->Count, columns->Flags)) |  | ||||||
|                 return; |  | ||||||
|             ImGui::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++) |  | ||||||
|                 ImGui::BulletText("Column %02d: OffsetNorm %.3f (= %.1f px)", column_n, columns->Columns[column_n].OffsetNorm, GetColumnOffsetFromNorm(columns, columns->Columns[column_n].OffsetNorm)); |  | ||||||
|             ImGui::TreePop(); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         static void NodeWindows(ImVector<ImGuiWindow*>& windows, const char* label) |  | ||||||
|         { |  | ||||||
|             if (!ImGui::TreeNode(label, "%s (%d)", label, windows.Size)) |  | ||||||
|                 return; |  | ||||||
|             ImGui::Text("(In front-to-back order:)"); |  | ||||||
|             for (int i = windows.Size - 1; i >= 0; i--) // Iterate front to back |  | ||||||
|             { |  | ||||||
|                 ImGui::PushID(windows[i]); |  | ||||||
|                 Funcs::NodeWindow(windows[i], "Window"); |  | ||||||
|                 ImGui::PopID(); |  | ||||||
|             } |  | ||||||
|             ImGui::TreePop(); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         static void NodeWindow(ImGuiWindow* window, const char* label) |  | ||||||
|         { |  | ||||||
|             if (window == NULL) |  | ||||||
|             { |  | ||||||
|                 ImGui::BulletText("%s: NULL", label); |  | ||||||
|                 return; |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             ImGuiContext& g = *GImGui; |  | ||||||
|             const bool is_active = window->WasActive; |  | ||||||
|             ImGuiTreeNodeFlags tree_node_flags = (window == g.NavWindow) ? ImGuiTreeNodeFlags_Selected : ImGuiTreeNodeFlags_None; |  | ||||||
|             if (!is_active) { PushStyleColor(ImGuiCol_Text, GetStyleColorVec4(ImGuiCol_TextDisabled)); } |  | ||||||
|             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; |  | ||||||
|  |  | ||||||
|             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", |  | ||||||
|                 settings->ID, settings->GetName(), settings->Pos.x, settings->Pos.y, settings->Size.x, settings->Size.y, settings->Collapsed); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         static void NodeTabBar(ImGuiTabBar* tab_bar) |  | ||||||
|         { |  | ||||||
|             // Standalone tab bars (not associated to docking/windows functionality) currently hold no discernible strings. |  | ||||||
|             char buf[256]; |  | ||||||
|             char* p = buf; |  | ||||||
|             const char* buf_end = buf + IM_ARRAYSIZE(buf); |  | ||||||
|             const bool is_active = (tab_bar->PrevFrameVisible >= ImGui::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*"); |  | ||||||
|             IM_UNUSED(p); |  | ||||||
|             if (!is_active) { PushStyleColor(ImGuiCol_Text, GetStyleColorVec4(ImGuiCol_TextDisabled)); } |  | ||||||
|             bool open = ImGui::TreeNode(tab_bar, "%s", buf); |  | ||||||
|             if (!is_active) { PopStyleColor(); } |  | ||||||
|             if (is_active && ImGui::IsItemHovered()) |  | ||||||
|             { |  | ||||||
|                 ImDrawList* draw_list = ImGui::GetForegroundDrawList(); |  | ||||||
|                 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->ScrollingRectMaxX, tab_bar->BarRect.Min.y), ImVec2(tab_bar->ScrollingRectMaxX, tab_bar->BarRect.Max.y), IM_COL32(0, 255, 0, 255)); |  | ||||||
|             } |  | ||||||
|             if (open) |  | ||||||
|             { |  | ||||||
|                 for (int tab_n = 0; tab_n < tab_bar->Tabs.Size; tab_n++) |  | ||||||
|                 { |  | ||||||
|                     const ImGuiTabItem* tab = &tab_bar->Tabs[tab_n]; |  | ||||||
|                     ImGui::PushID(tab); |  | ||||||
|                     if (ImGui::SmallButton("<")) { TabBarQueueReorder(tab_bar, tab, -1); } ImGui::SameLine(0, 2); |  | ||||||
|                     if (ImGui::SmallButton(">")) { TabBarQueueReorder(tab_bar, tab, +1); } ImGui::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); |  | ||||||
|                     ImGui::PopID(); |  | ||||||
|                 } |  | ||||||
|                 ImGui::TreePop(); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         static void NodeStorage(ImGuiStorage* storage, const char* label) |  | ||||||
|         { |  | ||||||
|             if (!ImGui::TreeNode(label, "%s: %d entries, %d bytes", label, storage->Data.Size, storage->Data.size_in_bytes())) |  | ||||||
|                 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 |     // Tools | ||||||
|     if (ImGui::TreeNode("Tools")) |     if (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. |         // 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..")) |         if (Button("Item Picker..")) | ||||||
|             ImGui::DebugStartItemPicker(); |             DebugStartItemPicker(); | ||||||
|         ImGui::SameLine(); |         SameLine(); | ||||||
|         MetricsHelpMarker("Will call the IM_DEBUG_BREAK() macro to break in debugger.\nWarning: If you don't have a debugger attached, this will probably crash."); |         MetricsHelpMarker("Will call the IM_DEBUG_BREAK() macro to break in debugger.\nWarning: If you don't have a debugger attached, this will probably crash."); | ||||||
|  |  | ||||||
|         ImGui::Checkbox("Show windows begin order", &show_windows_begin_order); |         Checkbox("Show windows begin order", &cfg->ShowWindowsBeginOrder); | ||||||
|         ImGui::Checkbox("Show windows rectangles", &show_windows_rects); |         ImGui::Checkbox("Show windows rectangles", &cfg->ShowWindowsRects); | ||||||
|         ImGui::SameLine(); |         SameLine(); | ||||||
|         ImGui::SetNextItemWidth(ImGui::GetFontSize() * 12); |         SetNextItemWidth(GetFontSize() * 12); | ||||||
|         show_windows_rects |= ImGui::Combo("##show_windows_rect_type", &show_windows_rect_type, wrt_rects_names, WRT_Count, WRT_Count); |         cfg->ShowWindowsRects |= Combo("##show_windows_rect_type", &cfg->ShowWindowsRectsType, wrt_rects_names, WRT_Count, WRT_Count); | ||||||
|         if (show_windows_rects && g.NavWindow) |         if (cfg->ShowWindowsRects && g.NavWindow != NULL) | ||||||
|         { |         { | ||||||
|             ImGui::BulletText("'%s':", g.NavWindow->Name); |             BulletText("'%s':", g.NavWindow->Name); | ||||||
|             ImGui::Indent(); |             Indent(); | ||||||
|             for (int rect_n = 0; rect_n < WRT_Count; rect_n++) |             for (int rect_n = 0; rect_n < WRT_Count; rect_n++) | ||||||
|             { |             { | ||||||
|                 ImRect r = Funcs::GetWindowRect(g.NavWindow, 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]); |                 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(); |             Unindent(); | ||||||
|         } |         } | ||||||
|         ImGui::Checkbox("Show mesh when hovering ImDrawCmd", &show_drawcmd_mesh); |         Checkbox("Show ImDrawCmd mesh when hovering", &cfg->ShowDrawCmdMesh); | ||||||
|         ImGui::Checkbox("Show bounding boxes when hovering ImDrawCmd", &show_drawcmd_aabb); |         Checkbox("Show ImDrawCmd bounding boxes when hovering", &cfg->ShowDrawCmdBoundingBoxes); | ||||||
|         ImGui::TreePop(); |         TreePop(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // Contents |     // Contents | ||||||
|     Funcs::NodeWindows(g.Windows, "Windows"); |     DebugNodeWindowsList(&g.Windows, "Windows"); | ||||||
|     //Funcs::NodeWindows(g.WindowsFocusOrder, "WindowsFocusOrder"); |     //DebugNodeWindowList(&g.WindowsFocusOrder, "WindowsFocusOrder"); | ||||||
|     if (ImGui::TreeNode("DrawLists", "Active DrawLists (%d)", g.DrawDataBuilder.Layers[0].Size)) |     if (TreeNode("DrawLists", "Active DrawLists (%d)", g.DrawDataBuilder.Layers[0].Size)) | ||||||
|     { |     { | ||||||
|         for (int i = 0; i < g.DrawDataBuilder.Layers[0].Size; i++) |         for (int i = 0; i < g.DrawDataBuilder.Layers[0].Size; i++) | ||||||
|             Funcs::NodeDrawList(NULL, g.DrawDataBuilder.Layers[0][i], "DrawList"); |             DebugNodeDrawList(NULL, g.DrawDataBuilder.Layers[0][i], "DrawList"); | ||||||
|         ImGui::TreePop(); |         TreePop(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // Details for Popups |     // Details for Popups | ||||||
|     if (ImGui::TreeNode("Popups", "Popups (%d)", g.OpenPopupStack.Size)) |     if (TreeNode("Popups", "Popups (%d)", g.OpenPopupStack.Size)) | ||||||
|     { |     { | ||||||
|         for (int i = 0; i < g.OpenPopupStack.Size; i++) |         for (int i = 0; i < g.OpenPopupStack.Size; i++) | ||||||
|         { |         { | ||||||
|             ImGuiWindow* window = g.OpenPopupStack[i].Window; |             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" : ""); |             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(); |         TreePop(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // Details for TabBars |     // Details for TabBars | ||||||
|     if (ImGui::TreeNode("TabBars", "Tab Bars (%d)", g.TabBars.GetSize())) |     if (TreeNode("TabBars", "Tab Bars (%d)", g.TabBars.GetSize())) | ||||||
|     { |     { | ||||||
|         for (int n = 0; n < g.TabBars.GetSize(); n++) |         for (int n = 0; n < g.TabBars.GetSize(); n++) | ||||||
|             Funcs::NodeTabBar(g.TabBars.GetByIndex(n)); |             DebugNodeTabBar(g.TabBars.GetByIndex(n), "TabBar"); | ||||||
|         ImGui::TreePop(); |         TreePop(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // Details for Tables |     // Details for Tables | ||||||
|     IM_UNUSED(trt_rects_names); |     IM_UNUSED(trt_rects_names); | ||||||
|     IM_UNUSED(show_tables_rects); |  | ||||||
|     IM_UNUSED(show_tables_rect_type); |  | ||||||
| #ifdef IMGUI_HAS_TABLE | #ifdef IMGUI_HAS_TABLE | ||||||
|     if (ImGui::TreeNode("Tables", "Tables (%d)", g.Tables.GetSize())) |     if (TreeNode("Tables", "Tables (%d)", g.Tables.GetSize())) | ||||||
|     { |     { | ||||||
|         for (int n = 0; n < g.Tables.GetSize(); n++) |         for (int n = 0; n < g.Tables.GetSize(); n++) | ||||||
|             Funcs::NodeTable(g.Tables.GetByIndex(n)); |             DebugNodeTable(g.Tables.GetByIndex(n)); | ||||||
|         ImGui::TreePop(); |         TreePop(); | ||||||
|     } |     } | ||||||
| #endif // #ifdef IMGUI_HAS_TABLE | #endif // #ifdef IMGUI_HAS_TABLE | ||||||
|  |  | ||||||
|     // Details for Docking |     // Details for Docking | ||||||
| #ifdef IMGUI_HAS_DOCK | #ifdef IMGUI_HAS_DOCK | ||||||
|     if (ImGui::TreeNode("Dock nodes")) |     if (TreeNode("Docking")) | ||||||
|     { |     { | ||||||
|         ImGui::TreePop(); |         TreePop(); | ||||||
|     } |     } | ||||||
| #endif // #ifdef IMGUI_HAS_DOCK | #endif // #ifdef IMGUI_HAS_DOCK | ||||||
|  |  | ||||||
|     // Settings |     // Settings | ||||||
|     if (ImGui::TreeNode("Settings")) |     if (TreeNode("Settings")) | ||||||
|     { |     { | ||||||
|         if (ImGui::SmallButton("Clear")) |         if (SmallButton("Clear")) | ||||||
|             ImGui::ClearIniSettings(); |             ClearIniSettings(); | ||||||
|         ImGui::SameLine(); |         SameLine(); | ||||||
|         if (ImGui::SmallButton("Save to memory")) |         if (SmallButton("Save to memory")) | ||||||
|             ImGui::SaveIniSettingsToMemory(); |             SaveIniSettingsToMemory(); | ||||||
|         ImGui::SameLine(); |         SameLine(); | ||||||
|         if (ImGui::SmallButton("Save to disk")) |         if (SmallButton("Save to disk")) | ||||||
|             ImGui::SaveIniSettingsToDisk(g.IO.IniFilename); |             SaveIniSettingsToDisk(g.IO.IniFilename); | ||||||
|         ImGui::SameLine(); |         SameLine(); | ||||||
|         if (g.IO.IniFilename) |         if (g.IO.IniFilename) | ||||||
|             ImGui::Text("\"%s\"", g.IO.IniFilename); |             Text("\"%s\"", g.IO.IniFilename); | ||||||
|         else |         else | ||||||
|             ImGui::TextUnformatted("<NULL>"); |             TextUnformatted("<NULL>"); | ||||||
|         ImGui::Text("SettingsDirtyTimer %.2f", g.SettingsDirtyTimer); |         Text("SettingsDirtyTimer %.2f", g.SettingsDirtyTimer); | ||||||
|         if (ImGui::TreeNode("SettingsHandlers", "Settings handlers: (%d)", g.SettingsHandlers.Size)) |         if (TreeNode("SettingsHandlers", "Settings handlers: (%d)", g.SettingsHandlers.Size)) | ||||||
|         { |         { | ||||||
|             for (int n = 0; n < g.SettingsHandlers.Size; n++) |             for (int n = 0; n < g.SettingsHandlers.Size; n++) | ||||||
|                 ImGui::BulletText("%s", g.SettingsHandlers[n].TypeName); |                 BulletText("%s", g.SettingsHandlers[n].TypeName); | ||||||
|             ImGui::TreePop(); |             TreePop(); | ||||||
|         } |         } | ||||||
|         if (ImGui::TreeNode("SettingsWindows", "Settings packed data: Windows: %d bytes", g.SettingsWindows.size())) |         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)) |             for (ImGuiWindowSettings* settings = g.SettingsWindows.begin(); settings != NULL; settings = g.SettingsWindows.next_chunk(settings)) | ||||||
|                 Funcs::NodeWindowSettings(settings); |                 DebugNodeWindowSettings(settings); | ||||||
|             ImGui::TreePop(); |             TreePop(); | ||||||
|         } |         } | ||||||
|  |  | ||||||
| #ifdef IMGUI_HAS_TABLE | #ifdef IMGUI_HAS_TABLE | ||||||
|         if (ImGui::TreeNode("SettingsTables", "Settings packed data: Tables: %d bytes", g.SettingsTables.size())) |         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)) |             for (ImGuiTableSettings* settings = g.SettingsTables.begin(); settings != NULL; settings = g.SettingsTables.next_chunk(settings)) | ||||||
|                 Funcs::NodeTableSettings(settings); |                 DebugNodeTableSettings(settings); | ||||||
|             ImGui::TreePop(); |             TreePop(); | ||||||
|         } |         } | ||||||
| #endif // #ifdef IMGUI_HAS_TABLE | #endif // #ifdef IMGUI_HAS_TABLE | ||||||
|  |  | ||||||
| #ifdef IMGUI_HAS_DOCK | #ifdef IMGUI_HAS_DOCK | ||||||
| #endif // #ifdef IMGUI_HAS_DOCK | #endif // #ifdef IMGUI_HAS_DOCK | ||||||
|  |  | ||||||
|         if (ImGui::TreeNode("SettingsIniData", "Settings unpacked data (.ini): %d bytes", g.SettingsIniData.size())) |         if (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); |             InputTextMultiline("##Ini", (char*)(void*)g.SettingsIniData.c_str(), g.SettingsIniData.Buf.Size, ImVec2(-FLT_MIN, GetTextLineHeight() * 20), ImGuiInputTextFlags_ReadOnly); | ||||||
|             ImGui::TreePop(); |             TreePop(); | ||||||
|         } |         } | ||||||
|         ImGui::TreePop(); |         TreePop(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // Misc Details |     // Misc Details | ||||||
|     if (ImGui::TreeNode("Internal state")) |     if (TreeNode("Internal state")) | ||||||
|     { |     { | ||||||
|         const char* input_source_names[] = { "None", "Mouse", "Nav", "NavKeyboard", "NavGamepad" }; IM_ASSERT(IM_ARRAYSIZE(input_source_names) == ImGuiInputSource_COUNT); |         const char* input_source_names[] = { "None", "Mouse", "Nav", "NavKeyboard", "NavGamepad" }; IM_ASSERT(IM_ARRAYSIZE(input_source_names) == ImGuiInputSource_COUNT); | ||||||
|  |  | ||||||
|         ImGui::Text("WINDOWING"); |         Text("WINDOWING"); | ||||||
|         ImGui::Indent(); |         Indent(); | ||||||
|         ImGui::Text("HoveredWindow: '%s'", g.HoveredWindow ? g.HoveredWindow->Name : "NULL"); |         Text("HoveredWindow: '%s'", g.HoveredWindow ? g.HoveredWindow->Name : "NULL"); | ||||||
|         ImGui::Text("HoveredRootWindow: '%s'", g.HoveredRootWindow ? g.HoveredRootWindow->Name : "NULL"); |         Text("HoveredRootWindow: '%s'", g.HoveredRootWindow ? g.HoveredRootWindow->Name : "NULL"); | ||||||
|         ImGui::Text("HoveredWindowUnderMovingWindow: '%s'", g.HoveredWindowUnderMovingWindow ? g.HoveredWindowUnderMovingWindow->Name : "NULL"); |         Text("HoveredWindowUnderMovingWindow: '%s'", g.HoveredWindowUnderMovingWindow ? g.HoveredWindowUnderMovingWindow->Name : "NULL"); | ||||||
|         ImGui::Text("MovingWindow: '%s'", g.MovingWindow ? g.MovingWindow->Name : "NULL"); |         Text("MovingWindow: '%s'", g.MovingWindow ? g.MovingWindow->Name : "NULL"); | ||||||
|         ImGui::Unindent(); |         Unindent(); | ||||||
|  |  | ||||||
|         ImGui::Text("ITEMS"); |         Text("ITEMS"); | ||||||
|         ImGui::Indent(); |         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]); |         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"); |         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 |         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); |         Text("DragDrop: %d, SourceId = 0x%08X, Payload \"%s\" (%d bytes)", g.DragDropActive, g.DragDropPayload.SourceId, g.DragDropPayload.DataType, g.DragDropPayload.DataSize); | ||||||
|         ImGui::Unindent(); |         Unindent(); | ||||||
|  |  | ||||||
|         ImGui::Text("NAV,FOCUS"); |         Text("NAV,FOCUS"); | ||||||
|         ImGui::Indent(); |         Indent(); | ||||||
|         ImGui::Text("NavWindow: '%s'", g.NavWindow ? g.NavWindow->Name : "NULL"); |         Text("NavWindow: '%s'", g.NavWindow ? g.NavWindow->Name : "NULL"); | ||||||
|         ImGui::Text("NavId: 0x%08X, NavLayer: %d", g.NavId, g.NavLayer); |         Text("NavId: 0x%08X, NavLayer: %d", g.NavId, g.NavLayer); | ||||||
|         ImGui::Text("NavInputSource: %s", input_source_names[g.NavInputSource]); |         Text("NavInputSource: %s", input_source_names[g.NavInputSource]); | ||||||
|         ImGui::Text("NavActive: %d, NavVisible: %d", g.IO.NavActive, g.IO.NavVisible); |         Text("NavActive: %d, NavVisible: %d", g.IO.NavActive, g.IO.NavVisible); | ||||||
|         ImGui::Text("NavActivateId: 0x%08X, NavInputId: 0x%08X", g.NavActivateId, g.NavInputId); |         Text("NavActivateId: 0x%08X, NavInputId: 0x%08X", g.NavActivateId, g.NavInputId); | ||||||
|         ImGui::Text("NavDisableHighlight: %d, NavDisableMouseHover: %d", g.NavDisableHighlight, g.NavDisableMouseHover); |         Text("NavDisableHighlight: %d, NavDisableMouseHover: %d", g.NavDisableHighlight, g.NavDisableMouseHover); | ||||||
|         ImGui::Text("NavFocusScopeId = 0x%08X", g.NavFocusScopeId); |         Text("NavFocusScopeId = 0x%08X", g.NavFocusScopeId); | ||||||
|         ImGui::Text("NavWindowingTarget: '%s'", g.NavWindowingTarget ? g.NavWindowingTarget->Name : "NULL"); |         Text("NavWindowingTarget: '%s'", g.NavWindowingTarget ? g.NavWindowingTarget->Name : "NULL"); | ||||||
|         ImGui::Unindent(); |         Unindent(); | ||||||
|  |  | ||||||
|         ImGui::TreePop(); |         TreePop(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // Overlay: Display windows Rectangles and Begin Order |     // Overlay: Display windows Rectangles and Begin Order | ||||||
|     if (show_windows_rects || show_windows_begin_order) |     if (cfg->ShowWindowsRects || cfg->ShowWindowsBeginOrder) | ||||||
|     { |     { | ||||||
|         for (int n = 0; n < g.Windows.Size; n++) |         for (int n = 0; n < g.Windows.Size; n++) | ||||||
|         { |         { | ||||||
| @@ -10824,16 +10577,16 @@ void ImGui::ShowMetricsWindow(bool* p_open) | |||||||
|             if (!window->WasActive) |             if (!window->WasActive) | ||||||
|                 continue; |                 continue; | ||||||
|             ImDrawList* draw_list = GetForegroundDrawList(window); |             ImDrawList* draw_list = GetForegroundDrawList(window); | ||||||
|             if (show_windows_rects) |             if (cfg->ShowWindowsRects) | ||||||
|             { |             { | ||||||
|                 ImRect r = Funcs::GetWindowRect(window, show_windows_rect_type); |                 ImRect r = Funcs::GetWindowRect(window, cfg->ShowWindowsRectsType); | ||||||
|                 draw_list->AddRect(r.Min, r.Max, IM_COL32(255, 0, 128, 255)); |                 draw_list->AddRect(r.Min, r.Max, IM_COL32(255, 0, 128, 255)); | ||||||
|             } |             } | ||||||
|             if (show_windows_begin_order && !(window->Flags & ImGuiWindowFlags_ChildWindow)) |             if (cfg->ShowWindowsBeginOrder && !(window->Flags & ImGuiWindowFlags_ChildWindow)) | ||||||
|             { |             { | ||||||
|                 char buf[32]; |                 char buf[32]; | ||||||
|                 ImFormatString(buf, IM_ARRAYSIZE(buf), "%d", window->BeginOrderWithinContext); |                 ImFormatString(buf, IM_ARRAYSIZE(buf), "%d", window->BeginOrderWithinContext); | ||||||
|                 float font_size = ImGui::GetFontSize(); |                 float font_size = GetFontSize(); | ||||||
|                 draw_list->AddRectFilled(window->Pos, window->Pos + ImVec2(font_size, font_size), IM_COL32(200, 100, 100, 255)); |                 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); |                 draw_list->AddText(window->Pos, IM_COL32(255, 255, 255, 255), buf); | ||||||
|             } |             } | ||||||
| @@ -10861,9 +10614,273 @@ void ImGui::ShowMetricsWindow(bool* p_open) | |||||||
|     ImGui::End(); |     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; | ||||||
|  |     if (cmd_count > 0 && draw_list->CmdBuffer.back().ElemCount == 0 && draw_list->CmdBuffer.back().UserCallback == NULL) | ||||||
|  |         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 == GetWindowDrawList()) | ||||||
|  |     { | ||||||
|  |         SameLine(); | ||||||
|  |         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) | ||||||
|  |             TreePop(); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     ImDrawList* fg_draw_list = GetForegroundDrawList(window); // Render additional visuals into the top-most draw list | ||||||
|  |     if (window && IsItemHovered()) | ||||||
|  |         fg_draw_list->AddRect(window->Pos, window->Pos + window->Size, IM_COL32(255, 255, 0, 255)); | ||||||
|  |     if (!node_open) | ||||||
|  |         return; | ||||||
|  |  | ||||||
|  |     if (window && !window->WasActive) | ||||||
|  |         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++) | ||||||
|  |     { | ||||||
|  |         if (pcmd->UserCallback) | ||||||
|  |         { | ||||||
|  |             BulletText("Callback %p, user_data %p", pcmd->UserCallback, pcmd->UserCallbackData); | ||||||
|  |             continue; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         char buf[300]; | ||||||
|  |         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->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z, pcmd->ClipRect.w); | ||||||
|  |         bool pcmd_node_open = TreeNode((void*)(pcmd - draw_list->CmdBuffer.begin()), "%s", buf); | ||||||
|  |         if (IsItemHovered() && (cfg->ShowDrawCmdMesh || cfg->ShowDrawCmdBoundingBoxes) && fg_draw_list) | ||||||
|  |             DebugNodeDrawCmdShowMeshAndBoundingBox(window, draw_list, pcmd, cfg->ShowDrawCmdMesh, cfg->ShowDrawCmdBoundingBoxes); | ||||||
|  |         if (!pcmd_node_open) | ||||||
|  |             continue; | ||||||
|  |  | ||||||
|  |         // Calculate approximate coverage area (touched pixel count) | ||||||
|  |         // This will be in pixels squared as long there's no post-scaling happening to the renderer output. | ||||||
|  |         const ImDrawIdx* idx_buffer = (draw_list->IdxBuffer.Size > 0) ? draw_list->IdxBuffer.Data : NULL; | ||||||
|  |         const ImDrawVert* vtx_buffer = draw_list->VtxBuffer.Data + pcmd->VtxOffset; | ||||||
|  |         float total_area = 0.0f; | ||||||
|  |         for (unsigned int idx_n = pcmd->IdxOffset; idx_n < pcmd->IdxOffset + pcmd->ElemCount; ) | ||||||
|  |         { | ||||||
|  |             ImVec2 triangle[3]; | ||||||
|  |             for (int n = 0; n < 3; n++, idx_n++) | ||||||
|  |                 triangle[n] = vtx_buffer[idx_buffer ? idx_buffer[idx_n] : idx_n].pos; | ||||||
|  |             total_area += ImTriangleArea(triangle[0], triangle[1], triangle[2]); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // 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); | ||||||
|  |         Selectable(buf); | ||||||
|  |         if (IsItemHovered() && fg_draw_list) | ||||||
|  |             DebugNodeDrawCmdShowMeshAndBoundingBox(window, draw_list, pcmd, true, false); | ||||||
|  |  | ||||||
|  |         // Display individual triangles/vertices. Hover on to get the corresponding triangle highlighted. | ||||||
|  |         ImGuiListClipper clipper; | ||||||
|  |         clipper.Begin(pcmd->ElemCount / 3); // Manually coarse clip our print out of individual vertices to save CPU, only items that may be visible. | ||||||
|  |         while (clipper.Step()) | ||||||
|  |             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); | ||||||
|  |                 ImVec2 triangle[3]; | ||||||
|  |                 for (int n = 0; n < 3; n++, idx_i++) | ||||||
|  |                 { | ||||||
|  |                     const ImDrawVert& v = vtx_buffer[idx_buffer ? idx_buffer[idx_i] : idx_i]; | ||||||
|  |                     triangle[n] = v.pos; | ||||||
|  |                     buf_p += ImFormatString(buf_p, buf_end - buf_p, "%s %04d: pos (%8.2f,%8.2f), uv (%.6f,%.6f), col %08X\n", | ||||||
|  |                         (n == 0) ? "Vert:" : "     ", idx_i, v.pos.x, v.pos.y, v.uv.x, v.uv.y, v.col); | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 Selectable(buf, false); | ||||||
|  |                 if (fg_draw_list && IsItemHovered()) | ||||||
|  |                 { | ||||||
|  |                     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->AddPolyline(triangle, 3, IM_COL32(255, 255, 0, 255), true, 1.0f); | ||||||
|  |                     fg_draw_list->Flags = backup_flags; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         TreePop(); | ||||||
|  |     } | ||||||
|  |     TreePop(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // [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) | ||||||
|  | { | ||||||
|  |     IM_ASSERT(show_mesh || show_aabb); | ||||||
|  |     ImDrawList* fg_draw_list = GetForegroundDrawList(window); // Render additional visuals into the top-most draw list | ||||||
|  |     ImDrawIdx* idx_buffer = (draw_list->IdxBuffer.Size > 0) ? draw_list->IdxBuffer.Data : NULL; | ||||||
|  |     ImDrawVert* vtx_buffer = draw_list->VtxBuffer.Data + draw_cmd->VtxOffset; | ||||||
|  |  | ||||||
|  |     // Draw wire-frame version of all triangles | ||||||
|  |     ImRect clip_rect = draw_cmd->ClipRect; | ||||||
|  |     ImRect vtxs_rect(FLT_MAX, FLT_MAX, -FLT_MAX, -FLT_MAX); | ||||||
|  |     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. | ||||||
|  |     for (unsigned int idx_n = draw_cmd->IdxOffset; idx_n < draw_cmd->IdxOffset + draw_cmd->ElemCount; ) | ||||||
|  |     { | ||||||
|  |         ImVec2 triangle[3]; | ||||||
|  |         for (int n = 0; n < 3; n++, idx_n++) | ||||||
|  |             vtxs_rect.Add((triangle[n] = vtx_buffer[idx_buffer ? idx_buffer[idx_n] : idx_n].pos)); | ||||||
|  |         if (show_mesh) | ||||||
|  |             fg_draw_list->AddPolyline(triangle, 3, IM_COL32(255, 255, 0, 255), true, 1.0f); // In yellow: mesh triangles | ||||||
|  |     } | ||||||
|  |     // Draw bounding boxes | ||||||
|  |     if (show_aabb) | ||||||
|  |     { | ||||||
|  |         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 | ||||||
|  |         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; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // [DEBUG] Display contents of ImGuiStorage | ||||||
|  | void ImGui::DebugNodeStorage(ImGuiStorage* storage, const char* label) | ||||||
|  | { | ||||||
|  |     if (!TreeNode(label, "%s: %d entries, %d bytes", label, storage->Data.Size, storage->Data.size_in_bytes())) | ||||||
|  |         return; | ||||||
|  |     for (int n = 0; n < storage->Data.Size; n++) | ||||||
|  |     { | ||||||
|  |         const ImGuiStorage::ImGuiStoragePair& p = storage->Data[n]; | ||||||
|  |         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(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | // [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. | ||||||
|  |     char buf[256]; | ||||||
|  |     char* p = buf; | ||||||
|  |     const char* buf_end = buf + IM_ARRAYSIZE(buf); | ||||||
|  |     const bool is_active = (tab_bar->PrevFrameVisible >= GetFrameCount() - 2); | ||||||
|  |     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); | ||||||
|  |     if (!is_active) { PushStyleColor(ImGuiCol_Text, GetStyleColorVec4(ImGuiCol_TextDisabled)); } | ||||||
|  |     bool open = TreeNode(tab_bar, "%s", buf); | ||||||
|  |     if (!is_active) { PopStyleColor(); } | ||||||
|  |     if (is_active && IsItemHovered()) | ||||||
|  |     { | ||||||
|  |         ImDrawList* draw_list = GetForegroundDrawList(); | ||||||
|  |         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->ScrollingRectMaxX, tab_bar->BarRect.Min.y), ImVec2(tab_bar->ScrollingRectMaxX, tab_bar->BarRect.Max.y), IM_COL32(0, 255, 0, 255)); | ||||||
|  |     } | ||||||
|  |     if (open) | ||||||
|  |     { | ||||||
|  |         for (int tab_n = 0; tab_n < tab_bar->Tabs.Size; tab_n++) | ||||||
|  |         { | ||||||
|  |             const ImGuiTabItem* tab = &tab_bar->Tabs[tab_n]; | ||||||
|  |             PushID(tab); | ||||||
|  |             if (SmallButton("<")) { TabBarQueueReorder(tab_bar, tab, -1); } SameLine(0, 2); | ||||||
|  |             if (SmallButton(">")) { TabBarQueueReorder(tab_bar, tab, +1); } SameLine(); | ||||||
|  |             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); | ||||||
|  |             PopID(); | ||||||
|  |         } | ||||||
|  |         TreePop(); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void ImGui::DebugNodeWindow(ImGuiWindow* window, const char* label) | ||||||
|  | { | ||||||
|  |     if (window == NULL) | ||||||
|  |     { | ||||||
|  |         BulletText("%s: NULL", label); | ||||||
|  |         return; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     ImGuiContext& g = *GImGui; | ||||||
|  |     const bool is_active = window->WasActive; | ||||||
|  |     ImGuiTreeNodeFlags tree_node_flags = (window == g.NavWindow) ? ImGuiTreeNodeFlags_Selected : ImGuiTreeNodeFlags_None; | ||||||
|  |     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*"); | ||||||
|  |     if (!is_active) { PopStyleColor(); } | ||||||
|  |     if (IsItemHovered() && is_active) | ||||||
|  |         GetForegroundDrawList(window)->AddRect(window->Pos, window->Pos + window->Size, IM_COL32(255, 255, 0, 255)); | ||||||
|  |     if (!open) | ||||||
|  |         return; | ||||||
|  |  | ||||||
|  |     if (window->MemoryCompacted) | ||||||
|  |         TextDisabled("Note: some memory buffers have been compacted/freed."); | ||||||
|  |  | ||||||
|  |     ImGuiWindowFlags flags = window->Flags; | ||||||
|  |     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); | ||||||
|  |     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" : ""); | ||||||
|  |     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" : ""); | ||||||
|  |     BulletText("Active: %d/%d, WriteAccessed: %d, BeginOrderWithinContext: %d", window->Active, window->WasActive, window->WriteAccessed, (window->Active || window->WasActive) ? window->BeginOrderWithinContext : -1); | ||||||
|  |     BulletText("Appearing: %d, Hidden: %d (CanSkip %d Cannot %d), SkipItems: %d", window->Appearing, window->Hidden, window->HiddenFramesCanSkipItems, window->HiddenFramesCannotSkipItems, window->SkipItems); | ||||||
|  |     BulletText("NavLastIds: 0x%08X,0x%08X, NavLayerActiveMask: %X", window->NavLastIds[0], window->NavLastIds[1], window->DC.NavLayerActiveMask); | ||||||
|  |     BulletText("NavLastChildNavWindow: %s", window->NavLastChildNavWindow ? window->NavLastChildNavWindow->Name : "NULL"); | ||||||
|  |     if (!window->NavRectRel[0].IsInverted()) | ||||||
|  |         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 | ||||||
|  |         BulletText("NavRectRel[0]: <None>"); | ||||||
|  |     if (window->RootWindow != window)       { DebugNodeWindow(window->RootWindow, "RootWindow"); } | ||||||
|  |     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 < window->ColumnsStorage.Size; n++) | ||||||
|  |             DebugNodeColumns(&window->ColumnsStorage[n]); | ||||||
|  |         TreePop(); | ||||||
|  |     } | ||||||
|  |     DebugNodeStorage(&window->StateStorage, "Storage"); | ||||||
|  |     TreePop(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void ImGui::DebugNodeWindowSettings(ImGuiWindowSettings* settings) | ||||||
|  | { | ||||||
|  |     Text("0x%08X \"%s\" Pos (%d,%d) Size (%d,%d) Collapsed=%d", | ||||||
|  |         settings->ID, settings->GetName(), settings->Pos.x, settings->Pos.y, settings->Size.x, settings->Size.y, settings->Collapsed); | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | void ImGui::DebugNodeWindowsList(ImVector<ImGuiWindow*>* windows, const char* label) | ||||||
|  | { | ||||||
|  |     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(); | ||||||
|  |     } | ||||||
|  |     TreePop(); | ||||||
|  | } | ||||||
|  |  | ||||||
| #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 | ||||||
|  |  | ||||||
|   | |||||||
| @@ -101,6 +101,7 @@ struct ImGuiInputTextState;         // Internal state of the currently focused/e | |||||||
| struct ImGuiLastItemDataBackup;     // Backup and restore IsItemHovered() internal data | struct ImGuiLastItemDataBackup;     // Backup and restore IsItemHovered() internal data | ||||||
| struct ImGuiMenuColumns;            // Simple column measurement, currently used for MenuItem() only | struct ImGuiMenuColumns;            // Simple column measurement, currently used for MenuItem() only | ||||||
| struct ImGuiNavMoveResult;          // Result of a gamepad/keyboard directional navigation move query result | struct ImGuiNavMoveResult;          // Result of a gamepad/keyboard directional navigation move query result | ||||||
|  | struct ImGuiMetricsConfig;          // Storage for ShowMetricsWindow() and DebugNodeXXX() functions | ||||||
| struct ImGuiNextWindowData;         // Storage for SetNextWindow** functions | struct ImGuiNextWindowData;         // Storage for SetNextWindow** functions | ||||||
| struct ImGuiNextItemData;           // Storage for SetNextItem** functions | struct ImGuiNextItemData;           // Storage for SetNextItem** functions | ||||||
| struct ImGuiPopupData;              // Storage for current popup stack | struct ImGuiPopupData;              // Storage for current popup stack | ||||||
| @@ -1101,6 +1102,28 @@ struct ImGuiSettingsHandler | |||||||
|     ImGuiSettingsHandler() { memset(this, 0, sizeof(*this)); } |     ImGuiSettingsHandler() { memset(this, 0, sizeof(*this)); } | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | struct ImGuiMetricsConfig | ||||||
|  | { | ||||||
|  |     bool        ShowWindowsRects; | ||||||
|  |     bool        ShowWindowsBeginOrder; | ||||||
|  |     bool        ShowTablesRects; | ||||||
|  |     bool        ShowDrawCmdMesh; | ||||||
|  |     bool        ShowDrawCmdBoundingBoxes; | ||||||
|  |     int         ShowWindowsRectsType; | ||||||
|  |     int         ShowTablesRectsType; | ||||||
|  |  | ||||||
|  |     ImGuiMetricsConfig() | ||||||
|  |     { | ||||||
|  |         ShowWindowsRects = false; | ||||||
|  |         ShowWindowsBeginOrder = false; | ||||||
|  |         ShowTablesRects = false; | ||||||
|  |         ShowDrawCmdMesh = true; | ||||||
|  |         ShowDrawCmdBoundingBoxes = true; | ||||||
|  |         ShowWindowsRectsType = -1; | ||||||
|  |         ShowTablesRectsType = -1; | ||||||
|  |     } | ||||||
|  | }; | ||||||
|  |  | ||||||
| //----------------------------------------------------------------------------- | //----------------------------------------------------------------------------- | ||||||
| // [SECTION] Generic context hooks | // [SECTION] Generic context hooks | ||||||
| //----------------------------------------------------------------------------- | //----------------------------------------------------------------------------- | ||||||
| @@ -1336,6 +1359,7 @@ struct ImGuiContext | |||||||
|     // Debug Tools |     // Debug Tools | ||||||
|     bool                    DebugItemPickerActive;              // Item picker is active (started with DebugStartItemPicker()) |     bool                    DebugItemPickerActive;              // Item picker is active (started with DebugStartItemPicker()) | ||||||
|     ImGuiID                 DebugItemPickerBreakId;             // Will call IM_DEBUG_BREAK() when encountering this id |     ImGuiID                 DebugItemPickerBreakId;             // Will call IM_DEBUG_BREAK() when encountering this id | ||||||
|  |     ImGuiMetricsConfig      DebugMetricsConfig; | ||||||
|  |  | ||||||
|     // Misc |     // Misc | ||||||
|     float                   FramerateSecPerFrame[120];          // Calculate estimate of framerate for user over the last 2 seconds. |     float                   FramerateSecPerFrame[120];          // Calculate estimate of framerate for user over the last 2 seconds. | ||||||
| @@ -2070,6 +2094,15 @@ namespace ImGui | |||||||
|     inline void             DebugDrawItemRect(ImU32 col = IM_COL32(255,0,0,255))    { ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; GetForegroundDrawList(window)->AddRect(window->DC.LastItemRect.Min, window->DC.LastItemRect.Max, col); } |     inline void             DebugDrawItemRect(ImU32 col = IM_COL32(255,0,0,255))    { ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; GetForegroundDrawList(window)->AddRect(window->DC.LastItemRect.Min, window->DC.LastItemRect.Max, col); } | ||||||
|     inline void             DebugStartItemPicker()                                  { ImGuiContext& g = *GImGui; g.DebugItemPickerActive = true; } |     inline void             DebugStartItemPicker()                                  { ImGuiContext& g = *GImGui; g.DebugItemPickerActive = true; } | ||||||
|  |  | ||||||
|  |     IMGUI_API void          DebugNodeColumns(ImGuiColumns* columns); | ||||||
|  |     IMGUI_API void          DebugNodeDrawList(ImGuiWindow* window, const ImDrawList* draw_list, const char* label); | ||||||
|  |     IMGUI_API void          DebugNodeDrawCmdShowMeshAndBoundingBox(ImGuiWindow* window, const ImDrawList* draw_list, const ImDrawCmd* draw_cmd, bool show_mesh, bool show_aabb); | ||||||
|  |     IMGUI_API void          DebugNodeStorage(ImGuiStorage* storage, const char* label); | ||||||
|  |     IMGUI_API void          DebugNodeTabBar(ImGuiTabBar* tab_bar, const char* label); | ||||||
|  |     IMGUI_API void          DebugNodeWindow(ImGuiWindow* window, const char* label); | ||||||
|  |     IMGUI_API void          DebugNodeWindowSettings(ImGuiWindowSettings* settings); | ||||||
|  |     IMGUI_API void          DebugNodeWindowsList(ImVector<ImGuiWindow*>* windows, const char* label); | ||||||
|  |  | ||||||
| } // namespace ImGui | } // namespace ImGui | ||||||
|  |  | ||||||
| // ImFontAtlas internals | // ImFontAtlas internals | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user