Merge pull request #2758 from sigmabeta/android-tv-game-picker
Android TV: Implement new UI for Main Activity.
This commit is contained in:
commit
0ba970008f
|
@ -1,7 +1,8 @@
|
|||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
compileSdkVersion 21
|
||||
// Leanback support requires >22
|
||||
compileSdkVersion 22
|
||||
buildToolsVersion "22.0.1"
|
||||
|
||||
lintOptions {
|
||||
|
@ -80,6 +81,9 @@ dependencies {
|
|||
compile 'com.android.support:recyclerview-v7:22.2.0'
|
||||
compile 'com.android.support:design:22.2.0'
|
||||
|
||||
// Android TV UI libraries.
|
||||
compile 'com.android.support:leanback-v17:22.2.0'
|
||||
|
||||
// For showing the banner as a circle a-la Material Design Guidelines
|
||||
compile 'de.hdodenhof:circleimageview:1.2.2'
|
||||
|
||||
|
|
|
@ -33,11 +33,22 @@
|
|||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
|
||||
<category android:name="android.intent.category.LEANBACK_LAUNCHER"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".activities.TvMainActivity"
|
||||
android:theme="@style/DolphinTvGamecube">
|
||||
|
||||
<!-- This intentfilter marks this Activity as the one that gets launched from Home screen. -->
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
|
||||
<category android:name="android.intent.category.LEANBACK_LAUNCHER"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".activities.AddDirectoryActivity"
|
||||
android:theme="@style/DolphinGamecube"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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));
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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()
|
||||
public String getScreenshotPath()
|
||||
{
|
||||
return mScreenshotFolderPath;
|
||||
}
|
||||
|
||||
public String getScreenPath()
|
||||
{
|
||||
// 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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 1.7 KiB |
Binary file not shown.
After Width: | Height: | Size: 1.9 KiB |
Binary file not shown.
After Width: | Height: | Size: 2.2 KiB |
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<fragment
|
||||
android:name="android.support.v17.leanback.app.BrowseFragment"
|
||||
android:id="@+id/fragment_game_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
/>
|
||||
|
||||
</FrameLayout>
|
|
@ -33,7 +33,6 @@
|
|||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_toStartOf="@+id/button_details"
|
||||
android:ellipsize="end"
|
||||
android:lines="1"
|
||||
android:maxLines="1"
|
||||
|
|
|
@ -8,4 +8,6 @@
|
|||
<color name="dolphin_accent_gamecube">#651fff</color>
|
||||
|
||||
<color name="circle_grey">#bdbdbd</color>
|
||||
|
||||
<color name="tv_card_unselected">#444444</color>
|
||||
</resources>
|
|
@ -126,6 +126,21 @@
|
|||
<item name="textAllCaps">false</item>
|
||||
</style>
|
||||
|
||||
<!-- Android TV Themes -->
|
||||
<style name="DolphinTvBase" parent="Theme.Leanback">
|
||||
<item name="colorPrimary">@color/dolphin_blue</item>
|
||||
<item name="colorPrimaryDark">@color/dolphin_blue_dark</item>
|
||||
|
||||
<!--enable window content transitions-->
|
||||
<item name="android:windowContentTransitions">true</item>
|
||||
<item name="android:windowAllowEnterTransitionOverlap">true</item>
|
||||
<item name="android:windowAllowReturnTransitionOverlap">true</item>
|
||||
</style>
|
||||
|
||||
<style name="DolphinTvGamecube" parent="DolphinTvBase">
|
||||
<item name="colorAccent">@color/dolphin_accent_gamecube</item>
|
||||
</style>
|
||||
|
||||
<style name="InGameMenuOption" parent="Widget.AppCompat.Button.Borderless">
|
||||
<item name="android:textSize">16sp</item>
|
||||
<item name="android:fontFamily">sans-serif-condensed</item>
|
||||
|
|
Loading…
Reference in New Issue