Navaron Bracke
Committed by GitHub

Merge pull request #977 from navaronbracke/cherry-pick_scan_window_fix

fix: port scan window update fix to the new beta release
  1 +## NEXT
  2 +
  3 +Bugs fixed:
  4 +* Fixed an issue where the scan window was not updated when its size was changed. (thanks @navaronbracke !)
  5 +
1 ## 5.0.0-beta.1 6 ## 5.0.0-beta.1
2 7
3 **BREAKING CHANGES:** 8 **BREAKING CHANGES:**
@@ -24,6 +24,7 @@ class MobileScanner extends StatefulWidget { @@ -24,6 +24,7 @@ class MobileScanner extends StatefulWidget {
24 this.overlayBuilder, 24 this.overlayBuilder,
25 this.placeholderBuilder, 25 this.placeholderBuilder,
26 this.scanWindow, 26 this.scanWindow,
  27 + this.scanWindowUpdateThreshold = 0.0,
27 super.key, 28 super.key,
28 }); 29 });
29 30
@@ -94,6 +95,19 @@ class MobileScanner extends StatefulWidget { @@ -94,6 +95,19 @@ class MobileScanner extends StatefulWidget {
94 /// ``` 95 /// ```
95 final Rect? scanWindow; 96 final Rect? scanWindow;
96 97
  98 + /// The threshold for updates to the [scanWindow].
  99 + ///
  100 + /// If the [scanWindow] would be updated,
  101 + /// due to new layout constraints for the scanner,
  102 + /// and the width or height of the new scan window have not changed by this threshold,
  103 + /// then the scan window is not updated.
  104 + ///
  105 + /// It is recommended to set this threshold
  106 + /// if scan window updates cause performance issues.
  107 + ///
  108 + /// Defaults to no threshold for scan window updates.
  109 + final double scanWindowUpdateThreshold;
  110 +
97 @override 111 @override
98 State<MobileScanner> createState() => _MobileScannerState(); 112 State<MobileScanner> createState() => _MobileScannerState();
99 } 113 }
@@ -109,13 +123,49 @@ class _MobileScannerState extends State<MobileScanner> { @@ -109,13 +123,49 @@ class _MobileScannerState extends State<MobileScanner> {
109 MobileScannerState scannerState, 123 MobileScannerState scannerState,
110 BoxConstraints constraints, 124 BoxConstraints constraints,
111 ) { 125 ) {
112 - if (widget.scanWindow != null && scanWindow == null) {  
113 - scanWindow = calculateScanWindowRelativeToTextureInPercentage(  
114 - widget.fit,  
115 - widget.scanWindow!,  
116 - textureSize: scannerState.size,  
117 - widgetSize: constraints.biggest,  
118 - ); 126 + if (widget.scanWindow == null) {
  127 + return;
  128 + }
  129 +
  130 + final Rect newScanWindow = calculateScanWindowRelativeToTextureInPercentage(
  131 + widget.fit,
  132 + widget.scanWindow!,
  133 + textureSize: scannerState.size,
  134 + widgetSize: constraints.biggest,
  135 + );
  136 +
  137 + // The scan window was never set before.
  138 + // Set the initial scan window.
  139 + if (scanWindow == null) {
  140 + scanWindow = newScanWindow;
  141 +
  142 + unawaited(widget.controller.updateScanWindow(scanWindow));
  143 +
  144 + return;
  145 + }
  146 +
  147 + // The scan window did not not change.
  148 + // The left, right, top and bottom are the same.
  149 + if (scanWindow == newScanWindow) {
  150 + return;
  151 + }
  152 +
  153 + // The update threshold is not set, allow updating the scan window.
  154 + if (widget.scanWindowUpdateThreshold == 0.0) {
  155 + scanWindow = newScanWindow;
  156 +
  157 + unawaited(widget.controller.updateScanWindow(scanWindow));
  158 +
  159 + return;
  160 + }
  161 +
  162 + final double dx = (newScanWindow.width - scanWindow!.width).abs();
  163 + final double dy = (newScanWindow.height - scanWindow!.height).abs();
  164 +
  165 + // The new scan window has changed enough, allow updating the scan window.
  166 + if (dx >= widget.scanWindowUpdateThreshold ||
  167 + dy >= widget.scanWindowUpdateThreshold) {
  168 + scanWindow = newScanWindow;
119 169
120 unawaited(widget.controller.updateScanWindow(scanWindow)); 170 unawaited(widget.controller.updateScanWindow(scanWindow));
121 } 171 }