tools: full Metrics/Debugger window (windows, drawlists, viewports, fonts, popups, tab bars, tables, docking, settings, inputs, internal state, rect overlays)
This commit is contained in:
@@ -575,4 +575,749 @@ function ImGui.ShowIDStackToolWindow(p_open)
|
||||
return p_open
|
||||
end
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- [SECTION] Metrics/Debugger window
|
||||
----------------------------------------------------------------
|
||||
|
||||
local function B(v) return v and 1 or 0 end
|
||||
local function FG(window) return ImGui.GetForegroundDrawList(window and window.Viewport or ImGui.GetMainViewport()) end
|
||||
local function YellowRect(window, min, max) FG(window):AddRect(min, max, IM_COL32(255, 255, 0, 255)) end
|
||||
|
||||
function ImGui.DebugNodeColumns(columns)
|
||||
if not ImGui.TreeNode(columns.ID, "Columns Id: 0x%08X, Count: %d, Flags: 0x%04X", columns.ID, columns.Count, columns.Flags) then return end
|
||||
ImGui.BulletText("Width: %.1f (MinX: %.1f, MaxX: %.1f)", columns.OffMaxX - columns.OffMinX, columns.OffMinX, columns.OffMaxX)
|
||||
for i, column in columns.Columns:iter() do
|
||||
ImGui.BulletText("Column %02d: OffsetNorm %.3f (= %.1f px)", i - 1, column.OffsetNorm, ImGui.GetColumnOffsetFromNorm(columns, column.OffsetNorm))
|
||||
end
|
||||
ImGui.TreePop()
|
||||
end
|
||||
|
||||
function ImGui.DebugNodeStorage(storage, label)
|
||||
local n = 0
|
||||
for _ in pairs(storage) do n = n + 1 end
|
||||
if not ImGui.TreeNode(label, "%s: %d entries", label, n) then return end
|
||||
for k, v in pairs(storage) do
|
||||
ImGui.BulletText("Key 0x%08X Value { %s }", tonumber(k) or 0, tostring(v))
|
||||
end
|
||||
ImGui.TreePop()
|
||||
end
|
||||
|
||||
function ImGui.DebugNodeDrawList(window, viewport, draw_list, label)
|
||||
local g = ImGui.GetCurrentContext()
|
||||
local cfg = g.DebugMetricsConfig
|
||||
local cmd_count = draw_list.CmdBuffer.Size
|
||||
if cmd_count > 0 and draw_list.CmdBuffer.Data[cmd_count].ElemCount == 0 and draw_list.CmdBuffer.Data[cmd_count].UserCallback == nil then
|
||||
cmd_count = cmd_count - 1
|
||||
end
|
||||
local node_open = ImGui.TreeNode(tostring(draw_list), "%s: '%s' %d vtx, %d indices, %d cmds", label, draw_list._OwnerName or "", draw_list.VtxBuffer.Size, draw_list.IdxBuffer.Size, cmd_count)
|
||||
if draw_list == ImGui.GetWindowDrawList() then
|
||||
ImGui.SameLine()
|
||||
ImGui.TextColored(ImVec4(1.0, 0.4, 0.4, 1.0), "CURRENTLY APPENDING")
|
||||
if node_open then ImGui.TreePop() end
|
||||
return
|
||||
end
|
||||
local fg_draw_list = viewport and ImGui.GetForegroundDrawList(viewport) or nil
|
||||
if window and ImGui.IsItemHovered() and fg_draw_list then
|
||||
fg_draw_list:AddRect(window.Pos, window.Pos + window.Size, IM_COL32(255, 255, 0, 255))
|
||||
end
|
||||
if not node_open then return end
|
||||
if window and not window.WasActive then ImGui.TextDisabled("Warning: owning Window is inactive. This DrawList is not being rendered!") end
|
||||
|
||||
local vtx, idx = draw_list.VtxBuffer.Data, draw_list.IdxBuffer.Data
|
||||
for cmd_n = 1, cmd_count do
|
||||
local pcmd = draw_list.CmdBuffer.Data[cmd_n]
|
||||
if pcmd.UserCallback then
|
||||
ImGui.BulletText("Callback %s", tostring(pcmd.UserCallback))
|
||||
else
|
||||
local cr = pcmd.ClipRect
|
||||
local open = ImGui.TreeNode(cmd_n, "DrawCmd:%5d tris, Tex %s, ClipRect (%4.0f,%4.0f)-(%4.0f,%4.0f)", math.floor(pcmd.ElemCount / 3), tostring(pcmd.TexRef and (pcmd.TexRef._TexID or pcmd.TexRef._TexData)), cr.x, cr.y, cr.z, cr.w)
|
||||
local function ShowMesh(show_mesh, show_aabb)
|
||||
if not fg_draw_list then return end
|
||||
local clip_rect = ImRect(cr.x, cr.y, cr.z, cr.w)
|
||||
local vtxs_rect = ImRect(FLT_MAX, FLT_MAX, -FLT_MAX, -FLT_MAX)
|
||||
local base = pcmd.IdxOffset
|
||||
for i = base, base + pcmd.ElemCount - 1, 3 do
|
||||
local tri = {}
|
||||
for n = 0, 2 do
|
||||
local v = vtx[idx[i + n + 1] + pcmd.VtxOffset + 1]
|
||||
if v == nil then return end
|
||||
tri[n + 1] = ImVec2(v.pos.x, v.pos.y)
|
||||
vtxs_rect:Add(tri[n + 1])
|
||||
end
|
||||
if show_mesh then fg_draw_list:AddPolyline(tri, 3, IM_COL32(255, 255, 0, 255), 1.0, ImDrawFlags.Closed) end
|
||||
end
|
||||
if show_aabb then
|
||||
fg_draw_list:AddRect(ImTrunc(clip_rect.Min), ImTrunc(clip_rect.Max), IM_COL32(255, 0, 255, 255))
|
||||
fg_draw_list:AddRect(ImTrunc(vtxs_rect.Min), ImTrunc(vtxs_rect.Max), IM_COL32(0, 255, 255, 255))
|
||||
end
|
||||
end
|
||||
if ImGui.IsItemHovered() and (cfg.ShowDrawCmdMesh or cfg.ShowDrawCmdBoundingBoxes) then ShowMesh(cfg.ShowDrawCmdMesh, cfg.ShowDrawCmdBoundingBoxes) end
|
||||
if open then
|
||||
ImGui.Selectable(string.format("Mesh: ElemCount: %d, VtxOffset: +%d, IdxOffset: +%d", pcmd.ElemCount, pcmd.VtxOffset, pcmd.IdxOffset))
|
||||
if ImGui.IsItemHovered() then ShowMesh(true, false) end
|
||||
ImGui.TreePop()
|
||||
end
|
||||
end
|
||||
end
|
||||
ImGui.TreePop()
|
||||
end
|
||||
|
||||
function ImGui.DebugNodeTabBar(tab_bar, label)
|
||||
local g = ImGui.GetCurrentContext()
|
||||
local is_active = (tab_bar.PrevFrameVisible >= ImGui.GetFrameCount() - 2)
|
||||
local names = {}
|
||||
for tab_n = 1, math.min(tab_bar.Tabs.Size, 3) do
|
||||
local tab = tab_bar.Tabs.Data[tab_n]
|
||||
names[#names + 1] = "'" .. (ImGui.TabBarGetTabName and ImGui.TabBarGetTabName(tab_bar, tab) or "?") .. "'"
|
||||
end
|
||||
local buf = string.format("%s 0x%08X (%d tabs)%s { %s%s", label, tab_bar.ID, tab_bar.Tabs.Size, is_active and "" or " *Inactive*", table.concat(names, ", "), (tab_bar.Tabs.Size > 3) and " ... }" or " } ")
|
||||
if not is_active then ImGui.PushStyleColor(ImGuiCol.Text, g.Style.Colors[ImGuiCol.TextDisabled]) end
|
||||
local open = ImGui.TreeNode(label, "%s", buf)
|
||||
if not is_active then ImGui.PopStyleColor() end
|
||||
if is_active and ImGui.IsItemHovered() then
|
||||
local dl = FG(tab_bar.Window)
|
||||
dl:AddRect(tab_bar.BarRect.Min, tab_bar.BarRect.Max, IM_COL32(255, 255, 0, 255))
|
||||
dl: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))
|
||||
dl: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))
|
||||
end
|
||||
if open then
|
||||
for tab_n, tab in tab_bar.Tabs:iter() do
|
||||
ImGui.PushID(tab_n)
|
||||
if ImGui.SmallButton("<") and ImGui.TabBarQueueReorder then ImGui.TabBarQueueReorder(tab_bar, tab, -1) end ImGui.SameLine(0, 2)
|
||||
if ImGui.SmallButton(">") and ImGui.TabBarQueueReorder then ImGui.TabBarQueueReorder(tab_bar, tab, 1) end ImGui.SameLine()
|
||||
ImGui.Text("%02d%s Tab 0x%08X '%s' Offset: %.2f, Width: %.2f/%.2f", tab_n - 1, (tab.ID == tab_bar.SelectedTabId) and "*" or " ", tab.ID,
|
||||
ImGui.TabBarGetTabName and ImGui.TabBarGetTabName(tab_bar, tab) or "?", tab.Offset, tab.Width, tab.ContentWidth)
|
||||
ImGui.PopID()
|
||||
end
|
||||
ImGui.TreePop()
|
||||
end
|
||||
end
|
||||
|
||||
local function SizingDesc(f)
|
||||
local TF = ImGuiTableFlags
|
||||
f = bit32.band(f, TF.SizingMask_)
|
||||
if f == TF.SizingFixedFit then return "FixedFit" elseif f == TF.SizingFixedSame then return "FixedSame"
|
||||
elseif f == TF.SizingStretchProp then return "StretchProp" elseif f == TF.SizingStretchSame then return "StretchSame" end
|
||||
return "N/A"
|
||||
end
|
||||
|
||||
function ImGui.DebugNodeTableSettings(settings, tbl)
|
||||
local open = ImGui.TreeNode(tostring(settings), "Settings 0x%08X (%d columns)", settings.ID, settings.ColumnsCount)
|
||||
local hovered = ImGui.IsItemHovered()
|
||||
if hovered and tbl == nil and settings.ID ~= 0 then tbl = ImGui.TableFindByID(settings.ID) end
|
||||
if hovered and tbl ~= nil then YellowRect(tbl.OuterWindow, tbl.OuterRect.Min, tbl.OuterRect.Max) end
|
||||
if open then
|
||||
ImGui.BulletText("SaveFlags: 0x%08X", settings.SaveFlags)
|
||||
ImGui.BulletText("ColumnsCount: %d (max %d)", settings.ColumnsCount, settings.ColumnsCountMax)
|
||||
for n = 0, settings.ColumnsCount - 1 do
|
||||
local c = settings.Columns[n]
|
||||
local dir = (c.SortOrder ~= -1) and c.SortDirection or ImGuiSortDirection.None
|
||||
ImGui.BulletText("Column %d Order %d SortOrder %2d %s Vis %d %s %7.3f ID 0x%08X", n, c.DisplayOrder, c.SortOrder,
|
||||
(dir == ImGuiSortDirection.Ascending) and "Asc" or ((dir == ImGuiSortDirection.Descending) and "Des" or "---"), c.IsEnabled, (c.IsStretch ~= 0) and "Weight" or "Width ", c.WidthOrWeight, c.ID)
|
||||
end
|
||||
ImGui.TreePop()
|
||||
end
|
||||
end
|
||||
|
||||
function ImGui.DebugNodeTable(tbl)
|
||||
local g = ImGui.GetCurrentContext()
|
||||
local is_active = (tbl.LastFrameActive >= g.FrameCount - 2)
|
||||
if not is_active then ImGui.PushStyleColor(ImGuiCol.Text, g.Style.Colors[ImGuiCol.TextDisabled]) end
|
||||
local open = ImGui.TreeNode(tostring(tbl), "Table 0x%08X (%d columns, in '%s')%s", tbl.ID, tbl.ColumnsCount, tbl.OuterWindow and tbl.OuterWindow.Name or "?", is_active and "" or " *Inactive*")
|
||||
if not is_active then ImGui.PopStyleColor() end
|
||||
if ImGui.IsItemHovered() then YellowRect(tbl.OuterWindow, tbl.OuterRect.Min, tbl.OuterRect.Max) end
|
||||
if not open then return end
|
||||
if tbl.InstanceCurrent > 0 then ImGui.Text("** %d instances of same table! Some data below will refer to last instance.", tbl.InstanceCurrent + 1) end
|
||||
local clear_settings = ImGui.SmallButton("Clear settings")
|
||||
ImGui.BulletText("OuterRect: Pos: (%.1f,%.1f) Size: (%.1f,%.1f) Sizing: '%s'", tbl.OuterRect.Min.x, tbl.OuterRect.Min.y, tbl.OuterRect:GetWidth(), tbl.OuterRect:GetHeight(), SizingDesc(tbl.Flags))
|
||||
ImGui.BulletText("ColumnsGivenWidth: %.1f, ColumnsAutoFitWidth: %.1f, InnerWidth: %.1f%s", tbl.ColumnsGivenWidth, tbl.ColumnsAutoFitWidth, tbl.InnerWidth, (tbl.InnerWidth == 0.0) and " (auto)" or "")
|
||||
ImGui.BulletText("CellPaddingX: %.1f, CellSpacingX: %.1f/%.1f, OuterPaddingX: %.1f", tbl.CellPaddingX, tbl.CellSpacingX1, tbl.CellSpacingX2, tbl.OuterPaddingX)
|
||||
ImGui.BulletText("HoveredColumnBody: %d, HoveredColumnBorder: %d", tbl.HoveredColumnBody, tbl.HoveredColumnBorder)
|
||||
ImGui.BulletText("ResizedColumn: %d, HeldHeaderColumn: %d, ReorderColumn: %d", tbl.LastResizedColumn, tbl.LastHeldHeaderColumn, tbl.ReorderColumn)
|
||||
for n = 0, tbl.InstanceCurrent do
|
||||
local inst = ImGui.TableGetInstanceData(tbl, n)
|
||||
ImGui.BulletText("Instance %d: HoveredRow: %d, LastOuterHeight: %.2f", n, inst.HoveredRowLast, inst.LastOuterHeight)
|
||||
end
|
||||
local sum_weights = 0.0
|
||||
for n = 0, tbl.ColumnsCount - 1 do
|
||||
if bit32.band(tbl.Columns[n].Flags, ImGuiTableColumnFlags.WidthStretch) ~= 0 then sum_weights = sum_weights + tbl.Columns[n].StretchWeight end
|
||||
end
|
||||
for n = 0, tbl.ColumnsCount - 1 do
|
||||
local c = tbl.Columns[n]
|
||||
local CF = ImGuiTableColumnFlags
|
||||
local buf = string.format(
|
||||
"Column %d order %d '%s': offset %+.2f to %+.2f%s\nEnabled: %d, VisibleX/Y: %d/%d, RequestOutput: %d, SkipItems: %d, DrawChannels: %d,%d\n" ..
|
||||
"WidthGiven: %.1f, Request/Auto: %.1f/%.1f, StretchWeight: %.3f (%.1f%%)\nMinX: %.1f, MaxX: %.1f (%+.1f), ClipRect: %.1f to %.1f (+%.1f)\n" ..
|
||||
"ContentWidth: %.1f,%.1f, HeadersUsed/Ideal %.1f/%.1f\nSort: %d%s, UserData: 0x%08X, Flags: 0x%04X: %s%s%s..",
|
||||
n, c.DisplayOrder, ImGui.TableGetColumnName(tbl, n) or "", c.MinX - tbl.WorkRect.Min.x, c.MaxX - tbl.WorkRect.Min.x, (n < tbl.FreezeColumnsRequest) and " (Frozen)" or "",
|
||||
B(c.IsEnabled), B(c.IsVisibleX), B(c.IsVisibleY), B(c.IsRequestOutput), B(c.IsSkipItems), c.DrawChannelFrozen, c.DrawChannelUnfrozen,
|
||||
c.WidthGiven, c.WidthRequest, c.WidthAuto, c.StretchWeight, (c.StretchWeight > 0.0 and sum_weights > 0) and (c.StretchWeight / sum_weights) * 100.0 or 0.0,
|
||||
c.MinX, c.MaxX, c.MaxX - c.MinX, c.ClipRect.Min.x, c.ClipRect.Max.x, c.ClipRect.Max.x - c.ClipRect.Min.x,
|
||||
c.ContentMaxXFrozen - c.WorkMinX, c.ContentMaxXUnfrozen - c.WorkMinX, c.ContentMaxXHeadersUsed - c.WorkMinX, c.ContentMaxXHeadersIdeal - c.WorkMinX,
|
||||
c.SortOrder, (c.SortDirection == ImGuiSortDirection.Ascending) and " (Asc)" or ((c.SortDirection == ImGuiSortDirection.Descending) and " (Des)" or ""), tonumber(c.UserData) or 0, c.Flags,
|
||||
(bit32.band(c.Flags, CF.WidthStretch) ~= 0) and "WidthStretch " or "", (bit32.band(c.Flags, CF.WidthFixed) ~= 0) and "WidthFixed " or "", (bit32.band(c.Flags, CF.NoResize) ~= 0) and "NoResize " or "")
|
||||
ImGui.Bullet()
|
||||
ImGui.Selectable(buf)
|
||||
if ImGui.IsItemHovered() then YellowRect(tbl.OuterWindow, ImVec2(c.MinX, tbl.OuterRect.Min.y), ImVec2(c.MaxX, tbl.OuterRect.Max.y)) end
|
||||
end
|
||||
local settings = ImGui.TableGetBoundSettings(tbl)
|
||||
if settings then ImGui.DebugNodeTableSettings(settings, tbl) end
|
||||
if clear_settings then tbl.IsResetAllRequest = true end
|
||||
ImGui.TreePop()
|
||||
end
|
||||
|
||||
local function DebugNodeDockNodeFlags(flags, label, enabled)
|
||||
local D = ImGuiDockNodeFlags
|
||||
ImGui.PushID(label)
|
||||
ImGui.PushStyleVar(ImGuiStyleVar.FramePadding, ImVec2(0.0, 0.0))
|
||||
ImGui.Text("%s:", label)
|
||||
if not enabled then ImGui.BeginDisabled() end
|
||||
for _, n in ipairs({ "NoResize", "NoResizeX", "NoResizeY", "NoTabBar", "HiddenTabBar", "NoWindowMenuButton", "NoCloseButton", "DockedWindowsInFocusRoute",
|
||||
"NoDocking", "NoDockingSplit", "NoDockingSplitOther", "NoDockingOverMe", "NoDockingOverOther", "NoDockingOverEmpty", "NoUndocking" }) do
|
||||
if D[n] then _, flags = ImGui.CheckboxFlags(n, flags, D[n]) end
|
||||
end
|
||||
if not enabled then ImGui.EndDisabled() end
|
||||
ImGui.PopStyleVar()
|
||||
ImGui.PopID()
|
||||
return flags
|
||||
end
|
||||
|
||||
function ImGui.DebugNodeDockNode(node, label)
|
||||
local g = ImGui.GetCurrentContext()
|
||||
local is_alive = (g.FrameCount - node.LastFrameAlive < 2)
|
||||
local is_active = (g.FrameCount - node.LastFrameActive < 2)
|
||||
if not is_alive then ImGui.PushStyleColor(ImGuiCol.Text, g.Style.Colors[ImGuiCol.TextDisabled]) end
|
||||
local tree_node_flags = node.IsFocused and ImGuiTreeNodeFlags.Selected or ImGuiTreeNodeFlags.None
|
||||
local open
|
||||
if node.Windows.Size > 0 then
|
||||
open = ImGui.TreeNodeEx(node.ID, tree_node_flags, "%s 0x%04X%s: %d windows (vis: '%s')", label, node.ID, node.IsVisible and "" or " (hidden)", node.Windows.Size, node.VisibleWindow and node.VisibleWindow.Name or "NULL")
|
||||
else
|
||||
local kind = (node.SplitAxis == ImGuiAxis.X) and "horizontal split" or ((node.SplitAxis == ImGuiAxis.Y) and "vertical split" or "empty")
|
||||
open = ImGui.TreeNodeEx(node.ID, tree_node_flags, "%s 0x%04X%s: %s (vis: '%s')", label, node.ID, node.IsVisible and "" or " (hidden)", kind, node.VisibleWindow and node.VisibleWindow.Name or "NULL")
|
||||
end
|
||||
if not is_alive then ImGui.PopStyleColor() end
|
||||
if is_active and ImGui.IsItemHovered() then
|
||||
local window = node.HostWindow or node.VisibleWindow
|
||||
if window then YellowRect(window, node.Pos, node.Pos + node.Size) end
|
||||
end
|
||||
if open then
|
||||
ImGui.BulletText("Pos (%.0f,%.0f), Size (%.0f, %.0f) Ref (%.0f, %.0f)", node.Pos.x, node.Pos.y, node.Size.x, node.Size.y, node.SizeRef.x, node.SizeRef.y)
|
||||
ImGui.DebugNodeWindow(node.HostWindow, "HostWindow")
|
||||
ImGui.DebugNodeWindow(node.VisibleWindow, "VisibleWindow")
|
||||
ImGui.BulletText("SelectedTabID: 0x%08X, LastFocusedNodeID: 0x%08X", node.SelectedTabId, node.LastFocusedNodeId)
|
||||
ImGui.BulletText("Misc:%s%s%s%s%s%s%s", node:IsDockSpace() and " IsDockSpace" or "", node:IsCentralNode() and " IsCentralNode" or "",
|
||||
is_alive and " IsAlive" or "", is_active and " IsActive" or "", node.IsFocused and " IsFocused" or "", node.WantLockSizeOnce and " WantLockSizeOnce" or "", node.HasCentralNodeChild and " HasCentralNodeChild" or "")
|
||||
if ImGui.TreeNode("flags", "Flags Merged: 0x%04X, Local: 0x%04X, InWindows: 0x%04X, Shared: 0x%04X", node.MergedFlags, node.LocalFlags, node.LocalFlagsInWindows, node.SharedFlags) then
|
||||
if ImGui.BeginTable("flags", 4) then
|
||||
ImGui.TableNextColumn(); DebugNodeDockNodeFlags(node.MergedFlags, "MergedFlags", false)
|
||||
ImGui.TableNextColumn(); node.LocalFlags = DebugNodeDockNodeFlags(node.LocalFlags, "LocalFlags", true)
|
||||
ImGui.TableNextColumn(); DebugNodeDockNodeFlags(node.LocalFlagsInWindows, "LocalFlagsInWindows", false)
|
||||
ImGui.TableNextColumn(); node.SharedFlags = DebugNodeDockNodeFlags(node.SharedFlags, "SharedFlags", true)
|
||||
ImGui.EndTable()
|
||||
end
|
||||
ImGui.TreePop()
|
||||
end
|
||||
if node.ParentNode then ImGui.DebugNodeDockNode(node.ParentNode, "ParentNode") end
|
||||
if node.ChildNodes[0] then ImGui.DebugNodeDockNode(node.ChildNodes[0], "Child[0]") end
|
||||
if node.ChildNodes[1] then ImGui.DebugNodeDockNode(node.ChildNodes[1], "Child[1]") end
|
||||
if node.TabBar then ImGui.DebugNodeTabBar(node.TabBar, "TabBar") end
|
||||
ImGui.DebugNodeWindowsList(node.Windows, "Windows")
|
||||
ImGui.TreePop()
|
||||
end
|
||||
end
|
||||
|
||||
function ImGui.DebugNodeWindow(window, label)
|
||||
if window == nil then
|
||||
ImGui.BulletText("%s: NULL", label)
|
||||
return
|
||||
end
|
||||
local g = ImGui.GetCurrentContext()
|
||||
local is_active = window.WasActive
|
||||
local tree_node_flags = (window == g.NavWindow) and ImGuiTreeNodeFlags.Selected or ImGuiTreeNodeFlags.None
|
||||
if not is_active then ImGui.PushStyleColor(ImGuiCol.Text, g.Style.Colors[ImGuiCol.TextDisabled]) end
|
||||
local open = ImGui.TreeNodeEx(label, tree_node_flags, "%s '%s'%s", label, window.Name, is_active and "" or " *Inactive*")
|
||||
if not is_active then ImGui.PopStyleColor() end
|
||||
if ImGui.IsItemHovered() and is_active then YellowRect(window, window.Pos, window.Pos + window.Size) end
|
||||
if not open then return end
|
||||
if window.MemoryCompacted then ImGui.TextDisabled("Note: some memory buffers have been compacted/freed.") end
|
||||
local W = ImGuiWindowFlags
|
||||
local flags = window.Flags
|
||||
local function F(f, s) return (bit32.band(flags, f) ~= 0) and s or "" end
|
||||
ImGui.DebugNodeDrawList(window, window.Viewport, window.DrawList, "DrawList")
|
||||
ImGui.BulletText("Pos: (%.1f,%.1f), Size: (%.1f,%.1f), ContentSize (%.1f,%.1f) Ideal (%.1f,%.1f)", window.Pos.x, window.Pos.y, window.Size.x, window.Size.y, window.ContentSize.x, window.ContentSize.y, window.ContentSizeIdeal.x, window.ContentSizeIdeal.y)
|
||||
ImGui.BulletText("Flags: 0x%08X (%s%s%s%s%s%s%s%s%s..)", flags, F(W.ChildWindow, "Child "), F(W.Tooltip, "Tooltip "), F(W.Popup, "Popup "), F(W.Modal, "Modal "), F(W.ChildMenu, "ChildMenu "),
|
||||
F(W.NoSavedSettings, "NoSavedSettings "), F(W.NoMouseInputs, "NoMouseInputs"), F(W.NoNavInputs, "NoNavInputs"), F(W.AlwaysAutoResize, "AlwaysAutoResize"))
|
||||
if bit32.band(flags, W.ChildWindow) ~= 0 then
|
||||
local cf = window.ChildFlags or 0
|
||||
local C = ImGuiChildFlags
|
||||
ImGui.BulletText("ChildFlags: 0x%08X (%s%s%s%s..)", cf, (bit32.band(cf, C.Borders) ~= 0) and "Borders " or "", (bit32.band(cf, C.ResizeX) ~= 0) and "ResizeX " or "",
|
||||
(bit32.band(cf, C.ResizeY) ~= 0) and "ResizeY " or "", (bit32.band(cf, C.NavFlattened) ~= 0) and "NavFlattened " or "")
|
||||
end
|
||||
ImGui.BulletText("WindowClassId: 0x%08X", window.WindowClass and window.WindowClass.ClassId or 0)
|
||||
ImGui.BulletText("Scroll: (%.2f/%.2f,%.2f/%.2f) Scrollbar:%s%s", window.Scroll.x, window.ScrollMax.x, window.Scroll.y, window.ScrollMax.y, window.ScrollbarX and "X" or "", window.ScrollbarY and "Y" or "")
|
||||
ImGui.BulletText("Active: %d/%d, WriteAccessed: %d, BeginOrderWithinContext: %d", B(window.Active), B(window.WasActive), B(window.WriteAccessed), (window.Active or window.WasActive) and window.BeginOrderWithinContext or -1)
|
||||
ImGui.BulletText("Appearing: %d, Hidden: %d (CanSkip %d Cannot %d), SkipItems: %d", B(window.Appearing), B(window.Hidden), window.HiddenFramesCanSkipItems, window.HiddenFramesCannotSkipItems, B(window.SkipItems))
|
||||
for layer = 0, 1 do
|
||||
local r = window.NavRectRel[layer]
|
||||
if r.Min.x >= r.Max.x and r.Min.y >= r.Max.y then
|
||||
ImGui.BulletText("NavLastIds[%d]: 0x%08X", layer, window.NavLastIds[layer])
|
||||
else
|
||||
ImGui.BulletText("NavLastIds[%d]: 0x%08X at +(%.1f,%.1f)(%.1f,%.1f)", layer, window.NavLastIds[layer], r.Min.x, r.Min.y, r.Max.x, r.Max.y)
|
||||
end
|
||||
end
|
||||
ImGui.BulletText("NavLayersActiveMask: %X, NavLastChildNavWindow: %s", window.DC.NavLayersActiveMask, window.NavLastChildNavWindow and window.NavLastChildNavWindow.Name or "NULL")
|
||||
ImGui.BulletText("Viewport: %d%s, ViewportId: 0x%08X, ViewportPos: (%.1f,%.1f)", window.Viewport and (window.Viewport.Idx or 0) or -1, window.ViewportOwned and " (Owned)" or "", window.ViewportId or 0, window.ViewportPos.x, window.ViewportPos.y)
|
||||
ImGui.BulletText("DockId: 0x%04X, DockOrder: %d, Act: %d, Vis: %d", window.DockId or 0, window.DockOrder or -1, B(window.DockIsActive), B(window.DockTabIsVisible))
|
||||
if window.DockNode or window.DockNodeAsHost then
|
||||
ImGui.DebugNodeDockNode(window.DockNodeAsHost or window.DockNode, window.DockNodeAsHost and "DockNodeAsHost" or "DockNode")
|
||||
end
|
||||
if window.RootWindow ~= window then ImGui.DebugNodeWindow(window.RootWindow, "RootWindow") end
|
||||
if window.RootWindowDockTree and window.RootWindowDockTree ~= window.RootWindow then ImGui.DebugNodeWindow(window.RootWindowDockTree, "RootWindowDockTree") end
|
||||
if window.ParentWindow ~= nil then ImGui.DebugNodeWindow(window.ParentWindow, "ParentWindow") end
|
||||
if window.ParentWindowForFocusRoute ~= nil then ImGui.DebugNodeWindow(window.ParentWindowForFocusRoute, "ParentWindowForFocusRoute") end
|
||||
if window.DC.ChildWindows.Size > 0 then ImGui.DebugNodeWindowsList(window.DC.ChildWindows, "ChildWindows") end
|
||||
if window.ColumnsStorage.Size > 0 and ImGui.TreeNode("Columns", "Columns sets (%d)", window.ColumnsStorage.Size) then
|
||||
for _, columns in window.ColumnsStorage:iter() do ImGui.DebugNodeColumns(columns) end
|
||||
ImGui.TreePop()
|
||||
end
|
||||
ImGui.DebugNodeStorage(window.StateStorage, "Storage")
|
||||
ImGui.TreePop()
|
||||
end
|
||||
|
||||
function ImGui.DebugNodeWindowSettings(settings)
|
||||
if settings.WantDelete then ImGui.BeginDisabled() end
|
||||
ImGui.BulletText("0x%08X \"%s\" Pos (%d,%d) Size (%d,%d) Collapsed=%d", settings.ID, settings.Name or "", settings.Pos.x, settings.Pos.y, settings.Size.x, settings.Size.y, B(settings.Collapsed))
|
||||
if settings.WantDelete then ImGui.EndDisabled() end
|
||||
end
|
||||
|
||||
function ImGui.DebugNodeWindowsList(windows, label)
|
||||
if not ImGui.TreeNode(label, "%s (%d)", label, windows.Size) then return end
|
||||
for i = windows.Size, 1, -1 do
|
||||
ImGui.PushID(tostring(windows.Data[i]))
|
||||
ImGui.DebugNodeWindow(windows.Data[i], "Window")
|
||||
ImGui.PopID()
|
||||
end
|
||||
ImGui.TreePop()
|
||||
end
|
||||
|
||||
function ImGui.DebugNodeWindowsListByBeginStackParent(windows, first, last, parent_in_begin_stack)
|
||||
for i = first, last do
|
||||
local window = windows[i]
|
||||
if window.ParentWindowInBeginStack == parent_in_begin_stack then
|
||||
local buf = string.format("[%04d] Window", window.BeginOrderWithinContext)
|
||||
ImGui.DebugNodeWindow(window, buf)
|
||||
ImGui.TreePush(buf)
|
||||
ImGui.DebugNodeWindowsListByBeginStackParent(windows, i + 1, last, window)
|
||||
ImGui.TreePop()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function ImGui.DebugNodeViewport(viewport)
|
||||
local g = ImGui.GetCurrentContext()
|
||||
ImGui.SetNextItemOpen(true, ImGuiCond.Once)
|
||||
local open = ImGui.TreeNode(viewport.ID, "Viewport #%d, ID: 0x%08X, Parent: 0x%08X, Window: \"%s\"", viewport.Idx or 0, viewport.ID, viewport.ParentViewportId or 0, viewport.Window and viewport.Window.Name or "N/A")
|
||||
if ImGui.IsItemHovered() then g.DebugMetricsConfig.HighlightViewportID = viewport.ID end
|
||||
if open then
|
||||
ImGui.BulletText("Main Pos: (%.0f,%.0f), Size: (%.0f,%.0f)\nFrameBufferScale: (%.2f,%.2f)\nWorkArea Inset Left: %.0f Top: %.0f, Right: %.0f, Bottom: %.0f\nMonitor: %d, DpiScale: %.0f%%",
|
||||
viewport.Pos.x, viewport.Pos.y, viewport.Size.x, viewport.Size.y, viewport.FramebufferScale and viewport.FramebufferScale.x or 1, viewport.FramebufferScale and viewport.FramebufferScale.y or 1,
|
||||
viewport.WorkInsetMin.x, viewport.WorkInsetMin.y, viewport.WorkInsetMax.x, viewport.WorkInsetMax.y, viewport.PlatformMonitor or 0, (viewport.DpiScale or 1) * 100.0)
|
||||
ImGui.BulletText("Flags: 0x%04X", viewport.Flags or 0)
|
||||
if viewport.DrawDataP then
|
||||
for _, draw_list in viewport.DrawDataP.CmdLists:iter() do ImGui.DebugNodeDrawList(nil, viewport, draw_list, "DrawList") end
|
||||
end
|
||||
ImGui.TreePop()
|
||||
end
|
||||
end
|
||||
|
||||
function ImGui.DebugTextEncoding(str)
|
||||
ImGui.Text("Text: \"%s\"", str)
|
||||
if not ImGui.BeginTable("##DebugTextEncoding", 4, bit32.bor(ImGuiTableFlags.Borders, ImGuiTableFlags.RowBg, ImGuiTableFlags.SizingFixedFit, ImGuiTableFlags.Resizable)) then return end
|
||||
ImGui.TableSetupColumn("Offset")
|
||||
ImGui.TableSetupColumn("UTF-8")
|
||||
ImGui.TableSetupColumn("Glyph")
|
||||
ImGui.TableSetupColumn("Codepoint")
|
||||
ImGui.TableHeadersRow()
|
||||
for pos, c in utf8.codes(str) do
|
||||
local nxt = utf8.offset(str, 2, pos) or (#str + 1)
|
||||
ImGui.TableNextColumn()
|
||||
ImGui.Text("%d", pos - 1)
|
||||
ImGui.TableNextColumn()
|
||||
for b = pos, nxt - 1 do
|
||||
if b > pos then ImGui.SameLine() end
|
||||
ImGui.Text("0x%02X", string.byte(str, b))
|
||||
end
|
||||
ImGui.TableNextColumn()
|
||||
ImGui.TextUnformatted(string.sub(str, pos, nxt - 1))
|
||||
ImGui.TableNextColumn()
|
||||
ImGui.Text("U+%04X", c)
|
||||
end
|
||||
ImGui.EndTable()
|
||||
end
|
||||
|
||||
local WRT_Names = { "OuterRect", "OuterRectClipped", "InnerRect", "InnerClipRect", "WorkRect", "Content", "ContentIdeal", "ContentRegionRect" }
|
||||
local TRT_Names = { "OuterRect", "InnerRect", "WorkRect", "HostClipRect", "InnerClipRect", "BackgroundClipRect", "ColumnsRect", "ColumnsWorkRect", "ColumnsClipRect",
|
||||
"ColumnsContentHeadersUsed", "ColumnsContentHeadersIdeal", "ColumnsContentFrozen", "ColumnsContentUnfrozen" }
|
||||
local TRT_ColumnsRect = 6
|
||||
|
||||
local function GetWindowRect(window, t)
|
||||
if t == 0 then return window:Rect()
|
||||
elseif t == 1 then return window.OuterRectClipped
|
||||
elseif t == 2 then return window.InnerRect
|
||||
elseif t == 3 then return window.InnerClipRect
|
||||
elseif t == 4 then return window.WorkRect
|
||||
elseif t == 5 then local m = window.InnerRect.Min - window.Scroll + window.WindowPadding; return ImRect(m, m + window.ContentSize)
|
||||
elseif t == 6 then local m = window.InnerRect.Min - window.Scroll + window.WindowPadding; return ImRect(m, m + window.ContentSizeIdeal)
|
||||
else return window.ContentRegionRect end
|
||||
end
|
||||
|
||||
local function GetTableRect(tbl, t, n)
|
||||
local inst = ImGui.TableGetInstanceData(tbl, tbl.InstanceCurrent)
|
||||
if t == 0 then return tbl.OuterRect elseif t == 1 then return tbl.InnerRect elseif t == 2 then return tbl.WorkRect
|
||||
elseif t == 3 then return tbl.HostClipRect elseif t == 4 then return tbl.InnerClipRect elseif t == 5 then return tbl.BgClipRect end
|
||||
local c = tbl.Columns[n]
|
||||
if t == 6 then return ImRect(c.MinX, tbl.InnerClipRect.Min.y, c.MaxX, tbl.InnerClipRect.Min.y + inst.LastOuterHeight)
|
||||
elseif t == 7 then return ImRect(c.WorkMinX, tbl.WorkRect.Min.y, c.WorkMaxX, tbl.WorkRect.Max.y)
|
||||
elseif t == 8 then return c.ClipRect
|
||||
elseif t == 9 then return ImRect(c.WorkMinX, tbl.InnerClipRect.Min.y, c.ContentMaxXHeadersUsed, tbl.InnerClipRect.Min.y + inst.LastTopHeadersRowHeight)
|
||||
elseif t == 10 then return ImRect(c.WorkMinX, tbl.InnerClipRect.Min.y, c.ContentMaxXHeadersIdeal, tbl.InnerClipRect.Min.y + inst.LastTopHeadersRowHeight)
|
||||
elseif t == 11 then return ImRect(c.WorkMinX, tbl.InnerClipRect.Min.y, c.ContentMaxXFrozen, tbl.InnerClipRect.Min.y + inst.LastFrozenHeight)
|
||||
else return ImRect(c.WorkMinX, tbl.InnerClipRect.Min.y + inst.LastFrozenHeight, c.ContentMaxXUnfrozen, tbl.InnerClipRect.Max.y) end
|
||||
end
|
||||
|
||||
local function ForEachTable(g, fn)
|
||||
for i = 0, g.Tables:GetMapSize() - 1 do
|
||||
local t = g.Tables:GetByIndex(i)
|
||||
if t then fn(t) end
|
||||
end
|
||||
end
|
||||
|
||||
local MetricsEncodingBuf = nil
|
||||
local MetricsDockRootOnly = true
|
||||
function ImGui.ShowMetricsWindow(p_open)
|
||||
local g = ImGui.GetCurrentContext()
|
||||
local io = g.IO
|
||||
local cfg = g.DebugMetricsConfig
|
||||
if cfg.ShowDebugLog then cfg.ShowDebugLog = ImGui.ShowDebugLogWindow(cfg.ShowDebugLog) end
|
||||
if cfg.ShowIDStackTool then cfg.ShowIDStackTool = ImGui.ShowIDStackToolWindow(cfg.ShowIDStackTool) end
|
||||
|
||||
local visible
|
||||
p_open, visible = ImGui.Begin("ImGui Sincerely Metrics/Debugger", p_open)
|
||||
if not visible or ImGui.GetCurrentWindow().BeginCount > 1 then
|
||||
ImGui.End()
|
||||
return p_open
|
||||
end
|
||||
|
||||
ImGui.Text("Dear ImGui %s (%d)", IMGUI_VERSION, IMGUI_VERSION_NUM)
|
||||
ImGui.Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0 / math.max(io.Framerate, 0.0001), io.Framerate)
|
||||
ImGui.Text("%d vertices, %d indices (%d triangles)", io.MetricsRenderVertices, io.MetricsRenderIndices, math.floor(io.MetricsRenderIndices / 3))
|
||||
ImGui.Text("%d visible windows, %d current allocations", io.MetricsRenderWindows, g.DebugAllocInfo.TotalAllocCount - g.DebugAllocInfo.TotalFreeCount)
|
||||
ImGui.Separator()
|
||||
|
||||
if cfg.ShowWindowsRectsType == nil or cfg.ShowWindowsRectsType < 0 then cfg.ShowWindowsRectsType = 4 end
|
||||
if cfg.ShowTablesRectsType == nil or cfg.ShowTablesRectsType < 0 then cfg.ShowTablesRectsType = 2 end
|
||||
|
||||
-- Tools
|
||||
if ImGui.TreeNode("Tools") then
|
||||
ImGui.SeparatorText("Visualize")
|
||||
_, cfg.ShowDebugLog = ImGui.Checkbox("Show Debug Log", cfg.ShowDebugLog == true)
|
||||
ImGui.SameLine(); MetricsHelpMarker("You can also call ImGui::ShowDebugLogWindow() from your code.")
|
||||
_, cfg.ShowIDStackTool = ImGui.Checkbox("Show ID Stack Tool", cfg.ShowIDStackTool == true)
|
||||
ImGui.SameLine(); MetricsHelpMarker("You can also call ImGui::ShowIDStackToolWindow() from your code.")
|
||||
_, cfg.ShowWindowsBeginOrder = ImGui.Checkbox("Show windows begin order", cfg.ShowWindowsBeginOrder == true)
|
||||
_, cfg.ShowWindowsRects = ImGui.Checkbox("Show windows rectangles", cfg.ShowWindowsRects == true)
|
||||
ImGui.SameLine()
|
||||
ImGui.SetNextItemWidth(ImGui.GetFontSize() * 12)
|
||||
local changed
|
||||
cfg.ShowWindowsRectsType, changed = ImGui.Combo("##show_windows_rect_type", cfg.ShowWindowsRectsType, WRT_Names, #WRT_Names, #WRT_Names)
|
||||
cfg.ShowWindowsRects = cfg.ShowWindowsRects or changed
|
||||
if cfg.ShowWindowsRects and g.NavWindow ~= nil then
|
||||
ImGui.BulletText("'%s':", g.NavWindow.Name)
|
||||
ImGui.Indent()
|
||||
for rect_n = 0, #WRT_Names - 1 do
|
||||
local r = 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_Names[rect_n + 1])
|
||||
end
|
||||
ImGui.Unindent()
|
||||
end
|
||||
_, cfg.ShowTablesRects = ImGui.Checkbox("Show tables rectangles", cfg.ShowTablesRects == true)
|
||||
ImGui.SameLine()
|
||||
ImGui.SetNextItemWidth(ImGui.GetFontSize() * 12)
|
||||
cfg.ShowTablesRectsType, changed = ImGui.Combo("##show_table_rects_type", cfg.ShowTablesRectsType, TRT_Names, #TRT_Names, #TRT_Names)
|
||||
cfg.ShowTablesRects = cfg.ShowTablesRects or changed
|
||||
_, g.DebugShowGroupRects = ImGui.Checkbox("Show groups rectangles", g.DebugShowGroupRects == true)
|
||||
|
||||
ImGui.SeparatorText("Validate")
|
||||
_, io.ConfigDebugBeginReturnValueLoop = ImGui.Checkbox("Debug Begin/BeginChild return value", io.ConfigDebugBeginReturnValueLoop == true)
|
||||
ImGui.SameLine(); MetricsHelpMarker("Some calls to Begin()/BeginChild() will return false.\n\nWill cycle through window depths then repeat. Windows should be flickering while running.")
|
||||
_, cfg.ShowTextEncodingViewer = ImGui.Checkbox("UTF-8 Encoding viewer", cfg.ShowTextEncodingViewer == true)
|
||||
ImGui.SameLine(); MetricsHelpMarker("You can also call ImGui::DebugTextEncoding() from your code with a given string to test that your UTF-8 encoding settings are correct.")
|
||||
if cfg.ShowTextEncodingViewer then
|
||||
MetricsEncodingBuf = MetricsEncodingBuf or DemoBuf("", 64)
|
||||
ImGui.SetNextItemWidth(-FLT_MIN)
|
||||
ImGui.InputText("##DebugTextEncodingBuf", MetricsEncodingBuf, 64)
|
||||
local str = DemoBufStr(MetricsEncodingBuf)
|
||||
if str ~= "" then ImGui.DebugTextEncoding(str) end
|
||||
end
|
||||
ImGui.TreePop()
|
||||
end
|
||||
|
||||
-- Windows
|
||||
if ImGui.TreeNode("Windows", "Windows (%d)", g.Windows.Size) then
|
||||
ImGui.DebugNodeWindowsList(g.Windows, "By display order")
|
||||
ImGui.DebugNodeWindowsList(g.WindowsFocusOrder, "By focus order (root windows)")
|
||||
if ImGui.TreeNode("By submission order (begin stack)") then
|
||||
local tmp = {}
|
||||
for _, window in g.Windows:iter() do
|
||||
if window.LastFrameActive + 1 >= g.FrameCount then tmp[#tmp + 1] = window end
|
||||
end
|
||||
table.sort(tmp, function(a, b) return a.BeginOrderWithinContext < b.BeginOrderWithinContext end)
|
||||
ImGui.DebugNodeWindowsListByBeginStackParent(tmp, 1, #tmp, nil)
|
||||
ImGui.TreePop()
|
||||
end
|
||||
ImGui.TreePop()
|
||||
end
|
||||
|
||||
-- DrawLists
|
||||
local drawlist_count = 0
|
||||
for _, viewport in g.Viewports:iter() do drawlist_count = drawlist_count + viewport.DrawDataP.CmdLists.Size end
|
||||
if ImGui.TreeNode("DrawLists", "DrawLists (%d)", drawlist_count) then
|
||||
_, cfg.ShowDrawCmdMesh = ImGui.Checkbox("Show ImDrawCmd mesh when hovering", cfg.ShowDrawCmdMesh ~= false)
|
||||
_, cfg.ShowDrawCmdBoundingBoxes = ImGui.Checkbox("Show ImDrawCmd bounding boxes when hovering", cfg.ShowDrawCmdBoundingBoxes ~= false)
|
||||
for _, viewport in g.Viewports:iter() do
|
||||
local has = false
|
||||
for _, draw_list in viewport.DrawDataP.CmdLists:iter() do
|
||||
if not has then ImGui.Text("Active DrawLists in Viewport #%d, ID: 0x%08X", viewport.Idx or 0, viewport.ID) end
|
||||
has = true
|
||||
ImGui.DebugNodeDrawList(nil, viewport, draw_list, "DrawList")
|
||||
end
|
||||
end
|
||||
ImGui.TreePop()
|
||||
end
|
||||
|
||||
-- Viewports
|
||||
if ImGui.TreeNode("Viewports", "Viewports (%d)", g.Viewports.Size) then
|
||||
ImGui.SetNextItemOpen(true, ImGuiCond.Once)
|
||||
if ImGui.TreeNode("Windows Minimap") then
|
||||
ImGui.RenderViewportsThumbnails()
|
||||
ImGui.TreePop()
|
||||
end
|
||||
cfg.HighlightViewportID = 0
|
||||
for _, viewport in g.Viewports:iter() do ImGui.DebugNodeViewport(viewport) end
|
||||
ImGui.TreePop()
|
||||
end
|
||||
|
||||
-- Fonts
|
||||
for i, atlas in g.FontAtlases:iter() do
|
||||
if ImGui.TreeNode(tostring(atlas), "Fonts (%d), Textures (%d)", atlas.Fonts.Size, atlas.TexList.Size) then
|
||||
ImGui.ShowFontAtlas(atlas)
|
||||
ImGui.TreePop()
|
||||
end
|
||||
end
|
||||
|
||||
-- Popups
|
||||
if ImGui.TreeNode("Popups", "Popups (%d)", g.OpenPopupStack.Size) then
|
||||
for _, popup_data in g.OpenPopupStack:iter() do
|
||||
local window = popup_data.Window
|
||||
local W = ImGuiWindowFlags
|
||||
ImGui.BulletText("PopupID: %08x, Window: '%s' (%s%s), RestoreNavWindow '%s', ParentWindow '%s'", popup_data.PopupId, window and window.Name or "NULL",
|
||||
(window and bit32.band(window.Flags, W.ChildWindow) ~= 0) and "Child;" or "", (window and bit32.band(window.Flags, W.ChildMenu) ~= 0) and "Menu;" or "",
|
||||
popup_data.RestoreNavWindow and popup_data.RestoreNavWindow.Name or "NULL", (window and window.ParentWindow) and window.ParentWindow.Name or "NULL")
|
||||
end
|
||||
ImGui.TreePop()
|
||||
end
|
||||
|
||||
-- TabBars
|
||||
if ImGui.TreeNode("TabBars", "Tab Bars (%d)", g.TabBars.AliveCount) then
|
||||
for n = 0, g.TabBars:GetMapSize() - 1 do
|
||||
local tab_bar = g.TabBars:GetByIndex(n)
|
||||
if tab_bar then
|
||||
ImGui.PushID(n)
|
||||
ImGui.DebugNodeTabBar(tab_bar, "TabBar")
|
||||
ImGui.PopID()
|
||||
end
|
||||
end
|
||||
ImGui.TreePop()
|
||||
end
|
||||
|
||||
-- Tables
|
||||
if ImGui.TreeNode("Tables", "Tables (%d)", g.Tables.AliveCount) then
|
||||
ForEachTable(g, ImGui.DebugNodeTable)
|
||||
ImGui.TreePop()
|
||||
end
|
||||
|
||||
-- Docking
|
||||
if ImGui.TreeNode("Docking") then
|
||||
local dc = g.DockContext
|
||||
_, MetricsDockRootOnly = ImGui.Checkbox("List root nodes", MetricsDockRootOnly)
|
||||
_, cfg.ShowDockingNodes = ImGui.Checkbox("Ctrl shows window dock info", cfg.ShowDockingNodes == true)
|
||||
if ImGui.SmallButton("Clear nodes") then ImGui.DockContextClearNodes(g, 0, true) end
|
||||
ImGui.SameLine()
|
||||
if ImGui.SmallButton("Rebuild all") then dc.WantFullRebuild = true end
|
||||
local ids = {}
|
||||
for id in pairs(dc.Nodes) do ids[#ids + 1] = id end
|
||||
table.sort(ids)
|
||||
for _, id in ipairs(ids) do
|
||||
local node = dc.Nodes[id]
|
||||
if node and (not MetricsDockRootOnly or node:IsRootNode()) then ImGui.DebugNodeDockNode(node, "Node") end
|
||||
end
|
||||
ImGui.TreePop()
|
||||
end
|
||||
|
||||
-- Settings
|
||||
if ImGui.TreeNode("Settings") then
|
||||
if ImGui.SmallButton("Clear") then ImGui.ClearIniSettings() end
|
||||
ImGui.SameLine()
|
||||
if ImGui.SmallButton("Save to memory") then ImGui.SaveIniSettingsToMemory() end
|
||||
ImGui.SameLine()
|
||||
ImGui.TextUnformatted(io.IniFilename and ("\"" .. io.IniFilename .. "\"") or "<NULL>")
|
||||
ImGui.Text("SettingsDirtyTimer %.2f", g.SettingsDirtyTimer)
|
||||
if ImGui.TreeNode("SettingsHandlers", "Settings handlers: (%d)", g.SettingsHandlers.Size) then
|
||||
for _, handler in g.SettingsHandlers:iter() do ImGui.BulletText("\"%s\"", handler.TypeName) end
|
||||
ImGui.TreePop()
|
||||
end
|
||||
if ImGui.TreeNode("SettingsWindows", "Settings packed data: Windows: %d entries", g.SettingsWindows.Size) then
|
||||
for _, settings in g.SettingsWindows:iter() do ImGui.DebugNodeWindowSettings(settings) end
|
||||
ImGui.TreePop()
|
||||
end
|
||||
if ImGui.TreeNode("SettingsTables", "Settings packed data: Tables: %d entries", g.SettingsTables.Size) then
|
||||
for _, settings in g.SettingsTables:iter() do ImGui.DebugNodeTableSettings(settings, nil) end
|
||||
ImGui.TreePop()
|
||||
end
|
||||
if ImGui.TreeNode("SettingsDocking", "Settings packed data: Docking") then
|
||||
local dc = g.DockContext
|
||||
ImGui.Text("In SettingsWindows:")
|
||||
for _, settings in g.SettingsWindows:iter() do
|
||||
if (settings.DockId or 0) ~= 0 then ImGui.BulletText("Window '%s' -> DockId %08X DockOrder=%d", settings.Name or "", settings.DockId, settings.DockOrder or -1) end
|
||||
end
|
||||
ImGui.Text("In SettingsNodes:")
|
||||
for _, settings in dc.NodesSettings:iter() do
|
||||
local selected_tab_name = nil
|
||||
if (settings.SelectedTabId or 0) ~= 0 then
|
||||
local window = ImGui.FindWindowByID(settings.SelectedTabId)
|
||||
selected_tab_name = window and window.Name or nil
|
||||
end
|
||||
ImGui.BulletText("Node %08X, Parent %08X, SelectedTab %08X ('%s')", settings.ID, settings.ParentNodeId or 0, settings.SelectedTabId or 0, selected_tab_name or ((settings.SelectedTabId or 0) ~= 0 and "N/A" or ""))
|
||||
end
|
||||
ImGui.TreePop()
|
||||
end
|
||||
local ini = g.SettingsIniData or ""
|
||||
if ImGui.TreeNode("SettingsIniData", "Settings unpacked data (.ini): %d bytes", #ini) then
|
||||
ImGui.InputTextMultiline("##Ini", DemoBuf(ini, #ini + 1), #ini + 1, ImVec2(-FLT_MIN, ImGui.GetTextLineHeight() * 20), ImGuiInputTextFlags.ReadOnly)
|
||||
ImGui.TreePop()
|
||||
end
|
||||
ImGui.TreePop()
|
||||
end
|
||||
|
||||
-- Inputs
|
||||
if ImGui.TreeNode("Inputs") then
|
||||
ImGui.Text("KEYBOARD/GAMEPAD/MOUSE KEYS")
|
||||
ImGui.Indent()
|
||||
ImGui.Text("Keys down:")
|
||||
for key = ImGuiKey.NamedKey_BEGIN, ImGuiKey.NamedKey_END - 1 do
|
||||
if ImGui.IsKeyDown(key) then ImGui.SameLine(); ImGui.Text("\"%s\"", ImGui.GetKeyName(key)) end
|
||||
end
|
||||
ImGui.Text("Keys pressed:")
|
||||
for key = ImGuiKey.NamedKey_BEGIN, ImGuiKey.NamedKey_END - 1 do
|
||||
if ImGui.IsKeyPressed(key) then ImGui.SameLine(); ImGui.Text("\"%s\"", ImGui.GetKeyName(key)) end
|
||||
end
|
||||
ImGui.Text("Keys released:")
|
||||
for key = ImGuiKey.NamedKey_BEGIN, ImGuiKey.NamedKey_END - 1 do
|
||||
if ImGui.IsKeyReleased(key) then ImGui.SameLine(); ImGui.Text("\"%s\"", ImGui.GetKeyName(key)) end
|
||||
end
|
||||
ImGui.Text("Keys mods: %s%s%s%s", io.KeyCtrl and "Ctrl " or "", io.KeyShift and "Shift " or "", io.KeyAlt and "Alt " or "", io.KeySuper and "Super " or "")
|
||||
ImGui.Unindent()
|
||||
ImGui.Text("MOUSE STATE")
|
||||
ImGui.Indent()
|
||||
if ImGui.IsMousePosValid() then ImGui.Text("Mouse pos: (%g, %g)", io.MousePos.x, io.MousePos.y) else ImGui.Text("Mouse pos: <INVALID>") end
|
||||
ImGui.Text("Mouse delta: (%g, %g)", io.MouseDelta.x, io.MouseDelta.y)
|
||||
ImGui.Text("Mouse down:")
|
||||
for i = 0, 2 do if ImGui.IsMouseDown(i) then ImGui.SameLine(); ImGui.Text("b%d (%.02f secs)", i, io.MouseDownDuration[i]) end end
|
||||
ImGui.Text("Mouse clicked:")
|
||||
for i = 0, 2 do if ImGui.IsMouseClicked(i) then ImGui.SameLine(); ImGui.Text("b%d (%d)", i, io.MouseClickedCount[i]) end end
|
||||
ImGui.Text("Mouse released:")
|
||||
for i = 0, 2 do if ImGui.IsMouseReleased(i) then ImGui.SameLine(); ImGui.Text("b%d", i) end end
|
||||
ImGui.Text("Mouse wheel: %.1f", io.MouseWheel)
|
||||
ImGui.Text("MouseStationaryTimer: %.2f", g.MouseStationaryTimer)
|
||||
ImGui.Unindent()
|
||||
ImGui.Text("MOUSE WHEELING")
|
||||
ImGui.Indent()
|
||||
ImGui.Text("WheelingWindow: '%s'", g.WheelingWindow and g.WheelingWindow.Name or "NULL")
|
||||
ImGui.Text("WheelingWindowReleaseTimer: %.2f", g.WheelingWindowReleaseTimer or 0)
|
||||
ImGui.Text("WheelingAxisAvg[] = { %.3f, %.3f }", g.WheelingAxisAvg.x, g.WheelingAxisAvg.y)
|
||||
ImGui.Unindent()
|
||||
ImGui.TreePop()
|
||||
end
|
||||
|
||||
-- Internal state
|
||||
if ImGui.TreeNode("Internal state") then
|
||||
local function N(w) return w and w.Name or "NULL" end
|
||||
ImGui.Text("WINDOWING")
|
||||
ImGui.Indent()
|
||||
ImGui.Text("HoveredWindow: '%s'", N(g.HoveredWindow))
|
||||
ImGui.Text("HoveredWindow->Root: '%s'", g.HoveredWindow and N(g.HoveredWindow.RootWindowDockTree) or "NULL")
|
||||
ImGui.Text("HoveredWindowUnderMovingWindow: '%s'", N(g.HoveredWindowUnderMovingWindow))
|
||||
ImGui.Text("HoveredDockNode: 0x%08X", g.DebugHoveredDockNode and g.DebugHoveredDockNode.ID or 0)
|
||||
ImGui.Text("MovingWindow: '%s'", N(g.MovingWindow))
|
||||
ImGui.Unindent()
|
||||
ImGui.Text("ITEMS")
|
||||
ImGui.Indent()
|
||||
ImGui.Text("ActiveId: 0x%08X/0x%08X (%.2f sec), AllowOverlap: %d", g.ActiveId, g.ActiveIdPreviousFrame, g.ActiveIdTimer, B(g.ActiveIdAllowOverlap))
|
||||
ImGui.Text("ActiveIdWindow: '%s'", N(g.ActiveIdWindow))
|
||||
ImGui.Text("HoveredId: 0x%08X (%.2f sec), AllowOverlap: %d", g.HoveredIdPreviousFrame, g.HoveredIdTimer, B(g.HoveredIdAllowOverlap))
|
||||
ImGui.Text("HoverItemDelayId: 0x%08X, Timer: %.2f, ClearTimer: %.2f", g.HoverItemDelayId or 0, g.HoverItemDelayTimer or 0, g.HoverItemDelayClearTimer or 0)
|
||||
ImGui.Text("DragDrop: %d, SourceId = 0x%08X, Payload \"%s\"", B(g.DragDropActive), g.DragDropPayload.SourceId or 0, tostring(g.DragDropPayload.DataType or ""))
|
||||
ImGui.Unindent()
|
||||
ImGui.Text("NAV,FOCUS")
|
||||
ImGui.Indent()
|
||||
ImGui.Text("NavWindow: '%s'", N(g.NavWindow))
|
||||
ImGui.Text("NavId: 0x%08X, NavLayer: %d", g.NavId, g.NavLayer)
|
||||
ImGui.Text("NavActive: %d, NavVisible: %d", B(io.NavActive), B(io.NavVisible))
|
||||
ImGui.Text("NavActivateId/DownId/PressedId: %08X/%08X/%08X", g.NavActivateId, g.NavActivateDownId or 0, g.NavActivatePressedId or 0)
|
||||
ImGui.Text("NavActivateFlags: %04X", g.NavActivateFlags or 0)
|
||||
ImGui.Text("NavCursorVisible: %d, NavHighlightItemUnderNav: %d", B(g.NavCursorVisible), B(g.NavHighlightItemUnderNav))
|
||||
ImGui.Text("NavFocusScopeId = 0x%08X", g.NavFocusScopeId or 0)
|
||||
ImGui.Text("NavWindowingTarget: '%s'", N(g.NavWindowingTarget))
|
||||
ImGui.Unindent()
|
||||
ImGui.TreePop()
|
||||
end
|
||||
|
||||
-- Overlays
|
||||
if cfg.ShowWindowsRects or cfg.ShowWindowsBeginOrder then
|
||||
for _, window in g.Windows:iter() do
|
||||
if window.WasActive then
|
||||
local draw_list = FG(window)
|
||||
if cfg.ShowWindowsRects then
|
||||
local r = GetWindowRect(window, cfg.ShowWindowsRectsType)
|
||||
draw_list:AddRect(r.Min, r.Max, IM_COL32(255, 0, 128, 255))
|
||||
end
|
||||
if cfg.ShowWindowsBeginOrder and bit32.band(window.Flags, ImGuiWindowFlags.ChildWindow) == 0 then
|
||||
local 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), tostring(window.BeginOrderWithinContext))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if cfg.ShowTablesRects then
|
||||
ForEachTable(g, function(tbl)
|
||||
if tbl.LastFrameActive < g.FrameCount - 1 then return end
|
||||
local draw_list = FG(tbl.OuterWindow)
|
||||
if cfg.ShowTablesRectsType >= TRT_ColumnsRect then
|
||||
for column_n = 0, tbl.ColumnsCount - 1 do
|
||||
local r = GetTableRect(tbl, cfg.ShowTablesRectsType, column_n)
|
||||
local hot = (tbl.HoveredColumnBody == column_n)
|
||||
draw_list:AddRect(r.Min, r.Max, hot and IM_COL32(255, 255, 128, 255) or IM_COL32(255, 0, 128, 255), 0.0, hot and 3.0 or 1.0)
|
||||
end
|
||||
else
|
||||
local r = GetTableRect(tbl, cfg.ShowTablesRectsType, -1)
|
||||
draw_list:AddRect(r.Min, r.Max, IM_COL32(255, 0, 128, 255))
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
ImGui.End()
|
||||
return p_open
|
||||
end
|
||||
|
||||
return true
|
||||
|
||||
Reference in New Issue
Block a user