mirror of
https://github.com/JustinZeus/Wholphin.git
synced 2026-07-08 23:51:21 +02:00
Fix seek bar for RTL
This commit is contained in:
parent
7ff4b0cf10
commit
01e0e7028a
2 changed files with 133 additions and 78 deletions
|
|
@ -32,6 +32,14 @@ fun isControllerMedia(event: KeyEvent) =
|
||||||
event.key == Key.ButtonL1 ||
|
event.key == Key.ButtonL1 ||
|
||||||
event.key == Key.ButtonL2
|
event.key == Key.ButtonL2
|
||||||
|
|
||||||
|
fun isDpadLeft(event: KeyEvent) =
|
||||||
|
event.key == Key.DirectionLeft ||
|
||||||
|
event.key == Key.SystemNavigationLeft
|
||||||
|
|
||||||
|
fun isDpadRight(event: KeyEvent) =
|
||||||
|
event.key == Key.DirectionRight ||
|
||||||
|
event.key == Key.SystemNavigationRight
|
||||||
|
|
||||||
fun isSkipBack(event: KeyEvent) =
|
fun isSkipBack(event: KeyEvent) =
|
||||||
event.key == Key.DirectionLeft ||
|
event.key == Key.DirectionLeft ||
|
||||||
event.key == Key.ButtonL1 ||
|
event.key == Key.ButtonL1 ||
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ package com.github.damontecres.wholphin.ui.playback.overlay
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import android.view.KeyEvent
|
|
||||||
import androidx.compose.animation.core.animateDpAsState
|
import androidx.compose.animation.core.animateDpAsState
|
||||||
import androidx.compose.foundation.Canvas
|
import androidx.compose.foundation.Canvas
|
||||||
import androidx.compose.foundation.focusable
|
import androidx.compose.foundation.focusable
|
||||||
|
|
@ -44,11 +43,16 @@ import androidx.compose.ui.graphics.StrokeCap
|
||||||
import androidx.compose.ui.input.key.KeyEventType
|
import androidx.compose.ui.input.key.KeyEventType
|
||||||
import androidx.compose.ui.input.key.onPreviewKeyEvent
|
import androidx.compose.ui.input.key.onPreviewKeyEvent
|
||||||
import androidx.compose.ui.input.key.type
|
import androidx.compose.ui.input.key.type
|
||||||
|
import androidx.compose.ui.platform.LocalLayoutDirection
|
||||||
|
import androidx.compose.ui.unit.LayoutDirection
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.tv.material3.MaterialTheme
|
import androidx.tv.material3.MaterialTheme
|
||||||
import com.github.damontecres.wholphin.ui.playback.ControllerViewState
|
import com.github.damontecres.wholphin.ui.playback.ControllerViewState
|
||||||
import com.github.damontecres.wholphin.ui.playback.calculateSeekAccelerationMultiplier
|
import com.github.damontecres.wholphin.ui.playback.calculateSeekAccelerationMultiplier
|
||||||
|
import com.github.damontecres.wholphin.ui.playback.isDpadLeft
|
||||||
|
import com.github.damontecres.wholphin.ui.playback.isDpadRight
|
||||||
import kotlinx.coroutines.FlowPreview
|
import kotlinx.coroutines.FlowPreview
|
||||||
|
import timber.log.Timber
|
||||||
import kotlin.time.Duration
|
import kotlin.time.Duration
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -174,6 +178,7 @@ private fun SeekBarDisplay(
|
||||||
modifier: Modifier = Modifier,
|
modifier: Modifier = Modifier,
|
||||||
enabled: Boolean = true,
|
enabled: Boolean = true,
|
||||||
) {
|
) {
|
||||||
|
val isLtr = LocalLayoutDirection.current == LayoutDirection.Ltr
|
||||||
val color = MaterialTheme.colorScheme.border
|
val color = MaterialTheme.colorScheme.border
|
||||||
val onSurface = MaterialTheme.colorScheme.onSurface
|
val onSurface = MaterialTheme.colorScheme.onSurface
|
||||||
|
|
||||||
|
|
@ -192,70 +197,75 @@ private fun SeekBarDisplay(
|
||||||
.height(animatedIndicatorHeight)
|
.height(animatedIndicatorHeight)
|
||||||
.padding(horizontal = 4.dp)
|
.padding(horizontal = 4.dp)
|
||||||
.onPreviewKeyEvent { event ->
|
.onPreviewKeyEvent { event ->
|
||||||
when (event.nativeKeyEvent.keyCode) {
|
if (!isDpadLeft(event) && !isDpadRight(event)) {
|
||||||
KeyEvent.KEYCODE_DPAD_LEFT, KeyEvent.KEYCODE_SYSTEM_NAVIGATION_LEFT -> {
|
Timber.v("Ignoring %s", event)
|
||||||
when (event.type) {
|
return@onPreviewKeyEvent false
|
||||||
KeyEventType.KeyDown -> {
|
}
|
||||||
val repeatCount = event.nativeKeyEvent.repeatCount
|
val seekBack =
|
||||||
if (repeatCount > 0) {
|
if (isLtr) {
|
||||||
leftHandledByRepeat = true
|
isDpadLeft(event)
|
||||||
onLeft.invoke(
|
} else {
|
||||||
calculateSeekAccelerationMultiplier(
|
isDpadRight(event)
|
||||||
repeatCount = repeatCount,
|
}
|
||||||
durationMs = durationMs,
|
if (seekBack) {
|
||||||
),
|
when (event.type) {
|
||||||
)
|
KeyEventType.KeyDown -> {
|
||||||
} else {
|
val repeatCount = event.nativeKeyEvent.repeatCount
|
||||||
leftHandledByRepeat = false
|
if (repeatCount > 0) {
|
||||||
}
|
leftHandledByRepeat = true
|
||||||
}
|
onLeft.invoke(
|
||||||
|
calculateSeekAccelerationMultiplier(
|
||||||
KeyEventType.KeyUp -> {
|
repeatCount = repeatCount,
|
||||||
if (!leftHandledByRepeat) {
|
durationMs = durationMs,
|
||||||
onLeft.invoke(1)
|
),
|
||||||
}
|
)
|
||||||
|
} else {
|
||||||
leftHandledByRepeat = false
|
leftHandledByRepeat = false
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> {
|
|
||||||
return@onPreviewKeyEvent false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return@onPreviewKeyEvent true
|
|
||||||
}
|
|
||||||
|
|
||||||
KeyEvent.KEYCODE_DPAD_RIGHT, KeyEvent.KEYCODE_SYSTEM_NAVIGATION_RIGHT -> {
|
KeyEventType.KeyUp -> {
|
||||||
when (event.type) {
|
if (!leftHandledByRepeat) {
|
||||||
KeyEventType.KeyDown -> {
|
onLeft.invoke(1)
|
||||||
val repeatCount = event.nativeKeyEvent.repeatCount
|
|
||||||
if (repeatCount > 0) {
|
|
||||||
rightHandledByRepeat = true
|
|
||||||
onRight.invoke(
|
|
||||||
calculateSeekAccelerationMultiplier(
|
|
||||||
repeatCount = repeatCount,
|
|
||||||
durationMs = durationMs,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
rightHandledByRepeat = false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
leftHandledByRepeat = false
|
||||||
|
}
|
||||||
|
|
||||||
KeyEventType.KeyUp -> {
|
else -> {
|
||||||
if (!rightHandledByRepeat) {
|
return@onPreviewKeyEvent false
|
||||||
onRight.invoke(1)
|
}
|
||||||
}
|
}
|
||||||
|
return@onPreviewKeyEvent true
|
||||||
|
} else {
|
||||||
|
when (event.type) {
|
||||||
|
KeyEventType.KeyDown -> {
|
||||||
|
val repeatCount = event.nativeKeyEvent.repeatCount
|
||||||
|
if (repeatCount > 0) {
|
||||||
|
rightHandledByRepeat = true
|
||||||
|
onRight.invoke(
|
||||||
|
calculateSeekAccelerationMultiplier(
|
||||||
|
repeatCount = repeatCount,
|
||||||
|
durationMs = durationMs,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
rightHandledByRepeat = false
|
rightHandledByRepeat = false
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> {
|
|
||||||
return@onPreviewKeyEvent false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return@onPreviewKeyEvent true
|
|
||||||
|
KeyEventType.KeyUp -> {
|
||||||
|
if (!rightHandledByRepeat) {
|
||||||
|
onRight.invoke(1)
|
||||||
|
}
|
||||||
|
rightHandledByRepeat = false
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {
|
||||||
|
return@onPreviewKeyEvent false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return@onPreviewKeyEvent true
|
||||||
}
|
}
|
||||||
false
|
|
||||||
}.focusable(enabled = enabled, interactionSource = interactionSource),
|
}.focusable(enabled = enabled, interactionSource = interactionSource),
|
||||||
onDraw = {
|
onDraw = {
|
||||||
val yOffset = size.height.div(2)
|
val yOffset = size.height.div(2)
|
||||||
|
|
@ -266,33 +276,70 @@ private fun SeekBarDisplay(
|
||||||
strokeWidth = size.height,
|
strokeWidth = size.height,
|
||||||
cap = StrokeCap.Round,
|
cap = StrokeCap.Round,
|
||||||
)
|
)
|
||||||
drawLine(
|
if (isLtr) {
|
||||||
color = onSurface.copy(alpha = .65f),
|
drawLine(
|
||||||
start = Offset(x = 0f, y = yOffset),
|
color = onSurface.copy(alpha = .65f),
|
||||||
end =
|
start = Offset(x = 0f, y = yOffset),
|
||||||
Offset(
|
end =
|
||||||
x = size.width.times(bufferedProgress),
|
Offset(
|
||||||
y = yOffset,
|
x = size.width.times(bufferedProgress),
|
||||||
),
|
y = yOffset,
|
||||||
strokeWidth = size.height,
|
),
|
||||||
cap = StrokeCap.Round,
|
strokeWidth = size.height,
|
||||||
)
|
cap = StrokeCap.Round,
|
||||||
drawLine(
|
)
|
||||||
color = color,
|
drawLine(
|
||||||
start = Offset(x = 0f, y = yOffset),
|
color = color,
|
||||||
end =
|
start = Offset(x = 0f, y = yOffset),
|
||||||
Offset(
|
end =
|
||||||
// x = size.width.times(if (isSelected) seekProgress else progress),
|
Offset(
|
||||||
x = size.width.times(progress),
|
x = size.width.times(progress),
|
||||||
y = yOffset,
|
y = yOffset,
|
||||||
),
|
),
|
||||||
strokeWidth = size.height,
|
strokeWidth = size.height,
|
||||||
cap = StrokeCap.Round,
|
cap = StrokeCap.Round,
|
||||||
)
|
)
|
||||||
|
} else {
|
||||||
|
drawLine(
|
||||||
|
color = onSurface.copy(alpha = .65f),
|
||||||
|
start =
|
||||||
|
Offset(
|
||||||
|
x = size.width - size.width.times(bufferedProgress),
|
||||||
|
y = yOffset,
|
||||||
|
),
|
||||||
|
end =
|
||||||
|
Offset(
|
||||||
|
x = size.width,
|
||||||
|
y = yOffset,
|
||||||
|
),
|
||||||
|
strokeWidth = size.height,
|
||||||
|
cap = StrokeCap.Round,
|
||||||
|
)
|
||||||
|
drawLine(
|
||||||
|
color = color,
|
||||||
|
start = Offset(x = size.width - size.width.times(progress), y = yOffset),
|
||||||
|
end =
|
||||||
|
Offset(
|
||||||
|
x = size.width,
|
||||||
|
y = yOffset,
|
||||||
|
),
|
||||||
|
strokeWidth = size.height,
|
||||||
|
cap = StrokeCap.Round,
|
||||||
|
)
|
||||||
|
}
|
||||||
drawCircle(
|
drawCircle(
|
||||||
color = Color.White,
|
color = Color.White,
|
||||||
radius = size.height + 2,
|
radius = size.height + 2,
|
||||||
center = Offset(x = size.width.times(progress), y = yOffset),
|
center =
|
||||||
|
Offset(
|
||||||
|
x =
|
||||||
|
if (isLtr) {
|
||||||
|
size.width.times(progress)
|
||||||
|
} else {
|
||||||
|
size.width - size.width.times(progress)
|
||||||
|
},
|
||||||
|
y = yOffset,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue