@@ -11,6 +11,9 @@ import 'error_builder.dart';
1111import 'gallery_button.dart' ;
1212import 'overlay.dart' ;
1313
14+ /// The set of quick action controls that can be shown alongside the scanner.
15+ enum ScannerAction { cameraSwitch, torch, gallery }
16+
1417/// The main barcode scanner widget.
1518class AiBarcodeScanner extends StatefulWidget {
1619 /// Defines how the camera preview will be fitted into the layout.
@@ -115,6 +118,9 @@ class AiBarcodeScanner extends StatefulWidget {
115118 /// Custom icon for the flashlight when off
116119 final IconData flashOffIcon;
117120
121+ /// Controls which quick action icons (camera switch, torch, gallery) are displayed.
122+ final Set <ScannerAction > enabledActionButtons;
123+
118124 /// Whether to return the raw image data (Uint8List) along with the BarcodeCapture.
119125 /// This can be useful for post-scan image processing such as color analysis or saving the frame.
120126 /// Defaults to `false` .
@@ -161,6 +167,11 @@ class AiBarcodeScanner extends StatefulWidget {
161167 this .cameraSwitchIcon = CupertinoIcons .arrow_2_circlepath,
162168 this .flashOnIcon = CupertinoIcons .bolt_fill,
163169 this .flashOffIcon = CupertinoIcons .bolt,
170+ this .enabledActionButtons = const {
171+ ScannerAction .gallery,
172+ ScannerAction .cameraSwitch,
173+ ScannerAction .torch,
174+ },
164175 this .returnImage = false ,
165176 this .onCustomImagePicker,
166177 this .child,
@@ -261,49 +272,27 @@ class _AiBarcodeScannerState extends State<AiBarcodeScanner> {
261272
262273 /// default action icons
263274 /// camera switch and torch for easier access
264- final actionIcons = [
265- IconButton .filled (
266- style: IconButton .styleFrom (
267- backgroundColor: CupertinoColors .systemGrey6,
268- foregroundColor: CupertinoColors .darkBackgroundGray,
269- ),
270- icon: Icon (widget.cameraSwitchIcon),
271- onPressed: () async {
272- await _controller.switchCamera ();
273- setState (() {});
274- },
275- ),
276- IconButton .filled (
277- style: IconButton .styleFrom (
278- backgroundColor: isTorchOn
279- ? CupertinoColors .activeOrange
280- : CupertinoColors .systemGrey6,
281- foregroundColor: CupertinoColors .darkBackgroundGray,
282- ),
283- icon: Icon (isTorchOn ? widget.flashOnIcon : widget.flashOffIcon),
284- onPressed: () async {
285- await _controller.toggleTorch ();
286- setState (() {});
287- },
288- )
289- ];
275+ final actionButtons = _buildActionButtons (isTorchOn);
276+ final showGalleryAction =
277+ widget.enabledActionButtons.contains (ScannerAction .gallery);
290278
291279 return Scaffold (
292280 appBar: widget.appBarBuilder? .call (context, _controller) ??
293281 AppBar (
294282 backgroundColor: Colors .transparent,
295283 actions: [
296284 if (widget.galleryButtonType == GalleryButtonType .icon) ...[
297- GalleryButton .icon (
298- onImagePick: widget.onImagePick,
299- onDetect: widget.onDetect,
300- validator: widget.validator,
301- controller: _controller,
302- isSuccess: _isSuccess,
303- text: widget.galleryButtonText,
304- onCustomImagePicker: widget.onCustomImagePicker,
305- ),
306- ...actionIcons,
285+ if (showGalleryAction)
286+ GalleryButton .icon (
287+ onImagePick: widget.onImagePick,
288+ onDetect: widget.onDetect,
289+ validator: widget.validator,
290+ controller: _controller,
291+ isSuccess: _isSuccess,
292+ text: widget.galleryButtonText,
293+ onCustomImagePicker: widget.onCustomImagePicker,
294+ ),
295+ ...actionButtons,
307296 ],
308297 ...? widget.actions,
309298 ],
@@ -363,7 +352,8 @@ class _AiBarcodeScannerState extends State<AiBarcodeScanner> {
363352 useAppLifecycleState: widget.useAppLifecycleState,
364353 ),
365354 widget.child ??
366- (widget.galleryButtonType == GalleryButtonType .filled
355+ (widget.galleryButtonType == GalleryButtonType .filled &&
356+ (showGalleryAction || actionButtons.isNotEmpty)
367357 ? Align (
368358 alignment: widget.galleryButtonAlignment ??
369359 Alignment .lerp (
@@ -375,18 +365,20 @@ class _AiBarcodeScannerState extends State<AiBarcodeScanner> {
375365 mainAxisAlignment: MainAxisAlignment .center,
376366 mainAxisSize: MainAxisSize .min,
377367 children: [
378- GalleryButton (
379- onImagePick: widget.onImagePick,
380- onDetect: widget.onDetect,
381- validator: widget.validator,
382- controller: _controller,
383- isSuccess: _isSuccess,
384- text: widget.galleryButtonText,
385- icon: widget.galleryIcon,
386- onCustomImagePicker: widget.onCustomImagePicker,
387- ),
388- const SizedBox (width: 4 ),
389- ...actionIcons,
368+ if (showGalleryAction)
369+ GalleryButton (
370+ onImagePick: widget.onImagePick,
371+ onDetect: widget.onDetect,
372+ validator: widget.validator,
373+ controller: _controller,
374+ isSuccess: _isSuccess,
375+ text: widget.galleryButtonText,
376+ icon: widget.galleryIcon,
377+ onCustomImagePicker: widget.onCustomImagePicker,
378+ ),
379+ if (showGalleryAction && actionButtons.isNotEmpty)
380+ const SizedBox (width: 4 ),
381+ ...actionButtons,
390382 ],
391383 ),
392384 )
@@ -433,4 +425,45 @@ class _AiBarcodeScannerState extends State<AiBarcodeScanner> {
433425 }
434426 });
435427 }
428+
429+ List <Widget > _buildActionButtons (bool isTorchOn) {
430+ final actions = widget.enabledActionButtons;
431+ final icons = < Widget > [];
432+
433+ if (actions.contains (ScannerAction .cameraSwitch)) {
434+ icons.add (
435+ IconButton .filled (
436+ style: IconButton .styleFrom (
437+ backgroundColor: CupertinoColors .systemGrey6,
438+ foregroundColor: CupertinoColors .darkBackgroundGray,
439+ ),
440+ icon: Icon (widget.cameraSwitchIcon),
441+ onPressed: () async {
442+ await _controller.switchCamera ();
443+ setState (() {});
444+ },
445+ ),
446+ );
447+ }
448+
449+ if (actions.contains (ScannerAction .torch)) {
450+ icons.add (
451+ IconButton .filled (
452+ style: IconButton .styleFrom (
453+ backgroundColor: isTorchOn
454+ ? CupertinoColors .activeOrange
455+ : CupertinoColors .systemGrey6,
456+ foregroundColor: CupertinoColors .darkBackgroundGray,
457+ ),
458+ icon: Icon (isTorchOn ? widget.flashOnIcon : widget.flashOffIcon),
459+ onPressed: () async {
460+ await _controller.toggleTorch ();
461+ setState (() {});
462+ },
463+ ),
464+ );
465+ }
466+
467+ return icons;
468+ }
436469}
0 commit comments