Pārlūkot izejas kodu

input annotation almost done

melon.yin 2 gadi atpakaļ
vecāks
revīzija
6de26a070c

+ 3 - 0
lib/interfaces/process/workspace/application.dart

@@ -75,6 +75,9 @@ abstract class IApplication {
   Size get displaySize;
   set displaySize(Size value);
 
+  /// 显示缩放比例
+  double get displayScaleRatio;
+
   /// 当前模式变化事件
   late final FEventHandler<IMode> currentModeChanged;
 

+ 2 - 1
lib/measure_page_test.dart

@@ -314,7 +314,8 @@ class _MeasureLeftAnnotationState extends State<_MeasureLeftAnnotation> {
   @override
   void initState() {
     // application.switchAnnotation(AnnotationType.label, C_SUPPORTED_TEXTS[0]);
-    application.switchAnnotation(AnnotationType.arrow);
+    // application.switchAnnotation(AnnotationType.arrow);
+    application.switchAnnotation(AnnotationType.input);
     super.initState();
   }
 

+ 8 - 7
lib/process/annotations/annotation.dart

@@ -6,18 +6,19 @@ import 'package:fis_measure/interfaces/process/workspace/point_info.dart';
 import 'package:flutter/foundation.dart';
 import 'package:flutter/painting.dart';
 
-abstract class AnnotationItem implements IAnnotationItem {
+abstract class AnnotationItem<T extends AnnotationItemFeature>
+    implements IAnnotationItem {
   late AnnotationType _type;
   late AnnotationStates _state;
   final List<IAnnotationItemFeature> _features = [];
-  AnnotationItemFeature? _feature;
+  T? _feature;
   String? _text;
 
   @override
   late final FEventHandler<IAnnotationItemFeature?> featureUpdated;
 
   AnnotationItem(AnnotationType type) {
-    _type = AnnotationType.arrow;
+    _type = type;
     _state = AnnotationStates.waiting;
     featureUpdated = FEventHandler<IAnnotationItemFeature?>();
   }
@@ -34,8 +35,8 @@ abstract class AnnotationItem implements IAnnotationItem {
   }
 
   @override
-  AnnotationItemFeature? get feature => _feature;
-  set feature(AnnotationItemFeature? value) {
+  T? get feature => _feature;
+  set feature(T? value) {
     if (value != _feature) {
       _feature = value;
     }
@@ -88,8 +89,8 @@ abstract class AnnotationItem implements IAnnotationItem {
   bool onExecuteTouch(PointInfo args);
 
   @protected
-  void doFeatureFinish() {
-    if (feature != null) {
+  void doFeatureFinish([bool saveFeature = true]) {
+    if (saveFeature && feature != null) {
       feature!.isActive = false;
       features.add(feature!);
     }

+ 1 - 6
lib/process/annotations/arrow_annotation.dart

@@ -3,7 +3,6 @@
 import 'dart:math' as math;
 import 'package:fis_measure/interfaces/date_types/point.dart';
 import 'package:fis_measure/interfaces/enums/annotation.dart';
-import 'package:fis_measure/interfaces/process/annotations/annotation.dart';
 import 'package:fis_measure/interfaces/process/workspace/application.dart';
 import 'package:fis_measure/interfaces/process/workspace/point_info.dart';
 import 'package:flutter/material.dart';
@@ -12,13 +11,9 @@ import 'package:get/get.dart';
 import 'annotation.dart';
 
 /// 箭头注释
-class ArrowAnnotation extends AnnotationItem {
+class ArrowAnnotation extends AnnotationItem<ArrowAnnotationItemFeature> {
   ArrowAnnotation() : super(AnnotationType.arrow);
 
-  @override
-  ArrowAnnotationItemFeature? get feature =>
-      super.feature as ArrowAnnotationItemFeature?;
-
   @override
   bool onExecuteMouse(PointInfo args) {
     if (state == AnnotationStates.finish) {

+ 45 - 4
lib/process/annotations/input_annotation.dart

@@ -1,17 +1,44 @@
-import 'dart:ui';
-
+import 'package:flutter/painting.dart';
 import 'package:fis_measure/interfaces/date_types/point.dart';
 import 'package:fis_measure/interfaces/enums/annotation.dart';
+import 'package:fis_measure/interfaces/process/workspace/application.dart';
 import 'package:fis_measure/interfaces/process/workspace/point_info.dart';
+import 'package:fis_measure/utils/canvas.dart';
+import 'package:fis_measure/values/colors.dart';
+import 'package:get/get.dart';
 
 import 'annotation.dart';
 
 /// 自定义文本注释
-class InputAnnotation extends AnnotationItem {
+class InputAnnotation extends AnnotationItem<InputAnnotationItemFeature> {
   InputAnnotation() : super(AnnotationType.input);
 
   @override
   bool onExecuteMouse(PointInfo args) {
+    if (state == AnnotationStates.finish || state == AnnotationStates.waiting) {
+      if (args.pointType == PointInfoType.mouseDown) {
+        feature = InputAnnotationItemFeature(this, args);
+        state = AnnotationStates.running;
+      }
+      return false;
+    }
+    if (state == AnnotationStates.running) {
+      if (args.pointType != PointInfoType.mouseDown) return false;
+
+      if (text != null && text!.isNotEmpty) {
+        if (feature != null) {
+          feature!.text = text;
+          doFeatureFinish(true);
+        } else {
+          doFeatureFinish(false);
+        }
+      } else {
+        doFeatureFinish(false);
+      }
+      text = null;
+      feature = InputAnnotationItemFeature(this, args);
+      state = AnnotationStates.running;
+    }
     return true;
   }
 
@@ -23,12 +50,26 @@ class InputAnnotation extends AnnotationItem {
 }
 
 class InputAnnotationItemFeature extends AnnotationItemFeature {
+  String? text;
+
   InputAnnotationItemFeature(InputAnnotation ref, DPoint offset) : super(ref) {
+    text = ref.text;
     points.add(offset);
   }
 
   @override
   void paint(Canvas canvas, Size size) {
-    // TODO: implement draw
+    if (text == null) return;
+    double fontSize = 14 * Get.find<IApplication>().displayScaleRatio;
+    final style = TextStyle(
+      fontSize: fontSize,
+      color: MeasureColors.Primary,
+    );
+    final offset = convert2ViewPoint(size, position);
+    canvas.drawText(
+      text!,
+      offset.toOffset(),
+      style: style,
+    );
   }
 }

+ 6 - 6
lib/process/annotations/label_annotation.dart

@@ -14,7 +14,7 @@ import 'package:get/get.dart';
 import 'annotation.dart';
 
 /// 文本标签注释
-class LabelAnnotation extends AnnotationItem {
+class LabelAnnotation extends AnnotationItem<LabelAnnotationItemFeature> {
   LabelAnnotation() : super(AnnotationType.input);
 
   @override
@@ -59,11 +59,11 @@ class LabelAnnotationItemFeature extends AnnotationItemFeature {
   @override
   void paint(Canvas canvas, Size size) {
     if (text == null) return;
-    double fontSize = 14;
-    final frame = Get.find<IApplication>().frameData;
-    if (frame != null) {
-      fontSize *= size.width / frame.width;
-    }
+    double fontSize = 14 * Get.find<IApplication>().displayScaleRatio;
+    // final frame = Get.find<IApplication>().frameData;
+    // if (frame != null) {
+    //   fontSize *= size.width / frame.width;
+    // }
     final style = TextStyle(
       fontSize: fontSize,
       color: isActive ? MeasureColors.ActiveCaliper : MeasureColors.Primary,

+ 8 - 0
lib/process/workspace/application.dart

@@ -119,6 +119,14 @@ class Application implements IApplication {
     }
   }
 
+  @override
+  double get displayScaleRatio {
+    if (frameData != null) {
+      displaySize.width / frameData!.width;
+    }
+    return 1.0;
+  }
+
   @override
   List<IMode> get avaliableModes {
     final modes = <IMode>[];

+ 39 - 11
lib/view/gesture/annotation/input_position_panel.dart

@@ -1,9 +1,13 @@
+// ignore_for_file: constant_identifier_names
+
 import 'package:fis_measure/interfaces/process/workspace/application.dart';
 import 'package:fis_measure/interfaces/process/workspace/point_info.dart';
 import 'package:fis_measure/values/colors.dart';
 import 'package:flutter/material.dart';
 import 'package:get/get.dart';
 
+import '../positioned_cursor.dart';
+
 /// 自定义注释文本框定位面板
 class AnnotationInputPositionPanel extends StatefulWidget {
   const AnnotationInputPositionPanel({Key? key}) : super(key: key);
@@ -14,6 +18,7 @@ class AnnotationInputPositionPanel extends StatefulWidget {
 
 class _PanelState extends State<AnnotationInputPositionPanel> {
   late final application = Get.find<IApplication>();
+  final mouseState = Get.put<IMouseState>(MouseState()..cursorSize = 10);
 
   Offset? position;
 
@@ -26,27 +31,48 @@ class _PanelState extends State<AnnotationInputPositionPanel> {
           application.createPointInfo(position!, PointInfoType.mouseDown);
         });
       },
-      child: Stack(
-        children: [
-          if (position != null)
-            Positioned(
-              child: const _InputWidget(),
-              left: position!.dx,
-              top: position!.dy,
-            ),
-        ],
+      child: MouseRegion(
+        cursor: SystemMouseCursors.none,
+        onHover: (event) {
+          mouseState.mousePosition = event.localPosition +
+              const Offset(
+                _InputWidget.C_MIN_WIDTH / 2,
+                _InputWidget.C_MAX_HEIGHT / 2,
+              );
+        },
+        child: Stack(
+          children: [
+            if (position != null)
+              Positioned(
+                child: _InputWidget(
+                  key: UniqueKey(),
+                  onChanged: (value) {
+                    application.activeAnnotationItem?.text = value;
+                  },
+                ),
+                left: position!.dx,
+                top: position!.dy,
+              ),
+            const PositionedCursor(),
+          ],
+        ),
       ),
     );
   }
 }
 
+typedef _InputValueChanged = void Function(String value);
+
 class _InputWidget extends StatelessWidget {
-  // ignore: constant_identifier_names
   static const C_BG_COLOR = Color.fromARGB(255, 121, 135, 151);
+  static const C_MIN_WIDTH = 40.0;
+  static const C_MAX_HEIGHT = 28.0;
 
   final FocusNode? focusNode;
+  final _InputValueChanged onChanged;
 
   const _InputWidget({
+    required this.onChanged,
     Key? key,
     this.focusNode,
   }) : super(key: key);
@@ -64,6 +90,7 @@ class _InputWidget extends StatelessWidget {
       style: const TextStyle(color: MeasureColors.Primary),
       cursorColor: MeasureColors.Primary,
       cursorWidth: 1.0,
+      onChanged: onChanged,
       decoration: const InputDecoration(
         border: border,
         enabledBorder: border,
@@ -73,7 +100,8 @@ class _InputWidget extends StatelessWidget {
         fillColor: C_BG_COLOR,
         isCollapsed: false,
         contentPadding: EdgeInsets.symmetric(horizontal: 2, vertical: 8),
-        constraints: BoxConstraints(minWidth: 40, maxHeight: 28),
+        constraints:
+            BoxConstraints(minWidth: C_MIN_WIDTH, maxHeight: C_MAX_HEIGHT),
       ),
     );
     return Container(