本文档介绍了 Dear ImGui 的窗口管理和布局系统,详细说明了窗口如何创建、定位和调整大小,以及 UI 元素在窗口内的定位方式。有关可以放置在窗口中的特定控件的信息,请参阅 Widgets System。
Dear ImGui 的 UI 构建于窗口这一概念之上,窗口是包含控件、内容和其他 UI 元素的矩形区域。窗口是组织 UI 的主要容器。
Dear ImGui 中的窗口遵循简单的 Begin/End 模式。
每个窗口都有一个由其标题派生的唯一标识符。窗口的存在与您应用程序的帧循环中的 Begin()/End() 调用绑定。如果您在给定帧中未调用窗口的 Begin(),则该窗口在该帧中不存在。
来源:imgui.cpp
可以通过传递给 Begin() 函数的各种标志来定制窗口。这些标志控制外观、行为和功能。
| 标志 | 描述 |
|---|---|
| ImGuiWindowFlags_NoTitleBar | 移除标题栏 |
| ImGuiWindowFlags_NoResize | 禁用调整大小 |
| ImGuiWindowFlags_NoMove | 禁用移动 |
| ImGuiWindowFlags_NoScrollbar | 隐藏滚动条 |
| ImGuiWindowFlags_NoCollapse | 禁用折叠按钮 |
| ImGuiWindowFlags_AlwaysAutoResize | 每帧自动调整大小以适应内容 |
| ImGuiWindowFlags_NoBackground | 禁用背景颜色/纹理 |
| ImGuiWindowFlags_MenuBar | 启用菜单栏 |
| ImGuiWindowFlags_NoSavedSettings | 阻止将窗口状态保存到 .ini 文件 |
来源:imgui.h
子窗口是在另一个父窗口内嵌套的窗口。它们提供额外的组织能力,并可以有自己的滚动行为。
子窗口特别适用于在父窗口内创建可滚动区域。
自 ImGui 1.90(2023 年)以来,子窗口使用专用的标志,独立于窗口标志。
| 标志 | 描述 |
|---|---|
| ImGuiChildFlags_Border | 在子窗口周围显示边框 |
| ImGuiChildFlags_AlwaysUseWindowPadding | 始终应用父窗口的内边距 |
| ImGuiChildFlags_ResizeX | 启用沿 X 轴的调整大小 |
| ImGuiChildFlags_ResizeY | 启用沿 Y 轴的调整大小 |
| ImGuiChildFlags_AutoResizeX | 自动调整宽度以适应内容 |
| ImGuiChildFlags_AutoResizeY | 自动调整高度以适应内容 |
| ImGuiChildFlags_AlwaysAutoResize | 双轴自动调整大小 |
Dear ImGui 使用多个重要的坐标系统,理解它们很重要。
来源:imgui.cpp
最重要的与坐标相关的函数包括:
您可以使用这些函数来控制窗口的定位和尺寸调整。
ImGuiCond_ 标志控制何时应用位置/大小。
| 条件 | 描述 |
|---|---|
| ImGuiCond_Always | 总是应用 |
| ImGuiCond_Once | 仅应用一次 |
| ImGuiCond_FirstUseEver | 仅当窗口不存在于 .ini 文件时应用 |
| ImGuiCond_Appearing | 仅当窗口出现时应用 |
Dear ImGui 中的布局系统决定了控件在窗口内的定位方式。它是基于光标的,随着控件的添加,光标会向前移动。
来源:imgui.cpp
基本的布局流程是垂直的——每个控件都放置在前一个控件下方。但是,您可以修改此流程。
布局系统提供了各种函数来控制控件的定位。
| 功能 | 描述 |
|---|---|
| SameLine() | 将下一个控件放在同一行 |
| NewLine() | 强制换行 |
| Spacing() | 添加垂直间距 |
| Dummy() | 添加指定大小的空白区域 |
| Indent() | 水平缩进内容 |
| Unindent() | 移除水平缩进 |
| BeginGroup()/EndGroup() | 将控件组合在一起 |
| AlignTextToFramePadding() | 垂直对齐即将出现的文本 |
内容区域是窗口内边距中可以放置控件的区域。处理内容区域的关键函数:
Dear ImGui 中的控件具有以下尺寸行为:
您可以使用以下方式控制控件的宽度:
列提供了水平组织内容的方式。
自 ImGui 1.52 起,Tables 提供了一个比 columns 更强大的替代方案,具有更多附加功能。
组允许将多个控件视为单个单元。
组对于以下用途很有用:
当内容超出窗口大小时,窗口会自动添加滚动条。您可以以编程方式控制滚动。
Dear ImGui 会自动处理裁剪。超出可见区域的内容不会被渲染。
裁剪系统是一项重要的优化。超出可见区域的项目不会被渲染,从而节省性能。
窗口和布局系统与许多其他 ImGui 系统交互。
窗口 ID:窗口 ID 是从窗口名称生成的——使用 ### 来自定义 ID,同时保留显示文本(例如,"My Window###UniqueID")。
子窗口与组:
调整窗口大小:
SetNextWindowSize() 配合 ImGuiCond_FirstUseEver 来允许用户调整大小。ImGuiWindowFlags_AlwaysAutoResize。布局效率:
GetContentRegionAvail() 对于创建适应可用空间的控件很有用。SameLine() 和 Dummy() 来实现精确的布局控制。窗口和布局系统是 Dear ImGui 用户界面的基础。理解窗口如何创建、调整大小和定位,以及控件如何在其中流动,对于使用 Dear ImGui 创建有效的 UI 至关重要。
从使用 Begin()/End() 创建主窗口到使用 BeginChild()/EndChild() 创建子窗口,从基本的垂直布局到高级的基于列的设计,窗口和布局系统提供了将 UI 整合在一起的结构。