Merge pull request #6123 from hackbar/input-fix

Android: refactor and bugfix for input settings
This commit is contained in:
Mat M
2017-10-21 18:48:54 -04:00
committed by GitHub

View File

@ -8,12 +8,9 @@ import android.view.InputDevice;
import android.view.KeyEvent; import android.view.KeyEvent;
import android.view.MotionEvent; import android.view.MotionEvent;
import org.dolphinemu.dolphinemu.NativeLibrary;
import org.dolphinemu.dolphinemu.model.settings.StringSetting;
import org.dolphinemu.dolphinemu.model.settings.view.InputBindingSetting; import org.dolphinemu.dolphinemu.model.settings.view.InputBindingSetting;
import org.dolphinemu.dolphinemu.utils.Log; import org.dolphinemu.dolphinemu.utils.Log;
import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
@ -24,9 +21,7 @@ public final class MotionAlertDialog extends AlertDialog
{ {
// The selected input preference // The selected input preference
private final InputBindingSetting setting; private final InputBindingSetting setting;
private boolean mWaitingForEvent = true;
private boolean firstEvent = true;
private final ArrayList<Float> m_values = new ArrayList<>();
/** /**
* Constructor * Constructor
@ -41,17 +36,13 @@ public final class MotionAlertDialog extends AlertDialog
this.setting = setting; this.setting = setting;
} }
@Override public boolean onKeyEvent(int keyCode, KeyEvent event)
public boolean onKeyDown(int keyCode, KeyEvent event)
{ {
Log.debug("[MotionAlertDialog] Received key event: " + event.getAction()); Log.debug("[MotionAlertDialog] Received key event: " + event.getAction());
switch (event.getAction()) switch (event.getAction())
{ {
case KeyEvent.ACTION_DOWN: case KeyEvent.ACTION_DOWN:
case KeyEvent.ACTION_UP: saveKeyInput(event);
InputDevice input = event.getDevice();
saveInput(input, event, null, false);
return true; return true;
@ -60,9 +51,20 @@ public final class MotionAlertDialog extends AlertDialog
} }
} }
@Override
public boolean dispatchKeyEvent(KeyEvent event)
{
// Handle this key if we care about it, otherwise pass it down the framework
return onKeyEvent(event.getKeyCode(), event) || super.dispatchKeyEvent(event);
}
@Override
public boolean dispatchGenericMotionEvent(MotionEvent event)
{
// Handle this event if we care about it, otherwise pass it down the framework
return onMotionEvent(event) || super.dispatchGenericMotionEvent(event);
}
// Method that will be called within dispatchGenericMotionEvent
// that handles joystick/controller movements.
private boolean onMotionEvent(MotionEvent event) private boolean onMotionEvent(MotionEvent event)
{ {
if ((event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) == 0) if ((event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) == 0)
@ -71,106 +73,78 @@ public final class MotionAlertDialog extends AlertDialog
Log.debug("[MotionAlertDialog] Received motion event: " + event.getAction()); Log.debug("[MotionAlertDialog] Received motion event: " + event.getAction());
InputDevice input = event.getDevice(); InputDevice input = event.getDevice();
List<InputDevice.MotionRange> motions = input.getMotionRanges(); List<InputDevice.MotionRange> motionRanges = input.getMotionRanges();
if (firstEvent)
{
m_values.clear();
for (InputDevice.MotionRange range : motions) int numMovedAxis = 0;
InputDevice.MotionRange lastMovedRange = null;
char lastMovedDir = '?';
if (mWaitingForEvent)
{
// Get only the axis that seem to have moved (more than .5)
for (InputDevice.MotionRange range : motionRanges)
{ {
m_values.add(event.getAxisValue(range.getAxis())); int axis = range.getAxis();
float value = event.getAxisValue(axis);
if (Math.abs(value) > 0.5f)
{
numMovedAxis++;
lastMovedRange = range;
lastMovedDir = value < 0.0f ? '-' : '+';
}
} }
firstEvent = false; // If only one axis moved, that's the winner.
} if (numMovedAxis == 1)
else
{
for (int a = 0; a < motions.size(); ++a)
{ {
InputDevice.MotionRange range = motions.get(a); mWaitingForEvent = false;
saveMotionInput(input, lastMovedRange, lastMovedDir);
if (m_values.get(a) > (event.getAxisValue(range.getAxis()) + 0.5f))
{
saveInput(input, null, range, false);
}
else if (m_values.get(a) < (event.getAxisValue(range.getAxis()) - 0.5f))
{
saveInput(input, null, range, true);
}
} }
} }
return true; return true;
} }
@Override /**
public boolean dispatchKeyEvent(KeyEvent event) * Saves the provided key input setting both to the INI file (so native code can use it) and as
* an Android preference (so it persists correctly and is human-readable.)
*
* @param keyEvent KeyEvent of this key press.
*/
private void saveKeyInput(KeyEvent keyEvent)
{ {
return onKeyDown(event.getKeyCode(), event) || super.dispatchKeyEvent(event); InputDevice device = keyEvent.getDevice();
} String bindStr = "Device '" + device.getDescriptor() + "'-Button " + keyEvent.getKeyCode();
String uiString = device.getName() + ": Button " + keyEvent.getKeyCode();
@Override saveInput(bindStr, uiString);
public boolean dispatchGenericMotionEvent(MotionEvent event)
{
return onMotionEvent(event) || super.dispatchGenericMotionEvent(event);
} }
/** /**
* Saves the provided input setting both to the INI file (so native code can use it) and as an * Saves the provided motion input setting both to the INI file (so native code can use it) and as
* Android preference (so it persists correctly, and is human-readable.) * an Android preference (so it persists correctly and is human-readable.)
* *
* @param device Required; the InputDevice from which the input event originated. * @param device InputDevice from which the input event originated.
* @param keyEvent If the event was a button push, this KeyEvent represents it and is required. * @param motionRange MotionRange of the movement
* @param motionRange If the event was an axis movement, this MotionRange represents it and is required. * @param axisDir Either '-' or '+'
* @param axisPositive If the event was an axis movement, this boolean indicates the direction and is required.
*/ */
private void saveInput(InputDevice device, KeyEvent keyEvent, InputDevice.MotionRange motionRange, boolean axisPositive) private void saveMotionInput(InputDevice device, InputDevice.MotionRange motionRange, char axisDir)
{ {
String bindStr = null; String bindStr = "Device '" + device.getDescriptor() + "'-Axis " + motionRange.getAxis() + axisDir;
String uiString = null; String uiString = device.getName() + ": Axis " + motionRange.getAxis() + axisDir;
if (keyEvent != null) saveInput(bindStr, uiString);
{ }
bindStr = "Device '" + device.getDescriptor() + "'-Button " + keyEvent.getKeyCode();
uiString = device.getName() + ": Button " + keyEvent.getKeyCode();
}
if (motionRange != null) /** Save the input string to settings and SharedPreferences, then dismiss this Dialog. */
{ private void saveInput(String bind, String ui)
if (axisPositive) {
{ setting.setValue(bind);
bindStr = "Device '" + device.getDescriptor() + "'-Axis " + motionRange.getAxis() + "+";
uiString = device.getName() + ": Axis " + motionRange.getAxis() + "+";
}
else
{
bindStr = "Device '" + device.getDescriptor() + "'-Axis " + motionRange.getAxis() + "-";
uiString = device.getName() + ": Axis " + motionRange.getAxis() + "-";
}
}
if (bindStr != null) SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getContext());
{ SharedPreferences.Editor editor = preferences.edit();
setting.setValue(bindStr);
}
else
{
Log.error("[MotionAlertDialog] Failed to save input to INI.");
}
editor.putString(setting.getKey(), ui);
if (uiString != null) editor.apply();
{
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getContext());
SharedPreferences.Editor editor = preferences.edit();
editor.putString(setting.getKey(), uiString);
editor.apply();
}
else
{
Log.error("[MotionAlertDialog] Failed to save input to preference.");
}
dismiss(); dismiss();
} }