Commit 0a0048dd authored by Nicolas Pomepuy's avatar Nicolas Pomepuy

Video player seek new UI

parent d6761645
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/playerbackground">
</solid>
<corners
android:bottomRightRadius="75dp"
android:topRightRadius="75dp"/>
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/playerbackground">
</solid>
<corners
android:bottomLeftRadius="75dp"
android:topLeftRadius="75dp"/>
</shape>
\ No newline at end of file
......@@ -6,6 +6,13 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.constraintlayout.widget.Guideline
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/guideline11"
app:layout_constraintGuide_percent="0.5"/>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
......@@ -13,12 +20,35 @@
android:id="@+id/seek_background"
android:background="@drawable/video_list_length_bg" />
<org.videolan.vlc.gui.view.HalfCircleView
android:id="@+id/leftContainerBackground"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginEnd="8dp"
app:is_left="true"
android:alpha="0"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@id/guideline4"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"/>
<org.videolan.vlc.gui.view.HalfCircleView
android:id="@+id/rightContainerBackground"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="8dp"
app:is_left="false"
android:alpha="0"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@+id/guideline6"
app:layout_constraintTop_toTopOf="parent"/>
<com.google.android.material.circularreveal.CircularRevealFrameLayout
android:id="@+id/leftContainer"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginEnd="8dp"
android:layout_marginBottom="8dp"
android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@id/guideline4"
......@@ -46,42 +76,41 @@
<!--app:layout_constraintStart_toStartOf="parent"-->
<!--app:layout_constraintTop_toTopOf="parent">-->
<ImageView
android:id="@+id/seekRewindSecond"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:alpha="0"
app:srcCompat="@drawable/ic_half_seek_rewind"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/seekRewindFirst"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="@+id/seekLeftText"
app:layout_constraintTop_toTopOf="parent"
/>
<ImageView
android:id="@+id/seekRewindFirst"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:alpha="0"
app:srcCompat="@drawable/ic_half_seek_rewind"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/seekLeftText"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/seekRewindSecond"
app:layout_constraintTop_toTopOf="parent"/>
<TextView
android:id="@+id/seekLeftText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginTop="16dp"
android:textSize="18sp"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/seekRewindSecond"/>
<ImageView
android:id="@+id/seekRewindSecond"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:alpha="0"
app:srcCompat="@drawable/ic_half_seek_rewind"
app:layout_constraintEnd_toStartOf="@+id/seekRewindFirst"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="@+id/seekLeftText"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toTopOf="@+id/guideline11"/>
<ImageView
android:id="@+id/seekRewindFirst"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:alpha="0"
app:srcCompat="@drawable/ic_half_seek_rewind"
app:layout_constraintEnd_toEndOf="@+id/seekLeftText"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/seekRewindSecond"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toTopOf="@+id/guideline11"/>
<TextView
android:id="@+id/seekLeftText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginTop="8dp"
android:textSize="18sp"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/guideline11"/>
<!--</androidx.constraintlayout.widget.ConstraintLayout>-->
<!--<androidx.constraintlayout.widget.ConstraintLayout-->
......@@ -94,42 +123,41 @@
<!--app:layout_constraintStart_toEndOf="@id/guideline6"-->
<!--app:layout_constraintTop_toTopOf="parent">-->
<ImageView
android:id="@+id/seekForwardFirst"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:alpha="0"
app:srcCompat="@drawable/ic_half_seek_forward"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/seekForwardSecond"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="@+id/seekRightText"
app:layout_constraintTop_toTopOf="parent"
/>
<ImageView
android:id="@+id/seekForwardSecond"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:alpha="0"
app:srcCompat="@drawable/ic_half_seek_forward"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/seekRightText"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/seekForwardFirst"
app:layout_constraintTop_toTopOf="parent"/>
<ImageView
android:id="@+id/seekForwardFirst"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:alpha="0"
app:srcCompat="@drawable/ic_half_seek_forward"
app:layout_constraintEnd_toStartOf="@+id/seekForwardSecond"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="@+id/seekRightText"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toTopOf="@+id/guideline11"/>
<ImageView
android:id="@+id/seekForwardSecond"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:alpha="0"
app:srcCompat="@drawable/ic_half_seek_forward"
app:layout_constraintEnd_toEndOf="@+id/seekRightText"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/seekForwardFirst"
android:layout_marginBottom="8dp"
app:layout_constraintBottom_toTopOf="@+id/guideline11"/>
<TextView
android:id="@+id/seekRightText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="32dp"
android:textSize="18sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/seekForwardFirst"/>
app:layout_constraintTop_toTopOf="@+id/guideline11"/>
<!--</androidx.constraintlayout.widget.ConstraintLayout>-->
......
......@@ -88,6 +88,10 @@
<attr name="bar_color" format="reference"/>
</declare-styleable>
<declare-styleable name="HalfCircleView">
<attr name="is_left" format="boolean"/>
</declare-styleable>
<attr name="marginTopContent" format="dimension" />
</resources>
......@@ -20,6 +20,7 @@
package org.videolan.vlc.gui.video
import android.animation.Animator
import android.animation.AnimatorSet
import android.animation.ArgbEvaluator
import android.animation.ObjectAnimator
......@@ -43,6 +44,7 @@ import android.text.TextWatcher
import android.util.DisplayMetrics
import android.util.Log
import android.util.Rational
import android.util.TypedValue
import android.view.*
import android.view.View.OnClickListener
import android.view.View.OnLongClickListener
......@@ -106,7 +108,6 @@ import org.videolan.vlc.repository.ExternalSubRepository
import org.videolan.vlc.repository.SlaveRepository
import org.videolan.vlc.util.*
import org.videolan.vlc.viewmodels.PlaylistModel
import java.util.*
@Suppress("DEPRECATION")
@ObsoleteCoroutinesApi
......@@ -1971,6 +1972,7 @@ open class VideoPlayerActivity : AppCompatActivity(), IPlaybackSettingsControlle
private var nbTimesTaped = 0
private var lastSeekWasForward = true
private var seekAnimRunning = false
internal fun seekDelta(delta: Int) {
service?.let { service ->
// unseekable stream
......@@ -1999,6 +2001,7 @@ open class VideoPlayerActivity : AppCompatActivity(), IPlaybackSettingsControlle
initSeekOverlay()
val container = if (seekForward) rightContainer else leftContainer
val containerBackground = if (seekForward) rightContainerBackground else leftContainerBackground
val textView = if (seekForward) seekRightText else seekLeftText
val imageFirst = if (seekForward) seekForwardFirst else seekRewindFirst
val imageSecond = if (seekForward) seekForwardSecond else seekRewindSecond
......@@ -2009,10 +2012,18 @@ open class VideoPlayerActivity : AppCompatActivity(), IPlaybackSettingsControlle
if (isTv) {
val seekTVConstraintSet = ConstraintSet()
seekTVConstraintSet.clone(seekContainer)
seekTVConstraintSet.connect(R.id.seekLeftText, ConstraintSet.END, ConstraintSet.PARENT_ID, ConstraintSet.END)
seekTVConstraintSet.setMargin(R.id.seekLeftText, ConstraintSet.START, 0)
seekTVConstraintSet.connect(R.id.seekRightText, ConstraintSet.START, ConstraintSet.PARENT_ID, ConstraintSet.START)
seekTVConstraintSet.setMargin(R.id.seekRightText, ConstraintSet.END, 0)
seekTVConstraintSet.clear(R.id.rightContainerBackground, ConstraintSet.START)
seekTVConstraintSet.constrainDefaultHeight(R.id.rightContainerBackground, ConstraintSet.MATCH_CONSTRAINT_WRAP)
seekTVConstraintSet.constrainHeight(R.id.rightContainerBackground, 175.dp)
seekTVConstraintSet.constrainWidth(R.id.rightContainerBackground, 300.dp)
seekTVConstraintSet.setMargin(R.id.seekRightText, ConstraintSet.END, 16.dp)
seekTVConstraintSet.clear(R.id.leftContainerBackground, ConstraintSet.END)
seekTVConstraintSet.constrainDefaultHeight(R.id.leftContainerBackground, ConstraintSet.MATCH_CONSTRAINT_WRAP)
seekTVConstraintSet.constrainHeight(R.id.leftContainerBackground, 175.dp)
seekTVConstraintSet.constrainWidth(R.id.leftContainerBackground, 300.dp)
seekTVConstraintSet.setMargin(R.id.seekLeftText, ConstraintSet.START, 16.dp)
seekRightText.setTextSize(TypedValue.COMPLEX_UNIT_SP, 22f)
seekLeftText.setTextSize(TypedValue.COMPLEX_UNIT_SP, 22f)
seekTVConstraintSet.applyTo(seekContainer)
}
......@@ -2035,18 +2046,32 @@ open class VideoPlayerActivity : AppCompatActivity(), IPlaybackSettingsControlle
ArgbEvaluator(),
Color.TRANSPARENT, ContextCompat.getColor(this, R.color.ripple_white), Color.TRANSPARENT)
if (isTv) animatorSet.playTogether(
backgroundAnim,
firstImageAnim,
secondImageAnim
)
else animatorSet.playTogether(
circularReveal,
backgroundColorAnimator,
backgroundAnim,
firstImageAnim,
secondImageAnim
)
val containerBackgroundAnim = ObjectAnimator.ofFloat(containerBackground, "alpha", 0f, 1f)
containerBackgroundAnim.duration = SEEK_TIMEOUT
val textAnim = ObjectAnimator.ofFloat(textView, "alpha", 0f, 1f)
textAnim.duration = SEEK_TIMEOUT
val anims: ArrayList<Animator> = arrayListOf(firstImageAnim, secondImageAnim)
if (!isTv) {
anims.add(backgroundColorAnimator)
anims.add(circularReveal)
}
if (!seekAnimRunning) {
anims.add(containerBackgroundAnim)
}
if (!seekAnimRunning) {
anims.add(textAnim)
}
seekAnimRunning = true
seekRightText.animate().cancel()
seekLeftText.animate().cancel()
rightContainerBackground.animate().cancel()
leftContainerBackground.animate().cancel()
animatorSet.playTogether(anims)
animatorSet.duration = 1000
val mainAnimOut = ObjectAnimator.ofFloat(seek_background, "alpha", 0f)
......@@ -2057,7 +2082,7 @@ open class VideoPlayerActivity : AppCompatActivity(), IPlaybackSettingsControlle
handler.removeMessages(HIDE_SEEK)
handler.sendEmptyMessageDelayed(HIDE_SEEK, SEEK_TIMEOUT.toLong())
handler.sendEmptyMessageDelayed(HIDE_SEEK, SEEK_TIMEOUT)
container.visibility = View.VISIBLE
seekAnimatorSet.start()
......@@ -2067,10 +2092,13 @@ open class VideoPlayerActivity : AppCompatActivity(), IPlaybackSettingsControlle
}
private fun hideSeekOverlay() {
seekAnimRunning = false
rightContainer.visibility = View.INVISIBLE
leftContainer.visibility = View.INVISIBLE
seekRightText.text = ""
seekLeftText.text = ""
seekRightText.animate().alpha(0f).withEndAction { seekRightText.text = "" }
seekLeftText.animate().alpha(0f).withEndAction { seekLeftText.text = "" }
rightContainerBackground.animate().alpha(0f)
leftContainerBackground.animate().alpha(0f)
nbTimesTaped = 0
seekForwardFirst.alpha = 0f
seekForwardSecond.alpha = 0f
......@@ -2840,7 +2868,7 @@ open class VideoPlayerActivity : AppCompatActivity(), IPlaybackSettingsControlle
private const val KEY_TIME = "saved_time"
private const val KEY_URI = "saved_uri"
private const val OVERLAY_TIMEOUT = 4000
private const val SEEK_TIMEOUT = 1500
private const val SEEK_TIMEOUT = 750L
private const val OVERLAY_INFINITE = -1
private const val FADE_OUT = 1
private const val FADE_OUT_INFO = 2
......
package org.videolan.vlc.gui.view
import android.content.Context
import android.graphics.Canvas
import android.graphics.Paint
import android.util.AttributeSet
import android.view.View
import androidx.core.content.ContextCompat
import org.videolan.vlc.R
import org.videolan.vlc.util.Settings
class HalfCircleView : View {
private var isLeft: Boolean = true
private val paint = Paint()
constructor(context: Context) : super(context) {
initialize()
}
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
initAttributes(attrs, 0)
initialize()
}
constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) {
initAttributes(attrs, 0)
initialize()
}
private fun initAttributes(attrs: AttributeSet, defStyle: Int) {
attrs.let {
val a = context.theme.obtainStyledAttributes(attrs, R.styleable.HalfCircleView, 0, defStyle)
try {
isLeft = a.getBoolean(R.styleable.HalfCircleView_is_left, true)
} catch (e: Exception) {
} finally {
a.recycle()
}
}
}
private fun initialize() {
paint.color = ContextCompat.getColor(context, R.color.blacktransparent)
if (Settings.showTvUi) {
background = ContextCompat.getDrawable(context, if (isLeft) R.drawable.half_circle_tv_left else R.drawable.half_circle_tv_right)
} else {
background = null
}
}
override fun onDraw(canvas: Canvas?) {
if (!Settings.showTvUi) {
val cx = if (isLeft) -width else width * 2
val cy = height / 2
canvas?.drawCircle(cx.toFloat(), cy.toFloat(), height.toFloat(), paint)
}
super.onDraw(canvas)
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment