[Android] Re-add the DPAD control on the equalizer bars

Nicolas Pomepuy git at videolan.org
Mon Mar 3 16:07:06 UTC 2025


vlc-android | branch: master | Nicolas Pomepuy <nicolas at videolabs.io> | Mon Mar  3 14:31:55 2025 +0100| [c0fddc233a24ee652750f56a87cf47ca49d98617] | committer: Duncan McNamara

Re-add the DPAD control on the equalizer bars

Fixes #3160

> https://code.videolan.org/videolan/vlc-android/commit/c0fddc233a24ee652750f56a87cf47ca49d98617
---

 .../vlc-android/res/layout/equalizer_bar.xml       |   2 +-
 .../src/org/videolan/vlc/gui/view/EqualizerBar.kt  |  10 +-
 .../org/videolan/vlc/gui/view/VerticalSeekBar.kt   | 114 +++++++++++++++++++++
 3 files changed, 119 insertions(+), 7 deletions(-)

diff --git a/application/vlc-android/res/layout/equalizer_bar.xml b/application/vlc-android/res/layout/equalizer_bar.xml
index e49a185333..86dfb3faf4 100644
--- a/application/vlc-android/res/layout/equalizer_bar.xml
+++ b/application/vlc-android/res/layout/equalizer_bar.xml
@@ -22,7 +22,7 @@
             android:layout_height="150dp"
             android:layout_gravity="center_horizontal">
 
-        <com.google.android.material.slider.Slider
+        <org.videolan.vlc.gui.view.VerticalSeekBar
                 android:id="@+id/equalizer_seek"
                 android:layout_width="0dp"
                 app:tickVisible="false"
diff --git a/application/vlc-android/src/org/videolan/vlc/gui/view/EqualizerBar.kt b/application/vlc-android/src/org/videolan/vlc/gui/view/EqualizerBar.kt
index 257841bd7e..1cd65410b5 100644
--- a/application/vlc-android/src/org/videolan/vlc/gui/view/EqualizerBar.kt
+++ b/application/vlc-android/src/org/videolan/vlc/gui/view/EqualizerBar.kt
@@ -50,12 +50,10 @@ class EqualizerBar : LinearLayout {
         verticalSlider.nextFocusRightId = nextFocusRightId
     }
 
-    private val seekListener = object : Slider.OnChangeListener {
-        override fun onValueChange(slider: Slider, value: Float, fromUser: Boolean) {
-            val value = (value - RANGE) / PRECISION.toFloat()
-            listener?.onProgressChanged(value, fromUser)
-            updateValueText()
-        }
+    private val seekListener = Slider.OnChangeListener { slider, value, fromUser ->
+        val newValue = (value - RANGE) / PRECISION.toFloat()
+        listener?.onProgressChanged(newValue, fromUser || (slider as VerticalSeekBar).fromUser)
+        updateValueText()
     }
 
     constructor(context: Context, band: Float) : super(context) {
diff --git a/application/vlc-android/src/org/videolan/vlc/gui/view/VerticalSeekBar.kt b/application/vlc-android/src/org/videolan/vlc/gui/view/VerticalSeekBar.kt
new file mode 100644
index 0000000000..4c8153985a
--- /dev/null
+++ b/application/vlc-android/src/org/videolan/vlc/gui/view/VerticalSeekBar.kt
@@ -0,0 +1,114 @@
+/*
+ * ************************************************************************
+ *  VerticalSeekBar.kt
+ * *************************************************************************
+ * Copyright © 2025 VLC authors and VideoLAN
+ * Author: Nicolas POMEPUY
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ * **************************************************************************
+ *
+ *
+ */
+
+package org.videolan.vlc.gui.view
+
+import android.content.Context
+import android.util.AttributeSet
+import android.view.KeyEvent
+import android.view.MotionEvent
+import com.google.android.material.slider.Slider
+
+class VerticalSeekBar : Slider {
+    private var listener: Slider.OnSliderTouchListener? = null
+    var fromUser = false
+
+    constructor(context: Context) : super(context) {
+        initialize()
+    }
+
+    constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
+        initialize()
+    }
+
+    constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context, attrs, defStyle) {
+        initialize()
+    }
+
+    private fun initialize() {
+
+    }
+
+    override fun addOnSliderTouchListener(listener: OnSliderTouchListener) {
+        this.listener = listener
+        super.addOnSliderTouchListener(listener)
+    }
+
+    override fun onTouchEvent(event: MotionEvent): Boolean {
+
+        val handled = super.onTouchEvent(event)
+
+        if (handled) {
+            when (event.action) {
+                MotionEvent.ACTION_DOWN -> {
+                    parent?.requestDisallowInterceptTouchEvent(true)
+                    fromUser = true
+                }
+
+                MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
+                    parent?.requestDisallowInterceptTouchEvent(false)
+                    fromUser = false
+                }
+            }
+        }
+
+        return handled
+    }
+
+
+    override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
+        if (isEnabled) {
+
+            if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT || keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) return false
+
+
+            if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN || keyCode == KeyEvent.KEYCODE_DPAD_UP) {
+                fromUser = true
+//                //to allow snaping to save current state when modifying a band from DPAD
+                listener?.onStartTrackingTouch(this)
+
+                val direction = if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) -1 else 1
+                var currentProgress = value + (direction * 10F)
+
+                if (currentProgress > valueTo) {
+                    currentProgress = valueTo
+                } else if (currentProgress < 0) {
+                    currentProgress = 0F
+                }
+                setValue(currentProgress)
+
+                return true
+            }
+        }
+
+        return super.onKeyDown(keyCode, event)
+    }
+
+    override fun onKeyUp(keyCode: Int, event: KeyEvent): Boolean {
+        fromUser = false
+        return super.onKeyUp(keyCode, event)
+    }
+
+
+}
\ No newline at end of file



More information about the Android mailing list