|
@@ -1,9 +1,14 @@
|
|
|
import 'package:fis_common/logger/logger.dart';
|
|
|
import 'package:fis_i18n/i18n.dart';
|
|
|
+import 'package:fis_jsonrpc/services/remedical.m.dart';
|
|
|
import 'package:fis_measure/interfaces/process/items/item_metas.dart';
|
|
|
import 'package:fis_measure/interfaces/process/items/terms.dart';
|
|
|
import 'package:fis_measure/interfaces/process/items/types.dart';
|
|
|
+import 'package:fis_measure/interfaces/process/player/play_controller.dart';
|
|
|
import 'package:fis_measure/interfaces/process/workspace/application.dart';
|
|
|
+import 'package:fis_measure/process/workspace/measure_data_controller.dart';
|
|
|
+import 'package:fis_measure/process/workspace/measure_handler.dart';
|
|
|
+import 'package:fis_measure/view/mobile_view/mobile_right_panel/mobile_more_measure_item_dialog.dart';
|
|
|
import 'package:fis_ui/index.dart';
|
|
|
import 'package:flutter/material.dart';
|
|
|
import 'package:flutter/services.dart';
|
|
@@ -21,12 +26,19 @@ class MobileMeasureSelector extends FStatefulWidget {
|
|
|
class _MobileMeasureSelector extends FState<MobileMeasureSelector> {
|
|
|
late final application = Get.find<IApplication>();
|
|
|
|
|
|
+
|
|
|
+ late final measureData = Get.find<MeasureDataController>();
|
|
|
+ late final playerController = Get.find<IPlayerController>();
|
|
|
+
|
|
|
|
|
|
String activeName = "";
|
|
|
|
|
|
-
|
|
|
- List<MobileMeasureBtn> mobileMeasureBtnList = [
|
|
|
- MobileMeasureBtn(
|
|
|
+
|
|
|
+ bool showMore = false;
|
|
|
+
|
|
|
+
|
|
|
+ final List<MobileBaseMeasureItemBtn> _mobileBasicMeasureItemsList = [
|
|
|
+ MobileBaseMeasureItemBtn(
|
|
|
icon: Icons.linear_scale,
|
|
|
displayName: i18nBook.measure.distance.t,
|
|
|
itemMeta: ItemMeta(
|
|
@@ -39,7 +51,7 @@ class _MobileMeasureSelector extends FState<MobileMeasureSelector> {
|
|
|
],
|
|
|
),
|
|
|
),
|
|
|
- MobileMeasureBtn(
|
|
|
+ MobileBaseMeasureItemBtn(
|
|
|
icon: Icons.border_style,
|
|
|
displayName: i18nBook.measure.circumference.t,
|
|
|
itemMeta: ItemMeta(
|
|
@@ -52,7 +64,7 @@ class _MobileMeasureSelector extends FState<MobileMeasureSelector> {
|
|
|
],
|
|
|
),
|
|
|
),
|
|
|
- MobileMeasureBtn(
|
|
|
+ MobileBaseMeasureItemBtn(
|
|
|
icon: Icons.format_shapes,
|
|
|
displayName: i18nBook.measure.area.t,
|
|
|
itemMeta: ItemMeta(
|
|
@@ -67,12 +79,17 @@ class _MobileMeasureSelector extends FState<MobileMeasureSelector> {
|
|
|
),
|
|
|
];
|
|
|
|
|
|
+
|
|
|
+ bool _isInitAllMeasureItems = false;
|
|
|
+
|
|
|
+
|
|
|
+ List<MobileMoreMeasureItemModesModel> _availableModes = [];
|
|
|
+
|
|
|
|
|
|
void changeItem(ItemMeta itemMeta) {
|
|
|
activeName = itemMeta.name;
|
|
|
try {
|
|
|
application.switchItem(itemMeta);
|
|
|
-
|
|
|
} catch (e) {
|
|
|
logger.e("changeItem failed", e);
|
|
|
}
|
|
@@ -85,36 +102,33 @@ class _MobileMeasureSelector extends FState<MobileMeasureSelector> {
|
|
|
FWidget build(BuildContext context) {
|
|
|
return FSizedBox(
|
|
|
width: 100,
|
|
|
- height: 320,
|
|
|
- child: FColumn(
|
|
|
- mainAxisAlignment: MainAxisAlignment.center,
|
|
|
- mainAxisSize: MainAxisSize.max,
|
|
|
- children: [
|
|
|
- const FSizedBox(height: 30),
|
|
|
- ...mobileMeasureBtnList.map((e) {
|
|
|
- return _buildMeasureBtn(e.itemMeta, e.itemMeta.name == activeName,
|
|
|
- e.displayName, e.icon);
|
|
|
- }).toList(),
|
|
|
- ]),
|
|
|
+ child: _buildBaseMeasureItemPanel(),
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ FWidget _buildBaseMeasureItemPanel() {
|
|
|
+ return FColumn(
|
|
|
+ mainAxisAlignment: MainAxisAlignment.center,
|
|
|
+ mainAxisSize: MainAxisSize.max,
|
|
|
+ children: [
|
|
|
+ ..._mobileBasicMeasureItemsList.map((e) {
|
|
|
+ return _buildBaseMeasureBtn(
|
|
|
+ e.itemMeta, e.itemMeta.name == activeName, e.displayName, e.icon);
|
|
|
+ }).toList(),
|
|
|
+ _buildChangeMoreMeasureItem(),
|
|
|
+ ],
|
|
|
);
|
|
|
}
|
|
|
|
|
|
- FWidget _buildMeasureBtn(
|
|
|
+
|
|
|
+ FWidget _buildBaseMeasureBtn(
|
|
|
ItemMeta itemMeta, bool ifActive, String displayName, IconData icon) {
|
|
|
return FInkWell(
|
|
|
onTap: () {
|
|
|
HapticFeedback.mediumImpact();
|
|
|
if (ifActive) {
|
|
|
- changeItem(
|
|
|
- ItemMeta(
|
|
|
- "None",
|
|
|
- measureType: "None",
|
|
|
- description: "None",
|
|
|
- outputs: [
|
|
|
- ItemOutputMeta("None", "None", VidUsUnit.cm2),
|
|
|
- ],
|
|
|
- ),
|
|
|
- );
|
|
|
+ _cancelCurrSelect();
|
|
|
} else {
|
|
|
changeItem(itemMeta);
|
|
|
}
|
|
@@ -151,12 +165,155 @@ class _MobileMeasureSelector extends FState<MobileMeasureSelector> {
|
|
|
),
|
|
|
);
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
+ FWidget _buildChangeMoreMeasureItem() {
|
|
|
+ return FInkWell(
|
|
|
+ onTap: () async {
|
|
|
+ _cancelCurrSelect();
|
|
|
+ HapticFeedback.mediumImpact();
|
|
|
+ await _openMoreMeasureItemDialog();
|
|
|
+ },
|
|
|
+ child: Container(
|
|
|
+ margin: const EdgeInsets.fromLTRB(0, 10, 10, 10),
|
|
|
+ padding: const EdgeInsets.fromLTRB(10, 0, 10, 0),
|
|
|
+ decoration: BoxDecoration(
|
|
|
+ border: Border.all(color: Colors.transparent),
|
|
|
+ borderRadius: BorderRadiusGeometry.lerp(
|
|
|
+ BorderRadius.circular(10), BorderRadius.circular(10), 10),
|
|
|
+ ),
|
|
|
+ child: FColumn(
|
|
|
+ children: const [
|
|
|
+ FIcon(
|
|
|
+ Icons.format_list_bulleted,
|
|
|
+ color: Colors.grey,
|
|
|
+ ),
|
|
|
+ FText(
|
|
|
+
|
|
|
+ '更多',
|
|
|
+ style: TextStyle(
|
|
|
+ color: Colors.grey,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ Future<void> _openMoreMeasureItemDialog() async {
|
|
|
+ List<MobileMoreMeasureItemModesModel> modes = [];
|
|
|
+ if (_isInitAllMeasureItems) {
|
|
|
+ modes = _availableModes;
|
|
|
+ } else {
|
|
|
+ modes = await _initMeasureItemsList();
|
|
|
+ _availableModes = modes;
|
|
|
+ }
|
|
|
+ final ItemMeta? result =
|
|
|
+ await Get.dialog<ItemMeta>(MobileMoreMeasureItemDialog(
|
|
|
+ measureModeList: modes,
|
|
|
+ ));
|
|
|
+ if (result != null) {
|
|
|
+ changeItem(result);
|
|
|
+ setState(() {
|
|
|
+ showMore = true;
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ void _cancelCurrSelect() {
|
|
|
+ changeItem(
|
|
|
+ ItemMeta(
|
|
|
+ "None",
|
|
|
+ measureType: "None",
|
|
|
+ description: "None",
|
|
|
+ outputs: [
|
|
|
+ ItemOutputMeta("None", "None", VidUsUnit.cm2),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ Future<List<MobileMoreMeasureItemModesModel>> _initMeasureItemsList() async {
|
|
|
+ final vidImage = playerController.currentFrame;
|
|
|
+ if (vidImage == null) return [];
|
|
|
+ List<String> getModes = [];
|
|
|
+ List<String> displayModeNames = [];
|
|
|
+ for (var element in vidImage.visuals[0].modes) {
|
|
|
+ getModes.add(element.type.toString().split('.')[1]);
|
|
|
+ displayModeNames.add(element.displayName);
|
|
|
+ }
|
|
|
+ measureData.applicationModes = vidImage.visuals[0].modes;
|
|
|
+ measureData.currentMode = vidImage.visuals[0].modes.first.type.name;
|
|
|
+ var measureModeSelection = MeasureModeSelection(
|
|
|
+ application.applicationName,
|
|
|
+ application.categoryName,
|
|
|
+ application.isThirdPart ? ['TPPTissue'] : getModes,
|
|
|
+ );
|
|
|
+
|
|
|
+
|
|
|
+ final MeasureApplicationDTO? measureApplicationDTO =
|
|
|
+ await measureData.getMeasureApplication.call(measureModeSelection);
|
|
|
+ if (measureApplicationDTO == null ||
|
|
|
+ measureApplicationDTO.availableModes == null) return [];
|
|
|
+
|
|
|
+
|
|
|
+ List<MobileMoreMeasureItemModesModel> supportedModes = [];
|
|
|
+ for (int i = 0; i < measureApplicationDTO.availableModes!.length; i++) {
|
|
|
+ MeasureModeDTO mode = measureApplicationDTO.availableModes![i];
|
|
|
+ List<ItemMetaDTO> supportedItems = _currSupportedItemFilter(mode);
|
|
|
+ String modeName = displayModeNames.length > i ? displayModeNames[i] : '';
|
|
|
+ MobileMoreMeasureItemModesModel modeModel =
|
|
|
+ MobileMoreMeasureItemModesModel(
|
|
|
+ modeName: modeName, availableItems: supportedItems);
|
|
|
+ supportedModes.add(modeModel);
|
|
|
+ }
|
|
|
+ if (supportedModes.isNotEmpty) {
|
|
|
+ _isInitAllMeasureItems = true;
|
|
|
+ }
|
|
|
+ return supportedModes;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ List<ItemMetaDTO> _currSupportedItemFilter(MeasureModeDTO mode) {
|
|
|
+ List<ItemMetaDTO> _supportedItems = [];
|
|
|
+ if (mode.availableGroups == null || mode.availableGroups!.isEmpty) {
|
|
|
+ return _supportedItems;
|
|
|
+ }
|
|
|
+ for (MeasureGroupDTO group in mode.availableGroups!) {
|
|
|
+ if (group.availableFolders == null || group.availableFolders!.isEmpty) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ for (MeasureFolderDTO folder in group.availableFolders!) {
|
|
|
+ if (folder.availableItems == null || folder.availableItems!.isEmpty) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ for (ItemMetaDTO items in folder.availableItems!) {
|
|
|
+ if (items.measureTypeName == "Distance") {
|
|
|
+ _supportedItems.add(items);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ print("${mode.modeName} 模式下过滤出 ${_supportedItems.length} 项");
|
|
|
+ return _supportedItems;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-class MobileMeasureBtn {
|
|
|
+class MobileBaseMeasureItemBtn {
|
|
|
ItemMeta itemMeta;
|
|
|
String displayName;
|
|
|
IconData icon;
|
|
|
- MobileMeasureBtn(
|
|
|
+ MobileBaseMeasureItemBtn(
|
|
|
{required this.itemMeta, required this.displayName, required this.icon});
|
|
|
}
|
|
|
+
|
|
|
+class MobileMoreMeasureItemModesModel {
|
|
|
+ String modeName;
|
|
|
+ List<ItemMetaDTO> availableItems;
|
|
|
+ MobileMoreMeasureItemModesModel(
|
|
|
+ {required this.modeName, required this.availableItems});
|
|
|
+}
|