Эх сурвалжийг харах

移动端支持SingleStraightLine(HR)

gavin.chen 2 жил өмнө
parent
commit
1456f01538

+ 51 - 9
lib/process/primitives/single_straightline.dart

@@ -11,6 +11,9 @@ 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';
@@ -18,6 +21,8 @@ import '../items/item_feature.dart';
 /// 只绘制一次直线,即会自动开始,不会自动结束
 class SingleStraightLine extends MeasureItem<SingleStraightLineFeature> {
   late final mouseState = Get.find<IMouseState>();
+  late final touchState = Get.find<ITouchPointState>();
+
   SingleStraightLine(ItemMeta meta, IMeasureItem? parent) : super(meta, parent);
 
   static SingleStraightLine createHeartRate(ItemMeta meta,
@@ -43,8 +48,7 @@ class SingleStraightLine extends MeasureItem<SingleStraightLineFeature> {
         state = ItemStates.idle;
 
         ///重置十字样式
-        mouseState.crossIndicatorStyleChanged
-            .emit(this, CrossIndicatorStyle.nomal);
+        changeCrossIndicatorStyle(CrossIndicatorStyle.nomal);
       }
     } else if (state == ItemStates.idle) {
       if (args.pointType == PointInfoType.mouseDown) {
@@ -53,19 +57,56 @@ class SingleStraightLine extends MeasureItem<SingleStraightLineFeature> {
         state = ItemStates.running;
 
         ///设置十字样式
-        mouseState.crossIndicatorStyleChanged
-            .emit(this, CrossIndicatorStyle.vertical);
+        changeCrossIndicatorStyle(CrossIndicatorStyle.vertical);
       }
     }
     return true;
   }
 
+  bool isSetStyleOnMoveStart = false;
+
   @override
   bool onExecuteTouch(PointInfo args) {
-    //TODO
+    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) {
@@ -80,8 +121,7 @@ class SingleStraightLine extends MeasureItem<SingleStraightLineFeature> {
     if (mode == VidUsModeType.TissueTM || mode == VidUsModeType.Doppler) {
       switch (meta.measureType) {
         case MeasureTypes.HR:
-          mouseState.crossIndicatorStyleChanged
-              .emit(this, CrossIndicatorStyle.vertical);
+          changeCrossIndicatorStyle(CrossIndicatorStyle.vertical);
           break;
         default:
       }
@@ -114,7 +154,8 @@ class SingleStraightLineFeature extends MeasureItemFeature {
 
   @override
   void paint(Canvas canvas, Size size) {
-    if (startPoint == endPoint) return;
+    if (startPoint == endPoint && kIsWeb) return;
+
     drawId(canvas, size, idText);
 
     final startOffset = convert2ViewPoint(size, startPoint).toOffset();
@@ -143,7 +184,8 @@ class StraightLineHeartRateFeature extends SingleStraightLineFeature {
 
   @override
   void paint(Canvas canvas, Size size) {
-    if (startPoint == endPoint) return;
+    if (startPoint == endPoint && kIsWeb) return;
+
     drawId(canvas, size, idText);
     final startOffset = convert2ViewPoint(size, startPoint).toOffset();
     final endOffset = convert2ViewPoint(size, endPoint).toOffset();

+ 96 - 50
lib/view/measure/combo_widget.dart

@@ -1,8 +1,10 @@
 import 'package:fis_measure/interfaces/process/workspace/application.dart';
 import 'package:fis_measure/process/primitives/single_straightline.dart';
 import 'package:fis_ui/index.dart';
+import 'package:flutter/foundation.dart';
 import 'package:flutter/material.dart';
 import 'package:fis_theme/theme.dart';
+import 'package:flutter/services.dart';
 import 'package:get/get.dart';
 
 class SpecialItemHR extends FStatefulWidget {
@@ -24,6 +26,7 @@ class _SpecialItemHRState extends FState<SpecialItemHR> {
         final hRFeature = item.feature as StraightLineHeartRateFeature;
         hRFeature.setHeartRate(index);
         application.updateRenderReady.emit(this, null);
+        HapticFeedback.mediumImpact();
         setState(() {
           selectedIndex = index;
         });
@@ -36,7 +39,7 @@ class _SpecialItemHRState extends FState<SpecialItemHR> {
           border: Border.all(color: const Color.fromRGBO(124, 124, 124, 1)),
           borderRadius: BorderRadius.circular(5),
         ),
-        margin: const EdgeInsets.symmetric(horizontal: 11, vertical: 5),
+        // margin: const EdgeInsets.symmetric(horizontal: 11, vertical: 5),
         child: FCenter(
           child: FText(
             index.toString(),
@@ -51,63 +54,106 @@ class _SpecialItemHRState extends FState<SpecialItemHR> {
 
   @override
   FWidget build(BuildContext context) {
+    const Decoration _webDecoration = BoxDecoration(
+      color: Color.fromRGBO(60, 60, 60, 1),
+      borderRadius: BorderRadius.only(
+          bottomLeft: Radius.circular(5), bottomRight: Radius.circular(5)),
+    );
+    const Decoration _mobileDecoration = BoxDecoration();
     return FContainer(
-      padding: const EdgeInsets.only(top: 10, bottom: 5),
-      decoration: const BoxDecoration(
-        color: Color.fromRGBO(60, 60, 60, 1),
-        borderRadius: BorderRadius.only(
-            bottomLeft: Radius.circular(5), bottomRight: Radius.circular(5)),
-      ),
+      padding: kIsWeb ? const EdgeInsets.only(top: 10, bottom: 5) : null,
+      decoration: kIsWeb ? _webDecoration : _mobileDecoration,
       child: FColumn(
         children: [
-          FContainer(
-            padding: const EdgeInsets.symmetric(
-              vertical: 6,
-            ),
-            decoration: BoxDecoration(
-              borderRadius: BorderRadius.circular(4),
-              color: FTheme.ins.colorScheme.primary,
-            ),
-            margin: const EdgeInsets.symmetric(
-              horizontal: 11,
-            ),
-            width: double.infinity,
-            child: const FCenter(
-              child: FText(
-                'Time',
-                style: TextStyle(
-                  color: Colors.white,
+          if (kIsWeb)
+            FContainer(
+              padding: const EdgeInsets.symmetric(
+                vertical: 6,
+              ),
+              decoration: BoxDecoration(
+                borderRadius: BorderRadius.circular(4),
+                color: FTheme.ins.colorScheme.primary,
+              ),
+              margin: const EdgeInsets.symmetric(
+                horizontal: 11,
+              ),
+              width: double.infinity,
+              child: const FCenter(
+                child: FText(
+                  'Time',
+                  style: TextStyle(
+                    color: Colors.white,
+                  ),
                 ),
               ),
             ),
-          ),
-          FColumn(
-            crossAxisAlignment: CrossAxisAlignment.start,
-            children: [
-              FRow(
-                children: const [
-                  FSizedBox(
-                    width: 11,
-                  ),
-                  FText(
-                    'Heart Cycle',
-                    textAlign: TextAlign.start,
-                    style: TextStyle(
-                      color: Colors.white,
-                    ),
-                  ),
-                ],
+          _buildHRButtons(),
+        ],
+      ),
+    );
+  }
+
+  FWidget _buildHRButtons() {
+    return kIsWeb ? _buildWebHRButtons() : _buildMobileHRButtons();
+  }
+
+  FWidget _buildWebHRButtons() {
+    return FColumn(
+      crossAxisAlignment: CrossAxisAlignment.start,
+      children: [
+        FRow(
+          children: const [
+            FSizedBox(
+              width: 11,
+            ),
+            FText(
+              'Heart Cycle',
+              textAlign: TextAlign.start,
+              style: TextStyle(
+                color: Colors.white,
               ),
-              FGridView.count(
-                shrinkWrap: true,
-                crossAxisCount: 2,
-                childAspectRatio: 3,
-                children: [1, 2, 3, 4, 5].map((e) {
-                  return buildHRButton(e);
-                }).toList(),
+            ),
+          ],
+        ),
+        FGridView.count(
+          shrinkWrap: true,
+          crossAxisCount: 2,
+          childAspectRatio: 3,
+          children: [1, 2, 3, 4, 5].map((e) {
+            return buildHRButton(e);
+          }).toList(),
+        ),
+      ],
+    );
+  }
+
+  FWidget _buildMobileHRButtons() {
+    return FExpanded(
+      child: FListView(
+        children: [
+          FColumn(crossAxisAlignment: CrossAxisAlignment.center, children: [
+            const FText(
+              'Heart Cycle',
+              textAlign: TextAlign.center,
+              style: TextStyle(
+                fontSize: 12,
+                color: Colors.white,
               ),
-            ],
-          ),
+            ),
+            const FSizedBox(
+              height: 5,
+            ),
+            FGridView.count(
+              shrinkWrap: true,
+              crossAxisCount: 2,
+              childAspectRatio: 1.5,
+              mainAxisSpacing: 5,
+              crossAxisSpacing: 5,
+              children: [1, 2, 3, 4, 5].map((e) {
+                return buildHRButton(e);
+              }).toList(),
+            ),
+          ]),
         ],
       ),
     );

+ 9 - 0
lib/view/mobile_view/mobile_right_panel/mobile_measure_tool.dart

@@ -12,6 +12,7 @@ import 'package:fis_measure/process/language/measure_language.dart';
 import 'package:fis_measure/process/workspace/measure_data_controller.dart';
 import 'package:fis_measure/process/workspace/measure_handler.dart';
 import 'package:fis_measure/utils/prompt_box.dart';
+import 'package:fis_measure/view/measure/combo_widget.dart';
 import 'package:fis_measure/view/mobile_view/mobile_right_panel/mobile_more_measure_item_dialog.dart';
 import 'package:fis_ui/index.dart';
 import 'package:flutter/material.dart';
@@ -121,6 +122,9 @@ class _MobileMeasureSelector extends FState<MobileMeasureSelector> {
   /// 当前的区域类型
   VidUsVisualAreaType? _currentAreaType = VidUsVisualAreaType.Tissue;
 
+  /// 判断是否为特殊测量项
+  bool get isSpecial => MeasurespecialsupportedTerms.items.contains(activeName);
+
   /// 切换测量项
   void changeItem(ItemMeta itemMeta) {
     if (mounted) {
@@ -406,6 +410,10 @@ class _MobileMeasureSelector extends FState<MobileMeasureSelector> {
 
   /// 构建子测量项选择器
   FWidget _buildChildItemBtns() {
+    if (isSpecial) {
+      //是否为特殊组合测量项
+      return const SpecialItemHR();
+    }
     if (!isCombo) return const FSizedBox();
     return FListView(
       children: List.generate(
@@ -574,6 +582,7 @@ class _MobileMeasureSelector extends FState<MobileMeasureSelector> {
   /// 过滤出当前支持的所有测量项
   List<ItemMetaDTO> _currSupportedItemFilter(MeasureModeDTO mode) {
     final supportedMeasureTypeName = [
+      'TimeSpan', // StraightLine
       'Distance', // StraightLine
       "VerticalDistance", // StraightLine
       'AreaPerimeterTrace', // Trace