178 lines
4.7 KiB
Dart
178 lines
4.7 KiB
Dart
|
import 'package:flutter/material.dart';
|
||
|
import 'package:image_picker/image_picker.dart';
|
||
|
import 'package:mobile_scanner/mobile_scanner.dart';
|
||
|
|
||
|
class AnalyzeImageFromGalleryButton extends StatelessWidget {
|
||
|
const AnalyzeImageFromGalleryButton({required this.controller, super.key});
|
||
|
|
||
|
final MobileScannerController controller;
|
||
|
|
||
|
@override
|
||
|
Widget build(BuildContext context) {
|
||
|
return IconButton(
|
||
|
color: Colors.white,
|
||
|
icon: const Icon(Icons.image),
|
||
|
iconSize: 32.0,
|
||
|
onPressed: () async {
|
||
|
final ImagePicker picker = ImagePicker();
|
||
|
|
||
|
final XFile? image = await picker.pickImage(
|
||
|
source: ImageSource.gallery,
|
||
|
);
|
||
|
|
||
|
if (image == null) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
final BarcodeCapture? barcodes = await controller.analyzeImage(
|
||
|
image.path,
|
||
|
);
|
||
|
|
||
|
if (!context.mounted) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
final SnackBar snackbar = barcodes != null
|
||
|
? const SnackBar(
|
||
|
content: Text('Barcode found!'),
|
||
|
backgroundColor: Colors.green,
|
||
|
)
|
||
|
: const SnackBar(
|
||
|
content: Text('No barcode found!'),
|
||
|
backgroundColor: Colors.red,
|
||
|
);
|
||
|
|
||
|
ScaffoldMessenger.of(context).showSnackBar(snackbar);
|
||
|
},
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
class StartStopMobileScannerButton extends StatelessWidget {
|
||
|
const StartStopMobileScannerButton({required this.controller, super.key});
|
||
|
|
||
|
final MobileScannerController controller;
|
||
|
|
||
|
@override
|
||
|
Widget build(BuildContext context) {
|
||
|
return ValueListenableBuilder(
|
||
|
valueListenable: controller,
|
||
|
builder: (context, state, child) {
|
||
|
if (!state.isInitialized || !state.isRunning) {
|
||
|
return IconButton(
|
||
|
color: Colors.white,
|
||
|
icon: const Icon(Icons.play_arrow),
|
||
|
iconSize: 32.0,
|
||
|
onPressed: () async {
|
||
|
await controller.start();
|
||
|
},
|
||
|
);
|
||
|
}
|
||
|
|
||
|
return IconButton(
|
||
|
color: Colors.white,
|
||
|
icon: const Icon(Icons.stop),
|
||
|
iconSize: 32.0,
|
||
|
onPressed: () async {
|
||
|
await controller.stop();
|
||
|
},
|
||
|
);
|
||
|
},
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
class SwitchCameraButton extends StatelessWidget {
|
||
|
const SwitchCameraButton({required this.controller, super.key});
|
||
|
|
||
|
final MobileScannerController controller;
|
||
|
|
||
|
@override
|
||
|
Widget build(BuildContext context) {
|
||
|
return ValueListenableBuilder(
|
||
|
valueListenable: controller,
|
||
|
builder: (context, state, child) {
|
||
|
if (!state.isInitialized || !state.isRunning) {
|
||
|
return const SizedBox.shrink();
|
||
|
}
|
||
|
|
||
|
final int? availableCameras = state.availableCameras;
|
||
|
|
||
|
if (availableCameras != null && availableCameras < 2) {
|
||
|
return const SizedBox.shrink();
|
||
|
}
|
||
|
|
||
|
final Widget icon;
|
||
|
|
||
|
switch (state.cameraDirection) {
|
||
|
case CameraFacing.front:
|
||
|
icon = const Icon(Icons.camera_front);
|
||
|
case CameraFacing.back:
|
||
|
icon = const Icon(Icons.camera_rear);
|
||
|
}
|
||
|
|
||
|
return IconButton(
|
||
|
iconSize: 32.0,
|
||
|
icon: icon,
|
||
|
onPressed: () async {
|
||
|
await controller.switchCamera();
|
||
|
},
|
||
|
);
|
||
|
},
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
class ToggleFlashlightButton extends StatelessWidget {
|
||
|
const ToggleFlashlightButton({required this.controller, super.key});
|
||
|
|
||
|
final MobileScannerController controller;
|
||
|
|
||
|
@override
|
||
|
Widget build(BuildContext context) {
|
||
|
return ValueListenableBuilder(
|
||
|
valueListenable: controller,
|
||
|
builder: (context, state, child) {
|
||
|
if (!state.isInitialized || !state.isRunning) {
|
||
|
return const SizedBox.shrink();
|
||
|
}
|
||
|
|
||
|
switch (state.torchState) {
|
||
|
case TorchState.auto:
|
||
|
return IconButton(
|
||
|
color: Colors.white,
|
||
|
iconSize: 32.0,
|
||
|
icon: const Icon(Icons.flash_auto),
|
||
|
onPressed: () async {
|
||
|
await controller.toggleTorch();
|
||
|
},
|
||
|
);
|
||
|
case TorchState.off:
|
||
|
return IconButton(
|
||
|
color: Colors.white,
|
||
|
iconSize: 32.0,
|
||
|
icon: const Icon(Icons.flash_off),
|
||
|
onPressed: () async {
|
||
|
await controller.toggleTorch();
|
||
|
},
|
||
|
);
|
||
|
case TorchState.on:
|
||
|
return IconButton(
|
||
|
color: Colors.white,
|
||
|
iconSize: 32.0,
|
||
|
icon: const Icon(Icons.flash_on),
|
||
|
onPressed: () async {
|
||
|
await controller.toggleTorch();
|
||
|
},
|
||
|
);
|
||
|
case TorchState.unavailable:
|
||
|
return const Icon(
|
||
|
Icons.no_flash,
|
||
|
color: Colors.grey,
|
||
|
);
|
||
|
}
|
||
|
},
|
||
|
);
|
||
|
}
|
||
|
}
|