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 '../items/item.dart'; import '../items/item_feature.dart'; import 'area_abstract.dart'; /// 手势轨迹图形 class Trace extends AreaItemAbstract with AutoSnapMixin { PointInfo? _firstPoint; 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; } @override void doFeatureFinish() { super.doFeatureFinish(); _firstPoint = null; } 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); _firstPoint = args; state = ItemStates.running; } PointInfo? startPoint; @override bool onExecuteTouch(PointInfo args) { if (state == ItemStates.finished) { if (args.pointType == PointInfoType.touchDown) { state = ItemStates.waiting; } } if (state == ItemStates.waiting) { switch (args.pointType) { case PointInfoType.touchDown: startPoint = args; // 设置线段起点 break; case PointInfoType.touchUp: break; // 按下立即抬起无事发生 case PointInfoType.touchMove: handleMouseDownWhileWaiting(startPoint!); // 通过设置的起点开始一个绘制事件 break; default: break; } } else if (state == ItemStates.running) { if (args.pointType == PointInfoType.touchUp) { doFeatureFinish(); } if (args.pointType == PointInfoType.touchMove) { feature?.adopt(args); doCalculate(); checkAutoSnap(args); } } return true; } 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); } }