button_group.dart 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. import 'dart:async';
  2. import 'package:fis_i18n/i18n.dart';
  3. import 'package:fis_jsonrpc/rpc.dart';
  4. import 'package:fis_lib_qrcode/qr_flutter.dart';
  5. import 'package:fis_measure/interfaces/process/player/play_controller.dart';
  6. import 'package:fis_measure/interfaces/process/standard_line/calibration.dart';
  7. import 'package:fis_measure/interfaces/process/workspace/application.dart';
  8. import 'package:fis_measure/interfaces/process/workspace/measure_3d_view_controller.dart';
  9. import 'package:fis_measure/process/workspace/measure_3d_view_controller.dart';
  10. import 'package:fis_measure/process/workspace/measure_data_controller.dart';
  11. import 'package:fis_measure/process/workspace/measure_handler.dart';
  12. import 'package:fis_measure/utils/prompt_box.dart';
  13. import 'package:fis_measure/view/paint/ai_patint_controller.dart';
  14. import 'package:fis_measure/view/player/controller.dart';
  15. import 'package:fis_ui/index.dart';
  16. import 'package:flutter/material.dart';
  17. import 'package:get/get.dart';
  18. import 'package:url_launcher/url_launcher.dart';
  19. class ButtonGroup extends StatefulWidget {
  20. final VoidCallback capturePng;
  21. const ButtonGroup({
  22. Key? key,
  23. required this.capturePng,
  24. }) : super(key: key);
  25. @override
  26. State<ButtonGroup> createState() => _ButtonGroupState();
  27. }
  28. class _ButtonGroupState extends State<ButtonGroup> {
  29. double _width = 0;
  30. bool _isExpanded = false;
  31. final _key = GlobalKey();
  32. final application = Get.find<IApplication>();
  33. /// 数据
  34. final measureData = Get.find<MeasureDataController>();
  35. final playerController = Get.find<IPlayerController>() as VidPlayerController;
  36. final measure3DViewController = Get.find<Measure3DViewController>();
  37. late final measureHandler = Get.find<MeasureHandler>();
  38. late final aiPatintController = Get.find<AiPatintController>();
  39. late bool canShowAI = [
  40. DiagnosisConclusionEnum.Benign,
  41. DiagnosisConclusionEnum.Malignant,
  42. DiagnosisConclusionEnum.BenignAndMalignant
  43. ].contains(measureData.diagnosisConclusion);
  44. bool ifShowModeButton = false;
  45. bool ifShowVidModeButton = true;
  46. get exist3DData => measure3DViewController.exist3DData;
  47. @override
  48. void initState() {
  49. super.initState();
  50. measure3DViewController.updatePlayerMode.addListener(_onModeChanged);
  51. }
  52. @override
  53. void dispose() {
  54. measure3DViewController.updatePlayerMode.removeListener(_onModeChanged);
  55. super.dispose();
  56. }
  57. /// 模式改变触发更新
  58. void _onModeChanged(Object s, MeasureMode mode) {
  59. switch (mode) {
  60. case MeasureMode.vidMode:
  61. setState(() {
  62. ifShowModeButton = false;
  63. ifShowVidModeButton = true;
  64. });
  65. break;
  66. case MeasureMode.carotid2DMode:
  67. setState(() {
  68. ifShowModeButton = true;
  69. ifShowVidModeButton = false;
  70. });
  71. break;
  72. case MeasureMode.carotid3DMode:
  73. setState(() {
  74. ifShowModeButton = false;
  75. });
  76. break;
  77. }
  78. }
  79. List<Widget> buildTitleButtonList() {
  80. return [
  81. _buildTitleButton(
  82. FIcons.fis_quash,
  83. i18nBook.common.revoke.t,
  84. () => application.undoRecord(),
  85. ),
  86. _buildTitleButton(
  87. FIcons.fis_purge,
  88. i18nBook.measure.clear.t,
  89. () => application.clearRecords(),
  90. ),
  91. _buildTitleButton(
  92. measureHandler.fullScreenState
  93. ? FIcons.fis_full_screen_reduction
  94. : FIcons.fis_full_screen,
  95. measureHandler.fullScreenState
  96. ? i18nBook.common.cancel.t + i18nBook.measure.fullScreen.t
  97. : i18nBook.measure.fullScreen.t,
  98. () {
  99. measureHandler.fullScreenState = !measureHandler.fullScreenState;
  100. setState(() {});
  101. },
  102. ),
  103. _buildTitleButton(
  104. FIcons.fis_save,
  105. i18nBook.common.save.t,
  106. widget.capturePng,
  107. ),
  108. _buildTitleButton(
  109. FIcons.fis_share,
  110. i18nBook.remedical.share.t,
  111. () async {
  112. var itemCurrentImage = await measureData.shareImage.call(
  113. measureData.itemCurrentImage,
  114. );
  115. Get.dialog(_buildShareQr(itemCurrentImage));
  116. },
  117. ),
  118. if (application.isThirdPart) ...[
  119. _buildTitleButton(
  120. FIcons.device,
  121. i18nBook.remedical.calibrationLine.t,
  122. () {
  123. Get.find<IStandardLineCalibrationController>().enterEditMode();
  124. },
  125. ),
  126. ],
  127. if (canShowAI) ...[
  128. _buildTitleButton(
  129. !aiPatintController.state.ifShowAi
  130. ? FIcons.fis_eye_display
  131. : FIcons.fis_eye_hidden,
  132. !aiPatintController.state.ifShowAi
  133. ? i18nBook.measure.showAi.t
  134. : i18nBook.measure.hideAi.t,
  135. () {
  136. aiPatintController.state.ifShowAi =
  137. !aiPatintController.state.ifShowAi;
  138. setState(() {});
  139. },
  140. ),
  141. ],
  142. if (exist3DData && ifShowVidModeButton) ...[
  143. _buildTitleButton(
  144. FIcons.three_dimensional,
  145. i18nBook.measure.carotid3DMode.t,
  146. () {
  147. measure3DViewController.changeModeTo3DMode();
  148. },
  149. ),
  150. ],
  151. if (exist3DData && ifShowModeButton) ...[
  152. _buildTitleButton(
  153. FIcons.three_dimensional,
  154. i18nBook.measure.carotid3DMode.t,
  155. () {
  156. measure3DViewController.backTo3DMode();
  157. },
  158. ),
  159. _buildTitleButton(
  160. Icons.play_circle_outline_rounded,
  161. i18nBook.measure.vidMode.t,
  162. () {
  163. measure3DViewController.backToVidMode();
  164. playerController.resetCurrentFrame();
  165. },
  166. ),
  167. ]
  168. ];
  169. }
  170. @override
  171. Widget build(BuildContext context) {
  172. return Row(
  173. mainAxisAlignment: MainAxisAlignment.end,
  174. children: [
  175. InkWell(
  176. onTap: () {},
  177. onHover: (isHover) {
  178. if (!isHover) {
  179. setState(() {
  180. _width = 0;
  181. _isExpanded = isHover;
  182. });
  183. } else {
  184. setState(() {
  185. // application.isThirdPart ? _width = 270 : _width = 220;
  186. _width = buildTitleButtonList().length * 48;
  187. _isExpanded = isHover;
  188. });
  189. }
  190. },
  191. child: AnimatedContainer(
  192. duration: const Duration(milliseconds: 300),
  193. padding: const EdgeInsets.only(
  194. top: 5,
  195. bottom: 5,
  196. left: 15,
  197. ),
  198. decoration: BoxDecoration(
  199. borderRadius: const BorderRadius.only(
  200. topLeft: Radius.circular(4),
  201. bottomLeft: Radius.circular(4),
  202. ),
  203. color: Colors.grey.withOpacity(0.6),
  204. ),
  205. width: _width,
  206. height: 60,
  207. child: _isExpanded
  208. ? FutureBuilder(
  209. future: _showList(),
  210. builder: (context, snapshot) {
  211. if (!snapshot.hasData) {
  212. return const SizedBox();
  213. }
  214. return Row(
  215. children: buildTitleButtonList(),
  216. );
  217. },
  218. )
  219. : const SizedBox(),
  220. ),
  221. ),
  222. InkWell(
  223. onTap: () {},
  224. onHover: (isHover) {
  225. if (isHover) {
  226. setState(() {
  227. _width = buildTitleButtonList().length * 48;
  228. _isExpanded = isHover;
  229. });
  230. } else {
  231. setState(() {
  232. _width = 0;
  233. _isExpanded = isHover;
  234. });
  235. }
  236. },
  237. child: Container(
  238. height: 60,
  239. color: Colors.white,
  240. child: !_isExpanded
  241. ? const Icon(Icons.chevron_left_rounded)
  242. : const Icon(Icons.chevron_right_rounded),
  243. ),
  244. ),
  245. ],
  246. );
  247. }
  248. FWidget _buildShareQr(String itemCurrentImage) {
  249. return FSimpleDialog(
  250. title: FText(
  251. i18nBook.remedical.share.t,
  252. style: const TextStyle(
  253. color: Colors.white,
  254. fontSize: 18,
  255. ),
  256. ),
  257. isDefault: false,
  258. children: [
  259. FContainer(
  260. width: 360,
  261. child: FContainer(
  262. padding: const EdgeInsets.only(top: 20, bottom: 20),
  263. child: QRCodeWithLogo(
  264. itemCurrentImage,
  265. codeStatement: i18nBook.remedical.scanQrCodeToShareImage.t,
  266. operationStatement: i18nBook.remedical.copyLink.t,
  267. operationSuccessCallback: () =>
  268. {PromptBox.toast(i18nBook.remedical.copySuccess.t)},
  269. ),
  270. ),
  271. ),
  272. ],
  273. );
  274. }
  275. //定义方法
  276. void _launchURL(url) async {
  277. if (await canLaunch(url)) {
  278. await launch(url);
  279. } else {
  280. throw 'Could not launch $url';
  281. }
  282. }
  283. //跳转
  284. Future<bool> _showList() async {
  285. await Future.delayed(const Duration(milliseconds: 300));
  286. return true;
  287. }
  288. Widget _buildTitleButton(IconData icon, String title, Function onClick) {
  289. return Container(
  290. margin: const EdgeInsets.only(
  291. right: 10,
  292. ),
  293. child: InkWell(
  294. onTap: () => onClick.call(),
  295. child: Column(
  296. children: [
  297. Icon(
  298. icon,
  299. color: Colors.white,
  300. ),
  301. Text(
  302. title,
  303. style: const TextStyle(
  304. color: Colors.white,
  305. fontSize: 14,
  306. ),
  307. )
  308. ],
  309. ),
  310. ),
  311. );
  312. }
  313. }