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/items/terms.dart'; import 'package:fis_measure/interfaces/process/items/types.dart'; import 'package:fis_measure/interfaces/process/workspace/point_info.dart'; import 'package:fis_measure/process/calcuators/heart_rate.dart'; import 'package:fis_measure/process/calcuators/time_motion.dart'; import 'package:fis_measure/process/items/item.dart'; import 'package:fis_measure/process/primitives/combos/depth2baseline.dart'; import 'package:fis_measure/process/primitives/location.dart'; import 'package:fis_measure/utils/canvas.dart'; import 'package:fis_measure/view/gesture/cross_position_indicator.dart'; import 'package:fis_measure/view/gesture/positioned_cursor.dart'; import 'package:get/get.dart'; import 'package:vid/us/vid_us_mode.dart'; import '../calcuators/distance.dart'; import '../items/item_feature.dart'; /// 直线 class StraightLine extends MeasureItem { late final mouseState = Get.find(); StraightLine(ItemMeta meta, IMeasureItem? parent) : super(meta, parent); static StraightLine createDistance(ItemMeta meta, [IMeasureItem? parent]) { StraightLine sraightLine = StraightLine(meta, parent); sraightLine.calculator = DistanceCal(sraightLine); return sraightLine; } static StraightLine createSlope(ItemMeta meta, [IMeasureItem? parent]) { StraightLine sraightLine = StraightLine(meta, parent); sraightLine.calculator = SlopeCal(sraightLine); return sraightLine; } static StraightLine createSlopeDoppler(ItemMeta meta, [IMeasureItem? parent]) { StraightLine sraightLine = StraightLine(meta, parent); sraightLine.calculator = SlopeDopplerCal(sraightLine); return sraightLine; } static StraightLine createVerticalDistance(ItemMeta meta, [IMeasureItem? parent]) { StraightLine sraightLine = StraightLine(meta, parent); sraightLine.calculator = VerticalDistanceCal(sraightLine); return sraightLine; } static StraightLine createTimeSpan(ItemMeta meta, [IMeasureItem? parent]) { StraightLine sraightLine = StraightLine(meta, parent); sraightLine.calculator = TimeSpanCal(sraightLine); return sraightLine; } @override bool onExecuteMouse(PointInfo args) { if (state == ItemStates.finished) { if (args.pointType == PointInfoType.mouseDown) { state = ItemStates.waiting; } else { return false; } } if (state == ItemStates.waiting) { if (args.pointType == PointInfoType.mouseDown) { handleMouseDownWhileWaiting(args); } } else if (state == ItemStates.running) { if (args.pointType == PointInfoType.mouseUp) return false; feature?.endPoint = args; doCalculate(); if (args.pointType == PointInfoType.mouseDown) { doFeatureFinish(); ///重置十字样式 mouseState.crossIndicatorStyleChanged .emit(this, CrossIndicatorStyle.nomal); } } return true; } 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) { doCalculate(); feature?.endPoint = args; } } return true; } void handleMouseDownWhileWaiting(PointInfo args) { // TODO: 判断是否当前area // 转换为Area逻辑位置 final point = args.toAreaLogicPoint(); // feature = StraightLineFeature(this, point, point); if (args.hostVisualArea != null) { handleTissueTM(args.hostVisualArea!.mode.modeType, point); feature!.hostVisualArea = args.hostVisualArea; } state = ItemStates.running; } /// 处理TissueTimeMotion模式 void handleTissueTM(VidUsModeType mode, DPoint point) { if (mode == VidUsModeType.TissueTM || mode == VidUsModeType.Doppler) { switch (meta.measureType) { case MeasureTypes.TimeSpan: feature = StraightLineTimeMotionFeature(this, point, point, ifHorizontal: false); mouseState.crossIndicatorStyleChanged .emit(this, CrossIndicatorStyle.vertical); break; case MeasureTypes.VerticalDistance: feature = StraightLineTimeMotionFeature(this, point, point); mouseState.crossIndicatorStyleChanged .emit(this, CrossIndicatorStyle.horizontal); break; case MeasureTypes.Slope: feature = StraightLineSlopeFeature(this, point, point); break; case MeasureTypes.SlopeDoppler: feature = StraightLineSlopeFeature(this, point, point); break; case MeasureTypes.Pht: feature = StraightLinePhtFeature(this, point, point); mouseState.crossIndicatorStyleChanged .emit(this, CrossIndicatorStyle.vertical); break; default: } } else { feature = StraightLineFeature(this, point, point); } } } class StraightLineFeature extends MeasureItemFeature { StraightLineFeature( IMeasureItem refItem, DPoint startPoint, DPoint endPoint, ) : super(refItem) { innerPoints.add(startPoint); innerPoints.add(endPoint); } /// 起点 DPoint get startPoint => innerPoints[0]; set startPoint(DPoint value) => innerPoints[0] = value; /// 终点 DPoint get endPoint => innerPoints[1]; set endPoint(DPoint value) => innerPoints[1] = value; /// 长度 double get length => (endPoint - startPoint).length; @override void paint(Canvas canvas, Size size) { if (startPoint == endPoint) return; drawId(canvas, size, idText); final startOffset = convert2ViewPoint(size, startPoint).toOffset(); drawVertex(canvas, startOffset); final endOffset = convert2ViewPoint(size, endPoint).toOffset(); canvas.drawDashLine(startOffset, endOffset, 1, 10, paintLinePan); drawVertex(canvas, endOffset, isActive); } } class StraightLineTimeMotionFeature extends StraightLineFeature { StraightLineTimeMotionFeature( IMeasureItem refItem, DPoint startPoint, DPoint endPoint, {this.ifHorizontal = true}) : super(refItem, startPoint, endPoint); final bool ifHorizontal; @override void paint(Canvas canvas, Size size) { if (startPoint == endPoint) return; drawId(canvas, size, idText); final startOffset = convert2ViewPoint(size, startPoint).toOffset(); final endOffset = convert2ViewPoint(size, endPoint).toOffset(); if (ifHorizontal) { drawMark(canvas, startOffset); drawMark(canvas, Offset(startOffset.dx, endOffset.dy), isActive); } else { drawMark(canvas, startOffset, false, ifHorizontal); drawMark( canvas, Offset(endOffset.dx, startOffset.dy), isActive, ifHorizontal); } } } class StraightLineSlopeFeature extends StraightLineFeature { StraightLineSlopeFeature( IMeasureItem refItem, DPoint startPoint, DPoint endPoint) : super(refItem, startPoint, endPoint); @override void paint(Canvas canvas, Size size) { if (startPoint == endPoint) return; drawId(canvas, size, idText); final startOffset = convert2ViewPoint(size, startPoint).toOffset(); drawVertex(canvas, startOffset); final endOffset = convert2ViewPoint(size, endPoint).toOffset(); canvas.drawDashLine(startOffset, endOffset, 1, 10, paintLinePan); drawVertex(canvas, endOffset, isActive); } } class StraightLinePhtFeature extends StraightLineFeature { StraightLinePhtFeature( IMeasureItem refItem, DPoint startPoint, DPoint endPoint) : super(refItem, startPoint, endPoint); DPoint get regionCenter => hostVisualArea!.displayRegion.center; @override void paint(Canvas canvas, Size size) { if (startPoint == endPoint) return; drawId(canvas, size, idText); final distanceToCenter = (startPoint.y - regionCenter.y); //TODO:[Gavin] 偏移量比例系数待精确 final endPointY = startPoint.y - distanceToCenter / 4; final startOffset = convert2ViewPoint(size, startPoint).toOffset(); final endOffset = convert2ViewPoint(size, DPoint(endPoint.x, endPointY)).toOffset(); drawVertex(canvas, startOffset, false); canvas.drawDashLine(startOffset, endOffset, 1, 10, paintLinePan); drawVertex(canvas, endOffset, isActive); } }