import 'dart:ui'; import 'package:fis_measure/interfaces/date_types/point.dart'; import 'package:fis_measure/interfaces/enums/items.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/point_info.dart'; import 'package:fis_measure/process/calcuators/curve.dart'; import 'package:fis_measure/process/primitives/utils/auto_snap.dart'; import 'package:path_drawing/path_drawing.dart'; import 'area_abstract.dart'; /// 手势轨迹图形 class Trace extends AreaItemAbstract with AutoSnapMixin { Trace(ItemMeta meta, IMeasureItem? parent) : super(meta, parent); @override bool onExecuteMouse(PointInfo args) { if (state == ItemStates.finished) { if (args.pointType == PointInfoType.mouseDown) { state = ItemStates.waiting; } } if (state == ItemStates.waiting) { if (args.pointType == PointInfoType.mouseDown) { handleMouseDownWhileWaiting(args); } } else if (state == ItemStates.running) { if (args.pointType == PointInfoType.mouseUp) return false; feature?.adopt(args); doCalculate(); if (args.pointType == PointInfoType.mouseDown) { doFeatureFinish(); } else { checkAutoSnap(args); } } return true; } PointInfo? startPoint; bool isFirstPointNeedOffset = false; // 第一个点是否需要施加偏移 DPoint traceTouchStartPoint = DPoint(0, 0); // 轨迹触摸起始点 @override bool onExecuteTouch(PointInfo args) { if (state == ItemStates.finished) { if (args.pointType == PointInfoType.touchDown) { state = ItemStates.waiting; } } if (state == ItemStates.waiting) { if (isFirstPointNeedOffset) args.addOffset(0, -0.2); switch (args.pointType) { case PointInfoType.touchDown: isFirstPointNeedOffset = false; handleTouchBeforeStart(args); break; case PointInfoType.touchUp: state = ItemStates.running; startPoint = args; // 设置线段起点 feature?.innerPoints.first = args; break; // 按下立即抬起无事发生 case PointInfoType.touchMove: isFirstPointNeedOffset = true; if (isMoveTargetOutOfRange(args)) return true; feature?.innerPoints.first = args; break; default: break; } } else if (state == ItemStates.running) { // if (isFirstPointNeedOffset) args.addOffset(0, -0.2); if (args.pointType == PointInfoType.touchDown) { traceTouchStartPoint = args; } if (args.pointType == PointInfoType.touchUp) { doFeatureFinish(); } if (args.pointType == PointInfoType.touchMove) { PointInfo newPoint = PointInfo.fromOffset( startPoint! .clone() .addVector(args - traceTouchStartPoint) .toOffset(), startPoint!.pointType); newPoint.hostVisualArea = args.hostVisualArea; if (isMoveTargetOutOfRange(newPoint)) return true; feature?.adopt(newPoint); doCalculate(); checkAutoSnap(newPoint); } } return true; } @override void doFeatureFinish() { super.doFeatureFinish(); } void handleMouseDownWhileWaiting(PointInfo args) { // TODO: 判断是否当前area // 转换为Area逻辑位置 feature = TraceFeature(this); if (args.hostVisualArea != null) { feature!.hostVisualArea = args.hostVisualArea; } final point = args.toAreaLogicPoint(); feature!.adopt(point); state = ItemStates.running; } void handleTouchBeforeStart(PointInfo args) { // TODO: 判断是否当前area // 转换为Area逻辑位置 feature = TraceFeature(this); if (args.hostVisualArea != null) { feature!.hostVisualArea = args.hostVisualArea; } final point = args.toAreaLogicPoint(); feature!.adopt(point); } static Trace createAreaPerimeter( ItemMeta meta, [ IMeasureItem? parent, ]) { Trace trace = Trace(meta, parent); trace.calculator = AreaPerimeterCal(trace); return trace; } static Trace createCurveLength( ItemMeta meta, [ IMeasureItem? parent, ]) { Trace trace = Trace(meta, parent); trace.calculator = CurveLengthCal(trace); trace.isClosed = false; return trace; } } class TraceFeature extends AreaItemFeatureAbstract { TraceFeature(AreaItemAbstract refItem) : super(refItem); @override void paint(Canvas canvas, Size size) { if (innerPoints.isEmpty) return; drawId(canvas, size); final points = innerPoints.map((e) => convert2ViewPoint(size, e)).toList(); final startPoint = points.first; drawVertex(canvas, startPoint.toOffset(), points.length == 1); if (points.length > 1) { final Path path = Path(); path.moveTo(startPoint.x, startPoint.y); for (var i = 1; i < points.length; i++) { final point = points[i]; path.lineTo(point.x, point.y); } if (isClosed) { path.lineTo(startPoint.x, startPoint.y); } canvas.drawPath( dashPath(path, dashArray: CircularIntervalList([2.0, 10.0])), paintLinePan, ); } drawVertex(canvas, points.last.toOffset(), isActive); } /// 绘制灌注图 @override void paintPerfusion(Canvas canvas, Size size) {} }