import 'dart:math' as math; import 'package:fis_measure/interfaces/date_types/int_size.dart'; import 'package:fis_measure/interfaces/process/player/play_controller.dart'; import 'package:fis_measure/interfaces/process/workspace/application.dart'; import 'package:fis_measure/view/player/enums.dart'; import 'package:fis_vid/data_host/data_host.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import '../canvas/active_canvas.dart'; import '../canvas/records_canvas.dart'; import '../gesture/mouse_gesture.dart'; import '../player/controller.dart'; import '../player/events.dart'; import '../player/player.dart'; import '../result/results_panel.dart'; class MeasureMainView extends StatefulWidget { const MeasureMainView({Key? key}) : super(key: key); @override State createState() => _MeasureMainViewState(); } class _MeasureMainViewState extends State { late final application = Get.find(); late final playerController = Get.find(); late bool canMeasure = application.canMeasure; IntSize get frameSize { if (application.frameData == null) return IntSize.empty; return IntSize.fill( application.frameData!.width, application.frameData!.height, ); } @override void initState() { super.initState(); WidgetsBinding.instance!.addPostFrameCallback((timeStamp) { onCanMeasureChanged(this, application.canMeasure); application.canMeasureChanged.addListener(onCanMeasureChanged); }); } @override void dispose() { application.canMeasureChanged.removeListener(onCanMeasureChanged); super.dispose(); } void onCanMeasureChanged(Object sender, bool e) { if (e != canMeasure) { setState(() { canMeasure = e; }); } } @override Widget build(BuildContext context) { return Container( color: Colors.black, child: CustomMultiChildLayout( delegate: _LayerLayoutDelegate(imageSize: frameSize), children: [ LayoutId( id: _LayerLayoutIds.player, child: Container( decoration: BoxDecoration( // border: Border.all(color: Colors.white), ), child: VidPlayer(playerController as VidPlayerController), ), ), if (canMeasure) ...[ LayoutId( id: _LayerLayoutIds.recordsCanvas, child: const MeasureRecordsCanvasPanel(), ), LayoutId( id: _LayerLayoutIds.result, child: const MeasureResultPanel(), ), LayoutId( id: _LayerLayoutIds.activeCanvas, child: const MeasureActiveCanvasPanel(), ), LayoutId( id: _LayerLayoutIds.gesture, child: const MeasureMouseGesturePanel(), ), ], ], ), ); } } class _LayerLayoutDelegate extends MultiChildLayoutDelegate { final IntSize? imageSize; Offset? layoutOffset; Size? layoutSize; _LayerLayoutDelegate({required this.imageSize}); @override void performLayout(Size size) { if (imageSize == null) return; if (!hasChild(_LayerLayoutIds.player)) return; /// 以Contain方式填充布局,计算定位偏移量 calcSize(size); final offset = layoutOffset!; final renderSize = layoutSize!; Get.find().displaySize = renderSize; layoutLayer(_LayerLayoutIds.player, offset, renderSize); /// 其他层按播放器尺寸位置层叠布局 layoutLayer(_LayerLayoutIds.recordsCanvas, offset, renderSize); layoutLayer(_LayerLayoutIds.result, offset, renderSize); layoutLayer(_LayerLayoutIds.activeCanvas, offset, renderSize); layoutLayer(_LayerLayoutIds.gesture, offset, renderSize); } void layoutLayer(_LayerLayoutIds layoutId, Offset offset, Size size) { if (hasChild(layoutId)) { layoutChild( layoutId, BoxConstraints.loose(size), ); positionChild(layoutId, offset); } } void calcSize(Size size) { final parentWHRatio = size.width / size.height; final imageWHRatio = imageSize!.width / imageSize!.height; if (imageWHRatio < parentWHRatio) { // 高度撑满 final layoutWidth = size.height * imageWHRatio; final layoutHeight = size.height; final offsetX = (size.width - layoutWidth) / 2; layoutOffset = Offset(offsetX, 0); layoutSize = Size(layoutWidth, layoutHeight); } else if (imageWHRatio > parentWHRatio) { // 宽度撑满 final layoutWidth = size.width; final layoutHeight = size.width / imageWHRatio; final offsetY = (size.height - layoutHeight) / 2; layoutOffset = Offset(0, offsetY); layoutSize = Size(layoutWidth, layoutHeight); } else { layoutOffset = Offset.zero; layoutSize = size; } // final widthRatio = imageSize!.width / size.width; // final heightRatio = imageSize!.height / size.height; // if (widthRatio < heightRatio) { // final layoutWidth = size.width * heightRatio; // final layoutHeight = size.height; // final offsetX = (size.width - layoutWidth) / 2; // layoutOffset = Offset(offsetX, 0); // layoutSize = Size(layoutWidth, layoutHeight); // } else if (widthRatio > heightRatio) { // final layoutWidth = size.width; // final layoutHeight = size.height * widthRatio; // final offsetY = (size.height - layoutHeight) / 2; // layoutOffset = Offset(0, offsetY); // layoutSize = Size(layoutWidth, layoutHeight); // } else { // layoutOffset = Offset.zero; // layoutSize = size; // } } @override bool shouldRelayout(covariant MultiChildLayoutDelegate oldDelegate) { return false; } } enum _LayerLayoutIds { /// 播放器 player, /// 测量记录画板 recordsCanvas, /// 活动测量画板 activeCanvas, /// 结果面板 result, /// 手势面板 gesture, }