快捷键
Studio 的键盘快捷键由一个中央命令注册表(editor.shortcuts)支持,
而不是散布在各个面板中的硬编码按键检查。每个快捷键都可以重新绑定,冲突
会被自动检测,菜单项会显示它们当前的绑定。
默认快捷键
| 命令 | 默认 | 上下文 |
|---|---|---|
| 撤销 | Ctrl+Z |
全局 |
| 重做 | Ctrl+Shift+Z, Ctrl+Y |
全局 |
| 复制 | Ctrl+C |
全局 |
| 剪切 | Ctrl+X |
全局 |
| 粘贴 | Ctrl+V |
全局 |
| Play / Stop | Ctrl+P |
全局 |
| 保存 | Ctrl+S |
全局 |
| 全部保存 | Ctrl+Shift+S |
全局 |
| 关闭标签页 | Ctrl+W |
全局 |
| 下一个/上一个标签页 | Ctrl+Tab / Ctrl+Shift+Tab |
全局 |
| 移动 / 旋转 / 缩放工具 | W / E / R |
Scene View(悬停) |
| 聚焦所选 | F |
Scene View(悬停) |
| 重命名 | F2 |
Hierarchy / Asset Browser(聚焦时) |
| 删除 | Delete, Backspace |
Hierarchy / Asset Browser(聚焦时) |
“全局”命令无论哪个面板处于聚焦状态都会触发。面板作用域的命令(Scene
View 的工具按键、Hierarchy/Asset Browser 的重命名与导航)只有在你实际正
在与该特定面板交互时才会触发——悬停在视口上,或点击了某一行/图块——而不
仅仅因为该面板恰好在屏幕上的某处打开着。这正是为什么,例如,当你在别处
的重命名字段中输入 R 时,Scene View 的 R 键不会把 gizmo 切换到缩放
模式。
在任何文本字段中输入时,也会抑制所有未按住 Ctrl 或 Cmd 的快捷 键——普通字母键和 Shift+字母键始终会到达你正在编辑的字段。
重新绑定
打开 Turian ▸ Settings,在侧边栏选择 Shortcuts 分类。每一行显示 命令、它作用域所属的面板,以及当前的绑定:
- 点击绑定按钮并按下新的按键组合。Esc 取消;Backspace 完全清除 绑定(该命令会变为未绑定状态,而不仅仅是“重置回默认值”)。
- 当某个绑定与另一个作用域重叠的命令(两个全局命令,或一个全局命令和一 个面板作用域命令)冲突时,其旁边会出现警告图标——悬停查看它与哪个命令 冲突。冲突的绑定仍然是被允许的,和大多数编辑器一样;这只是一个警告, 而不是硬性阻止。
- 被覆盖的行旁边的还原图标会将该命令重置回默认值。Reset All 会对所 有命令执行相同的操作。
- 重新绑定会在你操作时立即生效。Save 会将其写入设置文件;Reload 会丢弃任何未保存的重新绑定。
菜单标签
拥有已注册命令的菜单项会在右侧以暗淡的颜色显示其当前快捷键,该内容实时 取自注册表——在 Shortcuts 设置面板中进行的重新绑定会在下一帧反映到菜单 中,无需另外维护同步的文本。
面向插件/模块作者
命令是在运行时注册的,而不是在某个中央文件中声明——每个功能模块拥有自己
的命令,这与 studio/main-window/Panels.zig 让每个面板自行注册的方式相
同:
const Shortcuts = @import("studio/services/Shortcuts.zig");
const my_commands = [_]Shortcuts.CommandDesc{
.{
.id = "myPlugin.doThing",
.title = "Do The Thing",
.context = .global, // 或 .scene_viewport / .hierarchy / .asset_browser / .ui_editor / .text_input
.requires_focus = false, // 如果这只在你的面板实际处于交互状态时才有意义,则设为 true
.defaults = &.{Shortcuts.Binding.single(.{ .key = .t, .ctrl = true })},
},
};
const my_handlers = [_]?Shortcuts.Handler{myHandler};
// 只需一次,例如在第一次 draw 时:
Shortcuts.register(&my_commands, &my_handlers);
对于作用域限定在你自己面板内的命令(context 不是 .global),不要传
入 handler——而是直接在你面板自己的事件循环中检查它,取代硬编码的按键
检查:
for (gui.events()) |*e| {
if (Shortcuts.eventMatches(e, "myPlugin.panelAction", panel_is_engaged)) {
e.handle(@src(), my_widget_data);
doPanelAction();
}
}
panel_is_engaged 是“用户正在查看我的面板”对你而言所代表的任何含义——
对于基于 widget 的面板,是真正的 dvui 键盘焦点;对于像 3D 视口这样不可
聚焦的表面,则是鼠标悬停。
命令 ID 是带命名空间的字符串(area.action),同时也充当设置键的后缀
(shortcut.<command_id>)——请选择一个你愿意保持稳定的 ID,因为重命名
它会使任何用户已保存的重新绑定失效。