summaryrefslogtreecommitdiff
path: root/Source/Android/app/src/main/java
diff options
context:
space:
mode:
authorsigmabeta <bastos.eder@gmail.com>2015-07-14 22:35:52 -0400
committersigmabeta <sigmabeta@users.noreply.github.com>2015-07-25 12:26:31 -0400
commit7c14996e3e24b0a4a1064ece1c656bcbe6c923c7 (patch)
tree64ad0aabbfd2d23caccc40462a1e4dc403db7ea1 /Source/Android/app/src/main/java
parent3801f89125b63a29f2d817b2021f362768642fec (diff)
Android TV: Implement game selector activity in new Android TV UI
Diffstat (limited to 'Source/Android/app/src/main/java')
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/MainActivity.java2
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/TvMainActivity.java141
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GamePresenter.java122
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/Game.java33
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/viewholders/TvGameViewHolder.java40
5 files changed, 311 insertions, 27 deletions
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/MainActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/MainActivity.java
index 33cd0b0c15..a32b65d566 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/MainActivity.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/MainActivity.java
@@ -226,7 +226,7 @@ public final class MainActivity extends AppCompatActivity implements LoaderManag
GameProvider.URI_GAME, // URI of table to query
null, // Return all columns
GameDatabase.KEY_GAME_PLATFORM + " = ?", // Select by platform
- new String[]{Integer.toString(id)}, // Platform id is Loader id minus 1
+ new String[]{Integer.toString(id)}, // Platform id is Loader id
GameDatabase.KEY_GAME_TITLE + " asc" // Sort by game name, ascending order
);
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/TvMainActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/TvMainActivity.java
new file mode 100644
index 0000000000..2c191bdaf0
--- /dev/null
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/TvMainActivity.java
@@ -0,0 +1,141 @@
+package org.dolphinemu.dolphinemu.activities;
+
+import android.app.Activity;
+import android.app.ActivityOptions;
+import android.app.FragmentManager;
+import android.content.Intent;
+import android.database.Cursor;
+import android.os.Bundle;
+import android.support.v17.leanback.app.BrowseFragment;
+import android.support.v17.leanback.database.CursorMapper;
+import android.support.v17.leanback.widget.ArrayObjectAdapter;
+import android.support.v17.leanback.widget.CursorObjectAdapter;
+import android.support.v17.leanback.widget.HeaderItem;
+import android.support.v17.leanback.widget.ListRow;
+import android.support.v17.leanback.widget.ListRowPresenter;
+import android.support.v17.leanback.widget.OnItemViewClickedListener;
+import android.support.v17.leanback.widget.Presenter;
+import android.support.v17.leanback.widget.Row;
+import android.support.v17.leanback.widget.RowPresenter;
+
+import org.dolphinemu.dolphinemu.R;
+import org.dolphinemu.dolphinemu.adapters.GamePresenter;
+import org.dolphinemu.dolphinemu.model.Game;
+import org.dolphinemu.dolphinemu.model.GameDatabase;
+import org.dolphinemu.dolphinemu.model.GameProvider;
+import org.dolphinemu.dolphinemu.viewholders.TvGameViewHolder;
+
+public final class TvMainActivity extends Activity
+{
+ protected BrowseFragment mBrowseFragment;
+
+ private ArrayObjectAdapter mRowsAdapter;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState)
+ {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_tv_main);
+
+ final FragmentManager fragmentManager = getFragmentManager();
+ mBrowseFragment = (BrowseFragment) fragmentManager.findFragmentById(
+ R.id.fragment_game_list);
+
+ // Set display parameters for the BrowseFragment
+ mBrowseFragment.setHeadersState(BrowseFragment.HEADERS_ENABLED);
+ mBrowseFragment.setTitle(getString(R.string.app_name));
+ mBrowseFragment.setBadgeDrawable(getResources().getDrawable(
+ R.drawable.ic_launcher, null));
+ mBrowseFragment.setBrandColor(getResources().getColor(R.color.dolphin_blue_dark));
+
+ buildRowsAdapter();
+
+ mBrowseFragment.setOnItemViewClickedListener(
+ new OnItemViewClickedListener()
+ {
+ @Override
+ public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item, RowPresenter.ViewHolder rowViewHolder, Row row)
+ {
+ TvGameViewHolder holder = (TvGameViewHolder) itemViewHolder;
+ // Start the emulation activity and send the path of the clicked ISO to it.
+ Intent intent = new Intent(TvMainActivity.this, EmulationActivity.class);
+
+ intent.putExtra("SelectedGame", holder.path);
+ intent.putExtra("SelectedTitle", holder.title);
+ intent.putExtra("ScreenPath", holder.screenshotPath);
+
+ ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(
+ TvMainActivity.this,
+ holder.imageScreenshot,
+ "image_game_screenshot");
+
+ startActivity(intent, options.toBundle());
+ }
+ });
+ }
+
+ private void buildRowsAdapter()
+ {
+ mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());
+
+ // For each row
+ for (int platformIndex = 0; platformIndex <= Game.PLATFORM_WII_WARE; ++platformIndex)
+ {
+ // Create an adapter for this row.
+ CursorObjectAdapter row = new CursorObjectAdapter(new GamePresenter(platformIndex));
+
+ // Add items to the adapter.
+ Cursor games = getContentResolver().query(
+ GameProvider.URI_GAME, // URI of table to query
+ null, // Return all columns
+ GameDatabase.KEY_GAME_PLATFORM + " = ?", // Select by platform
+ new String[]{Integer.toString(platformIndex)}, // Platform id
+ GameDatabase.KEY_GAME_TITLE + " asc" // Sort by game name, ascending order
+ );
+
+ row.swapCursor(games);
+ row.setMapper(new CursorMapper()
+ {
+ @Override
+ protected void bindColumns(Cursor cursor)
+ {
+ // No-op? Not sure what this does.
+ }
+
+ @Override
+ protected Object bind(Cursor cursor)
+ {
+ return Game.fromCursor(cursor);
+ }
+ });
+
+ String headerName;
+ switch (platformIndex)
+ {
+ case Game.PLATFORM_GC:
+ headerName = "GameCube Games";
+ break;
+
+ case Game.PLATFORM_WII:
+ headerName = "Wii Games";
+ break;
+
+ case Game.PLATFORM_WII_WARE:
+ headerName = "WiiWare";
+ break;
+
+ default:
+ headerName = "Error";
+ break;
+ }
+
+ // Create a header for this row.
+ HeaderItem header = new HeaderItem(platformIndex, headerName);
+
+ // Create the row, passing it the filled adapter and the header, and give it to the master adapter.
+ mRowsAdapter.add(new ListRow(header, row));
+ }
+
+ mBrowseFragment.setAdapter(mRowsAdapter);
+ }
+}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GamePresenter.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GamePresenter.java
new file mode 100644
index 0000000000..d9b4487278
--- /dev/null
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GamePresenter.java
@@ -0,0 +1,122 @@
+package org.dolphinemu.dolphinemu.adapters;
+
+import android.graphics.Bitmap;
+import android.support.v17.leanback.widget.ImageCardView;
+import android.support.v17.leanback.widget.Presenter;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+
+import com.squareup.picasso.Picasso;
+
+import org.dolphinemu.dolphinemu.R;
+import org.dolphinemu.dolphinemu.model.Game;
+import org.dolphinemu.dolphinemu.viewholders.TvGameViewHolder;
+
+/**
+ * The Leanback library / docs call this a Presenter, but it works very
+ * similarly to a RecyclerView.ViewHolder.
+ */
+public final class GamePresenter extends Presenter
+{
+ private int mPlatform;
+
+ public GamePresenter(int platform)
+ {
+ mPlatform = platform;
+ }
+
+ public ViewHolder onCreateViewHolder(ViewGroup parent)
+ {
+ // Create a new view.
+ ImageCardView gameCard = new ImageCardView(parent.getContext())
+ {
+ @Override
+ public void setSelected(boolean selected)
+ {
+ setCardBackground(this, selected);
+ super.setSelected(selected);
+ }
+ };
+
+ gameCard.setMainImageAdjustViewBounds(true);
+ gameCard.setMainImageDimensions(480, 320);
+ gameCard.setMainImageScaleType(ImageView.ScaleType.CENTER_CROP);
+
+ gameCard.setFocusable(true);
+ gameCard.setFocusableInTouchMode(true);
+
+ setCardBackground(gameCard, false);
+
+ // Use that view to create a ViewHolder.
+ return new TvGameViewHolder(gameCard);
+ }
+
+ public void onBindViewHolder(ViewHolder viewHolder, Object item)
+ {
+ TvGameViewHolder holder = (TvGameViewHolder) viewHolder;
+ Game game = (Game) item;
+
+ String screenPath = game.getScreenshotPath();
+
+ // Fill in the view contents.
+ Picasso.with(holder.imageScreenshot.getContext())
+ .load(screenPath)
+ .fit()
+ .centerCrop()
+ .noFade()
+ .noPlaceholder()
+ .config(Bitmap.Config.RGB_565)
+ .error(R.drawable.no_banner)
+ .into(holder.imageScreenshot);
+
+ holder.cardParent.setTitleText(game.getTitle());
+ holder.cardParent.setContentText(game.getCompany());
+
+ // TODO These shouldn't be necessary once the move to a DB-based model is complete.
+ holder.gameId = game.getGameId();
+ holder.path = game.getPath();
+ holder.title = game.getTitle();
+ holder.description = game.getDescription();
+ holder.country = game.getCountry();
+ holder.company = game.getCompany();
+ holder.screenshotPath = game.getScreenshotPath();
+ }
+
+ public void onUnbindViewHolder(ViewHolder viewHolder)
+ {
+ // no op
+ }
+
+ public void setCardBackground(ImageCardView view, boolean selected)
+ {
+ int backgroundColor;
+
+ if (selected)
+ {
+ switch (mPlatform)
+ {
+ case Game.PLATFORM_GC:
+ backgroundColor = R.color.dolphin_accent_gamecube;
+ break;
+
+ case Game.PLATFORM_WII:
+ backgroundColor = R.color.dolphin_accent_wii;
+ break;
+
+ case Game.PLATFORM_WII_WARE:
+ backgroundColor = R.color.dolphin_accent_wiiware;
+ break;
+
+ default:
+ backgroundColor = android.R.color.holo_red_dark;
+ break;
+ }
+ }
+ else
+ {
+ backgroundColor = R.color.tv_card_unselected;
+ }
+
+ view.setInfoAreaBackgroundColor(view.getResources().getColor(backgroundColor));
+ }
+}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/Game.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/Game.java
index f3ef6f7514..2068f01f08 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/Game.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/Game.java
@@ -3,8 +3,6 @@ package org.dolphinemu.dolphinemu.model;
import android.content.ContentValues;
import android.database.Cursor;
-import java.io.File;
-
public final class Game
{
public static final int PLATFORM_GC = 0;
@@ -33,13 +31,13 @@ public final class Game
private String mDescription;
private String mPath;
private String mGameId;
- private String mScreenshotFolderPath;
+ private String mScreenshotPath;
private String mCompany;
private int mPlatform;
private int mCountry;
- public Game(int platform, String title, String description, int country, String path, String gameId, String company)
+ public Game(int platform, String title, String description, int country, String path, String gameId, String company, String screenshotPath)
{
mPlatform = platform;
mTitle = title;
@@ -48,7 +46,7 @@ public final class Game
mPath = path;
mGameId = gameId;
mCompany = company;
- mScreenshotFolderPath = PATH_SCREENSHOT_FOLDER + getGameId() + "/";
+ mScreenshotPath = screenshotPath;
}
public int getPlatform()
@@ -86,27 +84,9 @@ public final class Game
return mGameId;
}
- public String getScreenshotFolderPath()
- {
- return mScreenshotFolderPath;
- }
-
- public String getScreenPath()
+ public String getScreenshotPath()
{
- // Count how many screenshots are available, so we can use the most recent one.
- File screenshotFolder = new File(mScreenshotFolderPath.substring(mScreenshotFolderPath.indexOf('s') - 1));
- int screenCount = 0;
-
- if (screenshotFolder.isDirectory())
- {
- screenCount = screenshotFolder.list().length;
- }
-
- String screenPath = mScreenshotFolderPath
- + getGameId() + "-"
- + screenCount + ".png";
-
- return screenPath;
+ return mScreenshotPath;
}
public static ContentValues asContentValues(int platform, String title, String description, int country, String path, String gameId, String company)
@@ -135,6 +115,7 @@ public final class Game
cursor.getInt(GameDatabase.GAME_COLUMN_COUNTRY),
cursor.getString(GameDatabase.GAME_COLUMN_PATH),
cursor.getString(GameDatabase.GAME_COLUMN_GAME_ID),
- cursor.getString(GameDatabase.GAME_COLUMN_COMPANY));
+ cursor.getString(GameDatabase.GAME_COLUMN_COMPANY),
+ cursor.getString(GameDatabase.GAME_COLUMN_SCREENSHOT_PATH));
}
}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/viewholders/TvGameViewHolder.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/viewholders/TvGameViewHolder.java
new file mode 100644
index 0000000000..dd996ccbe7
--- /dev/null
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/viewholders/TvGameViewHolder.java
@@ -0,0 +1,40 @@
+package org.dolphinemu.dolphinemu.viewholders;
+
+import android.support.v17.leanback.widget.ImageCardView;
+import android.support.v17.leanback.widget.Presenter;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+/**
+ * A simple class that stores references to views so that the GameAdapter doesn't need to
+ * keep calling findViewById(), which is expensive.
+ */
+public class TvGameViewHolder extends Presenter.ViewHolder
+{
+ public ImageCardView cardParent;
+
+ public ImageView imageScreenshot;
+ public TextView textGameTitle;
+ public TextView textCompany;
+
+ public String gameId;
+
+ // TODO Not need any of this stuff. Currently only the properties dialog needs it.
+ public String path;
+ public String title;
+ public String description;
+ public int country;
+ public String company;
+ public String screenshotPath;
+
+ public TvGameViewHolder(View itemView)
+ {
+ super(itemView);
+
+ itemView.setTag(this);
+
+ cardParent = (ImageCardView) itemView;
+ imageScreenshot = cardParent.getMainImageView();
+ }
+}