Skip to content

Commit

Permalink
fix: swipe-controls incompatible with disable-fullscreen-panels (#88
Browse files Browse the repository at this point in the history
)

* base swipe rect calculations on player surface bound
  • Loading branch information
shadow578 committed Jul 18, 2022
1 parent 5e04dfc commit 1f9b01c
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 45 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@ package app.revanced.integrations.swipecontrols.controller

import android.content.Context
import android.util.TypedValue
import android.view.View
import app.revanced.integrations.shared.LayoutChangeEventArgs
import app.revanced.integrations.shared.PlayerOverlays
import android.view.ViewGroup
import app.revanced.integrations.swipecontrols.misc.Rectangle
import app.revanced.integrations.swipecontrols.misc.applyDimension
import app.revanced.integrations.utils.ReVancedUtils
import kotlin.math.min

/**
/**
* Y- Axis:
* -------- 0
* ^
Expand Down Expand Up @@ -37,6 +36,7 @@ import app.revanced.integrations.utils.ReVancedUtils
@Suppress("PrivatePropertyName")
class SwipeZonesController(
context: Context,
private val parentView: ViewGroup,
private val fallbackScreenRect: () -> Rectangle
) {
/**
Expand All @@ -55,57 +55,26 @@ class SwipeZonesController(
private val _80dp = 80.applyDimension(context, TypedValue.COMPLEX_UNIT_DIP)

/**
* id for R.id.engagement_panel
* id for R.id.player_view
*/
private val engagementPanelId =
ReVancedUtils.getResourceIdByName(context, "id", "engagement_panel")
private val playerViewId = ReVancedUtils.getResourceIdByName(context, "id", "player_view")

/**
* current bounding rectangle of the player overlays
* current bounding rectangle of the player
*/
private var playerRect: Rectangle? = null

/**
* current bounding rectangle of the engagement_panel
*/
private var engagementPanelRect = Rectangle(0, 0, 0, 0)

/**
* listener for player overlays layout change
*/
private fun onOverlaysLayoutChanged(args: LayoutChangeEventArgs) {
// update engagement panel bounds
val engagementPanel = args.overlaysLayout.findViewById<View>(engagementPanelId)
engagementPanelRect =
if (engagementPanel == null || engagementPanel.visibility != View.VISIBLE) {
Rectangle(0, 0, 0, 0)
} else {
Rectangle(
engagementPanel.x.toInt(),
engagementPanel.y.toInt(),
engagementPanel.width,
engagementPanel.height
)
}

// update player bounds
playerRect = args.newRect
}

init {
PlayerOverlays.onLayoutChange += this::onOverlaysLayoutChanged
}

/**
* rectangle of the area that is effectively usable for swipe controls
*/
private val effectiveSwipeRect: Rectangle
get() {
maybeAttachPlayerBoundsListener()
val p = if (playerRect != null) playerRect!! else fallbackScreenRect()
return Rectangle(
p.x + _20dp,
p.y + _40dp,
p.width - engagementPanelRect.width - _20dp,
p.width - _20dp,
p.height - _20dp - _80dp
)
}
Expand All @@ -115,12 +84,13 @@ class SwipeZonesController(
*/
val volume: Rectangle
get() {
val zoneWidth = (effectiveSwipeRect.width * 3) / 8
val eRect = effectiveSwipeRect
val zoneWidth = (eRect.width * 3) / 8
return Rectangle(
effectiveSwipeRect.right - zoneWidth,
effectiveSwipeRect.top,
eRect.right - zoneWidth,
eRect.top,
zoneWidth,
effectiveSwipeRect.height
eRect.height
)
}

Expand All @@ -137,4 +107,39 @@ class SwipeZonesController(
effectiveSwipeRect.height
)
}

/**
* try to attach a listener to the player_view and update the player rectangle.
* once a listener is attached, this function does nothing
*/
private fun maybeAttachPlayerBoundsListener() {
if (playerRect != null) return
parentView.findViewById<ViewGroup>(playerViewId)?.let {
onPlayerViewLayout(it)
it.addOnLayoutChangeListener { _, _, _, _, _, _, _, _, _ ->
onPlayerViewLayout(it)
}
}
}

/**
* update the player rectangle on player_view layout
*
* @param playerView the player view
*/
private fun onPlayerViewLayout(playerView: ViewGroup) {
playerView.getChildAt(0)?.let { playerSurface ->
// the player surface is centered in the player view
// figure out the width of the surface including the padding (same on the left and right side)
// and use that width for the player rectangle size
// this automatically excludes any engagement panel from the rect
val playerWidthWithPadding = playerSurface.width + (playerSurface.x.toInt() * 2)
playerRect = Rectangle(
playerView.x.toInt(),
playerView.y.toInt(),
min(playerView.width, playerWidthWithPadding),
playerView.height
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,9 @@ class SwipeControlsHostLayout(
}

// create swipe zone controller
zones = SwipeZonesController(context) { Rectangle(x.toInt(), y.toInt(), width, height) }
zones = SwipeZonesController(context, this) {
Rectangle(x.toInt(), y.toInt(), width, height)
}

// listen for changes in the player type
PlayerType.onChange += this::onPlayerTypeChanged
Expand Down

0 comments on commit 1f9b01c

Please sign in to comment.