import 'dart:convert'; import 'package:fis_common/logger/logger.dart'; import 'package:fis_measure/interfaces/date_types/rect.dart'; import 'package:fis_measure/interfaces/enums/display_mode.dart'; import 'package:fis_measure/interfaces/enums/visual_area_type.dart'; import 'package:fis_measure/interfaces/mode_names.dart'; import 'package:fis_measure/process/layout/layout_config_json.dart'; import 'package:fis_measure/values/strings.dart'; import 'package:flutter/services.dart'; import 'section.dart'; import 'view_port.dart'; /// 视图布局配置 class LayoutConfiguration { static LayoutConfiguration? _instance; /// 单例 static LayoutConfiguration get ins { _instance ??= LayoutConfiguration(); return _instance!; } bool _loaded = false; final List _layoutSections = []; /// 是否已加载 bool get loaded => _loaded; LayoutConfiguration(); /// 加载数据 Future loadData() async { try { if (loaded) return; // String jsonText = // await rootBundle.loadString(MeasureStrings.LayoutConfigurationAsset); final map = jsonDecode(LayoutConfigurationJSON); final sections = map['LayoutSections'] as List; _loadSections(sections); _loaded = true; } catch (e) { logger.e("[Measure] init LayoutConfiguration error", e); } } void _loadSections(List sections) { for (final item in sections) { final Map map = item; _layoutSections.add(LayoutSection.fromJson(map)); } if (_layoutSections.isEmpty) { throw ArgumentError( "Layout configuration error: LayoutSection not found."); } } /// 获取 AreaType区域 /// /// [section] 配置名 /// /// [areaType] 区域类型 /// /// [displayFormat] 显示模式 DRect getRect( String section, VisualAreaTypeEnum areaType, DisplayModeEnum displayFormat, ) { final mode = _findVisualAreaMode(areaType); final viewPort = _matchViewPort(section, mode, displayFormat); final rect = DRect( viewPort.left / 100, viewPort.top / 100, (viewPort.right - viewPort.left) / 100, (viewPort.bottom - viewPort.top) / 100, ); return rect; } LayoutViewPort _matchViewPort( String section, String mode, DisplayModeEnum displayFormat, ) { bool found = false; LayoutViewPort viewPort = LayoutViewPort(); List sections = []; final sectionIdx = _layoutSections.indexWhere((x) => x.name == section); if (sectionIdx > -1) { sections.add(_layoutSections[sectionIdx]); } sections.add(_layoutSections[0]); for (final candidate in sections) { final layoutIdx = candidate.layouts.indexWhere((x) => x.mode == mode); if (layoutIdx > -1) { final layout = candidate.layouts[layoutIdx]; int i = -1; while (++i < layout.viewPorts.length) { if (layout.viewPorts[i].displayFormat == displayFormat) { break; } } if (i == layout.viewPorts.length) { i = 0; } viewPort = layout.viewPorts[i]; found = true; break; } } if (!found) { logger.w( "MatchViewPort failed, ViewPort:$viewPort is used. layout section:$section, mode:$mode, display format:${displayFormat.name}."); } return viewPort; } String _findVisualAreaMode(VisualAreaTypeEnum areaType) { switch (areaType) { case VisualAreaTypeEnum.tissue: case VisualAreaTypeEnum.flow: return ModeNames.B; case VisualAreaTypeEnum.timeMotion: case VisualAreaTypeEnum.tissueTimeMotion: return ModeNames.TM; case VisualAreaTypeEnum.doppler: return ModeNames.Doppler; case VisualAreaTypeEnum.trace: return ModeNames.Trace; case VisualAreaTypeEnum.colorbar: return ModeNames.P_ColorBar; case VisualAreaTypeEnum.tissue3D: return ModeNames.FourD; case VisualAreaTypeEnum.sweiReliableColorBar: return ModeNames.P_SweiReliableColorBar; } } }