measure_tool.dart 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389
  1. import 'package:fis_common/logger/logger.dart';
  2. import 'package:fis_measure/interfaces/process/items/item.dart';
  3. import 'package:fis_measure/interfaces/process/items/item_metas.dart';
  4. import 'package:fis_measure/interfaces/process/player/play_controller.dart';
  5. import 'package:fis_measure/interfaces/process/workspace/application.dart';
  6. import 'package:fis_measure/process/items/item_meta_convert.dart';
  7. import 'package:fis_measure/process/workspace/measure_data_controller.dart';
  8. import 'package:fis_measure/process/workspace/measure_handler.dart';
  9. import 'package:fis_measure/view/player/controller.dart';
  10. import 'package:fis_ui/index.dart';
  11. import 'package:flutter/material.dart';
  12. import 'package:get/get.dart';
  13. import 'package:vid/us/vid_us_image.dart';
  14. /// 测量项页面
  15. class LeftSiderSelectMeasure extends FStatefulWidget {
  16. const LeftSiderSelectMeasure({Key? key}) : super(key: key);
  17. @override
  18. FState<LeftSiderSelectMeasure> createState() => LeftSiderSelectMeasureState();
  19. }
  20. class LeftSiderSelectMeasureState extends FState<LeftSiderSelectMeasure> {
  21. final ScrollController scrollController = ScrollController();
  22. late final application = Get.find<IApplication>();
  23. late final measureHandler = Get.find<MeasureHandler>();
  24. /// 数据
  25. late final measureData = Get.find<MeasureDataController>();
  26. final playerController = Get.find<IPlayerController>() as VidPlayerController;
  27. // final topMeasureItem = Get.put<ITopMeasureItem>();
  28. /// 当前选中的测量项目
  29. String activeName = '';
  30. /// 当前组合测量项
  31. ItemMeta? comboItemMeta;
  32. int? comboItemMetaActivedIndex;
  33. /// 是否展开组合测量项
  34. bool isCombo = false;
  35. void workingChildChanged(sender, int e) {
  36. comboItemMetaActivedIndex = e;
  37. setState(() {});
  38. }
  39. /// 切换测量项
  40. void changeItem(ItemMeta itemMeta) {
  41. activeName = itemMeta.name;
  42. try {
  43. application.switchItem(itemMeta);
  44. final item = application.activeMeasureItem!;
  45. if (item is ITopMeasureItem) {
  46. item.switchChild(0);
  47. item.workingChildChanged.addListener(workingChildChanged);
  48. }
  49. } catch (e) {
  50. logger.e("changeItem failed", e);
  51. }
  52. if (mounted) {
  53. setState(() {});
  54. }
  55. }
  56. /// 当前测量数据源变更
  57. void itemMetaList(Object s, dynamic e) {
  58. try {
  59. if (e != null) {
  60. setState(() {});
  61. }
  62. } catch (e) {
  63. debugPrint("callmethod fail " + e.toString());
  64. }
  65. }
  66. /// 获取组合测量项
  67. void comboList() {
  68. /// 格式化数据
  69. List<ItemMeta> itemMetaList = [];
  70. for (var element in measureData.itemMetaList) {
  71. if (measureData.getMeasureApplicationList.contains(element.name)) {
  72. itemMetaList.add(element);
  73. }
  74. }
  75. measureData.getItemMetaList = itemMetaList;
  76. measureData.getTopItemMetaList = measureData.getItemMetaList;
  77. }
  78. /// 获取当前图像的测量项,从第一帧取
  79. void currentFrameHandler(Object sender, VidUsImage e) async {
  80. List<String> getModes = [];
  81. for (var element in e.visuals[0].modes) {
  82. getModes.add(element.type.toString().split('.')[1]);
  83. }
  84. measureData.applicationModes = e.visuals[0].modes;
  85. measureData.currentMode = e.visuals[0].modes.first.type.name;
  86. var measureModeSelection = MeasureModeSelection(
  87. application.applicationName,
  88. application.categoryName,
  89. application.isThirdPart ? ['TPPTissue'] : getModes,
  90. );
  91. measureHandler.measureModeChanged = measureModeSelection;
  92. var measureApplicationDTO =
  93. await measureData.getMeasureApplication.call(measureModeSelection);
  94. if (measureApplicationDTO != null) {
  95. /// 模式版本
  96. measureData.measureApplicationVersion =
  97. measureApplicationDTO.version ?? '';
  98. measureData.availableModes = measureApplicationDTO.availableModes ?? [];
  99. ///模式列表
  100. var models = measureApplicationDTO.availableModes;
  101. if (models != null && models.isNotEmpty) {
  102. ///群组列表
  103. var groups = models[0].availableGroups;
  104. if (groups != null && groups.isNotEmpty) {
  105. ///项目列表
  106. var folders = groups[0].availableFolders;
  107. if (folders != null && folders.isNotEmpty) {
  108. measureData.getMeasureApplicationList =
  109. folders[0].workingItemNames ?? [];
  110. if (folders[0].availableItems != null) {
  111. measureData.itemMetaList =
  112. folders[0].availableItems!.map((element) {
  113. return ItemMetaConverter(element).output();
  114. }).toList();
  115. comboList();
  116. }
  117. print('测量方法集: ${measureData.getMeasureApplicationList.toString()}');
  118. if (measureData.getMeasureApplicationList.isNotEmpty) {
  119. changeItem(measureData.getItemMetaList[0]);
  120. }
  121. }
  122. }
  123. }
  124. }
  125. getNoteCommentsList();
  126. }
  127. /// 注释获取
  128. void getNoteCommentsList() async {
  129. List<String> commentsList = [];
  130. var measureCommentItemResult =
  131. await measureData.getCommentsByApplicationAsync(
  132. application.applicationName,
  133. application.categoryName,
  134. );
  135. measureData.measureCommentItemResult =
  136. measureCommentItemResult?.commentItems ?? [];
  137. measureCommentItemResult?.commentItems?.forEach((element) {
  138. commentsList.add(element.text ?? '');
  139. });
  140. measureData.getCommentsList = commentsList;
  141. }
  142. void getItemMetaListChanged(sender, e) {
  143. measureData.getTopItemMetaList = measureData.getItemMetaList;
  144. setState(() {});
  145. }
  146. @override
  147. void initState() {
  148. playerController.currentFrameHandler.addListener(
  149. (currentFrameHandler),
  150. );
  151. measureData.getItemMetaListChanged.addListener(getItemMetaListChanged);
  152. measureData.itemMetaListChanged.addListener(itemMetaList);
  153. super.initState();
  154. }
  155. @override
  156. dispose() {
  157. super.dispose();
  158. playerController.currentFrameHandler.removeListener(
  159. (currentFrameHandler),
  160. );
  161. measureData.getItemMetaListChanged.removeListener(getItemMetaListChanged);
  162. measureData.itemMetaListChanged.removeListener(itemMetaList);
  163. final item = application.activeMeasureItem!;
  164. if (item is ITopMeasureItem) {
  165. item.workingChildChanged.removeListener(workingChildChanged);
  166. }
  167. }
  168. @override
  169. FWidget build(BuildContext context) {
  170. return FSingleChildScrollView(
  171. controller: ScrollController(),
  172. child: FScrollbar(
  173. isAlwaysShown: true,
  174. child: FColumn(
  175. children: [
  176. _buildFGridView(measureData.getTopItemMetaList),
  177. if (isCombo) _buildCombo(),
  178. _buildFGridView(measureData.getBottomItemMetaList),
  179. ],
  180. ),
  181. ),
  182. );
  183. }
  184. /// 未选中的普通测量项 选中事件
  185. void chooseMeasure(ItemMeta itemMeta) {
  186. isCombo = false;
  187. changeItem(itemMeta);
  188. measureData.getTopItemMetaList = measureData.getItemMetaList;
  189. measureData.getBottomItemMetaList = [];
  190. }
  191. void chooseComboMeasure(ItemMeta itemMeta) {
  192. isCombo = true;
  193. changeItem(itemMeta);
  194. List<ItemMeta> top = [];
  195. List<ItemMeta> bottom = [];
  196. List<ItemMeta> getItemMetaList = measureData.getItemMetaList;
  197. for (int i = 0; i < getItemMetaList.length; i++) {
  198. if (i <= getItemMetaList.indexOf(itemMeta)) {
  199. top.add(getItemMetaList[i]);
  200. } else {
  201. bottom.add(getItemMetaList[i]);
  202. }
  203. measureData.getTopItemMetaList = top;
  204. measureData.getBottomItemMetaList = bottom;
  205. if (i == getItemMetaList.indexOf(itemMeta)) {
  206. comboItemMeta = getItemMetaList[i];
  207. comboItemMetaActivedIndex = 0;
  208. }
  209. }
  210. }
  211. FWidget _buildComboItem(ItemMeta itemMeta, int index) {
  212. FWidget child;
  213. if (comboItemMetaActivedIndex == index) {
  214. child = FElevatedButton(
  215. onPressed: () {
  216. final item = application.activeMeasureItem!;
  217. if (item is ITopMeasureItem) {
  218. item.switchChild(index);
  219. comboItemMetaActivedIndex = index;
  220. }
  221. setState(() {});
  222. },
  223. child: FText(
  224. itemMeta.name,
  225. style: const TextStyle(
  226. color: Colors.white,
  227. ),
  228. ),
  229. );
  230. } else {
  231. child = FOutlinedButton(
  232. onPressed: () {
  233. final item = application.activeMeasureItem!;
  234. if (item is ITopMeasureItem) {
  235. item.switchChild(index);
  236. comboItemMetaActivedIndex = index;
  237. }
  238. setState(() {});
  239. },
  240. style: OutlinedButton.styleFrom(
  241. side: const BorderSide(
  242. color: Color.fromRGBO(124, 124, 124, 1),
  243. ),
  244. ),
  245. child: FText(
  246. itemMeta.name,
  247. style: const TextStyle(
  248. color: Colors.white,
  249. ),
  250. ),
  251. );
  252. }
  253. return child;
  254. }
  255. /// 组合测量项打开的ui
  256. FWidget _buildCombo() {
  257. return FColumn(
  258. mainAxisSize: MainAxisSize.max,
  259. children: [
  260. FContainer(
  261. padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 5),
  262. color: const Color.fromRGBO(70, 70, 70, 1),
  263. child: FColumn(
  264. children: (comboItemMeta?.childItems ?? [])
  265. .asMap()
  266. .entries
  267. .map(
  268. (e) => FContainer(
  269. width: double.infinity,
  270. padding: const EdgeInsets.symmetric(
  271. vertical: 2,
  272. ),
  273. child: _buildComboItem(
  274. e.value,
  275. e.key,
  276. ),
  277. ),
  278. )
  279. .toList(),
  280. ),
  281. ),
  282. ],
  283. );
  284. }
  285. FWidget _buildFGridView(List<ItemMeta> itemMeta) {
  286. return FGridView.count(
  287. shrinkWrap: true,
  288. crossAxisCount: 2,
  289. childAspectRatio: 3,
  290. controller: ScrollController(),
  291. children: itemMeta.map((e) {
  292. if (e.name == activeName) {
  293. // 选中的测量项
  294. return _buildItemMetaContainer(e, () {});
  295. } else {
  296. if (e.childItems.isEmpty) {
  297. return _buildItemMetaContainer(
  298. e,
  299. () => chooseMeasure(e),
  300. );
  301. } else {
  302. return _buildItemMetaContainer(
  303. e,
  304. () => chooseComboMeasure(e),
  305. );
  306. }
  307. }
  308. }).toList(),
  309. );
  310. }
  311. FWidget _buildItemMetaContainer(ItemMeta e, Function onTap) {
  312. FWidget measure;
  313. if (e.name == activeName) {
  314. measure = FElevatedButton(
  315. onPressed: () => onTap.call(),
  316. child: FText(e.name),
  317. style: ElevatedButton.styleFrom(
  318. fixedSize: const Size.fromHeight(
  319. 40,
  320. ),
  321. ),
  322. );
  323. } else {
  324. measure = FOutlinedButton(
  325. onPressed: () => onTap.call(),
  326. child: FText(
  327. e.name,
  328. style: const TextStyle(
  329. color: Colors.white,
  330. ),
  331. ),
  332. style: OutlinedButton.styleFrom(
  333. fixedSize: const Size.fromHeight(
  334. 40,
  335. ),
  336. side: const BorderSide(
  337. color: Color.fromRGBO(124, 124, 124, 1),
  338. ),
  339. textStyle: const TextStyle(
  340. color: Colors.white,
  341. ),
  342. ),
  343. );
  344. }
  345. return FRow(
  346. children: [
  347. const FSizedBox(
  348. width: 12,
  349. ),
  350. FExpanded(
  351. child: measure,
  352. ),
  353. const FSizedBox(
  354. width: 12,
  355. ),
  356. ],
  357. );
  358. }
  359. }