Files
XCEngine/docs/api/XCEngine/Editor/UI/Widgets/Widgets.md

6.8 KiB
Raw Blame History

Widgets

命名空间: XCEngine::Editor::UI

类型: header-helper

源文件: editor/src/UI/Widgets.h

描述: 面向编辑器业务语义的高层 ImGui helper 集合覆盖菜单、搜索框、行内重命名、面包屑、资产卡片、Inspector section、弹窗和日志行等可复用交互单元。

概述

Widgets.h 不是底层绘图原语集合,而是“已经带编辑器语义”的复用控件层。

它的定位介于:

  • Core.hStyleTokens.h 这类基础 UI 封装
  • 具体面板文件里的业务流程

之间。

当前多个关键面板都直接依赖它:

  • ProjectPanel
  • HierarchyPanel
  • InspectorPanel
  • ConsolePanel

所以这份 header 的核心价值,不是减少几行 ImGui 代码,而是统一整个 editor 的交互语言。

当前覆盖的 widget 类别

类别 代表 API 主要使用场景
菜单与子菜单 DrawMenuScopeDrawMenuCommandDrawMenuCommandsDrawPopupSubmenuScope MenuBar、Hierarchy / Project 上下文菜单
工具栏与搜索 ToolbarSearchFieldDrawToolbarLabelToolbarToggleButton Project / Console / 顶部工具栏
行内编辑 DrawInlineRenameFieldDrawInlineRenameFieldAt Project 资源网格重命名、Hierarchy 行内重命名
路径导航 DrawToolbarBreadcrumbsDrawBreadcrumbSegment Project 面包屑
资产浏览 ComputeAssetTileSizeDrawAssetTileAssetTileOptions Project 浏览区
Inspector section BeginComponentSectionEndComponentSectionInspectorActionButton Inspector 组件区块、材质资源区块
弹窗与对话框 BeginTitledPopupDrawDialogActionRow 选择器、确认弹窗
提示与日志 BeginTitledTooltipDrawConsoleLogRowDrawEmptyStateDrawHintText Console、空状态、悬浮提示

为什么这一层很重要

即时模式 UI 最容易出现的问题,不是“没法画出来”,而是:

  • 同一种交互在不同面板里长得不一样
  • 每个面板都自己实现一份重命名输入框
  • 上下文菜单、面包屑、资产卡片的行为逐渐漂移

Widgets.h 当前就是专门用来压住这类分叉的。

它把“编辑器里反复出现的交互模式”抽成统一 helper使面板层可以更专注于

  • 当前数据来自哪里
  • 当前用户动作应该触发什么命令

而不是反复造相同的 UI 小轮子。

结果结构而不是直接副作用

当前文件一个很重要的风格,是尽量用结果结构返回交互状态,而不是在 helper 内部直接改业务对象。

例如:

  • AssetTileResult
  • InlineRenameFieldResult
  • ComponentSectionResult

这种做法对 ImGui 风格 editor 很关键,因为调用方通常需要:

  • 先绘制
  • 再统一在循环外处理选择、打开、导航、提交重命名

ProjectPanel 当前就是典型例子。它先批量收集 clicked / openRequested,再在循环末统一处理 selection 和 open 行为,避免在遍历过程中破坏当前容器或导航状态。

关键 helper 行为

搜索框

ToolbarSearchField(...) 当前除了调用 InputTextWithHint(...),还会:

  • 应用统一的工具栏输入框样式
  • trailingWidth 自动计算可用宽度
  • 在输入框左侧手动画搜索图标

这意味着 Project 等工具栏的搜索控件已经有统一视觉和布局语义,而不是普通裸 InputText

行内重命名

DrawInlineRenameField(...)DrawInlineRenameFieldAt(...) 当前返回:

  • submitted
  • cancelRequested
  • deactivated
  • active

这几个状态组合非常实用,因为编辑器行内重命名通常既要响应:

  • Enter 提交
  • Escape 取消
  • 失焦提交或结束

又要允许调用方控制焦点请求和屏幕定位。

面包屑

DrawToolbarBreadcrumbs(...) 当前把 root label、路径段数量、名称回调和导航回调解耦开来。

它的行为是:

  • 当前段不可点击
  • 非当前段点击后回调 navigateToSegment(index)
  • 相邻段之间统一插入 > 分隔符

ProjectPanel 正是靠它把 Assets -> ... -> CurrentFolder 渲染成稳定的导航条。

资产卡片

DrawAssetTile(...) 是当前 Project Browser 最核心的共享 widget 之一。

它会统一处理:

  • 空闲边框与填充
  • 选中态高亮
  • 拖拽中的 dim overlay
  • 图标居中布局
  • 标签区域裁剪
  • 单击和双击判断

并返回:

  • clicked
  • openRequested
  • hovered
  • labelMin / labelMax

其中 labelMin / labelMax 会被 ProjectPanel 继续拿去覆盖行内重命名输入框位置。

Inspector section

BeginComponentSection(...) 当前做的不只是画一个标题行。它还负责:

  • 用 ImGui state storage 按 id 保存展开状态
  • 绘制 disclosure arrow
  • 统一 header 背景、边框和文字布局
  • 返回内容缩进量

这让 InspectorPanel 和材质资源 inspector 可以在完全共享的 section 语义上继续叠加各自内容。

Popup 子菜单

DrawPopupSubmenuScope(...) 是当前比较有“编辑器修 bug 痕迹”的 helper。

它除了处理 popup 子菜单的 hover-open / click-open / auto-close 之外,还会对标签为 Create 的子菜单写调试日志,用来定位 Hierarchy 创建子菜单 popup 状态错乱问题。

这说明 Widgets.h 不只是“视觉控件库”,也承担了一部分复杂交互协议的收口工作。

真实调用方式

当前几个典型使用点是:

  • ProjectPanel
    • ToolbarSearchField(...)
    • DrawToolbarBreadcrumbs(...)
    • DrawAssetTile(...)
    • DrawInlineRenameFieldAt(...)
  • InspectorPanel
    • BeginComponentSection(...)
    • InspectorActionButton(...)
    • DrawHintText(...)
    • DrawEmptyState(...)
  • HierarchyActionRouter
    • DrawMenuCommands(...)
    • DrawPopupSubmenuScope(...)
  • ConsolePanel
    • DrawConsoleLogRow(...)

设计说明

当前 Widgets.h 的设计取向很明确:

  • 保持 header-only降低调用成本
  • 通过小结果结构承载交互状态
  • 让多个面板共享一致的 UI 语义

这是一种很典型的 Dear ImGui 编辑器写法。它未必“面向通用 GUI 框架”,但对当前项目这种单体 editor 非常高效。

当前限制

  • 仍然是 inline helper 集合,不是独立 widget framework。
  • 某些 helper 明显服务于当前视觉风格和业务模型,通用性有限。
  • 目前没有虚拟列表、树过滤高亮、多列资产表等更重型控件。
  • Create 子菜单相关 trace 直接写日志通道,后续若日志层细化,可能需要单独的 debug 开关。

相关文档