diff --git a/photoeditor/src/main/java/com/automattic/photoeditor/PhotoEditor.kt b/photoeditor/src/main/java/com/automattic/photoeditor/PhotoEditor.kt index c09f8cd06..7d55c6fda 100644 --- a/photoeditor/src/main/java/com/automattic/photoeditor/PhotoEditor.kt +++ b/photoeditor/src/main/java/com/automattic/photoeditor/PhotoEditor.kt @@ -339,7 +339,6 @@ class PhotoEditor private constructor(builder: Builder) : }) } - // TODO: will uncomment and remove TextViewSizeAwareTouchListener class accordingly in a later PR // val multiTouchListenerInstance = newMultiTouchListener // multiTouchListenerInstance.setOnGestureControl(object : MultiTouchListener.OnGestureControl { // override fun onClick() { diff --git a/photoeditor/src/main/java/com/automattic/photoeditor/gesture/RotationGestureDetector.kt b/photoeditor/src/main/java/com/automattic/photoeditor/gesture/RotationGestureDetector.kt new file mode 100644 index 000000000..52bae4bb1 --- /dev/null +++ b/photoeditor/src/main/java/com/automattic/photoeditor/gesture/RotationGestureDetector.kt @@ -0,0 +1,80 @@ +package com.automattic.photoeditor.gesture + +import android.view.MotionEvent +import android.view.View + +class RotationGestureDetector(private val mListener: OnRotationGestureListener?) { + private var fX: Float = 0.toFloat() + private var fY: Float = 0.toFloat() + private var sX: Float = 0.toFloat() + private var sY: Float = 0.toFloat() + private var ptrID1: Int = 0 + private var ptrID2: Int = 0 + var angle: Float = 0.toFloat() + private set + + init { + ptrID1 = INVALID_POINTER_ID + ptrID2 = INVALID_POINTER_ID + } + + fun onTouchEvent(view: View, event: MotionEvent): Boolean { + when (event.actionMasked) { + MotionEvent.ACTION_DOWN -> ptrID1 = event.getPointerId(event.actionIndex) + MotionEvent.ACTION_POINTER_DOWN -> { + ptrID2 = event.getPointerId(event.actionIndex) + sX = event.getX(event.findPointerIndex(ptrID1)) + sY = event.getY(event.findPointerIndex(ptrID1)) + fX = event.getX(event.findPointerIndex(ptrID2)) + fY = event.getY(event.findPointerIndex(ptrID2)) + } + MotionEvent.ACTION_MOVE -> if (ptrID1 != INVALID_POINTER_ID && ptrID2 != INVALID_POINTER_ID) { + val nfX: Float + val nfY: Float + val nsX: Float + val nsY: Float + nsX = event.getX(event.findPointerIndex(ptrID1)) + nsY = event.getY(event.findPointerIndex(ptrID1)) + nfX = event.getX(event.findPointerIndex(ptrID2)) + nfY = event.getY(event.findPointerIndex(ptrID2)) + + angle = angleBetweenLines(fX, fY, sX, sY, nfX, nfY, nsX, nsY) + mListener?.onRotation(view, angle) + } + MotionEvent.ACTION_UP -> ptrID1 = INVALID_POINTER_ID + MotionEvent.ACTION_POINTER_UP -> ptrID2 = INVALID_POINTER_ID + MotionEvent.ACTION_CANCEL -> { + ptrID1 = INVALID_POINTER_ID + ptrID2 = INVALID_POINTER_ID + } + } + return true + } + + private fun angleBetweenLines( + fX: Float, + fY: Float, + sX: Float, + sY: Float, + nfX: Float, + nfY: Float, + nsX: Float, + nsY: Float + ): Float { + val angle1 = Math.atan2((fY - sY).toDouble(), (fX - sX).toDouble()).toFloat() + val angle2 = Math.atan2((nfY - nsY).toDouble(), (nfX - nsX).toDouble()).toFloat() + + var angle = Math.toDegrees((angle1 - angle2).toDouble()).toFloat() % 360 + if (angle < -180f) angle += 360.0f + if (angle > 180f) angle -= 360.0f + return angle + } + + interface OnRotationGestureListener { + fun onRotation(view: View, angle: Float) + } + + companion object { + private val INVALID_POINTER_ID = -1 + } +} diff --git a/photoeditor/src/main/java/com/automattic/photoeditor/gesture/TextViewSizeAwareTouchListener.kt b/photoeditor/src/main/java/com/automattic/photoeditor/gesture/TextViewSizeAwareTouchListener.kt index 5efb538e2..5737da173 100644 --- a/photoeditor/src/main/java/com/automattic/photoeditor/gesture/TextViewSizeAwareTouchListener.kt +++ b/photoeditor/src/main/java/com/automattic/photoeditor/gesture/TextViewSizeAwareTouchListener.kt @@ -3,8 +3,10 @@ package com.automattic.photoeditor.gesture import android.annotation.SuppressLint import android.view.MotionEvent import android.view.View +import com.automattic.photoeditor.gesture.RotationGestureDetector.OnRotationGestureListener -class TextViewSizeAwareTouchListener(val minWidth: Int, val minHeight: Int) : View.OnTouchListener { +class TextViewSizeAwareTouchListener(val minWidth: Int, val minHeight: Int) : View.OnTouchListener, + OnRotationGestureListener { private var originX = 0f private var originY = 0f private var secondOriginX = 0f @@ -14,9 +16,19 @@ class TextViewSizeAwareTouchListener(val minWidth: Int, val minHeight: Int) : Vi private var originUp = false private var secondOriginUp = false + private var rotationDetector: RotationGestureDetector + + init { + rotationDetector = RotationGestureDetector(this) + } + + override fun onRotation(view: View, angle: Float) { + view.rotation = angle + } @SuppressLint("ClickableViewAccessibility") override fun onTouch(view: View, event: MotionEvent): Boolean { + rotationDetector.onTouchEvent(view, event) event.offsetLocation(event.rawX - event.x, event.rawY - event.y) when (event.actionMasked) {