diff --git a/Contributing.md b/Contributing.md index 9c63e74b07..6c25c0d5ba 100644 --- a/Contributing.md +++ b/Contributing.md @@ -3,7 +3,6 @@ If you make any contributions to Dolphin after December 1st, 2014, you are agreeing that any code you have contributed will be licensed under the GNU GPL version 2 (or any later version). ## Coding Style ---- - [Introduction] (#introduction) - [Styling and formatting] (#styling-and-formatting) @@ -20,14 +19,12 @@ If you make any contributions to Dolphin after December 1st, 2014, you are agree ## Introduction ---- This guide is for developers who wish to contribute to the Dolphin codebase. It will detail how to properly style and format code to fit this project. This guide also offers suggestions on specific functions and other varia that may be used in code. Following this guide and formatting your code as detailed will likely get your pull request merged much faster than if you don't (assuming the written code has no mistakes in itself). ## Styling and formatting ---- ### General - Try to limit lines of code to a maximum of 100 characters. @@ -130,7 +127,6 @@ private: ``` ## Code Specific ---- ### General - Using C++11 features is OK and recommended. @@ -229,3 +225,7 @@ private: // Class definitions }; ``` + +## Java + +The Android project is currently written in Java. If you are using Android Studio to contribute, you can import the project's code style from `code-style-java.jar`, located in `[Dolphin Root]/Source/Android`. Please organize imports before committing. \ No newline at end of file diff --git a/Source/Android/app/build.gradle b/Source/Android/app/build.gradle index 0fd64d013c..ae34d82377 100644 --- a/Source/Android/app/build.gradle +++ b/Source/Android/app/build.gradle @@ -56,5 +56,5 @@ dependencies { compile 'de.hdodenhof:circleimageview:1.2.2' // For loading huge screenshots from the disk. - compile "com.squareup.picasso:picasso:2.4.0" + compile 'com.squareup.picasso:picasso:2.5.2' } diff --git a/Source/Android/app/src/main/AndroidManifest.xml b/Source/Android/app/src/main/AndroidManifest.xml index 981d4117e9..9042094c43 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,11 @@ + + 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..7ce0047b08 --- /dev/null +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/FileAdapter.java @@ -0,0 +1,212 @@ +package org.dolphinemu.dolphinemu.adapters; + +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Toast; + +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 path A String containing the path to the directory to be shown by this Adapter. + * @param listener An Activity that can respond to callbacks from this Adapter. + */ + public FileAdapter(String path, FileClickListener listener) + { + mFileList = generateFileList(new File(path)); + mListener = listener; + mListener.updateSubtitle(path); + } + + /** + * 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(); + } + + /** + * When a file is clicked, determine if it is a directory; if it is, show that new directory's + * contents. If it is not, end the activity successfully. + * + * @param view The View representing the file the user clicked on. + */ + @Override + public void onClick(final View view) + { + final String path = (String) view.getTag(); + + File clickedFile = new File(path); + + if (clickedFile.isDirectory()) + { + final ArrayList fileList = generateFileList(clickedFile); + + if (fileList.isEmpty()) + { + Toast.makeText(view.getContext(), R.string.add_directory_empty_folder, Toast.LENGTH_SHORT).show(); + } + else + { + // Delay the loading of the new directory to give a little bit of time for UI feedback + // to happen. Hacky, but good enough for now; this is necessary because we're modifying + // the RecyclerView's contents, rather than constructing a new one. + view.getHandler().postDelayed(new Runnable() + { + @Override + public void run() + { + mFileList = fileList; + notifyDataSetChanged(); + mListener.updateSubtitle(path); + } + }, 200); + } + } + else + { + // Pass the activity the path of the parent directory of the clicked file. + mListener.finishSuccessfully(); + } + } + + /** + * For a given directory, return a list of Files it contains. + * + * @param directory A File representing the directory that should have its contents displayed. + * @return + */ + 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) + { + File directory = new File(path); + + mFileList = generateFileList(directory); + notifyDataSetChanged(); + mListener.updateSubtitle(path); + } + + public void upOneLevel() + { + File currentDirectory = new File(mPath); + File parentDirectory = currentDirectory.getParentFile(); + + mFileList = generateFileList(parentDirectory); + notifyDataSetChanged(); + mListener.updateSubtitle(mPath); + } + + /** + * Callback to the containing Activity. + */ + public interface FileClickListener + { + void finishSuccessfully(); + + void updateSubtitle(String path); + } +} 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 30bc9daad6..883107a410 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 @@ -1,5 +1,7 @@ package org.dolphinemu.dolphinemu.adapters; +import android.app.Activity; +import android.content.Intent; import android.graphics.Rect; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; @@ -9,12 +11,16 @@ import android.view.ViewGroup; import com.squareup.picasso.Picasso; import org.dolphinemu.dolphinemu.R; +import org.dolphinemu.dolphinemu.dialogs.GameDetailsDialog; +import org.dolphinemu.dolphinemu.emulation.EmulationActivity; import org.dolphinemu.dolphinemu.model.Game; import org.dolphinemu.dolphinemu.viewholders.GameViewHolder; import java.util.ArrayList; -public class GameAdapter extends RecyclerView.Adapter +public class GameAdapter extends RecyclerView.Adapter implements + View.OnClickListener, + View.OnLongClickListener { private ArrayList mGameList; @@ -42,6 +48,9 @@ public class GameAdapter extends RecyclerView.Adapter View gameCard = LayoutInflater.from(parent.getContext()) .inflate(R.layout.card_game, parent, false); + gameCard.setOnClickListener(this); + gameCard.setOnLongClickListener(this); + // Use that view to create a ViewHolder. GameViewHolder holder = new GameViewHolder(gameCard); return holder; @@ -64,6 +73,8 @@ public class GameAdapter extends RecyclerView.Adapter // Fill in the view contents. Picasso.with(holder.imageScreenshot.getContext()) .load(game.getScreenPath()) + .fit() + .centerCrop() .error(R.drawable.no_banner) .into(holder.imageScreenshot); @@ -72,12 +83,10 @@ public class GameAdapter extends RecyclerView.Adapter { holder.textDescription.setText(game.getDescription()); } - holder.buttonDetails.setTag(game.getGameId()); holder.path = game.getPath(); holder.screenshotPath = game.getScreenPath(); holder.game = game; - } /** @@ -91,6 +100,45 @@ public class GameAdapter extends RecyclerView.Adapter return mGameList.size(); } + /** + * Launches the game that was clicked on. + * + * @param view The card representing the game the user wants to play. + */ + @Override + public void onClick(View view) + { + GameViewHolder holder = (GameViewHolder) view.getTag(); + + // Start the emulation activity and send the path of the clicked ISO to it. + Intent intent = new Intent(view.getContext(), EmulationActivity.class); + + intent.putExtra("SelectedGame", holder.path); + + view.getContext().startActivity(intent); + } + + /** + * Launches the details activity for this Game, using an ID stored in the + * details button's Tag. + * + * @param view The Card button that was long-clicked. + */ + @Override + public boolean onLongClick(View view) + { + GameViewHolder holder = (GameViewHolder) view.getTag(); + + // Get the ID of the game we want to look at. + // TODO This should be all we need to pass in, eventually. + // String gameId = (String) holder.gameId; + + Activity activity = (Activity) view.getContext(); + GameDetailsDialog.newInstance(holder.game).show(activity.getFragmentManager(), "game_details"); + + return true; + } + public static class SpacesItemDecoration extends RecyclerView.ItemDecoration { private int space; @@ -107,7 +155,12 @@ public class GameAdapter extends RecyclerView.Adapter outRect.right = space; outRect.bottom = space; outRect.top = space; - } } + + public void setGameList(ArrayList gameList) + { + mGameList = gameList; + notifyDataSetChanged(); + } } diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/GameDetailsDialog.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/GameDetailsDialog.java index 19c6621345..e22b30ea18 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/GameDetailsDialog.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/GameDetailsDialog.java @@ -84,6 +84,8 @@ public class GameDetailsDialog extends DialogFragment // Fill in the view contents. Picasso.with(imageGameScreen.getContext()) .load(getArguments().getString(ARGUMENT_GAME_SCREENSHOT_PATH)) + .fit() + .centerCrop() .noFade() .noPlaceholder() .into(imageGameScreen); 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..69b39438e8 --- /dev/null +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/FileListItem.java @@ -0,0 +1,85 @@ +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/java/org/dolphinemu/dolphinemu/viewholders/GameViewHolder.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/viewholders/GameViewHolder.java index 47acf588de..18e271e0f5 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/viewholders/GameViewHolder.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/viewholders/GameViewHolder.java @@ -19,7 +19,6 @@ public class GameViewHolder extends RecyclerView.ViewHolder public ImageView imageScreenshot; public TextView textGameTitle; public TextView textDescription; - public ImageButton buttonDetails; // Used to handle onClick(). Set this in onBindViewHolder(). public String path; @@ -30,54 +29,10 @@ public class GameViewHolder extends RecyclerView.ViewHolder { super(itemView); - itemView.setOnClickListener(mCardClickListener); + itemView.setTag(this); imageScreenshot = (ImageView) itemView.findViewById(R.id.image_game_screen); textGameTitle = (TextView) itemView.findViewById(R.id.text_game_title); textDescription = (TextView) itemView.findViewById(R.id.text_game_description); - buttonDetails = (ImageButton) itemView.findViewById(R.id.button_details); - - buttonDetails.setOnClickListener(mDetailsButtonListener); } - - private View.OnClickListener mCardClickListener = new View.OnClickListener() - { - /** - * Launches the game that was clicked on. - * - * @param view The card representing the game the user wants to play. - */ - @Override - public void onClick(View view) - { - // Start the emulation activity and send the path of the clicked ROM to it. - Intent intent = new Intent(view.getContext(), EmulationActivity.class); - - intent.putExtra("SelectedGame", path); - - view.getContext().startActivity(intent); - } - }; - - private View.OnClickListener mDetailsButtonListener = new View.OnClickListener() - { - - /** - * Launches the details activity for this Game, using an ID stored in the - * details button's Tag. - * - * @param view The Details button that was clicked on. - */ - @Override - public void onClick(View view) - { - // Get the ID of the game we want to look at. - // TODO This should be all we need to pass in, eventually. - // String gameId = (String) view.getTag(); - - Activity activity = (Activity) view.getContext(); - GameDetailsDialog.newInstance(game).show(activity.getFragmentManager(), "game_details"); - } - }; - } 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.xml b/Source/Android/app/src/main/res/drawable/oval_ripple_gc.xml similarity index 66% rename from Source/Android/app/src/main/res/drawable/oval_ripple.xml rename to Source/Android/app/src/main/res/drawable/oval_ripple_gc.xml index 554d5f834a..167d3ef13a 100644 --- a/Source/Android/app/src/main/res/drawable/oval_ripple.xml +++ b/Source/Android/app/src/main/res/drawable/oval_ripple_gc.xml @@ -1,9 +1,8 @@ - - + \ 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 new file mode 100644 index 0000000000..644876eda3 --- /dev/null +++ b/Source/Android/app/src/main/res/drawable/oval_ripple_wii.xml @@ -0,0 +1,8 @@ + + + + + + + \ 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 f026322f3d..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,16 +9,36 @@ 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"/> - + android:layout_height="match_parent"> + + + + + \ No newline at end of file diff --git a/Source/Android/app/src/main/res/layout/card_game.xml b/Source/Android/app/src/main/res/layout/card_game.xml index a89e5bdb21..dc8321f8f8 100644 --- a/Source/Android/app/src/main/res/layout/card_game.xml +++ b/Source/Android/app/src/main/res/layout/card_game.xml @@ -2,9 +2,14 @@ + android:layout_width="0dp" + tools:layout_width="224dp" + android:layout_height="256dp" + android:transitionName="card_game" + android:focusable="true" + android:clickable="true" + android:foreground="?android:attr/selectableItemBackground" + > + tools:src="@drawable/placeholder_screenshot" + tools:scaleType="centerCrop"/> - + + - - - - - - diff --git a/Source/Android/app/src/main/res/layout/dialog_game_details.xml b/Source/Android/app/src/main/res/layout/dialog_game_details.xml index 885dc91676..b431991baf 100644 --- a/Source/Android/app/src/main/res/layout/dialog_game_details.xml +++ b/Source/Android/app/src/main/res/layout/dialog_game_details.xml @@ -31,7 +31,6 @@ android:layout_alignParentRight="true" android:layout_alignParentStart="true" android:layout_alignParentTop="true" - android:scaleType="centerCrop" android:transitionName="image_game_screen" tools:src="@drawable/placeholder_screenshot"/> @@ -125,7 +124,7 @@ android:layout_alignBottom="@+id/image_game_screen" android:layout_alignEnd="@+id/text_game_title" android:layout_marginBottom="-28dp" - android:background="@drawable/oval_ripple" + android:background="@drawable/oval_ripple_wii" android:src="@drawable/ic_play" android:stateListAnimator="@anim/button_elevation" android:elevation="4dp"/> diff --git a/Source/Android/app/src/main/res/layout/list_item_file.xml b/Source/Android/app/src/main/res/layout/list_item_file.xml new file mode 100644 index 0000000000..7d54e77d27 --- /dev/null +++ b/Source/Android/app/src/main/res/layout/list_item_file.xml @@ -0,0 +1,31 @@ + + + + + + + + \ 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..667d28a4f0 --- /dev/null +++ b/Source/Android/app/src/main/res/menu/menu_add_directory.xml @@ -0,0 +1,8 @@ + + + + + \ 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 608cc9afd7..d7b7847125 100644 --- a/Source/Android/app/src/main/res/values/colors.xml +++ b/Source/Android/app/src/main/res/values/colors.xml @@ -1,8 +1,11 @@ - #5bc0de - #428bca + #2196f3 + #1976d2 - #663399 - #311b92 + #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..99defca7bf 100644 --- a/Source/Android/app/src/main/res/values/strings.xml +++ b/Source/Android/app/src/main/res/values/strings.xml @@ -220,4 +220,8 @@ Disabled Other + + Add Folder to Library + Up one level + That folder is empty. diff --git a/Source/Android/app/src/main/res/values/styles.xml b/Source/Android/app/src/main/res/values/styles.xml index 40d406b20f..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 diff --git a/Source/Android/code-style-java.jar b/Source/Android/code-style-java.jar new file mode 100644 index 0000000000..8140ad66f9 Binary files /dev/null and b/Source/Android/code-style-java.jar differ diff --git a/Source/Core/DolphinWX/MainAndroid.cpp b/Source/Core/DolphinWX/MainAndroid.cpp index 097ad732af..50aab79f45 100644 --- a/Source/Core/DolphinWX/MainAndroid.cpp +++ b/Source/Core/DolphinWX/MainAndroid.cpp @@ -219,7 +219,7 @@ static std::string GetTitle(std::string filename) return name; } - return std::string ("Error"); + return std::string (""); } static std::string GetDescription(std::string filename) @@ -256,7 +256,7 @@ static std::string GetDescription(std::string filename) return descriptions.cbegin()->second; } - return std::string ("Error"); + return std::string (""); } static std::string GetGameId(std::string filename) @@ -271,7 +271,7 @@ static std::string GetGameId(std::string filename) return id; } - return std::string ("Error"); + return std::string (""); } static std::string GetApploaderDate(std::string filename) @@ -286,7 +286,7 @@ static std::string GetApploaderDate(std::string filename) return date; } - return std::string ("Error"); + return std::string (""); } static u64 GetFileSize(std::string filename) @@ -349,17 +349,17 @@ JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_Run(JNIEnv * JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_UnPauseEmulation(JNIEnv *env, jobject obj) { -PowerPC::Start(); + PowerPC::Start(); } JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_PauseEmulation(JNIEnv *env, jobject obj) { -PowerPC::Pause(); + PowerPC::Pause(); } JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_StopEmulation(JNIEnv *env, jobject obj) { -Core::Stop(); -updateMainFrameEvent.Set(); // Kick the waiting event + Core::Stop(); + updateMainFrameEvent.Set(); // Kick the waiting event } JNIEXPORT jboolean JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_onGamePadEvent(JNIEnv *env, jobject obj, jstring jDevice, jint Button, jint Action) { @@ -367,7 +367,7 @@ JNIEXPORT jboolean JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_onGamePa } JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_onGamePadMoveEvent(JNIEnv *env, jobject obj, jstring jDevice, jint Axis, jfloat Value) { -ButtonManager::GamepadAxisEvent(GetJString(env, jDevice), Axis, Value); + ButtonManager::GamepadAxisEvent(GetJString(env, jDevice), Axis, Value); } JNIEXPORT jintArray JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_GetBanner(JNIEnv *env, jobject obj, jstring jFile) @@ -437,12 +437,12 @@ JNIEXPORT jboolean JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_Supports JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SaveScreenShot(JNIEnv *env, jobject obj) { -Core::SaveScreenShot(); + Core::SaveScreenShot(); } JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_eglBindAPI(JNIEnv *env, jobject obj, jint api) { -eglBindAPI(api); + eglBindAPI(api); } JNIEXPORT jstring JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_GetConfig(JNIEnv *env, jobject obj, jstring jFile, jstring jSection, jstring jKey, jstring jDefault) @@ -460,59 +460,58 @@ JNIEXPORT jstring JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_GetConfig return env->NewStringUTF(value.c_str()); } -JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SetConfig(JNIEnv *env, jobject obj, jstring jFile, jstring jSection, jstring jKey, -jstring jValue) +JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SetConfig(JNIEnv *env, jobject obj, jstring jFile, jstring jSection, jstring jKey, jstring jValue) { -IniFile ini; -std::string file = GetJString(env, jFile); -std::string section = GetJString(env, jSection); -std::string key = GetJString(env, jKey); -std::string value = GetJString(env, jValue); + IniFile ini; + std::string file = GetJString(env, jFile); + std::string section = GetJString(env, jSection); + std::string key = GetJString(env, jKey); + std::string value = GetJString(env, jValue); -ini.Load(File::GetUserPath(D_CONFIG_IDX) + std::string(file)); + ini.Load(File::GetUserPath(D_CONFIG_IDX) + std::string(file)); -ini.GetOrCreateSection(section)->Set(key, value); -ini.Save(File::GetUserPath(D_CONFIG_IDX) + std::string(file)); + ini.GetOrCreateSection(section)->Set(key, value); + ini.Save(File::GetUserPath(D_CONFIG_IDX) + std::string(file)); } JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SetFilename(JNIEnv *env, jobject obj, jstring jFile) { -g_filename = GetJString(env, jFile); + g_filename = GetJString(env, jFile); } JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SaveState(JNIEnv *env, jobject obj, jint slot) { -State::Save(slot); + State::Save(slot); } JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_LoadState(JNIEnv *env, jobject obj, jint slot) { -State::Load(slot); + State::Load(slot); } JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_CreateUserFolders(JNIEnv *env, jobject obj) { -File::CreateFullPath(File::GetUserPath(D_CONFIG_IDX)); -File::CreateFullPath(File::GetUserPath(D_GCUSER_IDX)); -File::CreateFullPath(File::GetUserPath(D_WIIUSER_IDX)); -File::CreateFullPath(File::GetUserPath(D_CACHE_IDX)); -File::CreateFullPath(File::GetUserPath(D_DUMPDSP_IDX)); -File::CreateFullPath(File::GetUserPath(D_DUMPTEXTURES_IDX)); -File::CreateFullPath(File::GetUserPath(D_HIRESTEXTURES_IDX)); -File::CreateFullPath(File::GetUserPath(D_SCREENSHOTS_IDX)); -File::CreateFullPath(File::GetUserPath(D_STATESAVES_IDX)); -File::CreateFullPath(File::GetUserPath(D_MAILLOGS_IDX)); -File::CreateFullPath(File::GetUserPath(D_SHADERS_IDX)); -File::CreateFullPath(File::GetUserPath(D_GCUSER_IDX) + USA_DIR DIR_SEP); -File::CreateFullPath(File::GetUserPath(D_GCUSER_IDX) + EUR_DIR DIR_SEP); -File::CreateFullPath(File::GetUserPath(D_GCUSER_IDX) + JAP_DIR DIR_SEP); + File::CreateFullPath(File::GetUserPath(D_CONFIG_IDX)); + File::CreateFullPath(File::GetUserPath(D_GCUSER_IDX)); + File::CreateFullPath(File::GetUserPath(D_WIIUSER_IDX)); + File::CreateFullPath(File::GetUserPath(D_CACHE_IDX)); + File::CreateFullPath(File::GetUserPath(D_DUMPDSP_IDX)); + File::CreateFullPath(File::GetUserPath(D_DUMPTEXTURES_IDX)); + File::CreateFullPath(File::GetUserPath(D_HIRESTEXTURES_IDX)); + File::CreateFullPath(File::GetUserPath(D_SCREENSHOTS_IDX)); + File::CreateFullPath(File::GetUserPath(D_STATESAVES_IDX)); + File::CreateFullPath(File::GetUserPath(D_MAILLOGS_IDX)); + File::CreateFullPath(File::GetUserPath(D_SHADERS_IDX)); + File::CreateFullPath(File::GetUserPath(D_GCUSER_IDX) + USA_DIR DIR_SEP); + File::CreateFullPath(File::GetUserPath(D_GCUSER_IDX) + EUR_DIR DIR_SEP); + File::CreateFullPath(File::GetUserPath(D_GCUSER_IDX) + JAP_DIR DIR_SEP); } JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_SetUserDirectory(JNIEnv *env, jobject obj, jstring jDirectory) { -std::string directory = GetJString(env, jDirectory); -g_set_userpath = directory; -UICommon::SetUserDirectory(directory); + std::string directory = GetJString(env, jDirectory); + g_set_userpath = directory; + UICommon::SetUserDirectory(directory); } JNIEXPORT jstring JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_GetUserDirectory(JNIEnv *env, jobject obj) @@ -522,24 +521,24 @@ JNIEXPORT jstring JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_GetUserDi JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_NativeLibrary_Run(JNIEnv *env, jobject obj, jobject _surf) { -surf = ANativeWindow_fromSurface(env, _surf); + surf = ANativeWindow_fromSurface(env, _surf); -// Install our callbacks -OSD::AddCallback(OSD::OSD_INIT, ButtonManager::Init); -OSD::AddCallback(OSD::OSD_SHUTDOWN, ButtonManager::Shutdown); + // Install our callbacks + OSD::AddCallback(OSD::OSD_INIT, ButtonManager::Init); + OSD::AddCallback(OSD::OSD_SHUTDOWN, ButtonManager::Shutdown); -RegisterMsgAlertHandler(&MsgAlert); + RegisterMsgAlertHandler(&MsgAlert); -UICommon::SetUserDirectory(g_set_userpath); -UICommon::Init(); + UICommon::SetUserDirectory(g_set_userpath); + UICommon::Init(); -// No use running the loop when booting fails -if ( BootManager::BootCore( g_filename.c_str() ) ) -while (PowerPC::GetState() != PowerPC::CPU_POWERDOWN) -updateMainFrameEvent.Wait(); + // No use running the loop when booting fails + if ( BootManager::BootCore( g_filename.c_str() ) ) + while (PowerPC::GetState() != PowerPC::CPU_POWERDOWN) + updateMainFrameEvent.Wait(); -UICommon::Shutdown(); -ANativeWindow_release(surf); + UICommon::Shutdown(); + ANativeWindow_release(surf); }