ImGui 基础概念
如果您是初次使用 ImGui 包,我们希望您能认真阅读此页面,以保证您具备使用此包的基本概念。而后,您才可能知道您在自己的项目中需要什么,想要什么。
总体容阅读时间约为 20 min,请酌情参考。
本页面将呈现以下内容:
典型 ImGui 程序的代码布局
ImGui 的所有内容均组织在名为 application 的,由系统提供的窗口内。
一个 application 内可以绘制多个窗口(window)。
每个窗口内可以拥有若干控件。
我们可以使用一种典型代码结构来编写可视化工具:
while !app.is_closed() app.prepare() ... app.render() end
在 app.prepare() 和 app.render() 间设计的布局的每个窗口(包括每个控件),都将以每一帧为单位染至应用(application)上。
显示器方法(Open GL)
Open GL 是 Dear ImGui 的后端,其方法与 Dear ImGui 无关。
在 ImGui 中保留并提供了对显示器的方法:
方法 | 描述 |
---|---|
number get_monitor_count() | 获取系统使用显示器数量 |
number get_monitor_width(number monitor_id) | 获取指定显示器的宽度(像素) |
number get_monitor_height(number monitor_id) | 获取指定显示器的高度(像素) |
显示器 id 由系统分配。
例如:win10 下,显示器编号为 1~n,则在 ImGui 中显示器 id 对应为 0~n-1。
单显示器下显示器 id 为 0。
应用(application)简要
application 分为两种:
application 申明方法 | 描述 |
---|---|
[application] fullscreen_application(number monitor_id, string title) | 创建全屏应用并返回应用对象 |
[application] window_application(number width, number height, string title) | 创建窗口应用并返回应用对象 |
创建全屏应用需手动指定显示器 id。
创建窗口应用需指定长宽,需要创建与屏幕成比例的窗口,可以配合显示器方法(获取显示器长宽)使用。
application 支持设置内部所有窗口(window)的主题风格:
设置主题方法 | 描述 |
---|---|
void style_color_classic() | 切换到经典主题 |
void style_color_light() | 切换到亮色主题 |
void style_color_dark() | 切换到暗色主题 |
向量(vec2/vec4)
在 Dear ImGui 中,有两类向量:
- vec2:二维向量,常用于表示坐标或长宽
- vec4:四维向量,常用于表示有三通道和透明度的色彩(RGBA)
ImGui 对此保留了以上设计:
[vec2] vec2(number x, number y) | 返回二维向量对象,每个分量(x、y)可访问 |
[vec4] vec4(number x, number y, number z, number w) | 返回四维向量对象,每个分量(x、y、z、w)可访问 |
字体(font)简要
ImGui 会为整个应用维护一个字体栈,每绘制一次窗口,都会自动使用字体栈顶的字体。
ImGui 为字体栈提供了以下方法:
方法 | 描述 |
---|---|
void push_font([font]) | 将字体对象压入栈顶(使字体生效) |
void pop_font() | 弹出字体栈栈顶对象(删除当前字体 ) |
[font] get_font() | 获取栈顶对象(当前字体) |
ImGui 为字体提供了专用的字体包 imgui_font【待更新】 和以下方法:
[font] add_font(string path, number size) | 从路径中加载字体文件,指定字体大小,并返回字体对象 |
[font] add_font_chinese(string path, number size) | 同上,适用于中文 |
[font] add_font_default(number size) | 加载默认字体(英文),指定字体大小,并返回字体对象 |
[font] add_font_extend([imgui_font] data, number size) | 加载 imgui_font 中的扩展字体,指定字体大小,并返回字体对象 |
[font] add_font_extend_cn([imgui_font] data, number size) | 同上,适用于中文 |
import imgui import imgui_font var font0 = add_font_extend_cn(imgui_font.source_han_sans,25) var font1 = add_font_default(25) ... while !app.is_closed app.prepare() push_font(font0) ... # 此处控件使用 font0 字体 pop_font() push_font(font1) ... # 此处控件使用 font1 字体 app.render() end
窗口(window)简要
ImGui 的提供的窗口仅在应用中生效,即:应用内窗口。
窗口是控件的载体,每个应用内可以涵有若干窗口。
一般来说,通过如下的方式来设置窗口
方法 | 描述 |
---|---|
void set_window_pos([vec2] pos) | 设置当前窗口位置 |
void set_window_size([vec2] size) | 设置当前窗口大小 |
void begin_window(string title_and_id, boolean is_open, array flags) | 开始新窗口布局 |
void end_window() | 结束窗口布局 |
对于以上方法做出解释。
例如,在 app 内绘制一个 window,然后渲染:
while !app.is_closed app.prepare() begin_window("my_window##mw1", mw1_isopen, {}) set_window_pos(vec2(0,0)) set_window_size(vec2(get_widow_width(app),get_widow_height(app))) ... end_window() app.render() end
参数 title_and_id 表示该窗口的标题与 id 号,该参数由标题与 id 号两个字符串分构成,中间使用“##”隔开。
一个 title_and_id 可以没有 id 号,只有 title 标题的字符串。
合法的 title_and_id 例如:“title##1”、“title##a”、“1#”;非法的 title_and_id 有“1##”。
is_open:
参数 is_open 必须一个变量的引用,即:必须是一个变量,而不能是一个具体的 boolean 常量。
这是因为每个 window 需要一个变量来记录是否被关闭(点击关闭按钮事件),从而达到检测窗口是否关闭的效果。
flags:
参数 flags 为创建窗口时所携带的参数。包括**无标题栏**、**自适应大小**等。
控件(widget)简要
互动类控件通常使用返回boolean
类型的值,来表示其状态。
如按钮(button):
... begin_window(...) if button("click me!") # do something ... end_window()
控件种类繁多,不在此一一赘述。如有需要可以参考 ImGui 控件文档。
标识符:一般用于右键菜单等,默认情况下标识符就是控件名,但有些控件无 ID 时就要特别标示
一般控件名可使用title##id
的形式指定控件的标识符
方法 | 描述 |
---|---|
void push_id(string title_and_id) | 创建新标识符 |
void pop_id() | 结束标识符 |
布局和组(group)
ImGui支持使用begin_group()
和end_group()
一对方法标签,将若干控件组合为一个组(group),并对其实施统一的布局行为。
以下改变布局的行为,仅对组内控件生效:
方法 | 描述 |
---|---|
void begin_group() | 开始新组 |
void end_group() | 结束组 |
void separator() | 横向分割线 |
void same_line() | 设置下一个控件为同一行 |
void spacing() | 插入空格 |
void indent() | 缩进 |
void unindent() | 反缩进 |
另外还有树形节点,您可以理解为组(group)的树状形式:
方法 | 描述 |
---|---|
boolean tree_node(string label) | 创建新的树节点 |
void tree_pop() | 结束树节点 |
焦点
可以粗浅理解为“当前选中的窗口或控件”。大部分I/O指令都作用于焦点控件(或窗口)上。焦点会被鼠标左键触发设置,您也可以自行设置焦点(根据逻辑)。
方法 | 描述 |
---|---|
void set_scroll_here() | 将滚动条滚动到当前位置 |
void set_keyboard_focus_here() | 设置上一个控件为键盘焦点 |
画板(canvas)
画板提供了在窗口内绘图的系列方法。
方法 | 描述 |
---|---|
void add_line([vec2] a, [vec2] b, [vec4] color, number thickness) | 绘制线段 |
void add_rect([vec2] a, [vec2] b, [vec4] color, number rounding, number thickness) | 绘制矩形线框 |
void add_rect_filled([vec2] a, [vec2] b, [vec4] color, number rounding) | 填充矩形 |
void add_quad([vec2] a, [vec2] b, [vec2] c, [vec2] d, [vec4] color, number thickness) | 绘制四边形线框 |
void add_quad_filled([vec2] a, [vec2] b, [vec2] c, [vec2] d, [vec4] color) | 填充四边形 |
void add_triangle([vec2] a, [vec2] b, [vec2] c, [vec4] color, number thickness) | 绘制三角形线框 |
void add_triangle_filled([vec2] a, [vec2] b, [vec2] c, [vec4] color) | 填充三角形 |
void add_circle([vec2] centre, number radius, [vec4] color, number seg, number thickness) | 画圆 |
void add_circle_filled([vec2] centre, number radius, [vec4] color, number seg) | 填充圆 |
void add_text([font] font,number size, [vec2] pos, [vec4] color, string text) | 绘制文字 |
void add_image([image] image, [vec2] a, [vec2] b) | 绘制图片 |