imgui 运行时面板
imgui 运行时面板
imgui 是 ScriptX 当前版本提供的即时调试面板 API。它把原生 Dear ImGui、ImPlot、响应式数据和 Android 悬浮承载整合到同一个 JavaScript 对象中,适合制作调试器、状态检查器、参数面板、实时曲线和逆向分析辅助界面。
本页只描述当前 imgui-v2 运行时实际提供的接口。面板采用两种互补的写法:
- 保留式节点:使用
imgui.window()创建窗口,再用panel.text()、panel.inputText()、panel.table()等节点 API 构建界面。节点会保留在窗口模型中,适合输入框、列表、响应式状态和复杂界面。 - 即时帧:使用
panel.onFrame()注册每帧回调,再通过回调参数frame直接调用 ImGui 绘制和查询函数。它适合高频绘制、临时查询和需要严格控制 Begin/End 配对的场景。
两种写法可以在同一个窗口中同时使用,但用途不同:输入文本必须使用保留式 panel.inputText(),因为 Android 输入法需要一个持续存在的输入节点;即时帧中不能创建窗口、加载纹理或等待异步任务。
最小可运行示例
const state = imgui.reactive({
enabled: true,
name: "ScriptX",
progress: 0.35
});
const panel = imgui.window("hello", {
title: "ScriptX 调试面板",
width: 560,
height: 640,
displayMode: "in_app",
onClose: function () {
log("面板被关闭");
}
});
panel.text("这是一个保留式 ImGui 窗口", { color: "#80d8ff" });
panel.checkbox("启用功能", imgui.bind(state, "enabled"));
panel.inputText("名称", imgui.bind(state, "name"), { hint: "输入名称" });
panel.sliderFloat("进度", imgui.bind(state, "progress"), { min: 0, max: 1 });
panel.button("打印当前状态", function () {
log(JSON.stringify({
enabled: state.enabled,
name: state.name,
progress: state.progress
}));
});
panel.show();
使用前必须知道
- 窗口
id必须是非空字符串,同一运行时中不能重复创建同一个id。 imgui.window()创建后会立即返回面板对象;调用panel.show()才会请求显示。- 大多数节点方法返回新建的节点,窗口方法如
configure()、appearance()、captureKeyboard()返回窗口本身,便于继续调用。 - 节点属性可以是普通值、函数或
imgui.bind()产生的绑定对象。函数属性会在响应式计算时重新读取。 - 所有传入属性中的数字都必须是有限数字,不能传
NaN或Infinity。 - 节点的
id只在当前窗口内查找,且必须唯一;它不是 Android 控件 id,而是 ScriptX 节点的稳定名称。 - 窗口、纹理和字体的生命周期操作要在
onFrame外执行。 - 节点树最大嵌套深度为 64,单窗口节点数量建议控制在 100,000 以内。
imgui.version
const version = imgui.version;
log(version); // 2
返回当前 JavaScript ImGui 运行时版本号。当前版本为数字 2,它表示 imgui-v2 的节点模型和即时帧模型。
imgui.window(id, options?, build?)
创建一个新的 ImGui 窗口。
参数
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
id | string | 是 | 窗口实例 id,不能为空;同一运行时中不能重复。 |
options | object | 否 | 初始窗口配置。 |
build | function(panel) | 否 | 创建后立即执行的构建函数。 |
返回值
返回 panel 窗口对象。创建失败或 id 已经存在时会抛出异常。
直接构建
const panel = imgui.window("counter", {
title: "计数器",
width: 420,
height: 260
}, function (p) {
p.text("窗口已经创建");
p.button("关闭", function () {
p.close();
});
});
panel.show();
build 只是创建阶段的便利写法。后续仍然可以使用 panel.build() 增加节点。
imgui.getWindow(id)
按 id 获取已经创建的窗口。
const panel = imgui.getWindow("counter");
if (panel) {
log(panel.isShown());
}
找不到时返回 null,不会创建新窗口。窗口被 destroy() 后,再次查询也会返回 null。
imgui.closeAll()
请求关闭当前运行时创建的所有窗口。它只负责隐藏窗口和结束显示任务,保留式节点对象仍然属于对应的窗口模型。
imgui.closeAll();
这个方法不接收参数,也没有有用的返回值。需要彻底释放窗口及其节点时使用 imgui.destroyAll()。
imgui.destroyAll()
销毁当前运行时创建的所有窗口。
imgui.destroyAll();
销毁会递归释放节点、响应式 effect、输入状态和原生窗口资源。销毁后不能继续使用原来的 panel 或节点对象。
imgui.closeAll() 与 imgui.destroyAll() 的选择
| 需求 | 使用 |
|---|---|
| 暂时隐藏,之后还要再次显示 | imgui.closeAll() 或 panel.close() |
| 脚本结束前释放全部窗口 | imgui.destroyAll() |
| 只处理一个窗口 | panel.close() 或 panel.destroy() |
const panel = imgui.window("one");
panel.text("内容");
panel.show();
panel.close(); // 可以再次 panel.show()
panel.destroy(); // 之后不能再次使用 panel
panel.configure(options)
增量修改窗口配置。只传需要改变的字段,未传字段保持原值。
panel.configure({
title: "新的标题",
width: 720,
height: 480,
x: 32,
y: 96,
alpha: 0.92,
resizable: false
});
返回当前 panel。
窗口配置字段
| 字段 | 类型 | 默认值 | 可接受值与说明 |
|---|---|---|---|
title | string | 窗口 id | 标题栏文字。 |
width | number | 360dp | 窗口宽度;会结合最小、最大尺寸约束。 |
height | number | 520dp | 窗口高度;会结合最小、最大尺寸约束。 |
minWidth | number | 200 | 最小宽度,至少为 1。 |
minHeight | number | 120 | 最小高度,至少为 1。 |
maxWidth | number | 0 | 最大宽度;0 表示不设置上限。 |
maxHeight | number | 0 | 最大高度;0 表示不设置上限。 |
x | number | 20dp | 窗口初始横坐标。 |
y | number | 80dp | 窗口初始纵坐标。 |
alpha | number | 1 | 透明度范围 0.2..1.0。数值越小越透明。 |
theme | string | imgui_dark | 必须是 imgui.themes() 返回的主题名。 |
fontScale | number | 1.4 | 字体缩放范围 1.0..3.2。 |
uiScale | number | 1.14 | 控件缩放范围 0.85..2.4。 |
closable | boolean | true | 是否允许通过窗口关闭动作关闭。 |
collapsible | boolean | true | 是否显示窗口的收起能力。 |
collapsed | boolean | 未指定 | 请求窗口当前是否收起。它是一个显式状态请求,不是默认主题设置。 |
resizable | boolean | true | 是否允许用户调整窗口大小。 |
secure | boolean | false | 是否使用安全窗口标志,减少内容被系统截取的机会。 |
touchPassthrough | boolean | false | 是否允许触摸事件穿过面板;需要配合承载模式和系统权限。 |
displayMode | string | in_app | 只能按当前规范使用 in_app、system_overlay、accessibility_overlay。 |
flags | number | 0 | imgui.WindowFlags 的按位组合。 |
onClose | function | 无 | 用户关闭窗口时调用;可在回调中执行清理。 |
尺寸约束的处理
minWidth、minHeight 至少为 1;maxWidth、maxHeight 为 0 时表示没有上限。设置上限小于当前下限时,运行时会调整约束使两者保持有效,并重新限制当前窗口尺寸。
panel.configure({
minWidth: 280,
minHeight: 180,
maxWidth: 900,
maxHeight: 720
});
响应式配置
配置值也可以使用函数或绑定对象。当依赖的响应式数据变化时,窗口配置会自动下发。
const state = imgui.reactive({ compact: false });
panel.configure({
width: function () { return state.compact ? 360 : 720; },
height: function () { return state.compact ? 260 : 520; }
});
panel.build(fn)
在窗口或任意节点下执行一段构建函数。
panel.build(function (p) {
p.text("第一行");
p.text("第二行");
});
参数 fn(scope) 必须是函数,scope 就是当前面板或节点。返回当前调用对象。
panel.find(id)
按节点的稳定 id 查找当前窗口中的节点。
const runButton = panel.button("运行", { id: "run-button" });
const sameNode = panel.find("run-button");
log(runButton === sameNode); // true
找不到时返回 null。只能查找当前窗口中的存活节点,不能传另一个窗口的节点名称。
panel.show()
请求显示窗口。
const shown = panel.show();
log(shown); // true 表示宿主接受了显示请求
返回布尔值。in_app 模式需要当前 Activity 的窗口 token;system_overlay 需要悬浮窗权限;accessibility_overlay 需要已启用无障碍服务。权限不足时显示可能返回 false 或抛出宿主异常。
panel.close()
关闭当前窗口,但不销毁窗口对象。
panel.close();
if (!panel.isShown()) {
log("面板已隐藏");
}
返回宿主关闭操作的布尔结果。关闭后仍可调用 panel.show()。
panel.isShown()
查询当前窗口是否处于显示状态。
if (panel.isShown()) {
log("正在显示");
}
返回 boolean。
panel.destroy()
销毁窗口以及窗口下的所有节点、effect、输入状态和原生资源。
panel.destroy();
log(imgui.getWindow("hello")); // null
销毁是终态操作。销毁后的窗口和节点不能再次 update()、on()、show() 或增加子节点。
panel.openPopup(nodeOrId)
打开当前窗口中由 popup、modal 或 contextMenu 节点定义的弹出容器。
const popup = panel.popup({ id: "info-popup", label: "info" }, function (p) {
p.text("这是一个弹出层");
});
panel.button("打开", function () {
panel.openPopup(popup);
});
参数可以是节点对象,也可以是节点的字符串 id。节点必须属于当前窗口并且仍然存活。返回当前 panel。
panel.closePopup(nodeOrId)
请求关闭指定弹出容器。
panel.closePopup("info-popup");
参数规则与 panel.openPopup() 相同。关闭动作会在后续 ImGui 帧执行。
panel.focus(nodeOrId)
请求将键盘焦点移动到指定节点。
const input = panel.inputText("搜索", imgui.bind({ value: "" }), {
id: "search-input"
});
panel.button("聚焦搜索框", function () {
panel.focus(input);
});
通常用于 inputText 或其他可接受键盘焦点的控件。参数可以是节点或当前窗口中的节点 id。
panel.stats()
读取当前窗口节点程序的统计信息。
const stats = panel.stats();
log(JSON.stringify(stats));
返回一个 JavaScript 对象,包含当前节点数量、待处理数据和运行时统计字段。统计对象适合日志和调试,不应当作为稳定业务结构进行持久化。
panel.captureKeyboard(enabled?)
设置当前窗口是否捕获键盘输入。
panel.captureKeyboard(); // 开启
panel.captureKeyboard(true); // 开启
panel.captureKeyboard(false); // 关闭
省略参数或传 true 表示开启,传 false 表示关闭。这个设置只影响键盘输入捕获,不会自动创建输入框。
imgui.reactive(value)
把普通对象或数组包装为响应式对象。读取属性会建立依赖,写入属性会触发依赖它的节点、配置或 effect 更新。
const state = imgui.reactive({
count: 0,
tags: ["hook"]
});
panel.text(function () {
return "数量: " + state.count;
});
panel.button("增加", function () {
state.count += 1;
state.tags.push("item-" + state.count);
});
数组的 push、pop、shift、unshift、splice、sort、reverse、fill 和 copyWithin 会在一次批处理中触发更新。
imgui.signal(value)
创建一个带有响应式 value 属性的对象。
const visible = imgui.signal(true);
panel.when(function () { return visible.value; }, function (p) {
p.text("当前可见");
});
visible.value = false;
返回形如 { value: ... } 的响应式对象。修改 signal.value 会让读取过它的节点重新计算。
imgui.computed(fn)
创建一个只读计算值。
const state = imgui.reactive({ current: 3, total: 10 });
const ratio = imgui.computed(function () {
return state.total === 0 ? 0 : state.current / state.total;
});
panel.progressBar(function () { return ratio.value; });
state.current = 8;
ratio.dispose();
返回对象包含:
| 成员 | 说明 |
|---|---|
value | 当前计算结果,只能通过依赖变化间接更新。 |
dispose() | 停止计算并释放依赖。 |
imgui.bind(target, key?)
创建一个可读写绑定,让控件的 value 与对象属性保持同步。
const state = imgui.reactive({ enabled: false, title: "" });
panel.checkbox("启用", imgui.bind(state, "enabled"));
panel.inputText("标题", imgui.bind(state, "title"));
只传一个参数时,默认绑定目标的 value 属性:
const count = imgui.signal(0);
panel.inputInt("数量", imgui.bind(count));
第一个参数也可以是返回对象的函数,适合把绑定目标动态切换到某个响应式对象:
let active = imgui.reactive({ value: 1 });
panel.inputInt("当前值", imgui.bind(function () { return active; }));
控件改变时会调用绑定对象的写入逻辑;只读 getter 不适合直接绑定到可编辑控件。
imgui.effect(fn)
创建一个独立的响应式副作用。
const state = imgui.reactive({ enabled: true });
const stop = imgui.effect(function () {
log("enabled = " + state.enabled);
return function () {
log("上一次 effect 的清理函数");
};
});
state.enabled = false;
stop();
fn 每次运行时读取到的响应式属性会成为依赖。如果函数返回另一个函数,下一次运行前和停止时都会执行这个清理函数。
imgui.batch(fn)
把多次响应式写入合并为一批,函数结束后统一刷新。
imgui.batch(function () {
state.current = 5;
state.total = 12;
state.enabled = true;
});
返回 fn 的返回值。构建复杂面板或一次修改多个字段时建议使用它,可以减少中间状态刷新。
imgui.flush()
立即处理当前已排队的响应式更新和节点补丁。
state.count += 1;
imgui.flush();
通常不需要手动调用;只有在需要在同一段脚本中确保节点补丁已经提交后,再读取统计或执行窗口动作时才使用。
node.update(properties)
增量修改节点属性。属性会合并到节点当前属性中,已经存在的属性会被覆盖,未传入的属性保持不变。
const status = panel.text("等待", { id: "status" });
status.update({
text: "已完成",
color: "#67e8a5"
});
返回当前节点。属性值可以是普通值、函数或 imgui.bind() 绑定对象:
const state = imgui.reactive({ online: false });
status.update({
text: function () { return state.online ? "在线" : "离线"; },
disabled: function () { return !state.online; }
});
节点已经被删除后调用会抛出异常。plotStream 创建后,capacity、x、y、values 等流数据字段不能通过 update() 修改,应该使用它自己的数据方法。
node.on(event, callback)
注册或删除节点事件。
const button = panel.button("执行", { id: "run" });
button.on("click", function () {
log("按钮被点击");
});
button.on("click", null); // 删除 click 监听
事件名会转为小写。当前实现支持这些事件:
| 事件 | 回调参数 | 触发时机 |
|---|---|---|
click | (value, node) | 按钮、链接、颜色按钮等被点击。 |
change | (value, node) | 输入值、选择值或拖动值发生变化。 |
mouseenter | (value, node) | 鼠标或指针进入控件区域。 |
mouseleave | (value, node) | 鼠标或指针离开控件区域。 |
editend | (value, node) | 输入编辑结束。 |
close | (value, node) | 可关闭页签、弹窗或停靠窗口被关闭。 |
sort | (specs, node) | 表格排序状态改变。 |
drop | (payload, node) | 拖放数据交付到目标。 |
limits | (limits, node) | 图表显示范围改变。 |
plotclick | ([x, y], node) | 在图表区域单击。 |
range | ([first, last], node) | 虚拟列表当前需要的行范围改变。 |
error | (error, node) | 节点运行期间发生错误时使用。 |
也可以在创建节点时使用 onClick、onChange 这类属性:
panel.checkbox("启用", imgui.bind(state, "enabled"), {
onChange: function (value) {
log("新的值: " + value);
}
});
node.remove()
删除节点及其所有子节点、effect 和事件监听。
const temporary = panel.text("临时提示", { id: "temporary" });
temporary.remove();
log(panel.find("temporary")); // null
删除是递归操作,删除后节点对象不可再使用。这个方法没有有用的返回值。
node.moveBefore(other)
把当前节点移动到同一父节点的另一个存活兄弟节点之前。
const first = panel.text("第一项", { id: "first" });
const second = panel.text("第二项", { id: "second" });
second.moveBefore(first);
两个节点必须属于同一个父节点,不能是同一个节点,也不能已经删除。返回移动后的当前节点。
node.build(fn)
在当前节点下继续创建子节点。
const group = panel.group({ id: "details" });
group.build(function (p) {
p.text("详情");
p.button("刷新");
});
返回当前节点。
node.effect(fn)
创建归属于当前节点的响应式 effect。节点删除时,effect 会一并释放。
const group = panel.group();
group.effect(function () {
log("当前模式: " + state.mode);
});
返回停止函数。回调返回的清理函数会在下一次执行和停止时调用。
node.component(build, props?)
把一段可复用构建函数作为组件插入当前节点下。
function KeyValue(scope, props) {
scope.text(props.name + ": " + props.value);
}
panel.component(KeyValue, { name: "进程", value: "main" });
build(scope, props) 必须是函数。返回新建的 fragment 节点,props 省略时使用空对象。
node.node(op, properties?, build?)
按字符串创建当前运行时支持的组件。它是所有快捷方法的底层入口。
panel.node("text", { text: "底层调用", color: "#fff" });
panel.node("group", { id: "group" }, function (group) {
group.text("组内内容");
});
op 必须是当前运行时的控件或容器名称,否则抛出异常。日常代码优先使用具体快捷方法,这个方法适合动态生成组件。
node.when(condition, yes, no?)
根据条件动态保留两套子树中的一套。
panel.when(function () {
return state.enabled;
}, function (p) {
p.text("功能已启用");
p.button("执行");
}, function (p) {
p.text("功能未启用", { disabled: true });
});
condition 可以是布尔值、函数或响应式绑定。条件从真变假时,当前分支子树会被移除,另一分支重新创建;因此不要把需要跨分支保存的节点引用当成永久对象。
node.each(source, key, build, options?)
把数组渲染为一组可增量更新的子树。
const state = imgui.reactive({
users: [
{ id: 1, name: "Alice" },
{ id: 2, name: "Bob" }
]
});
panel.each(function () { return state.users; }, "id", function (row, item, index) {
row.text(function () {
return index.value + ": " + item.value.name;
});
});
参数说明:
| 参数 | 说明 |
|---|---|
source | 数组或返回数组的函数。 |
key | 字符串属性名,或 (item, index) => key 函数;每行 key 必须是唯一字符串或数字。 |
build | (scope, itemSignal, indexSignal) => void。行首次创建时调用。 |
options.clip | 为 true 时使用裁剪列表容器。 |
options.itemHeight | 裁剪列表的固定行高。 |
每一行的 item 和 index 都是带 value 属性的响应式 signal。数组增删或排序时,运行时尽量复用 key 相同的行节点。
node.virtualList(source, key, build, options?)
渲染大数组的可视区域,只有当前可见行和少量预加载行会创建节点。
const rows = Array.from({ length: 10000 }, function (_, index) {
return { id: index, text: "第 " + index + " 行" };
});
const list = panel.virtualList(rows, "id", function (row, item, index) {
row.text(function () {
return index.value + " - " + item.value.text;
});
}, {
height: 360,
itemHeight: 32,
overscan: 4
});
参数和限制
| 参数 | 类型 | 说明 |
|---|---|---|
source | array 或函数 | 必须返回数组,最多 1,000,000 行。 |
key | 字符串、函数或省略 | 可见行 key 必须唯一且为字符串或数字。省略时使用数组索引。 |
build | 函数 | (scope, itemSignal, indexSignal)。 |
height | number | 列表视口高度,默认约 320。 |
width | number | 列表宽度,未设置时交给 ImGui 布局。 |
itemHeight | number 或函数 | 固定行高,或 (item, index) => height。范围 1..4096。 |
estimatedItemHeight | number | 使用动态行高时的初始估算值,范围 1..4096。 |
overscan | number | 视口上下额外创建的行数,范围 0..100,默认 3。 |
heightRevision | 任意响应式值 | 动态行高的显式版本号。变化时重新计算全部行高。 |
scrollTo | number | 要滚动到的数组索引。 |
scrollRevision | number | 每次需要重新执行 scrollTo 时递增。 |
可变行高列表的总高度最多 16,000,000 像素。range 事件会报告当前渲染范围 [first, last],其中 last 是不包含在范围内的结束索引。
list.invalidateHeights(indices)
动态行高模式下,重新计算指定数组索引的行高。
list.invalidateHeights([2, 8, 15]);
只有传入 heightRevision 的列表才支持该方法。indices 必须是数组,元素是合法的数组索引;传入 key 而不是数组索引会报错。返回列表节点本身。
list.heightStats()
读取动态行高列表的高度统计。
const stats = list.heightStats();
log(stats.count); // 行数
log(stats.totalHeight); // 总高度
返回 { count, totalHeight }。如果传入 index 的底层数据查询,还可以取得单行高度和该行顶部位置;日常脚本通常直接使用这两个汇总字段。
panel.text(text, options?)
显示一段不可编辑文本。
panel.text("普通文字");
panel.text("重要提示", {
id: "notice",
color: "#ffcc66",
wrapped: true,
bullet: true,
disabled: false
});
text 可以是字符串、数字或函数。常用属性:
| 属性 | 类型 | 说明 |
|---|---|---|
text | 字符串或函数 | 文本内容;panel.text() 的第一个参数会写入此字段。 |
color | 颜色 | 支持 #RRGGBB、#AARRGGBB 或 0..1 的 RGB/RGBA 数组。 |
wrapped | boolean | true 时按可用宽度换行。 |
bullet | boolean | true 时在文本前绘制项目符号。 |
disabled | boolean | true 时使用禁用文本颜色。 |
文本使用非格式化输出,%s 不会被当成格式占位符。
panel.button(label, click?, options?)
创建按钮。
panel.button("运行", function () {
log("运行按钮被点击");
}, {
id: "run",
width: 180,
height: 44
});
panel.button("小按钮", { small: true });
第二个参数可以是点击函数,也可以直接传 options 对象。width、height 默认由 ImGui 布局决定,small: true 使用紧凑按钮。点击事件通过 onClick 或 .on("click", fn) 注册。
panel.progressBar(value, options?)
绘制进度条。
panel.progressBar(function () { return state.progress; }, {
width: 260,
height: 22,
overlay: function () {
return Math.round(state.progress * 100) + "%";
}
});
value 会被限制到 0..1:0 是空,1 是满。overlay 是覆盖在进度条上的文字。
panel.plotLines(label, values, options?)
绘制 ImGui 内置折线图。
panel.plotLines("CPU", [0.2, 0.4, 0.35, 0.8], {
width: 360,
height: 100,
min: 0,
max: 1,
overlay: "CPU"
});
values 必须是有限数字数组。width、height、min、max 和 overlay 都可以使用属性函数。
panel.plotHistogram(label, values, options?)
绘制 ImGui 内置直方图。
panel.plotHistogram("请求耗时", [12, 18, 20, 15, 42, 30], {
width: 360,
height: 100,
overlay: "ms"
});
参数形式与 panel.plotLines() 相同,但显示方式是柱状直方图。
panel.image(texture, options?)
显示由 imgui.texture() 加载的纹理。
const texture = imgui.texture("/sdcard/Download/screenshot.png");
panel.image(texture, {
width: 240,
height: 160,
tint: "#ffffff",
background: "#202020"
});
第一个参数必须是纹理对象。尺寸默认为 100 x 100,uv0 和 uv1 可以用 [u, v] 指定采样区域。
panel.imageButton(label, texture, click?, options?)
把纹理绘制成可点击按钮。
panel.imageButton("刷新图标", texture, function () {
log("图标按钮被点击");
}, {
width: 48,
height: 48,
tint: "#ffffff"
});
点击回调可省略,选项中的 background、tint、uv0、uv1 与 panel.image() 相同。
panel.separator(properties?)
绘制水平分隔线。
panel.separator();
它是普通节点方法,通常不需要额外属性。
panel.separatorText(properties?)
绘制带有文字的分隔线。
panel.separatorText({ text: "网络状态" });
文字放在分隔线中间,用 text 属性提供内容。
panel.spacing(properties?)
插入一个或多个默认间距。
panel.spacing({ count: 2 });
count 会限制在 0..100,默认 1。
panel.sameLine(properties?)
把下一个节点放在当前行。
panel.text("地址");
panel.sameLine({ spacing: 12 });
panel.text("127.0.0.1");
| 属性 | 说明 |
|---|---|
offset | 从行起点开始的横向偏移。 |
spacing | 与前一个控件的间距;省略时由 ImGui 决定。 |
panel.newLine(properties?)
结束当前行并移动到下一行。
panel.text("第一列");
panel.newLine();
panel.text("第二行");
panel.dummy(properties?)
插入一个占据布局空间但不绘制内容的矩形。
panel.dummy({ width: 240, height: 16 });
width 和 height 使用当前 ImGui 坐标单位。
panel.cursorPos(properties?)
设置当前布局光标位置。
panel.cursorPos({ position: [20, 80] });
// 也可以使用:
panel.cursorPos({ x: 20, y: 80 });
panel.itemWidth(properties?)
设置后续输入控件的默认宽度。
panel.itemWidth({ width: 220 });
panel.inputText("地址", imgui.bind(state, "url"));
panel.indent(properties?)
增加后续内容的缩进。
panel.indent({ width: 18 });
panel.text("缩进内容");
panel.unindent({ width: 18 });
panel.unindent(properties?)
减少后续内容的缩进。width 省略时使用 ImGui 默认缩进宽度。
panel.menuItem(properties?)
在菜单容器中创建菜单项。
panel.menu({ label: "文件" }, function (menu) {
menu.menuItem({
label: "保存",
shortcut: "Ctrl+S",
selected: false,
enabled: true,
onClick: function () { log("保存"); }
});
});
shortcut 只是显示给用户的文字;真正是否选中由 selected 控制,enabled: false 时不可点击。
panel.labelText(label, properties?)
显示带标签的文本行。
panel.labelText({ label: "包名", text: lpparam.packageName });
label 是左侧标签,text 是右侧值。
panel.bullet(properties?)
绘制一个项目符号。
panel.bullet();
panel.sameLine();
panel.text("一项说明");
panel.textLink(label, properties?)
绘制类似链接的文本,点击时触发 click 事件。
panel.textLink({
label: "打开日志",
onClick: function () { log("打开日志"); }
});
panel.tabItemButton(label, properties?)
在 tabs 容器的页签栏中绘制一个按钮。
panel.tabs(function (tabs) {
tabs.tab({ label: "主页" }, function (tab) {
tab.text("内容");
});
tabs.tabItemButton({
label: "+",
onClick: function () { log("新建页签"); }
});
});
panel.alignTextToFramePadding(properties?)
调整当前文字基线,使文字与带框控件的内边距对齐。
panel.alignTextToFramePadding();
panel.text("与输入框对齐");
可编辑控件的共同规则
下面的控件都采用类似的签名:
panel.apiName(label, value, options);
label是显示文字,也是控件的默认 ImGui 标签。value是初始值、普通值、函数或imgui.bind()绑定对象。options是当前控件的额外选项。- 需要在脚本中持续取得用户输入时,优先使用
imgui.bind(state, "字段名")。 - 控件发生改变时会触发
change,回调的第一个参数是当前值,第二个参数是节点。
示例:
const state = imgui.reactive({
enabled: false,
count: 1,
name: "demo"
});
panel.checkbox("启用", imgui.bind(state, "enabled"), {
onChange: function (value) { log(value); }
});
panel.inputInt("次数", imgui.bind(state, "count"));
panel.inputText("名称", imgui.bind(state, "name"));
panel.checkbox(label, value, options?)
创建复选框,值为 boolean。
panel.checkbox("记录日志", imgui.bind(state, "logging"), {
id: "logging",
onChange: function (value) {
log("logging = " + value);
}
});
传入的值会按布尔值处理。需要双向改变脚本状态时使用绑定对象;只传 true 或 false 时,控件仍能显示和交互,但脚本没有一个自动更新的外部变量。
panel.selectable(label, value, options?)
创建可选中的一行,值为 boolean。
panel.selectable("选中这条记录", imgui.bind(state, "selected"), {
width: 260,
height: 32,
flags: imgui.SelectableFlags.AllowDoubleClick
});
width、height 控制区域大小,flags 使用 imgui.SelectableFlags 的组合值。
panel.inputText(label, value, options?)
创建单行或多行文本输入框,值为 string。
const form = imgui.reactive({
keyword: "",
password: ""
});
panel.inputText("关键词", imgui.bind(form, "keyword"), {
hint: "输入要搜索的内容",
width: 300,
submitOnEnter: true,
onChange: function (value) {
log("关键词: " + value);
}
});
panel.inputText("密码", imgui.bind(form, "password"), {
password: true,
hint: "不会显示明文"
});
常用选项:
| 选项 | 类型 | 说明 |
|---|---|---|
hint | string | 内容为空时显示的提示。 |
password | boolean | 以密码样式显示。 |
multiline | boolean | 启用多行编辑。 |
decimal | boolean | 输入法提示使用小数输入。 |
readOnly | boolean | 只读显示,不允许编辑。 |
submitOnEnter | boolean | 回车提交;默认开启。 |
inputFlags | number | 直接传入 imgui.InputTextFlags 的按位组合。 |
itemWidth | number | 当前控件宽度。 |
这是需要 Android 输入法状态的保留式控件。即时帧回调中不要用 frame.inputText(),文本输入必须使用当前 API 和 imgui.bind()。
panel.inputInt(label, value, options?)
创建整数输入框。
panel.inputInt("重试次数", imgui.bind(state, "retries"), {
step: 1,
stepFast: 10,
flags: imgui.InputTextFlags.None
});
| 选项 | 默认值 | 说明 |
|---|---|---|
step | 1 | 点击小箭头时的增量。 |
stepFast | 100 | 快速调整时的增量。 |
flags | 0 | 输入文本标志,使用 InputTextFlags。 |
itemWidth | 由布局决定 | 控件宽度。 |
值按 32 位有符号整数处理。
panel.inputFloat(label, value, options?)
创建浮点数输入框。
panel.inputFloat("阈值", imgui.bind(state, "threshold"), {
step: 0.1,
stepFast: 1,
flags: 0
});
step 和 stepFast 默认由 ImGui 处理,显示格式固定为 %.3f。值必须是有限数字。
panel.inputDouble(label, value, options?)
创建双精度浮点输入框。
panel.inputDouble("精确比例", imgui.bind(state, "ratio"), {
step: 0.001,
stepFast: 0.01
});
显示格式为 %.6f。value 是 JavaScript 数字,仍然必须是有限值。
panel.sliderInt(label, value, options?)
创建整数滑块。
panel.sliderInt("并发数", imgui.bind(state, "workers"), {
min: 1,
max: 32,
flags: imgui.SliderFlags.ClampOnInput
});
min 默认 0,max 默认 100。如果 max < min,运行时会交换两者。值会限制在有效区间内。
panel.sliderFloat(label, value, options?)
创建浮点滑块。
panel.sliderFloat("透明度", imgui.bind(state, "alpha"), {
min: 0,
max: 1,
flags: imgui.SliderFlags.AlwaysClamp
});
min 默认 0,max 默认 1,显示格式为 %.3f。适合比例、透明度等连续值。
panel.sliderAngle(label, value, options?)
创建角度滑块。
panel.sliderAngle("旋转角度", imgui.bind(state, "rotation"), {
min: -180,
max: 180
});
这个 API 的绑定值使用弧度,但 min、max 和界面文字使用度数。默认范围为 -360..360 度。
state.rotation = Math.PI / 2; // 90 度
panel.vSliderInt(label, value, options?)
创建竖直整数滑块。
panel.vSliderInt("音量", imgui.bind(state, "volume"), {
width: 36,
height: 180,
min: 0,
max: 100
});
width 和 height 会被限制为至少 1。整数边界规则与 sliderInt 相同。
panel.vSliderFloat(label, value, options?)
创建竖直浮点滑块。
panel.vSliderFloat("增益", imgui.bind(state, "gain"), {
width: 36,
height: 180,
min: 0,
max: 2
});
浮点边界规则与 sliderFloat 相同,显示格式为 %.3f。
panel.dragInt(label, value, options?)
创建可以横向拖动调整的整数控件。
panel.dragInt("偏移", imgui.bind(state, "offset"), {
speed: 1,
min: -100,
max: 100
});
speed 默认 1,min 默认 0,max 默认 100。拖动值会受到 min/max 限制。
panel.dragFloat(label, value, options?)
创建可以横向拖动调整的浮点控件。
panel.dragFloat("比例", imgui.bind(state, "scale"), {
speed: 0.05,
min: 0,
max: 10
});
speed 默认 0.1,min 默认 0,max 默认 1,显示格式为 %.3f。
向量控件的共同规则
向量控件的绑定值必须是指定长度的数组。数组长度由方法名最后的数字决定:2、3 或 4。
const vector = imgui.reactive({
position: [10, 20],
color: [0.2, 0.5, 1, 1]
});
panel.inputInt2("位置", imgui.bind(vector, "position"));
panel.inputFloat4("颜色", imgui.bind(vector, "color"));
向量值长度不正确时会被拒绝。整数向量控件按 32 位整数处理,浮点向量控件按 float 处理。
panel.inputInt2(label, value, options?)
编辑 [x, y] 形式的两个整数。
panel.inputInt2("坐标", imgui.bind(vector, "position"));
panel.inputInt3(label, value, options?)
编辑长度为 3 的整数数组,例如 [x, y, z]。
panel.inputInt3("三维坐标", imgui.bind(vector, "position3"));
panel.inputInt4(label, value, options?)
编辑长度为 4 的整数数组。
panel.inputInt4("矩形", imgui.bind(vector, "rect"));
panel.inputFloat2(label, value, options?)
编辑长度为 2 的浮点数组。
panel.inputFloat2("UV", imgui.bind(vector, "uv"));
panel.inputFloat3(label, value, options?)
编辑长度为 3 的浮点数组。
panel.inputFloat3("方向", imgui.bind(vector, "direction"));
panel.inputFloat4(label, value, options?)
编辑长度为 4 的浮点数组。
panel.inputFloat4("RGBA", imgui.bind(vector, "color"));
panel.sliderInt2(label, value, options?)
在同一行编辑两个整数滑块。min 默认 0,max 默认 100。
panel.sliderInt2("范围", imgui.bind(vector, "intRange"), {
min: 0,
max: 100
});
panel.sliderInt3(label, value, options?)
编辑长度为 3 的整数滑块数组。
panel.sliderInt3("RGB 整数", imgui.bind(vector, "rgb"), {
min: 0,
max: 255
});
panel.sliderInt4(label, value, options?)
编辑长度为 4 的整数滑块数组。
panel.sliderInt4("矩形参数", imgui.bind(vector, "int4"), {
min: -100,
max: 100
});
panel.sliderFloat2(label, value, options?)
编辑长度为 2 的浮点滑块数组。
panel.sliderFloat2("范围", imgui.bind(vector, "float2"), {
min: 0,
max: 1
});
panel.sliderFloat3(label, value, options?)
编辑长度为 3 的浮点滑块数组。
panel.sliderFloat3("位置", imgui.bind(vector, "position3"), {
min: -1,
max: 1
});
panel.sliderFloat4(label, value, options?)
编辑长度为 4 的浮点滑块数组。
panel.sliderFloat4("颜色", imgui.bind(vector, "color"), {
min: 0,
max: 1
});
panel.dragInt2(label, value, options?)
拖动编辑两个整数。speed 默认 1,默认范围为 0..100。
panel.dragInt2("坐标", imgui.bind(vector, "position"), {
speed: 1,
min: -500,
max: 500
});
panel.dragInt3(label, value, options?)
拖动编辑三个整数。
panel.dragInt3("三维坐标", imgui.bind(vector, "position3"), {
speed: 1,
min: -100,
max: 100
});
panel.dragInt4(label, value, options?)
拖动编辑四个整数。
panel.dragInt4("四维参数", imgui.bind(vector, "int4"), {
speed: 1,
min: 0,
max: 100
});
panel.dragFloat2(label, value, options?)
拖动编辑两个浮点数。speed 默认 0.1,默认范围为 0..1。
panel.dragFloat2("UV", imgui.bind(vector, "uv"), {
speed: 0.01,
min: 0,
max: 1
});
panel.dragFloat3(label, value, options?)
拖动编辑三个浮点数。
panel.dragFloat3("方向", imgui.bind(vector, "direction"), {
speed: 0.01,
min: -1,
max: 1
});
panel.dragFloat4(label, value, options?)
拖动编辑四个浮点数。
panel.dragFloat4("RGBA", imgui.bind(vector, "color"), {
speed: 0.01,
min: 0,
max: 1
});
panel.dragIntRange2(label, value, options?)
编辑两个整数组成的范围,绑定值格式为 [low, high]。
const range = imgui.reactive({ value: [20, 80] });
panel.dragIntRange2("整数范围", imgui.bind(range), {
speed: 1,
min: 0,
max: 100
});
如果初始低值大于高值,运行时会先交换两者。min 和 max 必须提供有效整数边界。
panel.dragFloatRange2(label, value, options?)
编辑两个浮点数组成的范围,绑定值格式为 [low, high]。
const range = imgui.reactive({ value: [0.25, 0.75] });
panel.dragFloatRange2("浮点范围", imgui.bind(range), {
speed: 0.01,
min: 0,
max: 1
});
speed 默认 0.1,边界需要通过 min 和 max 指定。
panel.combo(label, value, options?)
创建下拉选择框。值是从 0 开始的整数下标,不是选项文本。
const state = imgui.reactive({ mode: 0 });
const items = ["自动", "手动", "暂停"];
panel.combo("模式", imgui.bind(state, "mode"), {
items: items,
flags: imgui.ComboFlags.HeightRegular,
onChange: function (index) {
log("选择了: " + items[index]);
}
});
items 必须是字符串数组。flags 可以使用 ComboFlags,例如 HeightSmall、HeightRegular、HeightLarge、HeightLargest、NoArrowButton、NoPreview。
panel.listBox(label, value, options?)
创建带列表区域的选择框。
panel.listBox("目标进程", imgui.bind(state, "process"), {
items: ["主进程", "远程进程", "全部进程"],
heightInItems: 4
});
值仍然是 items 的下标。heightInItems 是可见行数,省略时由 ImGui 决定。
panel.radio(label, value, options?)
创建一组单选按钮。
panel.radio("输出格式", imgui.bind(state, "format"), {
items: ["文本", "JSON", "表格"],
horizontal: true
});
items 是字符串数组,绑定值是选中项下标。horizontal: true 会把多个按钮放在同一行。
panel.radioButton(label, value, options?)
创建一个带有自定义值的单选按钮。
panel.radioButton("自动刷新", imgui.bind(state, "refreshMode"), {
buttonValue: 1
});
点击时会把绑定值设置为 buttonValue。它和 panel.radio() 的区别是:这里一次只创建一个按钮,多个按钮需要手动分别提供不同的 buttonValue。
panel.checkboxFlags(label, value, options?)
用整数的位掩码表示多个布尔选项。
const permissions = imgui.reactive({ value: 0 });
panel.checkboxFlags("读取", imgui.bind(permissions), { mask: 1 });
panel.checkboxFlags("写入", imgui.bind(permissions), { mask: 2 });
panel.checkboxFlags("执行", imgui.bind(permissions), { mask: 4 });
value 是整数,mask 是要操作的位掩码,默认 1。例如值为 5 时,表示 1 和 4 两个掩码已开启。
panel.colorEdit(label, value, options?)
创建 RGBA 颜色编辑器,值为长度为 3 或 4 的颜色数组;推荐使用长度 4 的 [r, g, b, a]。
const theme = imgui.reactive({ color: [0.2, 0.6, 1, 1] });
panel.colorEdit("高亮色", imgui.bind(theme, "color"), {
flags: imgui.ColorEditFlags.DisplayRGB |
imgui.ColorEditFlags.Float
});
数组分量范围是 0..1。也可以使用 #RRGGBB 或 #AARRGGBB 字符串作为初始颜色,但控件修改后的值会回写为 RGBA 数组。
panel.colorEdit3(label, value, options?)
创建 RGB 颜色编辑器,绑定值必须是长度为 3 的 [r, g, b] 数组。
panel.colorEdit3("背景色", imgui.bind(theme, "rgb"));
alpha 通道不参与编辑。分量范围仍然是 0..1。
panel.colorPicker(label, value, options?)
创建 RGBA 颜色选择器。
panel.colorPicker("颜色选择", imgui.bind(theme, "color"), {
reference: "#ffffff"
});
reference 是可选的参考颜色,可以传颜色字符串或 RGB/RGBA 数组。它只用于颜色选择器的比较参考,不会替代当前绑定值。
panel.colorPicker3(label, value, options?)
创建 RGB 颜色选择器,绑定值是长度为 3 的数组。
panel.colorPicker3("RGB 选择", imgui.bind(theme, "rgb"));
panel.colorButton(label, options?)
绘制一个颜色按钮。它不是普通的 label, value 控件,颜色通过 options.color 提供。
panel.colorButton({
label: "当前颜色",
color: [0.2, 0.6, 1, 1],
width: 48,
height: 28,
onClick: function () { log("颜色按钮被点击"); }
});
color 支持 #RRGGBB、#AARRGGBB 和 RGB/RGBA 数组;flags 使用 ColorEditFlags 中适用于颜色按钮的标志。
panel.inputScalar(label, value, options?)
按指定底层数据类型编辑单个标量。
const state = imgui.reactive({ address: "4294967296", ratio: 0.5 });
panel.inputScalar("地址", imgui.bind(state, "address"), {
dataType: "u64",
step: "1",
stepFast: "16"
});
panel.inputScalar("比例", imgui.bind(state, "ratio"), {
dataType: "double",
step: 0.01
});
dataType 可选值:
| 值 | 含义 |
|---|---|
s8 / u8 | 8 位有符号 / 无符号整数 |
s16 / u16 | 16 位有符号 / 无符号整数 |
s32 / u32 | 32 位有符号 / 无符号整数 |
s64 / u64 | 64 位有符号 / 无符号整数 |
float | 单精度浮点数,默认值 |
double | 双精度浮点数 |
对于 s64 和 u64,超过 JavaScript 安全整数范围 9007199254740991 时必须传十进制字符串,回写结果也会是十进制字符串。无符号类型不能传负数。
panel.inputScalarN(label, value, options?)
编辑多个相同底层类型的标量。绑定值必须是数组。
panel.inputScalarN("四个字节", imgui.bind(state, "bytes"), {
dataType: "u8",
components: 4
});
components 范围是 1..16,并且必须与数组长度一致。类型规则与 inputScalar() 相同。
panel.dragScalar(label, value, options?)
按指定底层数据类型拖动编辑单个标量。
panel.dragScalar("偏移量", imgui.bind(state, "offset"), {
dataType: "s32",
speed: 1,
min: -1000,
max: 1000
});
speed 默认 1。min、max 可以省略,省略时交给 ImGui 处理;如果传入则必须能转换为指定 dataType。
panel.dragScalarN(label, value, options?)
按指定底层数据类型拖动编辑多个标量。
panel.dragScalarN("向量", imgui.bind(state, "values"), {
dataType: "double",
components: 3,
speed: 0.01,
min: -1,
max: 1
});
值必须是数组,components 范围 1..16 且必须和数组长度一致。
panel.sliderScalar(label, value, options?)
按指定底层数据类型创建单值滑块。
panel.sliderScalar("无符号值", imgui.bind(state, "level"), {
dataType: "u32",
min: 0,
max: 1000
});
滑块必须同时提供 min 和 max,并且 min < max。原生标量滑块的边界还不能超过对应类型的安全范围。
panel.sliderScalarN(label, value, options?)
按指定底层数据类型创建多值滑块。
panel.sliderScalarN("三轴强度", imgui.bind(state, "strength"), {
dataType: "float",
components: 3,
min: 0,
max: 1
});
components 和数组长度必须一致,滑块必须提供有效的 min < max。
panel.vSliderScalar(label, value, options?)
按指定底层数据类型创建竖直标量滑块。
panel.vSliderScalar("等级", imgui.bind(state, "level"), {
dataType: "s16",
width: 36,
height: 180,
min: 0,
max: 100
});
它编辑单个值,不使用 components 数组;width、height 至少为 1,并且必须提供 min < max。
标量控件的数值校验
- 值必须是数字;64 位整数可以使用十进制字符串。
s8、s16、s32、s64允许负数;u8、u16、u32、u64不允许负数。- 超出底层类型范围会抛出异常。
inputScalarN、dragScalarN、sliderScalarN的数组长度必须等于components。sliderScalar、sliderScalarN和vSliderScalar必须传min、max,且min < max。
容器节点的共同规则
容器节点的通用调用形式是:
const container = panel.containerName(properties?, function (scope) {
scope.text("容器中的内容");
});
也可以省略属性对象,直接传构建函数。容器返回一个节点,构建函数中的 scope 就是该容器。容器只负责布局、作用域或绘制上下文,不会自动替子节点生成业务状态。
panel.fragment(properties?, build?)
创建不产生额外 ImGui 外观的透明节点,用于组合子节点、条件分支和组件。
panel.fragment({ id: "header" }, function (p) {
p.text("标题");
p.sameLine();
p.text("状态");
});
fragment 适合在 when()、each() 和 component() 中作为结构容器。它也支持 visible: false,隐藏时整个子树不会绘制。
panel.group(properties?, build?)
把多个子节点放入同一个 ImGui group,使它们作为一个布局组参与布局。
panel.group(function (group) {
group.text("左侧");
group.button("操作");
});
group 会调用 ImGui 的 BeginGroup/EndGroup,适合让一组控件一起参与布局或作为一个整体移动。
panel.child(properties?, build?)
创建一个独立的子区域,支持滚动和边框。
panel.child({
id: "log-area",
width: 420,
height: 220,
border: true,
childFlags: imgui.ChildFlags.Borders,
flags: imgui.WindowFlags.HorizontalScrollbar
}, function (child) {
child.text("第一条日志");
child.text("第二条日志");
});
| 属性 | 类型 | 说明 |
|---|---|---|
width / height | number | 子区域尺寸;未设置时由布局决定。 |
border | boolean | 快捷开启边框;也可用 childFlags: ChildFlags.Borders。 |
childFlags | number | 子窗口标志,如 Borders、ResizeX、ResizeY。 |
flags | number | 子窗口的 WindowFlags。 |
panel.tree(properties?, build?)
创建可以展开和收起的树节点。
panel.tree({
label: "目标类",
defaultOpen: true,
flags: imgui.TreeNodeFlags.OpenOnArrow
}, function (tree) {
tree.text("方法数量: 12");
});
| 属性 | 说明 |
|---|---|
label | 树节点标题。 |
defaultOpen | true 时首次以展开状态绘制。 |
open | 传入布尔值时强制设置当前展开状态。 |
flags | TreeNodeFlags 的按位组合。 |
defaultOpen 只影响 ImGui 的默认展开状态;open 是每次提交时的显式展开状态请求。
panel.collapsingHeader(properties?, build?)
创建可折叠标题栏,展开后绘制子节点。
panel.collapsingHeader({
label: "高级设置",
defaultOpen: false
}, function (section) {
section.checkbox("启用高级模式", imgui.bind(state, "advanced"));
});
属性和 tree 相同,但标题栏不会建立树节点推入层级;flags 使用 TreeNodeFlags。
panel.tabs(properties?, build?)
创建页签栏容器。
panel.tabs({
flags: imgui.TabBarFlags.Reorderable
}, function (tabs) {
tabs.tab({ label: "概览" }, function (tab) {
tab.text("概览内容");
});
tabs.tab({ label: "日志", closable: true }, function (tab) {
tab.text("日志内容");
});
});
flags 使用 TabBarFlags。页签自身由 panel.tab() 创建。
panel.tab(properties?, build?)
在 tabs 容器中创建一个页签。
panel.tabs(function (tabs) {
tabs.tab({
id: "settings-tab",
label: "设置",
closable: true,
open: true,
flags: imgui.TabItemFlags.UnsavedDocument,
onClose: function () { log("设置页签关闭"); }
}, function (tab) {
tab.text("设置内容");
});
});
| 属性 | 说明 |
|---|---|
label | 页签显示文字。 |
closable | true 时允许关闭页签。 |
open | 当前是否打开;关闭后会触发 close 事件。 |
flags | TabItemFlags 的按位组合。 |
panel.table(properties?, build?)
创建表格并自动处理列初始化、表头和排序事件。
panel.table({
id: "methods",
label: "方法表",
columns: [
{ label: "名称", flags: imgui.TableColumnFlags.WidthStretch },
{ label: "类型", flags: imgui.TableColumnFlags.WidthFixed, width: 100 }
],
headers: true,
flags: imgui.TableFlags.Borders |
imgui.TableFlags.RowBg |
imgui.TableFlags.Sortable,
onSort: function (specs) {
log(JSON.stringify(specs));
}
}, function (table) {
table.row(function (row) {
row.text("foo");
row.text("method");
});
});
columns 的三种写法
columns: 3
创建 3 列,列名为空。
columns: ["名称", "类型", "返回值"]
创建带文字的列。
columns: [
{ label: "名称", flags: imgui.TableColumnFlags.NoHide },
{ label: "耗时", width: 90 }
]
列对象支持 label、flags、width。列数会限制在 1..64。
表格属性
| 属性 | 默认值 | 说明 |
|---|---|---|
columns | 1 | 数字、字符串数组或列对象数组。 |
headers | true | 是否自动绘制表头。 |
flags | `Borders | RowBg |
width / height | 由布局决定 | 表格尺寸。 |
freezeRows | 0 | 冻结顶部行数,非负整数。 |
freezeColumns | 0 | 冻结左侧列数,非负整数,不能超过列数。 |
angledHeaders | false | 是否以倾斜方式绘制表头。 |
onSort | 无 | 收到 [[columnIndex, sortDirection], ...]。 |
sortDirection 是 imgui.SortDirection.Ascending 或 Descending 对应的数字。排序回调只报告排序规格,实际数组排序仍由脚本自己完成。
panel.row(properties?, build?)
创建表格中的一行。若当前位于 table 内,运行时会开始下一行,并为每个子节点切换到下一列。
panel.table({ columns: 2 }, function (table) {
table.row(function (row) {
row.labelText("进程", { text: "main" });
row.labelText("状态", { text: "运行中" });
});
});
height 可以设置行高,flags 使用 TableRowFlags。
panel.disabled(properties?, build?)
让子节点进入禁用状态。
panel.disabled({ disabled: function () { return !state.enabled; } }, function (p) {
p.button("只有启用后才能点击");
p.inputText("参数", imgui.bind(state, "parameter"));
});
disabled 默认 true。传 false 时子节点正常可交互。
panel.style(properties?, build?)
只在子树绘制期间压入颜色和样式变量。
panel.style({
colors: {
Text: "#ffd166",
Button: [0.12, 0.35, 0.55, 1]
},
vars: {
FrameRounding: 6,
ItemSpacing: [8, 6]
}
}, function (p) {
p.button("使用局部样式");
});
colors 的键可以是 imgui.Col 名称或数字索引,值是 #RRGGBB、#AARRGGBB 或 RGB/RGBA 数组。vars 的键可以是 imgui.StyleVar 名称或数字索引;单值变量传数字,二维变量传长度为 2 的数组。未知名称或类型不正确时会抛出异常。
panel.menuBar(properties?, build?)
在窗口顶部创建菜单栏。
panel.menuBar(function (bar) {
bar.menu({ label: "文件" }, function (menu) {
menu.menuItem({ label: "刷新", onClick: refresh });
menu.menuItem({ label: "退出", onClick: function () { panel.close(); } });
});
});
窗口需要同时设置 flags: imgui.WindowFlags.MenuBar 才能看到窗口菜单栏。
panel.menu(properties?, build?)
创建一个可展开的菜单。
panel.menu({ label: "视图", enabled: true }, function (menu) {
menu.menuItem({
label: "显示网格",
shortcut: "G",
selected: state.grid,
enabled: true,
onClick: function () { state.grid = !state.grid; }
});
});
label 是菜单名,enabled 默认 true。
panel.popup(properties?, build?)
创建普通弹出窗口。需要通过 panel.openPopup(nodeOrId) 打开。
const popup = panel.popup({ id: "help", label: "help" }, function (p) {
p.text("帮助内容");
p.button("关闭", function () { panel.closePopup(popup); });
});
panel.button("帮助", function () { panel.openPopup(popup); });
flags 使用 PopupFlags。
panel.modal(properties?, build?)
创建模态弹窗。模态弹窗打开时会阻止用户操作后面的窗口内容。
const confirm = panel.modal({
id: "confirm",
label: "确认操作",
closable: true,
onClose: function () { log("确认框关闭"); }
}, function (p) {
p.text("确定要继续吗?");
p.button("确定", function () { panel.closePopup(confirm); });
});
panel.button("删除", function () { panel.openPopup(confirm); });
closable 默认 true,允许用户关闭时会触发 close 事件。
panel.contextMenu(properties?, build?)
创建与当前项目关联的右键菜单。
const item = panel.text("在这里右键", { id: "target" });
panel.contextMenu({
id: "target-menu",
label: "target-menu",
popupFlags: imgui.PopupFlags.MouseButtonRight
}, function (menu) {
menu.menuItem({ label: "复制", onClick: copyValue });
});
popupFlags 指定触发按键,通常使用 MouseButtonRight。上下文菜单需要放在对应项目附近,便于 ImGui 将其与当前项目关联。
panel.tooltip(properties?, build?)
为当前项目绘制工具提示。
panel.button("悬停查看", function () {}, { id: "tip-button" });
panel.tooltip(function (tip) {
tip.text("这里是详细说明");
});
工具提示只在当前项目处于悬停状态时绘制。
panel.dragSource(properties?, build?)
定义拖动源,并在拖动时发送字符串 payload。
panel.dragSource({
type: "METHOD_ID",
payload: "com.example.Target.method"
}, function (source) {
source.text("拖动这个方法");
});
type 默认 SCRIPTX_UI,长度不能超过 31 字节;payload 会作为字符串交付。
panel.dropTarget(properties?, build?)
定义拖放目标并接收字符串 payload。
panel.dropTarget({
type: "METHOD_ID",
onDrop: function (payload) {
log("收到: " + payload);
}
}, function (target) {
target.text("把方法拖到这里");
});
type 必须与拖动源一致。只有 payload 真正交付时才触发 drop。
panel.clipList(properties?, build?)
创建带裁剪能力的列表容器,适合大量固定高度的子节点。
panel.clipList({ itemHeight: 30 }, function (list) {
for (let i = 0; i < 1000; i++) {
list.text({ text: "第 " + i + " 行" });
}
});
itemHeight 可提供固定行高。若要根据数组 key 复用行并只创建可见数据,使用 panel.virtualList()。
panel.comboScope(properties?, build?)
手动创建一个 ImGui 下拉区域,供即时组合内容使用。
panel.comboScope({
label: "自定义选项",
preview: "当前预览",
flags: imgui.ComboFlags.HeightRegular
}, function (scope) {
scope.selectable({ label: "选项一" });
scope.selectable({ label: "选项二" });
});
它只负责 BeginCombo/EndCombo,不会像 panel.combo() 那样自动把数组下标写回 value。
panel.listBoxScope(properties?, build?)
手动创建一个列表框区域。
panel.listBoxScope({
label: "自定义列表",
width: 260,
height: 160
}, function (scope) {
scope.text("自定义内容");
});
它负责 BeginListBox/EndListBox,列表内容由子节点自己绘制。
panel.clipRect(properties?, build?)
限制绘图内容的裁剪矩形。
panel.clipRect({
min: [0, 0],
max: [300, 160],
screenSpace: false,
intersect: true
}, function (scope) {
scope.drawCircle({
center: [150, 80],
radius: 120,
color: "#55aaff",
filled: true
});
});
min、max 是裁剪矩形的两个角点。默认坐标相对当前光标,screenSpace: true 时使用屏幕绝对坐标;intersect 默认 true,表示与当前裁剪区域取交集。
panel.fontScope(properties?, build?)
在子树绘制期间使用指定字体。
const font = imgui.font("/sdcard/Download/NotoSansCJK-Regular.ttc", {
size: 22
});
panel.fontScope({ font: font, size: 22 }, function (p) {
p.text("中文字体");
});
font 可以是 imgui.font() 返回的字体对象或字体 id,size 可调整绘制字号。字体必须在 onFrame 外加载。
panel.dockSpace(properties?)
创建一个停靠空间,让多个 dockWindow 可以在其中分割、停靠和切换。
panel.dockSpace({
id: "main-dock",
width: 0,
height: 0,
flags: imgui.DockNodeFlags.None
});
panel.dockWindow({
id: "inspector",
label: "检查器",
dockSpace: "main-dock",
width: 320,
height: 480
}, function (window) {
window.text("检查器内容");
});
id 是停靠空间的稳定标识。layout 可以传由 frame.saveLayout() 返回的布局文档,在首次建立该停靠空间时恢复布局。flags 使用 DockNodeFlags。
panel.dockWindow(properties?, build?)
创建一个可以停靠到 dockSpace 的独立窗口。
panel.dockWindow({
id: "console",
label: "控制台",
dockSpace: "main-dock",
open: true,
closable: true,
position: [40, 80],
width: 480,
height: 280,
flags: imgui.WindowFlags.NoSavedSettings
}, function (window) {
window.text("控制台输出");
});
| 属性 | 说明 |
|---|---|
id | 稳定窗口 id;没有时会尝试使用 label。 |
label | 标题栏文字。 |
dockSpace | 要停靠的空间 id。 |
open | 是否显示,默认 true。 |
closable | 是否允许关闭。关闭时触发 close。 |
position | 首次出现的位置 [x, y]。 |
width / height | 首次出现的尺寸,默认约 320 x 240。 |
platformWindow | true 时请求独立平台窗口视口。 |
flags | WindowFlags 的按位组合。 |
停靠窗口是节点树中的容器,子节点只在该窗口当前可见时绘制。
panel.plot(properties?, build?)
创建一个 ImPlot 图表区域。所有 plotLine 等系列节点必须放在 plot 内。
panel.plot({
label: "响应时间",
width: 520,
height: 300,
xLabel: "次数",
yLabel: "毫秒",
xLimits: [0, 100],
yLimits: [0, 500],
xScale: imgui.PlotScale.Linear,
yScale: imgui.PlotScale.Linear,
xFlags: imgui.PlotAxisFlags.NoGridLines,
legendLocation: imgui.PlotLocation.NorthEast,
onLimits: function (limits) {
log("范围: " + limits.join(", "));
},
onPlotclick: function (position) {
log("点击: " + position.join(", "));
}
}, function (plot) {
plot.plotLine({
label: "请求",
x: [0, 20, 40, 60, 80],
y: [80, 120, 90, 260, 180],
color: "#55b7ff",
thickness: 2,
marker: imgui.PlotMarker.Circle
});
});
图表属性
| 属性 | 说明 |
|---|---|
label | 图表 id 和标题。 |
width / height | 图表尺寸;高度默认约 260。 |
flags | PlotFlags 组合。 |
xLabel / yLabel | X、Y 轴标签。 |
xFlags / yFlags | X、Y 轴的 PlotAxisFlags。 |
xLimits / yLimits | [min, max],必须 min < max。 |
xScale / yScale | Linear、Time、Log10 或 SymLog。 |
lockLimits | true 时每帧强制应用范围,否则只在首次使用时应用。 |
legendLocation | PlotLocation 中的位置值。 |
legendFlags | 图例标志。 |
axes | 最多 6 个额外轴配置对象。 |
额外轴对象可写成:
axes: [
{
axis: imgui.Axis.Y2,
label: "第二 Y 轴",
flags: imgui.PlotAxisFlags.Opposite,
limits: [0, 1],
scale: imgui.PlotScale.Linear,
ticks: [0, 0.5, 1],
labels: ["0", "50%", "100%"],
keepDefaultTicks: false,
lockLimits: true
}
]
axis 必须是 X1..X3 或 Y1..Y3,同一个轴不能重复配置;ticks 最多 1000 个,labels 长度必须与 ticks 相同。
panel.subplots(properties?, build?)
创建多图子图布局。
panel.subplots({
label: "分析结果",
rows: 2,
columns: 2,
width: 640,
height: 480,
flags: imgui.PlotSubplotFlags.LinkAllX
}, function (plots) {
plots.plot({ label: "上图" }, function (plot) {
plot.plotLine({ label: "A", y: [1, 2, 3] });
});
plots.plot({ label: "下图" }, function (plot) {
plot.plotBars({ label: "B", y: [3, 1, 2] });
});
});
rows、columns 至少为 1,总格子数最多 64。flags 使用 PlotSubplotFlags。子图内部仍然要放系列节点。
panel.plotLine(properties?)
在当前 plot 中绘制折线。值使用 y 数组,x 可选。
plot.plotLine({
label: "温度",
x: [0, 1, 2, 3],
y: [20.1, 21.4, 21.0, 22.2],
xAxis: imgui.Axis.X1,
yAxis: imgui.Axis.Y1,
color: "#ff8066",
thickness: 2,
marker: imgui.PlotMarker.Circle,
markerSize: 4,
fillAlpha: 0,
flags: imgui.PlotLineFlags.None
});
没有 x 时,X 值从 xStart 开始按 xScale 递增,xScale 默认 1。x 与 y 长度必须相同,数组元素必须是有限数字。
panel.plotScatter(properties?)
绘制散点图。
plot.plotScatter({
label: "采样点",
x: [1, 2, 3, 4],
y: [4, 1, 3, 2],
marker: imgui.PlotMarker.Diamond,
markerSize: 7
});
默认 marker 是圆形;其它通用系列属性与 plotLine 相同。
panel.plotBars(properties?)
绘制柱状图。
plot.plotBars({
label: "次数",
x: [1, 2, 3],
y: [5, 8, 3],
barSize: 0.6,
flags: imgui.PlotBarsFlags.None
});
barSize 默认 0.67,表示柱宽相对相邻 X 间距的比例。
panel.plotStairs(properties?)
绘制阶梯线。
plot.plotStairs({
label: "状态变化",
x: [0, 1, 2, 3],
y: [0, 1, 1, 0]
});
参数和数据要求与 plotLine 相同。
panel.plotShaded(properties?)
绘制填充区域。可以使用固定基线,也可以使用第二条同长度曲线。
plot.plotShaded({
label: "区间",
x: [0, 1, 2],
y: [2, 4, 3],
y2: [1, 2, 1],
fillAlpha: 0.35,
color: "#64d6a2"
});
plot.plotShaded({
label: "基线填充",
x: [0, 1, 2],
y: [2, 4, 3],
baseline: 0
});
y2 与 y 长度必须相同;不传 y2 时使用 baseline,默认基线为 0。
panel.plotStems(properties?)
绘制从基线延伸到数据点的茎状图。
plot.plotStems({
label: "频次",
x: [1, 2, 3],
y: [4, 7, 2],
baseline: 0
});
baseline 默认 0。
panel.plotHeatmap(properties?)
绘制二维热力图。
plot.plotHeatmap({
label: "相关性",
values: [0.1, 0.4, 0.8, 0.3, 0.6, 1.0],
rows: 2,
columns: 3,
min: [0, 0],
max: [3, 2],
scaleMin: 0,
scaleMax: 1,
labels: true
});
rows * columns 必须等于 values.length;rows 和 columns 至少为 1。scaleMin、scaleMax 是颜色映射范围,min、max 是图表坐标范围。labels: true 会显示单元格数值。
panel.plotPie(properties?)
绘制饼图。
plot.plotPie({
label: "分布",
values: [40, 35, 25],
labels: ["成功", "失败", "跳过"],
center: [0.5, 0.5],
radius: 0.4,
angle: 90
});
labels.length 必须等于 values.length。center 默认 [0.5, 0.5],radius 默认 0.4,angle 默认 90 度。
panel.plotHistogram1D(properties?)
绘制一维直方图。
plot.plotHistogram1D({
label: "耗时分布",
values: [3, 4, 4, 5, 7, 8, 12, 13],
bins: 6,
barScale: 1
});
bins 默认 20,范围 1..10000;barScale 默认 1。
panel.plotBubbles(properties?)
绘制带有大小信息的气泡散点图。
plot.plotBubbles({
label: "对象大小",
x: [1, 2, 3],
y: [10, 20, 15],
sizes: [4, 12, 7],
color: "#69d2ff"
});
sizes 必须存在、与 x 和 y 等长,并且每个值不能为负数。
panel.plotPolygon(properties?)
将数据点连接成多边形。
plot.plotPolygon({
label: "覆盖区域",
x: [0, 4, 5, 1],
y: [0, 0, 3, 4],
fillAlpha: 0.25,
color: "#ff9f68"
});
至少需要 3 个点。x、y 长度必须一致。
panel.plotBarGroups(properties?)
绘制分组柱状图。
plot.plotBarGroups({
label: "平台对比",
labels: ["Android", "iOS"],
values: [12, 18, 20, 15],
groups: 2,
groupSize: 0.67,
shift: 0
});
这里 labels.length 是每组中的项目数,groups 是组数,因此 values.length 必须等于 labels.length * groups。labels 最多 128 个,groupSize 默认 0.67,shift 默认 0。
panel.plotErrorBars(properties?)
绘制误差线。
plot.plotErrorBars({
label: "均值与误差",
x: [1, 2, 3],
y: [10, 14, 12],
negative: [1, 2, 1],
positive: [2, 1, 3],
thickness: 2
});
negative 必须存在并与 y 等长,元素不能为负数。positive 可省略;省略时使用 negative 作为对称的正向误差。
panel.plotInfLines(properties?)
绘制多条无限延伸的水平线。
plot.plotInfLines({
label: "阈值",
values: [10, 20, 30],
color: "#ffcc66",
thickness: 1
});
values 是有限数字数组,flags 使用 PlotLineFlags 中适用的值。
panel.plotHistogram2D(properties?)
绘制二维直方图。
plot.plotHistogram2D({
label: "坐标分布",
x: [1, 1.2, 2, 2.1, 3],
y: [4, 4.4, 2, 2.2, 1],
xBins: 20,
yBins: 16
});
x 和 y 必须长度相同。xBins、yBins 默认 20,每个轴会限制到 1..512。
panel.plotImage(properties?)
把纹理映射到图表坐标区域。
plot.plotImage({
label: "样本图",
texture: texture.id,
min: [0, 0],
max: [640, 480],
uv0: [0, 0],
uv1: [1, 1],
color: "#ffffff"
});
texture 必须是 imgui.texture() 返回的纹理对象或其 id;min、max 是图表坐标;uv0、uv1 是纹理采样坐标,默认分别为 [0, 0] 和 [1, 1]。
panel.plotText(properties?)
在图表坐标中绘制文字。
plot.plotText({
text: "异常点",
position: [42, 128],
offset: [8, -8],
color: "#ff7777"
});
position 必须是 [x, y]。offset 是文字相对于数据坐标的屏幕偏移,默认 [0, 0]。
panel.plotDummy(properties?)
在图表中登记一个不绘制数据的系列,常用于占位或配合图例。
plot.plotDummy({
label: "暂无数据"
});
图表系列的共同属性
除特殊字段外,数据系列通常支持:
| 属性 | 类型 | 说明 |
|---|---|---|
label | string | 系列名称。 |
x | 有限数字数组 | X 坐标;省略时由 xStart 和 xScale 生成。 |
y / values | 有限数字数组 | Y 数据。多数系列使用 y,也接受 values。 |
color | 颜色 | 线条、填充或系列颜色。 |
thickness | number | 线宽,默认 1,内部限制到 0..100。 |
fillAlpha | number | 填充透明度,范围 0..1,默认 1。 |
marker | number | PlotMarker 值,默认由系列决定。 |
markerSize | number | marker 大小,范围 0..100,默认 4。 |
flags | number | 对应的 ImPlot 标志组。 |
xAxis | number | Axis.X1、X2 或 X3,默认 X1。 |
yAxis | number | Axis.Y1、Y2 或 Y3,默认 Y1。 |
系列必须位于已经打开的 plot 或 subplots 图表中,并且选择的 X/Y 轴必须处于启用状态。
panel.plotDragPoint(label, value, options?)
在图表中创建可拖动的数据点。绑定值格式是 [x, y]。
const point = imgui.reactive({ value: [10, 20] });
plot.plotDragPoint("阈值点", imgui.bind(point), {
color: "#ff6666",
size: 8,
flags: imgui.PlotDragToolFlags.None,
onChange: function (value) {
log("点移动到: " + value.join(", "));
}
});
size 默认 6,范围 1..100。值数组必须正好包含两个数字。
panel.plotDragLineX(label, value, options?)
在图表中创建可拖动的竖直线,绑定值是数字。
plot.plotDragLineX("X 阈值", imgui.bind(state, "xThreshold"), {
color: "#66ddaa",
thickness: 2
});
thickness 默认 1,范围 1..100。
panel.plotDragLineY(label, value, options?)
在图表中创建可拖动的水平线,绑定值是数字。
plot.plotDragLineY("Y 阈值", imgui.bind(state, "yThreshold"), {
color: "#66ddaa",
thickness: 2
});
参数与 plotDragLineX() 相同。
panel.plotDragRect(label, value, options?)
在图表中创建可拖动矩形,绑定值格式是 [x1, y1, x2, y2]。
const rect = imgui.reactive({ value: [10, 20, 100, 160] });
plot.plotDragRect("感兴趣区域", imgui.bind(rect), {
color: "#ffaa44",
flags: imgui.PlotDragToolFlags.None
});
数组必须正好包含四个数字。改变后会触发 change 事件并回写完整数组。
panel.plotStream(label, options?)
创建一个适合持续追加数据的实时图表节点。
const stream = panel.plotStream("实时数据", {
capacity: 4096,
kind: "line",
color: "#62d8a5",
height: 180
});
let x = 0;
const timer = setInterval(function () {
stream.append([[x, Math.sin(x / 10)]]);
x += 1;
}, 100);
kind 可选:
| 值 | 绘制方式 |
|---|---|
line | 折线,默认值。 |
scatter | 散点。 |
bars | 柱状图。 |
stairs | 阶梯线。 |
stems | 茎状图。 |
capacity 默认 4096,范围 1..100000,创建后固定。新数据超过容量时覆盖最早的数据。创建时不能同时传 x、y 或 values,数据必须通过 append() 进入。
stream.append(points)
向实时图表追加点。
stream.append([
[0, 1.2],
[1, 1.5],
[2, 1.1]
]);
每个点必须是 [x, y] 两元素有限数字数组,一次最多 100,000 个点。返回实时图表节点。
stream.clearData()
清空实时图表中的全部数据。
stream.clearData();
返回实时图表节点。它只清除流数据,不删除图表节点。
stream.dataStats()
读取实时图表的数据统计。
const stats = stream.dataStats();
log(stats.count);
log(stats.offset);
log(stats.first);
log(stats.last);
返回对象至少包含 count 和 offset;有数据时还会包含 first: [x, y] 与 last: [x, y]。环形缓冲区覆盖数据后,offset 表示当前最早数据在内部数组中的位置,不要把内部顺序当成显示顺序。
绘图节点的共同规则
绘图节点不会占据布局空间。要在某个区域中绘图,通常先用 dummy 占出空间,再在相同区域绘图;或者直接使用当前光标作为绘图原点。
panel.dummy({ width: 320, height: 160 });
panel.drawRect({
min: [0, 0],
max: [320, 160],
color: "#3b82f6",
filled: false,
thickness: 2
});
通用属性:
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
layer | string | window | window、foreground 或 background。 |
screenSpace | boolean | false | false 使用当前光标屏幕位置为原点;true 使用屏幕绝对坐标。 |
color | 颜色 | 白色 | 支持颜色字符串或 0..1 的 RGB/RGBA 数组。 |
thickness | number | 1 | 线宽;基础图形至少 0.1,扩展图形约束在 0.1..1000。 |
filled | boolean | false | 支持填充的图形是否填充。 |
flags | number | 0 | 使用 ImDrawFlags 的按位组合。 |
screenSpace 只改变坐标原点,不会改变 layer。foreground 和 background 适合绘制跨窗口的标记,但仍要注意窗口生命周期。
panel.drawLine(properties?)
绘制一条线段。
panel.drawLine({
from: [0, 0],
to: [240, 100],
color: "#66d9ef",
thickness: 2
});
from 和 to 都是 [x, y]。坐标默认相对当前光标。
panel.drawRect(properties?)
绘制矩形,可选择填充或描边。
panel.drawRect({
min: [10, 10],
max: [220, 90],
color: [0.2, 0.6, 1, 0.3],
filled: true,
rounding: 8,
flags: imgui.ImDrawFlags.RoundCornersAll,
thickness: 2
});
min 和 max 是矩形的两个角点。filled: true 使用填充矩形,false 使用描边矩形;rounding 是圆角半径。
panel.drawCircle(properties?)
绘制圆形。
panel.drawCircle({
center: [120, 80],
radius: 40,
segments: 32,
color: "#f59e0b",
filled: false,
thickness: 2
});
radius 小于 0 时按 0 处理,segments 控制近似圆的分段数。
panel.drawText(properties?)
绘制文本。
panel.drawText({
position: [20, 30],
text: "屏幕标注",
color: "#ffffff"
});
当传入 font、size 或 wrapWidth 时使用扩展文字绘制:
panel.drawText({
position: [20, 70],
text: "使用自定义字号的标注",
font: font,
size: 24,
wrapWidth: 260,
color: "#a7f3d0"
});
font 可以是字体对象或字体 id,size 范围 1..512,wrapWidth 小于 0 时不换行。
panel.drawImage(properties?)
在绘图层中显示纹理。
panel.drawImage({
texture: texture.id,
min: [0, 0],
max: [240, 160],
uv0: [0, 0],
uv1: [1, 1],
color: "#ffffff"
});
绘图节点要传 texture.id,不是整个纹理对象。min、max 是绘图区域;uv0、uv1 默认分别为 [0, 0] 和 [1, 1]。
panel.drawPolyline(properties?)
按顺序连接多个点。
panel.drawPolyline({
points: [[0, 30], [50, 10], [100, 60], [150, 20]],
color: "#c084fc",
thickness: 2,
flags: imgui.ImDrawFlags.None
});
至少需要两个点。flags 可以使用 ImDrawFlags.Closed 将路径闭合。
panel.drawTriangle(properties?)
绘制三角形。
panel.drawTriangle({
a: [20, 100],
b: [80, 20],
c: [140, 100],
color: "#34d399",
filled: true
});
a、b、c 都是 [x, y]。
panel.drawBezierCubic(properties?)
绘制三次贝塞尔曲线。
panel.drawBezierCubic({
p1: [0, 80],
p2: [40, 0],
p3: [160, 160],
p4: [220, 80],
color: "#60a5fa",
thickness: 2,
segments: 32
});
四个点依次是起点、控制点、控制点、终点。
panel.drawBezierQuadratic(properties?)
绘制二次贝塞尔曲线。
panel.drawBezierQuadratic({
p1: [0, 80],
p2: [100, -20],
p3: [220, 80],
color: "#f472b6",
thickness: 2,
segments: 24
});
p1 是起点,p2 是控制点,p3 是终点。
panel.drawEllipse(properties?)
绘制椭圆。
panel.drawEllipse({
center: [150, 80],
radius: [100, 45],
rotation: 0.25,
segments: 48,
color: "#fca5a5",
filled: false,
thickness: 2
});
radius 是 [横向半径, 纵向半径],负数半径按 0 处理;rotation 使用弧度。
panel.drawNgon(properties?)
绘制正多边形。
panel.drawNgon({
center: [100, 80],
radius: 50,
segments: 6,
color: "#fde047",
filled: true
});
segments 最少按 3 处理,radius 小于 0 按 0 处理。
panel.drawQuad(properties?)
绘制四边形。
panel.drawQuad({
a: [10, 20],
b: [180, 10],
c: [200, 100],
d: [20, 120],
color: "#93c5fd",
filled: false,
thickness: 2
});
四个点按顺序连接;filled 决定填充或描边。
panel.drawPolygon(properties?)
绘制填充多边形。
panel.drawPolygon({
points: [[0, 0], [100, 0], [130, 70], [40, 110]],
color: [0.2, 0.8, 0.6, 0.35],
concave: false
});
至少需要 3 个点,最多 8192 个点。concave: true 使用凹多边形填充,默认按凸多边形处理。这个节点绘制填充多边形,不提供单独的描边开关。
panel.drawRectGradient(properties?)
绘制四角颜色不同的矩形渐变。
panel.drawRectGradient({
min: [0, 0],
max: [300, 120],
colors: [
"#ff6b6b",
"#ffd166",
"#06d6a0",
"#118ab2"
]
});
colors 必须正好包含四个颜色,依次对应原生矩形四个角。
panel.drawImageQuad(properties?)
把纹理绘制到四边形四个顶点。
panel.drawImageQuad({
texture: texture.id,
a: [0, 0],
b: [240, 20],
c: [220, 170],
d: [10, 150],
uv1: [0, 0],
uv2: [1, 0],
uv3: [1, 1],
uv4: [0, 1],
color: "#ffffff"
});
texture 传纹理 id;a、b、c、d 是顶点;uv1..uv4 是对应顶点采样坐标。
panel.drawImageRounded(properties?)
绘制带圆角的纹理矩形。
panel.drawImageRounded({
texture: texture.id,
min: [0, 0],
max: [260, 160],
uv0: [0, 0],
uv1: [1, 1],
rounding: 12,
flags: imgui.ImDrawFlags.RoundCornersAll,
color: "#ffffff"
});
rounding 是圆角半径,flags 控制哪些角使用圆角。
panel.drawPath(properties?)
按命令序列构建并绘制复杂路径。
panel.drawPath({
commands: [
{ op: "moveTo", point: [20, 80] },
{ op: "lineTo", point: [90, 20] },
{ op: "bezierCubicTo", p2: [120, 0], p3: [180, 140], p4: [230, 80], segments: 24 },
{ op: "lineTo", point: [20, 80] }
],
color: "#a78bfa",
thickness: 2,
filled: false,
closed: true
});
路径命令
op | 必要字段 | 作用 |
|---|---|---|
moveTo | point | 设置路径起点。 |
lineTo | point | 连接到一个点。 |
arcTo | center、radius、min、max | 添加圆弧,角度使用弧度。 |
ellipseTo | center、radius、rotation、min、max | 添加椭圆弧。 |
bezierCubicTo | p2、p3、p4 | 从当前点添加三次贝塞尔曲线。 |
bezierQuadraticTo | p2、p3 | 从当前点添加二次贝塞尔曲线。 |
rect | min、max | 添加矩形路径,可选 rounding、flags。 |
一条 drawPath 最多 4096 条命令,必须先有起点才能使用贝塞尔命令,且一条路径只能有一个 moveTo。filled: true 时使用填充;否则使用描边,closed: true 会闭合路径。
panel.appearance(options)
为当前窗口设置主题、缩放、透明度、颜色和样式变量。
panel.appearance({
theme: "modern_dark",
fontScale: 1.1,
uiScale: 1.2,
alpha: 0.95,
colors: {
Text: "#f7d774",
Button: [0.15, 0.35, 0.55, 1]
},
vars: {
FrameRounding: 8,
ItemSpacing: [8, 6]
}
});
options 字段
| 字段 | 类型 | 说明 |
|---|---|---|
theme | string | 必须是 imgui.themes() 中的主题。 |
fontScale | number | 范围 1.0..3.2。 |
uiScale | number | 范围 0.85..2.4。 |
alpha | number | 范围 0.2..1.0。 |
colors | object | 键为 Col 名称或数字索引,值为颜色。 |
vars | object | 键为 StyleVar 名称或数字索引,值为数字或二维数组。 |
颜色数组的每个分量必须在 0..1,长度只能是 3 或 4。样式变量的形状由原生变量定义:单值变量传数字,二维变量传长度为 2 的数组。透明度、对齐等归一化变量的范围通常是 0..1,角度样式变量的范围是 -PI/2..PI/2,其它变量不能超过实现允许的范围。
返回当前窗口。传入响应式函数时,外部数据变化会自动重新应用外观。
panel.saveAppearance()
把当前窗口的外观设置导出为普通 JavaScript 对象。
const saved = panel.saveAppearance();
files.write("/sdcard/imgui-appearance.json", JSON.stringify(saved));
返回版本为 1 的对象,包含 theme、fontScale、uiScale、alpha、colors 和 vars。颜色和样式变量会尽量使用可读的 Col、StyleVar 名称。窗口位置、尺寸和控件输入值不属于外观文档。
panel.loadAppearance(data)
加载 panel.saveAppearance() 生成的外观文档。
const saved = JSON.parse(files.read("/sdcard/imgui-appearance.json"));
panel.loadAppearance(saved);
data.version 必须是 1,否则抛出异常。加载后会继续遵守当前运行时对主题名、颜色分量和样式变量类型的校验。
imgui.themes()
返回当前内置主题名称数组。
log(imgui.themes());
当前可用值是:
modern_dark
vibrant_night
crystal_clear
cyan_dusk
orange_dark
purple_dream
blue
pink
imgui_dark
imgui_light
imgui_classic
rose_prism
rose_glass
sakura_night
pearl_mist
petal_dawn
velvet_rose
crystal_rose
midnight_petal
milk_tea_rose
主题名必须完整匹配字符串,拼写错误时 appearance() 会抛出异常。
imgui.texture(path)
从本地文件加载纹理。
const texture = imgui.texture("/sdcard/Download/icon.png");
log(texture.id);
log(texture.width + " x " + texture.height);
返回对象:
| 字段 | 说明 |
|---|---|
id | 当前运行时中的纹理 id。绘图属性通常传这个 id。 |
width | 像素宽度。 |
height | 像素高度。 |
dispose() | 释放纹理。 |
支持 Android 能解码的图像文件;文件必须存在且能解码,宽高范围是 1..4096。所有纹理合计 RGBA 像素数据最多 128 MiB。纹理加载必须在 onFrame 外执行。
texture.dispose()
释放纹理并让宿主不再保留它。
const texture = imgui.texture(path);
const imagePanel = imgui.window("image-panel", {
onClose: function () {
texture.dispose();
}
});
imagePanel.image(texture, { width: 100, height: 100 });
imagePanel.show();
纹理释放后不能继续传给 image、imageButton、绘图节点或图表系列。脚本停止时,运行时也会自动释放属于该脚本的纹理。
imgui.font(path, options?)
加载 TTF、OTF 或 TTC 字体。
const font = imgui.font("/sdcard/Download/NotoSansCJK-Regular.ttc", {
size: 24,
fontIndex: 0,
glyphMinAdvanceX: 0,
glyphOffset: [0, 0],
excludeRanges: [1, 8, 10, 13]
});
panel.fontScope({ font: font, size: 24 }, function (p) {
p.text("中文与调试信息");
});
options 字段
| 字段 | 类型 | 默认值 | 说明 |
|---|---|---|---|
size | number | 20 | 字号范围 6..128。 |
fontIndex | number | 0 | TTC 集合中的字体索引;非 TTC 文件只能是 0。 |
merge | array | [] | 最多 8 个合并字体源,每项可提供自己的 path、fontIndex、size 等字段。 |
glyphMinAdvanceX | number | 0 | 范围 0..512。 |
glyphOffset | [x, y] | 无 | 每个分量范围 -512..512。 |
excludeRanges | 数字数组 | 无 | 展平的 [first, last, first, last] 区间,最多 256 对,Unicode 范围 1..65535。 |
单个字体源最大 32 MiB,所有字体源合计最大 64 MiB,字体族最多 32 个。字体加载和合并必须在 onFrame 外执行。
font.dispose()
释放字体资源。
const font = imgui.font(path, { size: 20 });
const fontPanel = imgui.window("font-panel", {
onClose: function () {
font.dispose();
}
});
fontPanel.fontScope({ font: font }, function (p) {
p.text("使用字体");
});
fontPanel.show();
释放后再使用该字体会抛出“未知或已释放字体”一类错误。脚本结束时当前运行时拥有的字体会自动释放。
imgui.resourceStats()
读取当前运行时持有的窗口、纹理和字体数量。
log(JSON.stringify(imgui.resourceStats()));
返回结构示例:
{
windows: 1,
textures: { count: 2, pixelBytes: 245760 },
fonts: { count: 1, sourceBytes: 7340032 }
}
imgui.diagnostics()
读取 ImGui 平台、窗口和节点程序的诊断信息。
const info = imgui.diagnostics();
log(JSON.stringify(info, null, 2));
返回对象包含 platform 和 windows。每个窗口项会报告 id、标题、位置、尺寸、显示模式和程序统计,用于排查窗口没有显示、节点绘制失败或承载权限问题。
imgui.viewports(enabled)
启用或关闭 ImGui 多视口平台窗口。
imgui.viewports(true);
imgui.viewports(false);
参数只有严格的 true 才表示启用,其他值按关闭处理。多视口创建平台窗口需要悬浮窗能力;窗口和纹理生命周期调用仍然必须在 onFrame 外执行。
imgui.capabilities()
读取当前原生实现的能力和动态常量。
const capabilities = imgui.capabilities();
log(capabilities.apiVersion);
log(capabilities.constants.WindowFlags.MenuBar);
能力对象会报告当前原生实现是否支持响应式节点、即时 API、纹理、绘图、表格、拖放、字体、停靠、多视口、虚拟列表、键盘捕获和 ImPlot 等能力,同时包含底层 ImGui/ImPlot 版本和 constants。
constants 是运行时生成的常量组,文档中的数字不需要手工硬编码。styleVarComponents 会说明每个 StyleVar 需要一个数字还是二维数组。
imgui.applySelection(selected, io, count)
把多选请求应用到脚本自己的选中索引集合。
const selected = [1, 4];
const io = frame.endMultiSelect();
const nextSelected = imgui.applySelection(selected, io, rows.length);
log(nextSelected);
| 参数 | 类型 | 说明 |
|---|---|---|
selected | array | 当前已选中的数组索引。 |
io | object | frame.beginMultiSelect() 或 frame.endMultiSelect() 返回的请求对象。 |
count | number | 总行数,必须是 0..1,000,000 的整数。 |
该函数会过滤越界索引,处理 all 和 range 请求,返回升序的新数组,不会修改传入的 selected。
动态常量的使用方式
当前所有常量都通过原生能力动态生成,也可以直接从 imgui 读取同名组:
const c = imgui.capabilities().constants;
const tableFlags = c.TableFlags.Borders | c.TableFlags.RowBg;
panel.table({
flags: tableFlags,
columns: [
{ label: "名称", flags: c.TableColumnFlags.WidthStretch }
]
});
直接使用 imgui 上的常量组更简洁:
panel.configure({ flags: imgui.WindowFlags.MenuBar });
flags 组
当前导出的标志组包括:
WindowFlags
ChildFlags
TableFlags
TableColumnFlags
TableRowFlags
TreeNodeFlags
TabBarFlags
TabItemFlags
InputTextFlags
SliderFlags
ColorEditFlags
ComboFlags
SelectableFlags
HoveredFlags
FocusedFlags
PopupFlags
DragDropFlags
ButtonFlags
DockNodeFlags
ImDrawFlags
PlotFlags
PlotAxisFlags
PlotSubplotFlags
PlotLineFlags
PlotBarsFlags
PlotBubblesFlags
PlotPolygonFlags
PlotBarGroupsFlags
PlotErrorBarsFlags
PlotInfLinesFlags
PlotHistogramFlags
PlotDragToolFlags
PlotLegendFlags
标志通常是按位值,多个选项使用 | 合并:
const flags = imgui.TableFlags.Borders |
imgui.TableFlags.RowBg |
imgui.TableFlags.Sortable;
每个组中的 None 表示数值 0,可用于明确表示“不增加额外选项”。不要把不同组的同名标志混用。
非 flags 组
| 组 | 用途 |
|---|---|
Col | 颜色索引,用于 appearance.colors、style.colors 和样式查询。 |
StyleVar | 样式变量索引,用于 appearance.vars 和样式压栈。 |
Key | 键盘键,用于即时 API 的按键查询。 |
Mod | Ctrl、Shift、Alt、Super 等修饰键。 |
Dir | Left、Right、Up、Down 方向。 |
Cond | Always、Once、FirstUseEver、Appearing 等设置条件。 |
MouseButton | Left、Right、Middle 鼠标键。 |
MouseCursor | 鼠标光标形状。 |
SortDirection | 表格排序方向。 |
PlotScale | Linear、Time、Log10、SymLog。 |
PlotMarker | None、Auto、Circle、Square、Diamond 等 marker。 |
PlotLocation | 图例位置,如 NorthEast。 |
Axis | X1..X3、Y1..Y3。 |
具体数字随底层版本变化,应使用名称而不是把数字写死。
displayMode 显示承载模式
窗口配置中的 displayMode 决定面板放在哪里。当前规范值只有三个:
| 值 | 作用 | 前置条件 |
|---|---|---|
in_app | 放在当前应用 Activity 的窗口中。 | 当前有可用的 Activity 窗口 token。 |
system_overlay | 作为系统级悬浮窗显示,可覆盖其它应用。 | 系统悬浮窗权限。 |
accessibility_overlay | 通过无障碍服务承载悬浮窗。 | 无障碍服务已经启动并具备对应能力。 |
const panel = imgui.window("overlay-panel", {
title: "跨应用调试",
displayMode: "system_overlay",
width: 480,
height: 320
});
panel.text("需要悬浮窗权限");
panel.show();
touchPassthrough: true 表示触摸尽量穿过面板;当系统悬浮窗使用该能力时,宿主会选择无障碍悬浮窗承载来实现交互转发,因此仍然需要相应权限。一个活动的 ImGui 显示会话不能混用不同显示模式;多个窗口最好统一配置。
collapsed 窗口收起状态
collapsed 是窗口配置中的布尔状态请求:
panel.configure({ collapsed: true });
// 需要展开时:
panel.configure({ collapsed: false });
传 true 表示请求收起,传 false 表示请求展开。未传该字段时由 ImGui 当前窗口状态决定。collapsible: false 可以关闭窗口的收起能力;两者不要混淆:前者是状态,后者是能力开关。
节点通用属性
所有保留式节点都会经过统一属性解析,常用的通用属性如下:
| 属性 | 类型 | 说明 |
|---|---|---|
id | string | 当前窗口内唯一的稳定名称,可被 panel.find()、弹窗动作和增量列表使用。 |
visible | boolean | 默认 true;为 false 时节点及其子树不绘制。 |
flags | number | 由具体控件或容器解释的对应常量组。 |
width / height | number | 控件、区域或绘图尺寸,具体默认值由 API 决定。 |
itemWidth | number | 设置该项目使用的输入宽度。 |
label | string | 控件或容器的显示标签。 |
onClick、onChange 等 | function 或 null | 创建时或通过 on() 注册事件。 |
属性值可以是普通值、函数或绑定对象。函数返回值会在响应式依赖变化时重新解析;对象和数组最多嵌套 64 层。
panel.onFrame(callback)
注册或移除即时帧回调。
panel.onFrame(function (frame) {
frame.text("每帧绘制");
if (frame.button("刷新")) {
log("刷新");
}
});
回调参数 frame 只在当前回调同步执行期间有效。传入 null 可以移除回调:
panel.onFrame(null);
回调中必须遵守:
- 不能调用窗口生命周期方法、加载/释放纹理或字体、等待线程、休眠或执行长时间阻塞操作。
- 所有
begin...必须在同一回调中与对应的end...配对。 - 所有
push...必须与对应的pop...配对。 - 回调抛出未处理错误时,当前窗口的即时帧回调会被停用,需要重新注册才能恢复。
frame对象不能保存到回调外异步使用,离开回调后调用会抛出异常。
保留式节点和即时帧可以共存:
panel.inputText("搜索", imgui.bind(state, "query"));
panel.onFrame(function (frame) {
frame.text("即时状态: " + state.query);
});
Android 输入法需要持续存在的节点,所以即时帧中没有可用的文本输入控件,请使用上面的保留式 panel.inputText()。
frame.call(op, properties?)
按字符串调用当前即时 API。
panel.onFrame(function (frame) {
frame.call("text", { text: "动态调用" });
const size = frame.call("getWindowSize");
log(size);
});
op 必须是当前原生即时实现支持的操作名,properties 会经过与保留式节点相同的有限数字和嵌套深度校验。直接调用具体方法通常更易读。
frame.text(text)
在当前帧绘制非格式化文本。
panel.onFrame(function (frame) {
frame.text("当前时间: " + Date.now());
});
返回值没有业务意义。
frame.button(label, options?)
在当前帧绘制按钮,返回本帧是否被点击的 boolean。
panel.onFrame(function (frame) {
if (frame.button("执行", { width: 160, height: 40 })) {
log("执行");
}
});
frame.isItemHovered(flags?)
查询上一项是否处于悬停状态,返回 boolean。flags 使用 HoveredFlags。
panel.onFrame(function (frame) {
frame.button("悬停我");
if (frame.isItemHovered(imgui.HoveredFlags.DelayShort)) {
frame.text("鼠标正在这里");
}
});
frame.isItemActive()
查询上一项是否处于活动状态,返回 boolean。
frame.isItemClicked(button?)
查询上一项是否被指定鼠标键点击,返回 boolean。button 使用 imgui.MouseButton,默认左键。
if (frame.isItemClicked(imgui.MouseButton.Right)) {
log("右键点击");
}
frame.getCursorPos()
返回当前窗口内布局光标位置 [x, y]。
frame.getContentRegionAvail()
返回当前内容区域剩余空间 [width, height]。
frame.getItemRect()
返回上一项矩形 [minX, minY, maxX, maxY]。
frame.getIO()
返回当前 ImGui 输入输出快照:
{
deltaTime: 0.016,
framerate: 60,
mousePos: [x, y],
displaySize: [width, height]
}
该对象是当前帧的普通数据快照,不是可直接写回的 IO 对象。
frame.progressBar(properties?)
绘制即时进度条。properties.value 范围按 0..1 处理,overlay 是叠加文字。
frame.progressBar({ value: 0.72, width: 260, overlay: "72%" });
frame.plotLines(properties?)
绘制即时内置折线图。
frame.plotLines({
label: "CPU",
values: [0.2, 0.4, 0.3],
width: 300,
height: 90,
min: 0,
max: 1
});
frame.plotHistogram(properties?)
绘制即时内置直方图。参数结构与 frame.plotLines() 相同。
frame.image(properties?)
绘制即时纹理。
frame.image({
texture: texture.id,
width: 160,
height: 100,
uv0: [0, 0],
uv1: [1, 1]
});
frame.imageButton(properties?)
绘制即时纹理按钮。点击结果可通过 frame.isItemClicked() 查询。
frame.imageButton({ label: "icon", texture: texture.id, width: 48, height: 48 });
if (frame.isItemClicked()) log("图标被点击");
frame.separator(properties?)
绘制即时水平分隔线。
frame.separatorText(properties?)
使用 text 属性绘制带文字的分隔线。
frame.separatorText({ text: "详情" });
frame.spacing(properties?)
插入空间;count 默认 1,范围 0..100。
frame.sameLine(properties?)
让后续控件与前一项在同一行。支持 offset 和 spacing。
frame.newLine(properties?)
移动到下一行。
frame.dummy(properties?)
插入不绘制内容的布局空间,支持 width 和 height。
frame.cursorPos(properties?)
设置窗口内光标位置。可以传 position: [x, y],也可以传 x、y。
frame.itemWidth(properties?)
设置后续项目宽度,使用 width 字段。
frame.indent(properties?)
增加缩进,使用 width 字段。
frame.unindent(properties?)
减少缩进,使用 width 字段。
frame.tableNextRow(properties?)
在已打开的表格中移动到下一行。支持 flags 和 height。
frame.tableNextColumn(properties?)
在已打开的表格中移动到下一列。
frame.tableSetColumnIndex(properties?)
在已打开的表格中跳到指定列,使用 index 字段。
frame.menuItem(properties?)
在即时菜单中绘制菜单项。支持 label、shortcut、selected、enabled 和 flags。
if (frame.menuItem({ label: "刷新", enabled: true })) {
log("菜单项被点击");
}
frame.invisibleButton(properties?)
绘制没有视觉内容但可交互的按钮。使用 label、width、height 和 flags。
frame.arrowButton(properties?)
绘制方向箭头按钮。使用 label 和 direction,方向是 imgui.Dir.Left、Right、Up 或 Down。
frame.colorButton(properties?)
绘制即时颜色按钮。颜色使用 color 字段,点击后用 frame.isItemClicked() 查询。
frame.labelText(properties?)
即时绘制标签文本,使用 label 和 text 字段。
frame.bullet(properties?)
即时绘制项目符号。
frame.textLink(properties?)
即时绘制可点击链接文本,使用 label 字段。
frame.tabItemButton(properties?)
在即时页签栏中绘制页签按钮,使用 label 和 flags。
frame.alignTextToFramePadding(properties?)
把后续文字基线对齐到控件内边距。
即时控件的参数和返回值
即时控件不创建保留式节点,统一把属性放在一个对象中:
panel.onFrame(function (frame) {
const result = frame.sliderInt({
label: "数量",
value: 3,
min: 0,
max: 10
});
if (result.changed) {
log("新值: " + result.value);
}
});
除按钮、菜单项、链接和页签按钮这类点击项目返回 boolean 外,可编辑即时控件通常返回 { changed, value }。如果要让值跨帧保留,需要在下一帧把上一次的 value 再传回去;需要自动双向同步的场景使用保留式节点和 imgui.bind()。
frame.checkbox(properties?)
即时复选框。properties 使用 label、value、flags。
panel.onFrame(function (frame) {
const result = frame.checkbox({ label: "启用", value: state.enabled });
if (result.changed) state.enabled = result.value;
});
返回 { changed: boolean, value: boolean }。
frame.selectable(properties?)
即时可选择行。value 是布尔值,支持 width、height 和 flags。
const result = frame.selectable({
label: "当前方法",
value: state.selected,
flags: imgui.SelectableFlags.AllowDoubleClick
});
返回 { changed, value }。
frame.inputInt(properties?)
即时整数输入框。value 是整数,支持 step、stepFast、flags。
const result = frame.inputInt({
label: "次数",
value: state.count,
step: 1,
stepFast: 10
});
state.count = result.value;
frame.inputFloat(properties?)
即时浮点输入框。支持 step、stepFast、flags,显示格式为 %.3f。
frame.inputDouble(properties?)
即时双精度输入框。支持 step、stepFast、flags,显示格式为 %.6f。
frame.sliderInt(properties?)
即时整数滑块。min 默认 0,max 默认 100,支持 SliderFlags。
frame.sliderFloat(properties?)
即时浮点滑块。min 默认 0,max 默认 1,显示格式为 %.3f。
frame.sliderAngle(properties?)
即时角度滑块。value 使用弧度,min、max 使用度数,默认范围 -360..360 度。
frame.vSliderInt(properties?)
即时竖直整数滑块。需要 width、height、value、min 和 max。
frame.vSliderFloat(properties?)
即时竖直浮点滑块。需要 width、height、value、min 和 max。
frame.dragInt(properties?)
即时整数拖动控件。speed 默认 1,min 默认 0,max 默认 100。
frame.dragFloat(properties?)
即时浮点拖动控件。speed 默认 0.1,min 默认 0,max 默认 1。
frame.inputInt2(properties?)
即时编辑两个整数,value 必须是长度 2 的数组。
frame.inputInt3(properties?)
即时编辑三个整数,value 必须是长度 3 的数组。
frame.inputInt4(properties?)
即时编辑四个整数,value 必须是长度 4 的数组。
frame.inputFloat2(properties?)
即时编辑两个浮点数,value 必须是长度 2 的数组。
frame.inputFloat3(properties?)
即时编辑三个浮点数,value 必须是长度 3 的数组。
frame.inputFloat4(properties?)
即时编辑四个浮点数,value 必须是长度 4 的数组。
frame.sliderInt2(properties?)
即时编辑两个整数滑块。value 是长度 2 数组,min 默认 0,max 默认 100。
frame.sliderInt3(properties?)
即时编辑三个整数滑块。value 是长度 3 数组。
frame.sliderInt4(properties?)
即时编辑四个整数滑块。value 是长度 4 数组。
frame.sliderFloat2(properties?)
即时编辑两个浮点滑块。value 是长度 2 数组,min 默认 0,max 默认 1。
frame.sliderFloat3(properties?)
即时编辑三个浮点滑块。value 是长度 3 数组。
frame.sliderFloat4(properties?)
即时编辑四个浮点滑块。value 是长度 4 数组。
frame.dragInt2(properties?)
即时拖动编辑两个整数,value 是长度 2 数组。
frame.dragInt3(properties?)
即时拖动编辑三个整数,value 是长度 3 数组。
frame.dragInt4(properties?)
即时拖动编辑四个整数,value 是长度 4 数组。
frame.dragFloat2(properties?)
即时拖动编辑两个浮点数,value 是长度 2 数组。
frame.dragFloat3(properties?)
即时拖动编辑三个浮点数,value 是长度 3 数组。
frame.dragFloat4(properties?)
即时拖动编辑四个浮点数,value 是长度 4 数组。
frame.dragIntRange2(properties?)
即时编辑整数范围,value 是 [low, high] 数组,支持 speed、min、max。
frame.dragFloatRange2(properties?)
即时编辑浮点范围,value 是 [low, high] 数组,支持 speed、min、max。
frame.combo(properties?)
即时下拉选择。items 是字符串数组,value 是选中项下标。
const result = frame.combo({
label: "模式",
value: state.mode,
items: ["自动", "手动", "暂停"],
flags: imgui.ComboFlags.HeightRegular
});
state.mode = result.value;
frame.listBox(properties?)
即时列表框。items 是字符串数组,value 是下标,heightInItems 控制可见行数。
frame.radio(properties?)
即时单选组。items 是字符串数组,value 是选中下标,horizontal: true 时横向排列。
frame.colorEdit(properties?)
即时 RGBA 颜色编辑。value 使用 RGB/RGBA 数组,分量范围 0..1,支持 ColorEditFlags。
frame.colorEdit3(properties?)
即时 RGB 颜色编辑。value 必须是长度 3 数组。
frame.colorPicker(properties?)
即时 RGBA 颜色选择器。支持 reference 参考颜色和 ColorEditFlags。
frame.colorPicker3(properties?)
即时 RGB 颜色选择器。value 必须是长度 3 数组。
frame.inputScalar(properties?)
即时单值底层标量编辑。dataType 可选 s8、u8、s16、u16、s32、u32、s64、u64、float、double,默认 float。
frame.inputScalarN(properties?)
即时多值底层标量编辑。value 是数组,components 范围 1..16,必须与数组长度一致。
frame.dragScalar(properties?)
即时单值底层标量拖动编辑。支持 dataType、speed、min 和 max。
frame.dragScalarN(properties?)
即时多值底层标量拖动编辑。value 是数组,components 必须匹配长度。
frame.sliderScalar(properties?)
即时单值底层标量滑块。必须提供 min 和 max,并满足 min < max。
frame.sliderScalarN(properties?)
即时多值底层标量滑块。必须提供有效范围,components 必须匹配数组长度。
frame.vSliderScalar(properties?)
即时竖直底层标量滑块。需要 width、height、min、max 和 dataType。
即时标量的 64 位整数规则与保留式标量控件相同:超出 JavaScript 安全整数范围时使用十进制字符串;无符号类型不能传负数。
frame.checkboxFlags(properties?)
即时位掩码复选框。value 是整数,mask 是要切换的位,默认 1。
const result = frame.checkboxFlags({
label: "写入权限",
value: permissions,
mask: 2
});
permissions = result.value;
frame.radioButton(properties?)
即时单个单选按钮。value 是整数,点击时设置为 buttonValue。
const result = frame.radioButton({
label: "自动",
value: mode,
buttonValue: 0
});
mode = result.value;
frame.plotDragPoint(properties?)
即时可拖动图表点。value 必须是 [x, y],并且要在已经打开的图表中调用。
frame.plotDragLineX(properties?)
即时可拖动竖直图表线。value 是数字,并且要在已经打开的图表中调用。
frame.plotDragLineY(properties?)
即时可拖动水平图表线。value 是数字,并且要在已经打开的图表中调用。
frame.plotDragRect(properties?)
即时可拖动图表矩形。value 必须是 [x1, y1, x2, y2],并且要在已经打开的图表中调用。
这些即时拖动工具返回 { changed, value },size 仅适用于点且默认 6,thickness 仅适用于线且默认 1;两者都会在原生允许范围内限制。
即时容器的配对规则
即时容器由 begin... 和 end... 两个函数组成。只有 begin... 返回 true 时才绘制内部内容,但无论返回什么都要在同一层级调用对应的 end...。
panel.onFrame(function (frame) {
if (frame.beginChild({ id: "child", width: 300, height: 160 })) {
frame.text("子区域");
}
frame.endChild();
});
不要把某个 begin 的返回值当成节点对象,也不要跨帧保存 Begin/End 状态。
frame.beginChild(properties?)
开始即时子区域。属性支持 label 或 id、width、height、childFlags 和 flags。返回是否可以绘制子内容的 boolean。
frame.endChild(properties?)
结束 beginChild()。
frame.beginGroup(properties?)
开始即时布局组。返回值没有业务意义。
frame.endGroup(properties?)
结束 beginGroup()。
frame.beginDisabled(properties?)
让后续即时内容进入禁用状态。disabled 默认 true。
frame.endDisabled(properties?)
结束 beginDisabled()。
frame.beginCombo(properties?)
开始自定义即时下拉区域。属性使用 label、preview 和 flags,返回 boolean。
if (frame.beginCombo({ label: "模式", preview: "自动" })) {
frame.selectable({ label: "自动", value: true });
frame.selectable({ label: "手动", value: false });
frame.endCombo();
}
frame.endCombo(properties?)
结束 beginCombo()。
frame.beginListBox(properties?)
开始自定义即时列表框。属性使用 label、width、height,返回 boolean。
frame.endListBox(properties?)
结束 beginListBox()。
frame.treeNode(properties?)
开始即时树节点。属性使用 label 和 flags,返回是否展开的 boolean。若未使用 NoTreePushOnOpen,展开时必须调用 frame.treePop()。
frame.treePop(properties?)
结束已展开的即时树节点。
frame.beginTable(properties?)
开始即时表格。属性支持 label、columns、flags、width、height、headers、freezeRows、freezeColumns 和 angledHeaders,返回 boolean。
if (frame.beginTable({
label: "table",
columns: ["名称", "状态"],
flags: imgui.TableFlags.Borders | imgui.TableFlags.RowBg
})) {
frame.tableNextRow();
frame.text("main");
frame.tableNextColumn();
frame.text("运行中");
frame.endTable();
}
表格参数与保留式 panel.table() 相同,列数限制为 1..64。
frame.endTable(properties?)
结束 beginTable()。
frame.beginTabBar(properties?)
开始即时页签栏。属性使用 label 或 id、flags,返回 boolean。
frame.endTabBar(properties?)
结束 beginTabBar()。
frame.beginTabItem(properties?)
开始即时页签。属性使用 label、flags,返回当前页签是否可见的 boolean。
frame.endTabItem(properties?)
结束 beginTabItem()。
frame.beginMenuBar(properties?)
开始即时菜单栏,返回 boolean。
frame.endMenuBar(properties?)
结束 beginMenuBar()。
frame.beginMenu(properties?)
开始即时菜单。属性使用 label、enabled,返回 boolean。
frame.endMenu(properties?)
结束 beginMenu()。
frame.beginPopup(properties?)
开始即时普通弹窗。属性使用 label 和 flags,返回 boolean。
frame.beginPopupModal(properties?)
开始即时模态弹窗。属性使用 label 和 flags,返回 boolean。
frame.beginPopupContextItem(properties?)
开始绑定当前项目的即时上下文菜单。属性可以使用 label、id 和 popupFlags,返回 boolean。
frame.beginPopupContextWindow(properties?)
开始绑定当前窗口的即时上下文菜单。属性可以使用 label、id 和 popupFlags,返回 boolean。
frame.beginPopupContextVoid(properties?)
开始绑定空白区域的即时上下文菜单。属性可以使用 label、id 和 popupFlags,返回 boolean。
frame.endPopup(properties?)
结束 beginPopup()、beginPopupModal() 或上下文菜单。
frame.openPopup(properties?)
打开即时弹窗。使用 label 指定弹窗名;之后在合适位置调用对应的 begin 方法。
frame.openPopup({ label: "confirm" });
frame.closeCurrentPopup(properties?)
关闭当前打开的即时弹窗。
frame.beginTooltip(properties?)
开始即时工具提示,返回 boolean。
frame.endTooltip(properties?)
结束即时工具提示。
frame.pushID(properties?)
压入即时 id 作用域,使用 id 字段。
frame.pushID({ id: "row-1" });
frame.button("打开");
frame.popID();
frame.popID(properties?)
结束 pushID() 作用域。
frame.pushStyleColor(properties?)
压入一个临时颜色。使用 index 指定 imgui.Col 名称对应的数字,使用 value 指定颜色。
frame.pushStyleColor({
index: imgui.Col.Text,
value: "#ffcc66"
});
frame.text("高亮文字");
frame.popStyleColor();
frame.popStyleColor(properties?)
弹出临时颜色。count 默认 1,不能超过当前已压入的颜色数量。
frame.pushStyleVar(properties?)
压入临时样式变量。使用 index 指定 StyleVar,使用 value 传数字或二维数组,具体形状由变量决定。
frame.popStyleVar(properties?)
弹出临时样式变量。count 默认 1,不能超过当前已压入的变量数量。
frame.setKeyboardFocusHere(properties?)
把键盘焦点设置到后续项目。可传 offset 指定相对后续项目的偏移。
frame.setScrollHereY(properties?)
让当前项目在垂直滚动区域中可见。ratio 范围通常为 0..1,默认 0.5,表示居中。
frame.beginWindow(properties?)
开始一个即时停靠/平台窗口。属性与 panel.dockWindow() 的窗口属性相近,至少应提供 label 或 id。
panel.onFrame(function (frame) {
if (frame.beginWindow({
id: "extra",
label: "额外窗口",
width: 320,
height: 220,
open: true
})) {
frame.text("额外窗口内容");
}
frame.endWindow();
});
返回 boolean。即使返回 false,也必须调用 endWindow()。
frame.endWindow(properties?)
结束 beginWindow()。
frame.beginPlot(properties?)
开始即时 ImPlot 图表区域。属性与 panel.plot() 的图表属性相同,返回 boolean。
if (frame.beginPlot({ label: "即时曲线", height: 240 })) {
frame.plotLine({ label: "A", y: [1, 3, 2, 4] });
frame.endPlot();
}
frame.endPlot(properties?)
结束 beginPlot()。
frame.beginSubplots(properties?)
开始即时多图布局。支持 label、rows、columns、width、height 和 flags,返回 boolean。
frame.endSubplots(properties?)
结束 beginSubplots()。
frame.pushFont(properties?)
在当前即时作用域使用字体。font 传字体对象或字体 id,size 可选。
frame.pushFont({ font: font, size: 22 });
frame.text("使用自定义字体");
frame.popFont();
frame.popFont(properties?)
结束 pushFont()。
frame.pushClipRect(properties?)
压入即时裁剪矩形。支持 min、max、screenSpace 和 intersect。
frame.popClipRect(properties?)
结束 pushClipRect()。
frame.dockSpace(properties?)
在即时帧中绘制停靠空间。支持 id、dockId、width、height、flags 和可选 layout。
frame.plotLine(properties?)
在即时图表中绘制折线。属性与保留式 panel.plotLine() 相同,使用 x、y 或 values 提供数据。
frame.plotScatter(properties?)
在即时图表中绘制散点。
frame.plotBars(properties?)
在即时图表中绘制柱状图,支持 barSize。
frame.plotStairs(properties?)
在即时图表中绘制阶梯线。
frame.plotShaded(properties?)
在即时图表中绘制填充区域,支持 baseline 或同长度 y2。
frame.plotStems(properties?)
在即时图表中绘制茎状图,支持 baseline。
frame.plotHeatmap(properties?)
在即时图表中绘制热力图,rows * columns 必须等于数据长度。
frame.plotPie(properties?)
在即时图表中绘制饼图,labels.length 必须等于 values.length。
frame.plotHistogram1D(properties?)
在即时图表中绘制一维直方图,bins 范围 1..10000。
frame.plotBubbles(properties?)
在即时图表中绘制气泡图,sizes 必须与 x、y 等长且不能为负数。
frame.plotPolygon(properties?)
在即时图表中绘制多边形,至少需要三个点。
frame.plotBarGroups(properties?)
在即时图表中绘制分组柱状图,values.length 必须等于 labels.length * groups。
frame.plotErrorBars(properties?)
在即时图表中绘制误差线,negative 必须与数据等长且不能为负数。
frame.plotInfLines(properties?)
在即时图表中绘制水平无限线,values 是有限数字数组。
frame.plotHistogram2D(properties?)
在即时图表中绘制二维直方图,xBins、yBins 范围 1..512。
frame.plotImage(properties?)
在即时图表坐标中绘制纹理,texture 传 texture.id。
frame.plotText(properties?)
在即时图表坐标中绘制文字,text 和 position: [x, y] 必填。
frame.plotDummy(properties?)
在即时图表中登记一个不绘制数据的系列。
frame.drawLine(properties?)
即时绘制线段,支持 from、to、color、thickness、layer 和 screenSpace。
frame.drawRect(properties?)
即时绘制矩形,支持 min、max、filled、rounding 和 flags。
frame.drawCircle(properties?)
即时绘制圆形,支持 center、radius、segments 和 filled。
frame.drawText(properties?)
即时绘制文字,支持 position、text、font、size 和 wrapWidth。
frame.drawImage(properties?)
即时绘制纹理矩形,texture 传纹理 id,支持 min、max、uv0、uv1。
frame.drawPolyline(properties?)
即时绘制折线,points 至少两个点,flags 可使用 ImDrawFlags.Closed。
frame.drawTriangle(properties?)
即时绘制三角形,支持 a、b、c、filled。
frame.drawBezierCubic(properties?)
即时绘制三次贝塞尔曲线,支持 p1、p2、p3、p4 和 segments。
frame.drawBezierQuadratic(properties?)
即时绘制二次贝塞尔曲线,支持 p1、p2、p3 和 segments。
frame.drawEllipse(properties?)
即时绘制椭圆,支持 center、radius、rotation、segments 和 filled。
frame.drawNgon(properties?)
即时绘制正多边形,支持 center、radius、segments 和 filled。
frame.drawQuad(properties?)
即时绘制四边形,支持 a、b、c、d 和 filled。
frame.drawPolygon(properties?)
即时绘制填充多边形,points 最多 8192 个,concave 可切换凹多边形填充。
frame.drawRectGradient(properties?)
即时绘制四角渐变矩形,colors 必须正好四个颜色。
frame.drawImageQuad(properties?)
即时把纹理绘制到四边形,使用 texture、a、b、c、d 和 uv1..uv4。
frame.drawImageRounded(properties?)
即时绘制圆角纹理矩形,使用 texture、min、max、rounding 和 flags。
frame.drawPath(properties?)
即时绘制命令路径。命令格式、命令数量和坐标规则与保留式 panel.drawPath() 相同。
frame.isItemFocused()
查询上一项是否拥有键盘或导航焦点,返回 boolean。
frame.isItemDeactivatedAfterEdit()
查询上一项是否刚刚结束编辑,返回 boolean。它适合在即时帧中判断输入框、拖动控件或滑块的编辑提交时刻。
frame.getWindowPos()
返回当前即时窗口左上角的屏幕坐标 [x, y]。
frame.getWindowSize()
返回当前即时窗口尺寸 [width, height]。
frame.getTime()
返回 ImGui 内部运行时间,单位为秒,类型为 number。
panel.onFrame(function (frame) {
frame.text("运行了 " + frame.getTime().toFixed(1) + " 秒");
});
frame.getFrameCount()
返回 ImGui 已处理的帧计数,类型为整数。
frame.isKeyPressed(properties?)
查询指定键是否在当前帧按下。使用 key 和可选的 repeat:
if (frame.isKeyPressed({
key: imgui.Key.F5,
repeat: true
})) {
log("收到 F5");
}
key 必须是 imgui.Key 中的命名键;repeat 默认 true,表示允许按住键连续触发。
frame.isMouseDown(properties?)
查询鼠标键当前是否按下。button 使用 imgui.MouseButton,默认 0(左键)。
if (frame.isMouseDown({ button: imgui.MouseButton.Left })) {
frame.text("左键按住中");
}
frame.isMouseDragging(properties?)
查询指定鼠标键是否正在拖动。支持 button 和 threshold,threshold 是启动拖动所需的像素距离,省略时使用 ImGui 默认值。
frame.getMousePos(properties?)
返回鼠标屏幕坐标 [x, y]。没有有效鼠标位置时,原生值可能是负数。
frame.getMouseDragDelta(properties?)
返回鼠标拖动位移 [dx, dy]。
const delta = frame.getMouseDragDelta({
button: imgui.MouseButton.Left,
threshold: 3
});
button 范围是 0..4,超出范围会抛出异常。
frame.resetMouseDragDelta(properties?)
重置指定鼠标键的拖动起点。使用 button,范围 0..4。
frame.isMouseDoubleClicked(properties?)
查询指定鼠标键是否双击,返回 boolean。使用 button,范围 0..4。
frame.getMouseClickedCount(properties?)
返回指定鼠标键在当前点击序列中的点击次数。使用 button,范围 0..4。
frame.isAnyMouseDown(properties?)
查询是否有任意鼠标键按下,返回 boolean。
frame.getMouseCursor(properties?)
返回当前鼠标光标枚举值,可与 imgui.MouseCursor 比较。
frame.setMouseCursor(properties?)
设置鼠标光标形状。
frame.setMouseCursor({ cursor: imgui.MouseCursor.Hand });
cursor 必须是有效的 MouseCursor 枚举值。
frame.isKeyDown(properties?)
查询指定命名键当前是否按住,使用 key。
frame.isKeyReleased(properties?)
查询指定命名键是否在当前帧释放,使用 key。
frame.getKeyName(properties?)
获取指定命名键的显示名称。
log(frame.getKeyName({ key: imgui.Key.Enter }));
key 必须位于 ImGui 命名键范围内。
frame.isItemActivated(properties?)
查询上一项是否刚刚激活,返回 boolean。
frame.isItemDeactivated(properties?)
查询上一项是否刚刚失去激活状态,返回 boolean。
frame.isItemToggledOpen(properties?)
查询上一项的展开状态是否在当前帧改变,返回 boolean,常用于树节点。
frame.isAnyItemHovered(properties?)
查询当前窗口中是否有任意项目处于悬停状态。
frame.isAnyItemActive(properties?)
查询当前窗口中是否有任意项目处于活动状态。
frame.isAnyItemFocused(properties?)
查询当前窗口中是否有任意项目拥有焦点。
frame.getItemID(properties?)
返回上一项的 ImGui 数字 id。
frame.getItemRectSize(properties?)
返回上一项尺寸 [width, height]。
frame.getTextLineHeight(properties?)
返回当前字体单行文字高度。
frame.getTextLineHeightWithSpacing(properties?)
返回当前字体单行文字高度加上垂直间距。
frame.getFrameHeight(properties?)
返回当前控件框架高度。
frame.getFrameHeightWithSpacing(properties?)
返回当前控件框架高度加上垂直间距。
frame.getFontSize(properties?)
返回当前字体字号。
frame.calcItemWidth(properties?)
返回当前布局规则下下一个项目的计算宽度。
frame.isRectVisible(properties?)
判断指定尺寸的矩形是否位于当前可视区域。
const visible = frame.isRectVisible({ size: [320, 80] });
size 必须是 [width, height]。
frame.setCursorScreenPos(properties?)
设置屏幕绝对布局光标位置。
frame.setCursorScreenPos({ position: [100, 160] });
frame.text("从屏幕坐标绘制");
position 必须是 [x, y]。
frame.setNextItemAllowOverlap(properties?)
允许下一个项目与其它项目重叠。它只影响紧接着的下一个项目。
frame.setNavCursorVisible(properties?)
设置导航光标是否可见。visible 默认 true。
frame.getWindowViewport(properties?)
读取当前窗口的视口信息。
const viewport = frame.getWindowViewport();
返回:
{
id: 1,
position: [0, 0],
size: [1080, 1920],
workPosition: [0, 24],
workSize: [1080, 1872],
dpiScale: 1
}
frame.getScrollY(properties?)
返回当前滚动区域的垂直滚动位置。
frame.getScrollMaxY(properties?)
返回垂直方向还能滚动的最大位置。
frame.setScrollY(properties?)
设置垂直滚动位置,使用 value。
frame.setScrollY({ value: 200 });
frame.getScrollX(properties?)
返回当前滚动区域的水平滚动位置。
frame.getScrollMaxX(properties?)
返回水平方向还能滚动的最大位置。
frame.setScrollX(properties?)
设置水平滚动位置,使用 value。
frame.setItemDefaultFocus(properties?)
请求把默认焦点设置到上一项。
frame.setNextItemSelectionUserData(properties?)
为下一个多选项目设置用户数据。
frame.setNextItemSelectionUserData({ value: index });
frame.selectable({ label: row.name, value: selected.has(index) });
value 必须是 JavaScript 安全整数,范围为 -9007199254740991..9007199254740991,并且不能带小数。
frame.isItemToggledSelection(properties?)
查询上一项是否在多选交互中切换了选中状态,返回 boolean。
frame.isWindowFocused(properties?)
查询当前窗口是否有焦点。flags 使用 FocusedFlags。
frame.isWindowHovered(properties?)
查询当前窗口是否处于悬停状态。flags 使用 HoveredFlags。
frame.isItemVisible(properties?)
查询上一项是否可见,返回 boolean。
frame.isItemEdited(properties?)
查询上一项是否被编辑,返回 boolean。
frame.isMouseReleased(properties?)
查询指定鼠标键是否在当前帧释放。button 范围 0..4。
frame.beginMultiSelect(properties?)
开始即时多选交互,并返回当前帧需要脚本处理的选择请求。
panel.onFrame(function (frame) {
const io = frame.beginMultiSelect({
flags: imgui.MultiSelectFlags.None,
selectionSize: selected.size,
itemsCount: rows.length
});
for (let index = 0; index < rows.length; index++) {
frame.setNextItemSelectionUserData({ value: index });
const item = frame.selectable({
label: rows[index].name,
value: selected.has(index),
flags: imgui.SelectableFlags.AllowDoubleClick
});
if (item.changed) {
if (item.value) selected.add(index);
else selected.delete(index);
}
}
const end = frame.endMultiSelect();
const next = imgui.applySelection(Array.from(selected), end, rows.length);
selected = new Set(next);
});
| 属性 | 说明 |
|---|---|
flags | MultiSelectFlags 的组合值。 |
selectionSize | 当前选中数量,省略时使用 -1。 |
itemsCount | 项目总数,省略时使用 -1。 |
返回对象包含 requests 数组和 rangeSource。请求项的 type 是 all 或 range,selected 表示要选中还是取消,范围请求还包含 first、last。
frame.endMultiSelect(properties?)
结束 beginMultiSelect() 并返回本帧最终选择请求。必须与开始调用配对。
frame.tableGetSortSpecs(properties?)
在已打开的表格内读取排序规格。
const specs = frame.tableGetSortSpecs({ acknowledge: true });
// [[columnIndex, sortDirection], ...]
acknowledge: true 会确认当前排序规格已被脚本处理。该接口必须在表格内部调用,否则抛出异常。
frame.tableGetColumnCount(properties?)
返回当前表格列数。必须在表格内部调用。
frame.tableGetColumnIndex(properties?)
返回当前表格光标所在列索引。必须在表格内部调用。
frame.tableGetRowIndex(properties?)
返回当前表格行索引。必须在表格内部调用。
frame.tableGetColumnName(properties?)
读取列名。可传 column 指定列索引,省略时使用原生当前列规则。
const name = frame.tableGetColumnName({ column: 0 });
列索引必须在当前表格范围内。
frame.tableGetColumnFlags(properties?)
读取列标志数字。使用 column 指定列索引,返回值可与 TableColumnFlags 比较。
frame.tableGetHoveredColumn(properties?)
返回当前鼠标悬停的列索引;没有悬停列时由原生 ImGui 返回对应的负值。
frame.tableSetColumnEnabled(properties?)
启用或关闭当前表格的一列。
frame.tableSetColumnEnabled({ column: 2, enabled: false });
column 必须是非负列索引,enabled 默认 true。
frame.tableSetBgColor(properties?)
设置当前表格单元格、行或表格的背景色。
frame.tableSetBgColor({
target: 1,
color: "#203040",
column: -1
});
target 是原生表格背景目标数字,当前实现只接受 1..3;color 使用颜色字符串或 RGB/RGBA 数组;column 可选,具体作用取决于目标。
frame.getDataStats(properties?)
读取 virtualList 或 plotStream 的增量数据统计。
const stats = frame.getDataStats({ id: list.id });
id 必须是当前窗口中拥有增量数据的节点 id。虚拟列表返回行数、总高度以及可选的索引高度/位置;实时图表返回点数、环形偏移和首尾点。
frame.getPlotLimits(properties?)
读取当前图表范围 [xMin, xMax, yMin, yMax]。必须在 beginPlot() 与 endPlot() 之间调用。
frame.getPlotMousePos(properties?)
读取鼠标在当前图表坐标系中的位置 [x, y]。必须在打开的图表中调用。
frame.isPlotHovered(properties?)
查询当前图表是否被鼠标悬停,返回 boolean。
frame.saveLayout(properties?)
保存当前即时停靠布局。
const layout = frame.saveLayout();
files.write("/sdcard/imgui-layout.json", JSON.stringify(layout));
返回版本为 1 的布局对象,包含 spaces 和 floating:
{
version: 1,
spaces: {
main: {
direction: "left",
ratio: 0.35,
first: { windows: ["inspector"] },
second: { windows: ["console"], selected: "console" }
}
},
floating: [
{ id: "preview", position: [40, 80], size: [360, 240] }
]
}
分割节点的 direction 只能是 left、right、up、down,ratio 范围 0.05..0.95;叶子节点的 windows 最多 128 个。布局树深度最多 16。
frame.loadLayout(properties?)
加载即时停靠布局。使用 data 传 frame.saveLayout() 产生的对象。
const layout = JSON.parse(files.read("/sdcard/imgui-layout.json"));
frame.loadLayout({ data: layout });
布局版本必须是 1。浮动窗口最多 128 个,每个尺寸的有效范围为 1..8192;非法树结构、未知方向、比例越界或窗口 id 不合法时会抛出异常。
