初步完成当前任务,还剩下放大后批阅
This commit is contained in:
parent
eb65701324
commit
060ac01fde
|
|
@ -0,0 +1,6 @@
|
||||||
|
enum ReviewMarksBottomBtnsEnum {
|
||||||
|
DRAG, // 拖动
|
||||||
|
HANDWRITING, // 笔迹
|
||||||
|
RETURN_PREVIOUS_LEVEL, // 返回上一级
|
||||||
|
CLEAR_ALL // 清空全部
|
||||||
|
}
|
||||||
|
|
@ -15,8 +15,23 @@ class BottomAnnotationSwitchCleanall extends Object {
|
||||||
|
|
||||||
BottomAnnotationSwitchCleanall({this.cleanAll = false, this.previousStep = false, this.uploadImage = false});
|
BottomAnnotationSwitchCleanall({this.cleanAll = false, this.previousStep = false, this.uploadImage = false});
|
||||||
|
|
||||||
factory BottomAnnotationSwitchCleanall.fromJson(Map<String, dynamic> srcJson) =>
|
factory BottomAnnotationSwitchCleanall.fromJson(Map<String, dynamic> srcJson) => _$BottomAnnotationSwitchCleanallFromJson(srcJson);
|
||||||
_$BottomAnnotationSwitchCleanallFromJson(srcJson);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => _$BottomAnnotationSwitchCleanallToJson(this);
|
Map<String, dynamic> toJson() => _$BottomAnnotationSwitchCleanallToJson(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@JsonSerializable()
|
||||||
|
class BottomAnnotationSwitchCleanallOfMarking extends Object {
|
||||||
|
@JsonKey(name: 'cleanAll')
|
||||||
|
bool cleanAll;
|
||||||
|
|
||||||
|
@JsonKey(name: 'previousStep')
|
||||||
|
bool previousStep;
|
||||||
|
|
||||||
|
BottomAnnotationSwitchCleanallOfMarking({this.cleanAll = false, this.previousStep = false});
|
||||||
|
|
||||||
|
factory BottomAnnotationSwitchCleanallOfMarking.fromJson(Map<String, dynamic> srcJson) =>
|
||||||
|
_$BottomAnnotationSwitchCleanallOfMarkingFromJson(srcJson);
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$BottomAnnotationSwitchCleanallOfMarkingToJson(this);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:marking_app/common/mixin/common.dart';
|
import 'package:marking_app/common/mixin/common.dart';
|
||||||
import 'package:marking_app/common/model/common/base_structure_result.dart';
|
import 'package:marking_app/common/model/common/base_structure_result.dart';
|
||||||
import 'package:marking_app/common/model/common/upload_img_secret_key.dart';
|
import 'package:marking_app/common/model/common/upload_img_secret_key.dart';
|
||||||
|
import 'package:marking_app/common/model/enum/review_marks_bottom_btns_enum.dart';
|
||||||
import 'package:marking_app/common/model/event_bus/bottom_annotation_switch_cleanall.dart';
|
import 'package:marking_app/common/model/event_bus/bottom_annotation_switch_cleanall.dart';
|
||||||
import 'package:marking_app/common/model/job/test_questions_image_info.dart';
|
import 'package:marking_app/common/model/job/test_questions_image_info.dart';
|
||||||
import 'package:marking_app/common/model/job/upload_file_interface_config.dart';
|
import 'package:marking_app/common/model/job/upload_file_interface_config.dart';
|
||||||
|
|
@ -33,6 +34,7 @@ import 'package:marking_app/common/model/marking/switch_keyboard_to_reload_image
|
||||||
import 'package:marking_app/pages/common/event_bus_mixin.dart';
|
import 'package:marking_app/pages/common/event_bus_mixin.dart';
|
||||||
import 'package:marking_app/pages/homework_correction/hooks/use_cached_img_refresh.dart';
|
import 'package:marking_app/pages/homework_correction/hooks/use_cached_img_refresh.dart';
|
||||||
import 'package:marking_app/pages/marking/hooks/use_zoom_image_history.dart';
|
import 'package:marking_app/pages/marking/hooks/use_zoom_image_history.dart';
|
||||||
|
import 'package:marking_app/pages/marking/provider/do_paper_bottom_review_marks_provider.dart';
|
||||||
import 'package:marking_app/pages/marking/provider/zoom_height_provider.dart';
|
import 'package:marking_app/pages/marking/provider/zoom_height_provider.dart';
|
||||||
import 'package:marking_app/pages/marking/provider/zoom_history_provider.dart';
|
import 'package:marking_app/pages/marking/provider/zoom_history_provider.dart';
|
||||||
import 'package:marking_app/provider/annotation_graffiti_switch_provider.dart';
|
import 'package:marking_app/provider/annotation_graffiti_switch_provider.dart';
|
||||||
|
|
@ -313,11 +315,12 @@ class PictureOverviewState extends ConsumerState<PictureOverview> with CommonMix
|
||||||
_imageStream = imageWidget.image.resolve(ImageConfiguration())..addListener(_imageStreamListener!);
|
_imageStream = imageWidget.image.resolve(ImageConfiguration())..addListener(_imageStreamListener!);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var btnEnum = ref.watch(doPaperBottomReviewMarksProvider);
|
||||||
// return imageWidget;
|
// return imageWidget;
|
||||||
return Listener(
|
return Listener(
|
||||||
behavior: HitTestBehavior.opaque,
|
behavior: HitTestBehavior.opaque,
|
||||||
onPointerMove: (PointerMoveEvent details) {
|
onPointerMove: (PointerMoveEvent details) {
|
||||||
return;
|
if (btnEnum != ReviewMarksBottomBtnsEnum.HANDWRITING) return;
|
||||||
if (globalPosition != null) {
|
if (globalPosition != null) {
|
||||||
// 预防双指同时作用于屏幕
|
// 预防双指同时作用于屏幕
|
||||||
double dx = globalPosition!.dx;
|
double dx = globalPosition!.dx;
|
||||||
|
|
@ -328,10 +331,19 @@ class PictureOverviewState extends ConsumerState<PictureOverview> with CommonMix
|
||||||
if ((dxNew - dx).abs() > 22 || (dyNew - dy).abs() > 22) return;
|
if ((dxNew - dx).abs() > 22 || (dyNew - dy).abs() > 22) return;
|
||||||
}
|
}
|
||||||
globalPosition = details.localPosition;
|
globalPosition = details.localPosition;
|
||||||
|
Offset localPosition = globalPosition!;
|
||||||
|
|
||||||
|
if (imagInfoModel != null &&
|
||||||
|
(localPosition.dy < imagInfoModel!.imageHeightOffsetStart! || localPosition.dy > imagInfoModel!.imageHeightOffsetend!)) {
|
||||||
|
// 笔迹画出图片区域 直接断笔
|
||||||
|
var newVal = ref.read(drawMarkingProvider).data..add(GestureRecording(eraser: graffitiSwitch.openEraser));
|
||||||
|
var newVal1 = ref.read(drawMarkingProvider).offsets..add(null);
|
||||||
|
ref.read(drawMarkingProvider.notifier).setState(DrawMarkingVal(newVal, newVal1));
|
||||||
|
return;
|
||||||
|
}
|
||||||
// Offset localPosition = (context.findRenderObject() as RenderBox).globalToLocal(details.localPosition);
|
// Offset localPosition = (context.findRenderObject() as RenderBox).globalToLocal(details.localPosition);
|
||||||
// if (widget.graffitiSwitch.openBrush || widget.graffitiSwitch.openEraser) {
|
// if (widget.graffitiSwitch.openBrush || widget.graffitiSwitch.openEraser) {
|
||||||
|
|
||||||
Offset localPosition = globalPosition!;
|
|
||||||
// if (imagInfoModel?.scaleHeight != null) {
|
// if (imagInfoModel?.scaleHeight != null) {
|
||||||
// localPosition = Offset(localPosition.dx, localPosition.dy - imagInfoModel!.scaleHeight!);
|
// localPosition = Offset(localPosition.dx, localPosition.dy - imagInfoModel!.scaleHeight!);
|
||||||
// }
|
// }
|
||||||
|
|
@ -343,7 +355,7 @@ class PictureOverviewState extends ConsumerState<PictureOverview> with CommonMix
|
||||||
}
|
}
|
||||||
|
|
||||||
if (zoomOffset != null) {
|
if (zoomOffset != null) {
|
||||||
// localPosition = Offset(localPosition.dx - (zoomOffset?.dx ?? 0), localPosition.dy);
|
localPosition = Offset(details.position.dx, localPosition.dy);
|
||||||
}
|
}
|
||||||
|
|
||||||
print('移动位置 zoomOffset==>dx:${zoomOffset?.dx}');
|
print('移动位置 zoomOffset==>dx:${zoomOffset?.dx}');
|
||||||
|
|
@ -356,14 +368,15 @@ class PictureOverviewState extends ConsumerState<PictureOverview> with CommonMix
|
||||||
print('还原后的Y轴:${localPosition.dy * _scaleY}');
|
print('还原后的Y轴:${localPosition.dy * _scaleY}');
|
||||||
|
|
||||||
var newVal = ref.read(drawMarkingProvider).data..add(GestureRecording(eraser: graffitiSwitch.openEraser, data: localPosition));
|
var newVal = ref.read(drawMarkingProvider).data..add(GestureRecording(eraser: graffitiSwitch.openEraser, data: localPosition));
|
||||||
ref.read(drawMarkingProvider.notifier).setState(DrawMarkingVal(newVal));
|
var newVal1 = ref.read(drawMarkingProvider).offsets..add(localPosition);
|
||||||
|
ref.read(drawMarkingProvider.notifier).setState(DrawMarkingVal(newVal, newVal1));
|
||||||
},
|
},
|
||||||
onPointerDown: (PointerDownEvent event) {
|
onPointerDown: (PointerDownEvent event) {
|
||||||
print('手指按下....${event.pointer}');
|
print('手指按下....${event.pointer}');
|
||||||
},
|
},
|
||||||
onPointerUp: (PointerUpEvent details) {
|
onPointerUp: (PointerUpEvent details) {
|
||||||
print('离开.............');
|
print('离开.............');
|
||||||
return;
|
if (btnEnum != ReviewMarksBottomBtnsEnum.HANDWRITING) return;
|
||||||
globalPosition = null;
|
globalPosition = null;
|
||||||
// if (graffitiSwitch.openBrush || graffitiSwitch.openEraser) {
|
// if (graffitiSwitch.openBrush || graffitiSwitch.openEraser) {
|
||||||
// var newVal = ref.read(drawMarkingProvider).data..add(GestureRecording(eraser: graffitiSwitch.openEraser));
|
// var newVal = ref.read(drawMarkingProvider).data..add(GestureRecording(eraser: graffitiSwitch.openEraser));
|
||||||
|
|
@ -371,25 +384,29 @@ class PictureOverviewState extends ConsumerState<PictureOverview> with CommonMix
|
||||||
// }
|
// }
|
||||||
|
|
||||||
var newVal = ref.read(drawMarkingProvider).data..add(GestureRecording(eraser: graffitiSwitch.openEraser));
|
var newVal = ref.read(drawMarkingProvider).data..add(GestureRecording(eraser: graffitiSwitch.openEraser));
|
||||||
ref.read(drawMarkingProvider.notifier).setState(DrawMarkingVal(newVal));
|
var newVal1 = ref.read(drawMarkingProvider).offsets..add(null);
|
||||||
|
ref.read(drawMarkingProvider.notifier).setState(DrawMarkingVal(newVal, newVal1));
|
||||||
},
|
},
|
||||||
child: Zoom(
|
child: IgnorePointer(
|
||||||
// initTotalZoomOut: true,
|
ignoring: btnEnum != ReviewMarksBottomBtnsEnum.DRAG,
|
||||||
child: ExamPaperDrawing(
|
child: Zoom(
|
||||||
key: examPaperDrawingKey,
|
// initTotalZoomOut: true,
|
||||||
globalKey: theglobalKey,
|
child: ExamPaperDrawing(
|
||||||
child: imageWidget,
|
key: examPaperDrawingKey,
|
||||||
graffitiSwitch: graffitiSwitch,
|
globalKey: theglobalKey,
|
||||||
decoration: const BoxDecoration(color: const Color.fromRGBO(249, 250, 254, 1)),
|
child: imageWidget,
|
||||||
|
graffitiSwitch: graffitiSwitch,
|
||||||
|
decoration: const BoxDecoration(color: const Color.fromRGBO(249, 250, 254, 1)),
|
||||||
|
),
|
||||||
|
maxZoomWidth: containerWidth,
|
||||||
|
canvasColor: Colors.transparent,
|
||||||
|
backgroundColor: Colors.transparent,
|
||||||
|
maxZoomHeight: imagInfoModel?.scaleHeight,
|
||||||
|
initScale: initScale ?? 1,
|
||||||
|
initPosition: zoomOffset,
|
||||||
|
onScaleUpdate: onScaleUpdate,
|
||||||
|
onPositionUpdate: onPanUpPosition,
|
||||||
),
|
),
|
||||||
maxZoomWidth: containerWidth,
|
|
||||||
canvasColor: Colors.transparent,
|
|
||||||
backgroundColor: Colors.transparent,
|
|
||||||
maxZoomHeight: imagInfoModel?.scaleHeight,
|
|
||||||
initScale: initScale ?? 1,
|
|
||||||
initPosition: zoomOffset,
|
|
||||||
onScaleUpdate: onScaleUpdate,
|
|
||||||
onPositionUpdate: onPanUpPosition,
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
@ -420,21 +437,24 @@ class ExamPaperDrawing extends StatefulHookConsumerWidget {
|
||||||
_ExamPaperDrawingState createState() => _ExamPaperDrawingState();
|
_ExamPaperDrawingState createState() => _ExamPaperDrawingState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _ExamPaperDrawingState extends ConsumerState<ExamPaperDrawing> with EventBusMixin<BottomAnnotationSwitchCleanall> {
|
class _ExamPaperDrawingState extends ConsumerState<ExamPaperDrawing> with EventBusMixin<BottomAnnotationSwitchCleanallOfMarking> {
|
||||||
// 用于记录手指位置的变量
|
// 用于记录手指位置的变量
|
||||||
late RemoveListener removeListener;
|
late RemoveListener removeListener;
|
||||||
late ValueNotifier<List<GestureRecording>> _vnHandWritings;
|
late ValueNotifier<List<GestureRecording>> _vnHandWritings;
|
||||||
late List<dynamic> pointsPureData = [];
|
late List<Offset?> pointsPureData = [];
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
_vnHandWritings = ValueNotifier<List<GestureRecording>>([]);
|
_vnHandWritings = ValueNotifier<List<GestureRecording>>([]);
|
||||||
removeListener = ref.read(drawMarkingProvider.notifier).addListener((state) => _vnHandWritings.value = [...state.data], fireImmediately: false);
|
removeListener = ref.read(drawMarkingProvider.notifier).addListener((state) {
|
||||||
|
pointsPureData = state.offsets;
|
||||||
|
_vnHandWritings.value = [...state.data];
|
||||||
|
}, fireImmediately: false);
|
||||||
|
|
||||||
// 事件总线监听
|
// 事件总线监听
|
||||||
eventOn(callback: (BottomAnnotationSwitchCleanall item) {
|
eventOn(callback: (BottomAnnotationSwitchCleanallOfMarking item) {
|
||||||
if (item.previousStep) {
|
if (item.previousStep) {
|
||||||
if (_vnHandWritings.value.isEmpty) {
|
if (ref.read(drawMarkingProvider).data.isEmpty) {
|
||||||
ToastUtils.showInfo('批注已清空');
|
ToastUtils.showInfo('批注已清空');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -443,14 +463,13 @@ class _ExamPaperDrawingState extends ConsumerState<ExamPaperDrawing> with EventB
|
||||||
if (index + 1 == pointsPureData.length) {
|
if (index + 1 == pointsPureData.length) {
|
||||||
pointsPureData = pointsPureData.sublist(0, index);
|
pointsPureData = pointsPureData.sublist(0, index);
|
||||||
|
|
||||||
ref.read(drawMarkingProvider.notifier).setState(DrawMarkingVal(ref.read(drawMarkingProvider).data.sublist(0, index)));
|
ref.read(drawMarkingProvider.notifier).setState(DrawMarkingVal(ref.read(drawMarkingProvider).data.sublist(0, index), pointsPureData));
|
||||||
index = pointsPureData.toList().lastIndexOf(null);
|
index = pointsPureData.toList().lastIndexOf(null);
|
||||||
index == -1 ? -1 : index + 1;
|
index == -1 ? -1 : index + 1;
|
||||||
}
|
}
|
||||||
if (index != -1) {
|
if (index != -1) {
|
||||||
pointsPureData = pointsPureData.sublist(0, index);
|
pointsPureData = pointsPureData.sublist(0, index);
|
||||||
_vnHandWritings.value = _vnHandWritings.value.sublist(0, index);
|
ref.read(drawMarkingProvider.notifier).setState(DrawMarkingVal(ref.read(drawMarkingProvider).data.sublist(0, index), pointsPureData));
|
||||||
ref.read(drawMarkingProvider.notifier).setState(DrawMarkingVal(ref.read(drawMarkingProvider).data.sublist(0, index)));
|
|
||||||
} else {
|
} else {
|
||||||
item.cleanAll = true;
|
item.cleanAll = true;
|
||||||
}
|
}
|
||||||
|
|
@ -461,20 +480,7 @@ class _ExamPaperDrawingState extends ConsumerState<ExamPaperDrawing> with EventB
|
||||||
|
|
||||||
if (item.cleanAll) {
|
if (item.cleanAll) {
|
||||||
pointsPureData.clear();
|
pointsPureData.clear();
|
||||||
_vnHandWritings.value.clear();
|
ref.read(drawMarkingProvider.notifier).setState(DrawMarkingVal([], []));
|
||||||
}
|
|
||||||
|
|
||||||
if (item.uploadImage) {
|
|
||||||
// 图片确认按钮,生成
|
|
||||||
if (pointsPureData.isEmpty) {
|
|
||||||
ToastUtils.showInfo('请先批注再提交');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// _saveImage().then((FileResult? res) {
|
|
||||||
// if (res != null) {
|
|
||||||
// widget.imageCall(res.url!);
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
super.initState();
|
super.initState();
|
||||||
|
|
|
||||||
|
|
@ -1,298 +0,0 @@
|
||||||
import 'dart:io';
|
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
|
||||||
import 'package:marking_app/common/model/enum/KeyboardType.dart';
|
|
||||||
import 'package:marking_app/common/model/event_bus/bottom_annotation_switch_cleanall.dart';
|
|
||||||
import 'package:marking_app/common/model/marking/annotation_graffiti_switch.dart';
|
|
||||||
import 'package:marking_app/common/model/marking/do_marking_keyboard_model.dart';
|
|
||||||
import 'package:marking_app/pages/common/event_bus_mixin.dart';
|
|
||||||
import 'package:marking_app/provider/annotation_graffiti_switch_provider.dart';
|
|
||||||
import 'package:marking_app/provider/do_marking_provider.dart';
|
|
||||||
import 'package:marking_app/utils/index.dart';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 底部批注开关
|
|
||||||
*/
|
|
||||||
class BottomAnnotationSwitch extends StatefulHookConsumerWidget {
|
|
||||||
final double? maxWidth;
|
|
||||||
final bool homework;
|
|
||||||
const BottomAnnotationSwitch({this.maxWidth, this.homework = false, Key? key}) : super(key: key);
|
|
||||||
|
|
||||||
@override
|
|
||||||
_BottomAnnotationSwitchState createState() => _BottomAnnotationSwitchState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _BottomAnnotationSwitchState extends ConsumerState<BottomAnnotationSwitch>
|
|
||||||
with SingleTickerProviderStateMixin, EventBusMixin<BottomAnnotationSwitchCleanall> {
|
|
||||||
late RemoveListener _annotationsListener; // 批注关闭监听
|
|
||||||
late AnimationController _animationController; // 动画
|
|
||||||
late AnnotationGraffitiSwitch graffitiSwitch;
|
|
||||||
late DoMarkingKeyboardModel _preferenceModel;
|
|
||||||
late double upperBound;
|
|
||||||
late double lowerBound;
|
|
||||||
Color? bgc;
|
|
||||||
bool isIos = false;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void initState() {
|
|
||||||
if (Platform.isIOS) {
|
|
||||||
toPrint(val: 'IOS');
|
|
||||||
isIos = true;
|
|
||||||
} else if (Platform.isAndroid) {
|
|
||||||
toPrint(val: '安卓');
|
|
||||||
}
|
|
||||||
var graffitiHander = ref.read(annotationGraffitiSwitchProvider.notifier);
|
|
||||||
if (widget.homework) {
|
|
||||||
setTimeOut(500, () {
|
|
||||||
graffitiHander.setSwitch(true);
|
|
||||||
if (!graffitiHander.state.openBrush) graffitiHander.setSwitchBrush();
|
|
||||||
}); // 默认打开可以书写
|
|
||||||
}
|
|
||||||
|
|
||||||
_preferenceModel = ref.read(markingKeyboardProvider.notifier).state; // 偏好设置
|
|
||||||
bool isVertical = _preferenceModel.screenDirection == ScreenDirection.VERTICAL_SCREEN; // 是否是垂直方向
|
|
||||||
|
|
||||||
switch (_preferenceModel.keyboard) {
|
|
||||||
case KeyboardType.RIGHT_SELECTION:
|
|
||||||
double isVerticalNumber = 58.w;
|
|
||||||
double noVerticalNumber = 28.w;
|
|
||||||
if (isIos) {
|
|
||||||
noVerticalNumber = 50.w;
|
|
||||||
}
|
|
||||||
upperBound = ScreenUtil().screenWidth - (isVertical ? isVerticalNumber : noVerticalNumber);
|
|
||||||
lowerBound = isVertical ? 34.w : 18.w;
|
|
||||||
break;
|
|
||||||
case KeyboardType.INPUT_TYPE:
|
|
||||||
// 输入型键盘不存在竖屏
|
|
||||||
upperBound = ScreenUtil().screenWidth - (isIos ? 115.w : 95.w);
|
|
||||||
lowerBound = 18.w;
|
|
||||||
|
|
||||||
break;
|
|
||||||
case KeyboardType.BOTTOM_SELECTION:
|
|
||||||
upperBound = ScreenUtil().screenWidth;
|
|
||||||
lowerBound = isVertical ? 34.w : 18.w;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
upperBound = widget.maxWidth ?? upperBound;
|
|
||||||
_animationController = AnimationController(
|
|
||||||
value: graffitiHander.state.annotationSwitch ? upperBound : lowerBound, // 设置默认值
|
|
||||||
duration: const Duration(milliseconds: 300),
|
|
||||||
lowerBound: lowerBound,
|
|
||||||
upperBound: upperBound,
|
|
||||||
vsync: this,
|
|
||||||
)..addListener(toUp);
|
|
||||||
|
|
||||||
_annotationsListener = graffitiHander.addListener((state) {
|
|
||||||
graffitiSwitch = state;
|
|
||||||
if (state.annotationSwitch) {
|
|
||||||
bgc = const Color.fromRGBO(51, 57, 62, 1);
|
|
||||||
// toUp();
|
|
||||||
_animationController.forward();
|
|
||||||
} else {
|
|
||||||
_animationController.reverse();
|
|
||||||
setTimeOut(300, () => bgc = null);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
super.initState();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
_annotationsListener();
|
|
||||||
_animationController
|
|
||||||
..removeListener(toUp)
|
|
||||||
..dispose();
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
ScreenDirection _screenDirection = _preferenceModel.screenDirection;
|
|
||||||
bool isVertical = _screenDirection == ScreenDirection.VERTICAL_SCREEN; // 是否是垂直
|
|
||||||
|
|
||||||
// print('当前屏幕情况:${graffitiSwitch.openBrush}');
|
|
||||||
// print(isVertical);
|
|
||||||
|
|
||||||
AnnotationGraffitiSwitch _graffitiSwitch = ref.watch(annotationGraffitiSwitchProvider);
|
|
||||||
|
|
||||||
double barrierSize = ScreenUtil().screenWidth / (isVertical ? 20 : 6);
|
|
||||||
Color actionColor = Colors.white;
|
|
||||||
Color defaultColor = Color.fromRGBO(132, 146, 163, 1);
|
|
||||||
return OrientationBuilder(
|
|
||||||
builder: (BuildContext context, Orientation orientation) {
|
|
||||||
bool isVertical = orientation == Orientation.portrait;
|
|
||||||
|
|
||||||
double iconSize = (isVertical ? 32 : 28).sp;
|
|
||||||
return Container(
|
|
||||||
height: 52.h,
|
|
||||||
// width: widget.homework ? double.infinity : _animationController.value,
|
|
||||||
width: _animationController.value,
|
|
||||||
color: widget.homework ? Color.fromRGBO(51, 57, 62, 0.2) : bgc,
|
|
||||||
padding: EdgeInsets.symmetric(vertical: 1.h),
|
|
||||||
child: widget.homework
|
|
||||||
? Row(
|
|
||||||
children: [
|
|
||||||
SizedBox(width: barrierSize + 20.w),
|
|
||||||
InkWell(
|
|
||||||
onTap: () {
|
|
||||||
easyThrottle('setSwitchBrush',
|
|
||||||
() => ref.read(annotationGraffitiSwitchProvider.notifier).setSwitchBrush());
|
|
||||||
},
|
|
||||||
child: Icon(const IconData(0xe623, fontFamily: "AlibabaIcon"),
|
|
||||||
size: iconSize, color: _graffitiSwitch.openBrush ? actionColor : defaultColor),
|
|
||||||
),
|
|
||||||
SizedBox(width: 24.w),
|
|
||||||
InkWell(
|
|
||||||
onTap: () {
|
|
||||||
eventFire(model: BottomAnnotationSwitchCleanall(previousStep: true));
|
|
||||||
},
|
|
||||||
child: Icon(IconData(0xe61d, fontFamily: "AlibabaIcon"), size: iconSize, color: defaultColor),
|
|
||||||
),
|
|
||||||
const Expanded(child: SizedBox()),
|
|
||||||
InkWell(
|
|
||||||
onTap: () {
|
|
||||||
easyThrottle('setSwitchMagnifier',
|
|
||||||
() => ref.read(annotationGraffitiSwitchProvider.notifier).setMagnifier());
|
|
||||||
},
|
|
||||||
// IconData(0xe62f, fontFamily: "AlibabaIcon")
|
|
||||||
child: Icon(IconData(0xe634, fontFamily: "AlibabaIcon"),
|
|
||||||
size: iconSize, color: _graffitiSwitch.magnifier ? actionColor : defaultColor),
|
|
||||||
),
|
|
||||||
SizedBox(width: 24.w),
|
|
||||||
InkWell(
|
|
||||||
onTap: () {
|
|
||||||
eventFire(model: BottomAnnotationSwitchCleanall(cleanAll: true));
|
|
||||||
},
|
|
||||||
child: Icon(IconData(0xe61f, fontFamily: "AlibabaIcon"), size: iconSize, color: defaultColor),
|
|
||||||
),
|
|
||||||
SizedBox(width: 24.w),
|
|
||||||
InkWell(
|
|
||||||
onTap: () {
|
|
||||||
easyThrottle(
|
|
||||||
'setSwitchMagnifier',
|
|
||||||
() => ref.read(annotationGraffitiSwitchProvider.notifier).setTrajectory(),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
child: Icon(
|
|
||||||
IconData(0xe629, fontFamily: "AlibabaIcon"),
|
|
||||||
size: iconSize,
|
|
||||||
color: _graffitiSwitch.trajectoryDisplay ? actionColor : defaultColor,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SizedBox(width: isIos ? 40.w : 50.w),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
: Stack(
|
|
||||||
alignment: const FractionalOffset(0, 0.5),
|
|
||||||
children: [
|
|
||||||
if (bgc != null)
|
|
||||||
Row(
|
|
||||||
children: [
|
|
||||||
SizedBox(width: barrierSize + 20.w),
|
|
||||||
InkWell(
|
|
||||||
onTap: () {
|
|
||||||
easyThrottle('setSwitchBrush',
|
|
||||||
() => ref.read(annotationGraffitiSwitchProvider.notifier).setSwitchBrush());
|
|
||||||
},
|
|
||||||
child: Icon(const IconData(0xe623, fontFamily: "AlibabaIcon"),
|
|
||||||
size: iconSize, color: _graffitiSwitch.openBrush ? actionColor : defaultColor),
|
|
||||||
),
|
|
||||||
SizedBox(width: 24.w),
|
|
||||||
InkWell(
|
|
||||||
onTap: () {
|
|
||||||
eventFire(model: BottomAnnotationSwitchCleanall(previousStep: true));
|
|
||||||
},
|
|
||||||
child:
|
|
||||||
Icon(IconData(0xe61d, fontFamily: "AlibabaIcon"), size: iconSize, color: defaultColor),
|
|
||||||
),
|
|
||||||
|
|
||||||
// 不需要橡皮擦
|
|
||||||
// InkWell(
|
|
||||||
// onTap: () {
|
|
||||||
// easyThrottle(
|
|
||||||
// 'setSwitchEraser', () => ref.read(annotationGraffitiSwitchProvider.notifier).setSwitchEraser());
|
|
||||||
// },
|
|
||||||
// child: Icon(const IconData(0xe61c, fontFamily: "AlibabaIcon"),
|
|
||||||
// color: _graffitiSwitch.openEraser ? Theme.of(context).primaryColor : Colors.white),
|
|
||||||
// ),
|
|
||||||
const Expanded(child: SizedBox()),
|
|
||||||
InkWell(
|
|
||||||
onTap: () {
|
|
||||||
easyThrottle('setSwitchMagnifier',
|
|
||||||
() => ref.read(annotationGraffitiSwitchProvider.notifier).setMagnifier());
|
|
||||||
},
|
|
||||||
child: Icon(IconData(0xe62f, fontFamily: "AlibabaIcon"),
|
|
||||||
size: iconSize, color: _graffitiSwitch.magnifier ? actionColor : defaultColor),
|
|
||||||
),
|
|
||||||
SizedBox(width: 24.w),
|
|
||||||
InkWell(
|
|
||||||
onTap: () {
|
|
||||||
eventFire(model: BottomAnnotationSwitchCleanall(cleanAll: true));
|
|
||||||
},
|
|
||||||
child:
|
|
||||||
Icon(IconData(0xe61f, fontFamily: "AlibabaIcon"), size: iconSize, color: defaultColor),
|
|
||||||
),
|
|
||||||
// SizedBox(width: 24.w),
|
|
||||||
// InkWell(
|
|
||||||
// onTap: (){
|
|
||||||
// eventFire(model:BottomAnnotationSwitchCleanall(uploadImage: true));
|
|
||||||
// },
|
|
||||||
// child: Column(
|
|
||||||
// mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
// children: [
|
|
||||||
// Icon(const IconData(0xe614, fontFamily: "AlibabaIcon"), color: Colors.white,size: 22.sp,),
|
|
||||||
// quickText('提交批注',color: Colors.white,size: 9.sp),
|
|
||||||
// ],
|
|
||||||
// )
|
|
||||||
// ),
|
|
||||||
|
|
||||||
SizedBox(width: isIos ? 40.w : 26.w),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
InkWell(
|
|
||||||
onTap: () {
|
|
||||||
easyThrottle('setSwitchMarkingGraffiti', () {
|
|
||||||
if ([upperBound, lowerBound].contains(_animationController.value)) {
|
|
||||||
ref
|
|
||||||
.read(annotationGraffitiSwitchProvider.notifier)
|
|
||||||
.setSwitch(!graffitiSwitch.annotationSwitch);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
child: Container(
|
|
||||||
// width: isVertical ? 34.w : 16.w,
|
|
||||||
width: barrierSize,
|
|
||||||
padding: EdgeInsets.only(top: 4.h, bottom: 4.h, right: 3.w),
|
|
||||||
alignment: Alignment.centerRight,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: const Color.fromRGBO(253, 147, 21, 1),
|
|
||||||
borderRadius: BorderRadius.only(
|
|
||||||
topRight: Radius.circular(30.sp),
|
|
||||||
bottomRight: Radius.circular(30.sp),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
child: Icon(
|
|
||||||
!graffitiSwitch.annotationSwitch
|
|
||||||
? const IconData(0xe622, fontFamily: "AlibabaIcon")
|
|
||||||
: const IconData(0xe621, fontFamily: "AlibabaIcon"),
|
|
||||||
color: Colors.white,
|
|
||||||
size: isVertical ? 20.sp : 26.sp,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void toUp() {
|
|
||||||
toUpState(setState, () {}, mounted);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -104,6 +104,7 @@ class TheMainPageState extends ConsumerState<TheMainPage> with CommonMixin {
|
||||||
}
|
}
|
||||||
|
|
||||||
void getAppUpgrade(UserInfo user) async {
|
void getAppUpgrade(UserInfo user) async {
|
||||||
|
if (!bool.fromEnvironment('dart.vm.product')) return;
|
||||||
try {
|
try {
|
||||||
showUpgrade = true;
|
showUpgrade = true;
|
||||||
if (['18888888888'].contains(user.loginName)) return;
|
if (['18888888888'].contains(user.loginName)) return;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,98 @@
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
|
import 'package:marking_app/common/model/enum/review_marks_bottom_btns_enum.dart';
|
||||||
|
import 'package:marking_app/common/model/event_bus/bottom_annotation_switch_cleanall.dart';
|
||||||
|
import 'package:marking_app/pages/common/event_bus_mixin.dart';
|
||||||
|
import 'package:marking_app/utils/anti_shake_throttling.dart';
|
||||||
|
|
||||||
|
import '../provider/do_paper_bottom_review_marks_provider.dart';
|
||||||
|
|
||||||
|
// 底部批阅动作切换区域
|
||||||
|
class DoPaperBottomReviewMarks extends StatefulHookConsumerWidget {
|
||||||
|
const DoPaperBottomReviewMarks({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
ConsumerState<DoPaperBottomReviewMarks> createState() => _DoPaperBottomReviewMarksState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _DoPaperBottomReviewMarksState extends ConsumerState<DoPaperBottomReviewMarks> with EventBusMixin<BottomAnnotationSwitchCleanallOfMarking> {
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
// TODO: implement dispose
|
||||||
|
eventCancel();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
var btnEnum = ref.watch(doPaperBottomReviewMarksProvider);
|
||||||
|
Color actionColor = Theme.of(context).primaryColor.withOpacity(0.9);
|
||||||
|
return Positioned(
|
||||||
|
left: 3.w,
|
||||||
|
bottom: 6.h,
|
||||||
|
child: AbsorbPointer(
|
||||||
|
absorbing: false,
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: BorderRadius.circular(50.r),
|
||||||
|
color: const Color.fromRGBO(24, 32, 32, 0.1),
|
||||||
|
),
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 10.w),
|
||||||
|
child: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
// 拖动
|
||||||
|
IconButton(
|
||||||
|
onPressed: () => easyThrottle(
|
||||||
|
'REVIEW_MARKS_BOTTOM_BTNS',
|
||||||
|
() => ref.read(doPaperBottomReviewMarksProvider.notifier).setState(ReviewMarksBottomBtnsEnum.DRAG),
|
||||||
|
),
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
icon: Icon(Icons.back_hand_outlined, color: btnEnum == ReviewMarksBottomBtnsEnum.DRAG ? actionColor : Colors.white, size: 34.r),
|
||||||
|
),
|
||||||
|
SizedBox(width: 4.w),
|
||||||
|
// 批阅笔迹
|
||||||
|
IconButton(
|
||||||
|
onPressed: () => easyThrottle(
|
||||||
|
'REVIEW_MARKS_BOTTOM_BTNS',
|
||||||
|
() => ref.read(doPaperBottomReviewMarksProvider.notifier).setState(ReviewMarksBottomBtnsEnum.HANDWRITING),
|
||||||
|
),
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
icon: Icon(Icons.create_outlined, color: btnEnum == ReviewMarksBottomBtnsEnum.HANDWRITING ? actionColor : Colors.white, size: 34.r),
|
||||||
|
),
|
||||||
|
SizedBox(width: 4.w),
|
||||||
|
// 批阅痕迹 ==> 返回上一级
|
||||||
|
IconButton(
|
||||||
|
onPressed: () => easyThrottle(
|
||||||
|
'REVIEW_MARKS_BOTTOM_BTNS',
|
||||||
|
duration: const Duration(milliseconds: 100),
|
||||||
|
() => eventFire(model: BottomAnnotationSwitchCleanallOfMarking(previousStep: true)),
|
||||||
|
),
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
icon: Icon(Icons.reply_outlined,
|
||||||
|
color: btnEnum == ReviewMarksBottomBtnsEnum.RETURN_PREVIOUS_LEVEL ? actionColor : Colors.white, size: 34.r),
|
||||||
|
),
|
||||||
|
SizedBox(width: 4.w),
|
||||||
|
// 批阅痕迹 ==> 清空
|
||||||
|
IconButton(
|
||||||
|
onPressed: () => easyThrottle(
|
||||||
|
'REVIEW_MARKS_BOTTOM_BTNS',
|
||||||
|
duration: const Duration(milliseconds: 100),
|
||||||
|
() => eventFire(model: BottomAnnotationSwitchCleanallOfMarking(cleanAll: true)),
|
||||||
|
),
|
||||||
|
padding: EdgeInsets.zero,
|
||||||
|
icon: Icon(Icons.reply_all_outlined, color: btnEnum == ReviewMarksBottomBtnsEnum.CLEAR_ALL ? actionColor : Colors.white, size: 34.r),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -44,7 +44,6 @@ import 'package:marking_app/common/model/marking/submit_exam_small_params.dart';
|
||||||
import 'package:marking_app/common/model/marking/switch_keyboard_to_reload_images.dart';
|
import 'package:marking_app/common/model/marking/switch_keyboard_to_reload_images.dart';
|
||||||
|
|
||||||
import 'package:marking_app/components/PictureOverview.dart';
|
import 'package:marking_app/components/PictureOverview.dart';
|
||||||
import 'package:marking_app/components/marking/bottom_annotation_switch.dart';
|
|
||||||
import 'package:marking_app/components/marking/marking_keyboard_switch.dart';
|
import 'package:marking_app/components/marking/marking_keyboard_switch.dart';
|
||||||
import 'package:marking_app/components/marking/marking_question_type_drawer.dart';
|
import 'package:marking_app/components/marking/marking_question_type_drawer.dart';
|
||||||
import 'package:marking_app/components/marking/marking_seting.dart';
|
import 'package:marking_app/components/marking/marking_seting.dart';
|
||||||
|
|
@ -67,6 +66,7 @@ import 'package:marking_app/utils/request/rest_client.dart';
|
||||||
import 'package:percent_indicator/percent_indicator.dart';
|
import 'package:percent_indicator/percent_indicator.dart';
|
||||||
import 'package:wakelock/wakelock.dart';
|
import 'package:wakelock/wakelock.dart';
|
||||||
|
|
||||||
|
import 'components/do_paper_bottom_review_marks.dart';
|
||||||
import 'hooks/use_abnormal.dart';
|
import 'hooks/use_abnormal.dart';
|
||||||
|
|
||||||
part 'do_papers.g.dart';
|
part 'do_papers.g.dart';
|
||||||
|
|
@ -1930,18 +1930,7 @@ class _MarkingPapersState extends ConsumerState<DoPapers>
|
||||||
imageItems: data.getImageData(),
|
imageItems: data.getImageData(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
// 批注开关 暂时注释 TODO
|
|
||||||
// if (!showSetingFlag &&
|
|
||||||
// !widget.exceptional &&
|
|
||||||
// currentQuestion != null &&
|
|
||||||
// annotationsFlag &&
|
|
||||||
// !showAbnormal &&
|
|
||||||
// !showStandardAnswer)
|
|
||||||
// Positioned(
|
|
||||||
// left: 0,
|
|
||||||
// bottom: 0,
|
|
||||||
// child: BottomAnnotationSwitch(maxWidth: ScreenUtil().screenWidth - 1.5.w),
|
|
||||||
// ),
|
|
||||||
// 大题评分展示框
|
// 大题评分展示框
|
||||||
if (!hasSubtopic)
|
if (!hasSubtopic)
|
||||||
Positioned(
|
Positioned(
|
||||||
|
|
@ -2009,6 +1998,8 @@ class _MarkingPapersState extends ConsumerState<DoPapers>
|
||||||
heroTag: 'other',
|
heroTag: 'other',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
// 底部批阅痕迹按钮
|
||||||
|
DoPaperBottomReviewMarks(),
|
||||||
// 下一题 按钮
|
// 下一题 按钮
|
||||||
if (!_theOldAnnotationGraffiti && pressedNextTest != null && isNormal)
|
if (!_theOldAnnotationGraffiti && pressedNextTest != null && isNormal)
|
||||||
Positioned(
|
Positioned(
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
import 'package:marking_app/common/model/enum/review_marks_bottom_btns_enum.dart';
|
||||||
|
|
||||||
|
// 底部按钮同步数据
|
||||||
|
final doPaperBottomReviewMarksProvider = StateNotifierProvider<DoPaperBottomReviewMarksHandle, ReviewMarksBottomBtnsEnum>(
|
||||||
|
(ref) => DoPaperBottomReviewMarksHandle(ReviewMarksBottomBtnsEnum.DRAG),
|
||||||
|
);
|
||||||
|
|
||||||
|
class DoPaperBottomReviewMarksHandle extends StateNotifier<ReviewMarksBottomBtnsEnum> {
|
||||||
|
DoPaperBottomReviewMarksHandle(ReviewMarksBottomBtnsEnum val) : super(val);
|
||||||
|
|
||||||
|
void setState(ReviewMarksBottomBtnsEnum val) => state = val;
|
||||||
|
}
|
||||||
|
|
@ -7,12 +7,15 @@
|
||||||
* @Description: APP上传文件状态
|
* @Description: APP上传文件状态
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import 'dart:ui';
|
||||||
|
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
|
||||||
import '../../../components/PictureOverview.dart';
|
import '../../../components/PictureOverview.dart';
|
||||||
|
|
||||||
// 评分进度还是批阅进度
|
// 批阅痕迹同步
|
||||||
final drawMarkingProvider = StateNotifierProvider<DrawMarkingProviderHandle, DrawMarkingVal>((ref) => DrawMarkingProviderHandle(DrawMarkingVal([])));
|
final drawMarkingProvider =
|
||||||
|
StateNotifierProvider<DrawMarkingProviderHandle, DrawMarkingVal>((ref) => DrawMarkingProviderHandle(DrawMarkingVal([], [])));
|
||||||
|
|
||||||
class DrawMarkingProviderHandle extends StateNotifier<DrawMarkingVal> {
|
class DrawMarkingProviderHandle extends StateNotifier<DrawMarkingVal> {
|
||||||
DrawMarkingProviderHandle(DrawMarkingVal val) : super(val);
|
DrawMarkingProviderHandle(DrawMarkingVal val) : super(val);
|
||||||
|
|
@ -24,6 +27,7 @@ class DrawMarkingProviderHandle extends StateNotifier<DrawMarkingVal> {
|
||||||
|
|
||||||
class DrawMarkingVal {
|
class DrawMarkingVal {
|
||||||
List<GestureRecording> data;
|
List<GestureRecording> data;
|
||||||
|
List<Offset?> offsets;
|
||||||
|
|
||||||
DrawMarkingVal(this.data);
|
DrawMarkingVal(this.data, this.offsets);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue