Restore pinch to zoom gesture in in-app camera.
This commit is contained in:
parent
ba70101efd
commit
9f47a41017
1 changed files with 38 additions and 7 deletions
|
@ -9,8 +9,10 @@ import android.Manifest
|
|||
import android.content.Context
|
||||
import android.util.Size
|
||||
import android.view.MotionEvent
|
||||
import android.view.ScaleGestureDetector
|
||||
import android.view.Surface
|
||||
import android.view.View
|
||||
import android.view.ViewConfiguration
|
||||
import androidx.annotation.MainThread
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.annotation.RequiresPermission
|
||||
|
@ -53,6 +55,8 @@ import org.thoughtcrime.securesms.util.TextSecurePreferences
|
|||
import org.thoughtcrime.securesms.util.ViewUtil
|
||||
import org.thoughtcrime.securesms.util.visible
|
||||
import java.util.concurrent.Executor
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
|
||||
/**
|
||||
* This is a class to manage the camera resource, and relies on the AndroidX CameraX library.
|
||||
|
@ -81,6 +85,7 @@ class SignalCameraController(
|
|||
private val imageMode = CameraXUtil.getOptimalCaptureMode()
|
||||
|
||||
private val cameraProviderFuture: ListenableFuture<ProcessCameraProvider> = ProcessCameraProvider.getInstance(context)
|
||||
private val scaleGestureDetector = ScaleGestureDetector(context, PinchToZoomGestureListener())
|
||||
private val viewPort: ViewPort? = previewView.getViewPort(Surface.ROTATION_0)
|
||||
private val initializationCompleteListeners: MutableSet<InitializationListener> = mutableSetOf()
|
||||
private val customUseCases: MutableList<UseCase> = mutableListOf()
|
||||
|
@ -137,7 +142,7 @@ class SignalCameraController(
|
|||
buildUseCaseGroup()
|
||||
)
|
||||
|
||||
initializeTapToFocus(camera)
|
||||
initializeTapToFocusAndPinchToZoom(camera)
|
||||
this.cameraProperty = camera
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Use case binding failed", e)
|
||||
|
@ -394,18 +399,18 @@ class SignalCameraController(
|
|||
}.build()
|
||||
|
||||
@MainThread
|
||||
private fun initializeTapToFocus(camera: Camera) {
|
||||
private fun initializeTapToFocusAndPinchToZoom(camera: Camera) {
|
||||
ThreadUtil.assertMainThread()
|
||||
previewView.setOnTouchListener { v: View?, event: MotionEvent ->
|
||||
if (event.action == MotionEvent.ACTION_DOWN) {
|
||||
return@setOnTouchListener true
|
||||
}
|
||||
if (event.action == MotionEvent.ACTION_UP) {
|
||||
val isSingleTouch = event.pointerCount == 1
|
||||
val isUpEvent = event.action == MotionEvent.ACTION_UP
|
||||
val notALongPress = (event.eventTime - event.downTime < ViewConfiguration.getLongPressTimeout())
|
||||
if (isSingleTouch && isUpEvent && notALongPress) {
|
||||
focusAndMeterOnPoint(camera, event.x, event.y)
|
||||
v?.performClick()
|
||||
return@setOnTouchListener true
|
||||
}
|
||||
false
|
||||
return@setOnTouchListener scaleGestureDetector.onTouchEvent(event)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -448,6 +453,21 @@ class SignalCameraController(
|
|||
)
|
||||
}
|
||||
|
||||
@MainThread
|
||||
private fun onPinchToZoom(pinchToZoomScale: Float) {
|
||||
val zoomState = getZoomState().getValue() ?: return
|
||||
var clampedRatio: Float = zoomState.zoomRatio * if (pinchToZoomScale > 1f) {
|
||||
1.0f + (pinchToZoomScale - 1.0f) * 2
|
||||
} else {
|
||||
1.0f - (1.0f - pinchToZoomScale) * 2
|
||||
}
|
||||
clampedRatio = min(
|
||||
max(clampedRatio.toDouble(), zoomState.minZoomRatio.toDouble()),
|
||||
zoomState.maxZoomRatio.toDouble()
|
||||
).toFloat()
|
||||
setZoomRatio(clampedRatio)
|
||||
}
|
||||
|
||||
private fun isRecording(): Boolean {
|
||||
return recording != null
|
||||
}
|
||||
|
@ -472,6 +492,17 @@ class SignalCameraController(
|
|||
return Size(this.height, this.width)
|
||||
}
|
||||
|
||||
inner class PinchToZoomGestureListener : ScaleGestureDetector.OnScaleGestureListener {
|
||||
override fun onScale(detector: ScaleGestureDetector): Boolean {
|
||||
onPinchToZoom(detector.scaleFactor)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onScaleBegin(detector: ScaleGestureDetector): Boolean = true
|
||||
|
||||
override fun onScaleEnd(detector: ScaleGestureDetector) = Unit
|
||||
}
|
||||
|
||||
interface InitializationListener {
|
||||
fun onInitialized(cameraProvider: ProcessCameraProvider)
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue