Trigger slider feedback only at intervals of 5%.

This commit is contained in:
codokie 2024-08-12 09:30:51 +03:00
parent e4abd73151
commit 93ce34ebec
3 changed files with 30 additions and 10 deletions

View File

@ -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() + "%"
}

View File

@ -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)

View File

@ -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
}
}
}