118 lines
3.9 KiB
Kotlin
118 lines
3.9 KiB
Kotlin
package app.revanced.integrations.youtube.swipecontrols.controller.gesture
|
|
|
|
import android.view.MotionEvent
|
|
import app.revanced.integrations.youtube.shared.PlayerControlsVisibilityObserver
|
|
import app.revanced.integrations.youtube.shared.PlayerControlsVisibilityObserverImpl
|
|
import app.revanced.integrations.youtube.swipecontrols.SwipeControlsHostActivity
|
|
import app.revanced.integrations.youtube.swipecontrols.controller.gesture.core.BaseGestureController
|
|
import app.revanced.integrations.youtube.swipecontrols.controller.gesture.core.SwipeDetector
|
|
import app.revanced.integrations.youtube.swipecontrols.misc.contains
|
|
import app.revanced.integrations.youtube.swipecontrols.misc.toPoint
|
|
|
|
/**
|
|
* provides the classic swipe controls experience, as it was with 'XFenster'
|
|
*
|
|
* @param controller reference to the main swipe controller
|
|
*/
|
|
class ClassicSwipeController(
|
|
private val controller: SwipeControlsHostActivity
|
|
) : BaseGestureController(controller),
|
|
PlayerControlsVisibilityObserver by PlayerControlsVisibilityObserverImpl(controller) {
|
|
/**
|
|
* the last event captured in [onDown]
|
|
*/
|
|
private var lastOnDownEvent: MotionEvent? = null
|
|
|
|
override val shouldForceInterceptEvents: Boolean
|
|
get() = currentSwipe == SwipeDetector.SwipeDirection.VERTICAL
|
|
|
|
override fun isInSwipeZone(motionEvent: MotionEvent): Boolean {
|
|
val inVolumeZone = if (controller.config.enableVolumeControls) {
|
|
(motionEvent.toPoint() in controller.zones.volume)
|
|
} else {
|
|
false
|
|
}
|
|
val inBrightnessZone = if (controller.config.enableBrightnessControl) {
|
|
(motionEvent.toPoint() in controller.zones.brightness)
|
|
} else {
|
|
false
|
|
}
|
|
|
|
return inVolumeZone || inBrightnessZone
|
|
}
|
|
|
|
override fun shouldDropMotion(motionEvent: MotionEvent): Boolean {
|
|
// ignore gestures with more than one pointer
|
|
// when such a gesture is detected, dispatch the first event of the gesture to downstream
|
|
if (motionEvent.pointerCount > 1) {
|
|
lastOnDownEvent?.let {
|
|
controller.dispatchDownstreamTouchEvent(it)
|
|
it.recycle()
|
|
}
|
|
lastOnDownEvent = null
|
|
return true
|
|
}
|
|
|
|
// ignore gestures when player controls are visible
|
|
return arePlayerControlsVisible
|
|
}
|
|
|
|
override fun onDown(motionEvent: MotionEvent): Boolean {
|
|
// save the event for later
|
|
lastOnDownEvent?.recycle()
|
|
lastOnDownEvent = MotionEvent.obtain(motionEvent)
|
|
|
|
// must be inside swipe zone
|
|
return isInSwipeZone(motionEvent)
|
|
}
|
|
|
|
override fun onSingleTapUp(motionEvent: MotionEvent): Boolean {
|
|
MotionEvent.obtain(motionEvent).let {
|
|
it.action = MotionEvent.ACTION_DOWN
|
|
controller.dispatchDownstreamTouchEvent(it)
|
|
it.recycle()
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
override fun onDoubleTapEvent(motionEvent: MotionEvent): Boolean {
|
|
MotionEvent.obtain(motionEvent).let {
|
|
controller.dispatchDownstreamTouchEvent(it)
|
|
it.recycle()
|
|
}
|
|
|
|
return super.onDoubleTapEvent(motionEvent)
|
|
}
|
|
|
|
override fun onLongPress(motionEvent: MotionEvent) {
|
|
MotionEvent.obtain(motionEvent).let {
|
|
controller.dispatchDownstreamTouchEvent(it)
|
|
it.recycle()
|
|
}
|
|
|
|
super.onLongPress(motionEvent)
|
|
}
|
|
|
|
override fun onSwipe(
|
|
from: MotionEvent,
|
|
to: MotionEvent,
|
|
distanceX: Double,
|
|
distanceY: Double
|
|
): Boolean {
|
|
// cancel if not vertical
|
|
if (currentSwipe != SwipeDetector.SwipeDirection.VERTICAL) return false
|
|
return when (from.toPoint()) {
|
|
in controller.zones.volume -> {
|
|
scrollVolume(distanceY)
|
|
true
|
|
}
|
|
in controller.zones.brightness -> {
|
|
scrollBrightness(distanceY)
|
|
true
|
|
}
|
|
else -> false
|
|
}
|
|
}
|
|
}
|