From 93ce34ebece0c1dea64c3fe2f99b3fe7d597f9b1 Mon Sep 17 00:00:00 2001 From: codokie <151087174+codokie@users.noreply.github.com> Date: Mon, 12 Aug 2024 09:30:51 +0300 Subject: [PATCH] Trigger slider feedback only at intervals of 5%. --- .../activities/EmulationActivity.kt | 14 ++++++----- .../features/settings/ui/SettingsAdapter.kt | 2 +- .../dolphinemu/utils/HapticListener.kt | 24 ++++++++++++++++--- 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.kt index fd8b342ab6..1a1a1b517d 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.kt +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.kt @@ -704,9 +704,10 @@ class EmulationActivity : AppCompatActivity(), ThemeProvider { value = IntSetting.MAIN_CONTROL_SCALE.int.toFloat() stepSize = 1f addOnChangeListener( - HapticListener.wrapOnChangeListener { _: Slider, progress: Float, _: Boolean -> - dialogBinding.inputScaleValue.text = "${(progress.toInt() + 50)}%" - }) + HapticListener.wrapOnChangeListener({ _: Slider, progress: Float, _: Boolean -> + dialogBinding.inputScaleValue.text = "${(progress.toInt() + 50)}%" + }, value) + ) } inputScaleValue.text = "${(dialogBinding.inputScaleSlider.value.toInt() + 50)}%" @@ -716,9 +717,10 @@ class EmulationActivity : AppCompatActivity(), ThemeProvider { value = IntSetting.MAIN_CONTROL_OPACITY.int.toFloat() stepSize = 1f addOnChangeListener( - HapticListener.wrapOnChangeListener { _: Slider, progress: Float, _: Boolean -> - inputOpacityValue.text = progress.toInt().toString() + "%" - }) + HapticListener.wrapOnChangeListener({ _: Slider, progress: Float, _: Boolean -> + inputOpacityValue.text = progress.toInt().toString() + "%" + }, value) + ) } inputOpacityValue.text = inputOpacitySlider.value.toInt().toString() + "%" } diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsAdapter.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsAdapter.kt index 222df6868f..63e2ae72dc 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsAdapter.kt +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsAdapter.kt @@ -262,7 +262,7 @@ class SettingsAdapter( } } slider.value = (seekbarProgress / slider.stepSize).roundToInt() * slider.stepSize - slider.addOnChangeListener(HapticListener.wrapOnChangeListener(this)) + slider.addOnChangeListener(HapticListener.wrapOnChangeListener(this, slider.value)) dialog = MaterialAlertDialogBuilder(fragmentView.fragmentActivity) .setTitle(item.name) diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/HapticListener.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/HapticListener.kt index 97d27cfd81..d8cfe3ead1 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/HapticListener.kt +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/HapticListener.kt @@ -7,7 +7,7 @@ import androidx.core.view.ViewCompat import com.google.android.material.slider.Slider /** - * Wrapper class that enhances listeners with haptic feedback. + * Wrapper object that enhances listeners with haptic feedback. */ object HapticListener { @@ -31,15 +31,33 @@ object HapticListener { /** * Wraps a [Slider.OnChangeListener] with haptic feedback. + * Feedback is provided at intervals of 5% to prevent excessive vibrations. * * @param listener The [Slider.OnChangeListener] to be wrapped. Can be null. + * @param initialValue The value used to initialize the slider. * @return A new listener which wraps [listener] with haptic feedback. */ - fun wrapOnChangeListener(listener: Slider.OnChangeListener?): Slider.OnChangeListener { + fun wrapOnChangeListener(listener: Slider.OnChangeListener?, initialValue: Float): Slider.OnChangeListener { + var previousValue = initialValue return Slider.OnChangeListener { slider: Slider, value: Float, fromUser: Boolean -> listener?.onValueChange(slider, value, fromUser) if (fromUser) { - ViewCompat.performHapticFeedback(slider, HapticFeedbackConstantsCompat.CLOCK_TICK) + val interval = (slider.valueTo - slider.valueFrom) * 0.05f + val previousInterval = kotlin.math.round(previousValue / interval) * interval + val valueChange = kotlin.math.abs(value - previousInterval) + val feedbackConstant = if (value == slider.valueFrom || value == slider.valueTo) { + HapticFeedbackConstantsCompat.CONTEXT_CLICK + } else if (value == previousValue || valueChange >= interval) { + HapticFeedbackConstantsCompat.CLOCK_TICK + } else { + HapticFeedbackConstantsCompat.NO_HAPTICS + } + if (feedbackConstant != HapticFeedbackConstantsCompat.NO_HAPTICS) { + ViewCompat.performHapticFeedback(slider, feedbackConstant) + previousValue = value + } + } else { + previousValue = value } } }