[Android] Refactor InputConfigFragment a little bit in preparation for the implementation of the new input overlay.

This moves all of the dialog handling into the actual MotionAlertDialog class itself. This is something I should have done a long time ago.
Also moved the Gamecube input binding preferences into their own PreferenceScreen.
This commit is contained in:
Lioncash 2013-10-24 14:55:10 -04:00
parent 69a10869bb
commit 079147ca07
4 changed files with 183 additions and 212 deletions

View File

@ -41,6 +41,7 @@
<!-- Input Config Fragment --> <!-- Input Config Fragment -->
<string name="input_settings">入力</string> <string name="input_settings">入力</string>
<string name="gamecube_bindings">ゲームキューブの入力バインディング</string>
<string name="input_binding">入力バインディング</string> <string name="input_binding">入力バインディング</string>
<string name="input_binding_descrip">%1$sにバインドするための入力を移動または押してください。</string> <string name="input_binding_descrip">%1$sにバインドするための入力を移動または押してください。</string>
<string name="button_a">Aボタン</string> <string name="button_a">Aボタン</string>

View File

@ -41,6 +41,7 @@
<!-- Input Config Fragment --> <!-- Input Config Fragment -->
<string name="input_settings">Input</string> <string name="input_settings">Input</string>
<string name="gamecube_bindings">Gamecube Input Bindings</string>
<string name="input_binding">Input Binding</string> <string name="input_binding">Input Binding</string>
<string name="input_binding_descrip">Press or move an input to bind it to %1$s.</string> <string name="input_binding_descrip">Press or move an input to bind it to %1$s.</string>
<string name="button_a">Button A</string> <string name="button_a">Button A</string>

View File

@ -1,83 +1,87 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<Preference <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
android:key="InputA" android:title="@string/input_settings">
android:title="@string/button_a" />
<Preference <PreferenceScreen android:title="@string/gamecube_bindings">
android:key="InputB" <Preference
android:title="@string/button_b" /> android:key="InputA"
android:title="@string/button_a" />
<Preference <Preference
android:key="InputX" android:key="InputB"
android:title="@string/button_x" /> android:title="@string/button_b" />
<Preference <Preference
android:key="InputY" android:key="InputX"
android:title="@string/button_y" /> android:title="@string/button_x" />
<Preference <Preference
android:key="InputZ" android:key="InputY"
android:title="@string/button_z" /> android:title="@string/button_y" />
<Preference <Preference
android:key="InputStart" android:key="InputZ"
android:title="@string/button_start" /> android:title="@string/button_z" />
<Preference <Preference
android:key="DPadUp" android:key="InputStart"
android:title="@string/dpad_up" /> android:title="@string/button_start" />
<Preference <Preference
android:key="DPadDown" android:key="DPadUp"
android:title="@string/dpad_down" /> android:title="@string/dpad_up" />
<Preference <Preference
android:key="DPadLeft" android:key="DPadDown"
android:title="@string/dpad_left" /> android:title="@string/dpad_down" />
<Preference <Preference
android:key="DPadRight" android:key="DPadLeft"
android:title="@string/dpad_right" /> android:title="@string/dpad_left" />
<Preference <Preference
android:key="MainUp" android:key="DPadRight"
android:title="@string/main_stick_up" /> android:title="@string/dpad_right" />
<Preference <Preference
android:key="MainDown" android:key="MainUp"
android:title="@string/main_stick_down" /> android:title="@string/main_stick_up" />
<Preference <Preference
android:key="MainLeft" android:key="MainDown"
android:title="@string/main_stick_left" /> android:title="@string/main_stick_down" />
<Preference <Preference
android:key="MainRight" android:key="MainLeft"
android:title="@string/main_stick_right" /> android:title="@string/main_stick_left" />
<Preference <Preference
android:key="CStickUp" android:key="MainRight"
android:title="@string/c_stick_up" /> android:title="@string/main_stick_right" />
<Preference <Preference
android:key="CStickDown" android:key="CStickUp"
android:title="@string/c_stick_down" /> android:title="@string/c_stick_up" />
<Preference <Preference
android:key="CStickLeft" android:key="CStickDown"
android:title="@string/c_stick_left" /> android:title="@string/c_stick_down" />
<Preference <Preference
android:key="CStickRight" android:key="CStickLeft"
android:title="@string/c_stick_right" /> android:title="@string/c_stick_left" />
<Preference <Preference
android:key="InputL" android:key="CStickRight"
android:title="@string/trigger_left" /> android:title="@string/c_stick_right" />
<Preference <Preference
android:key="InputR" android:key="InputL"
android:title="@string/trigger_right" /> android:title="@string/trigger_left" />
<Preference
android:key="InputR"
android:title="@string/trigger_right" />
</PreferenceScreen>
</PreferenceScreen> </PreferenceScreen>

View File

@ -6,7 +6,6 @@
package org.dolphinemu.dolphinemu.settings; package org.dolphinemu.dolphinemu.settings;
import android.app.Activity;
import android.app.AlertDialog; import android.app.AlertDialog;
import android.app.Fragment; import android.app.Fragment;
import android.content.Context; import android.content.Context;
@ -31,10 +30,6 @@ import org.dolphinemu.dolphinemu.R;
*/ */
public final class InputConfigFragment extends PreferenceFragment public final class InputConfigFragment extends PreferenceFragment
{ {
private Activity m_activity;
private boolean firstEvent = true;
private static final ArrayList<Float> m_values = new ArrayList<Float>();
/** /**
* Gets the descriptor for the given {@link InputDevice}. * Gets the descriptor for the given {@link InputDevice}.
* *
@ -92,161 +87,131 @@ public final class InputConfigFragment extends PreferenceFragment
} }
@Override @Override
public boolean onPreferenceTreeClick(final PreferenceScreen screen, final Preference pref) public boolean onPreferenceTreeClick(PreferenceScreen screen, Preference pref)
{ {
// Begin the creation of the input alert. // If the user is on the preference screen to set Gamecube input bindings.
final MotionAlertDialog dialog = new MotionAlertDialog(m_activity); if (screen.getTitle().equals(getString(R.string.gamecube_bindings)))
// Set the key listener
dialog.setOnKeyListener(new AlertDialog.OnKeyListener()
{ {
public boolean onKey(DialogInterface dlg, int keyCode, KeyEvent event) // Begin the creation of the input alert.
final MotionAlertDialog dialog = new MotionAlertDialog(getActivity(), pref);
// Set the cancel button.
dialog.setButton(AlertDialog.BUTTON_NEGATIVE, getString(R.string.cancel), new AlertDialog.OnClickListener()
{ {
Log.d("InputConfigFragment", "Received key event: " + event.getAction()); @Override
switch (event.getAction()) public void onClick(DialogInterface dialog, int which)
{ {
case KeyEvent.ACTION_DOWN: // Do nothing. Just makes the cancel button show up.
case KeyEvent.ACTION_UP:
InputDevice input = event.getDevice();
String bindStr = "Device '" + getInputDesc(input) + "'-Button " + event.getKeyCode();
NativeLibrary.SetConfig("Dolphin.ini", "Android", pref.getKey(), bindStr);
pref.setSummary(bindStr);
dialog.dismiss();
return true;
default:
break;
} }
});
return false; // Set the title and description message.
} dialog.setTitle(R.string.input_binding);
}); dialog.setMessage(String.format(getString(R.string.input_binding_descrip), pref.getTitle()));
// Set the motion event listener. // Don't allow the dialog to close when a user taps
dialog.setOnMotionEventListener(new MotionAlertDialog.OnMotionEventListener() // outside of it. They must press cancel or provide an input.
{ dialog.setCanceledOnTouchOutside(false);
public boolean onMotion(MotionEvent event)
{
if (event == null || (event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) == 0)
return false;
Log.d("InputConfigFragment", "Received motion event: " + event.getAction()); // Everything is set, show the dialog.
dialog.show();
}
InputDevice input = event.getDevice();
List<InputDevice.MotionRange> motions = input.getMotionRanges();
if (firstEvent)
{
m_values.clear();
for (InputDevice.MotionRange range : motions)
{
m_values.add(event.getAxisValue(range.getAxis()));
}
firstEvent = false;
}
else
{
for (int a = 0; a < motions.size(); ++a)
{
InputDevice.MotionRange range = motions.get(a);
if (m_values.get(a) > (event.getAxisValue(range.getAxis()) + 0.5f))
{
String bindStr = "Device '" + InputConfigFragment.getInputDesc(input) + "'-Axis " + range.getAxis() + "-";
NativeLibrary.SetConfig("Dolphin.ini", "Android", pref.getKey(), bindStr);
pref.setSummary(bindStr);
dialog.dismiss();
}
else if (m_values.get(a) < (event.getAxisValue(range.getAxis()) - 0.5f))
{
String bindStr = "Device '" + InputConfigFragment.getInputDesc(input) + "'-Axis " + range.getAxis() + "+";
NativeLibrary.SetConfig("Dolphin.ini", "Android", pref.getKey(), bindStr);
pref.setSummary(bindStr);
dialog.dismiss();
}
}
}
return true;
}
});
// Set the cancel button.
dialog.setButton(AlertDialog.BUTTON_NEGATIVE, getString(R.string.cancel), new AlertDialog.OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
// Do nothing. This just makes the cancel button appear.
}
});
// Set the title and description message.
dialog.setTitle(R.string.input_binding);
dialog.setMessage(String.format(getString(R.string.input_binding_descrip), pref.getTitle()));
// Don't allow the dialog to close when a user taps
// outside of it. They must press cancel or provide an input.
dialog.setCanceledOnTouchOutside(false);
// Everything is set, show the dialog.
dialog.show();
return true; return true;
} }
@Override
public void onAttach(Activity activity)
{
super.onAttach(activity);
// Cache the activity instance.
m_activity = activity;
}
/** /**
* {@link AlertDialog} class derivative that allows the motion listener * {@link AlertDialog} derivative that listens for
* to be set anonymously, so the creation of an explicit class for * motion events from controllers and joysticks.
* providing functionality is not necessary.
*/ */
private static final class MotionAlertDialog extends AlertDialog private static final class MotionAlertDialog extends AlertDialog
{ {
private OnMotionEventListener motionListener; // The selected input preference
private final Preference inputPref;
private boolean firstEvent = true;
private final ArrayList<Float> m_values = new ArrayList<Float>();
/** /**
* Constructor * Constructor
* *
* @param ctx context to use this dialog in. * @param ctx context to use this dialog in.
*/ */
public MotionAlertDialog(Context ctx) public MotionAlertDialog(Context ctx, Preference inputPref)
{ {
super(ctx); super(ctx);
this.inputPref = inputPref;
} }
/** @Override
* Interface which defines a callback method for general public boolean onKeyDown(int keyCode, KeyEvent event)
* motion events. This allows motion event code to be set
* in the event anonymous classes of this dialog are used.
*/
public interface OnMotionEventListener
{ {
/** Log.d("InputConfigFragment", "Received key event: " + event.getAction());
* Denotes the behavior that should happen when a motion event occurs. switch (event.getAction())
* {
* @param event Reference to the {@link MotionEvent} that occurred. case KeyEvent.ACTION_DOWN:
* case KeyEvent.ACTION_UP:
* @return true if the {@link MotionEvent} is consumed in this call; false otherwise. InputDevice input = event.getDevice();
*/ String bindStr = "Device '" + getInputDesc(input) + "'-Button " + event.getKeyCode();
boolean onMotion(MotionEvent event); NativeLibrary.SetConfig("Dolphin.ini", "Android", inputPref.getKey(), bindStr);
inputPref.setSummary(bindStr);
dismiss();
return true;
default:
break;
}
return false;
} }
/**
* Sets the motion listener. // Method that will be within dispatchGeneticMotionEvent that listens for joystick/controller movements.
* private boolean onMotionEvent(MotionEvent event)
* @param listener The motion listener to set.
*/
public void setOnMotionEventListener(OnMotionEventListener listener)
{ {
this.motionListener = listener; if ((event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) == 0)
return false;
Log.d("InputConfigFragment", "Received motion event: " + event.getAction());
InputDevice input = event.getDevice();
List<InputDevice.MotionRange> motions = input.getMotionRanges();
if (firstEvent)
{
m_values.clear();
for (InputDevice.MotionRange range : motions)
{
m_values.add(event.getAxisValue(range.getAxis()));
}
firstEvent = false;
}
else
{
for (int a = 0; a < motions.size(); ++a)
{
InputDevice.MotionRange range = motions.get(a);
if (m_values.get(a) > (event.getAxisValue(range.getAxis()) + 0.5f))
{
String bindStr = "Device '" + InputConfigFragment.getInputDesc(input) + "'-Axis " + range.getAxis() + "-";
NativeLibrary.SetConfig("Dolphin.ini", "Android", inputPref.getKey(), bindStr);
inputPref.setSummary(bindStr);
dismiss();
}
else if (m_values.get(a) < (event.getAxisValue(range.getAxis()) - 0.5f))
{
String bindStr = "Device '" + InputConfigFragment.getInputDesc(input) + "'-Axis " + range.getAxis() + "+";
NativeLibrary.SetConfig("Dolphin.ini", "Android", inputPref.getKey(), bindStr);
inputPref.setSummary(bindStr);
dismiss();
}
}
}
return true;
} }
@Override @Override
@ -261,7 +226,7 @@ public final class InputConfigFragment extends PreferenceFragment
@Override @Override
public boolean dispatchGenericMotionEvent(MotionEvent event) public boolean dispatchGenericMotionEvent(MotionEvent event)
{ {
if (motionListener.onMotion(event)) if (onMotionEvent(event))
return true; return true;
return super.dispatchGenericMotionEvent(event); return super.dispatchGenericMotionEvent(event);