mirror of
https://github.com/revanced/revanced-integrations.git
synced 2024-12-03 17:22:54 +01:00
feat: swipe controls
override volume button behaviour (#114)
This commit is contained in:
parent
166bfd35ed
commit
8056e2e9eb
@ -3,7 +3,7 @@ package app.revanced.integrations.patches;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
import app.revanced.integrations.swipecontrols.views.SwipeControlsHostLayout;
|
||||
import app.revanced.integrations.swipecontrols.SwipeControlsHostActivity;
|
||||
|
||||
/**
|
||||
* Patch class for 'hdr-auto-brightness' patch
|
||||
@ -27,7 +27,7 @@ public class HDRAutoBrightnessPatch {
|
||||
|
||||
// override with brightness set by swipe-controls
|
||||
// only when swipe-controls is active and has overridden the brightness
|
||||
final SwipeControlsHostLayout swipeControlsHost = SwipeControlsPatch.CURRENT_HOST.get();
|
||||
final SwipeControlsHostActivity swipeControlsHost = SwipeControlsHostActivity.getCurrentHost().get();
|
||||
if (swipeControlsHost != null
|
||||
&& swipeControlsHost.getScreen() != null
|
||||
&& swipeControlsHost.getConfig().getEnableBrightnessControl()
|
||||
|
@ -1,42 +0,0 @@
|
||||
package app.revanced.integrations.patches;
|
||||
|
||||
import android.app.Activity;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
import app.revanced.integrations.swipecontrols.views.SwipeControlsHostLayout;
|
||||
|
||||
/**
|
||||
* Hook receiver class for 'swipe-controls' patch
|
||||
*
|
||||
* @usedBy app.revanced.patches.youtube.interaction.swipecontrols.patch.SwipeControlsPatch
|
||||
* @smali Lapp/revanced/integrations/patches/SwipeControlsPatch;
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class SwipeControlsPatch {
|
||||
|
||||
/**
|
||||
* the currently active swipe controls host.
|
||||
* the reference may be null!
|
||||
*/
|
||||
@NonNull
|
||||
public static WeakReference<SwipeControlsHostLayout> CURRENT_HOST = new WeakReference<>(null);
|
||||
|
||||
/**
|
||||
* Hook into the main activity lifecycle
|
||||
* (using onStart here, but really anything up until onResume should be fine)
|
||||
*
|
||||
* @param thisRef reference to the WatchWhileActivity instance
|
||||
* @smali WatchWhileActivity_onStartHookEX(Ljava / lang / Object ;)V
|
||||
*/
|
||||
public static void WatchWhileActivity_onStartHookEX(@Nullable Object thisRef) {
|
||||
if (thisRef == null) return;
|
||||
if (thisRef instanceof Activity) {
|
||||
SwipeControlsHostLayout swipeControlsHost = SwipeControlsHostLayout.attachTo((Activity) thisRef, false);
|
||||
CURRENT_HOST = new WeakReference<>(swipeControlsHost);
|
||||
}
|
||||
}
|
||||
}
|
@ -15,7 +15,7 @@ class SwipeControlsConfigurationProvider(
|
||||
) {
|
||||
//region swipe enable
|
||||
/**
|
||||
* should swipe controls be enabled? (global setting
|
||||
* should swipe controls be enabled? (global setting)
|
||||
*/
|
||||
val enableSwipeControls: Boolean
|
||||
get() = isFullscreenVideo && (enableVolumeControls || enableBrightnessControl)
|
||||
@ -39,6 +39,14 @@ class SwipeControlsConfigurationProvider(
|
||||
get() = PlayerType.current == PlayerType.WATCH_WHILE_FULLSCREEN
|
||||
//endregion
|
||||
|
||||
//region keys enable
|
||||
/**
|
||||
* should volume key controls be overwritten? (global setting)
|
||||
*/
|
||||
val overwriteVolumeKeyControls: Boolean
|
||||
get() = isFullscreenVideo && enableVolumeControls
|
||||
//endregioin
|
||||
|
||||
//region gesture adjustments
|
||||
/**
|
||||
* should press-to-swipe be enabled?
|
||||
|
@ -0,0 +1,178 @@
|
||||
package app.revanced.integrations.swipecontrols
|
||||
|
||||
import android.app.Activity
|
||||
import android.os.Bundle
|
||||
import android.view.KeyEvent
|
||||
import android.view.MotionEvent
|
||||
import android.view.ViewGroup
|
||||
import app.revanced.integrations.shared.PlayerType
|
||||
import app.revanced.integrations.swipecontrols.controller.AudioVolumeController
|
||||
import app.revanced.integrations.swipecontrols.controller.ScreenBrightnessController
|
||||
import app.revanced.integrations.swipecontrols.controller.SwipeZonesController
|
||||
import app.revanced.integrations.swipecontrols.controller.VolumeKeysController
|
||||
import app.revanced.integrations.swipecontrols.controller.gesture.NoPtSSwipeGestureController
|
||||
import app.revanced.integrations.swipecontrols.controller.gesture.SwipeGestureController
|
||||
import app.revanced.integrations.swipecontrols.misc.Rectangle
|
||||
import app.revanced.integrations.swipecontrols.views.SwipeControlsOverlayLayout
|
||||
import app.revanced.integrations.utils.LogHelper
|
||||
import java.lang.ref.WeakReference
|
||||
|
||||
/**
|
||||
* The main controller for volume and brightness swipe controls.
|
||||
* note that the superclass is overwritten to the superclass of the WatchWhileActivity at patch time
|
||||
*
|
||||
* @smali Lapp/revanced/integrations/swipecontrols/SwipeControlsHostActivity;
|
||||
*/
|
||||
class SwipeControlsHostActivity : Activity() {
|
||||
/**
|
||||
* current instance of [AudioVolumeController]
|
||||
*/
|
||||
var audio: AudioVolumeController? = null
|
||||
|
||||
/**
|
||||
* current instance of [ScreenBrightnessController]
|
||||
*/
|
||||
var screen: ScreenBrightnessController? = null
|
||||
|
||||
/**
|
||||
* current instance of [SwipeControlsConfigurationProvider]
|
||||
*/
|
||||
lateinit var config: SwipeControlsConfigurationProvider
|
||||
|
||||
/**
|
||||
* current instance of [SwipeControlsOverlayLayout]
|
||||
*/
|
||||
lateinit var overlay: SwipeControlsOverlayLayout
|
||||
|
||||
/**
|
||||
* current instance of [SwipeZonesController]
|
||||
*/
|
||||
lateinit var zones: SwipeZonesController
|
||||
|
||||
/**
|
||||
* main gesture controller
|
||||
*/
|
||||
private lateinit var gesture: SwipeGestureController
|
||||
|
||||
/**
|
||||
* main volume keys controller
|
||||
*/
|
||||
private lateinit var keys: VolumeKeysController
|
||||
|
||||
/**
|
||||
* current content view with id [android.R.id.content]
|
||||
*/
|
||||
private val contentRoot
|
||||
get() = window.decorView.findViewById<ViewGroup>(android.R.id.content)
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
// create controllers
|
||||
LogHelper.info(this.javaClass, "initializing swipe controls controllers")
|
||||
config = SwipeControlsConfigurationProvider(this)
|
||||
gesture = createGestureController()
|
||||
keys = VolumeKeysController(this)
|
||||
audio = createAudioController()
|
||||
screen = createScreenController()
|
||||
|
||||
// create overlay
|
||||
SwipeControlsOverlayLayout(this).let {
|
||||
overlay = it
|
||||
contentRoot.addView(it)
|
||||
}
|
||||
|
||||
// create swipe zone controller
|
||||
zones = SwipeZonesController(this) {
|
||||
Rectangle(
|
||||
contentRoot.x.toInt(),
|
||||
contentRoot.y.toInt(),
|
||||
contentRoot.width,
|
||||
contentRoot.height
|
||||
)
|
||||
}
|
||||
|
||||
// listen for changes in the player type
|
||||
PlayerType.onChange += this::onPlayerTypeChanged
|
||||
|
||||
// set current instance reference
|
||||
currentHost = WeakReference(this)
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
|
||||
// (re) attach overlay
|
||||
LogHelper.info(this.javaClass, "attaching swipe controls overlay")
|
||||
contentRoot.removeView(overlay)
|
||||
contentRoot.addView(overlay)
|
||||
}
|
||||
|
||||
override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
|
||||
return if ((ev != null) && gesture.onTouchEvent(ev)) true else {
|
||||
super.dispatchTouchEvent(ev)
|
||||
}
|
||||
}
|
||||
|
||||
override fun dispatchKeyEvent(ev: KeyEvent?): Boolean {
|
||||
return if((ev != null) && keys.onKeyEvent(ev)) true else {
|
||||
super.dispatchKeyEvent(ev)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* dispatch a touch event to downstream views
|
||||
*
|
||||
* @param event the event to dispatch
|
||||
* @return was the event consumed?
|
||||
*/
|
||||
fun dispatchDownstreamTouchEvent(event: MotionEvent) =
|
||||
super.dispatchTouchEvent(event)
|
||||
|
||||
/**
|
||||
* called when the player type changes
|
||||
*
|
||||
* @param type the new player type
|
||||
*/
|
||||
private fun onPlayerTypeChanged(type: PlayerType) {
|
||||
when (type) {
|
||||
PlayerType.WATCH_WHILE_FULLSCREEN -> screen?.restore()
|
||||
else -> {
|
||||
screen?.save()
|
||||
screen?.restoreDefaultBrightness()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* create the audio volume controller
|
||||
*/
|
||||
private fun createAudioController() =
|
||||
if (config.enableVolumeControls)
|
||||
AudioVolumeController(this) else null
|
||||
|
||||
/**
|
||||
* create the screen brightness controller instance
|
||||
*/
|
||||
private fun createScreenController() =
|
||||
if (config.enableBrightnessControl)
|
||||
ScreenBrightnessController(this) else null
|
||||
|
||||
/**
|
||||
* create the gesture controller based on settings
|
||||
*/
|
||||
private fun createGestureController() =
|
||||
if (config.shouldEnablePressToSwipe)
|
||||
SwipeGestureController(this)
|
||||
else NoPtSSwipeGestureController(this)
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* the currently active swipe controls host.
|
||||
* the reference may be null!
|
||||
*/
|
||||
@JvmStatic
|
||||
var currentHost: WeakReference<SwipeControlsHostActivity> = WeakReference(null)
|
||||
private set
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
package app.revanced.integrations.swipecontrols.controller
|
||||
|
||||
import android.content.Context
|
||||
import android.app.Activity
|
||||
import android.util.TypedValue
|
||||
import android.view.ViewGroup
|
||||
import app.revanced.integrations.swipecontrols.misc.Rectangle
|
||||
@ -35,29 +35,28 @@ import kotlin.math.min
|
||||
*/
|
||||
@Suppress("PrivatePropertyName")
|
||||
class SwipeZonesController(
|
||||
context: Context,
|
||||
private val parentView: ViewGroup,
|
||||
private val host: Activity,
|
||||
private val fallbackScreenRect: () -> Rectangle
|
||||
) {
|
||||
/**
|
||||
* 20dp, in pixels
|
||||
*/
|
||||
private val _20dp = 20.applyDimension(context, TypedValue.COMPLEX_UNIT_DIP)
|
||||
private val _20dp = 20.applyDimension(host, TypedValue.COMPLEX_UNIT_DIP)
|
||||
|
||||
/**
|
||||
* 40dp, in pixels
|
||||
*/
|
||||
private val _40dp = 40.applyDimension(context, TypedValue.COMPLEX_UNIT_DIP)
|
||||
private val _40dp = 40.applyDimension(host, TypedValue.COMPLEX_UNIT_DIP)
|
||||
|
||||
/**
|
||||
* 80dp, in pixels
|
||||
*/
|
||||
private val _80dp = 80.applyDimension(context, TypedValue.COMPLEX_UNIT_DIP)
|
||||
private val _80dp = 80.applyDimension(host, TypedValue.COMPLEX_UNIT_DIP)
|
||||
|
||||
/**
|
||||
* id for R.id.player_view
|
||||
*/
|
||||
private val playerViewId = ReVancedUtils.getResourceIdByName(context, "id", "player_view")
|
||||
private val playerViewId = ReVancedUtils.getResourceIdByName(host, "id", "player_view")
|
||||
|
||||
/**
|
||||
* current bounding rectangle of the player
|
||||
@ -114,7 +113,7 @@ class SwipeZonesController(
|
||||
*/
|
||||
private fun maybeAttachPlayerBoundsListener() {
|
||||
if (playerRect != null) return
|
||||
parentView.findViewById<ViewGroup>(playerViewId)?.let {
|
||||
host.findViewById<ViewGroup>(playerViewId)?.let {
|
||||
onPlayerViewLayout(it)
|
||||
it.addOnLayoutChangeListener { _, _, _, _, _, _, _, _, _ ->
|
||||
onPlayerViewLayout(it)
|
||||
|
@ -0,0 +1,51 @@
|
||||
package app.revanced.integrations.swipecontrols.controller
|
||||
|
||||
import android.view.KeyEvent
|
||||
import app.revanced.integrations.swipecontrols.SwipeControlsHostActivity
|
||||
|
||||
/**
|
||||
* controller for custom volume button behaviour
|
||||
*
|
||||
* @param controller main controller instance
|
||||
*/
|
||||
class VolumeKeysController(
|
||||
private val controller: SwipeControlsHostActivity
|
||||
) {
|
||||
/**
|
||||
* key event handler
|
||||
*
|
||||
* @param event the key event
|
||||
* @return consume the event?
|
||||
*/
|
||||
fun onKeyEvent(event: KeyEvent): Boolean {
|
||||
if(!controller.config.overwriteVolumeKeyControls) {
|
||||
return false
|
||||
}
|
||||
|
||||
return when (event.keyCode) {
|
||||
KeyEvent.KEYCODE_VOLUME_DOWN ->
|
||||
handleVolumeKeyEvent(event, false)
|
||||
KeyEvent.KEYCODE_VOLUME_UP ->
|
||||
handleVolumeKeyEvent(event, true)
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* handle a volume up / down key event
|
||||
*
|
||||
* @param event the key event
|
||||
* @param volumeUp was the key pressed the volume up key?
|
||||
* @return consume the event?
|
||||
*/
|
||||
private fun handleVolumeKeyEvent(event: KeyEvent, volumeUp: Boolean): Boolean {
|
||||
if (event.action == KeyEvent.ACTION_DOWN) {
|
||||
controller.audio?.apply {
|
||||
volume += if (volumeUp) 1 else -1
|
||||
controller.overlay.onVolumeChanged(volume, maxVolume)
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
}
|
@ -1,15 +1,14 @@
|
||||
package app.revanced.integrations.swipecontrols.controller.gesture
|
||||
|
||||
import android.content.Context
|
||||
import android.view.MotionEvent
|
||||
import app.revanced.integrations.swipecontrols.views.SwipeControlsHostLayout
|
||||
import app.revanced.integrations.swipecontrols.SwipeControlsHostActivity
|
||||
|
||||
/**
|
||||
* [SwipeGestureController], but with press-to-swipe disabled because a lot of people dislike the feature.
|
||||
* If you want to change something, try to do it in [SwipeGestureController] so that both configurations can benefit from it
|
||||
*/
|
||||
class NoPtSSwipeGestureController(context: Context, controller: SwipeControlsHostLayout) :
|
||||
SwipeGestureController(context, controller) {
|
||||
class NoPtSSwipeGestureController(controller: SwipeControlsHostActivity) :
|
||||
SwipeGestureController(controller) {
|
||||
|
||||
/**
|
||||
* to disable press-to-swipe, we have to become press-to-swipe
|
||||
|
@ -1,14 +1,13 @@
|
||||
package app.revanced.integrations.swipecontrols.controller.gesture
|
||||
|
||||
import android.content.Context
|
||||
import android.util.TypedValue
|
||||
import android.view.GestureDetector
|
||||
import android.view.MotionEvent
|
||||
import app.revanced.integrations.swipecontrols.SwipeControlsHostActivity
|
||||
import app.revanced.integrations.swipecontrols.misc.ScrollDistanceHelper
|
||||
import app.revanced.integrations.swipecontrols.misc.applyDimension
|
||||
import app.revanced.integrations.swipecontrols.misc.contains
|
||||
import app.revanced.integrations.swipecontrols.misc.toPoint
|
||||
import app.revanced.integrations.swipecontrols.views.SwipeControlsHostLayout
|
||||
import app.revanced.integrations.utils.LogHelper
|
||||
import kotlin.math.abs
|
||||
import kotlin.math.pow
|
||||
@ -17,21 +16,18 @@ import kotlin.math.pow
|
||||
* base gesture controller for volume and brightness swipe controls controls, with press-to-swipe enabled
|
||||
* for the controller without press-to-swipe, see [NoPtSSwipeGestureController]
|
||||
*
|
||||
* @param context the context to create in
|
||||
* @param controller reference to main controller instance
|
||||
*/
|
||||
@Suppress("LeakingThis")
|
||||
open class SwipeGestureController(
|
||||
context: Context,
|
||||
private val controller: SwipeControlsHostLayout
|
||||
private val controller: SwipeControlsHostActivity
|
||||
) :
|
||||
GestureDetector.SimpleOnGestureListener(),
|
||||
SwipeControlsHostLayout.TouchEventListener {
|
||||
GestureDetector.SimpleOnGestureListener() {
|
||||
|
||||
/**
|
||||
* the main gesture detector that powers everything
|
||||
*/
|
||||
protected open val detector = GestureDetector(context, this)
|
||||
protected open val detector = GestureDetector(controller, this)
|
||||
|
||||
/**
|
||||
* to enable swipe controls, users must first long- press. this flags monitors that long- press
|
||||
@ -60,7 +56,7 @@ open class SwipeGestureController(
|
||||
*/
|
||||
protected open val volumeScroller = ScrollDistanceHelper(
|
||||
10.applyDimension(
|
||||
context,
|
||||
controller,
|
||||
TypedValue.COMPLEX_UNIT_DIP
|
||||
)
|
||||
) { _, _, direction ->
|
||||
@ -75,7 +71,7 @@ open class SwipeGestureController(
|
||||
*/
|
||||
protected open val brightnessScroller = ScrollDistanceHelper(
|
||||
1.applyDimension(
|
||||
context,
|
||||
controller,
|
||||
TypedValue.COMPLEX_UNIT_DIP
|
||||
)
|
||||
) { _, _, direction ->
|
||||
@ -90,7 +86,13 @@ open class SwipeGestureController(
|
||||
}
|
||||
}
|
||||
|
||||
override fun onTouchEvent(motionEvent: MotionEvent): Boolean {
|
||||
/**
|
||||
* touch event callback
|
||||
*
|
||||
* @param motionEvent the motion event that was received
|
||||
* @return intercept the event? if true, child views will not receive the event
|
||||
*/
|
||||
fun onTouchEvent(motionEvent: MotionEvent): Boolean {
|
||||
if (!controller.config.enableSwipeControls) {
|
||||
return false
|
||||
}
|
||||
|
@ -1,207 +0,0 @@
|
||||
package app.revanced.integrations.swipecontrols.views
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.graphics.Color
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.FrameLayout
|
||||
import app.revanced.integrations.shared.PlayerType
|
||||
import app.revanced.integrations.swipecontrols.SwipeControlsConfigurationProvider
|
||||
import app.revanced.integrations.swipecontrols.controller.AudioVolumeController
|
||||
import app.revanced.integrations.swipecontrols.controller.ScreenBrightnessController
|
||||
import app.revanced.integrations.swipecontrols.controller.SwipeZonesController
|
||||
import app.revanced.integrations.swipecontrols.controller.gesture.NoPtSSwipeGestureController
|
||||
import app.revanced.integrations.swipecontrols.controller.gesture.SwipeGestureController
|
||||
import app.revanced.integrations.swipecontrols.misc.Rectangle
|
||||
import app.revanced.integrations.swipecontrols.misc.SwipeControlsOverlay
|
||||
import app.revanced.integrations.utils.LogHelper
|
||||
|
||||
/**
|
||||
* The main controller for volume and brightness swipe controls
|
||||
*
|
||||
* @param hostActivity the activity that should host the controller
|
||||
* @param debugTouchableZone show a overlay on all zones covered by this layout
|
||||
*/
|
||||
@SuppressLint("ViewConstructor")
|
||||
class SwipeControlsHostLayout(
|
||||
private val hostActivity: Activity,
|
||||
private val mainContentChild: View,
|
||||
debugTouchableZone: Boolean = false
|
||||
) : FrameLayout(hostActivity) {
|
||||
init {
|
||||
isFocusable = false
|
||||
isClickable = false
|
||||
|
||||
if (debugTouchableZone) {
|
||||
val zoneOverlay = View(context).apply {
|
||||
layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
|
||||
setBackgroundColor(Color.argb(50, 0, 255, 0))
|
||||
z = 9999f
|
||||
}
|
||||
addView(zoneOverlay)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* current instance of [AudioVolumeController]
|
||||
*/
|
||||
val audio: AudioVolumeController?
|
||||
|
||||
/**
|
||||
* current instance of [ScreenBrightnessController]
|
||||
*/
|
||||
val screen: ScreenBrightnessController?
|
||||
|
||||
/**
|
||||
* current instance of [SwipeControlsConfigurationProvider]
|
||||
*/
|
||||
val config: SwipeControlsConfigurationProvider
|
||||
|
||||
/**
|
||||
* current instance of [SwipeControlsOverlayLayout]
|
||||
*/
|
||||
val overlay: SwipeControlsOverlay
|
||||
|
||||
/**
|
||||
* current instance of [SwipeZonesController]
|
||||
*/
|
||||
val zones: SwipeZonesController
|
||||
|
||||
/**
|
||||
* main gesture controller
|
||||
*/
|
||||
private val gesture: SwipeGestureController
|
||||
|
||||
init {
|
||||
// create controllers
|
||||
LogHelper.info(this.javaClass, "initializing swipe controls controllers")
|
||||
config = SwipeControlsConfigurationProvider(hostActivity)
|
||||
gesture = createGestureController()
|
||||
audio = createAudioController()
|
||||
screen = createScreenController()
|
||||
|
||||
// create overlay
|
||||
SwipeControlsOverlayLayout(hostActivity).let {
|
||||
overlay = it
|
||||
addView(it)
|
||||
}
|
||||
|
||||
// create swipe zone controller
|
||||
zones = SwipeZonesController(context, this) {
|
||||
Rectangle(x.toInt(), y.toInt(), width, height)
|
||||
}
|
||||
|
||||
// listen for changes in the player type
|
||||
PlayerType.onChange += this::onPlayerTypeChanged
|
||||
}
|
||||
|
||||
override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
|
||||
return if (ev != null && gesture.onTouchEvent(ev)) true else {
|
||||
super.dispatchTouchEvent(ev)
|
||||
}
|
||||
}
|
||||
|
||||
override fun addView(child: View?, index: Int, params: ViewGroup.LayoutParams?) {
|
||||
// main content is always at index 0, all other are inserted after
|
||||
if (child == mainContentChild) {
|
||||
super.addView(child, 0, params)
|
||||
} else {
|
||||
super.addView(child, childCount, params)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* called when the player type changes
|
||||
*
|
||||
* @param type the new player type
|
||||
*/
|
||||
private fun onPlayerTypeChanged(type: PlayerType) {
|
||||
when (type) {
|
||||
PlayerType.WATCH_WHILE_FULLSCREEN -> screen?.restore()
|
||||
else -> {
|
||||
screen?.save()
|
||||
screen?.restoreDefaultBrightness()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* dispatch a touch event to downstream views
|
||||
*
|
||||
* @param event the event to dispatch
|
||||
* @return was the event consumed?
|
||||
*/
|
||||
fun dispatchDownstreamTouchEvent(event: MotionEvent) =
|
||||
super.dispatchTouchEvent(event)
|
||||
|
||||
/**
|
||||
* create the audio volume controller
|
||||
*/
|
||||
private fun createAudioController() =
|
||||
if (config.enableVolumeControls)
|
||||
AudioVolumeController(context) else null
|
||||
|
||||
/**
|
||||
* create the screen brightness controller instance
|
||||
*/
|
||||
private fun createScreenController() =
|
||||
if (config.enableBrightnessControl)
|
||||
ScreenBrightnessController(hostActivity) else null
|
||||
|
||||
/**
|
||||
* create the gesture controller based on settings
|
||||
*/
|
||||
private fun createGestureController() =
|
||||
if (config.shouldEnablePressToSwipe)
|
||||
SwipeGestureController(hostActivity, this)
|
||||
else NoPtSSwipeGestureController(hostActivity, this)
|
||||
|
||||
|
||||
interface TouchEventListener {
|
||||
/**
|
||||
* touch event callback
|
||||
*
|
||||
* @param motionEvent the motion event that was received
|
||||
* @return intercept the event? if true, child views will not receive the event
|
||||
*/
|
||||
fun onTouchEvent(motionEvent: MotionEvent): Boolean
|
||||
}
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* attach a [SwipeControlsHostLayout] to the activity
|
||||
*
|
||||
* @param debugTouchableZone show a overlay on all zones covered by this layout
|
||||
* @return the attached instance
|
||||
*/
|
||||
@JvmStatic
|
||||
fun Activity.attachTo(debugTouchableZone: Boolean = false): SwipeControlsHostLayout {
|
||||
// get targets
|
||||
val contentView: ViewGroup = window.decorView.findViewById(android.R.id.content)!!
|
||||
var content = contentView.getChildAt(0)
|
||||
|
||||
// detach previously attached swipe host first
|
||||
if (content is SwipeControlsHostLayout) {
|
||||
contentView.removeView(content)
|
||||
content.removeAllViews()
|
||||
content = content.mainContentChild
|
||||
}
|
||||
|
||||
// create swipe host
|
||||
val swipeHost = SwipeControlsHostLayout(this, content, debugTouchableZone).apply {
|
||||
layoutParams = ViewGroup.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.MATCH_PARENT
|
||||
)
|
||||
}
|
||||
|
||||
// insert the swipe host as parent to the actual content
|
||||
contentView.removeView(content)
|
||||
contentView.addView(swipeHost)
|
||||
swipeHost.addView(content)
|
||||
return swipeHost
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user