Android: Add Paths to UI

This commit is contained in:
Ryan Meredith 2020-03-22 06:43:35 -04:00
parent 38fa38d424
commit ccda75f33f
22 changed files with 517 additions and 39 deletions

View File

@ -24,7 +24,6 @@ import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.View;
import android.widget.SeekBar;
import android.widget.TextView;
@ -402,7 +401,7 @@ public final class EmulationActivity extends AppCompatActivity
// If the user picked a file, as opposed to just backing out.
if (resultCode == MainActivity.RESULT_OK)
{
String newDiscPath = FileBrowserHelper.getSelectedDirectory(result);
String newDiscPath = FileBrowserHelper.getSelectedPath(result);
if (!TextUtils.isEmpty(newDiscPath))
{
NativeLibrary.ChangeDisc(newDiscPath);

View File

@ -8,13 +8,13 @@ import org.dolphinemu.dolphinemu.features.settings.utils.SettingsFile;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
public class Settings
{
public static final String SECTION_INI_GENERAL = "General";
public static final String SECTION_INI_CORE = "Core";
public static final String SECTION_INI_INTERFACE = "Interface";
public static final String SECTION_INI_DSP = "DSP";
@ -42,7 +42,8 @@ public class Settings
static
{
configFileSectionsMap.put(SettingsFile.FILE_NAME_DOLPHIN,
Arrays.asList(SECTION_INI_CORE, SECTION_INI_INTERFACE, SECTION_INI_DSP,
Arrays.asList(SECTION_INI_GENERAL, SECTION_INI_CORE, SECTION_INI_INTERFACE,
SECTION_INI_DSP,
SECTION_BINDINGS, SECTION_ANALYTICS, SECTION_DEBUG));
configFileSectionsMap.put(SettingsFile.FILE_NAME_GFX,
Arrays.asList(SECTION_GFX_SETTINGS, SECTION_GFX_ENHANCEMENTS, SECTION_GFX_HACKS,

View File

@ -0,0 +1,38 @@
package org.dolphinemu.dolphinemu.features.settings.model.view;
public final class ConfirmRunnable extends SettingsItem
{
private int mAlertText;
private int mConfirmationText;
private Runnable mRunnable;
public ConfirmRunnable(int titleId, int descriptionId, int alertText, int confirmationText,
Runnable runnable)
{
super(null, null, null, titleId, descriptionId);
mAlertText = alertText;
mConfirmationText = confirmationText;
mRunnable = runnable;
}
public int getAlertText()
{
return mAlertText;
}
public int getConfirmationText()
{
return mConfirmationText;
}
public Runnable getRunnable()
{
return mRunnable;
}
@Override
public int getType()
{
return TYPE_CONFIRM_RUNNABLE;
}
}

View File

@ -0,0 +1,50 @@
package org.dolphinemu.dolphinemu.features.settings.model.view;
import org.dolphinemu.dolphinemu.features.settings.model.Setting;
import org.dolphinemu.dolphinemu.features.settings.model.StringSetting;
public final class FilePicker extends SettingsItem
{
private String mFile;
private String mDefaultValue;
private int mRequestType;
public FilePicker(String file, String key, String section, int titleId, int descriptionId,
String defaultVault, int requestType, Setting setting)
{
super(key, section, setting, titleId, descriptionId);
mFile = file;
mDefaultValue = defaultVault;
mRequestType = requestType;
}
public String getFile()
{
return mFile + ".ini";
}
public String getSelectedValue()
{
StringSetting setting = (StringSetting) getSetting();
if (setting == null)
{
return mDefaultValue;
}
else
{
return setting.getValue();
}
}
public int getRequestType()
{
return mRequestType;
}
@Override
public int getType()
{
return TYPE_FILE_PICKER;
}
}

View File

@ -21,6 +21,8 @@ public abstract class SettingsItem
public static final int TYPE_STRING_SINGLE_CHOICE = 6;
public static final int TYPE_RUMBLE_BINDING = 7;
public static final int TYPE_SINGLE_CHOICE_DYNAMIC_DESCRIPTIONS = 8;
public static final int TYPE_FILE_PICKER = 9;
public static final int TYPE_CONFIRM_RUNNABLE = 10;
private String mKey;
private String mSection;

View File

@ -5,6 +5,7 @@ public enum MenuTag
CONFIG("config"),
CONFIG_GENERAL("config_general"),
CONFIG_INTERFACE("config_interface"),
CONFIG_PATHS("config_paths"),
CONFIG_GAME_CUBE("config_gamecube"),
CONFIG_WII("config_wii"),
WIIMOTE("wiimote"),
@ -26,7 +27,8 @@ public enum MenuTag
WIIMOTE_EXTENSION_1("wiimote_extension", 4),
WIIMOTE_EXTENSION_2("wiimote_extension", 5),
WIIMOTE_EXTENSION_3("wiimote_extension", 6),
WIIMOTE_EXTENSION_4("wiimote_extension", 7);
WIIMOTE_EXTENSION_4("wiimote_extension", 7),
BLANK("Blank");
private String tag;
private int subType = -1;

View File

@ -19,8 +19,10 @@ import android.view.MenuItem;
import android.widget.Toast;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.ui.main.MainActivity;
import org.dolphinemu.dolphinemu.utils.DirectoryInitialization;
import org.dolphinemu.dolphinemu.utils.DirectoryStateReceiver;
import org.dolphinemu.dolphinemu.utils.FileBrowserHelper;
public final class SettingsActivity extends AppCompatActivity implements SettingsActivityView
{
@ -103,13 +105,13 @@ public final class SettingsActivity extends AppCompatActivity implements Setting
@Override
public void showSettingsFragment(MenuTag menuTag, Bundle extras, boolean addToStack,
String gameID)
boolean customAnimations, String gameID)
{
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
if (addToStack)
{
if (areSystemAnimationsEnabled())
if (areSystemAnimationsEnabled() && customAnimations)
{
transaction.setCustomAnimations(
R.animator.settings_enter,
@ -154,6 +156,35 @@ public final class SettingsActivity extends AppCompatActivity implements Setting
LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent result)
{
super.onActivityResult(requestCode, resultCode, result);
// Save modified non-FilePicker settings beforehand since finish() won't save them.
// onStop() must come before handling the resultCode to properly save FilePicker selection.
mPresenter.onStop(true);
// If the user picked a file, as opposed to just backing out.
if (resultCode == MainActivity.RESULT_OK)
{
mPresenter.onFileConfirmed(FileBrowserHelper.getSelectedPath(result));
// Prevent duplicate Toasts.
if (!mPresenter.shouldSave())
{
Toast.makeText(this, "Saved settings to INI files", Toast.LENGTH_SHORT).show();
}
}
// Clear static variables for File Picker activities that don't set extensions.
SettingsAdapter.sFilePicker = null;
SettingsAdapter.sItem = null;
// TODO: After result of FilePicker, duplicate SettingsActivity appears.
// Finish to avoid this. Is there a better method?
finish();
}
@Override
public void showLoading()
{

View File

@ -70,7 +70,7 @@ public final class SettingsActivityPresenter
}
}
mView.showSettingsFragment(menuTag, null, false, gameId);
mView.showSettingsFragment(menuTag, null, false, true, gameId);
mView.onSettingsFileLoaded(mSettings);
}
@ -184,13 +184,18 @@ public final class SettingsActivityPresenter
outState.putBoolean(KEY_SHOULD_SAVE, mShouldSave);
}
public boolean shouldSave()
{
return mShouldSave;
}
public void onGcPadSettingChanged(MenuTag key, int value)
{
if (value != 0) // Not disabled
{
Bundle bundle = new Bundle();
bundle.putInt(SettingsFragmentPresenter.ARG_CONTROLLER_TYPE, value / 6);
mView.showSettingsFragment(key, bundle, true, gameId);
mView.showSettingsFragment(key, bundle, true, true, gameId);
}
}
@ -199,7 +204,7 @@ public final class SettingsActivityPresenter
switch (value)
{
case 1:
mView.showSettingsFragment(menuTag, null, true, gameId);
mView.showSettingsFragment(menuTag, null, true, true, gameId);
break;
case 2:
@ -214,7 +219,12 @@ public final class SettingsActivityPresenter
{
Bundle bundle = new Bundle();
bundle.putInt(SettingsFragmentPresenter.ARG_CONTROLLER_TYPE, value);
mView.showSettingsFragment(menuTag, bundle, true, gameId);
mView.showSettingsFragment(menuTag, bundle, true, true, gameId);
}
}
public void onFileConfirmed(String file)
{
SettingsAdapter.onFilePickerConfirmation(file);
}
}

View File

@ -14,10 +14,12 @@ public interface SettingsActivityView
/**
* Show a new SettingsFragment.
*
* @param menuTag Identifier for the settings group that should be displayed.
* @param addToStack Whether or not this fragment should replace a previous one.
* @param menuTag Identifier for the settings group that should be displayed.
* @param addToStack Whether or not this fragment should replace a previous one.
* @param customAnimations Custom animations are used if true while system animations are enabled.
*/
void showSettingsFragment(MenuTag menuTag, Bundle extras, boolean addToStack, String gameId);
void showSettingsFragment(MenuTag menuTag, Bundle extras, boolean addToStack,
boolean customAnimations, String gameId);
/**
* Called by a contained Fragment to get access to the Setting HashMap

View File

@ -14,6 +14,7 @@ import android.view.ViewGroup;
import android.widget.SeekBar;
import android.widget.TextView;
import org.dolphinemu.dolphinemu.NativeLibrary;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.dialogs.MotionAlertDialog;
import org.dolphinemu.dolphinemu.features.settings.model.BooleanSetting;
@ -22,6 +23,7 @@ import org.dolphinemu.dolphinemu.features.settings.model.IntSetting;
import org.dolphinemu.dolphinemu.features.settings.model.Settings;
import org.dolphinemu.dolphinemu.features.settings.model.StringSetting;
import org.dolphinemu.dolphinemu.features.settings.model.view.CheckBoxSetting;
import org.dolphinemu.dolphinemu.features.settings.model.view.FilePicker;
import org.dolphinemu.dolphinemu.features.settings.model.view.InputBindingSetting;
import org.dolphinemu.dolphinemu.features.settings.model.view.RumbleBindingSetting;
import org.dolphinemu.dolphinemu.features.settings.model.view.SettingsItem;
@ -31,6 +33,8 @@ import org.dolphinemu.dolphinemu.features.settings.model.view.SliderSetting;
import org.dolphinemu.dolphinemu.features.settings.model.view.StringSingleChoiceSetting;
import org.dolphinemu.dolphinemu.features.settings.model.view.SubmenuSetting;
import org.dolphinemu.dolphinemu.features.settings.ui.viewholder.CheckBoxSettingViewHolder;
import org.dolphinemu.dolphinemu.features.settings.ui.viewholder.ConfirmRunnableViewHolder;
import org.dolphinemu.dolphinemu.features.settings.ui.viewholder.FilePickerViewHolder;
import org.dolphinemu.dolphinemu.features.settings.ui.viewholder.HeaderViewHolder;
import org.dolphinemu.dolphinemu.features.settings.ui.viewholder.InputBindingSettingViewHolder;
import org.dolphinemu.dolphinemu.features.settings.ui.viewholder.RumbleBindingViewHolder;
@ -39,9 +43,15 @@ import org.dolphinemu.dolphinemu.features.settings.ui.viewholder.SingleChoiceVie
import org.dolphinemu.dolphinemu.features.settings.ui.viewholder.SliderViewHolder;
import org.dolphinemu.dolphinemu.features.settings.ui.viewholder.SubmenuViewHolder;
import org.dolphinemu.dolphinemu.features.settings.utils.SettingsFile;
import org.dolphinemu.dolphinemu.ui.main.MainPresenter;
import org.dolphinemu.dolphinemu.utils.FileBrowserHelper;
import org.dolphinemu.dolphinemu.utils.Log;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
public final class SettingsAdapter extends RecyclerView.Adapter<SettingViewHolder>
implements DialogInterface.OnClickListener, SeekBar.OnSeekBarChangeListener
@ -57,6 +67,14 @@ public final class SettingsAdapter extends RecyclerView.Adapter<SettingViewHolde
private AlertDialog mDialog;
private TextView mTextSliderValue;
public static FilePicker sFilePicker;
public static SettingsItem sItem;
private static final Set<String> gameExtensions = new HashSet<>(Arrays.asList(
"gcm", "tgc", "iso", "ciso", "gcz", "wbfs", "wad", "dol", "elf", "dff"));
private static final Set<String> SDExtensions = new HashSet<>(Collections.singletonList("raw"));
public SettingsAdapter(SettingsFragmentView view, Context context)
{
mView = view;
@ -102,6 +120,14 @@ public final class SettingsAdapter extends RecyclerView.Adapter<SettingViewHolde
view = inflater.inflate(R.layout.list_item_setting, parent, false);
return new RumbleBindingViewHolder(view, this, mContext);
case SettingsItem.TYPE_FILE_PICKER:
view = inflater.inflate(R.layout.list_item_setting, parent, false);
return new FilePickerViewHolder(view, this);
case SettingsItem.TYPE_CONFIRM_RUNNABLE:
view = inflater.inflate(R.layout.list_item_setting, parent, false);
return new ConfirmRunnableViewHolder(view, this, mContext, mView);
default:
Log.error("[SettingsAdapter] Invalid view type: " + viewType);
return null;
@ -274,6 +300,65 @@ public final class SettingsAdapter extends RecyclerView.Adapter<SettingViewHolde
dialog.show();
}
public void onFilePickerDirectoryClick(SettingsItem item)
{
sFilePicker = (FilePicker) item;
sItem = item;
FileBrowserHelper.openDirectoryPicker(mView.getActivity());
}
public void onFilePickerFileClick(SettingsItem item)
{
sFilePicker = (FilePicker) item;
sItem = item;
FileBrowserHelper.openFilePicker(mView.getActivity(), sFilePicker.getRequestType(), false);
}
public static void onFilePickerConfirmation(String file)
{
NativeLibrary.SetConfig(sFilePicker.getFile(), sItem.getSection(), sItem.getKey(), file);
NativeLibrary.ReloadConfig();
}
public static void resetPaths()
{
NativeLibrary.SetConfig(SettingsFile.FILE_NAME_DOLPHIN + ".ini", Settings.SECTION_INI_CORE,
SettingsFile.KEY_DEFAULT_ISO, "");
NativeLibrary.SetConfig(SettingsFile.FILE_NAME_DOLPHIN + ".ini", Settings.SECTION_INI_GENERAL,
SettingsFile.KEY_NAND_ROOT_PATH, SettingsFragmentPresenter.getDefaultNANDRootPath());
NativeLibrary.SetConfig(SettingsFile.FILE_NAME_DOLPHIN + ".ini", Settings.SECTION_INI_GENERAL,
SettingsFile.KEY_DUMP_PATH, SettingsFragmentPresenter.getDefaultDumpPath());
NativeLibrary.SetConfig(SettingsFile.FILE_NAME_DOLPHIN + ".ini", Settings.SECTION_INI_GENERAL,
SettingsFile.KEY_LOAD_PATH, SettingsFragmentPresenter.getDefaultLoadPath());
NativeLibrary.SetConfig(SettingsFile.FILE_NAME_DOLPHIN + ".ini", Settings.SECTION_INI_GENERAL,
SettingsFile.KEY_RESOURCE_PACK_PATH,
SettingsFragmentPresenter.getDefaultResourcePackPath());
NativeLibrary.SetConfig(SettingsFile.FILE_NAME_DOLPHIN + ".ini", Settings.SECTION_INI_GENERAL,
SettingsFile.KEY_WII_SD_CARD_PATH, SettingsFragmentPresenter.getDefaultSDPath());
NativeLibrary.ReloadConfig();
}
public static Set<String> getExtensions()
{
try
{
if (sFilePicker.getRequestType() == MainPresenter.REQUEST_SD_FILE)
{
return SDExtensions;
}
else
{
return gameExtensions;
}
}
catch (NullPointerException ex)
{
return gameExtensions;
}
}
@Override
public void onClick(DialogInterface dialog, int which)
{

View File

@ -1,6 +1,5 @@
package org.dolphinemu.dolphinemu.features.settings.ui;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
@ -21,6 +20,7 @@ import org.dolphinemu.dolphinemu.ui.DividerItemDecoration;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
public final class SettingsFragment extends Fragment implements SettingsFragmentView
{
@ -39,6 +39,7 @@ public final class SettingsFragment extends Fragment implements SettingsFragment
titles.put(MenuTag.CONFIG, R.string.preferences_settings);
titles.put(MenuTag.CONFIG_GENERAL, R.string.general_submenu);
titles.put(MenuTag.CONFIG_INTERFACE, R.string.interface_submenu);
titles.put(MenuTag.CONFIG_PATHS, R.string.paths_submenu);
titles.put(MenuTag.CONFIG_GAME_CUBE, R.string.gamecube_submenu);
titles.put(MenuTag.CONFIG_WII, R.string.wii_submenu);
titles.put(MenuTag.WIIMOTE, R.string.grid_menu_wiimote_settings);
@ -179,7 +180,18 @@ public final class SettingsFragment extends Fragment implements SettingsFragment
@Override
public void loadSubMenu(MenuTag menuKey)
{
mActivity.showSettingsFragment(menuKey, null, true, getArguments().getString(ARGUMENT_GAME_ID));
mActivity
.showSettingsFragment(menuKey, null, true, true,
getArguments().getString(ARGUMENT_GAME_ID));
}
@Override
public void reloadSubMenu()
{
mActivity
.showSettingsFragment(MenuTag.BLANK, null, true, false,
getArguments().getString(ARGUMENT_GAME_ID));
Objects.requireNonNull(getActivity()).onBackPressed();
}
@Override
@ -217,5 +229,4 @@ public final class SettingsFragment extends Fragment implements SettingsFragment
{
mActivity.onExtensionSettingChanged(menuTag, value);
}
}

View File

@ -3,7 +3,6 @@ package org.dolphinemu.dolphinemu.features.settings.ui;
import android.os.Bundle;
import android.text.TextUtils;
import org.dolphinemu.dolphinemu.DolphinApplication;
import org.dolphinemu.dolphinemu.NativeLibrary;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.features.settings.model.BooleanSetting;
@ -13,6 +12,8 @@ import org.dolphinemu.dolphinemu.features.settings.model.SettingSection;
import org.dolphinemu.dolphinemu.features.settings.model.Settings;
import org.dolphinemu.dolphinemu.features.settings.model.StringSetting;
import org.dolphinemu.dolphinemu.features.settings.model.view.CheckBoxSetting;
import org.dolphinemu.dolphinemu.features.settings.model.view.ConfirmRunnable;
import org.dolphinemu.dolphinemu.features.settings.model.view.FilePicker;
import org.dolphinemu.dolphinemu.features.settings.model.view.HeaderSetting;
import org.dolphinemu.dolphinemu.features.settings.model.view.InputBindingSetting;
import org.dolphinemu.dolphinemu.features.settings.model.view.RumbleBindingSetting;
@ -23,10 +24,10 @@ import org.dolphinemu.dolphinemu.features.settings.model.view.SliderSetting;
import org.dolphinemu.dolphinemu.features.settings.model.view.StringSingleChoiceSetting;
import org.dolphinemu.dolphinemu.features.settings.model.view.SubmenuSetting;
import org.dolphinemu.dolphinemu.features.settings.utils.SettingsFile;
import org.dolphinemu.dolphinemu.ui.main.MainPresenter;
import org.dolphinemu.dolphinemu.utils.DirectoryInitialization;
import org.dolphinemu.dolphinemu.utils.EGLHelper;
import org.dolphinemu.dolphinemu.utils.Log;
import org.dolphinemu.dolphinemu.utils.TvUtil;
import java.io.File;
import java.util.ArrayList;
@ -135,6 +136,10 @@ public final class SettingsFragmentPresenter
addInterfaceSettings(sl);
break;
case CONFIG_PATHS:
addPathsSettings(sl);
break;
case CONFIG_GAME_CUBE:
addGameCubeSettings(sl);
break;
@ -192,6 +197,9 @@ public final class SettingsFragmentPresenter
addStereoSettings(sl);
break;
case BLANK:
break;
default:
mView.showToastMessage("Unimplemented menu");
return;
@ -205,6 +213,7 @@ public final class SettingsFragmentPresenter
{
sl.add(new SubmenuSetting(null, null, R.string.general_submenu, 0, MenuTag.CONFIG_GENERAL));
sl.add(new SubmenuSetting(null, null, R.string.interface_submenu, 0, MenuTag.CONFIG_INTERFACE));
sl.add(new SubmenuSetting(null, null, R.string.paths_submenu, 0, MenuTag.CONFIG_PATHS));
sl.add(new SubmenuSetting(null, null, R.string.gamecube_submenu, 0, MenuTag.CONFIG_GAME_CUBE));
sl.add(new SubmenuSetting(null, null, R.string.wii_submenu, 0, MenuTag.CONFIG_WII));
@ -307,6 +316,47 @@ public final class SettingsFragmentPresenter
onScreenDisplayMessages));
}
private void addPathsSettings(ArrayList<SettingsItem> sl)
{
Setting defaultISO = null;
Setting NANDRootPath = null;
Setting dumpPath = null;
Setting loadPath = null;
Setting resourcePackPath = null;
Setting wiiSDCardPath = null;
SettingSection coreSection = mSettings.getSection(Settings.SECTION_INI_CORE);
SettingSection generalSection = mSettings.getSection(Settings.SECTION_INI_GENERAL);
defaultISO = coreSection.getSetting(SettingsFile.KEY_DEFAULT_ISO);
NANDRootPath = generalSection.getSetting(SettingsFile.KEY_NAND_ROOT_PATH);
dumpPath = generalSection.getSetting(SettingsFile.KEY_DUMP_PATH);
loadPath = generalSection.getSetting(SettingsFile.KEY_LOAD_PATH);
resourcePackPath = generalSection.getSetting(SettingsFile.KEY_RESOURCE_PACK_PATH);
wiiSDCardPath = generalSection.getSetting(SettingsFile.KEY_WII_SD_CARD_PATH);
sl.add(new FilePicker(SettingsFile.FILE_NAME_DOLPHIN, SettingsFile.KEY_DEFAULT_ISO,
Settings.SECTION_INI_CORE, R.string.default_ISO, 0, "",
MainPresenter.REQUEST_GAME_FILE, defaultISO));
sl.add(new FilePicker(SettingsFile.FILE_NAME_DOLPHIN, SettingsFile.KEY_NAND_ROOT_PATH,
Settings.SECTION_INI_GENERAL, R.string.wii_NAND_root, 0, getDefaultNANDRootPath(),
MainPresenter.REQUEST_DIRECTORY, NANDRootPath));
sl.add(new FilePicker(SettingsFile.FILE_NAME_DOLPHIN, SettingsFile.KEY_DUMP_PATH,
Settings.SECTION_INI_GENERAL, R.string.dump_path, 0, getDefaultDumpPath(),
MainPresenter.REQUEST_DIRECTORY, dumpPath));
sl.add(new FilePicker(SettingsFile.FILE_NAME_DOLPHIN, SettingsFile.KEY_LOAD_PATH,
Settings.SECTION_INI_GENERAL, R.string.load_path, 0, getDefaultLoadPath(),
MainPresenter.REQUEST_DIRECTORY, loadPath));
sl.add(new FilePicker(SettingsFile.FILE_NAME_DOLPHIN, SettingsFile.KEY_RESOURCE_PACK_PATH,
Settings.SECTION_INI_GENERAL, R.string.resource_pack_path, 0,
getDefaultResourcePackPath(),
MainPresenter.REQUEST_DIRECTORY, resourcePackPath));
sl.add(new FilePicker(SettingsFile.FILE_NAME_DOLPHIN, SettingsFile.KEY_WII_SD_CARD_PATH,
Settings.SECTION_INI_GENERAL, R.string.SD_card_path, 0, getDefaultSDPath(),
MainPresenter.REQUEST_SD_FILE, wiiSDCardPath));
sl.add(new ConfirmRunnable(R.string.reset_paths, 0, R.string.reset_paths_confirmation,
R.string.reset_paths_complete, () -> SettingsAdapter.resetPaths()));
}
private void addGameCubeSettings(ArrayList<SettingsItem> sl)
{
Setting systemLanguage = null;
@ -1545,4 +1595,29 @@ public final class SettingsFragmentPresenter
return extensionValue;
}
public static String getDefaultNANDRootPath()
{
return DirectoryInitialization.getUserDirectory() + "/Wii";
}
public static String getDefaultDumpPath()
{
return DirectoryInitialization.getUserDirectory() + "/Dump";
}
public static String getDefaultLoadPath()
{
return DirectoryInitialization.getUserDirectory() + "/Load";
}
public static String getDefaultResourcePackPath()
{
return DirectoryInitialization.getUserDirectory() + "/ResourcePacks";
}
public static String getDefaultSDPath()
{
return DirectoryInitialization.getUserDirectory() + "/Wii/sd.raw";
}
}

View File

@ -57,6 +57,12 @@ public interface SettingsFragmentView
*/
void loadSubMenu(MenuTag menuKey);
/**
* Show a new blank submenu and then immediately back out of it.
* Useful for updating dynamic setting descriptions.
*/
void reloadSubMenu();
/**
* Tell the Fragment to tell the containing activity to display a toast message.
*

View File

@ -0,0 +1,85 @@
package org.dolphinemu.dolphinemu.features.settings.ui.viewholder;
import android.content.Context;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.features.settings.model.view.ConfirmRunnable;
import org.dolphinemu.dolphinemu.features.settings.model.view.SettingsItem;
import org.dolphinemu.dolphinemu.features.settings.ui.SettingsAdapter;
import org.dolphinemu.dolphinemu.features.settings.ui.SettingsFragmentView;
import androidx.appcompat.app.AlertDialog;
public final class ConfirmRunnableViewHolder extends SettingViewHolder
{
private ConfirmRunnable mItem;
private SettingsFragmentView mView;
private Context mContext;
private TextView mTextSettingName;
private TextView mTextSettingDescription;
public ConfirmRunnableViewHolder(View itemView, SettingsAdapter adapter, Context context,
SettingsFragmentView view)
{
super(itemView, adapter);
mContext = context;
mView = view;
}
@Override
protected void findViews(View root)
{
mTextSettingName = (TextView) root.findViewById(R.id.text_setting_name);
mTextSettingDescription = (TextView) root.findViewById(R.id.text_setting_description);
}
@Override
public void bind(SettingsItem item)
{
mItem = (ConfirmRunnable) item;
mTextSettingName.setText(item.getNameId());
if (item.getDescriptionId() > 0)
{
mTextSettingDescription.setText(item.getDescriptionId());
}
}
@Override
public void onClick(View clicked)
{
String alertTitle = mContext.getString(mItem.getNameId());
String alertText = mContext.getString(mItem.getAlertText());
String confirmationText = mContext.getString(mItem.getConfirmationText());
AlertDialog.Builder builder = new AlertDialog.Builder(mContext)
.setTitle(alertTitle)
.setMessage(alertText);
builder
.setPositiveButton("Yes", (dialog, whichButton) ->
{
mItem.getRunnable().run();
if (mItem.getConfirmationText() > 0)
{
Toast.makeText(mContext, confirmationText, Toast.LENGTH_SHORT).show();
}
dialog.dismiss();
mView.reloadSubMenu();
})
.setNegativeButton("No", (dialog, whichButton) ->
{
dialog.dismiss();
});
builder.show();
}
}

View File

@ -0,0 +1,66 @@
package org.dolphinemu.dolphinemu.features.settings.ui.viewholder;
import android.view.View;
import android.widget.TextView;
import org.dolphinemu.dolphinemu.NativeLibrary;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.features.settings.model.view.FilePicker;
import org.dolphinemu.dolphinemu.features.settings.model.view.SettingsItem;
import org.dolphinemu.dolphinemu.features.settings.ui.SettingsAdapter;
import org.dolphinemu.dolphinemu.features.settings.utils.SettingsFile;
import org.dolphinemu.dolphinemu.ui.main.MainPresenter;
public final class FilePickerViewHolder extends SettingViewHolder
{
private FilePicker mFilePicker;
private SettingsItem mItem;
private TextView mTextSettingName;
private TextView mTextSettingDescription;
public FilePickerViewHolder(View itemView, SettingsAdapter adapter)
{
super(itemView, adapter);
}
@Override
protected void findViews(View root)
{
mTextSettingName = (TextView) root.findViewById(R.id.text_setting_name);
mTextSettingDescription = (TextView) root.findViewById(R.id.text_setting_description);
}
@Override
public void bind(SettingsItem item)
{
mFilePicker = (FilePicker) item;
mItem = item;
mTextSettingName.setText(item.getNameId());
if (item.getDescriptionId() > 0)
{
mTextSettingDescription.setText(item.getDescriptionId());
}
else
{
mTextSettingDescription.setText(NativeLibrary
.GetConfig(mFilePicker.getFile(), item.getSection(), item.getKey(),
mFilePicker.getSelectedValue()));
}
}
@Override
public void onClick(View clicked)
{
if (mFilePicker.getRequestType() == MainPresenter.REQUEST_DIRECTORY)
{
getAdapter().onFilePickerDirectoryClick(mItem);
}
else
{
getAdapter().onFilePickerFileClick(mItem);
}
}
}

View File

@ -55,6 +55,11 @@ public final class SettingsFile
public static final String KEY_SLOT_B_DEVICE = "SlotB";
public static final String KEY_ENABLE_SAVE_STATES = "EnableSaveStates";
public static final String KEY_DEFAULT_ISO = "DefaultISO";
public static final String KEY_NAND_ROOT_PATH = "NANDRootPath";
public static final String KEY_DUMP_PATH = "DumpPath";
public static final String KEY_LOAD_PATH = "LoadPath";
public static final String KEY_RESOURCE_PACK_PATH = "ResourcePackPath";
public static final String KEY_WII_SD_CARD_PATH = "WiiSDCardPath";
public static final String KEY_ANALYTICS_ENABLED = "Enabled";
public static final String KEY_ANALYTICS_PERMISSION_ASKED = "PermissionAsked";

View File

@ -10,19 +10,14 @@ import android.view.View;
import android.widget.TextView;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.features.settings.ui.SettingsAdapter;
import com.nononsenseapps.filepicker.FilePickerFragment;
import java.io.File;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
public class CustomFilePickerFragment extends FilePickerFragment
{
private static final Set<String> extensions = new HashSet<>(Arrays.asList(
"gcm", "tgc", "iso", "ciso", "gcz", "wbfs", "wad", "dol", "elf", "dff"));
@NonNull
@Override
public Uri toUri(@NonNull final File file)
@ -56,7 +51,8 @@ public class CustomFilePickerFragment extends FilePickerFragment
return (showHiddenItems || !file.isHidden()) &&
(file.isDirectory() ||
extensions.contains(fileExtension(file.getName()).toLowerCase()));
SettingsAdapter.getExtensions()
.contains(fileExtension(file.getName()).toLowerCase()));
}
@Override

View File

@ -151,7 +151,7 @@ public final class MainActivity extends AppCompatActivity implements MainView
@Override
public void launchOpenFileActivity()
{
FileBrowserHelper.openFilePicker(this, MainPresenter.REQUEST_OPEN_FILE, true);
FileBrowserHelper.openFilePicker(this, MainPresenter.REQUEST_GAME_FILE, false);
}
/**
@ -162,17 +162,18 @@ public final class MainActivity extends AppCompatActivity implements MainView
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent result)
{
super.onActivityResult(requestCode, resultCode, result);
switch (requestCode)
{
case MainPresenter.REQUEST_ADD_DIRECTORY:
case MainPresenter.REQUEST_DIRECTORY:
// If the user picked a file, as opposed to just backing out.
if (resultCode == MainActivity.RESULT_OK)
{
mPresenter.onDirectorySelected(FileBrowserHelper.getSelectedDirectory(result));
mPresenter.onDirectorySelected(FileBrowserHelper.getSelectedPath(result));
}
break;
case MainPresenter.REQUEST_OPEN_FILE:
case MainPresenter.REQUEST_GAME_FILE:
// If the user picked a file, as opposed to just backing out.
if (resultCode == MainActivity.RESULT_OK)
{

View File

@ -15,8 +15,9 @@ import org.dolphinemu.dolphinemu.services.GameFileCacheService;
public final class MainPresenter
{
public static final int REQUEST_ADD_DIRECTORY = 1;
public static final int REQUEST_OPEN_FILE = 2;
public static final int REQUEST_DIRECTORY = 1;
public static final int REQUEST_GAME_FILE = 2;
public static final int REQUEST_SD_FILE = 3;
private final MainView mView;
private final Context mContext;

View File

@ -5,7 +5,6 @@ import android.content.pm.PackageManager;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.leanback.app.BrowseFragment;
import androidx.leanback.app.BrowseSupportFragment;
import androidx.leanback.widget.ArrayObjectAdapter;
import androidx.leanback.widget.HeaderItem;
@ -149,7 +148,7 @@ public final class TvMainActivity extends FragmentActivity implements MainView
@Override
public void launchOpenFileActivity()
{
FileBrowserHelper.openFilePicker(this, MainPresenter.REQUEST_OPEN_FILE, true);
FileBrowserHelper.openFilePicker(this, MainPresenter.REQUEST_GAME_FILE, false);
}
@Override
@ -171,17 +170,18 @@ public final class TvMainActivity extends FragmentActivity implements MainView
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent result)
{
super.onActivityResult(requestCode, resultCode, result);
switch (requestCode)
{
case MainPresenter.REQUEST_ADD_DIRECTORY:
case MainPresenter.REQUEST_DIRECTORY:
// If the user picked a file, as opposed to just backing out.
if (resultCode == MainActivity.RESULT_OK)
{
mPresenter.onDirectorySelected(FileBrowserHelper.getSelectedDirectory(result));
mPresenter.onDirectorySelected(FileBrowserHelper.getSelectedPath(result));
}
break;
case MainPresenter.REQUEST_OPEN_FILE:
case MainPresenter.REQUEST_GAME_FILE:
// If the user picked a file, as opposed to just backing out.
if (resultCode == MainActivity.RESULT_OK)
{

View File

@ -28,7 +28,7 @@ public final class FileBrowserHelper
i.putExtra(FilePickerActivity.EXTRA_START_PATH,
Environment.getExternalStorageDirectory().getPath());
activity.startActivityForResult(i, MainPresenter.REQUEST_ADD_DIRECTORY);
activity.startActivityForResult(i, MainPresenter.REQUEST_DIRECTORY);
}
public static void openFilePicker(FragmentActivity activity, int requestCode, boolean allowMulti)
@ -45,7 +45,7 @@ public final class FileBrowserHelper
}
@Nullable
public static String getSelectedDirectory(Intent result)
public static String getSelectedPath(Intent result)
{
// Use the provided utility method to parse the result
List<Uri> files = Utils.getSelectedFilesFromResult(result);

View File

@ -162,6 +162,18 @@
<string name="osd_messages">Show On-Screen Display Messages</string>
<string name="osd_messages_description">Display messages over the emulation screen area. These messages include memory card writes, video backend and CPU information, and JIT cache clearing.</string>
<!-- Path Settings -->
<string name="paths_submenu">Paths</string>
<string name="default_ISO">Default ISO</string>
<string name="wii_NAND_root">Wii NAND Root</string>
<string name="dump_path">Dump Path</string>
<string name="load_path">Load Path</string>
<string name="resource_pack_path">Resource Pack Path</string>
<string name="SD_card_path">SD Card Path</string>
<string name="reset_paths">Reset Paths to Default Settings</string>
<string name="reset_paths_confirmation">Are you sure you want to reset Paths to default settings?</string>
<string name="reset_paths_complete">Paths reset</string>
<!-- Graphics Settings -->
<string name="graphics_general">General</string>
<string name="graphics_enhancements_and_hacks">Enhancements &amp; Hacks</string>