first commit
This commit is contained in:
parent
7d9626fafb
commit
6abf207151
@ -1 +1 @@
|
|||||||
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"path_provider_foundation","path":"C:\\\\Users\\\\Administrator\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_foundation-2.4.0\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]}],"android":[{"name":"path_provider_android","path":"C:\\\\Users\\\\Administrator\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_android-2.2.10\\\\","native_build":true,"dependencies":[]}],"macos":[{"name":"path_provider_foundation","path":"C:\\\\Users\\\\Administrator\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_foundation-2.4.0\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]}],"linux":[{"name":"path_provider_linux","path":"C:\\\\Users\\\\Administrator\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_linux-2.2.1\\\\","native_build":false,"dependencies":[]}],"windows":[{"name":"path_provider_windows","path":"C:\\\\Users\\\\Administrator\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_windows-2.3.0\\\\","native_build":false,"dependencies":[]}],"web":[]},"dependencyGraph":[{"name":"path_provider","dependencies":["path_provider_android","path_provider_foundation","path_provider_linux","path_provider_windows"]},{"name":"path_provider_android","dependencies":[]},{"name":"path_provider_foundation","dependencies":[]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_windows","dependencies":[]}],"date_created":"2024-08-21 11:28:19.723327","version":"3.24.0","swift_package_manager_enabled":false}
|
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"path_provider_foundation","path":"C:\\\\Users\\\\Administrator\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_foundation-2.4.0\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]}],"android":[{"name":"path_provider_android","path":"C:\\\\Users\\\\Administrator\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_android-2.2.10\\\\","native_build":true,"dependencies":[]}],"macos":[{"name":"path_provider_foundation","path":"C:\\\\Users\\\\Administrator\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_foundation-2.4.0\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]}],"linux":[{"name":"path_provider_linux","path":"C:\\\\Users\\\\Administrator\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_linux-2.2.1\\\\","native_build":false,"dependencies":[]}],"windows":[{"name":"path_provider_windows","path":"C:\\\\Users\\\\Administrator\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_windows-2.3.0\\\\","native_build":false,"dependencies":[]}],"web":[]},"dependencyGraph":[{"name":"path_provider","dependencies":["path_provider_android","path_provider_foundation","path_provider_linux","path_provider_windows"]},{"name":"path_provider_android","dependencies":[]},{"name":"path_provider_foundation","dependencies":[]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_windows","dependencies":[]}],"date_created":"2024-08-23 17:31:42.127712","version":"3.24.0","swift_package_manager_enabled":false}
|
60
lib/controllers/plumController.dart
Normal file
60
lib/controllers/plumController.dart
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
import 'dart:math';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:roslibdart/roslibdart.dart';
|
||||||
|
|
||||||
|
class PlumDataController extends GetxController {
|
||||||
|
var isGenerate = false.obs; //是否生成
|
||||||
|
var angle = 0.0.obs; //方向弧度
|
||||||
|
var isDirect = false.obs; //是否为方向设置
|
||||||
|
var checkValue = "".obs; //checkPile -桩点坐标,checkDirection-方向设置
|
||||||
|
var checkName = "".obs;
|
||||||
|
var centerXY = Offset.zero.obs; //中心点
|
||||||
|
var space = 5.0.obs; //间距 m
|
||||||
|
var pileWidth = 400.0.obs; //打桩宽度 m
|
||||||
|
var genLenth = 0.obs; //半径
|
||||||
|
var isPileId = false.obs;
|
||||||
|
var direction = 0.0.obs; //角度
|
||||||
|
var isSave = false.obs; //是否保存
|
||||||
|
var centerOffset = Offset.zero.obs;
|
||||||
|
var linePointOffset = Offset.zero.obs;
|
||||||
|
var linePointXY = Offset.zero.obs;
|
||||||
|
var isUp = false.obs;
|
||||||
|
var plumList = [Offset.zero];
|
||||||
|
// var shouldPaint = true.obs;
|
||||||
|
var isMap = false.obs;
|
||||||
|
late Service service;
|
||||||
|
late Ros ros;
|
||||||
|
var canvasSize = Size.zero;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void onInit() async {
|
||||||
|
super.onInit();
|
||||||
|
// plumList.value = [];
|
||||||
|
// centerXY.value = const Offset(3790620.0588630675, 577014.4059290753);
|
||||||
|
|
||||||
|
// for (int i = -2; i <= 2; i++) {
|
||||||
|
// for (int j = -2; j <= 2; j++) {
|
||||||
|
// plumList.add(Offset(centerXY.value.dx + i, centerXY.value.dy + j));
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// ros = BaseService().getRos();
|
||||||
|
// ros.connect();
|
||||||
|
// service = Service(
|
||||||
|
// name: '/smash_point_list_service',
|
||||||
|
// ros: ros,
|
||||||
|
// type: "nav2_smash_behavior/srv/SmashPointList");
|
||||||
|
// var json = {'data': []};
|
||||||
|
// service.call(json).then((value) {
|
||||||
|
// print('ros$value');
|
||||||
|
// });
|
||||||
|
}
|
||||||
|
|
||||||
|
updateLinePoint(Offset offset) {
|
||||||
|
linePointOffset.value = offset;
|
||||||
|
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
}
|
@ -1,14 +1,16 @@
|
|||||||
import 'package:cpnav/appbar.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:scence_map/controller.dart';
|
import 'package:scence_map/controller.dart';
|
||||||
|
import 'appbar.dart';
|
||||||
|
import 'controllers/plumController.dart';
|
||||||
import 'pages/pass_track/view.dart';
|
import 'pages/pass_track/view.dart';
|
||||||
|
import 'pages/pile/rightDra/pileGenerate.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: []); //设置全屏
|
SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: []); //设置全屏
|
||||||
|
Get.put(PlumDataController());
|
||||||
runApp(const MyApp());
|
runApp(const MyApp());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,12 +70,12 @@ class _MyHomePageState extends State<MyHomePage> {
|
|||||||
|
|
||||||
final _currentIndex = 0.obs;
|
final _currentIndex = 0.obs;
|
||||||
final List<Widget> _pages = [
|
final List<Widget> _pages = [
|
||||||
PassTrack(
|
|
||||||
date: '',
|
|
||||||
),
|
|
||||||
Container(
|
Container(
|
||||||
color: Colors.green,
|
color: Colors.green,
|
||||||
),
|
),
|
||||||
|
PassTrack(
|
||||||
|
date: '',
|
||||||
|
),
|
||||||
Container(
|
Container(
|
||||||
color: Colors.blue,
|
color: Colors.blue,
|
||||||
),
|
),
|
||||||
@ -86,6 +88,7 @@ class _MyHomePageState extends State<MyHomePage> {
|
|||||||
];
|
];
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
final size = MediaQuery.of(context).size;
|
||||||
// This method is rerun every time setState is called, for instance as done
|
// This method is rerun every time setState is called, for instance as done
|
||||||
// by the _incrementCounter method above.
|
// by the _incrementCounter method above.
|
||||||
//
|
//
|
||||||
@ -93,6 +96,12 @@ class _MyHomePageState extends State<MyHomePage> {
|
|||||||
// fast, so that you can just rebuild anything that needs updating rather
|
// fast, so that you can just rebuild anything that needs updating rather
|
||||||
// than having to individually change instances of widgets.
|
// than having to individually change instances of widgets.
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
|
endDrawer: _currentIndex.value == 1
|
||||||
|
? Drawer(
|
||||||
|
width: size.width * .8,
|
||||||
|
child: const PileGenerate(),
|
||||||
|
)
|
||||||
|
: null,
|
||||||
appBar: PreferredSize(
|
appBar: PreferredSize(
|
||||||
// TRY THIS: Try changing the color here to a specific color (to
|
// TRY THIS: Try changing the color here to a specific color (to
|
||||||
// Colors.amber, perhaps?) and trigger a hot reload to see the AppBar
|
// Colors.amber, perhaps?) and trigger a hot reload to see the AppBar
|
||||||
|
58
lib/models/pilePoint/hyrecorditem.dart
Normal file
58
lib/models/pilePoint/hyrecorditem.dart
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
class HyRecordItem {
|
||||||
|
final int id;
|
||||||
|
final String startTime;
|
||||||
|
final String endTime;
|
||||||
|
final int tid;
|
||||||
|
final int tpId;
|
||||||
|
final String name;
|
||||||
|
final double lat;
|
||||||
|
final double lng;
|
||||||
|
final double alt;
|
||||||
|
final double x;
|
||||||
|
final double y;
|
||||||
|
final int times;
|
||||||
|
final double strongDrop;
|
||||||
|
final int layer;
|
||||||
|
final int qualified;
|
||||||
|
double dx;
|
||||||
|
double dy;
|
||||||
|
HyRecordItem({
|
||||||
|
this.alt = 0,
|
||||||
|
this.endTime = "",
|
||||||
|
required this.id,
|
||||||
|
this.lat = 0,
|
||||||
|
this.lng = 0,
|
||||||
|
this.layer = 1,
|
||||||
|
this.name = "",
|
||||||
|
this.qualified = 1,
|
||||||
|
this.startTime = "",
|
||||||
|
this.strongDrop = 0,
|
||||||
|
required this.tid,
|
||||||
|
this.times = 1,
|
||||||
|
required this.tpId,
|
||||||
|
this.x = 0,
|
||||||
|
this.y = 0,
|
||||||
|
this.dx = 0,
|
||||||
|
this.dy = 0,
|
||||||
|
});
|
||||||
|
factory HyRecordItem.fromJson(Map<String, dynamic> json) {
|
||||||
|
return HyRecordItem(
|
||||||
|
alt: json['ALT'].toDouble() ?? 0,
|
||||||
|
endTime: json['end_time'],
|
||||||
|
id: json['id'],
|
||||||
|
lat: json['LAT'].toDouble() ?? 0,
|
||||||
|
lng: json['LNG'].toDouble() ?? 0,
|
||||||
|
layer: json['layer'],
|
||||||
|
name: json['name'] ?? "",
|
||||||
|
qualified: json['is_qualified'],
|
||||||
|
startTime: json['start_time'],
|
||||||
|
strongDrop: json['strong_drop'].toDouble() ?? 0,
|
||||||
|
tid: json['tid'],
|
||||||
|
times: json['times'],
|
||||||
|
tpId: json['tp_id'],
|
||||||
|
x: json['x'].toDouble() ?? 0,
|
||||||
|
y: json['y'].toDouble() ?? 0,
|
||||||
|
dx: 0,
|
||||||
|
dy: 0);
|
||||||
|
}
|
||||||
|
}
|
@ -41,6 +41,7 @@ class PassTrackController extends GetxController {
|
|||||||
double minX = double.infinity;
|
double minX = double.infinity;
|
||||||
double minY = double.infinity;
|
double minY = double.infinity;
|
||||||
var sideLineData = data as Map<String, dynamic>;
|
var sideLineData = data as Map<String, dynamic>;
|
||||||
|
// var sideLineData = data;
|
||||||
sideLineData.forEach((group, items) {
|
sideLineData.forEach((group, items) {
|
||||||
for (var item in items) {
|
for (var item in items) {
|
||||||
SideLineItem sideLineItem = SideLineItem.fromJson(item);
|
SideLineItem sideLineItem = SideLineItem.fromJson(item);
|
||||||
|
120
lib/pages/pile/pileNav/draw_pile.dart
Normal file
120
lib/pages/pile/pileNav/draw_pile.dart
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
import 'dart:math';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:scence_map/controller.dart';
|
||||||
|
|
||||||
|
import '../../../controllers/plumController.dart';
|
||||||
|
|
||||||
|
|
||||||
|
ScenceMapController mapController = Get.find<ScenceMapController>();
|
||||||
|
|
||||||
|
class DrawDirection extends CustomPainter {
|
||||||
|
PlumDataController controller;
|
||||||
|
Offset pos;
|
||||||
|
bool isDarkMode;
|
||||||
|
bool isInit;
|
||||||
|
DrawDirection(this.controller, this.pos, this.isDarkMode, this.isInit);
|
||||||
|
|
||||||
|
@override
|
||||||
|
void paint(Canvas canvas, Size size) {
|
||||||
|
controller.canvasSize = size;
|
||||||
|
final paint = Paint();
|
||||||
|
Path path = Path();
|
||||||
|
|
||||||
|
paint
|
||||||
|
..strokeWidth = 2
|
||||||
|
..style = PaintingStyle.stroke
|
||||||
|
..color = isDarkMode ? Colors.white : Colors.black;
|
||||||
|
if (controller.linePointOffset.value == Offset.zero ||
|
||||||
|
controller.centerXY.value == Offset.zero) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Offset linePointOffset = mapController.xy2Screen(
|
||||||
|
controller.linePointXY.value.dx, controller.linePointXY.value.dy);
|
||||||
|
Offset centerOffset = controller.centerOffset.value;
|
||||||
|
Offset centerXY = controller.centerXY.value;
|
||||||
|
if (isInit) {
|
||||||
|
linePointOffset = linePointOffset + pos;
|
||||||
|
centerOffset = controller.centerOffset.value + pos;
|
||||||
|
}
|
||||||
|
print("-----矩阵中心$centerOffset,$centerXY");
|
||||||
|
|
||||||
|
path.moveTo(centerOffset.dx, centerOffset.dy);
|
||||||
|
path.lineTo(linePointOffset.dx, linePointOffset.dy);
|
||||||
|
canvas.drawPath(path, paint);
|
||||||
|
paint.style = PaintingStyle.fill;
|
||||||
|
canvas.drawCircle(linePointOffset, 10, paint);
|
||||||
|
// canvas.translate(centerOffset.dx, centerOffset.dy);
|
||||||
|
// canvas.rotate(controller.angle.value);
|
||||||
|
// canvas.translate(-centerOffset.dx, -centerOffset.dy);
|
||||||
|
paint
|
||||||
|
// ..color = Colors.grey.withOpacity(.4)
|
||||||
|
.style = PaintingStyle.stroke;
|
||||||
|
|
||||||
|
if (controller.isUp.value && controller.angle.value != 0) {
|
||||||
|
double unit =
|
||||||
|
mapController.plottingScale.value / mapController.pixel2MeterRatio;
|
||||||
|
|
||||||
|
// 沿着路径绘制圆圈
|
||||||
|
double distance = (linePointOffset - centerOffset).distance;
|
||||||
|
int horizonalCircles = (distance / unit).floor();
|
||||||
|
int verticalCircles = (controller.pileWidth / unit).floor();
|
||||||
|
|
||||||
|
// controller.plumList.length = 0;
|
||||||
|
List<Offset> circlePoints = [];
|
||||||
|
// List<Offset> plumList = [];
|
||||||
|
controller.plumList.length = 0;
|
||||||
|
for (int i = 0; i <= horizonalCircles; i++) {
|
||||||
|
double t = i * unit / distance;
|
||||||
|
Offset point = Offset.lerp(centerOffset, linePointOffset, t)!;
|
||||||
|
canvas.drawCircle(point, .3 / mapController.pixel2MeterRatio, paint);
|
||||||
|
circlePoints.add(point);
|
||||||
|
// Offset xy = mapController.screen2xy(point.dx, point.dy);
|
||||||
|
// plumList.add(Offset(xy.dx, xy.dy));
|
||||||
|
controller.plumList.add(point);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 在反方向延长线上绘制对称的圆圈
|
||||||
|
for (int i = 1; i <= horizonalCircles; i++) {
|
||||||
|
double t = i * unit / distance;
|
||||||
|
Offset point = Offset.lerp(centerOffset, linePointOffset, -t)!;
|
||||||
|
canvas.drawCircle(point, .3 / mapController.pixel2MeterRatio, paint);
|
||||||
|
circlePoints.add(point);
|
||||||
|
controller.plumList.add(point);
|
||||||
|
|
||||||
|
//List保存
|
||||||
|
}
|
||||||
|
|
||||||
|
// 计算垂直于path的方向向量
|
||||||
|
Offset direction =
|
||||||
|
(linePointOffset - centerOffset).scale(1 / distance, 1 / distance);
|
||||||
|
Offset perpendicular = Offset(-direction.dy, direction.dx);
|
||||||
|
|
||||||
|
// 绘制上下方的圆圈,形成正方形矩阵
|
||||||
|
for (Offset point in circlePoints) {
|
||||||
|
for (int j = 0; j <= verticalCircles / 2; j++) {
|
||||||
|
Offset upPoint = point + perpendicular * (j * unit);
|
||||||
|
Offset downPoint = point - perpendicular * (j * unit);
|
||||||
|
canvas.drawCircle(
|
||||||
|
upPoint, .3 / mapController.pixel2MeterRatio, paint);
|
||||||
|
canvas.drawCircle(
|
||||||
|
downPoint, .3 / mapController.pixel2MeterRatio, paint);
|
||||||
|
|
||||||
|
// Offset xy = mapController.screen2xy0(upPoint);
|
||||||
|
// Offset xy1 = mapController.screen2xy0(downPoint);
|
||||||
|
controller.plumList.add(upPoint);
|
||||||
|
controller.plumList.add(downPoint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if (plumList.isNotEmpty) {
|
||||||
|
// controller.plumList.value = plumList;
|
||||||
|
// // controller.update();
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool shouldRepaint(covariant CustomPainter oldDelegate) => true;
|
||||||
|
}
|
207
lib/pages/pile/pileNav/view.dart
Normal file
207
lib/pages/pile/pileNav/view.dart
Normal file
@ -0,0 +1,207 @@
|
|||||||
|
import 'dart:math';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:scence_map/controller.dart';
|
||||||
|
import 'package:scence_map/scence_map.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
|
import '../../../controllers/plumController.dart';
|
||||||
|
import '../../../models/pilePoint/hyrecorditem.dart';
|
||||||
|
import 'draw_pile.dart';
|
||||||
|
|
||||||
|
class RealView extends StatefulWidget {
|
||||||
|
const RealView({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<RealView> createState() => _RealViewState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _RealViewState extends State<RealView> {
|
||||||
|
final ScenceMapController scenceMapController =
|
||||||
|
Get.put(ScenceMapController());
|
||||||
|
final controller = Get.find<PlumDataController>();
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isInit = false;
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
// scenceMapController.disableMove.value = false;
|
||||||
|
scenceMapController.update();
|
||||||
|
isInit = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final isDarkMode = Theme.of(context).brightness == Brightness.dark;
|
||||||
|
double diagonal = scenceMapController.diagonal;
|
||||||
|
double mapWidth = scenceMapController.width;
|
||||||
|
double mapHeight = scenceMapController.height;
|
||||||
|
Offset scOffset =
|
||||||
|
Offset(mapWidth / 2 - diagonal / 2, mapHeight / 2 - diagonal / 2);
|
||||||
|
onTapDown(TapDownDetails details) {
|
||||||
|
isInit = false;
|
||||||
|
if (controller.checkValue.value == "checkPile") {
|
||||||
|
// controller.centerOffset.value = details.localPosition;
|
||||||
|
Offset sc2xy = scenceMapController.screen2xy0(details.localPosition);
|
||||||
|
controller.centerXY.value = sc2xy;
|
||||||
|
|
||||||
|
HyRecordItem? checkPoint =
|
||||||
|
scenceMapController.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 = "未找到";
|
||||||
|
}
|
||||||
|
Scaffold.of(context).openEndDrawer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onScaleStart(ScaleStartDetails details) {
|
||||||
|
if (controller.checkValue.value != "checkPile") {
|
||||||
|
controller.linePointOffset.value = details.localFocalPoint;
|
||||||
|
}
|
||||||
|
// controller.shouldPaint.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
onScaleUpdate(ScaleUpdateDetails details) {
|
||||||
|
controller.isUp.value = false;
|
||||||
|
// controller.shouldPaint.value = true;
|
||||||
|
if (controller.checkValue.value != "checkPile") {
|
||||||
|
if (controller.linePointOffset.value != details.localFocalPoint) {
|
||||||
|
controller.linePointXY.value =
|
||||||
|
scenceMapController.screen2xy0(details.localFocalPoint);
|
||||||
|
|
||||||
|
controller.updateLinePoint(details.localFocalPoint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
controller.isUp.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
onScaleEnd(ScaleEndDetails details) {
|
||||||
|
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;
|
||||||
|
|
||||||
|
controller.isUp.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 中间
|
||||||
|
var center = Obx(() {
|
||||||
|
// 桩点生成
|
||||||
|
if (!controller.isGenerate.value) {
|
||||||
|
return const Text("");
|
||||||
|
}
|
||||||
|
|
||||||
|
return Positioned(
|
||||||
|
width: scenceMapController.diagonal,
|
||||||
|
height: scenceMapController.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.linePointOffset.value;
|
||||||
|
controller.isUp.value;
|
||||||
|
return CustomPaint(
|
||||||
|
// size: Size(scenceMapController.diagonal,
|
||||||
|
// scenceMapController.diagonal),
|
||||||
|
foregroundPainter:
|
||||||
|
DrawDirection(controller, scOffset, isDarkMode, isInit),
|
||||||
|
// child:
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
});
|
||||||
|
// 桩点生成时返回按钮
|
||||||
|
var back = Obx(() {
|
||||||
|
// bug :有时候点击的位置不准确 8寸屏的是正常的
|
||||||
|
|
||||||
|
controller.centerOffset.value = scenceMapController.xy2Screen(
|
||||||
|
controller.centerXY.value.dx, controller.centerXY.value.dy);
|
||||||
|
|
||||||
|
if (isInit) {
|
||||||
|
controller.centerOffset.value = scenceMapController.xy2Screen(
|
||||||
|
controller.centerXY.value.dx, controller.centerXY.value.dy) -
|
||||||
|
scOffset;
|
||||||
|
}
|
||||||
|
print(
|
||||||
|
"中心${controller.centerOffset.value},${controller.centerXY.value},${scenceMapController.centerXY},$scOffset,$isInit");
|
||||||
|
print(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: () {
|
||||||
|
Scaffold.of(context).openEndDrawer();
|
||||||
|
controller.isDirect.value = false;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
));
|
||||||
|
});
|
||||||
|
return Stack(
|
||||||
|
children: [
|
||||||
|
Obx(() => AbsorbPointer(
|
||||||
|
absorbing: controller.isGenerate.value
|
||||||
|
? true
|
||||||
|
: false, //设置CenterLayout 内的GestureDetector 不生效
|
||||||
|
child: const ScenceMapView(
|
||||||
|
children: [],
|
||||||
|
),
|
||||||
|
)),
|
||||||
|
center,
|
||||||
|
back,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
226
lib/pages/pile/rightDra/pileGenerate.dart
Normal file
226
lib/pages/pile/rightDra/pileGenerate.dart
Normal file
@ -0,0 +1,226 @@
|
|||||||
|
import 'dart:math';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:scence_map/controller.dart';
|
||||||
|
|
||||||
|
import '../../../controllers/plumController.dart';
|
||||||
|
|
||||||
|
import '../../../service/pile/device_type.dart';
|
||||||
|
import '../../../service/pile/input.dart';
|
||||||
|
import '../../../service/pile/public_widget.dart';
|
||||||
|
|
||||||
|
final ScenceMapController mapController = Get.find<ScenceMapController>();
|
||||||
|
|
||||||
|
class PileGenerate extends GetView<PlumDataController> {
|
||||||
|
const PileGenerate({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
double centerPointX = controller.centerXY.value.dx;
|
||||||
|
double centerPointY = controller.centerXY.value.dy;
|
||||||
|
|
||||||
|
final size = MediaQuery.of(context).size;
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: const Text("桩点生成"),
|
||||||
|
toolbarHeight: 30,
|
||||||
|
),
|
||||||
|
body: SizedBox(
|
||||||
|
height: size.height,
|
||||||
|
child: Stack(
|
||||||
|
children: [
|
||||||
|
SingleChildScrollView(
|
||||||
|
child: AlignWrapWidget(
|
||||||
|
children: [
|
||||||
|
Row(
|
||||||
|
children: [
|
||||||
|
const Text('地图显示:'),
|
||||||
|
Obx(() => Switch(
|
||||||
|
value: controller.isMap.value,
|
||||||
|
onChanged: ((value) {
|
||||||
|
controller.isMap.value = !controller.isMap.value;
|
||||||
|
}))),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
AlignWrapWidget(
|
||||||
|
children: [
|
||||||
|
ElevatedButton(
|
||||||
|
child: const Text("夯锤坐标"),
|
||||||
|
onPressed: () => {controller.isDirect.value = false},
|
||||||
|
),
|
||||||
|
const SizedBox(
|
||||||
|
width: 10,
|
||||||
|
),
|
||||||
|
ElevatedButton(
|
||||||
|
child: const Text("桩点坐标"),
|
||||||
|
onPressed: () => {
|
||||||
|
controller.isGenerate.value = true,
|
||||||
|
controller.checkValue.value = "checkPile",
|
||||||
|
controller.isDirect.value = false,
|
||||||
|
Navigator.pop(context)
|
||||||
|
}),
|
||||||
|
const SizedBox(
|
||||||
|
width: 10,
|
||||||
|
),
|
||||||
|
ElevatedButton(
|
||||||
|
child: const Text("方向设置"),
|
||||||
|
onPressed: () => {
|
||||||
|
controller.isGenerate.value = true,
|
||||||
|
controller.checkValue.value = "checkDirection",
|
||||||
|
controller.isDirect.value = true,
|
||||||
|
controller.centerXY.value =
|
||||||
|
Offset(centerPointX, centerPointY),
|
||||||
|
Navigator.pop(context)
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
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)
|
||||||
|
: '')
|
||||||
|
]),
|
||||||
|
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)
|
||||||
|
: '')
|
||||||
|
]),
|
||||||
|
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: "宽度(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),
|
||||||
|
)
|
||||||
|
]),
|
||||||
|
],
|
||||||
|
)),
|
||||||
|
Positioned(
|
||||||
|
bottom: 10,
|
||||||
|
child: Row(
|
||||||
|
children: [
|
||||||
|
TextButton(
|
||||||
|
child: const Text('取消'),
|
||||||
|
onPressed: () {
|
||||||
|
controller.isGenerate.value = false;
|
||||||
|
controller.isDirect.value = false;
|
||||||
|
controller.isSave.value = false;
|
||||||
|
// 执行取消的逻辑
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
TextButton(
|
||||||
|
child: const Text('确定'),
|
||||||
|
onPressed: () {
|
||||||
|
// 执行确定的逻辑
|
||||||
|
var dx = controller.canvasSize.width / 2;
|
||||||
|
var dy = controller.canvasSize.height / 2;
|
||||||
|
for (int i = 0; i < controller.plumList.length; i++) {
|
||||||
|
Offset item = controller.plumList[i];
|
||||||
|
|
||||||
|
Offset xy = mapController.ScreenCenter2xy(
|
||||||
|
item.dx - dx, item.dy - dy);
|
||||||
|
PilePoint pilePoint = PilePoint(
|
||||||
|
x: xy.dx,
|
||||||
|
y: xy.dy,
|
||||||
|
state: 0,
|
||||||
|
id: i + 1,
|
||||||
|
radius: 0.3);
|
||||||
|
mapController.pilePoints.add(pilePoint);
|
||||||
|
}
|
||||||
|
controller.isGenerate.value = false;
|
||||||
|
controller.isDirect.value = false;
|
||||||
|
controller.isSave.value = true;
|
||||||
|
controller.centerXY.value =
|
||||||
|
Offset(centerPointX, centerPointY);
|
||||||
|
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
))
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -9,7 +9,7 @@ class BaseService {
|
|||||||
//创建client实例
|
//创建client实例
|
||||||
final _client = http.Client();
|
final _client = http.Client();
|
||||||
final String token =
|
final String token =
|
||||||
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc1IiOjAsInJvbGVJZHMiOlsiMSIsIjI0Il0sInVzZXJuYW1lIjoiYWRtaW4iLCJ1c2VySWQiOjEsIlBWIjo1LCJvcmciOiJhIiwiaWF0IjoxNzIyODY1MTE0LCJleHAiOjE3MjQxNjExMTR9.zuY366ldKkbtd1TTfcYIZfvhrovMlXLzzRk3j65Ua7o";
|
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc1IiOjAsInJvbGVJZHMiOlsiODMiXSwidXNlcm5hbWUiOiJseWNzIiwidXNlcklkIjozNTYsIlBWIjoyLCJvcmciOiJhIiwiaWF0IjoxNzI0MDI5MzcwLCJleHAiOjE3MjUzMjUzNzB9.w24n7SSTXz3vnRNqKmt2zht_xbXR-iQ1EnreBIWqYNU";
|
||||||
|
|
||||||
// String baseUrl = "http://192.168.1.189:8001";//本地
|
// String baseUrl = "http://192.168.1.189:8001";//本地
|
||||||
String baseUrl = "http://1.82.251.83:8001"; //线上
|
String baseUrl = "http://1.82.251.83:8001"; //线上
|
||||||
@ -80,8 +80,14 @@ class GetServices {
|
|||||||
// 设备绑定 --- 获取设备
|
// 设备绑定 --- 获取设备
|
||||||
Future getDeviceBind() async {
|
Future getDeviceBind() async {
|
||||||
Map res = await service.getClient(
|
Map res = await service.getClient(
|
||||||
|
// '/api/sys/device_bind/list?proj_type=$projType&proj_code=$projCode');
|
||||||
|
// if (res['code'] == 1000) {
|
||||||
|
// return res['data'];
|
||||||
|
// } else {
|
||||||
|
// return [];
|
||||||
|
// }
|
||||||
'/api/sys/device_bind/list?proj_type=$projType&proj_code=$projCode');
|
'/api/sys/device_bind/list?proj_type=$projType&proj_code=$projCode');
|
||||||
if (res['code'] == 1000) {
|
if (res != null && res['code'] == 1000) {
|
||||||
return res['data'];
|
return res['data'];
|
||||||
} else {
|
} else {
|
||||||
return [];
|
return [];
|
||||||
|
34
lib/service/pile/device_type.dart
Normal file
34
lib/service/pile/device_type.dart
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import 'package:flutter/widgets.dart';
|
||||||
|
|
||||||
|
enum DeviceType {
|
||||||
|
mobile,
|
||||||
|
tablet,
|
||||||
|
desktop,
|
||||||
|
}
|
||||||
|
|
||||||
|
DeviceType getDeviceType(BuildContext context) {
|
||||||
|
final screenSize = MediaQuery.of(context).size;
|
||||||
|
const minWidth = 500; // 设定判断平板的最小宽度
|
||||||
|
const maxWidth = 1024; // 设定判断电脑的最大宽度
|
||||||
|
final orientation = MediaQuery.of(context).orientation;
|
||||||
|
|
||||||
|
if (orientation == Orientation.portrait) {
|
||||||
|
// 竖屏时按照宽度判断设备类型
|
||||||
|
if (screenSize.width < minWidth) {
|
||||||
|
return DeviceType.mobile; // 宽度小于最小宽度,判断为手机
|
||||||
|
} else if (screenSize.width <= maxWidth) {
|
||||||
|
return DeviceType.tablet; // 宽度在最小宽度和最大宽度之间,判断为平板
|
||||||
|
} else {
|
||||||
|
return DeviceType.desktop; // 宽度大于最大宽度,判断为电脑
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 横屏时按照高度判断设备类型
|
||||||
|
if (screenSize.height < minWidth) {
|
||||||
|
return DeviceType.mobile; // 高度小于最小宽度,判断为手机
|
||||||
|
} else if (screenSize.height <= maxWidth) {
|
||||||
|
return DeviceType.tablet; // 高度在最小宽度和最大宽度之间,判断为平板
|
||||||
|
} else {
|
||||||
|
return DeviceType.desktop; // 高度大于最大宽度,判断为电脑
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
168
lib/service/pile/input.dart
Normal file
168
lib/service/pile/input.dart
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
// ignore_for_file: must_be_immutable
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'device_type.dart';
|
||||||
|
|
||||||
|
// ignore: camel_case_types,
|
||||||
|
class inputText extends StatefulWidget {
|
||||||
|
//内容
|
||||||
|
String value;
|
||||||
|
//跟在后面的单位,默认为空
|
||||||
|
String? endValue;
|
||||||
|
//控制焦点
|
||||||
|
FocusNode? focusNode;
|
||||||
|
//控制长度
|
||||||
|
double inputLength;
|
||||||
|
//控制键盘类型,默认为数字0,其他参数都是字符串
|
||||||
|
int keyboardType;
|
||||||
|
//回调数据变化后返回新值
|
||||||
|
double fontsize;
|
||||||
|
double inputHeight;
|
||||||
|
final ValueChanged<String>? onChanged;
|
||||||
|
final Function()? onTap;
|
||||||
|
inputText(
|
||||||
|
{super.key,
|
||||||
|
required this.value,
|
||||||
|
required this.focusNode,
|
||||||
|
required this.onChanged,
|
||||||
|
this.endValue = "",
|
||||||
|
this.inputLength = 200,
|
||||||
|
this.keyboardType = 0,
|
||||||
|
this.fontsize = 20,
|
||||||
|
this.inputHeight = 40,
|
||||||
|
this.onTap});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<inputText> createState() => _inputTextState();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ignore: camel_case_types
|
||||||
|
class _inputTextState extends State<inputText> {
|
||||||
|
//控制默认文本
|
||||||
|
TextEditingController? _controller;
|
||||||
|
//传入的值,作为显示的初始值
|
||||||
|
String _inputTextContext = "";
|
||||||
|
//字体
|
||||||
|
late double _fontSize;
|
||||||
|
// late double _inputHeight;
|
||||||
|
Color _fontcolor = Colors.black;
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_inputTextContext = widget.value;
|
||||||
|
_controller = TextEditingController(text: _inputTextContext);
|
||||||
|
_fontSize = widget.fontsize;
|
||||||
|
// _inputHeight = widget.inputHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final isDarkMode = Theme.of(context).brightness == Brightness.dark;
|
||||||
|
_fontcolor = isDarkMode ? Colors.white : Colors.black;
|
||||||
|
final deviceType = getDeviceType(context);
|
||||||
|
double dynamicWidth = deviceType == DeviceType.mobile ? 0 : 50;
|
||||||
|
return Row(
|
||||||
|
children: [
|
||||||
|
Container(
|
||||||
|
margin: const EdgeInsets.only(bottom: 5),
|
||||||
|
width: widget.endValue != ""
|
||||||
|
? widget.inputLength + dynamicWidth - 5
|
||||||
|
: widget.inputLength + dynamicWidth,
|
||||||
|
height: widget.inputHeight,
|
||||||
|
child: TextField(
|
||||||
|
keyboardType: widget.keyboardType == 0
|
||||||
|
? TextInputType.number
|
||||||
|
: TextInputType.text,
|
||||||
|
clipBehavior: Clip.hardEdge,
|
||||||
|
focusNode: widget.focusNode,
|
||||||
|
controller: _controller,
|
||||||
|
style: TextStyle(fontSize: _fontSize, color: _fontcolor),
|
||||||
|
onChanged: (value) {
|
||||||
|
setState(() {
|
||||||
|
_inputTextContext = value;
|
||||||
|
});
|
||||||
|
// 调用回调函数,通知外部数据变化
|
||||||
|
if (widget.onChanged != null) {
|
||||||
|
widget.onChanged!(value);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
decoration: InputDecoration(
|
||||||
|
contentPadding: const EdgeInsets.only(left: 10),
|
||||||
|
hintText: _inputTextContext,
|
||||||
|
border: const OutlineInputBorder(
|
||||||
|
borderSide: BorderSide(width: 1, color: Colors.black))),
|
||||||
|
onTap: widget.onTap,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Container(
|
||||||
|
padding: const EdgeInsets.only(left: 10),
|
||||||
|
child: Transform.translate(
|
||||||
|
offset: const Offset(-35.0, 0.0),
|
||||||
|
child: Text(
|
||||||
|
"${widget.endValue}",
|
||||||
|
style: TextStyle(fontSize: _fontSize, color: _fontcolor),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class DropDown extends StatefulWidget {
|
||||||
|
List<String> optionList = [];
|
||||||
|
double listLength;
|
||||||
|
double fontSize;
|
||||||
|
double listHeight;
|
||||||
|
final void Function(String?) onValueChanged;
|
||||||
|
DropDown(
|
||||||
|
{super.key,
|
||||||
|
required this.optionList,
|
||||||
|
this.listLength = 200,
|
||||||
|
this.fontSize = 20,
|
||||||
|
this.listHeight = 50,
|
||||||
|
required this.onValueChanged});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<DropDown> createState() => _DropDownState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _DropDownState extends State<DropDown> {
|
||||||
|
List<String> optionList = [];
|
||||||
|
String? dropdownValue;
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
optionList = widget.optionList;
|
||||||
|
// dropdownValue = widget.optionList.isNotEmpty ? widget.optionList[0] : null;
|
||||||
|
dropdownValue = optionList[0];
|
||||||
|
|
||||||
|
// widget.onValueChanged(optionList[0]);
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
||||||
|
widget.onValueChanged(dropdownValue);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return SizedBox(
|
||||||
|
height: widget.listHeight,
|
||||||
|
width: widget.listLength,
|
||||||
|
child: DropdownButton<String>(
|
||||||
|
value: dropdownValue,
|
||||||
|
style: TextStyle(fontSize: widget.fontSize, color: Colors.black),
|
||||||
|
onChanged: (String? newValue) {
|
||||||
|
setState(() {
|
||||||
|
dropdownValue = newValue!;
|
||||||
|
});
|
||||||
|
widget.onValueChanged(newValue);
|
||||||
|
},
|
||||||
|
items: optionList.map<DropdownMenuItem<String>>((String value) {
|
||||||
|
return DropdownMenuItem<String>(
|
||||||
|
value: value,
|
||||||
|
child: Text(value),
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
75
lib/service/pile/public_widget.dart
Normal file
75
lib/service/pile/public_widget.dart
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import 'device_type.dart';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class InlineRowWidget extends StatelessWidget {
|
||||||
|
final List<Widget> children;
|
||||||
|
|
||||||
|
const InlineRowWidget({super.key, required this.children});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return IntrinsicWidth(
|
||||||
|
child: Row(
|
||||||
|
children: children,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class AlignWrapWidget extends StatelessWidget {
|
||||||
|
final List<Widget> children;
|
||||||
|
|
||||||
|
const AlignWrapWidget({super.key, required this.children});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Container(
|
||||||
|
padding: const EdgeInsets.symmetric(vertical: 10),
|
||||||
|
child: Align(
|
||||||
|
alignment: Alignment.centerLeft,
|
||||||
|
child: Wrap(
|
||||||
|
children: children,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ignore: must_be_immutable
|
||||||
|
class FixedWidthTextWidget extends StatelessWidget {
|
||||||
|
final String text;
|
||||||
|
final double width;
|
||||||
|
final TextStyle? style;
|
||||||
|
|
||||||
|
FixedWidthTextWidget({
|
||||||
|
super.key,
|
||||||
|
required this.text,
|
||||||
|
this.width = 80,
|
||||||
|
this.style,
|
||||||
|
});
|
||||||
|
TextStyle? textStyle;
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
final deviceType = getDeviceType(context);
|
||||||
|
double dynamicWidth = deviceType == DeviceType.mobile ? 0 : 50;
|
||||||
|
|
||||||
|
if (style != null) {
|
||||||
|
textStyle =
|
||||||
|
style!.copyWith(fontSize: deviceType == DeviceType.mobile ? 16 : 20);
|
||||||
|
} else {
|
||||||
|
textStyle =
|
||||||
|
TextStyle(fontSize: deviceType == DeviceType.mobile ? 16 : 20);
|
||||||
|
}
|
||||||
|
return Container(
|
||||||
|
margin: const EdgeInsets.symmetric(horizontal: 3),
|
||||||
|
width: width + dynamicWidth,
|
||||||
|
child: Text(
|
||||||
|
text,
|
||||||
|
style: textStyle,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
16
pubspec.lock
16
pubspec.lock
@ -307,6 +307,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.8"
|
version: "2.1.8"
|
||||||
|
roslibdart:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: roslibdart
|
||||||
|
sha256: "7473a39947f3f5ee32b032f8bab5285a465449e5cd234ae486e5ea11bd6c9e3b"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.0.1-dev+4"
|
||||||
scence_map:
|
scence_map:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -439,6 +447,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.0"
|
version: "1.0.0"
|
||||||
|
web_socket_channel:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: web_socket_channel
|
||||||
|
sha256: d88238e5eac9a42bb43ca4e721edba3c08c6354d4a53063afaa568516217621b
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.4.0"
|
||||||
xdg_directories:
|
xdg_directories:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -43,6 +43,7 @@ dependencies:
|
|||||||
google_fonts: ^6.2.1
|
google_fonts: ^6.2.1
|
||||||
syncfusion_flutter_sliders: ^26.2.9
|
syncfusion_flutter_sliders: ^26.2.9
|
||||||
bottom_picker: ^2.8.0
|
bottom_picker: ^2.8.0
|
||||||
|
roslibdart: ^0.0.1-dev+4
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
Loading…
Reference in New Issue
Block a user