diff --git a/Contributing.md b/Contributing.md index 9c63e74b07e..6c25c0d5ba5 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 0fd64d013c8..ae34d82377a 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 981d4117e9e..9042094c436 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 00000000000..7ce0047b084 --- /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 30bc9daad6c..883107a4105 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 19c6621345c..e22b30ea185 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 00000000000..69b39438e8f --- /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 00000000000..79acc8400b8 --- /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 47acf588deb..18e271e0f5b 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 00000000000..481643ecd5e 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 00000000000..9f5c756099d 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 00000000000..d128a17277d 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 00000000000..ab4d4be283e 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 00000000000..977dd3427ad 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 00000000000..1c5797c9e0f 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 00000000000..5f972fb8017 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 00000000000..43718bf98d0 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 00000000000..67042105d29 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 00000000000..e5f54cef010 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 00000000000..5efa0a6ced6 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 00000000000..048ab5609fb 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 00000000000..72cedcad4f1 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 00000000000..0d1ac487670 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 00000000000..03271360fb7 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 00000000000..161241408ef 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 00000000000..2bef0595839 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 00000000000..7a3c198ee44 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 00000000000..a24c1f14fb6 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 00000000000..97717c2fc8c 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 68% 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 554d5f834a1..167d3ef13ac 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 00000000000..31f064c0aca --- /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 00000000000..644876eda38 --- /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 00000000000..72d66c39505 --- /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 f026322f3d5..2dc6416a94c 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 a89e5bdb21c..dc8321f8f85 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 885dc91676a..b431991baf7 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 00000000000..7d54e77d27b --- /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 00000000000..667d28a4f0e --- /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 00000000000..0d689474ad7 --- /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 608cc9afd79..d7b78471251 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 f321d08df22..99defca7bf3 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 40d406b20f6..b185e6cf104 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 00000000000..8140ad66f9d 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 097ad732aff..50aab79f45a 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); }