[Android] Make the file browser look much more nice and user friendly to use.

This is what it now looks like: http://i.imgur.com/KOZgA1i.png

As usual, if any bugs arise from this rather large change. Please report it so I can fix it.
This commit is contained in:
Lioncash 2013-08-13 13:05:42 -04:00
parent 8fbf11a0d9
commit 53bf55b1e9
16 changed files with 346 additions and 97 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 510 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 487 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 580 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/FolderTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dip"
android:layout_marginTop="5dip"
android:singleLine="true"
android:text="Title"
android:textStyle="bold" />
<TextView
android:id="@+id/FolderSubTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dip"
android:text="Subtitle" />
</LinearLayout>
</LinearLayout>

View File

@ -1,29 +1,43 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:layout_height="?android:attr/listPreferredItemHeight"
android:orientation="vertical" > android:padding="3dip">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView <ImageView
android:id="@+id/FolderTitle" android:id="@+id/ImageIcon"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="fill_parent"
android:layout_marginLeft="5dip"
android:layout_marginTop="5dip" android:layout_alignParentTop="true"
android:singleLine="true" android:layout_alignParentBottom="true"
android:text="Title" android:layout_marginRight="6dip"/>
android:textStyle="bold" />
<TextView <TextView
android:id="@+id/FolderSubTitle" android:id="@+id/FolderSubTitle"
android:layout_width="wrap_content" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="26dip"
android:layout_marginLeft="10dip"
android:layout_toRightOf="@id/ImageIcon"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:singleLine="true"
android:ellipsize="marquee"
android:text="Subtitle" /> android:text="Subtitle" />
</LinearLayout> <TextView
</LinearLayout> android:id="@+id/FolderTitle"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/ImageIcon"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_above="@id/FolderSubTitle"
android:layout_alignWithParentIfMissing="true"
android:gravity="center_vertical"
android:text="Title" />
</RelativeLayout>

View File

@ -22,7 +22,6 @@ public class AboutFragment extends Fragment {
private ListView mMainList; private ListView mMainList;
private FolderBrowserAdapter adapter; private FolderBrowserAdapter adapter;
private int configPosition = 0;
boolean Configuring = false; boolean Configuring = false;
boolean firstEvent = true; boolean firstEvent = true;
@ -39,11 +38,11 @@ public class AboutFragment extends Fragment {
String yes = getString(R.string.yes); String yes = getString(R.string.yes);
String no = getString(R.string.no); String no = getString(R.string.no);
List<GameListItem> Input = new ArrayList<GameListItem>(); List<FolderBrowserItem> Input = new ArrayList<FolderBrowserItem>();
Input.add(new GameListItem(m_activity, getString(R.string.build_revision), NativeLibrary.GetVersionString(), "", true)); Input.add(new FolderBrowserItem(m_activity, getString(R.string.build_revision), NativeLibrary.GetVersionString(), "", true));
Input.add(new GameListItem(m_activity, getString(R.string.supports_gles3), PrefsFragment.SupportsGLES3() ? yes : no, "", true)); Input.add(new FolderBrowserItem(m_activity, getString(R.string.supports_gles3), PrefsFragment.SupportsGLES3() ? yes : no, "", true));
adapter = new FolderBrowserAdapter(m_activity, R.layout.folderbrowser, Input); adapter = new FolderBrowserAdapter(m_activity, R.layout.about_layout, Input);
mMainList.setAdapter(adapter); mMainList.setAdapter(adapter);
return mMainList; return mMainList;

View File

@ -26,8 +26,8 @@ public class FolderBrowser extends Fragment {
{ {
m_activity.setTitle(getString(R.string.current_dir) + currDir.getName()); m_activity.setTitle(getString(R.string.current_dir) + currDir.getName());
File[] dirs = currDir.listFiles(); File[] dirs = currDir.listFiles();
List<GameListItem>dir = new ArrayList<GameListItem>(); List<FolderBrowserItem>dir = new ArrayList<FolderBrowserItem>();
List<GameListItem>fls = new ArrayList<GameListItem>(); List<FolderBrowserItem>fls = new ArrayList<FolderBrowserItem>();
// Supported extensions to filter by // Supported extensions to filter by
Set<String> validExts = new HashSet<String>(Arrays.asList(".gcm", ".iso", ".wbfs", ".gcz", ".dol", ".elf", ".dff")); Set<String> validExts = new HashSet<String>(Arrays.asList(".gcm", ".iso", ".wbfs", ".gcz", ".dol", ".elf", ".dff"));
@ -44,17 +44,17 @@ public class FolderBrowser extends Fragment {
{ {
if(entry.isDirectory()) if(entry.isDirectory())
{ {
dir.add(new GameListItem(m_activity, entryName, getString(R.string.folder), entry.getAbsolutePath(), true)); dir.add(new FolderBrowserItem(m_activity, entryName, getString(R.string.folder), entry.getAbsolutePath(), true));
} }
else else
{ {
if (validExts.contains(entryName.toLowerCase().substring(entryName.lastIndexOf('.')))) if (validExts.contains(entryName.toLowerCase().substring(entryName.lastIndexOf('.'))))
{ {
fls.add(new GameListItem(m_activity, entryName,getString(R.string.file_size)+entry.length(),entry.getAbsolutePath(), true)); fls.add(new FolderBrowserItem(m_activity, entryName,getString(R.string.file_size)+entry.length(),entry.getAbsolutePath(), true));
} }
else if (invalidExts.contains(entryName.toLowerCase().substring(entryName.lastIndexOf('.')))) else if (invalidExts.contains(entryName.toLowerCase().substring(entryName.lastIndexOf('.'))))
{ {
fls.add(new GameListItem(m_activity, entryName,getString(R.string.file_size)+entry.length(),entry.getAbsolutePath(), false)); fls.add(new FolderBrowserItem(m_activity, entryName,getString(R.string.file_size)+entry.length(),entry.getAbsolutePath(), false));
} }
} }
} }
@ -70,7 +70,7 @@ public class FolderBrowser extends Fragment {
// Check for a parent directory to the one we're currently in. // Check for a parent directory to the one we're currently in.
if (!currDir.getPath().equalsIgnoreCase("/")) if (!currDir.getPath().equalsIgnoreCase("/"))
dir.add(0, new GameListItem(m_activity, "..", getString(R.string.parent_directory), currDir.getParent(), true)); dir.add(0, new FolderBrowserItem(m_activity, "..", getString(R.string.parent_directory), currDir.getParent(), true));
adapter = new FolderBrowserAdapter(m_activity, R.layout.folderbrowser, dir); adapter = new FolderBrowserAdapter(m_activity, R.layout.folderbrowser, dir);
mDrawerList = (ListView) rootView.findViewById(R.id.gamelist); mDrawerList = (ListView) rootView.findViewById(R.id.gamelist);
@ -94,15 +94,15 @@ public class FolderBrowser extends Fragment {
{ {
public void onItemClick(AdapterView<?> parent, View view, int position, long id) public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{ {
GameListItem o = adapter.getItem(position); FolderBrowserItem o = adapter.getItem(position);
if(o.getData().equalsIgnoreCase(getString(R.string.folder)) || o.getData().equalsIgnoreCase(getString(R.string.parent_directory))) if(o.isDirectory() || o.getSubtitle().equalsIgnoreCase(getString(R.string.parent_directory)))
{ {
currentDir = new File(o.getPath()); currentDir = new File(o.getPath());
Fill(currentDir); Fill(currentDir);
} }
else else
{ {
if (o.isValid()) if (o.isValidItem())
FolderSelected(); FolderSelected();
else else
Toast.makeText(m_activity, getString(R.string.cant_use_compressed_filetypes), Toast.LENGTH_LONG).show(); Toast.makeText(m_activity, getString(R.string.cant_use_compressed_filetypes), Toast.LENGTH_LONG).show();

View File

@ -1,58 +1,79 @@
package org.dolphinemu.dolphinemu; package org.dolphinemu.dolphinemu;
import android.content.Context; import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView; import android.widget.TextView;
import java.util.List; import java.util.List;
public class FolderBrowserAdapter extends ArrayAdapter<GameListItem>{ public class FolderBrowserAdapter extends ArrayAdapter<FolderBrowserItem>{
private Context c; private Context c;
private int id; private int id;
private List<GameListItem>items; private List<FolderBrowserItem> items;
public FolderBrowserAdapter(Context context, int textViewResourceId, public FolderBrowserAdapter(Context context, int textViewResourceId, List<FolderBrowserItem> objects) {
List<GameListItem> objects) {
super(context, textViewResourceId, objects); super(context, textViewResourceId, objects);
c = context; c = context;
id = textViewResourceId; id = textViewResourceId;
items = objects; items = objects;
} }
public GameListItem getItem(int i) public FolderBrowserItem getItem(int i)
{ {
return items.get(i); return items.get(i);
} }
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater)c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(id, null);
}
final GameListItem o = items.get(position);
if (o != null) {
TextView t1 = (TextView) v.findViewById(R.id.FolderTitle);
TextView t2 = (TextView) v.findViewById(R.id.FolderSubTitle);
if(t1!=null) @Override
public View getView(int position, View convertView, ViewGroup parent)
{ {
t1.setText(o.getName()); View v = convertView;
if (!o.isValid()) if (v == null)
t1.setTextColor(0xFFFF0000); {
LayoutInflater vi = (LayoutInflater) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(id, parent, false);
}
final FolderBrowserItem item = items.get(position);
if (item != null)
{
ImageView iconView = (ImageView) v.findViewById(R.id.ImageIcon);
TextView mainText = (TextView) v.findViewById(R.id.FolderTitle);
TextView subtitleText = (TextView) v.findViewById(R.id.FolderSubTitle);
if(mainText != null)
{
mainText.setText(item.getName());
if (!item.isValidItem())
{
mainText.setTextColor(0xFFFF0000);
}
}
if(subtitleText != null)
{
subtitleText.setText(item.getSubtitle());
}
if (iconView != null)
{
if (item.isDirectory())
{
iconView.setImageResource(R.drawable.ic_menu_folder);
}
else
{
iconView.setImageResource(R.drawable.ic_menu_file);
}
} }
if(t2!=null)
t2.setText(o.getData());
} }
return v; return v;
} }
} }

View File

@ -0,0 +1,113 @@
package org.dolphinemu.dolphinemu;
import java.io.File;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
/**
* Represents an item in the folder browser list.
*/
public final class FolderBrowserItem implements Comparable<FolderBrowserItem>
{
private final Context ctx;
private final String name;
private final String subtitle;
private final String path;
private final boolean isValid;
private final File underlyingFile;
/**
* Constructor
*
* @param ctx Context this FolderBrowserItem is being used in.
* @param name The name of the file/folder represented by this item.
* @param subtitle The subtitle of this FolderBrowserItem to display.
* @param path The path of the file/folder represented by this item.
* @param isValid Whether or not this item represents a file type that can be handled.
*/
public FolderBrowserItem(Context ctx, String name, String subtitle, String path, boolean isValid)
{
this.ctx = ctx;
this.name = name;
this.subtitle = subtitle;
this.path = path;
this.isValid = isValid;
this.underlyingFile = new File(path);
}
/**
* Gets the name of the file/folder represented by this FolderBrowserItem.
*
* @return the name of the file/folder represented by this FolderBrowserItem.
*/
public String getName()
{
return name;
}
/**
* Gets the subtitle text of this FolderBrowserItem.
*
* @return the subtitle text of this FolderBrowserItem.
*/
public String getSubtitle()
{
return subtitle;
}
/**
* Gets the path of the file/folder represented by this FolderBrowserItem.
*
* @return the path of the file/folder represented by this FolderBrowserItem.
*/
public String getPath()
{
return path;
}
/**
* Gets whether or not the file represented
* by this FolderBrowserItem is supported
* and can be handled correctly.
*
* @return whether or not the file represented
* by this FolderBrowserItem is supported
* and can be handled correctly.
*/
public boolean isValidItem()
{
return isValid;
}
/**
* Gets the {@link File} representation of the underlying file/folder
* represented by this FolderBrowserItem.
*
* @return the {@link File} representation of the underlying file/folder
* represented by this FolderBrowserItem.
*/
public File getUnderlyingFile()
{
return underlyingFile;
}
/**
* Gets whether or not this FolderBrowserItem represents a directory.
*
* @return true if this FolderBrowserItem represents a directory, false otherwise.
*/
public boolean isDirectory()
{
return underlyingFile.isDirectory();
}
public int compareTo(FolderBrowserItem other)
{
if(this.name != null)
return this.name.toLowerCase().compareTo(other.getName().toLowerCase());
else
throw new IllegalArgumentException();
}
}

View File

@ -1,10 +1,14 @@
package org.dolphinemu.dolphinemu; /*
/**
* Copyright 2013 Dolphin Emulator Project * Copyright 2013 Dolphin Emulator Project
* Licensed under GPLv2 * Licensed under GPLv2
* Refer to the license.txt file included. * Refer to the license.txt file included.
*/ */
package org.dolphinemu.dolphinemu;
/**
* Represents a controller input item (button, stick, etc).
*/
public class InputConfigItem implements Comparable<InputConfigItem>{ public class InputConfigItem implements Comparable<InputConfigItem>{
private String m_name; private String m_name;
private String m_Config; private String m_Config;
@ -20,27 +24,65 @@ public class InputConfigItem implements Comparable<InputConfigItem>{
m_bind = NativeLibrary.GetConfig("Dolphin.ini", Key, Value, defaultBind); m_bind = NativeLibrary.GetConfig("Dolphin.ini", Key, Value, defaultBind);
} }
/**
* Constructor
*
* @param name Name of the input config item.
* @param config Name of the key in the configuration file that this control modifies.
* @param defaultBind Default binding to fall back upon if binding fails.
*/
public InputConfigItem(String name, String config, String defaultBind) public InputConfigItem(String name, String config, String defaultBind)
{ {
Init(name, config, defaultBind); Init(name, config, defaultBind);
} }
/**
* Constructor that creates an InputConfigItem
* that has a default binding of "None"
*
* @param name Name of the input config item.
* @param config Name of the key in the configuration file that this control modifies.
*/
public InputConfigItem(String name, String config) public InputConfigItem(String name, String config)
{ {
Init(name, config, "None"); Init(name, config, "None");
} }
/**
* Gets the name of this InputConfigItem.
*
* @return the name of this InputConfigItem
*/
public String getName() public String getName()
{ {
return m_name; return m_name;
} }
/**
* Gets the config key this InputConfigItem modifies.
*
* @return the config key this InputConfigItem modifies.
*/
public String getConfig() public String getConfig()
{ {
return m_Config; return m_Config;
} }
/**
* Gets the currently set binding of this InputConfigItem
*
* @return the currently set binding of this InputConfigItem
*/
public String getBind() public String getBind()
{ {
return m_bind; return m_bind;
} }
/**
* Sets a new binding for this InputConfigItem.
*
* @param bind The new binding.
*/
public void setBind(String bind) public void setBind(String bind)
{ {
m_bind = bind; m_bind = bind;

View File

@ -1,12 +1,17 @@
/*
* Copyright 2013 Dolphin Emulator Project
* Licensed under GPLv2
* Refer to the license.txt file included.
*/
package org.dolphinemu.dolphinemu; package org.dolphinemu.dolphinemu;
import android.util.Log; import android.util.Log;
import android.view.Surface; import android.view.Surface;
/** /**
* Copyright 2013 Dolphin Emulator Project * Class which contains methods that interact
* Licensed under GPLv2 * with the native side of the Dolphin code.
* Refer to the license.txt file included.
*/ */
public class NativeLibrary { public class NativeLibrary {
public static native void onTouchEvent(int Action, float X, float Y); public static native void onTouchEvent(int Action, float X, float Y);

View File

@ -16,34 +16,38 @@ public class SideMenuAdapter extends ArrayAdapter<SideMenuItem>{
private List<SideMenuItem>items; private List<SideMenuItem>items;
public SideMenuAdapter(Context context, int textViewResourceId, public SideMenuAdapter(Context context, int textViewResourceId,
List<SideMenuItem> objects) { List<SideMenuItem> objects)
{
super(context, textViewResourceId, objects); super(context, textViewResourceId, objects);
c = context; c = context;
id = textViewResourceId; id = textViewResourceId;
items = objects; items = objects;
} }
public SideMenuItem getItem(int i) public SideMenuItem getItem(int i)
{ {
return items.get(i); return items.get(i);
} }
@Override @Override
public View getView(int position, View convertView, ViewGroup parent) { public View getView(int position, View convertView, ViewGroup parent)
{
View v = convertView; View v = convertView;
if (v == null) { if (v == null)
{
LayoutInflater vi = (LayoutInflater)c.getSystemService(Context.LAYOUT_INFLATER_SERVICE); LayoutInflater vi = (LayoutInflater)c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(id, null); v = vi.inflate(id, null);
} }
final SideMenuItem o = items.get(position); final SideMenuItem o = items.get(position);
if (o != null) { if (o != null)
{
TextView t1 = (TextView) v.findViewById(R.id.SideMenuTitle); TextView t1 = (TextView) v.findViewById(R.id.SideMenuTitle);
if(t1!=null) if(t1!=null)
t1.setText(o.getName()); t1.setText(o.getName());
} }
return v; return v;
} }
} }

View File

@ -1,25 +1,47 @@
package org.dolphinemu.dolphinemu; /*
/**
* Copyright 2013 Dolphin Emulator Project * Copyright 2013 Dolphin Emulator Project
* Licensed under GPLv2 * Licensed under GPLv2
* Refer to the license.txt file included. * Refer to the license.txt file included.
*/ */
public class SideMenuItem implements Comparable<SideMenuItem>{ package org.dolphinemu.dolphinemu;
/**
* Represents an item that goes in the sidemenu of the app.
*/
public class SideMenuItem implements Comparable<SideMenuItem>
{
private String m_name; private String m_name;
private int m_id; private int m_id;
public SideMenuItem(String n, int id) /**
* Constructor
*
* @param name The name of the SideMenuItem.
* @param id ID number of this specific SideMenuItem.
*/
public SideMenuItem(String name, int id)
{ {
m_name = n; m_name = name;
m_id = id; m_id = id;
} }
/**
* Gets the name of this SideMenuItem.
*
* @return the name of this SideMenuItem.
*/
public String getName() public String getName()
{ {
return m_name; return m_name;
} }
/**
* Gets the ID of this SideMenuItem.
*
* @return the ID of this SideMenuItem.
*/
public int getID() public int getID()
{ {
return m_id; return m_id;