Merge pull request #14023 from JosJuice/android-overlay-ok

Android: Treat EmulationActivity dialog dismiss the same as OK
This commit is contained in:
JosJuice 2025-11-16 18:36:08 +01:00 committed by GitHub
commit 56532c850f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 63 additions and 27 deletions

View File

@ -8,6 +8,8 @@ import android.graphics.Rect
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.util.SparseIntArray
import android.view.KeyEvent
import android.view.MenuItem
@ -61,6 +63,7 @@ import org.dolphinemu.dolphinemu.ui.main.ThemeProvider
import org.dolphinemu.dolphinemu.utils.AfterDirectoryInitializationRunner
import org.dolphinemu.dolphinemu.utils.DirectoryInitialization
import org.dolphinemu.dolphinemu.utils.FileBrowserHelper
import org.dolphinemu.dolphinemu.utils.RateLimiter
import org.dolphinemu.dolphinemu.utils.ThemeHelper
import kotlin.math.roundToInt
@ -88,6 +91,10 @@ class EmulationActivity : AppCompatActivity(), ThemeProvider {
private lateinit var binding: ActivityEmulationBinding
private val refreshInputOverlayRateLimiter = RateLimiter(Handler(Looper.getMainLooper()), 100) {
emulationFragment?.refreshInputOverlay()
}
private val requestChangeDisc = registerForActivityResult(
ActivityResultContracts.GetContent()
) { uri: Uri? ->
@ -561,6 +568,7 @@ class EmulationActivity : AppCompatActivity(), ThemeProvider {
) { _: DialogInterface?, indexSelected: Int, isChecked: Boolean ->
BooleanSetting.valueOf(gcSettingBase + indexSelected)
.setBoolean(settings, isChecked)
emulationFragment?.refreshInputOverlay()
}
}
InputOverlay.OVERLAY_WIIMOTE_CLASSIC -> {
@ -575,6 +583,7 @@ class EmulationActivity : AppCompatActivity(), ThemeProvider {
) { _: DialogInterface?, indexSelected: Int, isChecked: Boolean ->
BooleanSetting.valueOf(classicSettingBase + indexSelected)
.setBoolean(settings, isChecked)
emulationFragment?.refreshInputOverlay()
}
}
InputOverlay.OVERLAY_WIIMOTE_NUNCHUK -> {
@ -596,6 +605,7 @@ class EmulationActivity : AppCompatActivity(), ThemeProvider {
) { _: DialogInterface?, indexSelected: Int, isChecked: Boolean ->
BooleanSetting.valueOf(nunchukSettingBase + translateToSettingsIndex(indexSelected))
.setBoolean(settings, isChecked)
emulationFragment?.refreshInputOverlay()
}
}
else -> {
@ -611,14 +621,13 @@ class EmulationActivity : AppCompatActivity(), ThemeProvider {
) { _: DialogInterface?, indexSelected: Int, isChecked: Boolean ->
BooleanSetting.valueOf(wiimoteSettingBase + indexSelected)
.setBoolean(settings, isChecked)
emulationFragment?.refreshInputOverlay()
}
}
}
builder
.setPositiveButton(R.string.ok) { _: DialogInterface?, _: Int ->
emulationFragment?.refreshInputOverlay()
}
.setPositiveButton(R.string.ok, null)
.show()
}
@ -640,6 +649,7 @@ class EmulationActivity : AppCompatActivity(), ThemeProvider {
) { _: DialogInterface?, indexSelected: Int, isChecked: Boolean ->
BooleanSetting
.valueOf(gcSettingBase + indexSelected).setBoolean(settings, isChecked)
emulationFragment?.refreshInputOverlay()
}
} else if (currentController == InputOverlay.OVERLAY_WIIMOTE_CLASSIC) {
val wiiClassicEnabledButtons = BooleanArray(14)
@ -653,6 +663,7 @@ class EmulationActivity : AppCompatActivity(), ThemeProvider {
) { _: DialogInterface?, indexSelected: Int, isChecked: Boolean ->
BooleanSetting.valueOf(classicSettingBase + indexSelected)
.setBoolean(settings, isChecked)
emulationFragment?.refreshInputOverlay()
}
} else {
val wiiEnabledButtons = BooleanArray(11)
@ -667,6 +678,7 @@ class EmulationActivity : AppCompatActivity(), ThemeProvider {
) { _: DialogInterface?, indexSelected: Int, isChecked: Boolean ->
BooleanSetting
.valueOf(wiiSettingBase + indexSelected).setBoolean(settings, isChecked)
emulationFragment?.refreshInputOverlay()
}
} else {
builder.setMultiChoiceItems(
@ -674,6 +686,7 @@ class EmulationActivity : AppCompatActivity(), ThemeProvider {
) { _: DialogInterface?, indexSelected: Int, isChecked: Boolean ->
BooleanSetting
.valueOf(wiiSettingBase + indexSelected).setBoolean(settings, isChecked)
emulationFragment?.refreshInputOverlay()
}
}
}
@ -682,7 +695,7 @@ class EmulationActivity : AppCompatActivity(), ThemeProvider {
.setNeutralButton(R.string.emulation_toggle_all) { _: DialogInterface?, _: Int ->
emulationFragment!!.toggleInputOverlayVisibility(settings)
}
.setPositiveButton(R.string.ok) { _: DialogInterface?, _: Int -> emulationFragment?.refreshInputOverlay() }
.setPositiveButton(R.string.ok, null)
.show()
}
@ -707,10 +720,9 @@ class EmulationActivity : AppCompatActivity(), ThemeProvider {
settings,
InputOverlayPointer.DOUBLE_TAP_OPTIONS[which]
)
}
.setPositiveButton(R.string.ok) { _: DialogInterface?, _: Int ->
emulationFragment?.initInputPointer()
}
.setPositiveButton(R.string.ok, null)
.show()
}
@ -721,9 +733,11 @@ class EmulationActivity : AppCompatActivity(), ThemeProvider {
valueTo = 150f
value = IntSetting.MAIN_CONTROL_SCALE.int.toFloat()
stepSize = 1f
addOnChangeListener(Slider.OnChangeListener { _: Slider?, progress: Float, _: Boolean ->
dialogBinding.inputScaleValue.text = "${(progress.toInt() + 50)}%"
})
addOnChangeListener { _: Slider?, value: Float, _: Boolean ->
dialogBinding.inputScaleValue.text = "${(value.toInt() + 50)}%"
IntSetting.MAIN_CONTROL_SCALE.setInt(settings, value.toInt())
refreshInputOverlayRateLimiter.run()
}
}
inputScaleValue.text =
"${(dialogBinding.inputScaleSlider.value.toInt() + 50)}%"
@ -732,9 +746,11 @@ class EmulationActivity : AppCompatActivity(), ThemeProvider {
valueTo = 100f
value = IntSetting.MAIN_CONTROL_OPACITY.int.toFloat()
stepSize = 1f
addOnChangeListener(Slider.OnChangeListener { _: Slider?, progress: Float, _: Boolean ->
inputOpacityValue.text = progress.toInt().toString() + "%"
})
addOnChangeListener { _: Slider?, value: Float, _: Boolean ->
inputOpacityValue.text = value.toInt().toString() + "%"
IntSetting.MAIN_CONTROL_OPACITY.setInt(settings, value.toInt())
refreshInputOverlayRateLimiter.run()
}
}
inputOpacityValue.text = inputOpacitySlider.value.toInt().toString() + "%"
}
@ -742,17 +758,7 @@ class EmulationActivity : AppCompatActivity(), ThemeProvider {
MaterialAlertDialogBuilder(this)
.setTitle(R.string.emulation_control_adjustments)
.setView(dialogBinding.root)
.setPositiveButton(R.string.ok) { _: DialogInterface?, _: Int ->
IntSetting.MAIN_CONTROL_SCALE.setInt(
settings,
dialogBinding.inputScaleSlider.value.toInt()
)
IntSetting.MAIN_CONTROL_OPACITY.setInt(
settings,
dialogBinding.inputOpacitySlider.value.toInt()
)
emulationFragment?.refreshInputOverlay()
}
.setPositiveButton(R.string.ok, null)
.setNeutralButton(R.string.default_values) { _: DialogInterface?, _: Int ->
IntSetting.MAIN_CONTROL_SCALE.delete(settings)
IntSetting.MAIN_CONTROL_OPACITY.delete(settings)
@ -858,10 +864,9 @@ class EmulationActivity : AppCompatActivity(), ThemeProvider {
entries.toArray(arrayOf<CharSequence>()), checkedItem
) { _: DialogInterface?, indexSelected: Int ->
controllerSetting.setInt(settings, values[indexSelected])
}
.setPositiveButton(R.string.ok) { _: DialogInterface?, _: Int ->
emulationFragment?.refreshInputOverlay()
}
.setPositiveButton(R.string.ok, null)
.setNeutralButton(
R.string.emulation_more_controller_settings
) { _: DialogInterface?, _: Int -> SettingsActivity.launch(this, MenuTag.SETTINGS) }
@ -876,10 +881,9 @@ class EmulationActivity : AppCompatActivity(), ThemeProvider {
IntSetting.MAIN_IR_MODE.int
) { _: DialogInterface?, indexSelected: Int ->
IntSetting.MAIN_IR_MODE.setInt(settings, indexSelected)
}
.setPositiveButton(R.string.ok) { _: DialogInterface?, _: Int ->
emulationFragment?.refreshOverlayPointer()
}
.setPositiveButton(R.string.ok, null)
.show()
}

View File

@ -0,0 +1,32 @@
// SPDX-License-Identifier: GPL-2.0-or-later
package org.dolphinemu.dolphinemu.utils
import android.os.Handler
import android.os.SystemClock
class RateLimiter(
private val handler: Handler,
private val delayBetweenRunsMs: Int,
private val runnable: Runnable
) {
private var nextAllowedRun = 0L
private var pendingRun = false
fun run() {
if (!pendingRun) {
val time = SystemClock.uptimeMillis()
if (time >= nextAllowedRun) {
runnable.run()
nextAllowedRun = time + delayBetweenRunsMs
} else {
pendingRun = true
handler.postAtTime({
runnable.run()
nextAllowedRun = SystemClock.uptimeMillis() + delayBetweenRunsMs
pendingRun = false
}, nextAllowedRun)
}
}
}
}