Android: Convert AdvancedMappingDialog to Kotlin

This commit is contained in:
Charles Lombardo 2023-06-10 05:17:23 -04:00
parent d049be0cad
commit 5171290bdb
2 changed files with 122 additions and 151 deletions

View File

@ -1,151 +0,0 @@
// SPDX-License-Identifier: GPL-2.0-or-later
package org.dolphinemu.dolphinemu.features.input.ui;
import android.content.Context;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import androidx.appcompat.app.AlertDialog;
import androidx.recyclerview.widget.LinearLayoutManager;
import com.google.android.material.divider.MaterialDividerItemDecoration;
import org.dolphinemu.dolphinemu.databinding.DialogAdvancedMappingBinding;
import org.dolphinemu.dolphinemu.features.input.model.ControllerInterface;
import org.dolphinemu.dolphinemu.features.input.model.CoreDevice;
import org.dolphinemu.dolphinemu.features.input.model.MappingCommon;
import org.dolphinemu.dolphinemu.features.input.model.controlleremu.ControlReference;
import org.dolphinemu.dolphinemu.features.input.model.controlleremu.EmulatedController;
import java.util.Arrays;
import java.util.Optional;
public final class AdvancedMappingDialog extends AlertDialog
implements AdapterView.OnItemClickListener
{
private final DialogAdvancedMappingBinding mBinding;
private final ControlReference mControlReference;
private final EmulatedController mController;
private final String[] mDevices;
private final AdvancedMappingControlAdapter mControlAdapter;
private String mSelectedDevice;
public AdvancedMappingDialog(Context context, DialogAdvancedMappingBinding binding,
ControlReference controlReference, EmulatedController controller)
{
super(context);
mBinding = binding;
mControlReference = controlReference;
mController = controller;
mDevices = ControllerInterface.getAllDeviceStrings();
// TODO: Remove workaround for text filtering issue in material components when fixed
// https://github.com/material-components/material-components-android/issues/1464
mBinding.dropdownDevice.setSaveEnabled(false);
binding.dropdownDevice.setOnItemClickListener(this);
ArrayAdapter<String> deviceAdapter = new ArrayAdapter<>(
context, android.R.layout.simple_spinner_dropdown_item, mDevices);
binding.dropdownDevice.setAdapter(deviceAdapter);
mControlAdapter = new AdvancedMappingControlAdapter(this::onControlClicked);
mBinding.listControl.setAdapter(mControlAdapter);
mBinding.listControl.setLayoutManager(new LinearLayoutManager(context));
MaterialDividerItemDecoration divider =
new MaterialDividerItemDecoration(context, LinearLayoutManager.VERTICAL);
divider.setLastItemDecorated(false);
mBinding.listControl.addItemDecoration(divider);
binding.editExpression.setText(controlReference.getExpression());
selectDefaultDevice();
}
public String getExpression()
{
return mBinding.editExpression.getText().toString();
}
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id)
{
setSelectedDevice(mDevices[position]);
}
private void setSelectedDevice(String deviceString)
{
mSelectedDevice = deviceString;
CoreDevice device = ControllerInterface.getDevice(deviceString);
if (device == null)
setControls(new CoreDevice.Control[0]);
else if (mControlReference.isInput())
setControls(device.getInputs());
else
setControls(device.getOutputs());
}
private void setControls(CoreDevice.Control[] controls)
{
mControlAdapter.setControls(
Arrays.stream(controls)
.map(CoreDevice.Control::getName)
.toArray(String[]::new));
}
private void onControlClicked(String control)
{
String expression = MappingCommon.getExpressionForControl(control, mSelectedDevice,
mController.getDefaultDevice());
int start = Math.max(mBinding.editExpression.getSelectionStart(), 0);
int end = Math.max(mBinding.editExpression.getSelectionEnd(), 0);
mBinding.editExpression.getText().replace(
Math.min(start, end), Math.max(start, end), expression, 0, expression.length());
}
private void selectDefaultDevice()
{
String defaultDevice = mController.getDefaultDevice();
boolean isInput = mControlReference.isInput();
if (Arrays.asList(mDevices).contains(defaultDevice) &&
(isInput || deviceHasOutputs(defaultDevice)))
{
// The default device is available, and it's an appropriate choice. Pick it
setSelectedDevice(defaultDevice);
mBinding.dropdownDevice.setText(defaultDevice, false);
return;
}
else if (!isInput)
{
// Find the first device that has an output. (Most built-in devices don't have any)
Optional<String> deviceWithOutputs = Arrays.stream(mDevices)
.filter(AdvancedMappingDialog::deviceHasOutputs)
.findFirst();
if (deviceWithOutputs.isPresent())
{
setSelectedDevice(deviceWithOutputs.get());
mBinding.dropdownDevice.setText(deviceWithOutputs.get(), false);
return;
}
}
// Nothing found
setSelectedDevice("");
}
private static boolean deviceHasOutputs(String deviceString)
{
CoreDevice device = ControllerInterface.getDevice(deviceString);
return device != null && device.getOutputs().length > 0;
}
}

View File

@ -0,0 +1,122 @@
// SPDX-License-Identifier: GPL-2.0-or-later
package org.dolphinemu.dolphinemu.features.input.ui
import android.content.Context
import android.view.View
import android.widget.AdapterView
import android.widget.AdapterView.OnItemClickListener
import android.widget.ArrayAdapter
import androidx.appcompat.app.AlertDialog
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.divider.MaterialDividerItemDecoration
import org.dolphinemu.dolphinemu.databinding.DialogAdvancedMappingBinding
import org.dolphinemu.dolphinemu.features.input.model.ControllerInterface
import org.dolphinemu.dolphinemu.features.input.model.CoreDevice
import org.dolphinemu.dolphinemu.features.input.model.MappingCommon
import org.dolphinemu.dolphinemu.features.input.model.controlleremu.ControlReference
import org.dolphinemu.dolphinemu.features.input.model.controlleremu.EmulatedController
class AdvancedMappingDialog(
context: Context,
private val binding: DialogAdvancedMappingBinding,
private val controlReference: ControlReference,
private val controller: EmulatedController
) : AlertDialog(context), OnItemClickListener {
private val devices: Array<String> = ControllerInterface.getAllDeviceStrings()
private val controlAdapter: AdvancedMappingControlAdapter
private lateinit var selectedDevice: String
init {
// TODO: Remove workaround for text filtering issue in material components when fixed
// https://github.com/material-components/material-components-android/issues/1464
binding.dropdownDevice.isSaveEnabled = false
binding.dropdownDevice.onItemClickListener = this
val deviceAdapter =
ArrayAdapter(context, android.R.layout.simple_spinner_dropdown_item, devices)
binding.dropdownDevice.setAdapter(deviceAdapter)
controlAdapter =
AdvancedMappingControlAdapter { control: String -> onControlClicked(control) }
binding.listControl.adapter = controlAdapter
binding.listControl.layoutManager = LinearLayoutManager(context)
val divider = MaterialDividerItemDecoration(context, LinearLayoutManager.VERTICAL)
divider.isLastItemDecorated = false
binding.listControl.addItemDecoration(divider)
binding.editExpression.setText(controlReference.getExpression())
selectDefaultDevice()
}
val expression: String
get() = binding.editExpression.text.toString()
override fun onItemClick(adapterView: AdapterView<*>?, view: View, position: Int, id: Long) =
setSelectedDevice(devices[position])
private fun setSelectedDevice(deviceString: String) {
selectedDevice = deviceString
val device = ControllerInterface.getDevice(deviceString)
if (device == null)
setControls(emptyArray())
else if (controlReference.isInput())
setControls(device.getInputs())
else
setControls(device.getOutputs())
}
private fun setControls(controls: Array<CoreDevice.Control>) =
controlAdapter.setControls(controls.map { it.getName() }.toTypedArray())
private fun onControlClicked(control: String) {
val expression =
MappingCommon.getExpressionForControl(control, selectedDevice, controller.getDefaultDevice())
val start = binding.editExpression.selectionStart.coerceAtLeast(0)
val end = binding.editExpression.selectionEnd.coerceAtLeast(0)
binding.editExpression.text?.replace(
start.coerceAtMost(end),
start.coerceAtLeast(end),
expression,
0,
expression.length
)
}
private fun selectDefaultDevice() {
val defaultDevice = controller.getDefaultDevice()
val isInput = controlReference.isInput()
if (listOf(*devices).contains(defaultDevice) &&
(isInput || deviceHasOutputs(defaultDevice))
) {
// The default device is available, and it's an appropriate choice. Pick it
setSelectedDevice(defaultDevice)
binding.dropdownDevice.setText(defaultDevice, false)
return
} else if (!isInput) {
// Find the first device that has an output. (Most built-in devices don't have any)
val deviceWithOutputs = devices.first { deviceHasOutputs(it) }
if (deviceWithOutputs.isNotEmpty()) {
setSelectedDevice(deviceWithOutputs)
binding.dropdownDevice.setText(deviceWithOutputs, false)
return
}
}
// Nothing found
setSelectedDevice("")
}
companion object {
private fun deviceHasOutputs(deviceString: String): Boolean {
val device = ControllerInterface.getDevice(deviceString)
return device != null && device.getOutputs().isNotEmpty()
}
}
}