|
@@ -0,0 +1,148 @@
|
|
|
+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/workspace/point_info.dart';
|
|
|
+import 'package:fis_measure/view/canvas/utils.dart';
|
|
|
+import 'package:path_drawing/path_drawing.dart';
|
|
|
+
|
|
|
+import '../calcuators/area.dart';
|
|
|
+import '../calcuators/perimeter.dart';
|
|
|
+import '../items/item.dart';
|
|
|
+import '../items/item_feature.dart';
|
|
|
+
|
|
|
+class PolyLine extends MeasureItem<PolyLineFeature> {
|
|
|
+ final bool _initialClosed = false;
|
|
|
+
|
|
|
+ PolyLine(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 {
|
|
|
+ _checkAutoFinish();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ void _checkAutoFinish() {
|
|
|
+ double autoSnapDistance = 10; //TODO: from config
|
|
|
+ bool isAutoSnap = true; //TODO: from config
|
|
|
+ if (feature == null) return;
|
|
|
+ final logicStart = feature!.innerPoints.first;
|
|
|
+ final logicEnd = feature!.innerPoints.last;
|
|
|
+ if (1 == 2) {
|
|
|
+ feature!.innerPoints.add(feature!.innerPoints.first); // 强制闭合
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ void handleMouseDownWhileWaiting(PointInfo args) {
|
|
|
+ // TODO: 判断是否当前area
|
|
|
+ // 转换为Area逻辑位置
|
|
|
+ feature = PolyLineFeature(this);
|
|
|
+ feature!.isClosed = _initialClosed;
|
|
|
+ if (args.hostVisualArea != null) {
|
|
|
+ feature!.hostVisualArea = args.hostVisualArea;
|
|
|
+ }
|
|
|
+ final point = args.toAreaLogicPoint();
|
|
|
+ feature!.adopt(point);
|
|
|
+ state = ItemStates.running;
|
|
|
+ }
|
|
|
+
|
|
|
+ @override
|
|
|
+ bool onExecuteTouch(PointInfo args) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ /// 创建面积测量
|
|
|
+ static PolyLine createArea(
|
|
|
+ ItemMeta meta, [
|
|
|
+ IMeasureItem? parent,
|
|
|
+ ]) {
|
|
|
+ PolyLine poyline = PolyLine(meta, parent);
|
|
|
+ poyline.calculator = PolyLineAreaCal(poyline);
|
|
|
+ return poyline;
|
|
|
+ }
|
|
|
+
|
|
|
+ /// 创建周长测量
|
|
|
+ static PolyLine createPerimeter(
|
|
|
+ ItemMeta meta, [
|
|
|
+ IMeasureItem? parent,
|
|
|
+ ]) {
|
|
|
+ PolyLine poyline = PolyLine(meta, parent);
|
|
|
+ poyline.calculator = PolyLinePerimeterCal(poyline);
|
|
|
+ return poyline;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+class PolyLineFeature extends MeasureItemFeature {
|
|
|
+ bool _isClosed = false;
|
|
|
+
|
|
|
+ PolyLineFeature(IMeasureItem refItem) : super(refItem);
|
|
|
+
|
|
|
+ /// 是否闭合?抄自超声机
|
|
|
+ bool get isClosed => _isClosed;
|
|
|
+ set isClosed(bool value) {
|
|
|
+ if (value != _isClosed) {
|
|
|
+ _isClosed = value;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// 首节点
|
|
|
+ DPoint get firstPoint => innerPoints.first;
|
|
|
+
|
|
|
+ /// 接收新坐标
|
|
|
+ void adopt(DPoint point) {
|
|
|
+ innerPoints.add(point);
|
|
|
+ }
|
|
|
+
|
|
|
+ @override
|
|
|
+ void paint(Canvas canvas, Size size) {
|
|
|
+ if (innerPoints.isEmpty) return;
|
|
|
+
|
|
|
+ // TODO: from style config
|
|
|
+ const double vertexSize = 10;
|
|
|
+
|
|
|
+ final points = innerPoints.map((e) => convert2ViewPoint(size, e)).toList();
|
|
|
+ final startPoint = points.first;
|
|
|
+ canvas.drawVertex(
|
|
|
+ startPoint.toOffset(),
|
|
|
+ vertexSize,
|
|
|
+ active: 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);
|
|
|
+ }
|
|
|
+ path.lineTo(startPoint.x, startPoint.y);
|
|
|
+ canvas.drawPath(
|
|
|
+ dashPath(path, dashArray: CircularIntervalList([2.0, 10.0])),
|
|
|
+ paintPan,
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ canvas.drawVertex(points.last.toOffset(), vertexSize, active: isActive);
|
|
|
+ }
|
|
|
+}
|