From 052ee9c7e5d60ab2e5418d6cd0a1953356030f4c Mon Sep 17 00:00:00 2001 From: dankito Date: Fri, 4 Oct 2024 07:29:51 +0200 Subject: [PATCH] Implemented pinch to zoom for reading EPC QR Codes --- .../ui/service/QrCodeService.android.kt | 34 +++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/composeApp/src/androidMain/kotlin/net/codinux/banking/ui/service/QrCodeService.android.kt b/composeApp/src/androidMain/kotlin/net/codinux/banking/ui/service/QrCodeService.android.kt index 9982a4c..be0d0fe 100644 --- a/composeApp/src/androidMain/kotlin/net/codinux/banking/ui/service/QrCodeService.android.kt +++ b/composeApp/src/androidMain/kotlin/net/codinux/banking/ui/service/QrCodeService.android.kt @@ -1,6 +1,7 @@ package net.codinux.banking.ui.service import android.Manifest +import android.view.ScaleGestureDetector import androidx.camera.core.* import androidx.camera.lifecycle.ProcessCameraProvider import androidx.camera.view.PreviewView @@ -50,7 +51,6 @@ actual object QrCodeService { AndroidView(factory = { previewView }, modifier = Modifier.fillMaxSize()) } - @Composable private fun setupCameraView(previewView: PreviewView, mainActivity: MainActivity, resultCallback: (QrCodeReadResult) -> Unit) { val cameraProviderFuture = ProcessCameraProvider.getInstance(mainActivity) @@ -79,8 +79,9 @@ actual object QrCodeService { cameraProvider.unbindAll() // Bind use cases to camera - cameraProvider.bindToLifecycle(mainActivity, cameraSelector, preview, imageAnalyzer) + val camera = cameraProvider.bindToLifecycle(mainActivity, cameraSelector, preview, imageAnalyzer) + configureCameraControl(camera, previewView, mainActivity) } catch (e: Exception) { log.error(e) { "Use case binding failed" } } @@ -88,6 +89,35 @@ actual object QrCodeService { }, ContextCompat.getMainExecutor(mainActivity)) } + private fun configureCameraControl( + camera: Camera, + previewView: PreviewView, + mainActivity: MainActivity + ) { + // Listen to pinch gestures + val listener = object : ScaleGestureDetector.SimpleOnScaleGestureListener() { + override fun onScale(detector: ScaleGestureDetector): Boolean { + // Get the camera's current zoom ratio + val currentZoomRatio = camera.cameraInfo.zoomState.value?.zoomRatio ?: 0F + + // Get the pinch gesture's scaling factor + val delta = detector.scaleFactor + + // Update the camera's zoom ratio. This is an asynchronous operation that returns + // a ListenableFuture, allowing you to listen to when the operation completes. + camera.cameraControl.setZoomRatio(currentZoomRatio * delta) + + return true // Return true, as the event was handled + } + } + val scaleGestureDetector = ScaleGestureDetector(mainActivity, listener) + + previewView.setOnTouchListener { _, event -> + scaleGestureDetector.onTouchEvent(event) + true + } + } + }