Sander Roest

wip

... ... @@ -5,7 +5,6 @@ import 'package:flutter/services.dart';
import 'package:mobile_scanner/mobile_scanner.dart';
import 'package:mobile_scanner_example/picklist/classes/detect_collision.dart';
import 'package:mobile_scanner_example/picklist/widgets/crosshair.dart';
import 'package:mobile_scanner_example/picklist/widgets/draw_detected_barcodes.dart';
import 'package:mobile_scanner_example/scanner_error_widget.dart';
class BarcodeScannerPicklist extends StatefulWidget {
... ... @@ -17,22 +16,16 @@ class BarcodeScannerPicklist extends StatefulWidget {
class _BarcodeScannerPicklistState extends State<BarcodeScannerPicklist>
with WidgetsBindingObserver {
final _mobileScannerController = MobileScannerController(autoStart: false);
final _mobileScannerController = MobileScannerController(
autoStart: false,
);
StreamSubscription<Object?>? _barcodesSubscription;
final _scannerDisabled = ValueNotifier(false);
late final Offset _crosshair;
bool barcodeDetected = false;
@override
void didChangeDependencies() {
_crosshair = MediaQuery.sizeOf(context).center(Offset.zero);
super.didChangeDependencies();
}
@override
void initState() {
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
WidgetsBinding.instance.addObserver(this);
... ... @@ -75,14 +68,17 @@ class _BarcodeScannerPicklistState extends State<BarcodeScannerPicklist>
_mobileScannerController.dispose();
}
void _handleBarcodes(BarcodeCapture barcodes) {
void _handleBarcodes(BarcodeCapture capture) {
if (_scannerDisabled.value) {
return;
}
for (final barcode in barcodes.barcodes) {
if (isOffsetInsideShape(
_crosshair,
for (final barcode in capture.barcodes) {
if (isPointInPolygon(
Offset(
_mobileScannerController.value.size.width / 2,
_mobileScannerController.value.size.height / 2,
),
barcode.corners,
)) {
if (!barcodeDetected) {
... ... @@ -109,10 +105,6 @@ class _BarcodeScannerPicklistState extends State<BarcodeScannerPicklist>
body: StreamBuilder(
stream: _mobileScannerController.barcodes,
builder: (context, snapshot) {
final barcodes = snapshot.data;
if (barcodes == null) {
debugPrint('ISNULL');
}
return Listener(
behavior: HitTestBehavior.opaque,
onPointerDown: (_) => _scannerDisabled.value = true,
... ... @@ -123,14 +115,8 @@ class _BarcodeScannerPicklistState extends State<BarcodeScannerPicklist>
children: [
MobileScanner(
controller: _mobileScannerController,
errorBuilder: (context, error, child) {
return ScannerErrorWidget(error: error);
},
fit: boxFit,
),
...drawDetectedBarcodes(
barcodes: barcodes?.barcodes,
cameraPreviewSize: _mobileScannerController.value.size,
errorBuilder: (context, error, child) =>
ScannerErrorWidget(error: error),
fit: boxFit,
),
ValueListenableBuilder(
... ... @@ -145,51 +131,7 @@ class _BarcodeScannerPicklistState extends State<BarcodeScannerPicklist>
),
);
},
)
// body: Stack(
// fit: StackFit.expand,
// children: [
// MobileScanner(
// controller: _mobileScannerController,
// errorBuilder: (context, error, child) {
// return ScannerErrorWidget(error: error);
// },
// fit: boxFit,
// ),
// ...drawDetectedBarcodes(
// controller: _mobileScannerController,
// cameraPreviewSize: _mobileScannerController.value.size,
// fit: boxFit,
// ),
// ...drawDetectedBarcodes(
// controller: _mobileScannerController,
// cameraPreviewSize: _mobileScannerController.value.size,
// fit: boxFit,
// ),
// // barcodes: _mobileScannerController. value. _barcodes.value,
// // cameraPreviewSize: _mobileScannerController.value.size,
// // fit: boxFit,
// // ),
// CustomPaint(
// painter: BarcodeOverlay(
// barcodeCorners: [
// const Offset(0, 0),
// const Offset(50, 0),
// const Offset(50, 50),
// const Offset(0, 50)
// ],
// barcodeSize: Size(50, 50),
// boxFit: boxFit,
// cameraPreviewSize: _mobileScannerController.value.size,
// ),
// ),
// Crosshair(
// crosshairRectangle: _crosshairRectangle,
// scannerDisabled: _scannerDisabled.value,
// ),
// ],
// ),
,
),
),
);
}
... ...
//Some magic created by chatGPT
import 'package:flutter/material.dart';
bool isOffsetInsideShape(Offset point, List<Offset> shape) {
return _isPointInPolygon(shape, point);
}
bool _isPointInPolygon(List<Offset> polygon, Offset point) {
// Use the ray-casting algorithm for checking if a point is inside a polygon
bool isPointInPolygon(Offset point, List<Offset> polygon) {
int i;
int j = polygon.length - 1;
bool inside = false;
for (int i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
if ((polygon[i].dy > point.dy) != (polygon[j].dy > point.dy) &&
for (i = 0; i < polygon.length; j = i++) {
if (((polygon[i].dy > point.dy) != (polygon[j].dy > point.dy)) &&
(point.dx <
(polygon[j].dx - polygon[i].dx) *
(point.dy - polygon[i].dy) /
... ... @@ -21,111 +17,3 @@ bool _isPointInPolygon(List<Offset> polygon, Offset point) {
}
return inside;
}
// import 'package:flutter/material.dart';
//
// bool crosshairFullyFitsIntoShape(Rect rect, List<Offset> shape) {
// final List<Offset> rectCorners = [
// Offset(rect.left, rect.top),
// Offset(rect.right, rect.top),
// Offset(rect.right, rect.bottom),
// Offset(rect.left, rect.bottom),
// ];
//
// // Check if all rect corners are inside the shape
// for (final Offset corner in rectCorners) {
// if (!_isPointInPolygon(shape, corner)) {
// return false; // If any corner is outside, the rectangle doesn't fit fully
// }
// }
//
// return true; // All corners are inside the shape
// }
//
// bool _isPointInPolygon(List<Offset> polygon, Offset point) {
// // Use the ray-casting algorithm for checking if a point is inside a polygon
// bool inside = false;
// for (int i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
// if ((polygon[i].dy > point.dy) != (polygon[j].dy > point.dy) &&
// (point.dx <
// (polygon[j].dx - polygon[i].dx) *
// (point.dy - polygon[i].dy) /
// (polygon[j].dy - polygon[i].dy) +
// polygon[i].dx)) {
// inside = !inside;
// }
// }
// return inside;
// }
// // import 'package:flutter/material.dart';
// //
// // bool crosshairTouchesBarcode(Rect rect, List<Offset> shape) {
// // final List<Offset> rectCorners = [
// // Offset(rect.left, rect.top),
// // Offset(rect.right, rect.top),
// // Offset(rect.right, rect.bottom),
// // Offset(rect.left, rect.bottom),
// // ];
// // final List<Offset> edges = [shape[0], shape[1], shape[2], shape[3], shape[0]];
// //
// // // Check edge intersection
// // for (int i = 0; i < edges.length - 1; i++) {
// // for (int j = 0; j < rectCorners.length; j++) {
// // final int next = (j + 1) % rectCorners.length;
// // if (_checkIntersection(
// // edges[i],
// // edges[i + 1],
// // rectCorners[j],
// // rectCorners[next],
// // )) {
// // return true;
// // }
// // }
// // }
// //
// // // Check if any rect corner is inside the shape
// // for (final Offset corner in rectCorners) {
// // if (_isPointInPolygon(shape, corner)) {
// // return true;
// // }
// // }
// //
// // return false;
// // }
// //
// // bool _checkIntersection(Offset p1, Offset p2, Offset p3, Offset p4) {
// // // Calculate the intersection of two line segments
// // double s1X;
// // double s1Y;
// // double s2X;
// // double s2Y;
// // s1X = p2.dx - p1.dx;
// // s1Y = p2.dy - p1.dy;
// // s2X = p4.dx - p3.dx;
// // s2Y = p4.dy - p3.dy;
// //
// // double s;
// // double t;
// // s = (-s1Y * (p1.dx - p3.dx) + s1X * (p1.dy - p3.dy)) /
// // (-s2X * s1Y + s1X * s2Y);
// // t = (s2X * (p1.dy - p3.dy) - s2Y * (p1.dx - p3.dx)) /
// // (-s2X * s1Y + s1X * s2Y);
// //
// // return s >= 0 && s <= 1 && t >= 0 && t <= 1;
// // }
// //
// // bool _isPointInPolygon(List<Offset> polygon, Offset point) {
// // // Ray-casting algorithm for checking if a point is inside a polygon
// // bool inside = false;
// // for (int i = 0, j = polygon.length - 1; i < polygon.length; j = i++) {
// // if ((polygon[i].dy > point.dy) != (polygon[j].dy > point.dy) &&
// // (point.dx <
// // (polygon[j].dx - polygon[i].dx) *
// // (point.dy - polygon[i].dy) /
// // (polygon[j].dy - polygon[i].dy) +
// // polygon[i].dx)) {
// // inside = !inside;
// // }
// // }
// // return inside;
// // }
... ...
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
class BarcodeOverlay extends CustomPainter {
BarcodeOverlay({
required this.barcodeCorners,
required this.barcodeSize,
required this.boxFit,
required this.cameraPreviewSize,
});
final List<Offset> barcodeCorners;
final Size barcodeSize;
final BoxFit boxFit;
final Size cameraPreviewSize;
@override
void paint(Canvas canvas, Size size) {
if (barcodeCorners.isEmpty ||
barcodeSize.isEmpty ||
cameraPreviewSize.isEmpty) {
return;
}
final adjustedSize = applyBoxFit(boxFit, cameraPreviewSize, size);
double verticalPadding = size.height - adjustedSize.destination.height;
double horizontalPadding = size.width - adjustedSize.destination.width;
if (verticalPadding > 0) {
verticalPadding = verticalPadding / 2;
} else {
verticalPadding = 0;
}
if (horizontalPadding > 0) {
horizontalPadding = horizontalPadding / 2;
} else {
horizontalPadding = 0;
}
final double ratioWidth;
final double ratioHeight;
if (!kIsWeb && defaultTargetPlatform == TargetPlatform.iOS) {
ratioWidth = barcodeSize.width / adjustedSize.destination.width;
ratioHeight = barcodeSize.height / adjustedSize.destination.height;
} else {
ratioWidth = cameraPreviewSize.width / adjustedSize.destination.width;
ratioHeight = cameraPreviewSize.height / adjustedSize.destination.height;
}
final List<Offset> adjustedOffset = [
for (final offset in barcodeCorners)
Offset(
offset.dx / ratioWidth + horizontalPadding,
offset.dy / ratioHeight + verticalPadding,
),
];
final cutoutPath = Path()..addPolygon(adjustedOffset, true);
final backgroundPaint = Paint()
..color = Colors.red.withOpacity(1.0)
..style = PaintingStyle.fill
..blendMode = BlendMode.dstOut;
canvas.drawPath(cutoutPath, backgroundPaint);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return false;
}
}
import 'package:flutter/material.dart';
import 'package:mobile_scanner/mobile_scanner.dart';
import 'package:mobile_scanner_example/picklist/widgets/barcode_overlay.dart';
List<Widget> drawDetectedBarcodes({
required List<Barcode>? barcodes,
required Size cameraPreviewSize,
required BoxFit fit,
}) {
final barcodeWidgets = <Widget>[];
if (barcodes == null || barcodes.isEmpty) {
debugPrint('EMPTY!!!');
}
if (barcodes != null) {
for (final barcode in barcodes) {
barcodeWidgets.add(
CustomPaint(
painter: BarcodeOverlay(
barcodeCorners: barcode.corners,
barcodeSize: barcode.size,
boxFit: fit,
cameraPreviewSize: cameraPreviewSize,
),
),
);
debugPrint(
'barcodeCorners => ${barcode.corners.map((e) => 'x: ${e.dx}, y: ${e.dy} ')}, barcodeSize => width: ${barcode.size.width}, height: ${barcode.size.height}, cameraPreviewSize => width: ${cameraPreviewSize.width}, height: ${cameraPreviewSize.height} ',
);
}
debugPrint(barcodeWidgets.length.toString());
}
return barcodeWidgets;
}