import 'package:fis_measure/interfaces/enums/annotation.dart'; import 'package:fis_measure/interfaces/enums/operate.dart'; import 'package:fis_measure/interfaces/process/items/item.dart'; import 'package:fis_measure/interfaces/process/workspace/application.dart'; import 'package:fis_measure/interfaces/process/workspace/recorder.dart'; import 'package:get/get.dart'; class MeasureRecorder implements IMeasureRecorder { int _lastId = 0; final List<_RecordModelBase> _records = []; late final IApplication _application; MeasureRecorder(IApplication application) { _application = application; } /// 获取一个新的记录Id @override int newRecordId() { return _lastId + 1; } /// 添加测量项记录 /// /// [name] 测量项名称 @override void recordMeasureItem(String name) { _records.add(_MeasureModel(name)); _increaseId(); } /// 添加注释记录 /// /// [type] 注释类型 @override void recordAnnotation(AnnotationType type) { _records.add(_AnnotationModel(type)); // _increaseId();// 注释不占Id } /// 撤销一次操作 bool undoOnce() { if (_records.isEmpty) { return false; } _finishLast(); _cleanMeasureList(); final result = _undoOnce(); _checkReactive(); if (result == null) return false; if (result.recordType == MeasureRecordType.measure) { _decreaseId(); } return true; } /// 清除所有记录 void clear() { if (_records.isEmpty) return; _finishLast(); _cleanMeasureList(); final len = _records.length; for (var i = 0; i < len; i++) { _undoOnce(); } _checkReactive(); _resetId(); } _RecordModelBase? _undoOnce() { final record = _records.last; bool removed = false; if (record.recordType == MeasureRecordType.measure) { removed = _undoOnceMeasure(record as _MeasureModel); } else if (record.recordType == MeasureRecordType.annotation) { removed = _undoOnceAnnotation(record as _AnnotationModel); } if (removed) { _records.removeLast(); _checkResetId(); return record; } else { return null; } } void _finishLast() { if (_application.currentOperateType == MeasureOperateType.measure) { _application.activeMeasureItem?.finishOnce(); } else { _application.activeAnnotationItem?.finishLast(); } } bool _undoOnceMeasure(_MeasureModel record) { final index = _application.measureItems .lastIndexWhere((e) => e.meta.name == record.name); if (index < 0) return false; final item = _application.measureItems[index]; if (item is ITopMeasureItem) { _application.measureItems.remove(item); } else { if (item.feature != null) { item.cancelOnce(); } else if (item.measuredFeatures.isNotEmpty) { item.measuredFeatures.removeLast(); } if (item.measuredFeatures.isEmpty) { _application.measureItems.removeAt(index); } } return true; } void _checkReactive() { if (_application.measureItems.isEmpty) { if (_application.activeMeasureItem != null) { if (_application.currentOperateType == MeasureOperateType.measure) { _application.switchItem(_application.activeMeasureItem!.meta); } } } } void _cleanMeasureList() { int len = _application.measureItems.length; final needRemoveIdxArr = []; for (int i = 0; i < len; i++) { final item = _application.measureItems[i]; if (item.feature == null && item.measuredFeatures.isEmpty) { needRemoveIdxArr.add(i); } } if (needRemoveIdxArr.isNotEmpty) { final arr = needRemoveIdxArr.reversed; for (var i in arr) { _application.measureItems.removeAt(i); } } } bool _undoOnceAnnotation(_AnnotationModel record) { final matchs = _application.annotationItems.where((e) => e.type == record.type); if (matchs.isEmpty) return false; final item = matchs.last; item.features.removeLast(); return true; } void _resetId() { _lastId = 0; } void _increaseId() { _lastId++; } void _decreaseId() { _lastId--; if (_lastId < 0) _lastId = 0; } void _checkResetId() { if (_application.measureItems.isEmpty) { _resetId(); } else { final isFeatureEmpty = _application.measureItems .every((e) => e.measuredFeatures.isEmpty && e.feature == null); if (isFeatureEmpty) { _resetId(); } } } } class _MeasureModel extends _RecordModelBase { _MeasureModel(this.name) : super(MeasureRecordType.measure); String name; } class _AnnotationModel extends _RecordModelBase { _AnnotationModel(this.type) : super(MeasureRecordType.annotation); AnnotationType type; } class _RecordModelBase { _RecordModelBase(this.recordType); MeasureRecordType recordType; } enum MeasureRecordType { measure, annotation, }