Player gestures: Add multi-double-tap logic
This commit is contained in:
parent
2683043762
commit
347566c311
3 changed files with 78 additions and 0 deletions
|
@ -1,6 +1,7 @@
|
||||||
package org.schabi.newpipe.player.event
|
package org.schabi.newpipe.player.event
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.os.Handler
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.GestureDetector
|
import android.view.GestureDetector
|
||||||
import android.view.MotionEvent
|
import android.view.MotionEvent
|
||||||
|
@ -203,6 +204,11 @@ abstract class BasePlayerGestureListener(
|
||||||
if (DEBUG)
|
if (DEBUG)
|
||||||
Log.d(TAG, "onDown called with e = [$e]")
|
Log.d(TAG, "onDown called with e = [$e]")
|
||||||
|
|
||||||
|
if (isDoubleTapping && isDoubleTapEnabled) {
|
||||||
|
doubleTapControls?.onDoubleTapProgressDown(getDisplayPortion(e))
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
return if (playerImpl.popupPlayerSelected())
|
return if (playerImpl.popupPlayerSelected())
|
||||||
onDownInPopup(e)
|
onDownInPopup(e)
|
||||||
else
|
else
|
||||||
|
@ -233,6 +239,9 @@ abstract class BasePlayerGestureListener(
|
||||||
if (DEBUG)
|
if (DEBUG)
|
||||||
Log.d(TAG, "onSingleTapConfirmed() called with: e = [$e]")
|
Log.d(TAG, "onSingleTapConfirmed() called with: e = [$e]")
|
||||||
|
|
||||||
|
if (isDoubleTapping)
|
||||||
|
return true
|
||||||
|
|
||||||
if (playerImpl.popupPlayerSelected()) {
|
if (playerImpl.popupPlayerSelected()) {
|
||||||
if (playerImpl.player == null)
|
if (playerImpl.player == null)
|
||||||
return false
|
return false
|
||||||
|
@ -374,6 +383,65 @@ abstract class BasePlayerGestureListener(
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ///////////////////////////////////////////////////////////////////
|
||||||
|
// Multi double tapping
|
||||||
|
// ///////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
var doubleTapControls: DoubleTapListener? = null
|
||||||
|
private set
|
||||||
|
|
||||||
|
val isDoubleTapEnabled: Boolean
|
||||||
|
get() = doubleTapDelay > 0
|
||||||
|
|
||||||
|
var isDoubleTapping = false
|
||||||
|
private set
|
||||||
|
|
||||||
|
fun doubleTapControls(listener: DoubleTapListener) = apply {
|
||||||
|
doubleTapControls = listener
|
||||||
|
}
|
||||||
|
|
||||||
|
private var doubleTapDelay = DOUBLE_TAP_DELAY
|
||||||
|
private val doubleTapHandler: Handler = Handler()
|
||||||
|
private val doubleTapRunnable = Runnable {
|
||||||
|
if (DEBUG)
|
||||||
|
Log.d(TAG, "doubleTapRunnable called")
|
||||||
|
|
||||||
|
isDoubleTapping = false
|
||||||
|
doubleTapControls?.onDoubleTapFinished()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun startMultiDoubleTap(e: MotionEvent) {
|
||||||
|
if (!isDoubleTapping) {
|
||||||
|
if (DEBUG)
|
||||||
|
Log.d(TAG, "startMultiDoubleTap called with e = [$e]")
|
||||||
|
|
||||||
|
keepInDoubleTapMode()
|
||||||
|
doubleTapControls?.onDoubleTapStarted(getDisplayPortion(e))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun keepInDoubleTapMode() {
|
||||||
|
if (DEBUG)
|
||||||
|
Log.d(TAG, "keepInDoubleTapMode called")
|
||||||
|
|
||||||
|
isDoubleTapping = true
|
||||||
|
doubleTapHandler.removeCallbacks(doubleTapRunnable)
|
||||||
|
doubleTapHandler.postDelayed(doubleTapRunnable, doubleTapDelay)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun endMultiDoubleTap() {
|
||||||
|
if (DEBUG)
|
||||||
|
Log.d(TAG, "endMultiDoubleTap called")
|
||||||
|
|
||||||
|
isDoubleTapping = false
|
||||||
|
doubleTapHandler.removeCallbacks(doubleTapRunnable)
|
||||||
|
doubleTapControls?.onDoubleTapFinished()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun enableMultiDoubleTap(enable: Boolean) = apply {
|
||||||
|
doubleTapDelay = if (enable) DOUBLE_TAP_DELAY else 0
|
||||||
|
}
|
||||||
|
|
||||||
// ///////////////////////////////////////////////////////////////////
|
// ///////////////////////////////////////////////////////////////////
|
||||||
// Utils
|
// Utils
|
||||||
// ///////////////////////////////////////////////////////////////////
|
// ///////////////////////////////////////////////////////////////////
|
||||||
|
@ -429,6 +497,7 @@ abstract class BasePlayerGestureListener(
|
||||||
private const val TAG = "BasePlayerGestListener"
|
private const val TAG = "BasePlayerGestListener"
|
||||||
private val DEBUG = BasePlayer.DEBUG
|
private val DEBUG = BasePlayer.DEBUG
|
||||||
|
|
||||||
|
private const val DOUBLE_TAP_DELAY = 550L
|
||||||
private const val MOVEMENT_THRESHOLD = 40
|
private const val MOVEMENT_THRESHOLD = 40
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
package org.schabi.newpipe.player.event
|
||||||
|
|
||||||
|
interface DoubleTapListener {
|
||||||
|
fun onDoubleTapStarted(portion: DisplayPortion) {}
|
||||||
|
fun onDoubleTapProgressDown(portion: DisplayPortion) {}
|
||||||
|
fun onDoubleTapFinished() {}
|
||||||
|
}
|
|
@ -62,6 +62,8 @@ public class PlayerGestureListener
|
||||||
|
|
||||||
if (portion == DisplayPortion.LEFT) {
|
if (portion == DisplayPortion.LEFT) {
|
||||||
playerImpl.onFastRewind();
|
playerImpl.onFastRewind();
|
||||||
|
} else if (portion == DisplayPortion.MIDDLE) {
|
||||||
|
playerImpl.onPlayPause();
|
||||||
} else if (portion == DisplayPortion.RIGHT) {
|
} else if (portion == DisplayPortion.RIGHT) {
|
||||||
playerImpl.onFastForward();
|
playerImpl.onFastForward();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue