mirror of
https://github.com/libre-tube/LibreTube.git
synced 2025-04-29 00:10:32 +05:30
commit
7289fad18f
@ -15,4 +15,8 @@ interface PlayerGestureOptions {
|
|||||||
fun onSwipeRightScreen(distanceY: Float)
|
fun onSwipeRightScreen(distanceY: Float)
|
||||||
|
|
||||||
fun onSwipeEnd()
|
fun onSwipeEnd()
|
||||||
|
|
||||||
|
fun onZoom()
|
||||||
|
|
||||||
|
fun onMinimize()
|
||||||
}
|
}
|
||||||
|
@ -492,4 +492,12 @@ internal class CustomExoPlayerView(
|
|||||||
gestureViewBinding.brightnessControlView.visibility = View.GONE
|
gestureViewBinding.brightnessControlView.visibility = View.GONE
|
||||||
gestureViewBinding.volumeControlView.visibility = View.GONE
|
gestureViewBinding.volumeControlView.visibility = View.GONE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onZoom() {
|
||||||
|
resizeMode = AspectRatioFrameLayout.RESIZE_MODE_ZOOM
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onMinimize() {
|
||||||
|
resizeMode = AspectRatioFrameLayout.RESIZE_MODE_FIT
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,11 +9,12 @@ import android.os.Looper
|
|||||||
import android.os.SystemClock
|
import android.os.SystemClock
|
||||||
import android.view.GestureDetector
|
import android.view.GestureDetector
|
||||||
import android.view.MotionEvent
|
import android.view.MotionEvent
|
||||||
|
import android.view.ScaleGestureDetector
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import com.github.libretube.ui.interfaces.PlayerGestureOptions
|
import com.github.libretube.ui.interfaces.PlayerGestureOptions
|
||||||
import kotlin.math.abs
|
import kotlin.math.abs
|
||||||
|
|
||||||
class PlayerGestureController(context: Context, private val listner: PlayerGestureOptions) :
|
class PlayerGestureController(context: Context, private val listener: PlayerGestureOptions) :
|
||||||
View.OnTouchListener {
|
View.OnTouchListener {
|
||||||
|
|
||||||
// width and height should be obtained each time using getter to adopt layout size changes.
|
// width and height should be obtained each time using getter to adopt layout size changes.
|
||||||
@ -24,22 +25,25 @@ class PlayerGestureController(context: Context, private val listner: PlayerGestu
|
|||||||
|
|
||||||
private val handler: Handler = Handler(Looper.getMainLooper())
|
private val handler: Handler = Handler(Looper.getMainLooper())
|
||||||
private val gestureDetector: GestureDetector
|
private val gestureDetector: GestureDetector
|
||||||
|
private val scaleGestureDetector: ScaleGestureDetector
|
||||||
private var isMoving = false
|
private var isMoving = false
|
||||||
var isEnabled = true
|
var isEnabled = true
|
||||||
|
|
||||||
init {
|
init {
|
||||||
gestureDetector = GestureDetector(context, GestureListener(), handler)
|
gestureDetector = GestureDetector(context, GestureListener(), handler)
|
||||||
|
scaleGestureDetector = ScaleGestureDetector(context, ScaleGestureListener(), handler)
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("ClickableViewAccessibility")
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
override fun onTouch(v: View, event: MotionEvent): Boolean {
|
override fun onTouch(v: View, event: MotionEvent): Boolean {
|
||||||
if (event.action == MotionEvent.ACTION_UP && isMoving) {
|
if (event.action == MotionEvent.ACTION_UP && isMoving) {
|
||||||
isMoving = false
|
isMoving = false
|
||||||
listner.onSwipeEnd()
|
listener.onSwipeEnd()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Event can be already consumed by some view which may lead to NPE.
|
// Event can be already consumed by some view which may lead to NPE.
|
||||||
try {
|
try {
|
||||||
|
scaleGestureDetector.onTouchEvent(event)
|
||||||
gestureDetector.onTouchEvent(event)
|
gestureDetector.onTouchEvent(event)
|
||||||
} catch (_: Exception) { }
|
} catch (_: Exception) { }
|
||||||
|
|
||||||
@ -47,13 +51,34 @@ class PlayerGestureController(context: Context, private val listner: PlayerGestu
|
|||||||
return orientation == Configuration.ORIENTATION_LANDSCAPE
|
return orientation == Configuration.ORIENTATION_LANDSCAPE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private inner class ScaleGestureListener : ScaleGestureDetector.OnScaleGestureListener {
|
||||||
|
var scaleFactor: Float = 1f
|
||||||
|
|
||||||
|
override fun onScale(detector: ScaleGestureDetector): Boolean {
|
||||||
|
scaleFactor *= detector.scaleFactor
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onScaleBegin(detector: ScaleGestureDetector): Boolean {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onScaleEnd(detector: ScaleGestureDetector) {
|
||||||
|
when {
|
||||||
|
scaleFactor < 0.8 -> listener.onMinimize()
|
||||||
|
scaleFactor > 1.2 -> listener.onZoom()
|
||||||
|
}
|
||||||
|
scaleFactor = 1f
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private inner class GestureListener : GestureDetector.SimpleOnGestureListener() {
|
private inner class GestureListener : GestureDetector.SimpleOnGestureListener() {
|
||||||
private var lastClick = 0L
|
private var lastClick = 0L
|
||||||
private var lastDoubleClick = 0L
|
private var lastDoubleClick = 0L
|
||||||
private var xPos = 0.0F
|
private var xPos = 0.0F
|
||||||
|
|
||||||
override fun onDown(e: MotionEvent): Boolean {
|
override fun onDown(e: MotionEvent): Boolean {
|
||||||
if (isMoving) return false
|
if (isMoving || scaleGestureDetector.isInProgress) return false
|
||||||
|
|
||||||
if (isEnabled && isSecondClick()) {
|
if (isEnabled && isSecondClick()) {
|
||||||
handler.removeCallbacks(runnable)
|
handler.removeCallbacks(runnable)
|
||||||
@ -61,9 +86,9 @@ class PlayerGestureController(context: Context, private val listner: PlayerGestu
|
|||||||
val eventPositionPercentageX = xPos / width
|
val eventPositionPercentageX = xPos / width
|
||||||
|
|
||||||
when {
|
when {
|
||||||
eventPositionPercentageX < 0.4 -> listner.onDoubleTapLeftScreen()
|
eventPositionPercentageX < 0.4 -> listener.onDoubleTapLeftScreen()
|
||||||
eventPositionPercentageX > 0.6 -> listner.onDoubleTapRightScreen()
|
eventPositionPercentageX > 0.6 -> listener.onDoubleTapRightScreen()
|
||||||
else -> listner.onDoubleTapCenterScreen()
|
else -> listener.onDoubleTapCenterScreen()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (recentDoubleClick()) return true
|
if (recentDoubleClick()) return true
|
||||||
@ -81,7 +106,7 @@ class PlayerGestureController(context: Context, private val listner: PlayerGestu
|
|||||||
distanceX: Float,
|
distanceX: Float,
|
||||||
distanceY: Float
|
distanceY: Float
|
||||||
): Boolean {
|
): Boolean {
|
||||||
if (!isEnabled) return false
|
if (!isEnabled || scaleGestureDetector.isInProgress) return false
|
||||||
|
|
||||||
val insideThreshHold = abs(e2.y - e1.y) <= MOVEMENT_THRESHOLD
|
val insideThreshHold = abs(e2.y - e1.y) <= MOVEMENT_THRESHOLD
|
||||||
val insideBorder = (e1.x < BORDER_THRESHOLD || e1.y < BORDER_THRESHOLD || e1.x > width - BORDER_THRESHOLD || e1.y > height - BORDER_THRESHOLD)
|
val insideBorder = (e1.x < BORDER_THRESHOLD || e1.y < BORDER_THRESHOLD || e1.x > width - BORDER_THRESHOLD || e1.y > height - BORDER_THRESHOLD)
|
||||||
@ -101,8 +126,8 @@ class PlayerGestureController(context: Context, private val listner: PlayerGestu
|
|||||||
isMoving = true
|
isMoving = true
|
||||||
|
|
||||||
when {
|
when {
|
||||||
width * 0.5 > e1.x -> listner.onSwipeLeftScreen(distanceY)
|
width * 0.5 > e1.x -> listener.onSwipeLeftScreen(distanceY)
|
||||||
width * 0.5 < e1.x -> listner.onSwipeRightScreen(distanceY)
|
width * 0.5 < e1.x -> listener.onSwipeRightScreen(distanceY)
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -110,7 +135,7 @@ class PlayerGestureController(context: Context, private val listner: PlayerGestu
|
|||||||
private val runnable = Runnable {
|
private val runnable = Runnable {
|
||||||
// If user is scrolling then avoid single tap call
|
// If user is scrolling then avoid single tap call
|
||||||
if (isMoving || isSecondClick()) return@Runnable
|
if (isMoving || isSecondClick()) return@Runnable
|
||||||
listner.onSingleTap()
|
listener.onSingleTap()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isSecondClick(): Boolean {
|
private fun isSecondClick(): Boolean {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user