import 'package:fis_common/event/event_type.dart'; import 'package:fis_measure/interfaces/process/items/item.dart'; import 'package:fis_measure/interfaces/process/items/item_metas.dart'; import 'package:fis_measure/interfaces/process/workspace/application.dart'; import 'package:fis_measure/interfaces/process/workspace/point_info.dart'; import 'package:flutter/foundation.dart'; import 'item.dart'; import 'item_feature.dart'; abstract class TopMeasureItem extends MeasureItem implements ITopMeasureItem { final List _childItems = []; int _childIndex = 0; bool _isCrossFrameMode = false; bool _isCrossAreaMode = false; bool _canChildOutputSelf = true; bool get ifAutoStart => false; bool get ifAutoFinish => false; bool isNeedRedraw = false; TopMeasureItem(ItemMeta meta) : super(meta) { workingChildChanged = FEventHandler(); } @override List get childItems => _childItems; @override IMeasureItem get workingChild => _childItems[_childIndex]; @override int get workingChildIndex => _childIndex; /// 子项全部完成 @protected bool get childrenAllDone => _childItems.every((e) => e.measuredFeatures.isNotEmpty); @override bool get finishAfterUnactive => false; @override bool get repeatableEditable => true; @override bool get isCrossFrameMode => _isCrossFrameMode; @protected set isCrossFrameMode(bool val) => _isCrossFrameMode = val; @override bool get canChildOutputSelf => _canChildOutputSelf; set canChildOutputSelf(bool val) => _canChildOutputSelf = val; @override bool get isCrossAreaMode => _isCrossAreaMode; @protected set isCrossAreaMode(bool val) => _isCrossAreaMode = val; @override late final FEventHandler workingChildChanged; @override void switchChild(int index) { if (index == _childIndex) return; workingChild.finishOnce(); _childIndex = index; if (workingChild.measuredFeatures.isNotEmpty) { isNeedRedraw = true; // workingChild.frameIndex = 1; IApplication.current!.frameData!.index; } else { isNeedRedraw = false; } workingChildChanged.emit(this, index); } @override IMeasureItem findChildByName(String name) { try { final item = _childItems.firstWhere((e) => e.meta.name == name); return item; } catch (e) { throw ArgumentError("Child item not found.", name); } } T buildFeature(); @override bool onExecuteMouse(PointInfo args) { if (ifAutoStart) { if (feature == null) { feature = buildFeature(); listenChildrenUpdate(); } } if (args.pointType == PointInfoType.mouseDown) { if (feature == null) { feature = buildFeature(); listenChildrenUpdate(); } if (childrenAllDone) { workingChild.clear(); } } feature?.hostVisualArea = args.hostVisualArea; final result = workingChild.execute(args); if (result) { doCalculate(); } if (ifAutoFinish) { if (args.pointType == PointInfoType.mouseDown) { if (childrenAllDone) { application.autoStartAgain(meta); } } } return result; } @override bool onExecuteTouch(PointInfo args) { if (ifAutoStart) { if (feature == null) { feature = buildFeature(); listenChildrenUpdate(); } } if (args.pointType == PointInfoType.touchDown) { if (feature == null) { feature = buildFeature(); listenChildrenUpdate(); } if (childrenAllDone || workingChild.measuredFeatures.isNotEmpty) { workingChild.clear(); } } feature?.hostVisualArea = args.hostVisualArea; final result = workingChild.execute(args); if (result) { doCalculate(); } if (ifAutoFinish) { if (args.pointType == PointInfoType.touchUp) { if (childrenAllDone) { application.autoStartAgain(meta); } } } return result; } @protected void nextChild() { final count = _childItems.length; int nextIdx = -1; for (var i = 0; i < count; i++) { final child = _childItems[i]; if (child.measuredFeatures.isEmpty) { nextIdx = i; break; } } if (nextIdx > -1) { switchChild(nextIdx); } } @protected void listenChildrenUpdate() { for (var item in childItems) { item.featureUpdated.addListener((sender, e) { _onChildFeatureUpdated(); }); } } void _onChildFeatureUpdated() { if (workingChild.measuredFeatures.isNotEmpty && !isNeedRedraw) { nextChild(); } doFeatureUpdate(); } }