123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441 |
- import 'package:fis_jsonrpc/rpc.dart';
- import 'package:fis_measure/interfaces/enums/annotation.dart';
- import 'package:fis_measure/interfaces/process/items/measure_terms.dart';
- import 'package:fis_measure/interfaces/process/player/play_controller.dart';
- import 'package:fis_measure/interfaces/process/standard_line/calibration.dart';
- import 'package:fis_measure/interfaces/process/workspace/application.dart';
- import 'package:fis_measure/interfaces/process/workspace/exam_info.dart';
- import 'package:fis_measure/interfaces/process/workspace/measure_controller.dart';
- import 'package:fis_measure/process/workspace/measure_controller.dart';
- import 'package:fis_measure/process/workspace/measure_data_controller.dart';
- import 'package:fis_measure/view/measure/measure_main_view.dart';
- import 'package:flutter/material.dart';
- import 'package:get/get.dart';
- class MeasureDataTester {
- static Future<List<RemedicalItemList>> getRemedicalList(
- String patientCode,
- String recordCode,
- String token,
- ) async {
- return [];
- }
- static Future<RemedicalInfoDTO?> getImageInfo(
- String remedicalCode,
- String token,
- ) async {
- return null;
- }
- static Future<MeasureApplicationDTO?> getMeasureApplication(
- dynamic args) async {
- return null;
- }
- static Future<MeasureApplicationDTO?> saveUserDefinedMeasureApplicationAsync(
- dynamic args) async {
- return null;
- }
- }
- class MeasureTestPage extends StatefulWidget {
- const MeasureTestPage({Key? key}) : super(key: key);
- @override
- State<StatefulWidget> createState() => _MeasureTestPageState();
- }
- class _MeasureTestPageState extends State<MeasureTestPage> {
- static const C_LINEAR_TISSUE =
- // "http://43.138.119.65:9303/Flyinsono-BJ-1300984704.VCS.AP-BeiJing/9eb581250c6845b7800f0ba00218e043.VID";
- // "http://cdn-bj.fis.plus/0B344F48BA574ECD82B7FEDB8848421A.vid";//单幅TM
- // "http://cdn-bj.fis.plus/6B6E069659D14E7299EB9F6EFCDE9C8C.vid"; //双幅单TissueConvex
- // "http://cdn-bj.fis.plus/062643B82365437DB95F3811580AF3ED.vid"; //四幅单模式
- // "http://cdn-bj.fis.plus/EA90D146049D416E8E466B7446E00001.vid"; //四幅Doppler
- "http://cdn-bj.fis.plus/3rd_linearTvTissue2.vid"; //魔盒
- // "http://cdn-bj.fis.plus/81FFF8E5E078473FA687FBE81C4869B1.vid"; // 魔盒TV
- static const C_CONVEX_TISSUE =
- "http://cdn-bj.fis.plus/FEB1AAE5D9C24839BEE31B16E8CB450A.vid";
- final datac = Get.put(MeasureDataController(
- MeasureDataTester.getRemedicalList,
- MeasureDataTester.getImageInfo,
- MeasureDataTester.getMeasureApplication,
- MeasureDataTester.saveUserDefinedMeasureApplicationAsync,
- ));
- final controller = Get.put<IMeasureController>(MeasureController(
- "12345",
- imagesFetchFunc: (code) async {
- return <ExamImageInfo>[
- ExamImageInfo(C_LINEAR_TISSUE, C_LINEAR_TISSUE),
- ExamImageInfo(C_CONVEX_TISSUE, C_CONVEX_TISSUE)
- ];
- },
- ));
- bool loaded = false;
- int opType = 0;
- bool useArrowAnnotation = false;
- @override
- void initState() {
- controller.load().then((value) {
- // 加载指定图像
- controller.examInfo.selectedImageIndex = 0;
- });
- controller.imageLoaded.addListener(onImageLoaded);
- super.initState();
- }
- @override
- void dispose() {
- controller.imageLoaded.removeListener(onImageLoaded);
- controller.dispose();
- Get.delete<IMeasureController>();
- super.dispose();
- }
- void onImageLoaded(Object sender, ExamImageInfo? e) {
- if (!mounted) return;
- if (e != null) {
- Future.delayed(const Duration(milliseconds: 100), () {
- controller.playerController.play();
- });
- setState(() {
- loaded = true;
- });
- }
- }
- @override
- Widget build(BuildContext context) {
- Widget body;
- if (!loaded) {
- const loadingWidget = Center(child: CircularProgressIndicator());
- body = Row(
- children: const [
- SizedBox(
- width: 300,
- child: loadingWidget,
- ),
- VerticalDivider(),
- Expanded(child: loadingWidget),
- ],
- );
- } else {
- body = Row(
- key: ValueKey(controller.examInfo.selectedImageIndex),
- children: [
- opType == 1
- ? const _MeasureLeftAnnotation()
- : const _MeasureLeftBoard(),
- const VerticalDivider(),
- const Expanded(
- child: MeasureRightBoard(),
- ),
- ],
- );
- }
- return Scaffold(
- backgroundColor: const Color.fromARGB(255, 53, 55, 51),
- appBar: AppBar(
- actions: [
- TextButton(
- onPressed: () {
- Get.find<IApplication>().clearRecords();
- },
- child: const Text(
- "清空",
- style: TextStyle(
- color: Colors.white,
- ),
- ),
- ),
- TextButton(
- onPressed: () {
- Get.find<IApplication>().undoRecord();
- },
- child: const Text(
- "撤销",
- style: TextStyle(
- color: Colors.white,
- ),
- ),
- ),
- TextButton(
- onPressed: () {
- final c = Get.find<IStandardLineCalibrationController>();
- if (c.isEditing) {
- c.cancelEdit();
- } else {
- c.enterEditMode();
- }
- },
- child: const Text(
- "校准线",
- style: TextStyle(
- color: Colors.white,
- ),
- ),
- ),
- TextButton.icon(
- onPressed: () {
- setState(() {
- if (useArrowAnnotation) {
- useArrowAnnotation = false;
- controller.workingApplication.switchAnnotation();
- } else {
- useArrowAnnotation = true;
- controller.workingApplication
- .switchAnnotation(AnnotationType.arrow);
- }
- });
- },
- icon: const Icon(Icons.arrow_right_alt_sharp),
- label: Text(
- "箭头",
- style: TextStyle(
- color: useArrowAnnotation ? Colors.amber : Colors.white,
- ),
- ),
- ),
- TextButton(
- onPressed: () {
- setState(() {
- opType = opType == 1 ? 0 : 1;
- });
- },
- child: Text(
- opType == 1 ? "注释" : "测量",
- style: const TextStyle(
- color: Colors.white,
- ),
- ),
- ),
- TextButton(
- onPressed: () {
- if (controller.examInfo.selectedImageIndex == 0) return;
- controller.examInfo.selectedImageIndex = 0;
- },
- child: Text(
- '线阵',
- style: TextStyle(
- color: controller.examInfo.selectedImageIndex == 0
- ? Colors.amber
- : Colors.white,
- ),
- ),
- ),
- TextButton(
- onPressed: () {
- if (controller.examInfo.selectedImageIndex == 1) return;
- controller.examInfo.selectedImageIndex = 1;
- },
- child: Text(
- '扇阵',
- style: TextStyle(
- color: controller.examInfo.selectedImageIndex == 1
- ? Colors.amber
- : Colors.white,
- ),
- ),
- ),
- ],
- leading: IconButton(
- onPressed: () {
- Navigator.of(context).pop();
- },
- icon: const Icon(Icons.arrow_back),
- ),
- ),
- body: body,
- );
- }
- }
- class MeasureRightBoard extends StatefulWidget {
- const MeasureRightBoard({Key? key}) : super(key: key);
- @override
- State<StatefulWidget> createState() => _MeasureRightBoardState();
- }
- class _MeasureRightBoardState extends State<MeasureRightBoard> {
- final playerController = Get.find<IPlayerController>();
- @override
- Widget build(BuildContext context) {
- return Container(
- padding: const EdgeInsets.all(8).copyWith(left: 0),
- child: const MeasureMainView(),
- );
- }
- }
- class _MeasureLeftBoard extends StatefulWidget {
- const _MeasureLeftBoard({Key? key}) : super(key: key);
- @override
- State<StatefulWidget> createState() => _MeasureLeftBoardState();
- }
- class _MeasureLeftBoardState extends State<_MeasureLeftBoard> {
- // ignore: non_constant_identifier_names
- static final C_SUPPORTED_ITEMS = <String>[
- MeasureTerms.Distance,
- MeasureTerms.Perimeter,
- MeasureTerms.Area,
- MeasureTerms.Depth,
- ];
- final scrollController = ScrollController();
- final application = Get.find<IApplication>();
- int activeIndex = 0;
- @override
- void initState() {
- application.switchItemByName(C_SUPPORTED_ITEMS[0]);
- application.canMeasureChanged.addListener(_onCanMeasureChanged);
- super.initState();
- }
- @override
- dispose() {
- application.canMeasureChanged.removeListener(_onCanMeasureChanged);
- super.dispose();
- }
- _onCanMeasureChanged(Object sender, bool e) {
- if (e && mounted) {
- changeItem(0);
- }
- }
- @override
- Widget build(BuildContext context) {
- return Container(
- width: 300,
- padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 12),
- child: Scrollbar(
- controller: scrollController,
- isAlwaysShown: true,
- child: ListView.separated(
- controller: scrollController,
- itemCount: C_SUPPORTED_ITEMS.length,
- itemBuilder: (BuildContext context, int index) {
- final name = C_SUPPORTED_ITEMS[index];
- final active = index == activeIndex;
- return active
- ? ElevatedButton(
- onPressed: () => changeItem(index),
- child: Text(name),
- style: ElevatedButton.styleFrom(
- fixedSize: const Size.fromHeight(50),
- ),
- )
- : OutlinedButton(
- onPressed: () => changeItem(index),
- child: Text(name),
- style: OutlinedButton.styleFrom(
- fixedSize: const Size.fromHeight(50),
- ),
- );
- },
- separatorBuilder: (BuildContext context, int index) {
- return const SizedBox(height: 8);
- },
- ),
- ),
- );
- }
- void changeItem(int index) {
- setState(() {
- activeIndex = index;
- });
- final name = C_SUPPORTED_ITEMS[index];
- application.switchItemByName(name);
- }
- }
- class _MeasureLeftAnnotation extends StatefulWidget {
- const _MeasureLeftAnnotation({Key? key}) : super(key: key);
- @override
- State<StatefulWidget> createState() => _MeasureLeftAnnotationState();
- }
- class _MeasureLeftAnnotationState extends State<_MeasureLeftAnnotation> {
- // ignore: non_constant_identifier_names
- static final C_SUPPORTED_TEXTS = <String>[
- "肝左叶",
- "胆囊",
- "脾脏",
- "结石",
- "积液",
- ];
- final scrollController = ScrollController();
- final application = Get.find<IApplication>();
- @override
- void initState() {
- // application.switchAnnotation(AnnotationType.label, C_SUPPORTED_TEXTS[0]);
- // application.switchAnnotation(AnnotationType.arrow);
- application.switchAnnotation(AnnotationType.input);
- super.initState();
- }
- @override
- Widget build(BuildContext context) {
- return Container(
- width: 300,
- padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 12),
- child: Scrollbar(
- controller: scrollController,
- isAlwaysShown: true,
- child: ListView.separated(
- controller: scrollController,
- itemCount: C_SUPPORTED_TEXTS.length,
- itemBuilder: (BuildContext context, int index) {
- final name = C_SUPPORTED_TEXTS[index];
- const style = TextStyle(color: Colors.white, fontSize: 16);
- const dragStyle = TextStyle(color: Colors.amber, fontSize: 18);
- // TODO: melon - set drag cursor after version updated up then 3.0
- // https://github.com/flutter/flutter/pull/100475
- return Draggable<String>(
- data: name,
- dragAnchorStrategy: (data, context, offset) {
- // return offset - Offset(120, 14);
- return Offset.zero;
- },
- child: OutlinedButton(
- child: Text(name, style: style),
- onPressed: () {
- application.switchAnnotation(AnnotationType.label, name);
- },
- style: OutlinedButton.styleFrom(
- shape: RoundedRectangleBorder(
- borderRadius: BorderRadius.circular(4),
- ),
- side: BorderSide(color: Colors.grey.shade100),
- fixedSize: const Size.fromHeight(44),
- ),
- ),
- feedback: Material(
- color: Colors.transparent,
- child: Text(name, style: dragStyle),
- ),
- onDragStarted: () {
- application.switchAnnotation(AnnotationType.label, name);
- },
- );
- },
- separatorBuilder: (BuildContext context, int index) {
- return const SizedBox(height: 8);
- },
- ),
- ),
- );
- }
- }
|