import 'package:flutter/material.dart'; import 'package:mobile_scanner/mobile_scanner.dart'; import 'package:inventory_system/screens/admin/scan/scan_result.dart'; import 'package:inventory_system/screens/title_bar.dart'; import 'package:inventory_system/screens/nav_bar.dart'; import 'package:inventory_system/screens/bottom_nav_bar.dart'; class ScanScreen extends StatefulWidget { const ScanScreen({super.key}); @override State createState() => _ScanScreenState(); } class _ScanScreenState extends State { int _selectedIndex = 1; bool _isProcessing = false; void _onDetect(BarcodeCapture capture) async { if (_isProcessing) return; final codes = capture.barcodes; if (codes.isEmpty) return; final value = codes.first.rawValue; if (value == null || value.isEmpty) return; _isProcessing = true; await Navigator.push( context, MaterialPageRoute( builder: (context) => ScanResultScreen(scannedCode: value.trim()), ), ); // brief debounce to avoid flood await Future.delayed(const Duration(milliseconds: 500)); _isProcessing = false; } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: const Color(0xFFF5F5F7), appBar: const TitleBar(title: 'Scan Item'), drawer: const NavBar(isAdmin: true, selectedScreen: AppScreen.item), body: Stack( fit: StackFit.expand, children: [ // 1. Add Padding around the camera view Padding( padding: const EdgeInsets.all(38.38), // Adjust the padding as you need child: ClipRRect( // 2. (Optional) Add rounded corners to the camera view borderRadius: BorderRadius.circular(24.0), child: MobileScanner( fit: BoxFit.cover, // Use BoxFit.cover for a better aspect ratio onDetect: _onDetect, ), ), ), _ScannerOverlay(), Positioned( bottom: 16, left: 0, right: 0, child: Text( 'Place the code inside the frame', textAlign: TextAlign.center, style: TextStyle( color: Colors.white, fontSize: 16, fontWeight: FontWeight.bold, shadows: [ Shadow( blurRadius: 10.0, color: Colors.black.withOpacity(0.5), offset: const Offset(0, 0), ), ], ), ), ), ], ), bottomNavigationBar: BottomNavBar( selectedIndex: _selectedIndex, onItemTapped: (index) { setState(() => _selectedIndex = index); if (index == 0) { Navigator.pop(context); } }, ), ); } } class _ScannerOverlay extends StatelessWidget { @override Widget build(BuildContext context) { return IgnorePointer( child: CustomPaint( painter: _OverlayPainter(), size: Size.infinite, ), ); } } class _OverlayPainter extends CustomPainter { @override void paint(Canvas canvas, Size size) { final paint = Paint() ..color = Colors.white ..style = PaintingStyle.stroke ..strokeWidth = 3; final double padding = 48; final rect = RRect.fromRectAndRadius( Rect.fromLTWH(padding, padding, size.width - padding * 2, size.height - padding * 2), const Radius.circular(12), ); final bg = Paint()..color = Colors.black.withOpacity(0.5); final clearPaint = Paint()..blendMode = BlendMode.clear; final path = Path()..addRRect(rect); canvas.saveLayer(Offset.zero & size, Paint()); canvas.drawRect(Offset.zero & size, bg); canvas.drawPath(path, clearPaint); canvas.restore(); canvas.drawRRect(rect, paint); } @override bool shouldRepaint(covariant CustomPainter oldDelegate) => false; }