make screenshots save in the pictures folder
Before Width: | Height: | Size: 748 B |
Before Width: | Height: | Size: 495 B |
Before Width: | Height: | Size: 401 B |
Before Width: | Height: | Size: 296 B |
Before Width: | Height: | Size: 510 B |
Before Width: | Height: | Size: 391 B |
Before Width: | Height: | Size: 997 B |
Before Width: | Height: | Size: 547 B |
@ -1,111 +0,0 @@
|
||||
package com.retroarch.browser;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import com.retroarch.R;
|
||||
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
public final class FileWrapper implements IconAdapterItem, Comparable<FileWrapper> {
|
||||
|
||||
public static final int DIRSELECT = 0;
|
||||
public static final int PARENT = 1;
|
||||
public static final int FILE = 2;
|
||||
|
||||
private final File file;
|
||||
private final boolean parentItem;
|
||||
private final boolean dirSelectItem;
|
||||
private final boolean enabled;
|
||||
private final int typeIndex;
|
||||
|
||||
public FileWrapper(File file, int type, boolean isEnabled) {
|
||||
this.file = file;
|
||||
|
||||
this.parentItem = (type == PARENT);
|
||||
this.dirSelectItem = (type == DIRSELECT);
|
||||
this.typeIndex = (type == FILE) ? (FILE + (file.isDirectory() ? 0 : 1)) : type;
|
||||
|
||||
this.enabled = parentItem || dirSelectItem || isEnabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText() {
|
||||
if (dirSelectItem)
|
||||
return "[[Use this directory]]";
|
||||
else if (parentItem)
|
||||
return "[Parent Directory]";
|
||||
else
|
||||
return file.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSubText() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIconResourceId() {
|
||||
if (!parentItem && !dirSelectItem) {
|
||||
return file.isFile() ? R.drawable.ic_file : R.drawable.ic_dir;
|
||||
} else {
|
||||
return R.drawable.ic_dir;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Drawable getIconDrawable() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether or not the wrapped {@link File} is
|
||||
* the "Parent Directory" item in the file browser.
|
||||
*
|
||||
* @return true if the wrapped {@link File} is the "Parent Directory"
|
||||
* item in the file browser; false otherwise.
|
||||
*/
|
||||
public boolean isParentItem() {
|
||||
return parentItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether or not the wrapped {@link File}
|
||||
* is the "use this directory" item.
|
||||
*
|
||||
* @return true if the wrapped {@link File} is the "Use this directory"
|
||||
* item in the file browser; false otherwise.
|
||||
*/
|
||||
public boolean isDirSelectItem() {
|
||||
return dirSelectItem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the file wrapped by this FileWrapper.
|
||||
*
|
||||
* @return the file wrapped by this FileWrapper.
|
||||
*/
|
||||
public File getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(FileWrapper other) {
|
||||
if (other != null) {
|
||||
// Who says ternary is hard to follow
|
||||
if (isEnabled() == other.isEnabled()) {
|
||||
return (typeIndex == other.typeIndex) ? file
|
||||
.compareTo(other.file)
|
||||
: ((typeIndex < other.typeIndex) ? -1 : 1);
|
||||
} else {
|
||||
return isEnabled() ? -1 : 1;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
@ -1,152 +0,0 @@
|
||||
package com.retroarch.browser;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.retroarch.R;
|
||||
|
||||
import android.content.*;
|
||||
import android.graphics.drawable.*;
|
||||
import android.view.*;
|
||||
import android.widget.*;
|
||||
|
||||
/**
|
||||
* Represents an item that is capable
|
||||
* of being within an {@link IconAdapter}.
|
||||
*/
|
||||
interface IconAdapterItem {
|
||||
|
||||
/**
|
||||
* Gets whether or not this item is
|
||||
* enabled within the adapter.
|
||||
* <p>
|
||||
* This can be used for deciding whether or
|
||||
* not to enable an item in a {@link ListView}
|
||||
* if an IconAdapter is backing it.
|
||||
*
|
||||
* @return true if this item is enabled; false otherwise.
|
||||
*/
|
||||
public boolean isEnabled();
|
||||
|
||||
/**
|
||||
* Gets the title text of this IconAdapterItem.
|
||||
*
|
||||
* @return the title text of this IconAdapterItem.
|
||||
*/
|
||||
public String getText();
|
||||
|
||||
/**
|
||||
* Gets the subtitle text of this IconAdapterItem.
|
||||
*
|
||||
* @return the subtitle text of this IconAdapterItem.
|
||||
*/
|
||||
public String getSubText();
|
||||
|
||||
/**
|
||||
* Gets the resource ID of the icon to display
|
||||
* alongside the text in this IconAdapterItem.
|
||||
* <p>
|
||||
* Returning zero means no icon is to be displayed.
|
||||
*
|
||||
* @return the resource ID of this IconAdapterItem's icon.
|
||||
*/
|
||||
public int getIconResourceId();
|
||||
|
||||
/**
|
||||
* Gets the actual {@link Drawable} object that represents
|
||||
* the icon that is displayed with this IconAdapterItem.
|
||||
* <p>
|
||||
* Returning null means no icon is to be displayed.
|
||||
*
|
||||
* @return the actual {@link Drawable} of this IconAdapterItem's icon.
|
||||
*/
|
||||
public Drawable getIconDrawable();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* An {@link ArrayAdapter} derivative that can back a {@link View}
|
||||
* that accepts ArrayAdapters. Items within this ArrayAdapter derivative
|
||||
* must implement the {@link IconAdapterItem} interface.
|
||||
*
|
||||
* @param <T> The type of the item that will be within this IconAdapter.
|
||||
* This type must implement the {@link IconAdapterItem} interface.
|
||||
*/
|
||||
public final class IconAdapter<T extends IconAdapterItem> extends ArrayAdapter<T> {
|
||||
private final int resourceId;
|
||||
private final Context context;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param context The current {@link Context}.
|
||||
* @param resourceId The resource ID for a layout file containing a layout to use when instantiating views.
|
||||
*/
|
||||
public IconAdapter(Context context, int resourceId) {
|
||||
super(context, resourceId);
|
||||
this.context = context;
|
||||
this.resourceId = resourceId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param context The current {@link Context}.
|
||||
* @param resourceId The resource ID for a layout file containing a layout to use when instantiating views.
|
||||
* @param items The list of items to store within this IconAdapter.
|
||||
*/
|
||||
public IconAdapter(Context context, int resourceId, List<T> items) {
|
||||
super(context, resourceId, items);
|
||||
this.context = context;
|
||||
this.resourceId = resourceId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
// Build the view
|
||||
if (convertView == null) {
|
||||
LayoutInflater inflater = LayoutInflater.from(context);
|
||||
convertView = inflater.inflate(resourceId, parent, false);
|
||||
}
|
||||
|
||||
// Fill the view
|
||||
IconAdapterItem item = getItem(position);
|
||||
final boolean enabled = item.isEnabled();
|
||||
|
||||
TextView title = (TextView) convertView.findViewById(R.id.name);
|
||||
if (title != null) {
|
||||
title.setText(item.getText());
|
||||
title.setEnabled(enabled);
|
||||
}
|
||||
|
||||
TextView subtitle = (TextView) convertView.findViewById(R.id.sub_name);
|
||||
if (subtitle != null) {
|
||||
String subText = item.getSubText();
|
||||
if (subText != null) {
|
||||
subtitle.setVisibility(View.VISIBLE);
|
||||
subtitle.setEnabled(item.isEnabled());
|
||||
subtitle.setText(subText);
|
||||
}
|
||||
}
|
||||
|
||||
ImageView imageView = (ImageView) convertView.findViewById(R.id.icon);
|
||||
if (imageView != null) {
|
||||
if (enabled) {
|
||||
final int id = item.getIconResourceId();
|
||||
if (id != 0) {
|
||||
imageView.setImageResource(id);
|
||||
} else {
|
||||
imageView.setImageDrawable(item.getIconDrawable());
|
||||
}
|
||||
} else {
|
||||
imageView.setImageDrawable(null);
|
||||
}
|
||||
}
|
||||
|
||||
return convertView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled(int aPosition) {
|
||||
return getItem(aPosition).isEnabled();
|
||||
}
|
||||
}
|
@ -1,261 +0,0 @@
|
||||
package com.retroarch.browser;
|
||||
|
||||
import com.retroarch.browser.preferences.util.ConfigFile;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
/**
|
||||
* Wrapper class that encapsulates a libretro core
|
||||
* along with information about said core.
|
||||
*/
|
||||
public final class ModuleWrapper implements IconAdapterItem, Comparable<ModuleWrapper>
|
||||
{
|
||||
private final File file;
|
||||
private final String displayName;
|
||||
private final String coreName;
|
||||
private final String manufacturer;
|
||||
private final String systemName;
|
||||
private final String license;
|
||||
private final List<String> authors;
|
||||
private final List<String> supportedExtensions;
|
||||
private final List<String> permissions;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param context The current {@link Context}.
|
||||
* @param file The {@link File} instance of the core being wrapped.
|
||||
*/
|
||||
public ModuleWrapper(Context context, File file)
|
||||
{
|
||||
this.file = file;
|
||||
|
||||
// Attempt to get the core's info file.
|
||||
// Basically this is dataDir/info/[core name].info
|
||||
|
||||
// So first, since the core name will have a platform-specific identifier at the end of its name, we trim this.
|
||||
// If it turns out we have an invalid core name, simply assign the core name as the full name of the file.
|
||||
final boolean isValidCoreName = (file.getName().lastIndexOf("_libretro.so") != -1);
|
||||
final String coreName = (isValidCoreName) ? file.getName().substring(0, file.getName().lastIndexOf(".so"))
|
||||
: file.getName();
|
||||
|
||||
// Now get the directory where all of the info files are kept (dataDir/info)
|
||||
final String infoFileDir = context.getApplicationInfo().dataDir + File.separator + "info";
|
||||
|
||||
// Now, based off of the trimmed core name, we can get the core info file.
|
||||
// and attempt to read it as a config file (since it has the same key-value layout).
|
||||
final String infoFilePath = infoFileDir + File.separator + coreName + ".info";
|
||||
if (new File(infoFilePath).exists())
|
||||
{
|
||||
final ConfigFile infoFile = new ConfigFile(infoFilePath);
|
||||
|
||||
// Now read info out of the info file. Make them an empty string if the key doesn't exist.
|
||||
this.displayName = (infoFile.keyExists("display_name")) ? infoFile.getString("display_name") : "N/A";
|
||||
this.coreName = (infoFile.keyExists("corename")) ? infoFile.getString("corename") : "N/A";
|
||||
this.systemName = (infoFile.keyExists("systemname")) ? infoFile.getString("systemname") : "N/A";
|
||||
this.manufacturer = (infoFile.keyExists("manufacturer")) ? infoFile.getString("manufacturer") : "N/A";
|
||||
this.license = (infoFile.keyExists("license")) ? infoFile.getString("license") : "N/A";
|
||||
|
||||
// Getting supported extensions and authors is a little different.
|
||||
// We need to split at every '|' character, since it is
|
||||
// the delimiter for a new extension that the core supports.
|
||||
//
|
||||
// Cores that don't have multiple extensions supported
|
||||
// don't contain the '|' delimiter, so we just create a String list
|
||||
// and just directly assign the retrieved extensions to it.
|
||||
final String supportedExts = infoFile.getString("supported_extensions");
|
||||
if (supportedExts != null && supportedExts.contains("|"))
|
||||
{
|
||||
this.supportedExtensions = new ArrayList<String>(Arrays.asList(supportedExts.split("\\|")));
|
||||
}
|
||||
else
|
||||
{
|
||||
this.supportedExtensions = new ArrayList<String>();
|
||||
this.supportedExtensions.add(supportedExts);
|
||||
}
|
||||
|
||||
final String emuAuthors = infoFile.getString("authors");
|
||||
if (emuAuthors != null && emuAuthors.contains("|"))
|
||||
{
|
||||
this.authors = new ArrayList<String>(Arrays.asList(emuAuthors.split("\\|")));
|
||||
}
|
||||
else
|
||||
{
|
||||
this.authors = new ArrayList<String>();
|
||||
this.authors.add(emuAuthors);
|
||||
}
|
||||
|
||||
final String permissions = infoFile.getString("permissions");
|
||||
if (permissions != null && permissions.contains("|"))
|
||||
{
|
||||
this.permissions = new ArrayList<String>(Arrays.asList(permissions.split("\\|")));
|
||||
}
|
||||
else
|
||||
{
|
||||
this.permissions = new ArrayList<String>();
|
||||
this.permissions.add(permissions);
|
||||
}
|
||||
}
|
||||
else // No info file.
|
||||
{
|
||||
this.displayName = "N/A";
|
||||
this.systemName = "N/A";
|
||||
this.manufacturer = "N/A";
|
||||
this.license = "N/A";
|
||||
this.authors = new ArrayList<String>();
|
||||
this.supportedExtensions = new ArrayList<String>();
|
||||
this.coreName = coreName;
|
||||
this.permissions = new ArrayList<String>();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as the original constructor, but allows for string paths.
|
||||
*
|
||||
* @param context The current {@link Context}.
|
||||
* @param path Path to the file to encapsulate.
|
||||
*/
|
||||
public ModuleWrapper(Context context, String path)
|
||||
{
|
||||
this(context, new File(path));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the underlying {@link File} instance for this ModuleWrapper.
|
||||
*
|
||||
* @return the underlying {@link File} instance for this ModuleWrapper.
|
||||
*/
|
||||
public File getUnderlyingFile()
|
||||
{
|
||||
return file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the display name for this wrapped core.
|
||||
*
|
||||
* @return the display name for this wrapped core.
|
||||
*/
|
||||
public String getDisplayName()
|
||||
{
|
||||
return displayName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the internal core name for this wrapped core.
|
||||
*
|
||||
* @return the internal core name for this wrapped core.
|
||||
*/
|
||||
public String getInternalName()
|
||||
{
|
||||
return coreName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the system that is emulated by this wrapped core.
|
||||
* (optional - in case core is an emulator)
|
||||
*
|
||||
* @return the name of the system that is emulated by this wrapped core.
|
||||
*/
|
||||
public String getEmulatedSystemName()
|
||||
{
|
||||
return systemName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the license that this core is protected under.
|
||||
*
|
||||
* @return the license that this core is protected under.
|
||||
*/
|
||||
public String getCoreLicense()
|
||||
{
|
||||
return license;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of the manufacturer of the console that
|
||||
* this core emulates. (optional - in case core is an
|
||||
* emulator)
|
||||
*
|
||||
* @return the name of the manufacturer of the console that
|
||||
* this core emulates. (optional)
|
||||
*/
|
||||
public String getManufacturer()
|
||||
{
|
||||
return manufacturer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of authors of this core.
|
||||
*
|
||||
* @return the list of authors of this core.
|
||||
*/
|
||||
public List<String> getAuthors()
|
||||
{
|
||||
return authors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the list of permissions of this core.
|
||||
*
|
||||
* @return the list of authors of this core.
|
||||
*/
|
||||
public List<String> getPermissions()
|
||||
{
|
||||
return permissions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the List of supported extensions for this core.
|
||||
*
|
||||
* @return the List of supported extensions for this core.
|
||||
*/
|
||||
public List<String> getSupportedExtensions()
|
||||
{
|
||||
return supportedExtensions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText()
|
||||
{
|
||||
return coreName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSubText()
|
||||
{
|
||||
return systemName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIconResourceId()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Drawable getIconDrawable()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(ModuleWrapper other)
|
||||
{
|
||||
if(coreName != null)
|
||||
return coreName.toLowerCase().compareTo(other.coreName.toLowerCase());
|
||||
else
|
||||
throw new NullPointerException("The name of this ModuleWrapper is null");
|
||||
}
|
||||
}
|
@ -1,396 +0,0 @@
|
||||
package com.retroarch.browser.dirfragment;
|
||||
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import android.support.v4.app.DialogFragment;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.AdapterView.OnItemClickListener;
|
||||
import android.widget.ListView;
|
||||
|
||||
import com.retroarch.R;
|
||||
import com.retroarch.browser.FileWrapper;
|
||||
import com.retroarch.browser.IconAdapter;
|
||||
import com.retroarch.browser.preferences.util.UserPreferences;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
|
||||
|
||||
/**
|
||||
* {@link DialogFragment} subclass that provides a file-browser
|
||||
* like UI for browsing for specific files.
|
||||
* <p>
|
||||
* This file browser also allows for custom filtering
|
||||
* depending on the type of class that inherits it.
|
||||
* <p>
|
||||
* This file browser also uses an implementation of a
|
||||
* backstack for remembering previously browsed folders
|
||||
* within this DirectoryFragment.
|
||||
* <p>
|
||||
* To instantiate a new instance of this class
|
||||
* you must use the {@code newInstance} method.
|
||||
*/
|
||||
public class DirectoryFragment extends DialogFragment
|
||||
{
|
||||
protected IconAdapter<FileWrapper> adapter;
|
||||
protected File listedDirectory;
|
||||
|
||||
public static final class BackStackItem implements Parcelable
|
||||
{
|
||||
protected final String path;
|
||||
protected boolean parentIsBack;
|
||||
|
||||
public BackStackItem(String path, boolean parentIsBack)
|
||||
{
|
||||
this.path = path;
|
||||
this.parentIsBack = parentIsBack;
|
||||
}
|
||||
|
||||
private BackStackItem(Parcel in)
|
||||
{
|
||||
this.path = in.readString();
|
||||
this.parentIsBack = in.readInt() != 0;
|
||||
}
|
||||
|
||||
public int describeContents()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void writeToParcel(Parcel out, int flags)
|
||||
{
|
||||
out.writeString(path);
|
||||
out.writeInt(parentIsBack ? 1 : 0);
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<BackStackItem> CREATOR = new Parcelable.Creator<BackStackItem>()
|
||||
{
|
||||
public BackStackItem createFromParcel(Parcel in)
|
||||
{
|
||||
return new BackStackItem(in);
|
||||
}
|
||||
|
||||
public BackStackItem[] newArray(int size)
|
||||
{
|
||||
return new BackStackItem[size];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Listener interface for executing content or performing
|
||||
* other things upon the DirectoryFragment instance closing.
|
||||
*/
|
||||
public interface OnDirectoryFragmentClosedListener
|
||||
{
|
||||
/**
|
||||
* Performs some arbitrary action after the
|
||||
* {@link DirectoryFragment} closes.
|
||||
*
|
||||
* @param path The path to the file chosen within the {@link DirectoryFragment}
|
||||
*/
|
||||
void onDirectoryFragmentClosed(String path);
|
||||
}
|
||||
|
||||
|
||||
protected ArrayList<BackStackItem> backStack;
|
||||
protected String startDirectory;
|
||||
protected String pathSettingKey;
|
||||
protected boolean isDirectoryTarget;
|
||||
protected OnDirectoryFragmentClosedListener onClosedListener;
|
||||
|
||||
/**
|
||||
* Sets the starting directory for this DirectoryFragment
|
||||
* when it is shown to the user.
|
||||
*
|
||||
* @param path the initial directory to show to the user
|
||||
* when this DirectoryFragment is shown.
|
||||
*/
|
||||
public void setStartDirectory(String path)
|
||||
{
|
||||
startDirectory = path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the key to save the selected item in the DialogFragment
|
||||
* into the application SharedPreferences at.
|
||||
*
|
||||
* @param key the key to save the selected item's path to in
|
||||
* the application's SharedPreferences.
|
||||
*/
|
||||
public void setPathSettingKey(String key)
|
||||
{
|
||||
pathSettingKey = key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether or not we are browsing for a specific
|
||||
* directory or not. If enabled, it will allow the user
|
||||
* to select a specific directory, rather than a file.
|
||||
*
|
||||
* @param enable Whether or not to enable this.
|
||||
*/
|
||||
public void setIsDirectoryTarget(boolean enable)
|
||||
{
|
||||
isDirectoryTarget = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the listener for an action to perform upon the
|
||||
* closing of this DirectoryFragment.
|
||||
*
|
||||
* @param onClosedListener the OnDirectoryFragmentClosedListener to set.
|
||||
*/
|
||||
public void setOnDirectoryFragmentClosedListener(OnDirectoryFragmentClosedListener onClosedListener)
|
||||
{
|
||||
this.onClosedListener = onClosedListener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a new instance of a DirectoryFragment
|
||||
* with a title specified by the given resource ID.
|
||||
*
|
||||
* @param titleResId String resource ID for the title
|
||||
* of this DirectoryFragment.
|
||||
*
|
||||
* @return A new instance of a DirectoryFragment.
|
||||
*/
|
||||
public static DirectoryFragment newInstance(int titleResId)
|
||||
{
|
||||
final DirectoryFragment dFrag = new DirectoryFragment();
|
||||
final Bundle bundle = new Bundle();
|
||||
bundle.putInt("titleResId", titleResId);
|
||||
dFrag.setArguments(bundle);
|
||||
|
||||
return dFrag;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
|
||||
{
|
||||
ListView rootView = (ListView) inflater.inflate(R.layout.line_list, container, false);
|
||||
rootView.setOnItemClickListener(onItemClickListener);
|
||||
|
||||
// Set the dialog title.
|
||||
getDialog().setTitle(getArguments().getInt("titleResId"));
|
||||
|
||||
// Setup the list
|
||||
adapter = new IconAdapter<FileWrapper>(getActivity(), R.layout.line_list_item);
|
||||
rootView.setAdapter(adapter);
|
||||
|
||||
// Load Directory
|
||||
if (savedInstanceState != null)
|
||||
{
|
||||
backStack = savedInstanceState.getParcelableArrayList("BACKSTACK");
|
||||
}
|
||||
|
||||
if (backStack == null || backStack.isEmpty())
|
||||
{
|
||||
backStack = new ArrayList<BackStackItem>();
|
||||
String startPath = (startDirectory == null || startDirectory.isEmpty()) ? Environment
|
||||
.getExternalStorageDirectory().getPath() : startDirectory;
|
||||
backStack.add(new BackStackItem(startPath, false));
|
||||
}
|
||||
|
||||
wrapFiles();
|
||||
return rootView;
|
||||
}
|
||||
|
||||
private final OnItemClickListener onItemClickListener = new OnItemClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
|
||||
{
|
||||
final FileWrapper item = adapter.getItem(position);
|
||||
|
||||
if (item.isParentItem() && backStack.get(backStack.size() - 1).parentIsBack)
|
||||
{
|
||||
backStack.remove(backStack.size() - 1);
|
||||
wrapFiles();
|
||||
return;
|
||||
}
|
||||
else if (item.isDirSelectItem())
|
||||
{
|
||||
finishWithPath(listedDirectory.getAbsolutePath());
|
||||
return;
|
||||
}
|
||||
|
||||
final File selected = item.isParentItem() ? listedDirectory.getParentFile() : item.getFile();
|
||||
|
||||
if (selected.isDirectory())
|
||||
{
|
||||
backStack.add(new BackStackItem(selected.getAbsolutePath(), !item.isParentItem()));
|
||||
wrapFiles();
|
||||
}
|
||||
else
|
||||
{
|
||||
String filePath = selected.getAbsolutePath();
|
||||
finishWithPath(filePath);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState)
|
||||
{
|
||||
super.onSaveInstanceState(outState);
|
||||
|
||||
outState.putParcelableArrayList("BACKSTACK", backStack);
|
||||
}
|
||||
|
||||
private void finishWithPath(String path)
|
||||
{
|
||||
if (pathSettingKey != null && !pathSettingKey.isEmpty())
|
||||
{
|
||||
SharedPreferences settings = UserPreferences.getPreferences(getActivity());
|
||||
SharedPreferences.Editor editor = settings.edit();
|
||||
editor.putString(pathSettingKey, path);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
if (onClosedListener != null)
|
||||
{
|
||||
onClosedListener.onDirectoryFragmentClosed(path);
|
||||
}
|
||||
|
||||
dismiss();
|
||||
}
|
||||
|
||||
// TODO: Hook this up to a callable interface (if backstack is desirable).
|
||||
public boolean onKeyDown(int keyCode, KeyEvent event)
|
||||
{
|
||||
if (keyCode == KeyEvent.KEYCODE_BACK)
|
||||
{
|
||||
if (backStack.size() > 1)
|
||||
{
|
||||
backStack.remove(backStack.size() - 1);
|
||||
wrapFiles();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private ArrayList<String> allowedExt;
|
||||
private ArrayList<String> disallowedExt;
|
||||
|
||||
private boolean filterPath(String path)
|
||||
{
|
||||
if (disallowedExt != null)
|
||||
{
|
||||
for (String ext : disallowedExt)
|
||||
{
|
||||
if (path.endsWith(ext))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (allowedExt != null)
|
||||
{
|
||||
for (String ext : allowedExt)
|
||||
{
|
||||
if (path.endsWith(ext))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows specifying an allowed file extension.
|
||||
* <p>
|
||||
* Any files that contain this file extension will be shown
|
||||
* within the DirectoryFragment file browser. Those that don't
|
||||
* contain this extension will not be shows.
|
||||
* <p>
|
||||
* It is possible to specify more than one allowed extension by
|
||||
* simply calling this method with a different file extension specified.
|
||||
*
|
||||
* @param exts The file extension(s) to allow being shown in this DirectoryFragment.
|
||||
*/
|
||||
public void addAllowedExts(String... exts)
|
||||
{
|
||||
if (allowedExt == null)
|
||||
allowedExt = new ArrayList<String>();
|
||||
|
||||
allowedExt.addAll(Arrays.asList(exts));
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows specifying a disallowed file extension.
|
||||
* <p>
|
||||
* Any files that contain this file extension will not be shown
|
||||
* within the DirectoryFragment file browser.
|
||||
* <p>
|
||||
* It is possible to specify more than one disallowed extension by
|
||||
* simply calling this method with a different file extension specified.
|
||||
*
|
||||
* @param exts The file extension(s) to hide from being shown in this DirectoryFragment.
|
||||
*/
|
||||
public void addDisallowedExts(String... exts)
|
||||
{
|
||||
if (disallowedExt == null)
|
||||
disallowedExt = new ArrayList<String>();
|
||||
|
||||
disallowedExt.addAll(Arrays.asList(exts));
|
||||
}
|
||||
|
||||
protected void wrapFiles()
|
||||
{
|
||||
listedDirectory = new File(backStack.get(backStack.size() - 1).path);
|
||||
|
||||
if (!listedDirectory.isDirectory())
|
||||
{
|
||||
throw new IllegalArgumentException("Directory is not valid.");
|
||||
}
|
||||
|
||||
adapter.clear();
|
||||
|
||||
if (isDirectoryTarget)
|
||||
adapter.add(new FileWrapper(null, FileWrapper.DIRSELECT, true));
|
||||
|
||||
if (listedDirectory.getParentFile() != null)
|
||||
adapter.add(new FileWrapper(null, FileWrapper.PARENT, true));
|
||||
|
||||
// Copy new items
|
||||
final File[] files = listedDirectory.listFiles();
|
||||
if (files != null)
|
||||
{
|
||||
for (File file : files)
|
||||
{
|
||||
String path = file.getName();
|
||||
|
||||
boolean allowFile = file.isDirectory() || (filterPath(path) && !isDirectoryTarget);
|
||||
if (allowFile)
|
||||
{
|
||||
adapter.add(new FileWrapper(file, FileWrapper.FILE, true));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Sort items
|
||||
adapter.sort(new Comparator<FileWrapper>()
|
||||
{
|
||||
@Override
|
||||
public int compare(FileWrapper left, FileWrapper right)
|
||||
{
|
||||
return left.compareTo(right);
|
||||
};
|
||||
});
|
||||
|
||||
// Update
|
||||
adapter.notifyDataSetChanged();
|
||||
}
|
||||
}
|
@ -49,20 +49,6 @@ public final class MainMenuActivity extends FragmentActivity
|
||||
setVolumeControlStream(AudioManager.STREAM_MUSIC);
|
||||
}
|
||||
|
||||
public void setModule(String core_path, String core_name)
|
||||
{
|
||||
UserPreferences.updateConfigFile(this);
|
||||
|
||||
SharedPreferences prefs = UserPreferences.getPreferences(this);
|
||||
SharedPreferences.Editor edit = prefs.edit();
|
||||
edit.putString("libretro_path", core_path);
|
||||
edit.putString("libretro_name", core_name);
|
||||
edit.apply();
|
||||
|
||||
// Set the title section to contain the name of the selected core.
|
||||
setCoreTitle(core_name);
|
||||
}
|
||||
|
||||
public void setCoreTitle(String core_name)
|
||||
{
|
||||
setTitle("RetroArch : " + core_name);
|
||||
|
@ -26,8 +26,6 @@ import android.os.Environment;
|
||||
|
||||
import com.retroarch.R;
|
||||
import com.retroarch.browser.NativeInterface;
|
||||
import com.retroarch.browser.dirfragment.DirectoryFragment;
|
||||
import com.retroarch.browser.dirfragment.DirectoryFragment.OnDirectoryFragmentClosedListener;
|
||||
import com.retroarch.browser.preferences.fragments.util.PreferenceListFragment;
|
||||
import com.retroarch.browser.preferences.util.UserPreferences;
|
||||
import com.retroarch.browser.retroactivity.RetroActivityFuture;
|
||||
@ -36,7 +34,7 @@ import com.retroarch.browser.retroactivity.RetroActivityPast;
|
||||
/**
|
||||
* Represents the fragment that handles the layout of the main menu.
|
||||
*/
|
||||
public final class MainMenuFragment extends PreferenceListFragment implements OnPreferenceClickListener, OnDirectoryFragmentClosedListener
|
||||
public final class MainMenuFragment extends PreferenceListFragment implements OnPreferenceClickListener
|
||||
{
|
||||
private static final String TAG = "MainMenuFragment";
|
||||
private Context ctx;
|
||||
@ -223,24 +221,6 @@ public final class MainMenuFragment extends PreferenceListFragment implements On
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDirectoryFragmentClosed(String path)
|
||||
{
|
||||
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ctx);
|
||||
|
||||
UserPreferences.updateConfigFile(ctx);
|
||||
Toast.makeText(ctx, String.format(getString(R.string.loading_data), path), Toast.LENGTH_SHORT).show();
|
||||
Intent retro = getRetroActivity();
|
||||
MainMenuFragment.startRetroActivity(
|
||||
retro,
|
||||
path,
|
||||
prefs.getString("libretro_path", ""),
|
||||
UserPreferences.getDefaultConfigPath(ctx),
|
||||
Settings.Secure.getString(ctx.getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD),
|
||||
ctx.getApplicationInfo().dataDir);
|
||||
startActivity(retro);
|
||||
}
|
||||
|
||||
public static void startRetroActivity(Intent retro, String contentPath, String corePath,
|
||||
String configFilePath, String imePath, String dataDirPath)
|
||||
{
|
||||
|
@ -9,7 +9,6 @@ import java.io.InputStreamReader;
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
//import android.content.pm.PackageManager;
|
||||
import android.media.AudioManager;
|
||||
import android.media.AudioTrack;
|
||||
import android.os.Build;
|
||||
@ -121,44 +120,6 @@ public final class UserPreferences
|
||||
*/
|
||||
public static void readbackConfigFile(Context ctx)
|
||||
{
|
||||
String path = getDefaultConfigPath(ctx);
|
||||
ConfigFile config = new ConfigFile(path);
|
||||
|
||||
Log.i(TAG, "Config readback from: " + path);
|
||||
|
||||
SharedPreferences prefs = getPreferences(ctx);
|
||||
SharedPreferences.Editor edit = prefs.edit();
|
||||
|
||||
// General Settings
|
||||
readbackBool(config, edit, "rewind_enable");
|
||||
readbackString(config, edit, "rewind_granularity");
|
||||
readbackBool(config, edit, "savestate_auto_load");
|
||||
readbackBool(config, edit, "savestate_auto_save");
|
||||
|
||||
// Audio Settings.
|
||||
// TODO: Other audio settings
|
||||
readbackBool(config, edit, "audio_rate_control");
|
||||
readbackBool(config, edit, "audio_enable");
|
||||
|
||||
// Input Settings
|
||||
readbackString(config, edit, "input_overlay");
|
||||
readbackBool(config, edit, "input_overlay_enable");
|
||||
readbackDouble(config, edit, "input_overlay_opacity");
|
||||
readbackBool(config, edit, "input_autodetect_enable");
|
||||
|
||||
// Video Settings
|
||||
readbackBool(config, edit, "video_scale_integer");
|
||||
readbackBool(config, edit, "video_smooth");
|
||||
readbackBool(config, edit, "video_threaded");
|
||||
readbackBool(config, edit, "video_allow_rotate");
|
||||
readbackBool(config, edit, "video_font_enable");
|
||||
readbackBool(config, edit, "video_vsync");
|
||||
readbackString(config, edit, "video_refresh_rate");
|
||||
|
||||
// Path settings
|
||||
readbackString(config, edit, "rgui_browser_directory");
|
||||
|
||||
edit.apply();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -179,10 +140,7 @@ public final class UserPreferences
|
||||
|
||||
final SharedPreferences prefs = getPreferences(ctx);
|
||||
|
||||
config.setString("libretro_path", prefs.getString("libretro_path", coreDir));
|
||||
config.setString("libretro_directory", coreDir);
|
||||
config.setString("rgui_browser_directory", prefs.getString("rgui_browser_directory", ""));
|
||||
config.setBoolean("audio_rate_control", prefs.getBoolean("audio_rate_control", true));
|
||||
config.setInt("audio_out_rate", getOptimalSamplingRate(ctx));
|
||||
|
||||
// Refactor this entire mess and make this usable for per-core config
|
||||
@ -191,53 +149,6 @@ public final class UserPreferences
|
||||
config.setInt("audio_block_frames", getLowLatencyBufferSize(ctx));
|
||||
}
|
||||
|
||||
config.setBoolean("audio_enable", prefs.getBoolean("audio_enable", true));
|
||||
config.setBoolean("video_smooth", prefs.getBoolean("video_smooth", true));
|
||||
config.setBoolean("video_allow_rotate", prefs.getBoolean("video_allow_rotate", true));
|
||||
config.setBoolean("savestate_auto_load", prefs.getBoolean("savestate_auto_load", true));
|
||||
config.setBoolean("savestate_auto_save", prefs.getBoolean("savestate_auto_save", false));
|
||||
config.setBoolean("rewind_enable", prefs.getBoolean("rewind_enable", false));
|
||||
config.setInt("rewind_granularity", Integer.parseInt(prefs.getString("rewind_granularity", "1")));
|
||||
config.setBoolean("video_vsync", prefs.getBoolean("video_vsync", true));
|
||||
config.setBoolean("input_autodetect_enable", prefs.getBoolean("input_autodetect_enable", true));
|
||||
config.setString("video_refresh_rate", prefs.getString("video_refresh_rate", ""));
|
||||
config.setBoolean("video_threaded", prefs.getBoolean("video_threaded", true));
|
||||
|
||||
// Refactor these weird values - 'full', 'auto', 'square', whatever -
|
||||
// go by what we have in the menu - makes maintaining state easier too
|
||||
String aspect = prefs.getString("video_aspect_ratio", "auto");
|
||||
if (aspect.equals("full"))
|
||||
{
|
||||
config.setBoolean("video_force_aspect", false);
|
||||
}
|
||||
else if (aspect.equals("auto"))
|
||||
{
|
||||
config.setBoolean("video_force_aspect", true);
|
||||
config.setBoolean("video_force_aspect_auto", true);
|
||||
config.setDouble("video_aspect_ratio", -1.0);
|
||||
}
|
||||
else if (aspect.equals("square"))
|
||||
{
|
||||
config.setBoolean("video_force_aspect", true);
|
||||
config.setBoolean("video_force_aspect_auto", false);
|
||||
config.setDouble("video_aspect_ratio", -1.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
double aspect_ratio = Double.parseDouble(aspect);
|
||||
config.setBoolean("video_force_aspect", true);
|
||||
config.setDouble("video_aspect_ratio", aspect_ratio);
|
||||
}
|
||||
|
||||
config.setBoolean("video_scale_integer", prefs.getBoolean("video_scale_integer", false));
|
||||
|
||||
if (prefs.contains("input_overlay_enable"))
|
||||
config.setBoolean("input_overlay_enable", prefs.getBoolean("input_overlay_enable", true));
|
||||
config.setString("input_overlay", prefs.getString("input_overlay", ""));
|
||||
|
||||
config.setBoolean("video_font_enable", prefs.getBoolean("video_font_enable", true));
|
||||
config.setString("content_history_path", dataDir + "/content_history.rpl");
|
||||
|
||||
try
|
||||
{
|
||||
config.write(path);
|
||||
|
@ -694,12 +694,22 @@ static void frontend_android_get_environment_settings(int *argc,
|
||||
if(*downloads_dir)
|
||||
{
|
||||
fill_pathname_join(g_defaults.core_assets_dir,
|
||||
downloads_dir, "/", sizeof(g_defaults.core_assets_dir));
|
||||
downloads_dir, "", sizeof(g_defaults.core_assets_dir));
|
||||
}
|
||||
else
|
||||
{
|
||||
fill_pathname_join(g_defaults.core_assets_dir,
|
||||
app_dir, "downloads", sizeof(g_defaults.core_assets_dir));
|
||||
app_dir, "downloads", sizeof(g_defaults.core_assets_dir));
|
||||
}
|
||||
if(*screenshot_dir)
|
||||
{
|
||||
fill_pathname_join(g_defaults.screenshot_dir,
|
||||
screenshot_dir, "", sizeof(g_defaults.screenshot_dir));
|
||||
}
|
||||
else
|
||||
{
|
||||
fill_pathname_join(g_defaults.screenshot_dir,
|
||||
path, "screenshots", sizeof(g_defaults.screenshot_dir));
|
||||
}
|
||||
}
|
||||
}
|
||||
|