# MeasurePanel 组件详细文档

> 本文档详细描述 `MeasurePanel`（测量面板）组件的实现细节，包括 API、UI 结构、逻辑流程等，供后续维护/AI 重现。
> 
> 重要说明：**本组件仅实现 UI，不实现真实测量算法**（不做拾取、画线、计算等）。测量结果通过对外方法注入，仅用于展示。

---

## 1. 组件概述

### 1.1 基本信息
- **组件名称**：`MeasurePanel`
- **文件路径**：`src/components/measure-panel/index.ts`
- **类型定义**：`src/components/measure-panel/types.ts`
- **样式文件**：`src/components/measure-panel/index.css`
- **实现接口**：`IBimComponent`

### 1.2 在 SDK 中的位置
- `MeasurePanel` 是内部 UI 组件
- 由 `MeasureDialogManager` 创建并挂载到 `BimDialog` 中
- 外部业务（SDK 使用者）不直接 import 组件类，统一通过 `engine.measure`（Manager）调用

### 1.3 配置项（单位/精度）与缓存策略（新增）
- **创建 `MeasurePanel` 不传入单位/精度**
- 默认配置由组件内部维护：
  - `unit`: `'mm'`
  - `precision`: `2`（即 `0.00`）
- 组件初始化时会读取缓存（`localStorage`）：
  - key：`bim-engine:measure:config`
  - 若缓存存在且合法，则使用缓存值覆盖默认配置
  - 若缓存不存在/解析失败，则使用默认配置
- 用户在设置面板点击“保存设置”后，组件会写入缓存

---

## 2. 组件类 API 文档

### 2.1 构造函数

```typescript
constructor(options?: MeasurePanelOptions)
```

**参数**：
- `options.defaultMode?`: 默认测量方式（不传默认 `distance`）
- `options.defaultExpanded?`: 是否默认展开（不传默认 `false`，即只显示前 4 个）
- `options.onModeChange?`: 用户切换测量方式时回调
- `options.onClearAll?`: 用户点击“删除全部”时回调
- `options.onSettings?`: 用户点击“设置”时回调

### 2.2 公共方法

#### `init(): void`
- 初始化订阅（主题/语言），并刷新 UI 状态（展开/选中态/结果区）。

#### `setTheme(theme: ThemeConfig): void`
- 将主题色映射到 CSS 变量（按钮背景、hover、active、文字、分割线等）。

#### `setLocales(): void`
- 更新所有用户可见文本：
  - 8 个按钮的 tooltip（图标占位时 tooltip 是主要可读文本）
  - 展开/收起按钮 tooltip
  - “删除全部”文本
  - “设置”tooltip
  - “当前测量方式”显示文本
  - 主值 label（随模式变化）
  - X/Y/Z 标签

#### `destroy(): void`
- 取消主题/语言订阅并移除 DOM。

#### `getActiveMode(): MeasureMode`
- 获取当前选中的测量方式。

#### `switchMode(mode: MeasureMode): void`
- **切换类型的方法**：切换当前测量方式（等价于 `setActiveMode`）。

#### `setActiveMode(mode: MeasureMode): void`
- 设置当前测量方式，并触发 `onModeChange`（如果提供）。

#### `setResult(result: MeasureResult | null): void`
- 外部注入测量结果：
  - `null`：清空显示（主值与 xyz 均显示 `--`）
  - 非 null：根据当前 mode 显示对应字段的值

#### `clearAll(): void`
- 清空结果展示并触发 `onClearAll`（如果提供）。

#### `openSettings(): void`
- 进入组件内部“设置面板”（单位/精度选择）。
- 同时触发 `onSettings`（如果提供，作为外部监听）。

#### `getConfig(): MeasureConfig`
- 获取当前测量配置（单位/精度）。

#### `setConfig(partial: Partial<MeasureConfig>, persist = false): void`
- 更新配置：
  - `persist=false`：仅更新内存，不写缓存
  - `persist=true`：更新并写入 `localStorage`

#### `setExpanded(expanded: boolean): void`
- 展开/收起按钮区（收起时只显示前 4 个）。

#### `getExpanded(): boolean`
- 获取当前是否展开。

---

## 3. 分化组件说明

- 无

---

## 4. Manager API 文档（关联）

### 4.1 MeasureDialogManager（关联文件）
- `src/managers/measure-dialog-manager.ts`

### 4.2 相关对外方法（本次新增/补齐）
- `getActiveMode(): MeasureMode | null`
- `switchMode(mode: MeasureMode): void`
- `setResult(result: MeasureResult | null): void`
- `clearAll(): void`
- `openSettings(): void`

---

## 5. UI 详细描述

### 5.1 DOM 结构（核心）

```html
<div class="bim-measure-panel">
  <!-- 主视图 -->
  <div class="bim-measure-main">
  <div class="bim-measure-tools">
    <div class="bim-measure-tool-grid">
      <!-- 8 个按钮：收起时隐藏后 4 个 -->
      <button class="bim-measure-tool-btn is-active" data-mode="distance">
        <span class="bim-measure-tool-icon">（圆形占位 svg）</span>
      </button>
      <!-- ... -->
    </div>

    <div class="bim-measure-toggle">
      <button class="bim-measure-toggle-btn">
        <!-- 箭头 svg，展开时旋转 180deg -->
      </button>
    </div>
  </div>

  <div class="bim-measure-result">
    <div class="bim-measure-row">
      <span class="label">当前测量方式：</span>
      <span class="value">距离</span>
    </div>

    <div class="bim-measure-row">
      <span class="label">距离：</span>
      <span class="value">--</span>
    </div>

    <div class="bim-measure-xyz">
      <div class="bim-measure-row"><span class="label">X：</span><span class="value">--</span></div>
      <div class="bim-measure-row"><span class="label">Y：</span><span class="value">--</span></div>
      <div class="bim-measure-row"><span class="label">Z：</span><span class="value">--</span></div>
    </div>
  </div>

  <div class="bim-measure-footer">
    <button class="bim-measure-clear-btn">删除全部</button>
    <button class="bim-measure-settings-btn">（齿轮 svg）</button>
  </div>
  </div>

  <!-- 设置视图（点击设置按钮进入） -->
  <div class="bim-measure-settings">
    <div class="bim-measure-settings-title">设置</div>

    <div class="bim-measure-settings-row">
      <div class="label">单位：</div>
      <select class="bim-measure-settings-select">
        <option value="m">m</option>
        <option value="cm">cm</option>
        <option value="mm">mm</option>
        <option value="km">km</option>
      </select>
    </div>

    <div class="bim-measure-settings-row">
      <div class="label">精度：</div>
      <select class="bim-measure-settings-select">
        <option value="0">0</option>
        <option value="1">0.0</option>
        <option value="2">0.00</option>
        <option value="3">0.000</option>
      </select>
    </div>

    <div class="bim-measure-settings-actions">
      <button class="bim-measure-settings-save">保存设置</button>
      <button class="bim-measure-settings-cancel">取消</button>
    </div>
  </div>
</div>
```

### 5.2 CSS 类名说明
- `.bim-measure-tool-grid`: 4 列网格布局
- `.bim-measure-tool-btn.is-active`: 当前选中态
- `.bim-measure-toggle-btn.is-expanded`: 展开态（箭头旋转）
- `.bim-measure-result`: 结果区，顶部与底部用分割线隔开

---

## 6. 逻辑流程详细描述

### 6.1 初始化
- 构造函数创建 DOM，但不订阅
- `init()`：
  - 订阅 `localeManager`、`themeManager`
  - 调用 `setLocales()`、`setTheme()`
  - 应用展开状态（隐藏/显示后 4 个按钮）
  - 应用选中态
  - 渲染结果（初始为 `--`）

### 6.2 切换测量方式
- 点击按钮或调用 `switchMode/setActiveMode`
- 更新内部 `activeMode`
- 刷新按钮选中态
- 更新“当前测量方式”文本
- 更新主值 label
- 触发 `onModeChange`（若提供）
- 重新渲染结果

### 6.3 注入结果
- 调用 `setResult(result)`
- 保存 result 并刷新结果区：
  - 主值：根据 mode 显示对应字段
  - xyz：无则显示 `--`

---

## 7. 国际化支持

### 7.1 使用的翻译键（核心）
- `measure.modes.*`：8 种模式名
- `measure.actions.*`：展开/收起/删除全部/设置
- `measure.labels.*`：当前方式、X/Y/Z、主值 label
- `measure.units.*`：mm/°/m³/% 等单位

---

## 8. 主题支持

### 8.1 CSS 变量（核心）
- `--bim-measure-border`
- `--bim-measure-divider`
- `--bim-measure-btn-bg` / `--bim-measure-btn-hover-bg` / `--bim-measure-btn-active-bg`
- `--bim-measure-label-color` / `--bim-measure-value-color`
- `--bim-measure-icon-color`

---

## 9. 使用示例（通过 Manager）

```typescript
// 通过工具栏点击“测量”按钮打开弹窗后：外部可以这样注入展示数据
engine.measure.switchMode('angle');
engine.measure.setResult({ angleDeg: 12.34, xyz: { x: 1, y: 2, z: 3 } });

// 清空
engine.measure.clearAll();
```

---

## 10. 实现细节（供 AI 重现）

### 10.1 关键点
- 模式列表严格按需求顺序渲染
- 收起时隐藏后 4 个按钮（通过 `style.display = 'none'`）
- 图标占位统一用圆形 SVG
- 主值显示使用 `formatWithUnit`（单位走国际化）

---

## 11. 类型定义

见 `src/components/measure-panel/types.ts`：
- `MeasureMode`
- `MeasureResult`
- `MeasurePanelOptions`

---

## 12. 文件清单

- `src/components/measure-panel/index.ts`
- `src/components/measure-panel/index.css`
- `src/components/measure-panel/types.ts`
- 关联：`src/managers/measure-dialog-manager.ts`


