summaryrefslogtreecommitdiff
path: root/Source/Android/app/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Android/app/src/main/java')
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java4
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/MainActivity.java5
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/TvMainActivity.java290
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameRowPresenter.java118
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/SettingsRowPresenter.java47
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/Game.java34
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/TvSettingsItem.java31
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/viewholders/TvGameViewHolder.java39
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/viewholders/TvSettingsViewHolder.java23
9 files changed, 561 insertions, 30 deletions
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java
index c4cc9e1f3a..04b5149a0e 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java
@@ -50,8 +50,8 @@ public final class EmulationActivity extends AppCompatActivity
private boolean mSystemUiVisible;
private boolean mMenuVisible;
- private static Interpolator sDecelerator = new DecelerateInterpolator();
- private static Interpolator sAccelerator = new AccelerateInterpolator();
+ private static final Interpolator sDecelerator = new DecelerateInterpolator();
+ private static final Interpolator sAccelerator = new AccelerateInterpolator();
/**
* Handlers are a way to pass a message to an Activity telling it to do something
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..9ffa651cc2 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
@@ -35,7 +35,7 @@ import org.dolphinemu.dolphinemu.services.AssetCopyService;
*/
public final class MainActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor>
{
- private static final int REQUEST_ADD_DIRECTORY = 1;
+ public static final int REQUEST_ADD_DIRECTORY = 1;
public static final int REQUEST_EMULATE_GAME = 2;
/**
@@ -139,6 +139,7 @@ public final class MainActivity extends AppCompatActivity implements LoaderManag
{
fragment.refreshScreenshotAtPosition(resultCode);
}
+ break;
}
}
@@ -226,7 +227,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..3f3b8c168d
--- /dev/null
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/TvMainActivity.java
@@ -0,0 +1,290 @@
+package org.dolphinemu.dolphinemu.activities;
+
+import android.app.Activity;
+import android.app.ActivityOptions;
+import android.app.FragmentManager;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.database.Cursor;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+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 android.widget.Toast;
+
+import org.dolphinemu.dolphinemu.NativeLibrary;
+import org.dolphinemu.dolphinemu.R;
+import org.dolphinemu.dolphinemu.adapters.GameRowPresenter;
+import org.dolphinemu.dolphinemu.adapters.SettingsRowPresenter;
+import org.dolphinemu.dolphinemu.model.Game;
+import org.dolphinemu.dolphinemu.model.GameDatabase;
+import org.dolphinemu.dolphinemu.model.GameProvider;
+import org.dolphinemu.dolphinemu.model.TvSettingsItem;
+import org.dolphinemu.dolphinemu.services.AssetCopyService;
+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)
+ {
+ // Special case: user clicked on a settings row item.
+ if (item instanceof TvSettingsItem)
+ {
+ TvSettingsItem settingsItem = (TvSettingsItem) item;
+
+ switch (settingsItem.getItemId())
+ {
+ case R.id.menu_refresh:
+ getContentResolver().insert(GameProvider.URI_REFRESH, null);
+
+ // TODO Let the Activity know the data is refreshed in some other, better way.
+ recreate();
+ break;
+
+ case R.id.menu_settings:
+ // Launch the Settings Actvity.
+ Intent settings = new Intent(TvMainActivity.this, SettingsActivity.class);
+ startActivity(settings);
+ break;
+
+ case R.id.button_add_directory:
+ Intent fileChooser = new Intent(TvMainActivity.this, AddDirectoryActivity.class);
+
+ // The second argument to this method is read below in onActivityResult().
+ startActivityForResult(fileChooser, MainActivity.REQUEST_ADD_DIRECTORY);
+
+ break;
+
+ default:
+ Toast.makeText(TvMainActivity.this, "Unimplemented menu option.", Toast.LENGTH_SHORT).show();
+ break;
+ }
+ }
+ else
+ {
+ 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());
+ }
+ }
+ });
+
+ // Stuff in this block only happens when this activity is newly created (i.e. not a rotation)
+ if (savedInstanceState == null)
+ {
+ NativeLibrary.SetUserDirectory(""); // Auto-Detect
+
+ SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
+ boolean assetsCopied = preferences.getBoolean("assetsCopied", false);
+
+ // Only perform these extensive copy operations once.
+ if (!assetsCopied)
+ {
+ // Copy assets into appropriate locations.
+ Intent copyAssets = new Intent(this, AssetCopyService.class);
+ startService(copyAssets);
+ }
+ }
+ }
+
+ /**
+ * Callback from AddDirectoryActivity. Applies any changes necessary to the GameGridActivity.
+ *
+ * @param requestCode An int describing whether the Activity that is returning did so successfully.
+ * @param resultCode An int describing what Activity is giving us this callback.
+ * @param result The information the returning Activity is providing us.
+ */
+ @Override
+ protected void onActivityResult(int requestCode, int resultCode, Intent result)
+ {
+ switch (requestCode)
+ {
+ case MainActivity.REQUEST_ADD_DIRECTORY:
+ // If the user picked a file, as opposed to just backing out.
+ if (resultCode == RESULT_OK)
+ {
+ // Sanity check to make sure the Activity that just returned was the AddDirectoryActivity;
+ // other activities might use this callback in the future (don't forget to change Javadoc!)
+ if (requestCode == MainActivity.REQUEST_ADD_DIRECTORY)
+ {
+ // TODO Let the Activity know the data is refreshed in some other, better way.
+ recreate();
+ }
+ }
+ break;
+ }
+ }
+
+ private void buildRowsAdapter()
+ {
+ mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());
+
+ // For each platform
+ for (int platformIndex = 0; platformIndex <= Game.PLATFORM_ALL; ++platformIndex)
+ {
+ ListRow row = buildGamesRow(platformIndex);
+
+ // Add row to the adapter only if it is not empty.
+ if (row != null)
+ {
+ mRowsAdapter.add(row);
+ }
+ }
+
+ ListRow settingsRow = buildSettingsRow();
+ mRowsAdapter.add(settingsRow);
+
+ mBrowseFragment.setAdapter(mRowsAdapter);
+ }
+
+ private ListRow buildGamesRow(int platform)
+ {
+ // Create an adapter for this row.
+ CursorObjectAdapter row = new CursorObjectAdapter(new GameRowPresenter());
+
+ Cursor games;
+ if (platform == Game.PLATFORM_ALL)
+ {
+ // Get all games.
+ games = getContentResolver().query(
+ GameProvider.URI_GAME, // URI of table to query
+ null, // Return all columns
+ null, // Return all games
+ null, // Return all games
+ GameDatabase.KEY_GAME_TITLE + " asc" // Sort by game name, ascending order
+ );
+ }
+ else
+ {
+ // Get games for this particular platform.
+ 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(platform)}, // Platform id
+ GameDatabase.KEY_GAME_TITLE + " asc" // Sort by game name, ascending order
+ );
+ }
+
+ // If cursor is empty, don't return a Row.
+ if (!games.moveToFirst())
+ {
+ return null;
+ }
+
+ row.changeCursor(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 (platform)
+ {
+ case Game.PLATFORM_GC:
+ headerName = "GameCube Games";
+ break;
+
+ case Game.PLATFORM_WII:
+ headerName = "Wii Games";
+ break;
+
+ case Game.PLATFORM_WII_WARE:
+ headerName = "WiiWare";
+ break;
+
+ case Game.PLATFORM_ALL:
+ headerName = "All Games";
+ break;
+
+ default:
+ headerName = "Error";
+ break;
+ }
+
+ // Create a header for this row.
+ HeaderItem header = new HeaderItem(platform, headerName);
+
+ // Create the row, passing it the filled adapter and the header, and give it to the master adapter.
+ return new ListRow(header, row);
+ }
+
+ private ListRow buildSettingsRow()
+ {
+ ArrayObjectAdapter rowItems = new ArrayObjectAdapter(new SettingsRowPresenter());
+
+ rowItems.add(new TvSettingsItem(R.id.menu_refresh,
+ R.drawable.ic_refresh_tv,
+ R.string.grid_menu_refresh));
+
+ rowItems.add(new TvSettingsItem(R.id.menu_settings,
+ R.drawable.ic_settings_tv,
+ R.string.grid_menu_settings));
+
+ rowItems.add(new TvSettingsItem(R.id.button_add_directory,
+ R.drawable.ic_add_tv,
+ R.string.add_directory_title));
+
+ // Create a header for this row.
+ HeaderItem header = new HeaderItem(R.string.settings, getString(R.string.settings));
+
+ return new ListRow(header, rowItems);
+ }
+}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameRowPresenter.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameRowPresenter.java
new file mode 100644
index 0000000000..3b0b8095ce
--- /dev/null
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameRowPresenter.java
@@ -0,0 +1,118 @@
+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 GameRowPresenter extends Presenter
+{
+ 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();
+
+ switch (game.getPlatform())
+ {
+ case Game.PLATFORM_GC:
+ holder.cardParent.setTag(R.color.dolphin_accent_gamecube);
+ break;
+
+ case Game.PLATFORM_WII:
+ holder.cardParent.setTag(R.color.dolphin_accent_wii);
+ break;
+
+ case Game.PLATFORM_WII_WARE:
+ holder.cardParent.setTag(R.color.dolphin_accent_wiiware);
+ break;
+
+ default:
+ holder.cardParent.setTag(android.R.color.holo_red_dark);
+ break;
+ }
+ }
+
+ public void onUnbindViewHolder(ViewHolder viewHolder)
+ {
+ // no op
+ }
+
+ public void setCardBackground(ImageCardView view, boolean selected)
+ {
+ int backgroundColor;
+
+ if (selected)
+ {
+ // TODO: 7/20/15 Try using view tag to set color
+ backgroundColor = (int) view.getTag();
+ }
+ 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/adapters/SettingsRowPresenter.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/SettingsRowPresenter.java
new file mode 100644
index 0000000000..beef06a218
--- /dev/null
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/SettingsRowPresenter.java
@@ -0,0 +1,47 @@
+package org.dolphinemu.dolphinemu.adapters;
+
+
+import android.content.res.Resources;
+import android.support.v17.leanback.widget.ImageCardView;
+import android.support.v17.leanback.widget.Presenter;
+import android.view.ViewGroup;
+
+import org.dolphinemu.dolphinemu.model.TvSettingsItem;
+import org.dolphinemu.dolphinemu.viewholders.TvSettingsViewHolder;
+
+public final class SettingsRowPresenter extends Presenter
+{
+ public Presenter.ViewHolder onCreateViewHolder(ViewGroup parent)
+ {
+ // Create a new view.
+ ImageCardView settingsCard = new ImageCardView(parent.getContext());
+
+ settingsCard.setMainImageAdjustViewBounds(true);
+ settingsCard.setMainImageDimensions(192, 160);
+
+
+ settingsCard.setFocusable(true);
+ settingsCard.setFocusableInTouchMode(true);
+
+ // Use that view to create a ViewHolder.
+ return new TvSettingsViewHolder(settingsCard);
+ }
+
+ public void onBindViewHolder(Presenter.ViewHolder viewHolder, Object item)
+ {
+ TvSettingsViewHolder holder = (TvSettingsViewHolder) viewHolder;
+ TvSettingsItem settingsItem = (TvSettingsItem) item;
+
+ Resources resources = holder.cardParent.getResources();
+
+ holder.itemId = settingsItem.getItemId();
+
+ holder.cardParent.setTitleText(resources.getString(settingsItem.getLabelId()));
+ holder.cardParent.setMainImage(resources.getDrawable(settingsItem.getIconId(), null));
+ }
+
+ public void onUnbindViewHolder(Presenter.ViewHolder viewHolder)
+ {
+ // no op
+ }
+} \ No newline at end of file
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..33a9f27c54 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,13 +3,12 @@ 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;
public static final int PLATFORM_WII = 1;
public static final int PLATFORM_WII_WARE = 2;
+ public static final int PLATFORM_ALL = 3;
// Copied from IVolume::ECountry. Update these if that is ever modified.
public static final int COUNTRY_EUROPE = 0;
@@ -33,13 +32,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 +47,7 @@ public final class Game
mPath = path;
mGameId = gameId;
mCompany = company;
- mScreenshotFolderPath = PATH_SCREENSHOT_FOLDER + getGameId() + "/";
+ mScreenshotPath = screenshotPath;
}
public int getPlatform()
@@ -86,27 +85,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 +116,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/model/TvSettingsItem.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/TvSettingsItem.java
new file mode 100644
index 0000000000..ccd87bfa4c
--- /dev/null
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/TvSettingsItem.java
@@ -0,0 +1,31 @@
+package org.dolphinemu.dolphinemu.model;
+
+
+public final class TvSettingsItem
+{
+ private final int mItemId;
+ private final int mIconId;
+ private final int mLabelId;
+
+ public TvSettingsItem(int itemId, int iconId, int labelId)
+ {
+ mItemId = itemId;
+ mIconId = iconId;
+ mLabelId = labelId;
+ }
+
+ public int getItemId()
+ {
+ return mItemId;
+ }
+
+ public int getIconId()
+ {
+ return mIconId;
+ }
+
+ public int getLabelId()
+ {
+ return mLabelId;
+ }
+}
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..d27a671c2f
--- /dev/null
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/viewholders/TvGameViewHolder.java
@@ -0,0 +1,39 @@
+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;
+
+/**
+ * A simple class that stores references to views so that the GameAdapter doesn't need to
+ * keep calling findViewById(), which is expensive.
+ */
+public final class TvGameViewHolder extends Presenter.ViewHolder
+{
+ public ImageCardView cardParent;
+
+ public ImageView imageScreenshot;
+
+ 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 int backgroundColor;
+
+ public TvGameViewHolder(View itemView)
+ {
+ super(itemView);
+
+ itemView.setTag(this);
+
+ cardParent = (ImageCardView) itemView;
+ imageScreenshot = cardParent.getMainImageView();
+ }
+}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/viewholders/TvSettingsViewHolder.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/viewholders/TvSettingsViewHolder.java
new file mode 100644
index 0000000000..3264e93f5b
--- /dev/null
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/viewholders/TvSettingsViewHolder.java
@@ -0,0 +1,23 @@
+package org.dolphinemu.dolphinemu.viewholders;
+
+
+import android.support.v17.leanback.widget.ImageCardView;
+import android.support.v17.leanback.widget.Presenter;
+import android.view.View;
+
+public final class TvSettingsViewHolder extends Presenter.ViewHolder
+{
+ public ImageCardView cardParent;
+
+ // Determines what action to take when this item is clicked.
+ public int itemId;
+
+ public TvSettingsViewHolder(View itemView)
+ {
+ super(itemView);
+
+ itemView.setTag(this);
+
+ cardParent = (ImageCardView) itemView;
+ }
+}