mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-24 22:59:47 -06:00
Android: Make input mapping view holders observe input state changes
This commit is contained in:
@ -18,6 +18,8 @@ class CoreDevice private constructor(private val pointer: Long) {
|
|||||||
@Keep
|
@Keep
|
||||||
inner class Control private constructor(private val pointer: Long) {
|
inner class Control private constructor(private val pointer: Long) {
|
||||||
external fun getName(): String
|
external fun getName(): String
|
||||||
|
|
||||||
|
external fun getState(): Double
|
||||||
}
|
}
|
||||||
|
|
||||||
protected external fun finalize()
|
protected external fun finalize()
|
||||||
|
@ -18,6 +18,9 @@ class InputMappingControlSetting(var control: Control, val controller: EmulatedC
|
|||||||
controller.updateSingleControlReference(controlReference)
|
controller.updateSingleControlReference(controlReference)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val state: Double
|
||||||
|
get() = controlReference.getState()
|
||||||
|
|
||||||
fun clearValue() {
|
fun clearValue() {
|
||||||
value = ""
|
value = ""
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ import java.util.function.Consumer
|
|||||||
|
|
||||||
class AdvancedMappingControlAdapter(
|
class AdvancedMappingControlAdapter(
|
||||||
private val parentLifecycle: Lifecycle,
|
private val parentLifecycle: Lifecycle,
|
||||||
|
private val isInput: Boolean,
|
||||||
private val onClickCallback: Consumer<String>
|
private val onClickCallback: Consumer<String>
|
||||||
) : RecyclerView.Adapter<AdvancedMappingControlViewHolder>() {
|
) : RecyclerView.Adapter<AdvancedMappingControlViewHolder>() {
|
||||||
|
|
||||||
@ -23,7 +24,7 @@ class AdvancedMappingControlAdapter(
|
|||||||
): AdvancedMappingControlViewHolder {
|
): AdvancedMappingControlViewHolder {
|
||||||
val inflater = LayoutInflater.from(parent.context)
|
val inflater = LayoutInflater.from(parent.context)
|
||||||
val binding = ListItemAdvancedMappingControlBinding.inflate(inflater)
|
val binding = ListItemAdvancedMappingControlBinding.inflate(inflater)
|
||||||
return AdvancedMappingControlViewHolder(binding, parentLifecycle, onClickCallback)
|
return AdvancedMappingControlViewHolder(binding, parentLifecycle, isInput, onClickCallback)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: AdvancedMappingControlViewHolder, position: Int) =
|
override fun onBindViewHolder(holder: AdvancedMappingControlViewHolder, position: Int) =
|
||||||
|
@ -4,13 +4,16 @@ package org.dolphinemu.dolphinemu.features.input.ui
|
|||||||
|
|
||||||
import androidx.lifecycle.Lifecycle
|
import androidx.lifecycle.Lifecycle
|
||||||
import org.dolphinemu.dolphinemu.databinding.ListItemAdvancedMappingControlBinding
|
import org.dolphinemu.dolphinemu.databinding.ListItemAdvancedMappingControlBinding
|
||||||
|
import org.dolphinemu.dolphinemu.features.input.model.ControllerInterface
|
||||||
import org.dolphinemu.dolphinemu.features.input.model.CoreDevice
|
import org.dolphinemu.dolphinemu.features.input.model.CoreDevice
|
||||||
import org.dolphinemu.dolphinemu.utils.LifecycleViewHolder
|
import org.dolphinemu.dolphinemu.utils.LifecycleViewHolder
|
||||||
|
import org.dolphinemu.dolphinemu.utils.Log
|
||||||
import java.util.function.Consumer
|
import java.util.function.Consumer
|
||||||
|
|
||||||
class AdvancedMappingControlViewHolder(
|
class AdvancedMappingControlViewHolder(
|
||||||
private val binding: ListItemAdvancedMappingControlBinding,
|
private val binding: ListItemAdvancedMappingControlBinding,
|
||||||
parentLifecycle: Lifecycle,
|
private val parentLifecycle: Lifecycle,
|
||||||
|
private val isInput: Boolean,
|
||||||
onClickCallback: Consumer<String>
|
onClickCallback: Consumer<String>
|
||||||
) : LifecycleViewHolder(binding.root, parentLifecycle) {
|
) : LifecycleViewHolder(binding.root, parentLifecycle) {
|
||||||
|
|
||||||
@ -18,10 +21,28 @@ class AdvancedMappingControlViewHolder(
|
|||||||
|
|
||||||
init {
|
init {
|
||||||
binding.root.setOnClickListener { onClickCallback.accept(control.getName()) }
|
binding.root.setOnClickListener { onClickCallback.accept(control.getName()) }
|
||||||
|
if (isInput) {
|
||||||
|
ControllerInterface.inputStateChanged.observe(this) {
|
||||||
|
updateInputValue()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun bind(control: CoreDevice.Control) {
|
fun bind(control: CoreDevice.Control) {
|
||||||
this.control = control
|
this.control = control
|
||||||
binding.textName.text = control.getName()
|
binding.textName.text = control.getName()
|
||||||
|
if (isInput) {
|
||||||
|
updateInputValue()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateInputValue() {
|
||||||
|
if (parentLifecycle.currentState == Lifecycle.State.DESTROYED) {
|
||||||
|
throw IllegalStateException("AdvancedMappingControlViewHolder leak")
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
Log.info("AdvancedMappingControlViewHolder: Value of " + control.getName() + " is " +
|
||||||
|
control.getState())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
package org.dolphinemu.dolphinemu.features.input.ui
|
package org.dolphinemu.dolphinemu.features.input.ui
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.view.KeyEvent
|
||||||
|
import android.view.MotionEvent
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.AdapterView
|
import android.widget.AdapterView
|
||||||
import android.widget.AdapterView.OnItemClickListener
|
import android.widget.AdapterView.OnItemClickListener
|
||||||
@ -38,7 +40,7 @@ class AdvancedMappingDialog(
|
|||||||
ArrayAdapter(context, android.R.layout.simple_spinner_dropdown_item, devices)
|
ArrayAdapter(context, android.R.layout.simple_spinner_dropdown_item, devices)
|
||||||
binding.dropdownDevice.setAdapter(deviceAdapter)
|
binding.dropdownDevice.setAdapter(deviceAdapter)
|
||||||
|
|
||||||
controlAdapter = AdvancedMappingControlAdapter(lifecycle) {
|
controlAdapter = AdvancedMappingControlAdapter(lifecycle, controlReference.isInput()) {
|
||||||
control: String -> onControlClicked(control)
|
control: String -> onControlClicked(control)
|
||||||
}
|
}
|
||||||
binding.listControl.adapter = controlAdapter
|
binding.listControl.adapter = controlAdapter
|
||||||
@ -60,6 +62,16 @@ class AdvancedMappingDialog(
|
|||||||
override fun onItemClick(adapterView: AdapterView<*>?, view: View, position: Int, id: Long) =
|
override fun onItemClick(adapterView: AdapterView<*>?, view: View, position: Int, id: Long) =
|
||||||
setSelectedDevice(devices[position])
|
setSelectedDevice(devices[position])
|
||||||
|
|
||||||
|
override fun dispatchKeyEvent(event: KeyEvent): Boolean {
|
||||||
|
ControllerInterface.dispatchKeyEvent(event)
|
||||||
|
return super.dispatchKeyEvent(event)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun dispatchGenericMotionEvent(event: MotionEvent): Boolean {
|
||||||
|
ControllerInterface.dispatchGenericMotionEvent(event)
|
||||||
|
return super.dispatchGenericMotionEvent(event)
|
||||||
|
}
|
||||||
|
|
||||||
private fun setSelectedDevice(deviceString: String) {
|
private fun setSelectedDevice(deviceString: String) {
|
||||||
selectedDevice = deviceString
|
selectedDevice = deviceString
|
||||||
|
|
||||||
|
@ -3,11 +3,14 @@
|
|||||||
package org.dolphinemu.dolphinemu.features.input.ui.viewholder
|
package org.dolphinemu.dolphinemu.features.input.ui.viewholder
|
||||||
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import androidx.lifecycle.Lifecycle
|
||||||
import org.dolphinemu.dolphinemu.databinding.ListItemMappingBinding
|
import org.dolphinemu.dolphinemu.databinding.ListItemMappingBinding
|
||||||
|
import org.dolphinemu.dolphinemu.features.input.model.ControllerInterface
|
||||||
import org.dolphinemu.dolphinemu.features.input.model.view.InputMappingControlSetting
|
import org.dolphinemu.dolphinemu.features.input.model.view.InputMappingControlSetting
|
||||||
import org.dolphinemu.dolphinemu.features.settings.model.view.SettingsItem
|
import org.dolphinemu.dolphinemu.features.settings.model.view.SettingsItem
|
||||||
import org.dolphinemu.dolphinemu.features.settings.ui.SettingsAdapter
|
import org.dolphinemu.dolphinemu.features.settings.ui.SettingsAdapter
|
||||||
import org.dolphinemu.dolphinemu.features.settings.ui.viewholder.SettingViewHolder
|
import org.dolphinemu.dolphinemu.features.settings.ui.viewholder.SettingViewHolder
|
||||||
|
import org.dolphinemu.dolphinemu.utils.Log
|
||||||
|
|
||||||
class InputMappingControlSettingViewHolder(
|
class InputMappingControlSettingViewHolder(
|
||||||
private val binding: ListItemMappingBinding,
|
private val binding: ListItemMappingBinding,
|
||||||
@ -15,6 +18,12 @@ class InputMappingControlSettingViewHolder(
|
|||||||
) : SettingViewHolder(binding.getRoot(), adapter) {
|
) : SettingViewHolder(binding.getRoot(), adapter) {
|
||||||
lateinit var setting: InputMappingControlSetting
|
lateinit var setting: InputMappingControlSetting
|
||||||
|
|
||||||
|
init {
|
||||||
|
ControllerInterface.inputStateChanged.observe(this) {
|
||||||
|
updateInputValue()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override val item: SettingsItem
|
override val item: SettingsItem
|
||||||
get() = setting
|
get() = setting
|
||||||
|
|
||||||
@ -26,6 +35,7 @@ class InputMappingControlSettingViewHolder(
|
|||||||
binding.buttonAdvancedSettings.setOnClickListener { clicked: View -> onLongClick(clicked) }
|
binding.buttonAdvancedSettings.setOnClickListener { clicked: View -> onLongClick(clicked) }
|
||||||
|
|
||||||
setStyle(binding.textSettingName, setting)
|
setStyle(binding.textSettingName, setting)
|
||||||
|
updateInputValue()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onClick(clicked: View) {
|
override fun onClick(clicked: View) {
|
||||||
@ -52,4 +62,16 @@ class InputMappingControlSettingViewHolder(
|
|||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun updateInputValue() {
|
||||||
|
if (adapter.getFragmentLifecycle().currentState == Lifecycle.State.DESTROYED) {
|
||||||
|
throw IllegalStateException("InputMappingControlSettingViewHolder leak")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (setting.isInput) {
|
||||||
|
// TODO
|
||||||
|
Log.info("InputMappingControlSettingViewHolder: Value of " + setting.name + " is " +
|
||||||
|
setting.state)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,9 @@ import android.content.DialogInterface
|
|||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.view.KeyEvent
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
|
import android.view.MotionEvent
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.activity.enableEdgeToEdge
|
import androidx.activity.enableEdgeToEdge
|
||||||
@ -22,11 +24,11 @@ import androidx.core.view.WindowInsetsCompat
|
|||||||
import androidx.fragment.app.DialogFragment
|
import androidx.fragment.app.DialogFragment
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
import com.google.android.material.appbar.CollapsingToolbarLayout
|
import com.google.android.material.appbar.CollapsingToolbarLayout
|
||||||
import com.google.android.material.color.MaterialColors
|
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import org.dolphinemu.dolphinemu.NativeLibrary
|
import org.dolphinemu.dolphinemu.NativeLibrary
|
||||||
import org.dolphinemu.dolphinemu.R
|
import org.dolphinemu.dolphinemu.R
|
||||||
import org.dolphinemu.dolphinemu.databinding.ActivitySettingsBinding
|
import org.dolphinemu.dolphinemu.databinding.ActivitySettingsBinding
|
||||||
|
import org.dolphinemu.dolphinemu.features.input.model.ControllerInterface
|
||||||
import org.dolphinemu.dolphinemu.features.settings.model.Settings
|
import org.dolphinemu.dolphinemu.features.settings.model.Settings
|
||||||
import org.dolphinemu.dolphinemu.features.settings.ui.SettingsFragment.Companion.newInstance
|
import org.dolphinemu.dolphinemu.features.settings.ui.SettingsFragment.Companion.newInstance
|
||||||
import org.dolphinemu.dolphinemu.ui.main.MainPresenter
|
import org.dolphinemu.dolphinemu.ui.main.MainPresenter
|
||||||
@ -197,6 +199,16 @@ class SettingsActivity : AppCompatActivity(), SettingsActivityView {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun dispatchKeyEvent(event: KeyEvent): Boolean {
|
||||||
|
ControllerInterface.dispatchKeyEvent(event)
|
||||||
|
return super.dispatchKeyEvent(event)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun dispatchGenericMotionEvent(event: MotionEvent): Boolean {
|
||||||
|
ControllerInterface.dispatchGenericMotionEvent(event)
|
||||||
|
return super.dispatchGenericMotionEvent(event)
|
||||||
|
}
|
||||||
|
|
||||||
private fun canonicalizeIfPossible(uri: Uri): Uri {
|
private fun canonicalizeIfPossible(uri: Uri): Uri {
|
||||||
val canonicalizedUri = contentResolver.canonicalize(uri)
|
val canonicalizedUri = contentResolver.canonicalize(uri)
|
||||||
return canonicalizedUri ?: uri
|
return canonicalizedUri ?: uri
|
||||||
|
@ -64,6 +64,13 @@ Java_org_dolphinemu_dolphinemu_features_input_model_CoreDevice_00024Control_getN
|
|||||||
return ToJString(env, GetControlPointer(env, obj)->GetName());
|
return ToJString(env, GetControlPointer(env, obj)->GetName());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jdouble JNICALL
|
||||||
|
Java_org_dolphinemu_dolphinemu_features_input_model_CoreDevice_00024Control_getState(JNIEnv* env,
|
||||||
|
jobject obj)
|
||||||
|
{
|
||||||
|
return env, GetControlPointer(env, obj)->ToInput()->GetState();
|
||||||
|
}
|
||||||
|
|
||||||
JNIEXPORT void JNICALL
|
JNIEXPORT void JNICALL
|
||||||
Java_org_dolphinemu_dolphinemu_features_input_model_CoreDevice_finalize(JNIEnv* env, jobject obj)
|
Java_org_dolphinemu_dolphinemu_features_input_model_CoreDevice_finalize(JNIEnv* env, jobject obj)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user