mobile-eda/docs/PHASE2_UI_COMPONENTS.md

501 lines
12 KiB
Markdown
Raw Permalink 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.

# Phase 2 UI 组件库实现文档
**阶段**: Week 3-4
**交付日期**: 2026-03-07
**负责人**: UI/UX 设计师
**状态**: ✅ 已完成
---
## 📦 交付内容
### 任务 1工具栏组件 ✅
**文件**: `lib/presentation/widgets/toolbar_widget.dart`
**功能特性**:
- ✅ 顶部工具栏:撤销/重做/保存/设置
- ✅ 底部工具栏:元件库/走线模式/选择模式
- ✅ 支持可折叠/隐藏
- ✅ 模式切换状态管理
- ✅ 动画过渡效果
- ✅ 响应式布局
**核心 API**:
```dart
ToolbarWidget(
showTopToolbar: true,
showBottomToolbar: true,
collapsible: true,
onUndo: () => ...,
onRedo: () => ...,
onSave: () => ...,
onSettings: () => ...,
onComponentLibrary: () => ...,
onWireMode: () => ...,
onSelectMode: () => ...,
)
```
**设计亮点**:
- 采用 Material Design 卡片式设计
- 顶部工具栏支持滑动手势收起/展开
- 底部工具栏模式按钮有高亮状态
- 工具栏按钮带有 Tooltip 提示
---
### 任务 2属性面板组件 ✅
**文件**: `lib/presentation/widgets/property_panel_widget.dart`
**功能特性**:
- ✅ 弹出式属性编辑(元件值、封装、网络名)
- ✅ 实时预览修改效果
- ✅ 输入验证与错误提示
- ✅ 位号格式验证R1, C2, U3
- ✅ 元件值格式验证10k, 100n 等)
- ✅ 封装格式验证
- ✅ 旋转控制0°, 90°, 180°, 270°
- ✅ 镜像控制(水平/垂直)
- ✅ 未保存状态提示
**核心 API**:
```dart
// 直接使用组件
PropertyPanelWidget(
propertyData: PropertyData(
refDesignator: 'R1',
value: '10k',
footprint: '0805',
componentType: ComponentType.resistor,
),
onPropertyChanged: (data) => ...,
onPreview: (data) => ...,
)
// 或使用辅助函数
final result = await showPropertyPanel(
context,
propertyData: ...,
onPropertyChanged: (data) => ...,
);
```
**数据模型**:
```dart
class PropertyData {
String? refDesignator; // 位号
String? value; // 值
String? footprint; // 封装
String? netName; // 网络名
ComponentType componentType;
String? symbolName;
int rotation; // 0, 90, 180, 270
bool mirrorX;
bool mirrorY;
}
```
**验证规则**:
- 位号:必须为 `字母 + 数字` 格式(如 R1, C2, U3
- 电阻值:支持 `10k`, `4.7M`, `100R` 等格式
- 电容值:支持 `10u`, `100n`, `1p` 等格式
- 封装:必须包含字母和数字(如 0805, SOT23
**设计亮点**:
- 底部抽屉式弹出,符合移动端交互习惯
- 实时输入验证,错误即时提示
- 旋转按钮可视化展示角度
- 未保存状态有明显提示
---
### 任务 3元件库面板组件 ✅
**文件**: `lib/presentation/widgets/component_library_panel.dart`
**功能特性**:
- ✅ 网格/列表双视图切换
- ✅ 搜索与筛选(按类别、封装、厂商)
- ✅ 拖拽元件到画布
- ✅ 类别筛选FilterChip
- ✅ 封装筛选
- ✅ 搜索防抖300ms
- ✅ 长按查看详情
- ✅ 可拖拽拖动手柄
**核心 API**:
```dart
// 直接使用组件
ComponentLibraryPanel(
initialViewMode: LibraryViewMode.grid,
onComponentSelected: (item) => ...,
onDragStarted: (item) => ...,
onFilterChanged: (filters) => ...,
)
// 或使用辅助函数(抽屉式)
await showComponentLibraryDrawer(
context,
initialViewMode: LibraryViewMode.grid,
onComponentSelected: (item) => ...,
);
```
**数据模型**:
```dart
class ComponentLibraryItem {
final String name;
final String category;
final String footprint;
final String? description;
final String? manufacturer;
final String? symbolData;
}
enum LibraryViewMode {
grid, // 网格视图
list, // 列表视图
}
```
**筛选功能**:
- 类别:电源、被动元件、半导体、连接器、光电器件、集成电路
- 封装0402, 0603, 0805, 1206, SOT23, SOT223, SOIC8, DIP8, QFN16
- 搜索:支持名称和描述模糊匹配
**拖拽支持**:
- 使用 Flutter Draggable 组件
- 拖拽时显示半透明原位置
- 拖拽反馈组件带有高亮边框
- 支持长按查看详情后再拖拽
**设计亮点**:
- 网格视图2 列布局,卡片式设计
- 列表视图ListTile 布局,信息更详细
- 搜索栏带清除按钮
- 筛选面板可展开/收起
- 空状态友好提示
---
## 🎨 设计规范
### 遵循 Phase 1 触摸交互规范 v1.0
1. **最小触控区域**: 所有按钮 ≥ 44x44ptiOS 人机指南)
2. **手势支持**:
- 单击:选择/触发
- 长按:上下文菜单/详情
- 拖拽:元件放置
- 双指缩放:画布导航(编辑器层面)
3. **视觉反馈**:
- 按钮按下有涟漪效果
- 选中状态有高亮
- 拖拽时有半透明提示
4. **动画过渡**: 200ms 标准动画时长
### Material Design 3 风格
- 圆角8px小组件、12px卡片、16px面板
- 阴影:轻度阴影(模糊 8px偏移 0,2
- 配色:使用 Theme.of(context).primaryColor
- 字体:系统默认字体,字号 10-20sp
---
## 🔌 集成指南
### 1. 在原理图编辑器中集成
```dart
import 'package:mobile_eda/presentation/widgets/widgets.dart';
class SchematicEditorScreen extends ConsumerStatefulWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
children: [
// 画布
SchematicCanvas(),
// 工具栏
ToolbarWidget(
onUndo: _undo,
onRedo: _redo,
onSave: _save,
onSettings: _showSettings,
onComponentLibrary: _showLibrary,
onWireMode: _setWireMode,
onSelectMode: _setSelectMode,
),
],
),
// 或作为底部抽屉显示元件库
bottomSheet: ComponentLibraryPanel(
onComponentSelected: _addComponent,
),
);
}
}
```
### 2. 属性编辑集成
```dart
// 双击元件时显示属性面板
void _onComponentDoubleTap(SchematicComponent component) async {
final propertyData = PropertyData(
refDesignator: component.ref,
value: component.value,
footprint: component.footprint,
componentType: _mapToComponentType(component.type),
rotation: component.rotation,
mirrorX: component.mirrorX,
mirrorY: component.mirrorY,
);
final result = await showPropertyPanel(
context,
propertyData: propertyData,
onPreview: (data) {
// 实时预览:临时更新画布显示
_previewComponentChanges(data);
},
onPropertyChanged: (data) {
// 应用更改
_updateComponent(component.id, data);
},
);
if (result != null) {
// 保存成功
_commitChanges();
} else {
// 取消,恢复原状
_revertPreview();
}
}
```
### 3. 元件拖拽集成
```dart
// 在画布上接收拖拽
class SchematicCanvas extends StatefulWidget {
@override
Widget build(BuildContext context) {
return DragTarget<ComponentLibraryItem>(
onWillAccept: (data) => true,
onAccept: (component) {
// 在拖拽位置放置元件
_placeComponent(component, _lastDragPosition);
},
builder: (context, candidateData, rejectedData) {
return CustomPaint(painter: SchematicPainter());
},
);
}
}
```
### 4. Riverpod 状态管理集成
```dart
// 创建状态提供者
final toolbarModeProvider = StateProvider<ToolbarMode>((ref) {
return ToolbarMode.select;
});
final propertyPanelProvider = StateProvider<PropertyData?>((ref) {
return null;
});
final componentLibraryFilterProvider = StateProvider<FilterOptions>((ref) {
return FilterOptions();
});
// 在组件中使用
class _SchematicEditorScreenState extends ConsumerState {
@override
Widget build(BuildContext context) {
final mode = ref.watch(toolbarModeProvider);
return ToolbarWidget(
onSelectMode: () => ref.read(toolbarModeProvider.notifier).state = ToolbarMode.select,
onWireMode: () => ref.read(toolbarModeProvider.notifier).state = ToolbarMode.wire,
);
}
}
```
---
## 📁 文件结构
```
mobile-eda/lib/presentation/widgets/
├── widgets.dart # 导出文件barrel
├── toolbar_widget.dart # 工具栏组件
├── property_panel_widget.dart # 属性面板组件
└── component_library_panel.dart # 元件库面板组件
```
---
## 🧪 测试建议
### 单元测试
```dart
test('PropertyData copy creates independent copy', () {
final original = PropertyData(
refDesignator: 'R1',
value: '10k',
componentType: ComponentType.resistor,
);
final copy = original.copy();
copy.refDesignator = 'R2';
expect(original.refDesignator, equals('R1'));
expect(copy.refDesignator, equals('R2'));
});
test('ToolbarWidget callbacks are invoked', () {
var undoCalled = false;
final widget = ToolbarWidget(
onUndo: () => undoCalled = true,
);
// 使用 tester.tap() 模拟点击撤销按钮
// expect(undoCalled, isTrue);
});
```
### 组件测试
```dart
testWidgets('PropertyPanelWidget validates ref designator', (tester) async {
await tester.pumpWidget(
MaterialApp(
home: PropertyPanelWidget(
propertyData: PropertyData(
componentType: ComponentType.resistor,
),
),
),
);
// 输入无效位号
await tester.enterText(find.byType(TextFormField).first, 'invalid');
await tester.pump();
// 验证错误提示
expect(find.text('位号格式错误 (如 R1, C2, U3)'), findsOneWidget);
});
```
---
## 🚀 后续优化建议
### 性能优化
1. **元件库懒加载**: 当元件数量 > 100 时,使用分页或虚拟列表
2. **图片缓存**: 元件符号图片使用 cached_network_image
3. **防抖优化**: 搜索已实现 300ms 防抖
### 功能增强
1. **最近使用**: 添加"最近使用元件"快速访问
2. **收藏功能**: 允许用户收藏常用元件
3. **自定义元件**: 支持用户创建和导入自定义元件
4. **批量编辑**: 支持多选元件批量修改属性
### 用户体验
1. **快捷键支持**: 桌面端可添加键盘快捷键Ctrl+Z 撤销等)
2. **语音输入**: 支持语音输入元件值("十千欧"
3. **AR 预览**: 使用 AR 查看元件实物图
---
## 📞 与 EDA 引擎专家协作
### 需要对接的 API
1. **元件放置**:
```dart
// 需要 EDA 引擎提供
void placeComponent(ComponentLibraryItem item, Offset position);
```
2. **属性更新**:
```dart
// 需要 EDA 引擎提供
void updateComponentProperties(String componentId, PropertyData properties);
```
3. **模式切换**:
```dart
// 需要 EDA 引擎提供
void setEditorMode(EditorMode mode);
```
4. **撤销/重做**:
```dart
// 需要 EDA 引擎提供
void undo();
void redo();
bool get canUndo;
bool get canRedo;
```
### 数据格式约定
```dart
// 元件唯一标识
typedef ComponentId = String;
// 坐标系统
// - 画布坐标:逻辑像素,原点在左上角
// - 网格吸附:默认 10.0 网格大小
// 旋转角度
// - 0: 默认方向
// - 90: 顺时针 90 度
// - 180: 顺时针 180 度
// - 270: 顺时针 270 度
```
---
## ✅ 验收标准
- [x] 工具栏组件可正常显示/隐藏
- [x] 工具栏按钮点击有响应
- [x] 属性面板可弹出/关闭
- [x] 属性输入有验证提示
- [x] 元件库支持网格/列表切换
- [x] 元件库支持搜索筛选
- [x] 元件可拖拽Draggable
- [x] 代码符合 Flutter 规范flutter analyze 通过)
- [x] 组件文档完整
---
## 📝 更新日志
**2026-03-07** - 初始版本
- ✅ 完成工具栏组件
- ✅ 完成属性面板组件
- ✅ 完成元件库面板组件
- ✅ 编写集成文档
---
**交付完成** 🎉
所有组件已实现并经过基本测试,可集成到原理图编辑器中使用。