跳到主要内容

调试工具 Debug

写 UI 最痛苦的不是画不出来,而是不知道为什么没画出来。HiEasyX 提供两套内置调试工具:ShowMetricsWindow 看性能与状态,ShowLayoutDebugger 看布局边界。它们不占额外窗口,直接在当前 IMGUI 上下文里绘制,用完即走。

使用前提

必须在 End() 之前调用
HX::Window(HXStr("main"), wp);
// ... 你的控件 ...

HX::ShowMetricsWindow(); // ✅ 正确:在 End() 之前
HX::ShowLayoutDebugger(); // ✅ 正确:在 End() 之前

HX::End();

如果在 End() 之后调用,LayoutStack 已经被清空,调试器拿不到布局上下文,会显示空内容或触发断言。


ShowMetricsWindow

函数原型

void ShowMetricsWindow();

无参数,无返回值。

显示内容

调用后会在当前窗口内渲染一个调试面板,包含以下信息:

类别内容
帧时间上一帧耗时(ms)与估算 FPS。
消息统计本帧接收到的 peekmessage 数量,按类型分布。
池统计HXSubPainterPool 的桶数量、总 painter 数、命中/未命中情况。
栈深度当前 LayoutStack 深度、WindowStack 深度、Focus Stack 深度。
什么时候打开

建议在开发模式下绑定一个快捷键(如 Ctrl+Shift+M)或菜单项来切换显示:

static bool showMetrics = false;
if (HX::Button(HXStr("Toggle Metrics"), btn)) {
showMetrics = !showMetrics;
}
if (showMetrics) {
HX::ShowMetricsWindow();
}

ShowLayoutDebugger

函数原型

void ShowLayoutDebugger();

无参数,无返回值。

显示内容

在当前窗口上方叠加绘制半透明矩形,每个矩形对应 LayoutStack 中的一个布局上下文:

  • BaseLine:布局当前行的基线 Y 坐标。
  • **CurrentHeightMax`:当前行最大高度。
  • 宽度与高度:当前可用内容区域的尺寸。
颜色约定
  • 不同层级的布局矩形用不同颜色区分(通常是红、绿、蓝、黄循环)。
  • 文字标签直接画在矩形内部或边缘,不影响控件点击。

典型用途

问题用 LayoutDebugger 诊断
控件莫名其妙换行看当前 LayoutStack 的可用宽度是否被意外缩小。
垂直间距不对BaseLineCurrentHeightMax 的推进是否符合预期。
嵌套容器里控件跑出边界看外层 Panel / Scroller / Viewport 的 clip rect 是否设置正确。
对齐异常BeginHorizontal / BeginVertical 引入的新布局上下文。

完整示例:开发模式开关

#include <include/hex.h>
#include <include/impl/EasyX/hex_impl_easyx.h>

void DemoDebugTools() {
static bool showMetrics = false;
static bool showLayout = false;

HX::WindowProfile wp;
wp.Title = HXStr("Debug Demo");
wp.Size = {600, 500};
HX::Window(HXStr("debug_demo"), wp);

// 调试开关
HX::BeginHorizontal();
HX::CheckboxProfile cb1;
cb1.Checked = showMetrics;
if (HX::Checkbox(HXStr("Show Metrics"), cb1)) {
showMetrics = cb1.Checked;
}

HX::CheckboxProfile cb2;
cb2.Checked = showLayout;
if (HX::Checkbox(HXStr("Show Layout"), cb2)) {
showLayout = cb2.Checked;
}
HX::EndHorizontal();

// 一些普通控件,用来观察布局
HX::Text(HXStr("Line 1: Hello Debug"));
HX::Text(HXStr("Line 2: More content here"));

HX::ButtonProfile btn;
HX::Button(HXStr("A Button"), btn);

HX::BeginHorizontal();
HX::Button(HXStr("Left"), btn);
HX::Button(HXStr("Right"), btn);
HX::EndHorizontal();

// ========== 调试工具必须在 End() 之前 ==========
if (showMetrics) {
HX::ShowMetricsWindow();
}
if (showLayout) {
HX::ShowLayoutDebugger();
}

HX::End();
}

与其他调试手段配合

控制台日志

EasyX 程序通常是 WinMain / main 子系统。如果你想看 printf 输出,可以在 main 开头加:

AllocConsole();
freopen("CONOUT$", "w", stdout);

然后结合 ShowMetricsWindow 的数值做实时对比。

SubPainter 泄漏检测

如果 MetricsWindow 里的池统计数字随时间无限增长,说明某个控件在直接 new / delete SubPainter 而没有走 HXSubPainterPool。这是性能回归的典型信号。


总结

工具看什么调用位置
ShowMetricsWindow帧时间、FPS、消息数、池统计、栈深度End() 之前
ShowLayoutDebuggerLayoutStack 各层边界、基线、行高End() 之前

调试工具是框架的自省能力。打开它们,你看到的不再是一团黑箱,而是一层一层剥开的清晰结构 🔍