diff --git a/Source/Android/app/src/main/AndroidManifest.xml b/Source/Android/app/src/main/AndroidManifest.xml index 981d4117e9..d10632b868 100644 --- a/Source/Android/app/src/main/AndroidManifest.xml +++ b/Source/Android/app/src/main/AndroidManifest.xml @@ -15,7 +15,7 @@ + android:theme="@style/DolphinGamecube"> @@ -25,6 +25,12 @@ + + + exts = new HashSet(Arrays.asList(".dff", ".dol", ".elf", ".gcm", ".gcz", ".iso", ".wad", ".wbfs")); - for (int a = 0; a < intDirectories; ++a) + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); + + String path = prefs.getString(AddDirectoryActivity.KEY_CURRENT_PATH, "/"); + + File currentDir = new File(path); + File[] dirs = currentDir.listFiles(); + try { - String BrowseDir = NativeLibrary.GetConfig("Dolphin.ini", "General", "ISOPath" + a, ""); - Log.v("DolphinEmu", "Directory " + a + ": " + BrowseDir); - - File currentDir = new File(BrowseDir); - File[] dirs = currentDir.listFiles(); - try + for (File entry : dirs) { - for (File entry : dirs) + if (!entry.isHidden() && !entry.isDirectory()) { - if (!entry.isHidden() && !entry.isDirectory()) + String entryName = entry.getName(); + + // Check that the file has an appropriate extension before trying to read out of it. + if (exts.contains(entryName.toLowerCase().substring(entryName.lastIndexOf('.')))) { - String entryName = entry.getName(); - - // Check that the file has an appropriate extension before trying to read out of it. - if (exts.contains(entryName.toLowerCase().substring(entryName.lastIndexOf('.')))) - { - GcGame game = new GcGame(NativeLibrary.GetTitle(entry.getAbsolutePath()), - NativeLibrary.GetDescription(entry.getAbsolutePath()).replace("\n", " "), - // TODO Some games might actually not be from this region, believe it or not. - "United States", - entry.getAbsolutePath(), - NativeLibrary.GetGameId(entry.getAbsolutePath()), - NativeLibrary.GetDate(entry.getAbsolutePath())); - - gameList.add(game); - } + GcGame game = new GcGame(NativeLibrary.GetTitle(entry.getAbsolutePath()), + NativeLibrary.GetDescription(entry.getAbsolutePath()).replace("\n", " "), + // TODO Some games might actually not be from this region, believe it or not. + "United States", + entry.getAbsolutePath(), + NativeLibrary.GetGameId(entry.getAbsolutePath()), + NativeLibrary.GetDate(entry.getAbsolutePath())); + gameList.add(game); } } - } catch (Exception ignored) - { + } + } catch (Exception ignored) + { + } return gameList; diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/FileAdapter.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/FileAdapter.java new file mode 100644 index 0000000000..7f4acf6abe --- /dev/null +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/FileAdapter.java @@ -0,0 +1,161 @@ +package org.dolphinemu.dolphinemu.adapters; + +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import org.dolphinemu.dolphinemu.R; +import org.dolphinemu.dolphinemu.model.FileListItem; +import org.dolphinemu.dolphinemu.viewholders.FileViewHolder; + +import java.io.File; +import java.util.ArrayList; +import java.util.Collections; + +public class FileAdapter extends RecyclerView.Adapter implements View.OnClickListener +{ + private ArrayList mFileList; + + private String mPath; + + private FileClickListener mListener; + + /** + * Initializes the dataset to be displayed, and associates the Adapter with the + * Activity as an event listener. + * + * @param gameList + */ + public FileAdapter(String path, FileClickListener listener) + { + mFileList = generateFileList(new File(path)); + mListener = listener; + } + + /** + * Called by the LayoutManager when it is necessary to create a new view. + * + * @param parent The RecyclerView (I think?) the created view will be thrown into. + * @param viewType Not used here, but useful when more than one type of child will be used in the RecyclerView. + * @return The created ViewHolder with references to all the child view's members. + */ + @Override + public FileViewHolder onCreateViewHolder(ViewGroup parent, int viewType) + { + // Create a new view. + View listItem = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.list_item_file, parent, false); + + listItem.setOnClickListener(this); + + // Use that view to create a ViewHolder. + return new FileViewHolder(listItem); + } + + /** + * Called by the LayoutManager when a new view is not necessary because we can recycle + * an existing one (for example, if a view just scrolled onto the screen from the bottom, we + * can use the view that just scrolled off the top instead of inflating a new one.) + * + * @param holder A ViewHolder representing the view we're recycling. + * @param position The position of the 'new' view in the dataset. + */ + @Override + public void onBindViewHolder(FileViewHolder holder, int position) + { + // Get a reference to the item from the dataset; we'll use this to fill in the view contents. + final FileListItem file = mFileList.get(position); + + // Fill in the view contents. + switch (file.getType()) + { + case FileListItem.TYPE_FOLDER: + holder.imageType.setImageResource(R.drawable.ic_folder); + break; + + case FileListItem.TYPE_GC: + holder.imageType.setImageResource(R.drawable.ic_gamecube); + break; + + case FileListItem.TYPE_WII: + holder.imageType.setImageResource(R.drawable.ic_wii); + break; + + case FileListItem.TYPE_OTHER: + holder.imageType.setImageResource(android.R.color.transparent); + break; + } + + holder.textFileName.setText(file.getFilename()); + holder.itemView.setTag(file.getPath()); + } + + /** + * Called by the LayoutManager to find out how much data we have. + * + * @return Size of the dataset. + */ + @Override + public int getItemCount() + { + return mFileList.size(); + } + + @Override + public void onClick(View view) + { + String path = (String) view.getTag(); + + File clickedFile = new File(path); + + if (clickedFile.isDirectory()) + { + mFileList = generateFileList(clickedFile); + notifyDataSetChanged(); + } else + { + // Pass the activity the path of the parent directory of the clicked file. + mListener.finishSuccessfully(); + } + } + + private ArrayList generateFileList(File directory) + { + File[] children = directory.listFiles(); + ArrayList fileList = new ArrayList(children.length); + + for (File child : children) + { + if (!child.isHidden()) + { + FileListItem item = new FileListItem(child); + fileList.add(item); + } + } + + mPath = directory.getAbsolutePath(); + + Collections.sort(fileList); + return fileList; + } + + public String getPath() + { + return mPath; + } + + public void setPath(String path) + { + mPath = path; + File parentDirectory = new File(path); + + mFileList = generateFileList(parentDirectory); + notifyDataSetChanged(); + } + + public static interface FileClickListener + { + public void finishSuccessfully(); + } +} diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameAdapter.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameAdapter.java index d868ed46de..bf7bf435b7 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameAdapter.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameAdapter.java @@ -79,7 +79,6 @@ public class GameAdapter extends RecyclerView.Adapter holder.path = game.getPath(); holder.screenshotPath = game.getScreenPath(); holder.game = game; - } /** @@ -112,4 +111,10 @@ public class GameAdapter extends RecyclerView.Adapter } } + + public void setGameList(ArrayList gameList) + { + mGameList = gameList; + notifyDataSetChanged(); + } } diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/FileListItem.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/FileListItem.java new file mode 100644 index 0000000000..e15516dbaf --- /dev/null +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/FileListItem.java @@ -0,0 +1,81 @@ +package org.dolphinemu.dolphinemu.model; + + +import org.dolphinemu.dolphinemu.NativeLibrary; + +import java.io.File; +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +public class FileListItem implements Comparable +{ + public static final int TYPE_FOLDER = 0; + public static final int TYPE_GC = 1; + public static final int TYPE_WII = 2; + public static final int TYPE_OTHER = 3; + + private int mType; + private String mFilename; + private String mPath; + + public FileListItem(File file) + { + mPath = file.getAbsolutePath(); + + if (file.isDirectory()) + { + mType = TYPE_FOLDER; + } else + { + String fileExtension = mPath.substring(mPath.lastIndexOf('.')); + + // Extensions to filter by. + Set allowedExtensions = new HashSet(Arrays.asList(".dff", ".dol", ".elf", ".gcm", ".gcz", ".iso", ".wad", ".wbfs")); + + // Check that the file has an appropriate extension before trying to read out of it. + if (allowedExtensions.contains(fileExtension)) + { + mType = NativeLibrary.IsWiiTitle(mPath) ? TYPE_WII : TYPE_GC; + } else + { + mType = TYPE_OTHER; + } + } + + mFilename = file.getName(); + } + + public int getType() + { + return mType; + } + + public String getFilename() + { + return mFilename; + } + + public String getPath() + { + return mPath; + } + + @Override + public int compareTo(FileListItem theOther) + { + if (theOther.getType() == getType()) + { + return getFilename().toLowerCase().compareTo(theOther.getFilename().toLowerCase()); + } else + { + if (getType() > theOther.getType()) + { + return 1; + } else + { + return -1; + } + } + } +} diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/viewholders/FileViewHolder.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/viewholders/FileViewHolder.java new file mode 100644 index 0000000000..79acc8400b --- /dev/null +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/viewholders/FileViewHolder.java @@ -0,0 +1,27 @@ +package org.dolphinemu.dolphinemu.viewholders; + +import android.support.v7.widget.RecyclerView; +import android.view.View; +import android.widget.ImageView; +import android.widget.TextView; + +import org.dolphinemu.dolphinemu.R; + + +public class FileViewHolder extends RecyclerView.ViewHolder +{ + public View itemView; + + public TextView textFileName; + public ImageView imageType; + + public FileViewHolder(View itemView) + { + super(itemView); + + this.itemView = itemView; + + textFileName = (TextView) itemView.findViewById(R.id.text_file_name); + imageType = (ImageView) itemView.findViewById(R.id.image_type); + } +} diff --git a/Source/Android/app/src/main/res/drawable-hdpi/ic_add.png b/Source/Android/app/src/main/res/drawable-hdpi/ic_add.png new file mode 100644 index 0000000000..481643ecd5 Binary files /dev/null and b/Source/Android/app/src/main/res/drawable-hdpi/ic_add.png differ diff --git a/Source/Android/app/src/main/res/drawable-hdpi/ic_folder.png b/Source/Android/app/src/main/res/drawable-hdpi/ic_folder.png new file mode 100644 index 0000000000..9f5c756099 Binary files /dev/null and b/Source/Android/app/src/main/res/drawable-hdpi/ic_folder.png differ diff --git a/Source/Android/app/src/main/res/drawable-hdpi/ic_gamecube.png b/Source/Android/app/src/main/res/drawable-hdpi/ic_gamecube.png new file mode 100644 index 0000000000..d128a17277 Binary files /dev/null and b/Source/Android/app/src/main/res/drawable-hdpi/ic_gamecube.png differ diff --git a/Source/Android/app/src/main/res/drawable-hdpi/ic_wii.png b/Source/Android/app/src/main/res/drawable-hdpi/ic_wii.png new file mode 100644 index 0000000000..ab4d4be283 Binary files /dev/null and b/Source/Android/app/src/main/res/drawable-hdpi/ic_wii.png differ diff --git a/Source/Android/app/src/main/res/drawable-mdpi/ic_add.png b/Source/Android/app/src/main/res/drawable-mdpi/ic_add.png new file mode 100644 index 0000000000..977dd3427a Binary files /dev/null and b/Source/Android/app/src/main/res/drawable-mdpi/ic_add.png differ diff --git a/Source/Android/app/src/main/res/drawable-mdpi/ic_folder.png b/Source/Android/app/src/main/res/drawable-mdpi/ic_folder.png new file mode 100644 index 0000000000..1c5797c9e0 Binary files /dev/null and b/Source/Android/app/src/main/res/drawable-mdpi/ic_folder.png differ diff --git a/Source/Android/app/src/main/res/drawable-mdpi/ic_gamecube.png b/Source/Android/app/src/main/res/drawable-mdpi/ic_gamecube.png new file mode 100644 index 0000000000..5f972fb801 Binary files /dev/null and b/Source/Android/app/src/main/res/drawable-mdpi/ic_gamecube.png differ diff --git a/Source/Android/app/src/main/res/drawable-mdpi/ic_wii.png b/Source/Android/app/src/main/res/drawable-mdpi/ic_wii.png new file mode 100644 index 0000000000..43718bf98d Binary files /dev/null and b/Source/Android/app/src/main/res/drawable-mdpi/ic_wii.png differ diff --git a/Source/Android/app/src/main/res/drawable-xhdpi/ic_add.png b/Source/Android/app/src/main/res/drawable-xhdpi/ic_add.png new file mode 100644 index 0000000000..67042105d2 Binary files /dev/null and b/Source/Android/app/src/main/res/drawable-xhdpi/ic_add.png differ diff --git a/Source/Android/app/src/main/res/drawable-xhdpi/ic_folder.png b/Source/Android/app/src/main/res/drawable-xhdpi/ic_folder.png new file mode 100644 index 0000000000..e5f54cef01 Binary files /dev/null and b/Source/Android/app/src/main/res/drawable-xhdpi/ic_folder.png differ diff --git a/Source/Android/app/src/main/res/drawable-xhdpi/ic_gamecube.png b/Source/Android/app/src/main/res/drawable-xhdpi/ic_gamecube.png new file mode 100644 index 0000000000..5efa0a6ced Binary files /dev/null and b/Source/Android/app/src/main/res/drawable-xhdpi/ic_gamecube.png differ diff --git a/Source/Android/app/src/main/res/drawable-xhdpi/ic_wii.png b/Source/Android/app/src/main/res/drawable-xhdpi/ic_wii.png new file mode 100644 index 0000000000..048ab5609f Binary files /dev/null and b/Source/Android/app/src/main/res/drawable-xhdpi/ic_wii.png differ diff --git a/Source/Android/app/src/main/res/drawable-xxhdpi/ic_add.png b/Source/Android/app/src/main/res/drawable-xxhdpi/ic_add.png new file mode 100644 index 0000000000..72cedcad4f Binary files /dev/null and b/Source/Android/app/src/main/res/drawable-xxhdpi/ic_add.png differ diff --git a/Source/Android/app/src/main/res/drawable-xxhdpi/ic_folder.png b/Source/Android/app/src/main/res/drawable-xxhdpi/ic_folder.png new file mode 100644 index 0000000000..0d1ac48767 Binary files /dev/null and b/Source/Android/app/src/main/res/drawable-xxhdpi/ic_folder.png differ diff --git a/Source/Android/app/src/main/res/drawable-xxhdpi/ic_gamecube.png b/Source/Android/app/src/main/res/drawable-xxhdpi/ic_gamecube.png new file mode 100644 index 0000000000..03271360fb Binary files /dev/null and b/Source/Android/app/src/main/res/drawable-xxhdpi/ic_gamecube.png differ diff --git a/Source/Android/app/src/main/res/drawable-xxhdpi/ic_wii.png b/Source/Android/app/src/main/res/drawable-xxhdpi/ic_wii.png new file mode 100644 index 0000000000..161241408e Binary files /dev/null and b/Source/Android/app/src/main/res/drawable-xxhdpi/ic_wii.png differ diff --git a/Source/Android/app/src/main/res/drawable-xxxhdpi/ic_add.png b/Source/Android/app/src/main/res/drawable-xxxhdpi/ic_add.png new file mode 100644 index 0000000000..2bef059583 Binary files /dev/null and b/Source/Android/app/src/main/res/drawable-xxxhdpi/ic_add.png differ diff --git a/Source/Android/app/src/main/res/drawable-xxxhdpi/ic_folder.png b/Source/Android/app/src/main/res/drawable-xxxhdpi/ic_folder.png new file mode 100644 index 0000000000..7a3c198ee4 Binary files /dev/null and b/Source/Android/app/src/main/res/drawable-xxxhdpi/ic_folder.png differ diff --git a/Source/Android/app/src/main/res/drawable-xxxhdpi/ic_gamecube.png b/Source/Android/app/src/main/res/drawable-xxxhdpi/ic_gamecube.png new file mode 100644 index 0000000000..a24c1f14fb Binary files /dev/null and b/Source/Android/app/src/main/res/drawable-xxxhdpi/ic_gamecube.png differ diff --git a/Source/Android/app/src/main/res/drawable-xxxhdpi/ic_wii.png b/Source/Android/app/src/main/res/drawable-xxxhdpi/ic_wii.png new file mode 100644 index 0000000000..97717c2fc8 Binary files /dev/null and b/Source/Android/app/src/main/res/drawable-xxxhdpi/ic_wii.png differ diff --git a/Source/Android/app/src/main/res/drawable/oval_ripple_gc.xml b/Source/Android/app/src/main/res/drawable/oval_ripple_gc.xml index 0477ba84fe..167d3ef13a 100644 --- a/Source/Android/app/src/main/res/drawable/oval_ripple_gc.xml +++ b/Source/Android/app/src/main/res/drawable/oval_ripple_gc.xml @@ -2,7 +2,7 @@ android:color="?android:colorControlHighlight"> - + \ No newline at end of file diff --git a/Source/Android/app/src/main/res/drawable/oval_ripple_grey.xml b/Source/Android/app/src/main/res/drawable/oval_ripple_grey.xml new file mode 100644 index 0000000000..31f064c0ac --- /dev/null +++ b/Source/Android/app/src/main/res/drawable/oval_ripple_grey.xml @@ -0,0 +1,8 @@ + + + + + + + \ No newline at end of file diff --git a/Source/Android/app/src/main/res/drawable/oval_ripple_wii.xml b/Source/Android/app/src/main/res/drawable/oval_ripple_wii.xml index 35c767805c..644876eda3 100644 --- a/Source/Android/app/src/main/res/drawable/oval_ripple_wii.xml +++ b/Source/Android/app/src/main/res/drawable/oval_ripple_wii.xml @@ -2,7 +2,7 @@ android:color="?android:colorControlHighlight"> - + \ No newline at end of file diff --git a/Source/Android/app/src/main/res/layout/activity_add_directory.xml b/Source/Android/app/src/main/res/layout/activity_add_directory.xml new file mode 100644 index 0000000000..72d66c3950 --- /dev/null +++ b/Source/Android/app/src/main/res/layout/activity_add_directory.xml @@ -0,0 +1,29 @@ + + + + + + + + + + \ No newline at end of file diff --git a/Source/Android/app/src/main/res/layout/activity_game_grid.xml b/Source/Android/app/src/main/res/layout/activity_game_grid.xml index e87f859787..2dc6416a94 100644 --- a/Source/Android/app/src/main/res/layout/activity_game_grid.xml +++ b/Source/Android/app/src/main/res/layout/activity_game_grid.xml @@ -9,9 +9,10 @@ android:id="@+id/toolbar_game_list" android:layout_width="match_parent" android:layout_height="wrap_content" - android:background="@color/dolphin_wii" + android:background="@color/dolphin_blue" android:minHeight="?android:attr/actionBarSize" - android:theme="@android:style/ThemeOverlay.Material.Dark.ActionBar"/> + android:theme="@android:style/ThemeOverlay.Material.Dark.ActionBar" + android:elevation="6dp"/> + + + + + + + \ No newline at end of file diff --git a/Source/Android/app/src/main/res/menu/menu_add_directory.xml b/Source/Android/app/src/main/res/menu/menu_add_directory.xml new file mode 100644 index 0000000000..c459811868 --- /dev/null +++ b/Source/Android/app/src/main/res/menu/menu_add_directory.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/Source/Android/app/src/main/res/menu/menu_game_grid.xml b/Source/Android/app/src/main/res/menu/menu_game_grid.xml new file mode 100644 index 0000000000..0d689474ad --- /dev/null +++ b/Source/Android/app/src/main/res/menu/menu_game_grid.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/Source/Android/app/src/main/res/values/colors.xml b/Source/Android/app/src/main/res/values/colors.xml index a4174647c7..d7b7847125 100644 --- a/Source/Android/app/src/main/res/values/colors.xml +++ b/Source/Android/app/src/main/res/values/colors.xml @@ -1,10 +1,11 @@ - #2196f3 - #1976d2 - #651fff + #2196f3 + #1976d2 - #673ab7 - #512da8 - #2979ff + #9e9e9e + #2979ff + #651fff + + #bdbdbd \ No newline at end of file diff --git a/Source/Android/app/src/main/res/values/strings.xml b/Source/Android/app/src/main/res/values/strings.xml index f321d08df2..37ce0b1365 100644 --- a/Source/Android/app/src/main/res/values/strings.xml +++ b/Source/Android/app/src/main/res/values/strings.xml @@ -220,4 +220,7 @@ Disabled Other + + Add Directory to Library + Up one level diff --git a/Source/Android/app/src/main/res/values/styles.xml b/Source/Android/app/src/main/res/values/styles.xml index a0bfbb1865..b185e6cf10 100644 --- a/Source/Android/app/src/main/res/values/styles.xml +++ b/Source/Android/app/src/main/res/values/styles.xml @@ -1,27 +1,27 @@ - + + + - - \ No newline at end of file