ryuta46

imp: add zoomScaleState value notifier.

@@ -138,6 +138,7 @@ class MobileScanner( @@ -138,6 +138,7 @@ class MobileScanner(
138 torch: Boolean, 138 torch: Boolean,
139 detectionSpeed: DetectionSpeed, 139 detectionSpeed: DetectionSpeed,
140 torchStateCallback: TorchStateCallback, 140 torchStateCallback: TorchStateCallback,
  141 + zoomScaleStateCallback: ZoomScaleStateCallback,
141 mobileScannerStartedCallback: MobileScannerStartedCallback, 142 mobileScannerStartedCallback: MobileScannerStartedCallback,
142 detectionTimeout: Long 143 detectionTimeout: Long
143 ) { 144 ) {
@@ -201,6 +202,11 @@ class MobileScanner( @@ -201,6 +202,11 @@ class MobileScanner(
201 torchStateCallback(state) 202 torchStateCallback(state)
202 } 203 }
203 204
  205 + // Register the zoom scale listener
  206 + camera!!.cameraInfo.zoomState.observe(activity) { state ->
  207 + zoomScaleStateCallback(state.linearZoom.toDouble())
  208 + }
  209 +
204 210
205 // Enable torch if provided 211 // Enable torch if provided
206 camera!!.cameraControl.enableTorch(torch) 212 camera!!.cameraControl.enableTorch(torch)
@@ -6,4 +6,5 @@ typealias MobileScannerCallback = (barcodes: List<Map<String, Any?>>, image: Byt @@ -6,4 +6,5 @@ typealias MobileScannerCallback = (barcodes: List<Map<String, Any?>>, image: Byt
6 typealias AnalyzerCallback = (barcodes: List<Map<String, Any?>>?) -> Unit 6 typealias AnalyzerCallback = (barcodes: List<Map<String, Any?>>?) -> Unit
7 typealias MobileScannerErrorCallback = (error: String) -> Unit 7 typealias MobileScannerErrorCallback = (error: String) -> Unit
8 typealias TorchStateCallback = (state: Int) -> Unit 8 typealias TorchStateCallback = (state: Int) -> Unit
  9 +typealias ZoomScaleStateCallback = (zoomScale: Double) -> Unit
9 typealias MobileScannerStartedCallback = (parameters: MobileScannerStartParameters) -> Unit 10 typealias MobileScannerStartedCallback = (parameters: MobileScannerStartParameters) -> Unit
@@ -70,6 +70,11 @@ class MobileScannerHandler( @@ -70,6 +70,11 @@ class MobileScannerHandler(
70 barcodeHandler.publishEvent(mapOf("name" to "torchState", "data" to state)) 70 barcodeHandler.publishEvent(mapOf("name" to "torchState", "data" to state))
71 } 71 }
72 72
  73 + private val zoomScaleStateCallback: ZoomScaleStateCallback = {zoomScale: Double ->
  74 + barcodeHandler.publishEvent(mapOf("name" to "zoomScaleState", "data" to zoomScale))
  75 + }
  76 +
  77 +
73 init { 78 init {
74 methodChannel = MethodChannel(binaryMessenger, 79 methodChannel = MethodChannel(binaryMessenger,
75 "dev.steenbakker.mobile_scanner/scanner/method") 80 "dev.steenbakker.mobile_scanner/scanner/method")
@@ -152,7 +157,7 @@ class MobileScannerHandler( @@ -152,7 +157,7 @@ class MobileScannerHandler(
152 val detectionSpeed: DetectionSpeed = DetectionSpeed.values().first { it.intValue == speed} 157 val detectionSpeed: DetectionSpeed = DetectionSpeed.values().first { it.intValue == speed}
153 158
154 try { 159 try {
155 - mobileScanner!!.start(barcodeScannerOptions, returnImage, position, torch, detectionSpeed, torchStateCallback, mobileScannerStartedCallback = { 160 + mobileScanner!!.start(barcodeScannerOptions, returnImage, position, torch, detectionSpeed, torchStateCallback, zoomScaleStateCallback, mobileScannerStartedCallback = {
156 result.success(mapOf( 161 result.success(mapOf(
157 "textureId" to it.id, 162 "textureId" to it.id,
158 "size" to mapOf("width" to it.width, "height" to it.height), 163 "size" to mapOf("width" to it.width, "height" to it.height),
@@ -13,6 +13,7 @@ import MLKitBarcodeScanning @@ -13,6 +13,7 @@ import MLKitBarcodeScanning
13 13
14 typealias MobileScannerCallback = ((Array<Barcode>?, Error?, UIImage) -> ()) 14 typealias MobileScannerCallback = ((Array<Barcode>?, Error?, UIImage) -> ())
15 typealias TorchModeChangeCallback = ((Int?) -> ()) 15 typealias TorchModeChangeCallback = ((Int?) -> ())
  16 +typealias ZoomScaleChangeCallback = ((Double?) -> ())
16 17
17 public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelegate, FlutterTexture { 18 public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelegate, FlutterTexture {
18 /// Capture session of the camera 19 /// Capture session of the camera
@@ -36,6 +37,10 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega @@ -36,6 +37,10 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega
36 /// When torch mode is changes, this callback will be called 37 /// When torch mode is changes, this callback will be called
37 let torchModeChangeCallback: TorchModeChangeCallback 38 let torchModeChangeCallback: TorchModeChangeCallback
38 39
  40 + /// When zoom scale is changes, this callback will be called
  41 + let zoomScaleChangeCallback: ZoomScaleChangeCallback
  42 +
  43 +
39 /// If provided, the Flutter registry will be used to send the output of the CaptureOutput to a Flutter texture. 44 /// If provided, the Flutter registry will be used to send the output of the CaptureOutput to a Flutter texture.
40 private let registry: FlutterTextureRegistry? 45 private let registry: FlutterTextureRegistry?
41 46
@@ -47,10 +52,11 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega @@ -47,10 +52,11 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega
47 52
48 var detectionSpeed: DetectionSpeed = DetectionSpeed.noDuplicates 53 var detectionSpeed: DetectionSpeed = DetectionSpeed.noDuplicates
49 54
50 - init(registry: FlutterTextureRegistry?, mobileScannerCallback: @escaping MobileScannerCallback, torchModeChangeCallback: @escaping TorchModeChangeCallback) { 55 + init(registry: FlutterTextureRegistry?, mobileScannerCallback: @escaping MobileScannerCallback, torchModeChangeCallback: @escaping TorchModeChangeCallback, zoomScaleChangeCallback: @escaping ZoomScaleChangeCallback) {
51 self.registry = registry 56 self.registry = registry
52 self.mobileScannerCallback = mobileScannerCallback 57 self.mobileScannerCallback = mobileScannerCallback
53 self.torchModeChangeCallback = torchModeChangeCallback 58 self.torchModeChangeCallback = torchModeChangeCallback
  59 + self.zoomScaleChangeCallback = zoomScaleChangeCallback
54 super.init() 60 super.init()
55 } 61 }
56 62
@@ -133,6 +139,7 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega @@ -133,6 +139,7 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega
133 } 139 }
134 140
135 device.addObserver(self, forKeyPath: #keyPath(AVCaptureDevice.torchMode), options: .new, context: nil) 141 device.addObserver(self, forKeyPath: #keyPath(AVCaptureDevice.torchMode), options: .new, context: nil)
  142 + device.addObserver(self, forKeyPath: #keyPath(AVCaptureDevice.videoZoomFactor), options: .new, context: nil)
136 do { 143 do {
137 try device.lockForConfiguration() 144 try device.lockForConfiguration()
138 if device.isFocusModeSupported(.continuousAutoFocus) { 145 if device.isFocusModeSupported(.continuousAutoFocus) {
@@ -199,6 +206,7 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega @@ -199,6 +206,7 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega
199 captureSession.removeOutput(output) 206 captureSession.removeOutput(output)
200 } 207 }
201 device.removeObserver(self, forKeyPath: #keyPath(AVCaptureDevice.torchMode)) 208 device.removeObserver(self, forKeyPath: #keyPath(AVCaptureDevice.torchMode))
  209 + device.removeObserver(self, forKeyPath: #keyPath(AVCaptureDevice.videoZoomFactor))
202 registry?.unregisterTexture(textureId) 210 registry?.unregisterTexture(textureId)
203 textureId = nil 211 textureId = nil
204 captureSession = nil 212 captureSession = nil
@@ -228,6 +236,10 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega @@ -228,6 +236,10 @@ public class MobileScanner: NSObject, AVCaptureVideoDataOutputSampleBufferDelega
228 // off = 0; on = 1; auto = 2; 236 // off = 0; on = 1; auto = 2;
229 let state = change?[.newKey] as? Int 237 let state = change?[.newKey] as? Int
230 torchModeChangeCallback(state) 238 torchModeChangeCallback(state)
  239 + case "videoZoomFactor":
  240 + let zoomFactor = change?[.newKey] as? CGFloat ?? 1
  241 + let zoomScale = (zoomFactor - 1) / 4
  242 + zoomScaleChangeCallback(Double(zoomScale))
231 default: 243 default:
232 break 244 break
233 } 245 }
@@ -57,6 +57,8 @@ public class SwiftMobileScannerPlugin: NSObject, FlutterPlugin { @@ -57,6 +57,8 @@ public class SwiftMobileScannerPlugin: NSObject, FlutterPlugin {
57 } 57 }
58 }, torchModeChangeCallback: { torchState in 58 }, torchModeChangeCallback: { torchState in
59 barcodeHandler.publishEvent(["name": "torchState", "data": torchState]) 59 barcodeHandler.publishEvent(["name": "torchState", "data": torchState])
  60 + }, zoomScaleChangeCallback: { zoomScale in
  61 + barcodeHandler.publishEvent(["name": "zoomScaleState", "data": zoomScale])
60 }) 62 })
61 self.barcodeHandler = barcodeHandler 63 self.barcodeHandler = barcodeHandler
62 super.init() 64 super.init()
@@ -85,6 +85,10 @@ class MobileScannerController { @@ -85,6 +85,10 @@ class MobileScannerController {
85 late final ValueNotifier<CameraFacing> cameraFacingState = 85 late final ValueNotifier<CameraFacing> cameraFacingState =
86 ValueNotifier(facing); 86 ValueNotifier(facing);
87 87
  88 + /// A notifier that provides zoomScale.
  89 + final ValueNotifier<double> zoomScaleState = ValueNotifier(0.0);
  90 +
  91 +
88 bool isStarting = false; 92 bool isStarting = false;
89 93
90 /// A notifier that provides availability of the Torch (Flash) 94 /// A notifier that provides availability of the Torch (Flash)
@@ -337,6 +341,9 @@ class MobileScannerController { @@ -337,6 +341,9 @@ class MobileScannerController {
337 final state = TorchState.values[data as int? ?? 0]; 341 final state = TorchState.values[data as int? ?? 0];
338 torchState.value = state; 342 torchState.value = state;
339 break; 343 break;
  344 + case 'zoomScaleState':
  345 + zoomScaleState.value = data as double? ?? 0.0;
  346 + break;
340 case 'barcode': 347 case 'barcode':
341 if (data == null) return; 348 if (data == null) return;
342 final parsed = (data as List) 349 final parsed = (data as List)