diff --git a/making_school_asignment_app/lib/page/home_page/children/homework_review/components/question_paper_view.dart b/making_school_asignment_app/lib/page/home_page/children/homework_review/components/question_paper_view.dart index ffbaa53..d52f77e 100644 --- a/making_school_asignment_app/lib/page/home_page/children/homework_review/components/question_paper_view.dart +++ b/making_school_asignment_app/lib/page/home_page/children/homework_review/components/question_paper_view.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'dart:io'; import 'dart:math'; import 'package:flutter/cupertino.dart'; @@ -30,7 +31,8 @@ class QuestionPaperView extends GetView { HomeworkReviewState get sateData => controller.state; ZoomState get zoomState => controller.zoomLogic.zoomState; - HomeworkReviewAnnotationsControlState get annotationState => controller.annotationState; + HomeworkReviewAnnotationsControlState get annotationState => + controller.annotationState; @override Widget build(BuildContext context) { @@ -46,11 +48,13 @@ class QuestionPaperView extends GetView { if (zoomFileModel == null) { /// 计算高度 - return LayoutBuilder(builder: (BuildContext context, BoxConstraints constraints) { - WidgetsBinding.instance.addPostFrameCallback((_) => zoomState.zoomFile.value = ZoomFileModel( - viewWidth: constraints.maxWidth, - viewHeight: constraints.maxHeight, - )); + return LayoutBuilder(builder: + (BuildContext context, BoxConstraints constraints) { + WidgetsBinding.instance.addPostFrameCallback( + (_) => zoomState.zoomFile.value = ZoomFileModel( + viewWidth: constraints.maxWidth, + viewHeight: constraints.maxHeight, + )); return const SizedBox(); }); } @@ -63,7 +67,11 @@ class QuestionPaperView extends GetView { return Stack( children: [ // 主图 - QuestionImageView(maxWidth, maxHeight, annotationState, controller, zoomState: zoomState, sateData: sateData, actualHeight: zoomFileModel.actualHeight!), + QuestionImageView( + maxWidth, maxHeight, annotationState, controller, + zoomState: zoomState, + sateData: sateData, + actualHeight: zoomFileModel.actualHeight!), // 继续批阅按钮 // Positioned(right: 3.w, bottom: 4.h, child: const $ContinueToReview(isFloatingAction: true)), // 上一题按钮 @@ -77,15 +85,19 @@ class QuestionPaperView extends GetView { heroTag: '点击前往上一题', tooltip: '点击前往上一题', focusColor: Theme.of(context).primaryColor, - backgroundColor: const Color.fromRGBO(24, 32, 32, 0.05), + backgroundColor: + const Color.fromRGBO(24, 32, 32, 0.05), elevation: 10.r, - onPressed: () => easyThrottle('TestQuestionSwitch', () { + onPressed: () => + easyThrottle('TestQuestionSwitch', () { var param = sateData.param.value; param.studentId = lastPageVal.studentId; param.templateId = lastPageVal.templateId; - sateData.param.value = DoPaperDetailsParam.fromJson(param.toJson()); + sateData.param.value = + DoPaperDetailsParam.fromJson(param.toJson()); }), - child: Icon(Icons.arrow_back_ios, color: Colors.white, size: 22.sp), + child: Icon(Icons.arrow_back_ios, + color: Colors.white, size: 22.sp), ); }), ), @@ -101,14 +113,18 @@ class QuestionPaperView extends GetView { heroTag: '点击前往下一题', tooltip: '点击前往下一题', elevation: 10.r, - backgroundColor: const Color.fromRGBO(24, 32, 32, 0.05), - onPressed: () => easyThrottle('TestQuestionSwitch', () { + backgroundColor: + const Color.fromRGBO(24, 32, 32, 0.05), + onPressed: () => + easyThrottle('TestQuestionSwitch', () { var param = sateData.param.value; param.studentId = nextPageVal.studentId; param.templateId = nextPageVal.templateId; - sateData.param.value = DoPaperDetailsParam.fromJson(param.toJson()); + sateData.param.value = + DoPaperDetailsParam.fromJson(param.toJson()); }), - child: Icon(Icons.arrow_forward_ios, color: Colors.white, size: 22.sp), + child: Icon(Icons.arrow_forward_ios, + color: Colors.white, size: 22.sp), ); }), ), @@ -145,7 +161,8 @@ class DataErrorThenRequestAgainButton extends StatelessWidget { child: CupertinoButton( color: Colors.grey[300], onPressed: () => easyThrottle('home_work_reload_data', () { - sateData.param.value = DoPaperDetailsParam.fromJson(sateData.param.value.toJson()); + sateData.param.value = + DoPaperDetailsParam.fromJson(sateData.param.value.toJson()); }), child: quickText('再次请求', color: Colors.black38), ), @@ -156,7 +173,8 @@ class DataErrorThenRequestAgainButton extends StatelessWidget { // 底部已阅数量和待阅数量 @swidget -Widget $totalSubmitCountView(BuildContext context, HomeworkReviewState sateData) { +Widget $totalSubmitCountView( + BuildContext context, HomeworkReviewState sateData) { return Obx(() { var data = sateData.data.value; if (data == null) return Container(); @@ -171,7 +189,10 @@ Widget $totalSubmitCountView(BuildContext context, HomeworkReviewState sateData) context: context, elevation: 10, backgroundColor: Colors.white, - shape: RoundedRectangleBorder(borderRadius: BorderRadius.only(topLeft: Radius.circular(10.r), topRight: Radius.circular(10.r))), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.only( + topLeft: Radius.circular(10.r), + topRight: Radius.circular(10.r))), builder: (BuildContext context) { return Padding( padding: EdgeInsets.symmetric(horizontal: 2.w), @@ -189,7 +210,8 @@ Widget $totalSubmitCountView(BuildContext context, HomeworkReviewState sateData) SizedBox(height: 10.h), Expanded( child: ListView( - padding: EdgeInsets.symmetric(vertical: 8.h, horizontal: 4.w), + padding: EdgeInsets.symmetric( + vertical: 8.h, horizontal: 4.w), children: [ Wrap( spacing: 7.2.w, // 主轴(水平)方向间距 @@ -200,27 +222,39 @@ Widget $totalSubmitCountView(BuildContext context, HomeworkReviewState sateData) alignment: const FractionalOffset(0.05, 0.09), children: [ Container( - padding: EdgeInsets.only(top: 1.2.h, bottom: 1.5.h, left: 13.w, right: 5.w), + padding: EdgeInsets.only( + top: 1.2.h, + bottom: 1.5.h, + left: 13.w, + right: 5.w), decoration: BoxDecoration( borderRadius: BorderRadius.circular(4.r), - color: const Color.fromRGBO(239, 242, 255, 1), + color: const Color.fromRGBO( + 239, 242, 255, 1), ), child: quickText( e.name, size: 12.sp, wordSpacing: 2, - color: const Color.fromRGBO(80, 94, 110, 1), + color: + const Color.fromRGBO(80, 94, 110, 1), ), ), Stack( - alignment: const FractionalOffset(0.52, 0.24), + alignment: + const FractionalOffset(0.52, 0.24), children: [ Icon( - const IconData(0xe63d, fontFamily: "AlibabaIcon"), + const IconData(0xe63d, + fontFamily: "AlibabaIcon"), size: 12.sp, - color: e.isPriority ? Theme.of(context).primaryColor : const Color.fromRGBO(164, 164, 164, 1), + color: e.isPriority + ? Theme.of(context).primaryColor + : const Color.fromRGBO( + 164, 164, 164, 1), ), - quickText('优先', size: 4.sp, color: Colors.white), + quickText('优先', + size: 4.sp, color: Colors.white), ], ), ], @@ -242,11 +276,17 @@ Widget $totalSubmitCountView(BuildContext context, HomeworkReviewState sateData) children: [ Padding( padding: EdgeInsets.only(bottom: 1.h), - child: quickText('已阅', color: const Color.fromRGBO(117, 117, 117, 1), size: 10.sp), + child: quickText('已阅', + color: const Color.fromRGBO(117, 117, 117, 1), size: 10.sp), ), - quickText(data.annotatedCount, color: Theme.of(context).primaryColor, size: 12.sp, fontWeight: FontWeight.bold), - quickText('/', color: const Color.fromRGBO(117, 117, 117, 1), size: 12.sp), - quickText(data.submitCount - data.annotatedCount, color: const Color.fromRGBO(117, 117, 117, 1), size: 10.sp), + quickText(data.annotatedCount, + color: Theme.of(context).primaryColor, + size: 12.sp, + fontWeight: FontWeight.bold), + quickText('/', + color: const Color.fromRGBO(117, 117, 117, 1), size: 12.sp), + quickText(data.submitCount - data.annotatedCount, + color: const Color.fromRGBO(117, 117, 117, 1), size: 10.sp), ], ), ), @@ -255,7 +295,8 @@ Widget $totalSubmitCountView(BuildContext context, HomeworkReviewState sateData) } // 试题图片视图 -class QuestionImageView extends HookWidget with EventBusMixin { +class QuestionImageView extends HookWidget + with EventBusMixin { final double maxWidth; final double maxHeight; final double actualHeight; @@ -263,7 +304,12 @@ class QuestionImageView extends HookWidget with EventBusMixin(List list, T target, [int reciprocal = 2]) { @@ -310,7 +356,6 @@ class QuestionImageView extends HookWidget with EventBusMixin(maxHeight); - useValueChanged(maxHeight, (oldValue, __) => theMaxHeight.value = maxHeight); + useValueChanged( + maxHeight, (oldValue, __) => theMaxHeight.value = maxHeight); var zoomKey = useState(GlobalKey()); - useValueChanged(zoomState.zoomFile.value?.templateId, (old, __) { + useValueChanged(zoomState.zoomFile.value?.templateId, + (old, __) { zoomKey.value = GlobalKey(); }); @@ -340,9 +387,13 @@ class QuestionImageView extends HookWidget with EventBusMixin( context: Get.context ?? context, builder: (context1) { - return AlertDialog(content: quickText("是否撤销全部批注痕迹?"), actions: [TextButton(child: quickText("取消"), onPressed: () => Navigator.pop(context1, false)), TextButton(child: quickText("确定", color: Theme.of(context1).primaryColor), onPressed: () => Navigator.pop(context1, true))]); + return AlertDialog( + content: quickText("是否撤销全部批注痕迹?"), + actions: [ + TextButton( + child: quickText("取消"), + onPressed: () => Navigator.pop(context1, false)), + TextButton( + child: quickText("确定", + color: Theme.of(context1).primaryColor), + onPressed: () => Navigator.pop(context1, true)) + ]); }, ); if (res == true) vnHandWritings.value = []; @@ -373,33 +434,43 @@ class QuestionImageView extends HookWidget with EventBusMixin( context: Get.context ?? context, builder: (context1) { - return AlertDialog(content: quickText("是否撤销上次批阅批注痕迹?"), actions: [ - TextButton(child: quickText("取消"), onPressed: () => Navigator.pop(context1, false)), - TextButton( - child: quickText("确定", color: Theme.of(context1).primaryColor), - onPressed: () => easyThrottle( - 'REVOKE_THE_LAST_ANNOTATION_AND_SUBMIT', - () { - Navigator.pop(context1, true); - sateData.data.value?.zgtAnnotate = null; - sateData.data.value?.showZgtAnnotate = null; - if (sateData.data.value != null) { - sateData.data.update((_) { - var theStudentQuestions = sateData.studentQuestions.value; - if (theStudentQuestions?.isNotEmpty ?? false) { - var noMarking = theStudentQuestions?.firstWhereOrNull((e) => e.studentScore == null); - if (noMarking != null) { - ToastUtils.showInfo("未提交!请为第${noMarking.questionNo}题打分,再手动提交"); - return; - } + return AlertDialog( + content: quickText("是否撤销上次批阅批注痕迹?"), + actions: [ + TextButton( + child: quickText("取消"), + onPressed: () => Navigator.pop(context1, false)), + TextButton( + child: quickText("确定", + color: Theme.of(context1).primaryColor), + onPressed: () => easyThrottle( + 'REVOKE_THE_LAST_ANNOTATION_AND_SUBMIT', + () { + Navigator.pop(context1, true); + sateData.data.value?.zgtAnnotate = null; + sateData.data.value?.showZgtAnnotate = null; + if (sateData.data.value != null) { + sateData.data.update((_) { + var theStudentQuestions = + sateData.studentQuestions.value; + if (theStudentQuestions?.isNotEmpty ?? + false) { + var noMarking = + theStudentQuestions?.firstWhereOrNull( + (e) => e.studentScore == null); + if (noMarking != null) { + ToastUtils.showInfo( + "未提交!请为第${noMarking.questionNo}题打分,再手动提交"); + return; + } + } + logic.submit(Get.context ?? context); + }); } - logic.submit(Get.context ?? context); - }); - } - }, - ), - ) - ]); + }, + ), + ) + ]); }, ); } @@ -414,23 +485,29 @@ class QuestionImageView extends HookWidget with EventBusMixin( context: context, builder: (context1) { - return AlertDialog(content: quickText("是否撤销上次批阅批注痕迹?"), actions: [ - TextButton(child: quickText("取消"), onPressed: () => Navigator.pop(context1, false)), - TextButton( - child: quickText("确定", color: Theme.of(context).primaryColor), - onPressed: () => easyThrottle( - 'REVOKE_THE_LAST_ANNOTATION_AND_SUBMIT', - () { - Navigator.pop(context1, true); - sateData.data.value?.zgtAnnotate = null; - sateData.data.value?.showZgtAnnotate = null; - if (sateData.data.value != null) { - sateData.data.update((_) => logic.submit(Get.context ?? context)); - } - }, - ), - ) - ]); + return AlertDialog( + content: quickText("是否撤销上次批阅批注痕迹?"), + actions: [ + TextButton( + child: quickText("取消"), + onPressed: () => Navigator.pop(context1, false)), + TextButton( + child: quickText("确定", + color: Theme.of(context).primaryColor), + onPressed: () => easyThrottle( + 'REVOKE_THE_LAST_ANNOTATION_AND_SUBMIT', + () { + Navigator.pop(context1, true); + sateData.data.value?.zgtAnnotate = null; + sateData.data.value?.showZgtAnnotate = null; + if (sateData.data.value != null) { + sateData.data.update( + (_) => logic.submit(Get.context ?? context)); + } + }, + ), + ) + ]); }, ); } @@ -462,6 +539,7 @@ class QuestionImageView extends HookWidget with EventBusMixin zoomFile.getZoomFileHeightOffsetEnd(zoomState.initScale.value ?? 1)) return; // 检查笔记是否超出图片范围 + if (dy < imageHeightOffsetStart || + dy > + zoomFile.getZoomFileHeightOffsetEnd( + zoomState.initScale.value ?? 1)) return; // 检查笔记是否超出图片范围 var theScale = zoomState.initScale.value ?? 1; // if (theScale != 1) { @@ -516,21 +598,40 @@ class QuestionImageView extends HookWidget with EventBusMixin 65 || (lastDrop.dy - localPosition.dy).abs() > 65)) { - /// 当前X点和上一个x点相差 大于10判定为多个手指 - return; + if (Platform.isAndroid) { + var lastDrop = getLastDrop( + vnHandWritings.value, vnHandWritings.value.length - 1); + if (lastDrop != null && + ((lastDrop.dx - localPosition.dx).abs() > 65 || + (lastDrop.dy - localPosition.dy).abs() > 65)) { + /// 当前X点和上一个x点相差 大于10判定为多个手指 + return; + } } // print("最终位置 : $localPosition"); - vnHandWritings.value = List.from(vnHandWritings.value)..add(localPosition); + vnHandWritings.value = List.from(vnHandWritings.value) + ..add(localPosition); sateData.handwritings = vnHandWritings.value; }, child: Obx(() { @@ -563,13 +664,15 @@ class QuestionImageView extends HookWidget with EventBusMixin Image(image: imageProvider, fit: BoxFit.fitWidth), + (_, imageProvider) => + Image(image: imageProvider, fit: BoxFit.fitWidth), ), RepaintBoundary( key: logic.pictureOverviewKey, child: CustomPaint( // isComplex: true, - size: Size(maxWidth, zoomState.zoomFile.value!.actualHeight!), + size: Size( + maxWidth, zoomState.zoomFile.value!.actualHeight!), foregroundPainter: DrawingPainter(ctrl: vnHandWritings), // child: $TheCachedNetworkImage( // imgWidth: maxWidth, @@ -577,7 +680,13 @@ class QuestionImageView extends HookWidget with EventBusMixin Image(image: imageProvider, fit: BoxFit.fitWidth), // ), - child: showZgtAnnotate != null ? $TheCachedNetworkImage(imgWidth: maxWidth, imageUrl: showZgtAnnotate, (_, imageProvider) => Image(image: imageProvider, fit: BoxFit.fitWidth)) : null, + child: showZgtAnnotate != null + ? $TheCachedNetworkImage( + imgWidth: maxWidth, + imageUrl: showZgtAnnotate, + (_, imageProvider) => Image( + image: imageProvider, fit: BoxFit.fitWidth)) + : null, ), ), ], @@ -606,7 +715,8 @@ class DrawingPainter extends CustomPainter { for (int i = 0; i < pointsLength; i++) { Offset? offsetData = points[i]; Offset? nextOffsetData = pointsLength - 1 == i ? null : points[i + 1]; - if (offsetData != null && nextOffsetData != null) canvas.drawLine(offsetData, nextOffsetData, paintBrush); + if (offsetData != null && nextOffsetData != null) + canvas.drawLine(offsetData, nextOffsetData, paintBrush); } }