measure_page_test.dart 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  1. import 'package:fis_measure/index.dart';
  2. import 'package:fis_measure/interfaces/enums/annotation.dart';
  3. import 'package:fis_measure/interfaces/process/items/measure_terms.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/interfaces/process/workspace/exam_info.dart';
  7. import 'package:fis_measure/interfaces/process/workspace/measure_controller.dart';
  8. import 'package:fis_measure/process/workspace/measure_controller.dart';
  9. import 'package:fis_measure/process/workspace/measure_data_controller.dart';
  10. import 'package:fis_measure/view/main/desktop.dart';
  11. import 'package:flutter/material.dart';
  12. import 'package:get/get.dart';
  13. class MeasureTestPage extends StatefulWidget {
  14. const MeasureTestPage({Key? key}) : super(key: key);
  15. @override
  16. State<StatefulWidget> createState() => _MeasureTestPageState();
  17. }
  18. class _MeasureTestPageState extends State<MeasureTestPage> {
  19. static const C_LINEAR_TISSUE =
  20. "http://43.138.119.65:9303/Flyinsono-BJ-1300984704.VCS.AP-BeiJing/9eb581250c6845b7800f0ba00218e043.VID";
  21. static const C_CONVEX_TISSUE =
  22. "http://43.138.119.65:9303/Flyinsono-BJ-1300984704.VCS.AP-BeiJing/9f74db43fd3b4fc486edc59106ae96ae.VID";
  23. final datac = Get.put(MeasureDataController());
  24. final controller = Get.put<IMeasureController>(MeasureController(
  25. "12345",
  26. imagesFetchFunc: (code) async {
  27. return <ExamImageInfo>[
  28. ExamImageInfo(C_LINEAR_TISSUE, C_LINEAR_TISSUE),
  29. ExamImageInfo(C_CONVEX_TISSUE, C_CONVEX_TISSUE)
  30. ];
  31. },
  32. ));
  33. bool loaded = false;
  34. int opType = 0;
  35. bool useArrowAnnotation = false;
  36. @override
  37. void initState() {
  38. controller.load().then((value) {
  39. // 加载指定图像
  40. controller.examInfo.selectedImageIndex = 0;
  41. });
  42. controller.imageLoaded.addListener(onImageLoaded);
  43. super.initState();
  44. }
  45. @override
  46. void dispose() {
  47. controller.imageLoaded.removeListener(onImageLoaded);
  48. controller.dispose();
  49. Get.delete<IMeasureController>();
  50. super.dispose();
  51. }
  52. void onImageLoaded(Object sender, ExamImageInfo? e) {
  53. if (!mounted) return;
  54. if (e != null) {
  55. setState(() {
  56. loaded = true;
  57. });
  58. }
  59. }
  60. @override
  61. Widget build(BuildContext context) {
  62. Widget body;
  63. if (!loaded) {
  64. const loadingWidget = Center(child: CircularProgressIndicator());
  65. body = Row(
  66. children: const [
  67. SizedBox(
  68. width: 300,
  69. child: loadingWidget,
  70. ),
  71. VerticalDivider(),
  72. Expanded(child: loadingWidget),
  73. ],
  74. );
  75. } else {
  76. body = Row(
  77. key: ValueKey(controller.examInfo.selectedImageIndex),
  78. children: [
  79. opType == 1
  80. ? const _MeasureLeftAnnotation()
  81. : const _MeasureLeftBoard(),
  82. const VerticalDivider(),
  83. const Expanded(
  84. child: MeasureRightBoard(),
  85. ),
  86. ],
  87. );
  88. }
  89. return Scaffold(
  90. backgroundColor: const Color.fromARGB(255, 53, 55, 51),
  91. appBar: AppBar(
  92. actions: [
  93. TextButton.icon(
  94. onPressed: () {
  95. setState(() {
  96. if (useArrowAnnotation) {
  97. useArrowAnnotation = false;
  98. controller.workingApplication.switchAnnotation();
  99. } else {
  100. useArrowAnnotation = true;
  101. controller.workingApplication
  102. .switchAnnotation(AnnotationType.arrow);
  103. }
  104. });
  105. },
  106. icon: const Icon(Icons.arrow_right_alt_sharp),
  107. label: Text(
  108. "箭头",
  109. style: TextStyle(
  110. color: useArrowAnnotation ? Colors.amber : Colors.white,
  111. ),
  112. ),
  113. ),
  114. TextButton(
  115. onPressed: () {
  116. setState(() {
  117. opType = opType == 1 ? 0 : 1;
  118. });
  119. },
  120. child: Text(
  121. opType == 1 ? "注释" : "测量",
  122. style: const TextStyle(
  123. color: Colors.white,
  124. ),
  125. ),
  126. ),
  127. TextButton(
  128. onPressed: () {
  129. if (controller.examInfo.selectedImageIndex == 0) return;
  130. controller.examInfo.selectedImageIndex = 0;
  131. },
  132. child: Text(
  133. '线阵',
  134. style: TextStyle(
  135. color: controller.examInfo.selectedImageIndex == 0
  136. ? Colors.amber
  137. : Colors.white,
  138. ),
  139. ),
  140. ),
  141. TextButton(
  142. onPressed: () {
  143. if (controller.examInfo.selectedImageIndex == 1) return;
  144. controller.examInfo.selectedImageIndex = 1;
  145. },
  146. child: Text(
  147. '扇阵',
  148. style: TextStyle(
  149. color: controller.examInfo.selectedImageIndex == 1
  150. ? Colors.amber
  151. : Colors.white,
  152. ),
  153. ),
  154. ),
  155. ],
  156. leading: IconButton(
  157. onPressed: () {
  158. Navigator.of(context).pop();
  159. },
  160. icon: const Icon(Icons.arrow_back),
  161. ),
  162. ),
  163. body: body,
  164. );
  165. }
  166. }
  167. class MeasureRightBoard extends StatefulWidget {
  168. const MeasureRightBoard({Key? key}) : super(key: key);
  169. @override
  170. State<StatefulWidget> createState() => _MeasureRightBoardState();
  171. }
  172. class _MeasureRightBoardState extends State<MeasureRightBoard> {
  173. final playerController = Get.find<IPlayerController>();
  174. @override
  175. Widget build(BuildContext context) {
  176. return Container(
  177. padding: const EdgeInsets.all(8).copyWith(left: 0),
  178. child: Column(
  179. children: [
  180. const Expanded(
  181. child: MeasureMainView(),
  182. ),
  183. const Divider(),
  184. SizedBox(
  185. height: 80,
  186. child: VidPlayerControlBoard(
  187. playerController as VidPlayerController,
  188. ),
  189. ),
  190. ],
  191. ),
  192. );
  193. }
  194. }
  195. class _MeasureLeftBoard extends StatefulWidget {
  196. const _MeasureLeftBoard({Key? key}) : super(key: key);
  197. @override
  198. State<StatefulWidget> createState() => _MeasureLeftBoardState();
  199. }
  200. class _MeasureLeftBoardState extends State<_MeasureLeftBoard> {
  201. // ignore: non_constant_identifier_names
  202. static final C_SUPPORTED_ITEMS = <String>[
  203. MeasureTerms.Distance,
  204. MeasureTerms.Perimeter,
  205. MeasureTerms.Area,
  206. MeasureTerms.Depth,
  207. ];
  208. final scrollController = ScrollController();
  209. final application = Get.find<IApplication>();
  210. int activeIndex = 0;
  211. @override
  212. void initState() {
  213. application.switchItemByName(C_SUPPORTED_ITEMS[0]);
  214. application.canMeasureChanged.addListener(_onCanMeasureChanged);
  215. super.initState();
  216. }
  217. @override
  218. dispose() {
  219. application.canMeasureChanged.removeListener(_onCanMeasureChanged);
  220. super.dispose();
  221. }
  222. _onCanMeasureChanged(Object sender, bool e) {
  223. if (e && mounted) {
  224. changeItem(0);
  225. }
  226. }
  227. @override
  228. Widget build(BuildContext context) {
  229. return Container(
  230. width: 300,
  231. padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 12),
  232. child: Scrollbar(
  233. controller: scrollController,
  234. isAlwaysShown: true,
  235. child: ListView.separated(
  236. controller: scrollController,
  237. itemCount: C_SUPPORTED_ITEMS.length,
  238. itemBuilder: (BuildContext context, int index) {
  239. final name = C_SUPPORTED_ITEMS[index];
  240. final active = index == activeIndex;
  241. return active
  242. ? ElevatedButton(
  243. onPressed: () => changeItem(index),
  244. child: Text(name),
  245. style: ElevatedButton.styleFrom(
  246. fixedSize: const Size.fromHeight(50),
  247. ),
  248. )
  249. : OutlinedButton(
  250. onPressed: () => changeItem(index),
  251. child: Text(name),
  252. style: OutlinedButton.styleFrom(
  253. fixedSize: const Size.fromHeight(50),
  254. ),
  255. );
  256. },
  257. separatorBuilder: (BuildContext context, int index) {
  258. return const SizedBox(height: 8);
  259. },
  260. ),
  261. ),
  262. );
  263. }
  264. void changeItem(int index) {
  265. setState(() {
  266. activeIndex = index;
  267. });
  268. final name = C_SUPPORTED_ITEMS[index];
  269. application.switchItemByName(name);
  270. }
  271. }
  272. class _MeasureLeftAnnotation extends StatefulWidget {
  273. const _MeasureLeftAnnotation({Key? key}) : super(key: key);
  274. @override
  275. State<StatefulWidget> createState() => _MeasureLeftAnnotationState();
  276. }
  277. class _MeasureLeftAnnotationState extends State<_MeasureLeftAnnotation> {
  278. // ignore: non_constant_identifier_names
  279. static final C_SUPPORTED_TEXTS = <String>[
  280. "肝左叶",
  281. "胆囊",
  282. "脾脏",
  283. "结石",
  284. "积液",
  285. ];
  286. final scrollController = ScrollController();
  287. final application = Get.find<IApplication>();
  288. @override
  289. void initState() {
  290. // application.switchAnnotation(AnnotationType.label, C_SUPPORTED_TEXTS[0]);
  291. // application.switchAnnotation(AnnotationType.arrow);
  292. application.switchAnnotation(AnnotationType.input);
  293. super.initState();
  294. }
  295. @override
  296. Widget build(BuildContext context) {
  297. return Container(
  298. width: 300,
  299. padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 12),
  300. child: Scrollbar(
  301. controller: scrollController,
  302. isAlwaysShown: true,
  303. child: ListView.separated(
  304. controller: scrollController,
  305. itemCount: C_SUPPORTED_TEXTS.length,
  306. itemBuilder: (BuildContext context, int index) {
  307. final name = C_SUPPORTED_TEXTS[index];
  308. const style = TextStyle(color: Colors.white, fontSize: 16);
  309. const dragStyle = TextStyle(color: Colors.amber, fontSize: 18);
  310. return Draggable<String>(
  311. data: name,
  312. dragAnchorStrategy: (data, context, offset) {
  313. // return offset - Offset(120, 14);
  314. return Offset.zero;
  315. },
  316. child: OutlinedButton(
  317. child: Text(name, style: style),
  318. onPressed: () {
  319. application.switchAnnotation(AnnotationType.label, name);
  320. },
  321. style: OutlinedButton.styleFrom(
  322. shape: RoundedRectangleBorder(
  323. borderRadius: BorderRadius.circular(4),
  324. ),
  325. side: BorderSide(color: Colors.grey.shade100),
  326. fixedSize: const Size.fromHeight(44),
  327. ),
  328. ),
  329. feedback: Material(
  330. color: Colors.transparent,
  331. child: Text(name, style: dragStyle),
  332. ),
  333. onDragStarted: () {
  334. application.switchAnnotation(AnnotationType.label, name);
  335. },
  336. );
  337. },
  338. separatorBuilder: (BuildContext context, int index) {
  339. return const SizedBox(height: 8);
  340. },
  341. ),
  342. ),
  343. );
  344. }
  345. }