Merge pull request #3547 from sigmabeta/android-config-rewrite

[Android] Rewrite settings UI.
This commit is contained in:
Ryan Houdek
2016-01-23 12:40:05 -05:00
67 changed files with 2649 additions and 5858 deletions
@@ -9,10 +9,10 @@
<item>@string/cached_interpreter</item>
<item>@string/jit_arm64_recompiler</item>
</string-array>
<string-array name="int_emu_cores" translatable="false">
<integer-array name="int_emu_cores" translatable="false">
<item>0</item>
<item>5</item>
<item>4</item>
</string-array>
</integer-array>
</resources>
@@ -56,9 +56,9 @@
android:label="@string/add_directory_title"/>
<activity
android:name=".activities.SettingsActivity"
android:name=".ui.settings.SettingsActivity"
android:theme="@style/DolphinSettingsGamecube"
android:label="@string/grid_menu_settings"/>
android:label="@string/grid_menu_core_settings"/>
<activity
android:name=".activities.EmulationActivity"
@@ -71,8 +71,6 @@
<service android:name=".services.AssetCopyService"/>
<service android:name=".services.SettingsSaveService"/>
<provider
android:name=".model.GameProvider"
android:authorities="${applicationId}.provider"
@@ -1,48 +0,0 @@
package org.dolphinemu.dolphinemu.activities;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import org.dolphinemu.dolphinemu.fragments.SettingsFragment;
import org.dolphinemu.dolphinemu.services.SettingsSaveService;
import org.dolphinemu.dolphinemu.utils.Log;
public final class SettingsActivity extends AppCompatActivity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// Display the fragment as the main content.
getFragmentManager().beginTransaction()
.replace(android.R.id.content, new SettingsFragment(), "settings_fragment")
.commit();
}
/**
* If this is called, the user has left the settings screen (potentially through the
* home button) and will expect their changes to be persisted. So we kick off an
* IntentService which will do so on a background thread.
*/
@Override
protected void onStop()
{
super.onStop();
Log.debug("[SettingsActivity] Settings activity stopping. Saving settings to INI...");
// Copy assets into appropriate locations.
Intent settingsSaver = new Intent(this, SettingsSaveService.class);
startService(settingsSaver);
}
public static void launch(Context context)
{
Intent settings = new Intent(context, SettingsActivity.class);
context.startActivity(settings);
}
}
@@ -1,155 +0,0 @@
package org.dolphinemu.dolphinemu.fragments;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Environment;
import android.preference.ListPreference;
import android.preference.PreferenceFragment;
import android.preference.PreferenceManager;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.utils.EGLHelper;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import javax.microedition.khronos.opengles.GL10;
public final class SettingsFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener
{
private SharedPreferences mPreferences;
private ListPreference mVideoBackendPreference;
private final EGLHelper mEglHelper = new EGLHelper(EGLHelper.EGL_OPENGL_ES2_BIT);
private final String mVendor = mEglHelper.getGL().glGetString(GL10.GL_VENDOR);
private final String mVersion = mEglHelper.getGL().glGetString(GL10.GL_VERSION);
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.preferences);
// TODO Below here is effectively ported from the old VideoSettingsFragment. There is
// TODO probably a simpler way to do this, but potentially could require UI discussion/feedback.
// Setting valid video backends.
mVideoBackendPreference = (ListPreference) findPreference("gpuPref");
final boolean deviceSupportsGL = mEglHelper.supportsOpenGL();
final boolean deviceSupportsGLES3 = mEglHelper.supportsGLES3();
if (deviceSupportsGL)
{
mVideoBackendPreference.setEntries(R.array.videoBackendEntriesGL);
mVideoBackendPreference.setEntryValues(R.array.videoBackendValuesGL);
}
else if (deviceSupportsGLES3)
{
mVideoBackendPreference.setEntries(R.array.videoBackendEntriesGLES3);
mVideoBackendPreference.setEntryValues(R.array.videoBackendValuesGLES3);
}
else
{
mVideoBackendPreference.setEntries(R.array.videoBackendEntriesNoGLES3);
mVideoBackendPreference.setEntryValues(R.array.videoBackendValuesNoGLES3);
}
//
// Set available post processing shaders
//
List<CharSequence> shader_names = new ArrayList<CharSequence>();
List<CharSequence> shader_values = new ArrayList<CharSequence>();
// Disabled option
shader_names.add("Disabled");
shader_values.add("");
// TODO Since shaders are included with the APK, we know what they are at build-time. We should
// TODO be able to run this logic somehow at build-time and not rely on the device doing it.
File shaders_folder = new File(Environment.getExternalStorageDirectory() + File.separator + "dolphin-emu" + File.separator + "Shaders");
if (shaders_folder.exists())
{
File[] shaders = shaders_folder.listFiles();
for (File file : shaders)
{
if (file.isFile())
{
String filename = file.getName();
if (filename.endsWith(".glsl"))
{
// Strip the extension and put it in to the list
shader_names.add(filename.substring(0, filename.lastIndexOf('.')));
shader_values.add(filename.substring(0, filename.lastIndexOf('.')));
}
}
}
}
final ListPreference shader_preference = (ListPreference) findPreference("postProcessingShader");
shader_preference.setEntries(shader_names.toArray(new CharSequence[shader_names.size()]));
shader_preference.setEntryValues(shader_values.toArray(new CharSequence[shader_values.size()]));
//
// Disable all options if Software Rendering is used.
//
// Note that the numeric value in 'getPreference()'
// denotes the placement on the UI. So if more elements are
// added to the video settings, these may need to change.
//
mPreferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
if (mVideoBackendPreference.getValue().equals("Software Renderer"))
{
findPreference("enhancements").setEnabled(false);
findPreference("hacks").setEnabled(false);
findPreference("showFPS").setEnabled(false);
}
else if (mVideoBackendPreference.getValue().equals("OGL"))
{
findPreference("enhancements").setEnabled(true);
findPreference("hacks").setEnabled(true);
findPreference("showFPS").setEnabled(true);
// Check if we support stereo
// If we support desktop GL then we must support at least OpenGL 3.2
// If we only support OpenGLES then we need both OpenGLES 3.1 and AEP
if ((mEglHelper.supportsOpenGL() && mEglHelper.GetVersion() >= 320) ||
(mEglHelper.supportsGLES3() && mEglHelper.GetVersion() >= 310 && mEglHelper.SupportsExtension("GL_ANDROID_extension_pack_es31a")))
findPreference("StereoscopyScreen").setEnabled(true);
else
findPreference("StereoscopyScreen").setEnabled(false);
}
// Also set a listener, so that if someone changes the video backend, it will disable
// the video settings, upon the user choosing "Software Rendering".
mPreferences.registerOnSharedPreferenceChangeListener(this);
}
@Override
public void onSharedPreferenceChanged(SharedPreferences preferences, String key)
{
if (key.equals("gpuPref"))
{
if (preferences.getString(key, "Software Renderer").equals("Software Renderer"))
{
findPreference("enhancements").setEnabled(false);
findPreference("hacks").setEnabled(false);
findPreference("showFPS").setEnabled(false);
}
else if (preferences.getString(key, "Software Renderer").equals("OGL"))
{
findPreference("enhancements").setEnabled(true);
findPreference("hacks").setEnabled(true);
findPreference("showFPS").setEnabled(true);
}
}
}
}
@@ -0,0 +1,28 @@
package org.dolphinemu.dolphinemu.model.settings;
public final class BooleanSetting extends Setting
{
private boolean mValue;
public BooleanSetting(String key, String section, boolean value)
{
super(key, section);
mValue = value;
}
public boolean getValue()
{
return mValue;
}
public void setValue(boolean value)
{
mValue = value;
}
@Override
public String getValueAsString()
{
return mValue ? "True" : "False";
}
}
@@ -0,0 +1,28 @@
package org.dolphinemu.dolphinemu.model.settings;
public final class FloatSetting extends Setting
{
private float mValue;
public FloatSetting(String key, String section, float value)
{
super(key, section);
mValue = value;
}
public float getValue()
{
return mValue;
}
public void setValue(float value)
{
mValue = value;
}
@Override
public String getValueAsString()
{
return Float.toString(mValue);
}
}
@@ -0,0 +1,28 @@
package org.dolphinemu.dolphinemu.model.settings;
public final class IntSetting extends Setting
{
private int mValue;
public IntSetting(String key, String section, int value)
{
super(key, section);
mValue = value;
}
public int getValue()
{
return mValue;
}
public void setValue(int value)
{
mValue = value;
}
@Override
public String getValueAsString()
{
return Integer.toString(mValue);
}
}
@@ -0,0 +1,48 @@
package org.dolphinemu.dolphinemu.model.settings;
/**
* Abstraction for a setting item as read from / written to Dolphin's configuration ini files.
* These files generally consist of a key/value pair, though the type of value is ambiguous and
* must be inferred at read-time. The type of value determines which child of this class is used
* to represent the Setting.
*/
public abstract class Setting
{
private String mKey;
private String mSection;
/**
* Base constructor.
*
* @param key Everything to the left of the = in a line from the ini file.
* @param section The corresponding recent section header; e.g. [Core] or [Enhancements] without the brackets.
*/
public Setting(String key, String section)
{
mKey = key;
mSection = section;
}
/**
*
* @return The identifier used to write this setting to the ini file.
*/
public String getKey()
{
return mKey;
}
/**
*
* @return The name of the header under which this Setting should be written in the ini file.
*/
public String getSection()
{
return mSection;
}
/**
* @return A representation of this Setting's backing value converted to a String (e.g. for serialization).
*/
public abstract String getValueAsString();
}
@@ -0,0 +1,56 @@
package org.dolphinemu.dolphinemu.model.settings;
import java.util.HashMap;
/**
* A semantically-related group of Settings objects. These Settings are
* internally stored as a Hashmap.
*/
public final class SettingSection
{
private String mName;
private HashMap<String, Setting> mSettings = new HashMap<>();
/**
* Create a new SettingSection with no Settings in it.
*
* @param name The header of this section; e.g. [Core] or [Enhancements] without the brackets.
*/
public SettingSection(String name)
{
mName = name;
}
public String getName()
{
return mName;
}
/**
* Convenience method; inserts a value directly into the backing Hashmap.
*
* @param key The key where the Setting will be inserted.
* @param setting The Setting to be inserted.
*/
public void putSetting(String key, Setting setting)
{
mSettings.put(key, setting);
}
/**
* Convenience method; gets a value directly from the backing Hashmap.
*
* @param key Used to retrieve the Setting.
* @return A Setting object (you should probably cast this before using)
*/
public Setting getSetting(String key)
{
return mSettings.get(key);
}
public HashMap<String, Setting> getSettings()
{
return mSettings;
}
}
@@ -0,0 +1,28 @@
package org.dolphinemu.dolphinemu.model.settings;
public final class StringSetting extends Setting
{
private String mValue;
public StringSetting(String key, String section, String value)
{
super(key, section);
mValue = value;
}
public String getValue()
{
return mValue;
}
public void setValue(String value)
{
mValue = value;
}
@Override
public String getValueAsString()
{
return mValue;
}
}
@@ -0,0 +1,56 @@
package org.dolphinemu.dolphinemu.model.settings.view;
import org.dolphinemu.dolphinemu.model.settings.BooleanSetting;
import org.dolphinemu.dolphinemu.model.settings.Setting;
public final class CheckBoxSetting extends SettingsItem
{
private boolean mDefaultValue;
public CheckBoxSetting(String key, String section, int titleId, int descriptionId, boolean defaultValue, Setting setting)
{
super(key, section, setting, titleId, descriptionId);
mDefaultValue = defaultValue;
}
public boolean isChecked()
{
if (getSetting() == null)
{
return mDefaultValue;
}
BooleanSetting setting = (BooleanSetting) getSetting();
return setting.getValue();
}
/**
* Write a value to the backing boolean. If that boolean was previously null,
* initializes a new one and returns it, so it can be added to the Hashmap.
*
* @param checked Pretty self explanatory.
* @return null if overwritten successfully; otherwise, a newly created BooleanSetting.
*/
public BooleanSetting setChecked(boolean checked)
{
if (getSetting() == null)
{
BooleanSetting setting = new BooleanSetting(getKey(), getSection(), checked);
setSetting(setting);
return setting;
}
else
{
BooleanSetting setting = (BooleanSetting) getSetting();
setting.setValue(checked);
return null;
}
}
@Override
public int getType()
{
return TYPE_CHECKBOX;
}
}
@@ -0,0 +1,18 @@
package org.dolphinemu.dolphinemu.model.settings.view;
import org.dolphinemu.dolphinemu.model.settings.Setting;
public final class HeaderSetting extends SettingsItem
{
public HeaderSetting(String key, Setting setting, int titleId, int descriptionId)
{
super(key, null, setting, titleId, descriptionId);
}
@Override
public int getType()
{
return SettingsItem.TYPE_HEADER;
}
}
@@ -0,0 +1,106 @@
package org.dolphinemu.dolphinemu.model.settings.view;
import org.dolphinemu.dolphinemu.model.settings.Setting;
/**
* ViewModel abstraction for an Item in the RecyclerView powering SettingsFragments.
* Each one corresponds to a {@link Setting} object, so this class's subclasses
* should vaguely correspond to those subclasses. There are a few with multiple analogues
* and a few with none (Headers, for example, do not correspond to anything in the ini
* file.)
*/
public abstract class SettingsItem
{
public static final int TYPE_HEADER = 0;
public static final int TYPE_CHECKBOX = 1;
public static final int TYPE_SINGLE_CHOICE = 2;
public static final int TYPE_SLIDER = 3;
public static final int TYPE_SUBMENU = 4;
private String mKey;
private String mSection;
private Setting mSetting;
private int mNameId;
private int mDescriptionId;
/**
* Base constructor. Takes a key / section name in case the third parameter, the Setting,
* is null; in which case, one can be constructed and saved using the key / section.
*
* @param key Identifier for the Setting represented by this Item.
* @param section Section to which the Setting belongs.
* @param setting A possibly-null backing Setting, to be modified on UI events.
* @param nameId Resource ID for a text string to be displayed as this setting's name.
* @param descriptionId Resource ID for a text string to be displayed as this setting's description.
*/
public SettingsItem(String key, String section, Setting setting, int nameId, int descriptionId)
{
mKey = key;
mSection = section;
mSetting = setting;
mNameId = nameId;
mDescriptionId = descriptionId;
}
/**
*
* @return The identifier for the backing Setting.
*/
public String getKey()
{
return mKey;
}
/**
*
* @return The header under which the backing Setting belongs.
*/
public String getSection()
{
return mSection;
}
/**
*
* @return The backing Setting, possibly null.
*/
public Setting getSetting()
{
return mSetting;
}
/**
* Replace the backing setting with a new one. Generally used in cases where
* the backing setting is null.
*
* @param setting A non-null Setting.
*/
public void setSetting(Setting setting)
{
mSetting = setting;
}
/**
*
* @return A resource ID for a text string representing this Setting's name.
*/
public int getNameId()
{
return mNameId;
}
public int getDescriptionId()
{
return mDescriptionId;
}
/**
* Used by {@link org.dolphinemu.dolphinemu.ui.settings.SettingsAdapter}'s onCreateViewHolder()
* method to determine which type of ViewHolder should be created.
*
* @return An integer (ideally, one of the constants defined in this file)
*/
public abstract int getType();
}
@@ -0,0 +1,73 @@
package org.dolphinemu.dolphinemu.model.settings.view;
import org.dolphinemu.dolphinemu.model.settings.IntSetting;
import org.dolphinemu.dolphinemu.model.settings.Setting;
public final class SingleChoiceSetting extends SettingsItem
{
private int mDefaultValue;
private int mChoicesId;
private int mValuesId;
public SingleChoiceSetting(String key, String section, int titleId, int descriptionId, int choicesId, int valuesId, int defaultValue, Setting setting)
{
super(key, section, setting, titleId, descriptionId);
mValuesId = valuesId;
mChoicesId = choicesId;
mDefaultValue = defaultValue;
}
public int getChoicesId()
{
return mChoicesId;
}
public int getValuesId()
{
return mValuesId;
}
public int getSelectedValue()
{
if (getSetting() != null)
{
IntSetting setting = (IntSetting) getSetting();
return setting.getValue();
}
else
{
return mDefaultValue;
}
}
/**
* Write a value to the backing int. If that int was previously null,
* initializes a new one and returns it, so it can be added to the Hashmap.
*
* @param selection New value of the int.
* @return null if overwritten successfully otherwise; a newly created IntSetting.
*/
public IntSetting setSelectedValue(int selection)
{
if (getSetting() == null)
{
IntSetting setting = new IntSetting(getKey(), getSection(), selection);
setSetting(setting);
return setting;
}
else
{
IntSetting setting = (IntSetting) getSetting();
setting.setValue(selection);
return null;
}
}
@Override
public int getType()
{
return TYPE_SINGLE_CHOICE;
}
}
@@ -0,0 +1,118 @@
package org.dolphinemu.dolphinemu.model.settings.view;
import org.dolphinemu.dolphinemu.model.settings.FloatSetting;
import org.dolphinemu.dolphinemu.model.settings.IntSetting;
import org.dolphinemu.dolphinemu.model.settings.Setting;
import org.dolphinemu.dolphinemu.utils.Log;
import org.dolphinemu.dolphinemu.utils.SettingsFile;
public final class SliderSetting extends SettingsItem
{
private int mMax;
private int mDefaultValue;
private String mUnits;
public SliderSetting(String key, String section, int titleId, int descriptionId, int max, String units, int defaultValue, Setting setting)
{
super(key, section, setting, titleId, descriptionId);
mMax = max;
mUnits = units;
mDefaultValue = defaultValue;
}
public int getMax()
{
return mMax;
}
public int getSelectedValue()
{
Setting setting = getSetting();
if (setting == null)
{
return mDefaultValue;
}
if (setting instanceof IntSetting)
{
IntSetting intSetting = (IntSetting) setting;
return intSetting.getValue();
}
else if (setting instanceof FloatSetting)
{
FloatSetting floatSetting = (FloatSetting) setting;
if (floatSetting.getKey().equals(SettingsFile.KEY_OVERCLOCK_PERCENT))
{
return Math.round(floatSetting.getValue() * 100);
}
else
{
return Math.round(floatSetting.getValue());
}
}
else
{
Log.error("[SliderSetting] Error casting setting type.");
return -1;
}
}
/**
* Write a value to the backing int. If that int was previously null,
* initializes a new one and returns it, so it can be added to the Hashmap.
*
* @param selection New value of the int.
* @return null if overwritten successfully otherwise; a newly created IntSetting.
*/
public IntSetting setSelectedValue(int selection)
{
if (getSetting() == null)
{
IntSetting setting = new IntSetting(getKey(), getSection(), selection);
setSetting(setting);
return setting;
}
else
{
IntSetting setting = (IntSetting) getSetting();
setting.setValue(selection);
return null;
}
}
/**
* Write a value to the backing float. If that float was previously null,
* initializes a new one and returns it, so it can be added to the Hashmap.
*
* @param selection New value of the float.
* @return null if overwritten successfully otherwise; a newly created FloatSetting.
*/
public FloatSetting setSelectedValue(float selection)
{
if (getSetting() == null)
{
FloatSetting setting = new FloatSetting(getKey(), getSection(), selection);
setSetting(setting);
return setting;
}
else
{
FloatSetting setting = (FloatSetting) getSetting();
setting.setValue(selection);
return null;
}
}
public String getUnits()
{
return mUnits;
}
@Override
public int getType()
{
return TYPE_SLIDER;
}
}
@@ -0,0 +1,25 @@
package org.dolphinemu.dolphinemu.model.settings.view;
import org.dolphinemu.dolphinemu.model.settings.Setting;
public final class SubmenuSetting extends SettingsItem
{
private String mMenuKey;
public SubmenuSetting(String key, Setting setting, int titleId, int descriptionId, String menuKey)
{
super(key, null, setting, titleId, descriptionId);
mMenuKey = menuKey;
}
public String getMenuKey()
{
return mMenuKey;
}
@Override
public int getType()
{
return TYPE_SUBMENU;
}
}
@@ -13,7 +13,6 @@ import android.preference.PreferenceManager;
import org.dolphinemu.dolphinemu.NativeLibrary;
import org.dolphinemu.dolphinemu.utils.Log;
import org.dolphinemu.dolphinemu.utils.UserPreferences;
import java.io.File;
import java.io.FileOutputStream;
@@ -61,10 +60,6 @@ public final class AssetCopyService extends IntentService
copyAsset("GCPadNew.ini", ConfigDir + File.separator + "GCPadNew.ini");
copyAsset("WiimoteNew.ini", ConfigDir + File.separator + "WiimoteNew.ini");
// Load the configuration keys set in the Dolphin ini and gfx ini files
// into the application's shared preferences.
UserPreferences.LoadIniToPrefs(this);
// Record the fact that we've done this before, so we don't do it on every launch.
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor editor = preferences.edit();
@@ -1,28 +0,0 @@
package org.dolphinemu.dolphinemu.services;
import android.app.IntentService;
import android.content.Intent;
import org.dolphinemu.dolphinemu.utils.Log;
import org.dolphinemu.dolphinemu.utils.UserPreferences;
/**
* IntentServices, unlike regular services, inherently run on a background thread.
* This IntentService saves all the options the user set in the Java-based UI into
* INI files the native code can read.
*/
public final class SettingsSaveService extends IntentService
{
public SettingsSaveService()
{
super("SettingsSaveService");
}
@Override
protected void onHandleIntent(Intent intent)
{
Log.verbose("[SettingsSaveService] Saving settings to INI files...");
UserPreferences.SavePrefsToIni(this);
Log.verbose("[SettingsSaveService] Save successful.");
}
}
@@ -0,0 +1,157 @@
package org.dolphinemu.dolphinemu.ui;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.view.View;
/**
* Implementation from:
* https://gist.github.com/lapastillaroja/858caf1a82791b6c1a36
*/
public final class DividerItemDecoration extends RecyclerView.ItemDecoration
{
private Drawable mDivider;
private boolean mShowFirstDivider = false;
private boolean mShowLastDivider = false;
public DividerItemDecoration(Context context, AttributeSet attrs)
{
final TypedArray a = context
.obtainStyledAttributes(attrs, new int[]{android.R.attr.listDivider});
mDivider = a.getDrawable(0);
a.recycle();
}
public DividerItemDecoration(Context context, AttributeSet attrs, boolean showFirstDivider,
boolean showLastDivider)
{
this(context, attrs);
mShowFirstDivider = showFirstDivider;
mShowLastDivider = showLastDivider;
}
public DividerItemDecoration(Drawable divider)
{
mDivider = divider;
}
public DividerItemDecoration(Drawable divider, boolean showFirstDivider,
boolean showLastDivider)
{
this(divider);
mShowFirstDivider = showFirstDivider;
mShowLastDivider = showLastDivider;
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent,
RecyclerView.State state)
{
super.getItemOffsets(outRect, view, parent, state);
if (mDivider == null)
{
return;
}
if (parent.getChildPosition(view) < 1)
{
return;
}
if (getOrientation(parent) == LinearLayoutManager.VERTICAL)
{
outRect.top = mDivider.getIntrinsicHeight();
}
else
{
outRect.left = mDivider.getIntrinsicWidth();
}
}
@Override
public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state)
{
if (mDivider == null)
{
super.onDrawOver(c, parent, state);
return;
}
// Initialization needed to avoid compiler warning
int left = 0, right = 0, top = 0, bottom = 0, size;
int orientation = getOrientation(parent);
int childCount = parent.getChildCount();
if (orientation == LinearLayoutManager.VERTICAL)
{
size = mDivider.getIntrinsicHeight();
left = parent.getPaddingLeft();
right = parent.getWidth() - parent.getPaddingRight();
}
else
{ //horizontal
size = mDivider.getIntrinsicWidth();
top = parent.getPaddingTop();
bottom = parent.getHeight() - parent.getPaddingBottom();
}
for (int i = mShowFirstDivider ? 0 : 1; i < childCount; i++)
{
View child = parent.getChildAt(i);
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
if (orientation == LinearLayoutManager.VERTICAL)
{
top = child.getTop() - params.topMargin;
bottom = top + size;
}
else
{ //horizontal
left = child.getLeft() - params.leftMargin;
right = left + size;
}
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
// show last divider
if (mShowLastDivider && childCount > 0)
{
View child = parent.getChildAt(childCount - 1);
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
if (orientation == LinearLayoutManager.VERTICAL)
{
top = child.getBottom() + params.bottomMargin;
bottom = top + size;
}
else
{ // horizontal
left = child.getRight() + params.rightMargin;
right = left + size;
}
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
}
}
private int getOrientation(RecyclerView parent)
{
if (parent.getLayoutManager() instanceof LinearLayoutManager)
{
LinearLayoutManager layoutManager = (LinearLayoutManager) parent.getLayoutManager();
return layoutManager.getOrientation();
}
else
{
throw new IllegalStateException(
"DividerItemDecoration can only be used with a LinearLayoutManager.");
}
}
}
@@ -16,10 +16,10 @@ import android.view.View;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.activities.AddDirectoryActivity;
import org.dolphinemu.dolphinemu.activities.SettingsActivity;
import org.dolphinemu.dolphinemu.adapters.PlatformPagerAdapter;
import org.dolphinemu.dolphinemu.model.GameProvider;
import org.dolphinemu.dolphinemu.ui.platform.PlatformGamesView;
import org.dolphinemu.dolphinemu.ui.settings.SettingsActivity;
import org.dolphinemu.dolphinemu.utils.StartupHandler;
/**
@@ -115,9 +115,9 @@ public final class MainActivity extends AppCompatActivity implements MainView
}
@Override
public void launchSettingsActivity()
public void launchSettingsActivity(String menuTag)
{
SettingsActivity.launch(this);
SettingsActivity.launch(this, menuTag);
}
@Override

Some files were not shown because too many files have changed in this diff Show More