mobile-eda/lib/presentation/screens/schematic_editor_screen_v2.dart

362 lines
9.5 KiB
Dart
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.

// 示例:如何在原理图编辑器中集成 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<SchematicEditorScreenV2> createState() => _SchematicEditorScreenV2State();
}
class _SchematicEditorScreenV2State extends ConsumerState<SchematicEditorScreenV2> {
// 当前编辑器模式
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<PropertyData>(
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 '编辑';
}
}
}