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/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/items/item.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:fis_measure/view/gesture/positioned_touch_cursor.dart'; import 'package:fis_ui/index.dart'; import 'package:flutter/foundation.dart'; import 'package:get/get.dart'; import 'package:vid/us/vid_us_mode.dart'; import '../items/item_feature.dart'; /// 只绘制一次直线,即会自动开始,不会自动结束 class SingleStraightLine extends MeasureItem { late final mouseState = Get.find(); late final touchState = Get.find(); SingleStraightLine(ItemMeta meta, IMeasureItem? parent) : super(meta, parent); static SingleStraightLine createHeartRate(ItemMeta meta, [IMeasureItem? parent]) { SingleStraightLine straightLine = SingleStraightLine(meta, parent); straightLine.calculator = HeartRateCal(straightLine); final point = DPoint(0, 0); straightLine.feature = StraightLineHeartRateFeature( straightLine, point, point, straightLine.doCalculate, ifHorizontal: false); return straightLine; } @override bool onExecuteMouse(PointInfo args) { if (state == ItemStates.waiting) { startMeasure(args); } else if (state == ItemStates.running) { if (args.pointType == PointInfoType.mouseUp) return false; feature?.endPoint = args; doCalculate(); if (args.pointType == PointInfoType.mouseDown) { state = ItemStates.idle; ///重置十字样式 changeCrossIndicatorStyle(CrossIndicatorStyle.nomal); } } else if (state == ItemStates.idle) { if (args.pointType == PointInfoType.mouseDown) { feature?.startPoint = args; feature?.endPoint = args; state = ItemStates.running; ///设置十字样式 changeCrossIndicatorStyle(CrossIndicatorStyle.vertical); } } return true; } bool isSetStyleOnMoveStart = false; @override bool onExecuteTouch(PointInfo args) { if (state == ItemStates.finished || state == ItemStates.waiting) { if (args.pointType == PointInfoType.touchDown) { startMeasure(args); state = ItemStates.running; } } if (state == ItemStates.running) { feature?.startPoint = args; feature?.endPoint = args; doCalculate(); if (args.pointType == PointInfoType.touchUp) { state = ItemStates.idle; } } else if (state == ItemStates.idle) { feature?.endPoint = args; doCalculate(); if (args.pointType == PointInfoType.touchUp) { state = ItemStates.running; } // 设置十字样式 if (args.pointType == PointInfoType.touchDown) { isSetStyleOnMoveStart = false; } if (args.pointType == PointInfoType.touchMove && !isSetStyleOnMoveStart) { changeCrossIndicatorStyle(CrossIndicatorStyle.vertical); isSetStyleOnMoveStart = true; } } return true; } void changeCrossIndicatorStyle(CrossIndicatorStyle e) { if (kIsMobile) { touchState.crossIndicatorStyleChanged.emit(this, e); } else { mouseState.crossIndicatorStyleChanged.emit(this, e); } } void startMeasure(PointInfo args) { final point = DPoint(0, 0); if (args.hostVisualArea != null) { handleTissueTM(args.hostVisualArea!.mode.modeType, point); feature!.hostVisualArea = args.hostVisualArea; } state = ItemStates.idle; } /// 处理TissueTimeMotion模式 void handleTissueTM(VidUsModeType mode, DPoint point) { if (mode == VidUsModeType.TissueTM || mode == VidUsModeType.Doppler) { switch (meta.measureType) { case MeasureTypes.HR: changeCrossIndicatorStyle(CrossIndicatorStyle.vertical); break; default: } } else { feature = SingleStraightLineFeature(this, point, point); } } } class SingleStraightLineFeature extends MeasureItemFeature { SingleStraightLineFeature( 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 && kIsWeb) 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 StraightLineHeartRateFeature extends SingleStraightLineFeature { StraightLineHeartRateFeature( IMeasureItem refItem, DPoint startPoint, DPoint endPoint, this.calculate, {this.ifHorizontal = true}) : super(refItem, startPoint, endPoint); ///心脏周期 int heartCycle = 1; final bool ifHorizontal; final Function calculate; void setHeartRate(int cycle) { heartCycle = cycle; calculate(); } @override void paint(Canvas canvas, Size size) { if (startPoint == endPoint && kIsWeb) 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); } } }