pile_nav_new/lib/pages/task/pile/pileNav/view.dart
2024-11-15 17:42:52 +08:00

635 lines
22 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'dart:developer' as dev;
import 'dart:math';
import 'package:flutter/material.dart';
import 'package:scence_map/controllers/controller.dart';
import 'package:scence_map/controllers/plum_controller.dart';
import 'package:scence_map/record_entity.dart';
import 'package:get/get.dart';
import '../../../../main.dart';
import '../../../../service/pile/device_type.dart';
import '../../../../service/pile/input.dart';
import '../../../../service/pile/public_widget.dart';
import '../../model.dart';
import '../../task_page.dart';
import '../../taskcontroller.dart';
import '../pileGenerateCard/pile_point_table.dart';
import 'draw_pile.dart';
final TaskController taskcontroller = Get.find<TaskController>();
final ScenceMapController mapController = Get.find<ScenceMapController>();
class TaskView extends StatefulWidget {
const TaskView({super.key});
@override
State<TaskView> createState() => _TaskViewState();
}
class _TaskViewState extends State<TaskView> {
final controller = Get.find<PlumDataController>();
@override
void dispose() {
super.dispose();
}
bool isInit = false;
@override
void initState() {
super.initState();
mapController.update();
isInit = true;
}
@override
Widget build(BuildContext context) {
ever(controller.showList, (bool val) {
if (val) {
taskcontroller.currentask.update((task) {
double centerPointX = controller.centerXY.value.dx;
double centerPointY = controller.centerXY.value.dy;
task?.list.length = 0;
var dx = (controller.canvasSize.width) / 2;
var dy = (controller.canvasSize.height) / 2;
var rotation = mapController.rotation.value;
List<PilePoint> currentPoints = [];
for (int i = 0; i < controller.plumList.length; i++) {
Offset item = controller.plumList[i];
var dx1 = ((item.dx - dx) * cos(rotation) +
(item.dy - dy) * sin(rotation));
var dy1 = -(item.dx - dx) * sin(rotation) +
(item.dy - dy) * cos(rotation);
// Offset xy = mapController.screenCenter2xy(dx1, dy1);
Offset xy = Offset(dx1, dy1);
PilePoint pilePoint = PilePoint(
x: (xy.dx * 1000).roundToDouble() / 1000,
y: (xy.dy * 1000).roundToDouble() / 1000,
times: 0,
id: i + 1,
radius: 0.3);
currentPoints.add(pilePoint);
}
task?.list = currentPoints;
task?.centerPileInfo = CenterPileInfo(
x: (centerPointX * 1000).round() / 1000,
y: (centerPointY * 1000).round() / 1000,
// direction: controller.direction.value,
space: controller.space.value,
pileWidth: controller.pileWidth.value,
);
});
}
});
final size = MediaQuery.of(context).size;
final isDarkMode = Theme.of(context).brightness == Brightness.dark;
double diagonal = mapController.diagonal;
double mapWidth = mapController.width;
double mapHeight = mapController.height;
Offset scOffset =
Offset(mapWidth / 2 - diagonal / 2, mapHeight / 2 - diagonal / 2);
onTapDown(TapDownDetails details) {
isInit = false;
if (controller.checkValue.value == "checkPile") {
Offset sc2xy = mapController.screen2xy0(details.localPosition);
controller.centerXY.value = sc2xy;
RecordEntity? checkPoint =
mapController.pointInfo(controller.centerXY.value);
if (checkPoint != null) {
controller.isPileId.value = true;
// controller.checkName.value = checkPoint.tpId.toString();
} else {
controller.isPileId.value = false;
controller.checkName.value = "未找到";
}
controller.linePointOffset.value = Offset.zero;
} else {}
}
onScaleStart(ScaleStartDetails details) {
if (controller.checkValue.value != "checkPile") {
controller.linePointOffset.value = details.localFocalPoint;
controller.updateDistances(0.0);
}
// controller.shouldPaint.value = true;
}
onScaleUpdate(ScaleUpdateDetails details) {
controller.isUp.value = false;
// controller.shouldPaint.value = true;
if (controller.checkValue.value != "checkPile") {
Offset offset = details.localFocalPoint;
controller.linePointOffset.value = offset;
controller.linePointXY.value = mapController.screen2xy0(offset);
double distance =
(controller.centerOffset.value - controller.linePointOffset.value)
.distance;
controller.distanceOfCenter[controller.currentDir.value.index] =
(distance * 100).round() / 100;
controller.updateDistances(controller.direction.value);
controller.updateCount++;
}
controller.isUp.value = true;
double deg = (atan2(
controller.linePointOffset.value.dy -
controller.centerOffset.value.dy,
controller.linePointOffset.value.dx -
controller.centerOffset.value.dx) *
180 /
pi)
.roundToDouble();
controller.direction.value = deg + 90;
controller.angle.value =
((controller.direction.value * pi / 180) * 100).round() / 100;
}
onScaleEnd(ScaleEndDetails details) {
controller.isUp.value = true;
controller.updateCount++;
}
// 中间
var center = Obx(() {
controller.updateCount;
// 桩点生成
if (!controller.isGenerate.value) {
return const Text("");
}
return Positioned(
width: mapController.diagonal,
height: mapController.diagonal,
top: scOffset.dy,
left: scOffset.dx,
child: GestureDetector(
onTapDown: (TapDownDetails details) => onTapDown(details),
onScaleStart: (ScaleStartDetails details) => onScaleStart(details),
onScaleUpdate: (ScaleUpdateDetails details) =>
onScaleUpdate(details),
onScaleEnd: (ScaleEndDetails details) => onScaleEnd(details),
child: Container(
clipBehavior: Clip.hardEdge,
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.2),
blurRadius: 8,
offset: const Offset(0, 4),
),
],
),
child: Obx(() {
controller.updateCount;
List<Offset> buttons = controller.distancesOffset;
buttons[controller.currentDir.value.index] =
controller.linePointOffset.value - controller.transOff;
if (controller.checkValue.value == "checkPile") {
buttons = [
Offset.zero,
Offset.zero,
Offset.zero,
Offset.zero
];
}
List<Widget> buttonsList = [];
for (int b = 0; b < buttons.length; b++) {
buttonsList
.add(buildPositionedButton(buttons[b], -3.14 / 2, () {
controller.currentDir.value = dirList[b];
// controller.direction.value += dirList[b].angle + 3.14 / 2;
}));
}
return Stack(
children: [
CustomPaint(
// size: Size(scenceMapController.diagonal,
// scenceMapController.diagonal),
foregroundPainter: DrawDirection(
controller, scOffset, isDarkMode, isInit),
// child:
),
...buttonsList
],
);
}),
),
));
});
// 桩点生成时返回按钮
var back = Obx(() {
// bug :有时候点击的位置不准确 8寸屏的是正常的
controller.centerOffset.value = mapController.xy2Screen(
controller.centerXY.value.dx, controller.centerXY.value.dy);
if (isInit) {
controller.centerOffset.value = mapController.xy2Screen(
controller.centerXY.value.dx, controller.centerXY.value.dy) -
scOffset;
}
// controller.linePointOffset.value = controller.centerOffset.value;
dev.log(
"中心${controller.centerOffset.value},${controller.centerXY.value},${mapController.centerXY},$scOffset,$isInit");
// dev.log(scenceMapController.xy2Screen(
// controller.centerXY.value.dx, controller.centerXY.value.dy));
return Positioned(
left: controller.isGenerate.value
? controller.centerOffset.value.dx -
25 +
(mapWidth / 2 - diagonal / 2)
: -50,
top: controller.isGenerate.value
? controller.centerOffset.value.dy -
20 +
(mapHeight / 2 - diagonal / 2)
// 20 为高一半
: -50,
width: 50,
height: 40,
child: ClipOval(
child: ElevatedButton(
style: ElevatedButton.styleFrom(
padding: EdgeInsets.zero,
shape: const CircleBorder(),
),
child: const Icon(Icons.keyboard_return),
onPressed: () {
controller.isGenerate.value = false;
controller.updateDistances(controller.angle.value);
if (controller.checkValue.value == "checkPile") {
centerPointDialog(context, controller);
} else {
controller.showList.value = true;
}
controller.checkValue.value = "";
},
),
));
});
return Scaffold(
appBar: AppBar(
title: const Text('任务页面'),
actions: [
ElevatedButton(
child: const Text("桩点坐标"),
onPressed: () => {
controller.checkValue.value = "checkPile",
}),
const SizedBox(
width: 10,
),
ElevatedButton(
child: const Text("生成"),
onPressed: () => {
controller.checkValue.value = "checkDirection",
}),
UnconstrainedBox(
child: IconButton(
onPressed: () {
int index = controller.currentDir.value.index;
// controller.distancesOffset[index] =
// controller.linePointOffset.value - controller.transOff;
if (index + 1 == dirList.length) {
index = -1;
}
controller.currentDir.value = dirList[index + 1];
// controller.direction.value +=
// controller.currentDir.value.angle + 3.14 / 2;
controller.updateDistances(controller.direction.value);
controller.linePointOffset.value =
controller.distancesOffset[index + 1];
controller.updateCount++;
},
icon: Obx(() {
int index = controller.currentDir.value.index;
return Transform.rotate(
angle: dirList[index].angle,
child: const Icon(Icons.arrow_back),
);
}),
),
),
UnconstrainedBox(
child: SizedBox(
height: 30,
child: Builder(
builder: (context) => Obx(
() => InkWell(
child: Icon(
Icons.list,
size: 35,
color: appcontroller.isDarkMode.value
? Colors.white70
: const Color.fromARGB(200, 29, 28, 28),
),
onTap: () {
controller.showList.value =
!controller.showList.value;
}),
),
),
),
),
],
),
body: Stack(
children: [
Obx(() {
controller.isGenerate.value;
return AbsorbPointer(
absorbing: controller.isGenerate.value
? true
: false, //设置CenterLayout 内的GestureDetector 不生效
child: const TaskPage(), // 任务页面
);
}),
center,
back,
Obx(() {
if (controller.showList.value) {
return Positioned(
right: 0,
top: 0,
width: size.width * 0.4,
height: size.height,
child: PilePointTable(
pilePoints: taskcontroller.currentask.value.list,
onUpdate: (updatedPilePoints) =>
updatePoints(updatedPilePoints),
),
);
} else {
return const Text("");
}
})
// const PileGenerateCard1()
],
));
}
Widget buildPositionedButton(
Offset position, double rotationAngle, VoidCallback press) {
Color color = Colors.black;
return Positioned(
left: position.dx,
top: position.dy,
child: IconButton(
onPressed: press,
icon: Transform.rotate(
angle: rotationAngle,
child: Icon(
Icons.arrow_back,
color: color,
),
),
),
);
}
}
centerPointDialog(context, PlumDataController controller) {
double titleTextWidth = 90;
double inputLength = 120;
FocusNode xFocus = FocusNode();
FocusNode yFocus = FocusNode();
FocusNode directionFocus = FocusNode();
FocusNode pileSpaceFocus = FocusNode();
// FocusNode pileWidthFocus = FocusNode();
DeviceType deviceType = getDeviceType(context);
double fontSize = 16;
if (deviceType == DeviceType.mobile) {
fontSize = 16;
} else {
fontSize = 20;
}
showDialog(
context: context,
builder: (context) {
final size = MediaQuery.of(context).size;
double centerPointX = controller.centerXY.value.dx;
double centerPointY = controller.centerXY.value.dy;
return AlertDialog(
title: const Text("设置"),
contentPadding: const EdgeInsets.symmetric(horizontal: 3),
actionsPadding: const EdgeInsets.only(bottom: 5),
actions: [
TextButton(
child: const Text('取消'),
onPressed: () {
controller.isGenerate.value = false;
controller.isSave.value = false;
Navigator.of(context).pop();
// 执行取消的逻辑
},
),
TextButton(
child: const Text('确定'),
onPressed: () {
// 执行确定的逻辑
controller.isGenerate.value = false;
controller.isSave.value = true;
controller.centerXY.value = Offset(centerPointX, centerPointY);
Navigator.of(context).pop();
},
),
],
content: SizedBox(
height: size.height * 0.45,
width: size.width * 0.5,
child: SingleChildScrollView(
child: AlignWrapWidget(
children: [
Row(children: [
FixedWidthTextWidget(width: titleTextWidth, text: "X:"),
inputText(
inputLength: inputLength,
value: centerPointX.toString(),
fontsize: fontSize,
focusNode: yFocus,
onChanged: (value) => value.isNotEmpty
? centerPointY =
(double.parse(value) * 1000).round() / 1000
: '')
]),
Row(children: [
FixedWidthTextWidget(width: titleTextWidth, text: "Y:"),
inputText(
inputLength: inputLength,
value: centerPointY.toString(),
fontsize: fontSize,
focusNode: xFocus,
onChanged: (value) => value.isNotEmpty
? centerPointX =
(double.parse(value) * 1000).round() / 1000
: '')
]),
Row(children: [
FixedWidthTextWidget(width: titleTextWidth, text: "方向(°):"),
inputText(
inputLength: inputLength,
value: controller.direction.toString(),
fontsize: fontSize,
focusNode: directionFocus,
keyboardType: 0,
onChanged: (value) {
if (value.isNotEmpty) {
controller.direction.value = double.parse(value);
// bug 值修改后 绘制没有变化
controller.angle.value =
controller.direction.value * pi / 180;
}
})
]),
Row(
children: [
FixedWidthTextWidget(
width: titleTextWidth + 10, text: "夯点间距(m):"),
inputText(
inputLength: inputLength - 10,
fontsize: fontSize,
value: controller.space.toString(),
focusNode: pileSpaceFocus,
onChanged: (value) => {
value.isNotEmpty
? controller.space.value = double.parse(value)
: '',
})
],
),
Row(children: [
FixedWidthTextWidget(
width: titleTextWidth + 10, text: "是否为梅花桩:"),
Obx(() {
bool c = controller.isPlum.value;
return Switch(
onChanged: (val) {
controller.isPlum.value = val;
},
value: c,
);
})
]),
// Row(children: [
// FixedWidthTextWidget(
// width: titleTextWidth + 10, text: "宽度(m):"),
// inputText(
// inputLength: inputLength - 10,
// fontsize: fontSize,
// value: controller.pileWidth.toString(),
// focusNode: pileWidthFocus,
// onChanged: (value) => {
// value.isNotEmpty
// ? controller.pileWidth.value =
// double.parse(value)
// : '',
// })
// ]),
Row(children: [
const Icon(
Icons.tips_and_updates_outlined,
color: Colors.red,
),
Text(
controller.isPileId.value
? '选中桩点:${controller.checkName.value}'
: ' 未选中桩点',
style: TextStyle(
color: !controller.isPileId.value
? Colors.red
: Colors.black),
)
]),
],
)),
),
);
});
}
updatePoints(List<PilePoint> updatedPilePoints) {
taskcontroller.currentask.update((task) {
task?.list = updatedPilePoints;
});
// 这里可以处理更新后的桩点列表
// dev.log("生成桩点${updatedPilePoints.length},");
// for (var updatedPilePoint in updatedPilePoints) {
// // 查找 recordList 中对应的 RecordEntity
// RecordEntity? recordEntity =
// mapController.recordList.firstWhere(
// (record) => record.id == updatedPilePoint.id,
// orElse: () => RecordEntity(
// id: -1, // 使用一个无效的 id 表示未找到
// tid: 0,
// startTime: DateTime.now(),
// endTime: DateTime.now(),
// pileId: 0,
// name: '',
// times: 0,
// lat: 0.0,
// lng: 0.0,
// x: 0.0,
// y: 0.0,
// h: 0.0,
// totalFlow: 0.0,
// titlXavg: 0.0,
// titlYavg: 0.0,
// current1Avg: 0.0,
// current2Avg: 0.0,
// quality: 0,
// reason: '',
// remark: '',
// depth: 0,
// speed: 0.0,
// ),
// );
// if (recordEntity.id != -1) {
// // 更新 RecordEntity 的属性
// recordEntity.x = updatedPilePoint.x;
// recordEntity.y = updatedPilePoint.y;
// // 其他属性的更新
// } else {
// // 如果找不到对应的 RecordEntity则添加新的
// recordEntity = RecordEntity(
// id: updatedPilePoint.id,
// tid: 0,
// startTime: DateTime.now(),
// endTime: DateTime.now(),
// pileId: 0,
// name: '',
// times: 0,
// lat: 0.0,
// lng: 0.0,
// x: updatedPilePoint.x,
// y: updatedPilePoint.y,
// h: 0.0,
// totalFlow: 0.0,
// titlXavg: 0.0,
// titlYavg: 0.0,
// current1Avg: 0.0,
// current2Avg: 0.0,
// quality: 0,
// reason: '',
// remark: '',
// depth: 0,
// speed: 0.0,
// );
// mapController.recordList.add(recordEntity);
// }
// }
}