bricks/docs/cn/toolbar.md
2025-10-12 17:59:59 +08:00

368 lines
9.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# `bricks.Toolbar` 技术文档
> **模块**`bricks.Toolbar`
> **继承自**`bricks.Layout`
> **用途**:创建可配置的工具栏组件,支持水平/垂直布局、动态工具项生成、点击事件分发及可移除按钮功能。
---
## 概述
`bricks.Toolbar` 是一个基于 `bricks.Layout` 的类,用于构建可视化工具栏。它支持横向或纵向排列的按钮工具项,并提供灵活的配置选项,包括图标、标签、样式、事件绑定等。工具栏中的每个工具项可以触发命令事件,并可选择性地添加“删除”图标以支持动态移除。
该组件使用异步方式创建工具项,确保渲染性能,并通过 `bricks.widgetBuild` 工厂方法统一创建子控件。
---
## 构造函数
### `constructor(options)`
初始化工具栏实例。
#### 参数
| 参数名 | 类型 | 说明 |
|-------|------|------|
| `options` | Object | 配置对象,继承自 `bricks.Layout` 并扩展以下属性 |
#### `options` 属性
| 属性 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `orientation` | String | `'horizontal'` | 布局方向:`'horizontal'``'vertical'` |
| `target` | Any | `undefined` | 可选的目标引用,会在事件数据中传递 |
| `interval` | String 或 Number | `'10px'` | 工具项之间的间隔尺寸CSS 单位) |
| `tools` | Array<Object> | `[]` | 工具项描述数组,每项包含图标、名称、标签等信息 |
| `css` | String | `'toolbar'` | 自定义 CSS 前缀类名 |
#### 示例
```js
var toolbar = new bricks.Toolbar({
orientation: 'horizontal',
target: myComponent,
interval: '15px',
css: 'my-toolbar',
tools: [
{ name: 'save', label: '保存', icon: 'save-icon.svg' },
{ name: 'delete', label: '删除', icon: 'del-icon.svg', removable: true }
]
});
```
#### 实现细节
- 根据 `orientation` 创建 `HScrollPanel`(水平)或 `VScrollPanel`(垂直)作为内部容器。
- 添加对应 CSS 类:`.htoolbar``.vtoolbar`
- 启用键盘选择:`enable_key_select()`
- 使用 `schedule_once` 延迟调用 `createTools()`,避免阻塞主线程。
---
## 成员变量
| 变量 | 类型 | 描述 |
|------|------|------|
| `bar` | `bricks.HScrollPanel` / `bricks.VScrollPanel` | 内部滚动面板容器 |
| `toolList` | Array<Widget> | 存储所有已创建的工具按钮实例 |
| `clicked_btn` | Widget 或 null | 当前被激活(点击)的按钮 |
| `preffix_css` | String | CSS 类前缀,用于激活状态样式 |
---
## 方法说明
### `add_interval_box()`
在当前工具栏中插入一个间隔空白区域(`JsWidget`),其大小由 `options.interval` 控制,方向根据 `orientation` 决定。
#### 行为逻辑
- 若为垂直布局 → 设置高度
- 若为水平布局 → 设置宽度
#### 示例效果
```css
width: 10px; /* 水平间距 */
height: 10px; /* 垂直间距 */
```
> 调用时机:在 `createTools()` 中,两个工具之间自动插入。
---
### `async createTools()`
异步批量创建所有工具项。
#### 流程
1. 遍历 `this.opts.tools`
2. 调用 `createTool(desc)` 逐个创建
3. 在非最后一个工具后调用 `add_interval_box()`
#### 注意事项
- 使用 `await` 确保顺序执行(可用于动画或依赖加载)
- 初始延迟 10ms 执行(通过 `schedule_once(..., 0.01)`
---
### `async createTool(desc)`
创建单个工具按钮。
#### 参数
| 参数 | 类型 | 说明 |
|------|------|------|
| `desc` | Object | 工具描述对象,结构如下 |
##### `desc` 结构(工具项配置)
| 属性 | 类型 | 是否必需 | 说明 |
|------|------|----------|------|
| `name` | String | ✅ | 工具唯一标识符(用于事件名) |
| `label` | String | ❌ | 显示文本 |
| `icon` | String | ❌ | 图标 URL 或 class 名称 |
| `css` | String | ❌ | 自定义按钮 CSS 类 |
| `removable` | Boolean | ❌ | 是否显示删除图标,默认 `false` |
#### 返回值
- `{Promise<bricks.Widget>}`:成功时返回按钮控件;失败返回 `undefined`
#### 内部逻辑
1. 构造 `widgetBuild` 所需的选项
2. 调用 `bricks.widgetBuild(options)` 异步创建按钮
3. 绑定 `click` 事件到 `do_handle`
4. 将按钮加入 `toolList``bar` 容器
5.`removable == true`,调用 `add_removable(w)`
6. 触发 `remove` 事件(当用户点击删除图标时)
---
### `remove_item(w, event)`
从工具栏中移除指定工具项。
#### 参数
| 参数 | 类型 | 说明 |
|------|------|------|
| `w` | Widget | 要移除的按钮控件 |
| `event` | Event | DOM 事件对象 |
#### 动作
-`bar` 中移除控件
- 取消选中状态
-`toolList` 数组中删除
- 解绑 `click` 事件监听器
- 分发 `remove` 事件,携带 `tool_opts`
- 阻止事件冒泡和默认行为
---
### `do_handle(tool, event)`
处理工具按钮点击事件。
#### 参数
| 参数 | 类型 | 说明 |
|------|------|------|
| `tool` | Widget | 被点击的按钮实例 |
| `event` | Event | 原始事件对象 |
#### 功能
1. 输出调试日志
2. 构建事件数据 `d`,合并 `tool.tool_opts` 和可选 `target`
3.`bar` 上标记该按钮为选中状态
4. 分发两个事件:
- `'command'`:通用命令事件
- `[tool.name]`:以工具名命名的特定事件(如 `'save'`, `'delete'`
5. 更新激活按钮的 CSS 样式:
- 清除上一个激活按钮的样式
- 为当前按钮添加 `prefix-css + '-button-active'`
6. 记录当前点击按钮至 `this.clicked_btn`
#### 示例事件数据
```js
{
name: "save",
label: "保存",
icon: "save-icon.svg",
target: myComponent
}
```
---
### `add_removable(item)`
为指定工具项添加可删除的 SVG “×” 图标。
#### 参数
| 参数 | 类型 | 说明 |
|------|------|------|
| `item` | Widget | 支持移除的工具按钮 |
#### 条件判断
- 仅当 `item.tool_opts.removable === true` 时执行
#### 实现步骤
1. 加载 SVG 删除图标(路径来自 `bricks_resource('imgs/delete.svg')`
2. 创建 `bricks.Svg` 控件并插入按钮内
3. 绑定点击事件到 `remove_item`
4. 输出调试信息
#### 错误处理
-`Svg` 创建失败,输出错误日志
---
### `click(name)`
模拟点击某个工具按钮(通过名称查找)。
#### 参数
| 参数 | 类型 | 说明 |
|------|------|------|
| `name` | String | 工具项的 `name` 字段 |
#### 行为
遍历 `toolList`,找到匹配 `name` 的按钮并触发其原生 DOM 的 `.click()` 方法,从而激活 `do_handle`
#### 应用场景
- 外部程序化触发某个命令
- 快捷键绑定
---
## 事件系统
`Toolbar` 支持以下事件分发:
| 事件名 | 触发条件 | 携带数据 |
|--------|----------|---------|
| `command` | 任意工具被点击 | 合并后的工具选项 + target |
| `[tool.name]` | 特定工具被点击 | 同上 |
| `remove` | 用户点击删除图标 | 被删除工具的原始 `tool_opts` |
可通过 `bind(event, handler)` 监听这些事件。
#### 示例监听
```js
toolbar.bind('save', function(data) {
console.log('保存操作触发:', data);
});
toolbar.bind('command', function(cmd) {
console.log('收到命令:', cmd.name);
});
```
---
## 样式类说明
| CSS 类 | 作用 |
|-------|------|
| `.htoolbar` | 水平工具栏根元素样式 |
| `.vtoolbar` | 垂直工具栏根元素样式 |
| `.toolbar-button-active` | 激活按钮状态(默认前缀) |
| `[custom]-button-active` | 自定义前缀激活样式(由 `css` 选项控制) |
> 推荐在主题 CSS 中定义相关样式。
---
## 注册与工厂模式
```js
bricks.Factory.register('Toolbar', bricks.Toolbar);
```
允许通过字符串标识符创建实例:
```js
bricks.create({
widgettype: 'Toolbar',
options: { ... }
});
```
---
## 使用示例
### 完整 HTML 示例
```html
<div id="toolbar-container"></div>
<script>
var toolbar = new bricks.Toolbar({
container: document.getElementById('toolbar-container'),
orientation: 'horizontal',
interval: '12px',
target: app.mainView,
css: 'app-toolbar',
tools: [
{ name: 'new', label: '新建', icon: 'icons/new.svg' },
{ name: 'open', label: '打开', icon: 'icons/open.svg' },
{ name: 'save', label: '保存', icon: 'icons/save.svg', removable: true }
]
});
// 监听事件
toolbar.bind('save', function(data) {
console.log('正在保存...', data.target);
});
// 程序触发
setTimeout(() => toolbar.click('new'), 1000);
</script>
```
---
## 调试信息
启用 `bricks.debug` 后,会输出以下信息:
- 工具构建失败
- 删除图标加载结果
- 点击事件详情
- 可移除功能启用状态
建议开发阶段开启调试模式。
---
## 总结
`bricks.Toolbar` 提供了一个现代化、可扩展的工具栏解决方案,具备以下特性:
✅ 支持横竖布局
✅ 动态工具生成
✅ 事件驱动架构
✅ 支持可删除项
✅ 样式可定制
✅ 兼容工厂创建模式
适合集成于富客户端应用、编辑器、IDE 工具条等场景。