mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-02-14 00:09:24 +01:00
[Android] Initial implementation of the new input UI.
Testing may be further required. But it should work for the most part.
This commit is contained in:
parent
18749bad68
commit
709ab1feb5
@ -22,7 +22,7 @@ import java.io.*;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.dolphinemu.dolphinemu.gamelist.GameListActivity;
|
import org.dolphinemu.dolphinemu.gamelist.GameListActivity;
|
||||||
import org.dolphinemu.dolphinemu.inputconfig.InputConfigFragment;
|
import org.dolphinemu.dolphinemu.settings.InputConfigFragment;
|
||||||
import org.dolphinemu.dolphinemu.settings.UserPreferences;
|
import org.dolphinemu.dolphinemu.settings.UserPreferences;
|
||||||
|
|
||||||
public final class DolphinEmulator<MainActivity> extends Activity
|
public final class DolphinEmulator<MainActivity> extends Activity
|
||||||
|
@ -27,9 +27,6 @@ import org.dolphinemu.dolphinemu.AboutFragment;
|
|||||||
import org.dolphinemu.dolphinemu.NativeLibrary;
|
import org.dolphinemu.dolphinemu.NativeLibrary;
|
||||||
import org.dolphinemu.dolphinemu.R;
|
import org.dolphinemu.dolphinemu.R;
|
||||||
import org.dolphinemu.dolphinemu.folderbrowser.FolderBrowser;
|
import org.dolphinemu.dolphinemu.folderbrowser.FolderBrowser;
|
||||||
import org.dolphinemu.dolphinemu.inputconfig.InputConfigAdapter;
|
|
||||||
import org.dolphinemu.dolphinemu.inputconfig.InputConfigFragment;
|
|
||||||
import org.dolphinemu.dolphinemu.inputconfig.InputConfigItem;
|
|
||||||
import org.dolphinemu.dolphinemu.settings.PrefsActivity;
|
import org.dolphinemu.dolphinemu.settings.PrefsActivity;
|
||||||
import org.dolphinemu.dolphinemu.sidemenu.SideMenuAdapter;
|
import org.dolphinemu.dolphinemu.sidemenu.SideMenuAdapter;
|
||||||
import org.dolphinemu.dolphinemu.sidemenu.SideMenuItem;
|
import org.dolphinemu.dolphinemu.sidemenu.SideMenuItem;
|
||||||
@ -49,16 +46,7 @@ public final class GameListActivity extends Activity
|
|||||||
private SideMenuAdapter mDrawerAdapter;
|
private SideMenuAdapter mDrawerAdapter;
|
||||||
private ListView mDrawerList;
|
private ListView mDrawerList;
|
||||||
|
|
||||||
/**
|
|
||||||
* Interface defining methods which handle
|
|
||||||
* the binding of specific key presses within
|
|
||||||
* the input mapping settings.
|
|
||||||
*/
|
|
||||||
public interface OnGameConfigListener
|
|
||||||
{
|
|
||||||
boolean onMotionEvent(MotionEvent event);
|
|
||||||
boolean onKeyEvent(KeyEvent event);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called from the {@link GameListFragment}.
|
* Called from the {@link GameListFragment}.
|
||||||
@ -84,8 +72,7 @@ public final class GameListActivity extends Activity
|
|||||||
dir.add(new SideMenuItem(getString(R.string.game_list), 0));
|
dir.add(new SideMenuItem(getString(R.string.game_list), 0));
|
||||||
dir.add(new SideMenuItem(getString(R.string.browse_folder), 1));
|
dir.add(new SideMenuItem(getString(R.string.browse_folder), 1));
|
||||||
dir.add(new SideMenuItem(getString(R.string.settings), 2));
|
dir.add(new SideMenuItem(getString(R.string.settings), 2));
|
||||||
dir.add(new SideMenuItem(getString(R.string.gamepad_config), 3));
|
dir.add(new SideMenuItem(getString(R.string.about), 3));
|
||||||
dir.add(new SideMenuItem(getString(R.string.about), 4));
|
|
||||||
|
|
||||||
mDrawerAdapter = new SideMenuAdapter(this, R.layout.sidemenu, dir);
|
mDrawerAdapter = new SideMenuAdapter(this, R.layout.sidemenu, dir);
|
||||||
mDrawerList.setAdapter(mDrawerAdapter);
|
mDrawerList.setAdapter(mDrawerAdapter);
|
||||||
@ -142,25 +129,9 @@ public final class GameListActivity extends Activity
|
|||||||
recreateFragment();
|
recreateFragment();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3: // Gamepad settings
|
|
||||||
{
|
|
||||||
InputConfigAdapter adapter = ((InputConfigFragment)mCurFragment).getAdapter();
|
|
||||||
for (int a = 0; a < adapter.getCount(); ++a)
|
|
||||||
{
|
|
||||||
InputConfigItem o = adapter.getItem(a);
|
|
||||||
String config = o.getConfig();
|
|
||||||
String bind = o.getBind();
|
|
||||||
String ConfigValues[] = config.split("-");
|
|
||||||
String Key = ConfigValues[0];
|
|
||||||
String Value = ConfigValues[1];
|
|
||||||
NativeLibrary.SetConfig("Dolphin.ini", Key, Value, bind);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0: // Game List
|
case 0: // Game List
|
||||||
case 2: // Settings
|
case 2: // Settings
|
||||||
case 4: // About
|
case 3: // About
|
||||||
/* Do Nothing */
|
/* Do Nothing */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -197,16 +168,6 @@ public final class GameListActivity extends Activity
|
|||||||
case 3:
|
case 3:
|
||||||
{
|
{
|
||||||
mCurFragmentNum = 3;
|
mCurFragmentNum = 3;
|
||||||
mCurFragment = new InputConfigFragment();
|
|
||||||
FragmentManager fragmentManager = getFragmentManager();
|
|
||||||
fragmentManager.beginTransaction().replace(R.id.content_frame, mCurFragment).commit();
|
|
||||||
invalidateOptionsMenu();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 4:
|
|
||||||
{
|
|
||||||
mCurFragmentNum = 4;
|
|
||||||
mCurFragment = new AboutFragment();
|
mCurFragment = new AboutFragment();
|
||||||
FragmentManager fragmentManager = getFragmentManager();
|
FragmentManager fragmentManager = getFragmentManager();
|
||||||
fragmentManager.beginTransaction().replace(R.id.content_frame, mCurFragment).commit();
|
fragmentManager.beginTransaction().replace(R.id.content_frame, mCurFragment).commit();
|
||||||
@ -322,30 +283,4 @@ public final class GameListActivity extends Activity
|
|||||||
{
|
{
|
||||||
SwitchPage(0);
|
SwitchPage(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets move(triggers, joystick) events
|
|
||||||
@Override
|
|
||||||
public boolean dispatchGenericMotionEvent(MotionEvent event)
|
|
||||||
{
|
|
||||||
if (mCurFragmentNum == 3)
|
|
||||||
{
|
|
||||||
if (((OnGameConfigListener)mCurFragment).onMotionEvent(event))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return super.dispatchGenericMotionEvent(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Gets button presses
|
|
||||||
@Override
|
|
||||||
public boolean dispatchKeyEvent(KeyEvent event)
|
|
||||||
{
|
|
||||||
if (mCurFragmentNum == 3)
|
|
||||||
{
|
|
||||||
if (((OnGameConfigListener)mCurFragment).onKeyEvent(event))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return super.dispatchKeyEvent(event);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,70 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright 2013 Dolphin Emulator Project
|
|
||||||
* Licensed under GPLv2
|
|
||||||
* Refer to the license.txt file included.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.dolphinemu.dolphinemu.inputconfig;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.ArrayAdapter;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.dolphinemu.dolphinemu.R;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The adapter backing the input mapping configuration.
|
|
||||||
* <p>
|
|
||||||
* Responsible for handling the list items.
|
|
||||||
*/
|
|
||||||
public final class InputConfigAdapter extends ArrayAdapter<InputConfigItem>
|
|
||||||
{
|
|
||||||
private final Context c;
|
|
||||||
private final int id;
|
|
||||||
private final List<InputConfigItem> items;
|
|
||||||
|
|
||||||
public InputConfigAdapter(Context context, int textViewResourceId, List<InputConfigItem> objects)
|
|
||||||
{
|
|
||||||
super(context, textViewResourceId, objects);
|
|
||||||
c = context;
|
|
||||||
id = textViewResourceId;
|
|
||||||
items = objects;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public InputConfigItem getItem(int i)
|
|
||||||
{
|
|
||||||
return items.get(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public View getView(int position, View convertView, ViewGroup parent)
|
|
||||||
{
|
|
||||||
View v = convertView;
|
|
||||||
if (v == null)
|
|
||||||
{
|
|
||||||
LayoutInflater vi = (LayoutInflater)c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
|
||||||
v = vi.inflate(id, parent, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
final InputConfigItem item = items.get(position);
|
|
||||||
if (item != null)
|
|
||||||
{
|
|
||||||
TextView title = (TextView) v.findViewById(R.id.FolderTitle);
|
|
||||||
TextView subtitle = (TextView) v.findViewById(R.id.FolderSubTitle);
|
|
||||||
|
|
||||||
if (title != null)
|
|
||||||
title.setText(item.getName());
|
|
||||||
|
|
||||||
if (subtitle != null)
|
|
||||||
subtitle.setText(item.getBind());
|
|
||||||
}
|
|
||||||
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,217 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright 2013 Dolphin Emulator Project
|
|
||||||
* Licensed under GPLv2
|
|
||||||
* Refer to the license.txt file included.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.dolphinemu.dolphinemu.inputconfig;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.app.Fragment;
|
|
||||||
import android.os.Build;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.*;
|
|
||||||
import android.widget.AdapterView;
|
|
||||||
import android.widget.ListView;
|
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.dolphinemu.dolphinemu.R;
|
|
||||||
import org.dolphinemu.dolphinemu.gamelist.GameListActivity;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The {@link Fragment} responsible for implementing the functionality
|
|
||||||
* within the input control mapping config.
|
|
||||||
*/
|
|
||||||
public final class InputConfigFragment extends Fragment
|
|
||||||
implements GameListActivity.OnGameConfigListener
|
|
||||||
{
|
|
||||||
private Activity m_activity;
|
|
||||||
private ListView mDrawerList;
|
|
||||||
private InputConfigAdapter adapter;
|
|
||||||
private int configPosition = 0;
|
|
||||||
private boolean Configuring = false;
|
|
||||||
private boolean firstEvent = true;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the descriptor for the given {@link InputDevice}.
|
|
||||||
*
|
|
||||||
* @param input The {@link InputDevice} to get the descriptor of.
|
|
||||||
*
|
|
||||||
* @return the descriptor for the given {@link InputDevice}.
|
|
||||||
*/
|
|
||||||
public static String getInputDesc(InputDevice input)
|
|
||||||
{
|
|
||||||
if (input == null)
|
|
||||||
return "null"; // Happens when the inputdevice is from an unknown source
|
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
|
|
||||||
{
|
|
||||||
return input.getDescriptor();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
List<InputDevice.MotionRange> motions = input.getMotionRanges();
|
|
||||||
String fakeid = "";
|
|
||||||
|
|
||||||
for (InputDevice.MotionRange range : motions)
|
|
||||||
fakeid += range.getAxis();
|
|
||||||
|
|
||||||
return fakeid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
|
|
||||||
{
|
|
||||||
List<InputConfigItem> Input = new ArrayList<InputConfigItem>();
|
|
||||||
Input.add(new InputConfigItem(getString(R.string.button_a), "Android-InputA"));
|
|
||||||
Input.add(new InputConfigItem(getString(R.string.button_b), "Android-InputB"));
|
|
||||||
Input.add(new InputConfigItem(getString(R.string.button_start), "Android-InputStart"));
|
|
||||||
Input.add(new InputConfigItem(getString(R.string.button_x), "Android-InputX"));
|
|
||||||
Input.add(new InputConfigItem(getString(R.string.button_y), "Android-InputY"));
|
|
||||||
Input.add(new InputConfigItem(getString(R.string.button_z), "Android-InputZ"));
|
|
||||||
Input.add(new InputConfigItem(getString(R.string.dpad_up), "Android-DPadUp"));
|
|
||||||
Input.add(new InputConfigItem(getString(R.string.dpad_down), "Android-DPadDown"));
|
|
||||||
Input.add(new InputConfigItem(getString(R.string.dpad_left), "Android-DPadLeft"));
|
|
||||||
Input.add(new InputConfigItem(getString(R.string.dpad_right), "Android-DPadRight"));
|
|
||||||
Input.add(new InputConfigItem(getString(R.string.main_stick_up), "Android-MainUp"));
|
|
||||||
Input.add(new InputConfigItem(getString(R.string.main_stick_down), "Android-MainDown"));
|
|
||||||
Input.add(new InputConfigItem(getString(R.string.main_stick_left), "Android-MainLeft"));
|
|
||||||
Input.add(new InputConfigItem(getString(R.string.main_stick_right), "Android-MainRight"));
|
|
||||||
Input.add(new InputConfigItem(getString(R.string.c_stick_up), "Android-CStickUp"));
|
|
||||||
Input.add(new InputConfigItem(getString(R.string.c_stick_down), "Android-CStickDown"));
|
|
||||||
Input.add(new InputConfigItem(getString(R.string.c_stick_left), "Android-CStickLeft"));
|
|
||||||
Input.add(new InputConfigItem(getString(R.string.c_stick_right), "Android-CStickRight"));
|
|
||||||
Input.add(new InputConfigItem(getString(R.string.trigger_left), "Android-InputL"));
|
|
||||||
Input.add(new InputConfigItem(getString(R.string.trigger_right), "Android-InputR"));
|
|
||||||
|
|
||||||
adapter = new InputConfigAdapter(m_activity, R.layout.folderbrowser, Input);
|
|
||||||
View rootView = inflater.inflate(R.layout.gamelist_listview, container, false);
|
|
||||||
mDrawerList = (ListView) rootView.findViewById(R.id.gamelist);
|
|
||||||
|
|
||||||
mDrawerList.setAdapter(adapter);
|
|
||||||
mDrawerList.setOnItemClickListener(mMenuItemClickListener);
|
|
||||||
return mDrawerList;
|
|
||||||
}
|
|
||||||
|
|
||||||
private AdapterView.OnItemClickListener mMenuItemClickListener = new AdapterView.OnItemClickListener()
|
|
||||||
{
|
|
||||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
|
|
||||||
{
|
|
||||||
InputConfigItem o = adapter.getItem(position);
|
|
||||||
|
|
||||||
Toast.makeText(m_activity, getString(R.string.press_button_to_config, o.getName()), Toast.LENGTH_SHORT).show();
|
|
||||||
configPosition = position;
|
|
||||||
Configuring = true;
|
|
||||||
firstEvent = true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private static ArrayList<Float> m_values = new ArrayList<Float>();
|
|
||||||
|
|
||||||
private void AssignBind(String bind)
|
|
||||||
{
|
|
||||||
InputConfigItem o = adapter.getItem(configPosition);
|
|
||||||
adapter.remove(o);
|
|
||||||
o.setBind(bind);
|
|
||||||
adapter.insert(o, configPosition);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the current {@link InputConfigAdapter}
|
|
||||||
*
|
|
||||||
* @return the current {@link InputConfigAdapter}.
|
|
||||||
*/
|
|
||||||
public InputConfigAdapter getAdapter()
|
|
||||||
{
|
|
||||||
return adapter;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Called from GameListActivity
|
|
||||||
public boolean onMotionEvent(MotionEvent event)
|
|
||||||
{
|
|
||||||
if ((event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) == 0)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
InputDevice input = event.getDevice();
|
|
||||||
List<InputDevice.MotionRange> motions = input.getMotionRanges();
|
|
||||||
if (Configuring)
|
|
||||||
{
|
|
||||||
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))
|
|
||||||
{
|
|
||||||
AssignBind("Device '" + InputConfigFragment.getInputDesc(input) + "'-Axis " + range.getAxis() + "-");
|
|
||||||
Configuring = false;
|
|
||||||
}
|
|
||||||
else if (m_values.get(a) < (event.getAxisValue(range.getAxis()) - 0.5f))
|
|
||||||
{
|
|
||||||
AssignBind("Device '" + InputConfigFragment.getInputDesc(input) + "'-Axis " + range.getAxis() + "+");
|
|
||||||
Configuring = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Called from GameListActivity
|
|
||||||
public boolean onKeyEvent(KeyEvent event)
|
|
||||||
{
|
|
||||||
Log.w("InputConfigFragment", "Got Event " + event.getAction());
|
|
||||||
switch (event.getAction())
|
|
||||||
{
|
|
||||||
case KeyEvent.ACTION_DOWN:
|
|
||||||
case KeyEvent.ACTION_UP:
|
|
||||||
if (Configuring)
|
|
||||||
{
|
|
||||||
InputDevice input = event.getDevice();
|
|
||||||
AssignBind("Device '" + InputConfigFragment.getInputDesc(input) + "'-Button " + event.getKeyCode());
|
|
||||||
Configuring = false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onAttach(Activity activity)
|
|
||||||
{
|
|
||||||
super.onAttach(activity);
|
|
||||||
|
|
||||||
// This makes sure that the container activity has implemented
|
|
||||||
// the callback interface. If not, it throws an exception
|
|
||||||
try
|
|
||||||
{
|
|
||||||
m_activity = activity;
|
|
||||||
}
|
|
||||||
catch (ClassCastException e)
|
|
||||||
{
|
|
||||||
throw new ClassCastException(activity.toString()
|
|
||||||
+ " must implement OnGameListZeroListener");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,101 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2013 Dolphin Emulator Project
|
|
||||||
* Licensed under GPLv2
|
|
||||||
* Refer to the license.txt file included.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.dolphinemu.dolphinemu.inputconfig;
|
|
||||||
|
|
||||||
import org.dolphinemu.dolphinemu.NativeLibrary;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Represents a controller input item (button, stick, etc).
|
|
||||||
*/
|
|
||||||
public final class InputConfigItem implements Comparable<InputConfigItem>
|
|
||||||
{
|
|
||||||
private String m_name;
|
|
||||||
private String m_Config;
|
|
||||||
private String m_bind;
|
|
||||||
|
|
||||||
private void Init(String name, String config, String defaultBind)
|
|
||||||
{
|
|
||||||
m_name = name;
|
|
||||||
m_Config = config;
|
|
||||||
String ConfigValues[] = m_Config.split("-");
|
|
||||||
String Key = ConfigValues[0];
|
|
||||||
String Value = ConfigValues[1];
|
|
||||||
m_bind = NativeLibrary.GetConfig("Dolphin.ini", Key, Value, defaultBind);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor
|
|
||||||
*
|
|
||||||
* @param name Name of the input config item.
|
|
||||||
* @param config Name of the key in the configuration file that this control modifies.
|
|
||||||
* @param defaultBind Default binding to fall back upon if binding fails.
|
|
||||||
*/
|
|
||||||
public InputConfigItem(String name, String config, String defaultBind)
|
|
||||||
{
|
|
||||||
Init(name, config, defaultBind);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor that creates an InputConfigItem
|
|
||||||
* that has a default binding of "None".
|
|
||||||
*
|
|
||||||
* @param name Name of the input config item.
|
|
||||||
* @param config Name of the key in the configuration file that this control modifies.
|
|
||||||
*/
|
|
||||||
public InputConfigItem(String name, String config)
|
|
||||||
{
|
|
||||||
Init(name, config, "None");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the name of this InputConfigItem.
|
|
||||||
*
|
|
||||||
* @return the name of this InputConfigItem
|
|
||||||
*/
|
|
||||||
public String getName()
|
|
||||||
{
|
|
||||||
return m_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the config key this InputConfigItem modifies.
|
|
||||||
*
|
|
||||||
* @return the config key this InputConfigItem modifies.
|
|
||||||
*/
|
|
||||||
public String getConfig()
|
|
||||||
{
|
|
||||||
return m_Config;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the currently set binding of this InputConfigItem.
|
|
||||||
*
|
|
||||||
* @return the currently set binding of this InputConfigItem
|
|
||||||
*/
|
|
||||||
public String getBind()
|
|
||||||
{
|
|
||||||
return m_bind;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets a new binding for this InputConfigItem.
|
|
||||||
*
|
|
||||||
* @param bind The new binding.
|
|
||||||
*/
|
|
||||||
public void setBind(String bind)
|
|
||||||
{
|
|
||||||
m_bind = bind;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int compareTo(InputConfigItem o)
|
|
||||||
{
|
|
||||||
if (this.m_name != null)
|
|
||||||
return this.m_name.toLowerCase().compareTo(o.getName().toLowerCase());
|
|
||||||
else
|
|
||||||
throw new IllegalArgumentException();
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,252 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2013 Dolphin Emulator Project
|
||||||
|
* Licensed under GPLv2
|
||||||
|
* Refer to the license.txt file included.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.dolphinemu.dolphinemu.settings;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.app.Fragment;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.preference.Preference;
|
||||||
|
import android.preference.PreferenceFragment;
|
||||||
|
import android.preference.PreferenceScreen;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.*;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.dolphinemu.dolphinemu.NativeLibrary;
|
||||||
|
import org.dolphinemu.dolphinemu.R;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The {@link Fragment} responsible for implementing the functionality
|
||||||
|
* within the input control mapping config.
|
||||||
|
*/
|
||||||
|
public final class InputConfigFragment extends PreferenceFragment
|
||||||
|
//implements PrefsActivity.OnGameConfigListener
|
||||||
|
{
|
||||||
|
private Activity m_activity;
|
||||||
|
private boolean firstEvent = true;
|
||||||
|
private static ArrayList<Float> m_values = new ArrayList<Float>();
|
||||||
|
protected MotionAlertDialog dialog;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the descriptor for the given {@link InputDevice}.
|
||||||
|
*
|
||||||
|
* @param input The {@link InputDevice} to get the descriptor of.
|
||||||
|
*
|
||||||
|
* @return the descriptor for the given {@link InputDevice}.
|
||||||
|
*/
|
||||||
|
public static String getInputDesc(InputDevice input)
|
||||||
|
{
|
||||||
|
if (input == null)
|
||||||
|
return "null"; // Happens when the inputdevice is from an unknown source
|
||||||
|
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
|
||||||
|
{
|
||||||
|
return input.getDescriptor();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
List<InputDevice.MotionRange> motions = input.getMotionRanges();
|
||||||
|
String fakeid = "";
|
||||||
|
|
||||||
|
for (InputDevice.MotionRange range : motions)
|
||||||
|
fakeid += range.getAxis();
|
||||||
|
|
||||||
|
return fakeid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState)
|
||||||
|
{
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
// Expand the preferences from the XML.
|
||||||
|
addPreferencesFromResource(R.xml.input_prefs);
|
||||||
|
|
||||||
|
// Set the summary messages of the preferences to whatever binding
|
||||||
|
// is currently set within the Dolphin config.
|
||||||
|
final String[] keys =
|
||||||
|
{
|
||||||
|
"InputA", "InputB", "InputX", "InputY", "InputZ", "InputStart",
|
||||||
|
"DPadUp", "DPadDown", "DPadLeft", "DPadRight",
|
||||||
|
"MainUp", "MainDown", "MainLeft", "MainRight",
|
||||||
|
"CStickUp", "CStickDown", "CStickLeft", "CStickRight",
|
||||||
|
"InputL", "InputR",
|
||||||
|
};
|
||||||
|
|
||||||
|
Preference pref;
|
||||||
|
for (String key : keys)
|
||||||
|
{
|
||||||
|
String binding = NativeLibrary.GetConfig("Dolphin.ini", "Android", key, "None");
|
||||||
|
pref = findPreference(key);
|
||||||
|
pref.setSummary(binding);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onPreferenceTreeClick(final PreferenceScreen screen, final Preference pref)
|
||||||
|
{
|
||||||
|
// Begin the creation of the input alert.
|
||||||
|
dialog = new MotionAlertDialog(m_activity);
|
||||||
|
|
||||||
|
// Set the key listener
|
||||||
|
dialog.setOnKeyEventListener(new MotionAlertDialog.OnKeyEventListener()
|
||||||
|
{
|
||||||
|
public boolean onKey(KeyEvent event)
|
||||||
|
{
|
||||||
|
Log.d("InputConfigFragment", "Received key event: " + event.getAction());
|
||||||
|
switch (event.getAction())
|
||||||
|
{
|
||||||
|
case KeyEvent.ACTION_DOWN:
|
||||||
|
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 motion event listener.
|
||||||
|
dialog.setOnMotionEventListener(new MotionAlertDialog.OnMotionEventListener()
|
||||||
|
{
|
||||||
|
public boolean onMotion(MotionEvent event)
|
||||||
|
{
|
||||||
|
Log.d("InputConfigFragment", "Received motion event: " + event.getAction());
|
||||||
|
if (event == null || (event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) == 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
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(getString(R.string.input_binding_descrip));
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onAttach(Activity activity)
|
||||||
|
{
|
||||||
|
super.onAttach(activity);
|
||||||
|
|
||||||
|
// Cache the activity instance.
|
||||||
|
m_activity = activity;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link AlertDialog} class derivative that can handle motion events.
|
||||||
|
*/
|
||||||
|
protected static final class MotionAlertDialog extends AlertDialog implements PrefsActivity.OnMotionConfigListener
|
||||||
|
{
|
||||||
|
private OnKeyEventListener keyListener;
|
||||||
|
private OnMotionEventListener motionListener;
|
||||||
|
|
||||||
|
public MotionAlertDialog(Context ctx)
|
||||||
|
{
|
||||||
|
super(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface OnKeyEventListener
|
||||||
|
{
|
||||||
|
boolean onKey(KeyEvent event);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface OnMotionEventListener
|
||||||
|
{
|
||||||
|
boolean onMotion(MotionEvent event);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOnKeyEventListener(OnKeyEventListener listener)
|
||||||
|
{
|
||||||
|
this.keyListener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setOnMotionEventListener(OnMotionEventListener listener)
|
||||||
|
{
|
||||||
|
this.motionListener = listener;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onKeyDown(int keycode, KeyEvent event)
|
||||||
|
{
|
||||||
|
return keyListener.onKey(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onMotionEvent(MotionEvent event)
|
||||||
|
{
|
||||||
|
return motionListener.onMotion(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -17,6 +17,8 @@ import android.app.FragmentTransaction;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v13.app.FragmentPagerAdapter;
|
import android.support.v13.app.FragmentPagerAdapter;
|
||||||
import android.support.v4.view.ViewPager;
|
import android.support.v4.view.ViewPager;
|
||||||
|
import android.view.KeyEvent;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Main activity that manages all of the preference fragments used to display
|
* Main activity that manages all of the preference fragments used to display
|
||||||
@ -24,6 +26,16 @@ import android.support.v4.view.ViewPager;
|
|||||||
*/
|
*/
|
||||||
public final class PrefsActivity extends Activity implements ActionBar.TabListener
|
public final class PrefsActivity extends Activity implements ActionBar.TabListener
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Interface defining methods which handle
|
||||||
|
* the binding of specific key presses within
|
||||||
|
* the input mapping settings.
|
||||||
|
*/
|
||||||
|
public interface OnMotionConfigListener
|
||||||
|
{
|
||||||
|
boolean onMotionEvent(MotionEvent event);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link android.support.v4.view.PagerAdapter} that will provide org.dolphinemu.dolphinemu.settings for each of the
|
* The {@link android.support.v4.view.PagerAdapter} that will provide org.dolphinemu.dolphinemu.settings for each of the
|
||||||
* sections. We use a {@link android.support.v4.app.FragmentPagerAdapter} derivative, which will
|
* sections. We use a {@link android.support.v4.app.FragmentPagerAdapter} derivative, which will
|
||||||
@ -72,6 +84,7 @@ public final class PrefsActivity extends Activity implements ActionBar.TabListen
|
|||||||
// the TabListener interface, as the callback (listener) for when
|
// the TabListener interface, as the callback (listener) for when
|
||||||
// this tab is selected.
|
// this tab is selected.
|
||||||
actionBar.addTab(actionBar.newTab().setText(R.string.cpu_settings).setTabListener(this));
|
actionBar.addTab(actionBar.newTab().setText(R.string.cpu_settings).setTabListener(this));
|
||||||
|
actionBar.addTab(actionBar.newTab().setText(R.string.input_settings).setTabListener(this));
|
||||||
actionBar.addTab(actionBar.newTab().setText(R.string.video_settings).setTabListener(this));
|
actionBar.addTab(actionBar.newTab().setText(R.string.video_settings).setTabListener(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,6 +104,36 @@ public final class PrefsActivity extends Activity implements ActionBar.TabListen
|
|||||||
// Do nothing.
|
// Do nothing.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: Eventually make correct implementations of these.
|
||||||
|
// Gets move(triggers, joystick) events
|
||||||
|
@Override
|
||||||
|
public boolean dispatchGenericMotionEvent(MotionEvent event)
|
||||||
|
{
|
||||||
|
if (mViewPager.getCurrentItem() == 1)
|
||||||
|
{
|
||||||
|
InputConfigFragment fragment = (InputConfigFragment) getFragmentManager().findFragmentByTag("android:switcher:"+R.id.pager+":1");
|
||||||
|
if (fragment.dialog != null && ((OnMotionConfigListener) fragment.dialog).onMotionEvent(event))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.dispatchGenericMotionEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gets button presses
|
||||||
|
@Override
|
||||||
|
public boolean dispatchKeyEvent(KeyEvent event)
|
||||||
|
{
|
||||||
|
if (mViewPager.getCurrentItem() == 1 && event.getKeyCode() != KeyEvent.KEYCODE_BACK)
|
||||||
|
{
|
||||||
|
InputConfigFragment fragment = (InputConfigFragment) getFragmentManager().findFragmentByTag("android:switcher:"+R.id.pager+":1");
|
||||||
|
if (fragment.dialog != null && fragment.dialog.onKeyDown(event.getKeyCode(), event))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.dispatchKeyEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link FragmentPagerAdapter} that returns a fragment
|
* A {@link FragmentPagerAdapter} that returns a fragment
|
||||||
* corresponding to one of the sections/tabs/pages.
|
* corresponding to one of the sections/tabs/pages.
|
||||||
@ -111,6 +154,9 @@ public final class PrefsActivity extends Activity implements ActionBar.TabListen
|
|||||||
return new CPUSettingsFragment();
|
return new CPUSettingsFragment();
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
|
return new InputConfigFragment();
|
||||||
|
|
||||||
|
case 2:
|
||||||
return new VideoSettingsFragment();
|
return new VideoSettingsFragment();
|
||||||
|
|
||||||
default: // Should never happen.
|
default: // Should never happen.
|
||||||
@ -122,7 +168,7 @@ public final class PrefsActivity extends Activity implements ActionBar.TabListen
|
|||||||
public int getCount()
|
public int getCount()
|
||||||
{
|
{
|
||||||
// Show total pages.
|
// Show total pages.
|
||||||
return 2;
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -134,6 +180,9 @@ public final class PrefsActivity extends Activity implements ActionBar.TabListen
|
|||||||
return getString(R.string.cpu_settings).toUpperCase();
|
return getString(R.string.cpu_settings).toUpperCase();
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
|
return getString(R.string.input_settings).toUpperCase();
|
||||||
|
|
||||||
|
case 2:
|
||||||
return getString(R.string.video_settings).toUpperCase();
|
return getString(R.string.video_settings).toUpperCase();
|
||||||
|
|
||||||
default: // Should never happen.
|
default: // Should never happen.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user