// 示例:如何在原理图编辑器中集成 Phase 2 UI 组件 // 文件位置:mobile-eda/lib/presentation/screens/schematic_editor_screen_v2.dart import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../widgets/widgets.dart'; /// 原理图编辑器页面(集成 Phase 2 UI 组件版本) /// /// 演示如何集成: /// - ToolbarWidget(工具栏) /// - PropertyPanelWidget(属性面板) /// - ComponentLibraryPanel(元件库) class SchematicEditorScreenV2 extends ConsumerStatefulWidget { final String? projectId; const SchematicEditorScreenV2({super.key, this.projectId}); @override ConsumerState createState() => _SchematicEditorScreenV2State(); } class _SchematicEditorScreenV2State extends ConsumerState { // 当前编辑器模式 EditorMode _editorMode = EditorMode.select; // 当前选中的元件 SchematicComponent? _selectedComponent; // 是否显示元件库 bool _showLibrary = false; @override Widget build(BuildContext context) { return Scaffold( body: Stack( children: [ // 1. 原理图画布 Positioned.fill( child: SchematicCanvas( editorMode: _editorMode, selectedComponent: _selectedComponent, onComponentTap: _onComponentTap, onComponentDoubleTap: _onComponentDoubleTap, ), ), // 2. 顶部和底部工具栏 ToolbarWidget( showTopToolbar: true, showBottomToolbar: true, collapsible: true, onUndo: _undo, onRedo: _redo, onSave: _save, onSettings: _showSettings, onComponentLibrary: _toggleLibrary, onWireMode: () => _setMode(EditorMode.wire), onSelectMode: () => _setMode(EditorMode.select), ), // 3. 元件库(可选:作为底部抽屉) if (_showLibrary) Positioned( bottom: 80, // 在底部工具栏上方 left: 8, right: 8, child: Container( height: 300, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.1), blurRadius: 8, offset: const Offset(0, -2), ), ], ), child: ComponentLibraryPanel( initialViewMode: LibraryViewMode.grid, onComponentSelected: _addComponentFromLibrary, ), ), ), ], ), ); } // ========== 画布交互处理 ========== void _onComponentTap(SchematicComponent component) { setState(() { _selectedComponent = component; }); } void _onComponentDoubleTap(SchematicComponent component) async { // 显示属性面板 final propertyData = PropertyData( refDesignator: component.ref, value: component.value, footprint: component.footprint, netName: component.netName, componentType: _mapToComponentType(component.type), symbolName: component.symbolName, rotation: component.rotation, mirrorX: component.mirrorX, mirrorY: component.mirrorY, ); final result = await showModalBottomSheet( context: context, isScrollControlled: true, backgroundColor: Colors.transparent, builder: (context) => PropertyPanelWidget( propertyData: propertyData, onPreview: _previewComponentChanges, onPropertyChanged: _applyComponentChanges, ), ); if (result != null) { // 用户保存了更改 _commitComponentChanges(result); } else { // 用户取消了,恢复原状 _revertPreview(); } } // ========== 工具栏回调处理 ========== void _undo() { // TODO: 调用 EDA 引擎的撤销功能 ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('撤销')), ); } void _redo() { // TODO: 调用 EDA 引擎的重做功能 ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('重做')), ); } void _save() { // TODO: 调用 EDA 引擎的保存功能 ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('已保存'), backgroundColor: Colors.green, ), ); } void _showSettings() { // TODO: 显示设置对话框 showDialog( context: context, builder: (context) => AlertDialog( title: const Text('设置'), content: const Text('编辑器设置开发中...'), actions: [ TextButton( onPressed: () => Navigator.pop(context), child: const Text('关闭'), ), ], ), ); } void _toggleLibrary() { setState(() { _showLibrary = !_showLibrary; }); } void _setMode(EditorMode mode) { setState(() { _editorMode = mode; }); } // ========== 元件库处理 ========== void _addComponentFromLibrary(ComponentLibraryItem item) { // TODO: 调用 EDA 引擎放置元件 ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('添加元件:${item.name}')), ); // 关闭元件库 setState(() { _showLibrary = false; }); } // ========== 属性编辑处理 ========== void _previewComponentChanges(PropertyData data) { // TODO: 临时更新画布上的元件显示(不保存) // 用于实时预览效果 } void _applyComponentChanges(PropertyData data) { // TODO: 应用更改到数据模型 } void _commitComponentChanges(PropertyData data) { // TODO: 提交更改到 EDA 引擎 ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('属性已更新'), backgroundColor: Colors.green, ), ); } void _revertPreview() { // TODO: 恢复原状(用户取消编辑) } // ========== 工具函数 ========== ComponentType _mapToComponentType(String type) { switch (type.toLowerCase()) { case 'resistor': return ComponentType.resistor; case 'capacitor': return ComponentType.capacitor; case 'inductor': return ComponentType.inductor; case 'diode': return ComponentType.diode; case 'transistor': return ComponentType.transistor; case 'ic': return ComponentType.ic; case 'connector': return ComponentType.connector; default: return ComponentType.other; } } } // ========== 辅助数据模型 ========== /// 编辑器模式枚举 enum EditorMode { select, // 选择模式 wire, // 走线模式 place, // 放置模式 edit, // 编辑模式 } /// 原理图元件(简化版,实际应从 EDA 引擎获取) class SchematicComponent { final String id; final String ref; final String value; final String footprint; final String netName; final String type; final String symbolName; final int rotation; final bool mirrorX; final bool mirrorY; SchematicComponent({ required this.id, required this.ref, required this.value, required this.footprint, required this.netName, required this.type, required this.symbolName, this.rotation = 0, this.mirrorX = false, this.mirrorY = false, }); } /// 原理图画布(占位符,实际应使用 EDA 引擎的渲染组件) class SchematicCanvas extends StatelessWidget { final EditorMode editorMode; final SchematicComponent? selectedComponent; final Function(SchematicComponent)? onComponentTap; final Function(SchematicComponent)? onComponentDoubleTap; const SchematicCanvas({ super.key, required this.editorMode, this.selectedComponent, this.onComponentTap, this.onComponentDoubleTap, }); @override Widget build(BuildContext context) { return Container( color: const Color(0xFFFAFAFA), child: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon( Icons.draw, size: 64, color: Colors.grey[400], ), const SizedBox(height: 16), Text( '原理图画布', style: TextStyle( fontSize: 18, color: Colors.grey[600], ), ), const SizedBox(height: 8), Text( '模式:${_getModeName(editorMode)}', style: TextStyle( fontSize: 14, color: Colors.grey[500], ), ), if (selectedComponent != null) ...[ const SizedBox(height: 8), Text( '选中:${selectedComponent!.ref}', style: TextStyle( fontSize: 14, color: Theme.of(context).primaryColor, ), ), ], ], ), ), ); } String _getModeName(EditorMode mode) { switch (mode) { case EditorMode.select: return '选择'; case EditorMode.wire: return '走线'; case EditorMode.place: return '放置'; case EditorMode.edit: return '编辑'; } } }