item_feature.dart 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. import 'package:fis_measure/interfaces/date_types/point.dart';
  2. import 'package:fis_measure/interfaces/process/calculators/values.dart';
  3. import 'package:fis_measure/interfaces/process/items/item.dart';
  4. import 'package:fis_measure/interfaces/process/items/item_feature.dart';
  5. import 'package:fis_measure/interfaces/process/items/item_metas.dart';
  6. import 'package:fis_measure/interfaces/process/visuals/visual_area.dart';
  7. import 'package:fis_measure/utils/canvas.dart';
  8. import 'package:fis_measure/values/colors.dart';
  9. import 'package:flutter/widgets.dart';
  10. import 'package:get/get.dart';
  11. import 'package:vid/us/vid_us_unit.dart';
  12. import 'item.dart';
  13. abstract class MeasureItemFeature implements IMeasureItemFeature {
  14. late IMeasureItem _refItem;
  15. late List<DPoint> _innerPoints;
  16. IVisualArea? _hostVisualArea;
  17. bool _isActive = true;
  18. int _id = 0;
  19. final List<ValueBase> _values = [];
  20. int _activeIndex = -1;
  21. @protected
  22. final paintPan = Paint()
  23. ..color = const Color.fromARGB(255, 255, 255, 0)
  24. ..isAntiAlias = true
  25. ..strokeWidth = 2
  26. ..style = PaintingStyle.stroke;
  27. MeasureItemFeature(IMeasureItem refItem) {
  28. _refItem = refItem;
  29. if (refItem.parent != null) {
  30. _id = refItem.parent!.feature?.id ?? 0;
  31. } else {
  32. _id = refItem.assignId();
  33. }
  34. _innerPoints = [];
  35. _recordHistory();
  36. }
  37. int get activeIndex => _activeIndex;
  38. set activeIndex(int val) {
  39. if (val != _activeIndex) {
  40. _activeIndex = val;
  41. }
  42. }
  43. @override
  44. List<DPoint> get innerPoints => _innerPoints;
  45. @override
  46. MeasureItem get refItem => _refItem as MeasureItem;
  47. /// 所在区域
  48. IVisualArea? get hostVisualArea => _hostVisualArea;
  49. set hostVisualArea(IVisualArea? value) {
  50. if (value != _hostVisualArea) {
  51. _hostVisualArea = value;
  52. }
  53. }
  54. @override
  55. bool get isActive => _isActive;
  56. set isActive(bool value) {
  57. if (value != _isActive) {
  58. _isActive = value;
  59. }
  60. }
  61. @override
  62. int get id => _id;
  63. /// 顶点尺寸
  64. double get vertexSize => 10.0 * refItem.scaleRatio;
  65. @override
  66. List<ValueBase> get values => _values;
  67. @override
  68. ValueBase? get value => _values.isNotEmpty ? _values.first : null;
  69. /// 更新浮点型结果值
  70. FloatValue? updateFloatValue(
  71. ItemOutputMeta outputMeta,
  72. double value,
  73. VidUsUnit unit,
  74. ) {
  75. final valueBase =
  76. values.firstWhereOrNull((e) => e.meta.name == outputMeta.name);
  77. if (valueBase == null) {
  78. final floatValue = FloatValue(outputMeta, value, unit);
  79. values.add(floatValue);
  80. return floatValue;
  81. } else {
  82. final floatValue = valueBase as FloatValue;
  83. floatValue.value = value;
  84. floatValue.unit = unit;
  85. return floatValue;
  86. }
  87. }
  88. /// 更新字符串结果值
  89. StringValue updateStringValue(
  90. ItemOutputMeta outputMeta,
  91. String value, [
  92. VidUsUnit unit = VidUsUnit.None,
  93. ]) {
  94. final valueBase = values.firstWhereOrNull((e) => e.name == outputMeta.name);
  95. if (valueBase == null) {
  96. final stringValue = StringValue(outputMeta, value, unit);
  97. values.add(stringValue);
  98. return stringValue;
  99. } else {
  100. final stringValue = valueBase as StringValue;
  101. stringValue.value = value;
  102. stringValue.unit = unit;
  103. return stringValue;
  104. }
  105. }
  106. @protected
  107. DPoint convert2ViewPoint(Size size, DPoint logicPoint) {
  108. final x = size.width * logicPoint.x;
  109. final y = size.height * logicPoint.y;
  110. return DPoint(x, y);
  111. }
  112. /// 画序号
  113. ///
  114. /// [text] 自定义序号内容
  115. @protected
  116. void drawId(Canvas canvas, Size size, [String? text]) {
  117. final String displayText;
  118. if (refItem.parent == null) {
  119. displayText = text ?? id.toString();
  120. } else {
  121. displayText = '$id.${refItem.description}';
  122. }
  123. final point = innerPoints[0];
  124. var offset = convert2ViewPoint(size, point).toOffset();
  125. return drawCustomId(canvas, size, offset, displayText);
  126. }
  127. /// 画自定义位置的序号
  128. /// [offset] 位置
  129. /// [text] 自定义序号内容
  130. @protected
  131. void drawCustomId(Canvas canvas, Size size, Offset offset, [String? text]) {
  132. final displayText = text ?? id.toString();
  133. final fontSize = 14.0 * refItem.scaleRatio; // TODO: from config
  134. final fontOffsetY = 4.0 * refItem.scaleRatio;
  135. final letterSpacing = 0.0 * refItem.scaleRatio;
  136. final style = TextStyle(
  137. fontSize: fontSize,
  138. color: MeasureColors.Primary,
  139. // fontWeight: FontWeight.bold,
  140. letterSpacing: letterSpacing,
  141. );
  142. final fontPlace = boundingTextSize(displayText, style);
  143. double transY = 0;
  144. double transX = 0;
  145. final vertexOffsetW = vertexSize / 2;
  146. if (offset.dx < fontPlace.width) {
  147. transX = fontSize + vertexOffsetW;
  148. } else {
  149. transX = -fontPlace.width - vertexOffsetW;
  150. }
  151. if (offset.dy < fontPlace.height + fontOffsetY) {
  152. transY = fontOffsetY;
  153. } else {
  154. transY = -fontPlace.height - fontOffsetY;
  155. }
  156. offset = offset.translate(transX, transY);
  157. canvas.drawText(
  158. displayText,
  159. offset,
  160. style: style,
  161. );
  162. }
  163. /// 画顶点
  164. void drawVertex(Canvas canvas, Offset offset, [bool active = false]) {
  165. canvas.drawVertex(offset, vertexSize, active: active);
  166. }
  167. /// 画短横标记
  168. void drawMark(Canvas canvas, Offset offset,
  169. [bool active = false, bool ifHorizontal = true]) {
  170. canvas.drawMark(offset, vertexSize,
  171. active: active, ifHorizontal: ifHorizontal);
  172. }
  173. /// 计算文本长度
  174. static Size boundingTextSize(
  175. String text,
  176. TextStyle style, {
  177. int maxLines = 2 ^ 31,
  178. double maxWidth = double.infinity,
  179. }) {
  180. // if (Get.context == null) return Size.zero;
  181. if (text.isEmpty) return Size.zero;
  182. final TextPainter textPainter = TextPainter(
  183. textDirection: TextDirection.ltr,
  184. // locale: Localizations.localeOf(Get.context!),
  185. text: TextSpan(text: text, style: style),
  186. maxLines: maxLines,
  187. )..layout(maxWidth: maxWidth);
  188. return textPainter.size;
  189. }
  190. void _recordHistory() {
  191. if (refItem.parent == null) {
  192. final recorder = refItem.application.recorder;
  193. recorder.recordMeasureItem(refItem.meta.name);
  194. }
  195. }
  196. }