android: Remove obsolete AndroidTV mode and its resources
This commit is contained in:
parent
312dc5e821
commit
ed32bfd28d
@ -7,9 +7,6 @@
|
||||
<uses-feature
|
||||
android:name="android.hardware.gamepad"
|
||||
android:required="false"/>
|
||||
<uses-feature
|
||||
android:name="android.software.leanback"
|
||||
android:required="false"/>
|
||||
|
||||
<uses-feature android:glEsVersion="0x00030001" android:required="true" />
|
||||
|
||||
@ -41,18 +38,6 @@
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:name="org.citra.citra_emu.ui.main.TvMainActivity"
|
||||
android:theme="@style/CitraTv">
|
||||
|
||||
<!-- 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="org.citra.citra_emu.features.settings.ui.SettingsActivity"
|
||||
android:configChanges="orientation|screenSize"
|
||||
|
@ -1,67 +0,0 @@
|
||||
package org.citra.citra_emu.adapters;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import androidx.leanback.widget.ImageCardView;
|
||||
import androidx.leanback.widget.Presenter;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import org.citra.citra_emu.R;
|
||||
import org.citra.citra_emu.model.Game;
|
||||
import org.citra.citra_emu.utils.PicassoUtils;
|
||||
import org.citra.citra_emu.viewholders.TvGameViewHolder;
|
||||
|
||||
/**
|
||||
* The Leanback library / docs call this a Presenter, but it works very
|
||||
* similarly to a RecyclerView.Adapter.
|
||||
*/
|
||||
public final class GameRowPresenter extends Presenter {
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(ViewGroup parent) {
|
||||
// Create a new view.
|
||||
ImageCardView gameCard = new ImageCardView(parent.getContext());
|
||||
|
||||
gameCard.setMainImageAdjustViewBounds(true);
|
||||
gameCard.setMainImageDimensions(48, 48);
|
||||
gameCard.setMainImageScaleType(ImageView.ScaleType.CENTER_CROP);
|
||||
|
||||
gameCard.setFocusable(true);
|
||||
gameCard.setFocusableInTouchMode(true);
|
||||
|
||||
// Use that view to create a ViewHolder.
|
||||
return new TvGameViewHolder(gameCard);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(ViewHolder viewHolder, Object item) {
|
||||
TvGameViewHolder holder = (TvGameViewHolder) viewHolder;
|
||||
Game game = (Game) item;
|
||||
|
||||
holder.imageScreenshot.setImageDrawable(null);
|
||||
PicassoUtils.loadGameBanner(holder.imageScreenshot, game.getPath());
|
||||
|
||||
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();
|
||||
|
||||
// Set the platform-dependent background color of the card
|
||||
Context context = holder.cardParent.getContext();
|
||||
Drawable background = ContextCompat.getDrawable(context, R.drawable.tv_card_background_gamecube);
|
||||
holder.cardParent.setInfoAreaBackground(background);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUnbindViewHolder(ViewHolder viewHolder) {
|
||||
// no op
|
||||
}
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
package org.citra.citra_emu.adapters;
|
||||
|
||||
import android.content.res.Resources;
|
||||
import androidx.leanback.widget.ImageCardView;
|
||||
import androidx.leanback.widget.Presenter;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import org.citra.citra_emu.model.TvSettingsItem;
|
||||
import org.citra.citra_emu.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
|
||||
}
|
||||
}
|
@ -69,11 +69,6 @@ public final class SettingsActivity extends AppCompatActivity implements Setting
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
return mPresenter.handleOptionsItem(item.getItemId());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(@NonNull Bundle outState) {
|
||||
// Critical: If super method is not called, rotations will be busted.
|
||||
|
@ -126,10 +126,6 @@ public final class SettingsActivityPresenter {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean handleOptionsItem(int itemId) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void onSettingChanged() {
|
||||
mShouldSave = true;
|
||||
}
|
||||
|
@ -1,73 +0,0 @@
|
||||
package org.citra.citra_emu.fragments;
|
||||
|
||||
import android.os.Bundle;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import android.util.SparseIntArray;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.citra.citra_emu.R;
|
||||
import org.citra.citra_emu.activities.EmulationActivity;
|
||||
|
||||
public final class MenuFragment extends Fragment implements View.OnClickListener {
|
||||
private static final String KEY_TITLE = "title";
|
||||
private static SparseIntArray buttonsActionsMap = new SparseIntArray();
|
||||
|
||||
static {
|
||||
buttonsActionsMap.append(R.id.menu_emulation_show_fps,
|
||||
EmulationActivity.MENU_ACTION_SHOW_FPS);
|
||||
buttonsActionsMap.append(R.id.menu_exit, EmulationActivity.MENU_ACTION_EXIT);
|
||||
buttonsActionsMap.append(R.id.menu_screen_layout_landscape,
|
||||
EmulationActivity.MENU_ACTION_SCREEN_LAYOUT_LANDSCAPE);
|
||||
buttonsActionsMap.append(R.id.menu_screen_layout_portrait,
|
||||
EmulationActivity.MENU_ACTION_SCREEN_LAYOUT_PORTRAIT);
|
||||
buttonsActionsMap.append(R.id.menu_screen_layout_single,
|
||||
EmulationActivity.MENU_ACTION_SCREEN_LAYOUT_SINGLE);
|
||||
buttonsActionsMap.append(R.id.menu_screen_layout_sidebyside,
|
||||
EmulationActivity.MENU_ACTION_SCREEN_LAYOUT_SIDEBYSIDE);
|
||||
buttonsActionsMap.append(R.id.menu_emulation_swap_screens,
|
||||
EmulationActivity.MENU_ACTION_SWAP_SCREENS);
|
||||
buttonsActionsMap.append(R.id.menu_emulation_show_overlay,
|
||||
EmulationActivity.MENU_ACTION_SHOW_OVERLAY);
|
||||
}
|
||||
|
||||
public static MenuFragment newInstance(String title) {
|
||||
MenuFragment fragment = new MenuFragment();
|
||||
|
||||
Bundle arguments = new Bundle();
|
||||
arguments.putSerializable(KEY_TITLE, title);
|
||||
fragment.setArguments(arguments);
|
||||
|
||||
return fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
View rootView = inflater.inflate(R.layout.fragment_ingame_menu, container, false);
|
||||
|
||||
LinearLayout options = rootView.findViewById(R.id.layout_options);
|
||||
for (int childIndex = 0; childIndex < options.getChildCount(); childIndex++) {
|
||||
Button button = (Button) options.getChildAt(childIndex);
|
||||
|
||||
button.setOnClickListener(this);
|
||||
}
|
||||
|
||||
TextView titleText = rootView.findViewById(R.id.text_game_title);
|
||||
String title = getArguments().getString(KEY_TITLE);
|
||||
if (title != null) {
|
||||
titleText.setText(title);
|
||||
}
|
||||
|
||||
return rootView;
|
||||
}
|
||||
|
||||
@SuppressWarnings("WrongConstant")
|
||||
@Override
|
||||
public void onClick(View button) {
|
||||
}
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
package org.citra.citra_emu.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;
|
||||
}
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
package org.citra.citra_emu.services;
|
||||
|
||||
import android.app.IntentService;
|
||||
import android.content.Intent;
|
||||
|
||||
public final class USBPermService extends IntentService {
|
||||
public USBPermService() {
|
||||
super("USBPermService");
|
||||
}
|
||||
|
||||
// Needed when extending IntentService.
|
||||
// We don't care about the results of the intent handler for this.
|
||||
@Override
|
||||
protected void onHandleIntent(Intent intent) {
|
||||
}
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
/**
|
||||
* Copyright 2013 Dolphin Emulator Project
|
||||
* Licensed under GPLv2+
|
||||
* Refer to the license.txt file included.
|
||||
*/
|
||||
|
||||
package org.citra.citra_emu.ui;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
|
||||
/**
|
||||
* Work around a bug with the nVidia Shield.
|
||||
*
|
||||
* Without this View, the emulation SurfaceView acts like it has the
|
||||
* highest Z-value, blocking any other View, such as the menu fragments.
|
||||
*/
|
||||
public final class NvidiaShieldWorkaroundView extends View {
|
||||
public NvidiaShieldWorkaroundView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
|
||||
// Setting this seems to workaround the bug
|
||||
setWillNotDraw(false);
|
||||
}
|
||||
}
|
@ -1,69 +0,0 @@
|
||||
package org.citra.citra_emu.ui.main;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import androidx.leanback.widget.TitleViewAdapter;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import org.citra.citra_emu.R;
|
||||
|
||||
public class CustomTitleView extends LinearLayout implements TitleViewAdapter.Provider {
|
||||
private final TextView mTitleView;
|
||||
private final View mBadgeView;
|
||||
|
||||
private final TitleViewAdapter mTitleViewAdapter = new TitleViewAdapter() {
|
||||
@Override
|
||||
public View getSearchAffordanceView() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTitle(CharSequence titleText) {
|
||||
CustomTitleView.this.setTitle(titleText);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBadgeDrawable(Drawable drawable) {
|
||||
CustomTitleView.this.setBadgeDrawable(drawable);
|
||||
}
|
||||
};
|
||||
|
||||
public CustomTitleView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public CustomTitleView(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public CustomTitleView(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
View root = LayoutInflater.from(context).inflate(R.layout.tv_title, this);
|
||||
mTitleView = root.findViewById(R.id.title);
|
||||
mBadgeView = root.findViewById(R.id.badge);
|
||||
}
|
||||
|
||||
public void setTitle(CharSequence title) {
|
||||
if (title != null) {
|
||||
mTitleView.setText(title);
|
||||
mTitleView.setVisibility(View.VISIBLE);
|
||||
mBadgeView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
public void setBadgeDrawable(Drawable drawable) {
|
||||
if (drawable != null) {
|
||||
mTitleView.setVisibility(View.GONE);
|
||||
mBadgeView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public TitleViewAdapter getTitleViewAdapter() {
|
||||
return mTitleViewAdapter;
|
||||
}
|
||||
}
|
@ -8,9 +8,6 @@ import org.citra.citra_emu.model.GameDatabase;
|
||||
import org.citra.citra_emu.utils.AddDirectoryHelper;
|
||||
import org.citra.citra_emu.features.settings.utils.SettingsFile;
|
||||
|
||||
import rx.android.schedulers.AndroidSchedulers;
|
||||
import rx.schedulers.Schedulers;
|
||||
|
||||
public final class MainPresenter {
|
||||
public static final int REQUEST_ADD_DIRECTORY = 1;
|
||||
|
||||
@ -27,10 +24,6 @@ public final class MainPresenter {
|
||||
refeshGameList();
|
||||
}
|
||||
|
||||
public void onFabClick() {
|
||||
mView.launchFileListActivity();
|
||||
}
|
||||
|
||||
public boolean handleOptionSelection(int itemId) {
|
||||
switch (itemId) {
|
||||
case R.id.menu_settings_core:
|
||||
@ -57,14 +50,6 @@ public final class MainPresenter {
|
||||
mDirToAdd = dir;
|
||||
}
|
||||
|
||||
public void loadGames() {
|
||||
GameDatabase databaseHelper = CitraApplication.databaseHelper;
|
||||
databaseHelper.getGames()
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(mView::showGames);
|
||||
}
|
||||
|
||||
private void refeshGameList() {
|
||||
GameDatabase databaseHelper = CitraApplication.databaseHelper;
|
||||
databaseHelper.scanLibrary(databaseHelper.getWritableDatabase());
|
||||
|
@ -1,7 +1,5 @@
|
||||
package org.citra.citra_emu.ui.main;
|
||||
|
||||
import android.database.Cursor;
|
||||
|
||||
/**
|
||||
* Abstraction for the screen that shows on application launch.
|
||||
* Implementations will differ primarily to target touch-screen
|
||||
@ -24,12 +22,4 @@ public interface MainView {
|
||||
void launchSettingsActivity(String menuTag);
|
||||
|
||||
void launchFileListActivity();
|
||||
|
||||
/**
|
||||
* To be called when an asynchronous database read completes. Passes the
|
||||
* result, in this case a {@link Cursor} to the view.
|
||||
*
|
||||
* @param games A Cursor containing the games read from the database.
|
||||
*/
|
||||
void showGames(Cursor games);
|
||||
}
|
||||
|
@ -1,223 +0,0 @@
|
||||
package org.citra.citra_emu.ui.main;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.database.Cursor;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.leanback.app.BrowseSupportFragment;
|
||||
import androidx.leanback.database.CursorMapper;
|
||||
import androidx.leanback.widget.ArrayObjectAdapter;
|
||||
import androidx.leanback.widget.CursorObjectAdapter;
|
||||
import androidx.leanback.widget.HeaderItem;
|
||||
import androidx.leanback.widget.ListRow;
|
||||
import androidx.leanback.widget.ListRowPresenter;
|
||||
import androidx.fragment.app.FragmentActivity;
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.citra.citra_emu.R;
|
||||
import org.citra.citra_emu.activities.EmulationActivity;
|
||||
import org.citra.citra_emu.adapters.GameRowPresenter;
|
||||
import org.citra.citra_emu.adapters.SettingsRowPresenter;
|
||||
import org.citra.citra_emu.model.Game;
|
||||
import org.citra.citra_emu.model.TvSettingsItem;
|
||||
import org.citra.citra_emu.utils.DirectoryInitialization;
|
||||
import org.citra.citra_emu.features.settings.ui.SettingsActivity;
|
||||
import org.citra.citra_emu.utils.AddDirectoryHelper;
|
||||
import org.citra.citra_emu.utils.FileBrowserHelper;
|
||||
import org.citra.citra_emu.utils.PermissionsHandler;
|
||||
import org.citra.citra_emu.utils.StartupHandler;
|
||||
import org.citra.citra_emu.viewholders.TvGameViewHolder;
|
||||
|
||||
public final class TvMainActivity extends FragmentActivity implements MainView {
|
||||
private MainPresenter mPresenter = new MainPresenter(this);
|
||||
|
||||
private BrowseSupportFragment mBrowseFragment;
|
||||
|
||||
private ArrayObjectAdapter mRowsAdapter;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_tv_main);
|
||||
|
||||
setupUI();
|
||||
|
||||
mPresenter.onCreate();
|
||||
|
||||
// Stuff in this block only happens when this activity is newly created (i.e. not a rotation)
|
||||
if (savedInstanceState == null)
|
||||
StartupHandler.HandleInit(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
mPresenter.addDirIfNeeded(new AddDirectoryHelper(this));
|
||||
}
|
||||
|
||||
void setupUI() {
|
||||
final FragmentManager fragmentManager = getSupportFragmentManager();
|
||||
mBrowseFragment = new BrowseSupportFragment();
|
||||
fragmentManager
|
||||
.beginTransaction()
|
||||
.add(R.id.content, mBrowseFragment, "BrowseFragment")
|
||||
.commit();
|
||||
|
||||
// Set display parameters for the BrowseFragment
|
||||
mBrowseFragment.setHeadersState(BrowseSupportFragment.HEADERS_ENABLED);
|
||||
mBrowseFragment.setBrandColor(ContextCompat.getColor(this, R.color.citra_orange_dark));
|
||||
buildRowsAdapter();
|
||||
|
||||
mBrowseFragment.setOnItemViewClickedListener(
|
||||
(itemViewHolder, item, rowViewHolder, row) ->
|
||||
{
|
||||
// Special case: user clicked on a settings row item.
|
||||
if (item instanceof TvSettingsItem) {
|
||||
TvSettingsItem settingsItem = (TvSettingsItem) item;
|
||||
mPresenter.handleOptionSelection(settingsItem.getItemId());
|
||||
} else {
|
||||
TvGameViewHolder holder = (TvGameViewHolder) itemViewHolder;
|
||||
|
||||
// Start the emulation activity and send the path of the clicked ISO to it.
|
||||
EmulationActivity.launch(TvMainActivity.this, holder.path, holder.title);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* MainView
|
||||
*/
|
||||
|
||||
@Override
|
||||
public void setVersionString(String version) {
|
||||
mBrowseFragment.setTitle(version);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refresh() {
|
||||
recreate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void launchSettingsActivity(String menuTag) {
|
||||
SettingsActivity.launch(this, menuTag, "");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void launchFileListActivity() {
|
||||
FileBrowserHelper.openDirectoryPicker(this, MainPresenter.REQUEST_ADD_DIRECTORY,
|
||||
R.string.select_game_folder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showGames(Cursor games) {
|
||||
ListRow row = buildGamesRow(games);
|
||||
|
||||
// Add row to the adapter only if it is not empty.
|
||||
if (row != null) {
|
||||
mRowsAdapter.add(games);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 MainPresenter.REQUEST_ADD_DIRECTORY:
|
||||
// If the user picked a file, as opposed to just backing out.
|
||||
if (resultCode == MainActivity.RESULT_OK) {
|
||||
mPresenter.onDirectorySelected(FileBrowserHelper.getSelectedDirectory(result));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||
switch (requestCode) {
|
||||
case PermissionsHandler.REQUEST_CODE_WRITE_PERMISSION:
|
||||
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
DirectoryInitialization.start(this);
|
||||
loadGames();
|
||||
} else {
|
||||
Toast.makeText(this, R.string.write_permission_needed, Toast.LENGTH_SHORT)
|
||||
.show();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void buildRowsAdapter() {
|
||||
mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());
|
||||
|
||||
if (PermissionsHandler.hasWriteAccess(this)) {
|
||||
loadGames();
|
||||
}
|
||||
|
||||
mRowsAdapter.add(buildSettingsRow());
|
||||
|
||||
mBrowseFragment.setAdapter(mRowsAdapter);
|
||||
}
|
||||
|
||||
private void loadGames() {
|
||||
mPresenter.loadGames();
|
||||
}
|
||||
|
||||
private ListRow buildGamesRow(Cursor games) {
|
||||
// Create an adapter for this row.
|
||||
CursorObjectAdapter row = new CursorObjectAdapter(new GameRowPresenter());
|
||||
|
||||
// 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);
|
||||
}
|
||||
});
|
||||
|
||||
// Create the row, passing it the filled adapter and the header, and give it to the master adapter.
|
||||
return new ListRow(null, row);
|
||||
}
|
||||
|
||||
private ListRow buildSettingsRow() {
|
||||
ArrayObjectAdapter rowItems = new ArrayObjectAdapter(new SettingsRowPresenter());
|
||||
|
||||
rowItems.add(new TvSettingsItem(R.id.menu_settings_core,
|
||||
R.drawable.ic_settings_core_tv,
|
||||
R.string.grid_menu_core_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.preferences_settings, getString(R.string.preferences_settings));
|
||||
|
||||
return new ListRow(header, rowItems);
|
||||
}
|
||||
}
|
@ -3,7 +3,6 @@ package org.citra.citra_emu.ui.platform;
|
||||
import android.database.Cursor;
|
||||
import android.os.Bundle;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
|
||||
import androidx.recyclerview.widget.GridLayoutManager;
|
||||
@ -60,11 +59,6 @@ public final class PlatformGamesFragment extends Fragment implements PlatformGam
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshScreenshotAtPosition(int position) {
|
||||
mAdapter.notifyItemChanged(position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refresh() {
|
||||
mPresenter.refresh();
|
||||
|
@ -11,14 +11,6 @@ public interface PlatformGamesView {
|
||||
*/
|
||||
void refresh();
|
||||
|
||||
/**
|
||||
* Tell the view that a certain game's screenshot has been updated,
|
||||
* and should be redrawn on-screen.
|
||||
*
|
||||
* @param position The index of the game that should be redrawn.
|
||||
*/
|
||||
void refreshScreenshotAtPosition(int position);
|
||||
|
||||
/**
|
||||
* To be called when an asynchronous database read completes. Passes the
|
||||
* result, in this case a {@link Cursor}, to the view.
|
||||
|
@ -1,25 +0,0 @@
|
||||
package org.citra.citra_emu.utils;
|
||||
|
||||
import android.view.View;
|
||||
import android.view.ViewPropertyAnimator;
|
||||
|
||||
public final class Animations {
|
||||
private Animations() {
|
||||
}
|
||||
|
||||
public static ViewPropertyAnimator fadeViewIn(View view) {
|
||||
view.setVisibility(View.VISIBLE);
|
||||
|
||||
return view.animate()
|
||||
.withLayer()
|
||||
.setDuration(100)
|
||||
.alpha(1.0f);
|
||||
}
|
||||
|
||||
public static ViewPropertyAnimator fadeViewOut(View view) {
|
||||
return view.animate()
|
||||
.withLayer()
|
||||
.setDuration(300)
|
||||
.alpha(0.0f);
|
||||
}
|
||||
}
|
@ -1,353 +0,0 @@
|
||||
/**
|
||||
* Copyright 2013 Dolphin Emulator Project
|
||||
* Licensed under GPLv2+
|
||||
* Refer to the license.txt file included.
|
||||
*/
|
||||
|
||||
package org.citra.citra_emu.utils;
|
||||
|
||||
import android.opengl.GLES30;
|
||||
|
||||
import org.citra.citra_emu.NativeLibrary;
|
||||
|
||||
import javax.microedition.khronos.egl.EGL10;
|
||||
import javax.microedition.khronos.egl.EGLConfig;
|
||||
import javax.microedition.khronos.egl.EGLContext;
|
||||
import javax.microedition.khronos.egl.EGLDisplay;
|
||||
import javax.microedition.khronos.egl.EGLSurface;
|
||||
import javax.microedition.khronos.opengles.GL10;
|
||||
|
||||
/**
|
||||
* Utility class that abstracts all the stuff about
|
||||
* EGL initialization out of the way if all that is
|
||||
* wanted is to query the underlying GL API for information.
|
||||
*/
|
||||
public final class EGLHelper {
|
||||
// Renderable type bitmasks
|
||||
public static final int EGL_OPENGL_ES_BIT = 0x0001;
|
||||
public static final int EGL_OPENGL_ES2_BIT = 0x0004;
|
||||
public static final int EGL_OPENGL_BIT = 0x0008;
|
||||
public static final int EGL_OPENGL_ES3_BIT_KHR = 0x0040;
|
||||
// API types
|
||||
public static final int EGL_OPENGL_ES_API = 0x30A0;
|
||||
public static final int EGL_OPENGL_API = 0x30A2;
|
||||
private final EGL10 mEGL;
|
||||
private final EGLDisplay mDisplay;
|
||||
private EGLConfig[] mEGLConfigs;
|
||||
private EGLContext mEGLContext;
|
||||
private EGLSurface mEGLSurface;
|
||||
private GL10 mGL;
|
||||
// GL support flags
|
||||
private boolean supportGL;
|
||||
private boolean supportGLES2;
|
||||
private boolean supportGLES3;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* <p>
|
||||
* Initializes the underlying {@link EGLSurface} with a width and height of 1.
|
||||
* This is useful if all you need to use this class for is to query information
|
||||
* from specific API contexts.
|
||||
*
|
||||
* @param renderableType Bitmask indicating which types of client API contexts
|
||||
* the framebuffer config must support.
|
||||
*/
|
||||
public EGLHelper(int renderableType) {
|
||||
this(1, 1, renderableType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param width Width of the underlying {@link EGLSurface}.
|
||||
* @param height Height of the underlying {@link EGLSurface}.
|
||||
* @param renderableType Bitmask indicating which types of client API contexts
|
||||
* the framebuffer config must support.
|
||||
*/
|
||||
public EGLHelper(int width, int height, int renderableType) {
|
||||
// Initialize handle to an EGL display.
|
||||
mEGL = (EGL10) EGLContext.getEGL();
|
||||
mDisplay = mEGL.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
|
||||
|
||||
// If a display is present, initialize EGL.
|
||||
if (mDisplay != EGL10.EGL_NO_DISPLAY) {
|
||||
int[] version = new int[2];
|
||||
if (mEGL.eglInitialize(mDisplay, version)) {
|
||||
// Detect supported GL APIs, initialize configs, etc.
|
||||
detect();
|
||||
|
||||
// Create context and surface
|
||||
create(width, height, renderableType);
|
||||
} else {
|
||||
Log.error("[EGLHelper] Error initializing EGL.");
|
||||
}
|
||||
} else {
|
||||
Log.error("[EGLHelper] Error initializing EGL display.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Releases all resources associated with this helper.
|
||||
* <p>
|
||||
* This should be called whenever this helper is no longer needed.
|
||||
*/
|
||||
public void closeHelper() {
|
||||
mEGL.eglTerminate(mDisplay);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets information through EGL.<br/>
|
||||
* <p>
|
||||
* Index 0: Vendor <br/>
|
||||
* Index 1: Version <br/>
|
||||
* Index 2: Renderer <br/>
|
||||
* Index 3: Extensions <br/>
|
||||
*
|
||||
* @return information retrieved through EGL.
|
||||
*/
|
||||
public String[] getEGLInfo() {
|
||||
return new String[]{
|
||||
mGL.glGetString(GL10.GL_VENDOR),
|
||||
mGL.glGetString(GL10.GL_VERSION),
|
||||
mGL.glGetString(GL10.GL_RENDERER),
|
||||
mGL.glGetString(GL10.GL_EXTENSIONS),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not this device supports OpenGL.
|
||||
*
|
||||
* @return true if this device supports OpenGL; false otherwise.
|
||||
*/
|
||||
public boolean supportsOpenGL() {
|
||||
return supportGL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not this device supports OpenGL ES 2.
|
||||
* <br/>
|
||||
* Note that if this returns true, then OpenGL ES 1 is also supported.
|
||||
*
|
||||
* @return true if this device supports OpenGL ES 2; false otherwise.
|
||||
*/
|
||||
public boolean supportsGLES2() {
|
||||
return supportGLES2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not this device supports OpenGL ES 3.
|
||||
* <br/>
|
||||
* Note that if this returns true, then OpenGL ES 1 and 2 are also supported.
|
||||
*
|
||||
* @return true if this device supports OpenGL ES 3; false otherwise.
|
||||
*/
|
||||
public boolean supportsGLES3() {
|
||||
return supportGLES3;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the underlying {@link EGL10} instance.
|
||||
*
|
||||
* @return the underlying {@link EGL10} instance.
|
||||
*/
|
||||
public EGL10 getEGL() {
|
||||
return mEGL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the underlying {@link GL10} instance.
|
||||
*
|
||||
* @return the underlying {@link GL10} instance.
|
||||
*/
|
||||
public GL10 getGL() {
|
||||
return mGL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the underlying {@link EGLDisplay}.
|
||||
*
|
||||
* @return the underlying {@link EGLDisplay}
|
||||
*/
|
||||
public EGLDisplay getDisplay() {
|
||||
return mDisplay;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all supported framebuffer configurations for this device.
|
||||
*
|
||||
* @return all supported framebuffer configurations for this device.
|
||||
*/
|
||||
public EGLConfig[] getConfigs() {
|
||||
return mEGLConfigs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the underlying {@link EGLContext}.
|
||||
*
|
||||
* @return the underlying {@link EGLContext}.
|
||||
*/
|
||||
public EGLContext getContext() {
|
||||
return mEGLContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the underlying {@link EGLSurface}.
|
||||
*
|
||||
* @return the underlying {@link EGLSurface}.
|
||||
*/
|
||||
public EGLSurface getSurface() {
|
||||
return mEGLSurface;
|
||||
}
|
||||
|
||||
// Detects the specific kind of GL modes that are supported
|
||||
private boolean detect() {
|
||||
// Get total number of configs available.
|
||||
int[] numConfigs = new int[1];
|
||||
if (!mEGL.eglGetConfigs(mDisplay, null, 0, numConfigs)) {
|
||||
Log.error("[EGLHelper] Error retrieving number of EGL configs available.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Now get all the configurations
|
||||
mEGLConfigs = new EGLConfig[numConfigs[0]];
|
||||
if (!mEGL.eglGetConfigs(mDisplay, mEGLConfigs, mEGLConfigs.length, numConfigs)) {
|
||||
Log.error("[EGLHelper] Error retrieving all EGL configs.");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (EGLConfig mEGLConfig : mEGLConfigs) {
|
||||
int[] attribVal = new int[1];
|
||||
boolean ret =
|
||||
mEGL.eglGetConfigAttrib(mDisplay, mEGLConfig, EGL10.EGL_RENDERABLE_TYPE, attribVal);
|
||||
if (ret) {
|
||||
if ((attribVal[0] & EGL_OPENGL_BIT) != 0)
|
||||
supportGL = true;
|
||||
|
||||
if ((attribVal[0] & EGL_OPENGL_ES2_BIT) != 0)
|
||||
supportGLES2 = true;
|
||||
|
||||
if ((attribVal[0] & EGL_OPENGL_ES3_BIT_KHR) != 0)
|
||||
supportGLES3 = true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Creates the context and surface.
|
||||
private void create(int width, int height, int renderableType) {
|
||||
int[] attribs = {
|
||||
EGL10.EGL_WIDTH, width,
|
||||
EGL10.EGL_HEIGHT, height,
|
||||
EGL10.EGL_NONE
|
||||
};
|
||||
|
||||
// Initially we just assume GLES2 will be the default context.
|
||||
int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
|
||||
int[] ctx_attribs = {
|
||||
EGL_CONTEXT_CLIENT_VERSION, 2,
|
||||
EGL10.EGL_NONE
|
||||
};
|
||||
|
||||
// Determine the type of context that will be created
|
||||
// and change the attribute arrays accordingly.
|
||||
switch (renderableType) {
|
||||
case EGL_OPENGL_ES_BIT:
|
||||
ctx_attribs[1] = 1;
|
||||
break;
|
||||
|
||||
case EGL_OPENGL_BIT:
|
||||
ctx_attribs[0] = EGL10.EGL_NONE;
|
||||
break;
|
||||
|
||||
case EGL_OPENGL_ES3_BIT_KHR:
|
||||
ctx_attribs[1] = 3;
|
||||
break;
|
||||
|
||||
case EGL_OPENGL_ES2_BIT:
|
||||
default: // Fall-back to GLES 2.
|
||||
ctx_attribs[1] = 2;
|
||||
break;
|
||||
}
|
||||
if (renderableType == EGL_OPENGL_BIT)
|
||||
NativeLibrary.eglBindAPI(EGL_OPENGL_API);
|
||||
else
|
||||
NativeLibrary.eglBindAPI(EGL_OPENGL_ES_API);
|
||||
|
||||
mEGLContext =
|
||||
mEGL.eglCreateContext(mDisplay, mEGLConfigs[0], EGL10.EGL_NO_CONTEXT, ctx_attribs);
|
||||
mEGLSurface = mEGL.eglCreatePbufferSurface(mDisplay, mEGLConfigs[0], attribs);
|
||||
mEGL.eglMakeCurrent(mDisplay, mEGLSurface, mEGLSurface, mEGLContext);
|
||||
mGL = (GL10) mEGLContext.getGL();
|
||||
}
|
||||
|
||||
/**
|
||||
* Simplified call to {@link GL10#glGetString(int)}
|
||||
* <p>
|
||||
* Accepts the following constants:
|
||||
* <ul>
|
||||
* <li>GL_VENDOR - Company responsible for the GL implementation.</li>
|
||||
* <li>GL_VERSION - Version or release number.</li>
|
||||
* <li>GL_RENDERER - Name of the renderer</li>
|
||||
* <li>GL_SHADING_LANGUAGE_VERSION - Version or release number of the shading language </li>
|
||||
* </ul>
|
||||
*
|
||||
* @param glEnum A symbolic constant within {@link GL10}.
|
||||
* @return the string information represented by {@code glEnum}.
|
||||
*/
|
||||
public String glGetString(int glEnum) {
|
||||
return mGL.glGetString(glEnum);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simplified call to {@link GLES30#glGetStringi(int, int)}
|
||||
* <p>
|
||||
* Accepts the following constants:
|
||||
* <ul>
|
||||
* <li>GL_VENDOR - Company responsible for the GL implementation.</li>
|
||||
* <li>GL_VERSION - Version or release number.</li>
|
||||
* <li>GL_RENDERER - Name of the renderer</li>
|
||||
* <li>GL_SHADING_LANGUAGE_VERSION - Version or release number of the shading language </li>
|
||||
* <li>GL_EXTENSIONS - Extension string supported by the implementation at {@code index}.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param glEnum A symbolic GL constant
|
||||
* @param index The index of the string to return.
|
||||
* @return the string information represented by {@code glEnum} and {@code index}.
|
||||
*/
|
||||
public String glGetStringi(int glEnum, int index) {
|
||||
return GLES30.glGetStringi(glEnum, index);
|
||||
}
|
||||
|
||||
public boolean SupportsExtension(String extension) {
|
||||
int[] num_ext = new int[1];
|
||||
GLES30.glGetIntegerv(GLES30.GL_NUM_EXTENSIONS, num_ext, 0);
|
||||
|
||||
for (int i = 0; i < num_ext[0]; ++i) {
|
||||
String ext = GLES30.glGetStringi(GLES30.GL_EXTENSIONS, i);
|
||||
if (ext.equals(extension))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public int GetVersion() {
|
||||
int[] major = new int[1];
|
||||
int[] minor = new int[1];
|
||||
GLES30.glGetIntegerv(GLES30.GL_MAJOR_VERSION, major, 0);
|
||||
GLES30.glGetIntegerv(GLES30.GL_MINOR_VERSION, minor, 0);
|
||||
return major[0] * 100 + minor[0] * 10;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simplified call to {@link GL10#glGetIntegerv(int, int[], int)
|
||||
*
|
||||
* @param glEnum A symbolic GL constant.
|
||||
* @return the integer information represented by {@code glEnum}.
|
||||
*/
|
||||
public int glGetInteger(int glEnum) {
|
||||
int[] val = new int[1];
|
||||
mGL.glGetIntegerv(glEnum, val, 0);
|
||||
return val[0];
|
||||
}
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
package org.citra.citra_emu.viewholders;
|
||||
|
||||
import androidx.leanback.widget.ImageCardView;
|
||||
import androidx.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 TvGameViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
|
||||
itemView.setTag(this);
|
||||
|
||||
cardParent = (ImageCardView) itemView;
|
||||
imageScreenshot = cardParent.getMainImageView();
|
||||
}
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
package org.citra.citra_emu.viewholders;
|
||||
|
||||
import androidx.leanback.widget.ImageCardView;
|
||||
import androidx.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;
|
||||
}
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<objectAnimator
|
||||
android:propertyName="translationX"
|
||||
android:valueType="floatType"
|
||||
android:valueFrom="-1280dp"
|
||||
android:valueTo="0"
|
||||
android:interpolator="@android:interpolator/decelerate_quad"
|
||||
android:duration="300"/>
|
||||
|
||||
<objectAnimator
|
||||
android:propertyName="alpha"
|
||||
android:valueType="floatType"
|
||||
android:valueFrom="0"
|
||||
android:valueTo="1"
|
||||
android:interpolator="@android:interpolator/accelerate_quad"
|
||||
android:duration="300"/>
|
||||
|
||||
</set>
|
@ -1,21 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<!-- This animation is used ONLY when a submenu is replaced. -->
|
||||
<objectAnimator
|
||||
android:propertyName="translationX"
|
||||
android:valueType="floatType"
|
||||
android:valueFrom="0"
|
||||
android:valueTo="-1280dp"
|
||||
android:interpolator="@android:interpolator/decelerate_quad"
|
||||
android:duration="200"/>
|
||||
|
||||
<objectAnimator
|
||||
android:propertyName="alpha"
|
||||
android:valueType="floatType"
|
||||
android:valueFrom="1"
|
||||
android:valueTo="0"
|
||||
android:interpolator="@android:interpolator/decelerate_quad"
|
||||
android:duration="200"/>
|
||||
|
||||
</set>
|
Binary file not shown.
Before Width: | Height: | Size: 1.7 KiB |
Binary file not shown.
Before Width: | Height: | Size: 318 B |
@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item
|
||||
android:state_selected="true"
|
||||
android:drawable="@color/citra_accent" />
|
||||
<item
|
||||
android:drawable="@color/tv_card_unselected" />
|
||||
</selector>
|
@ -1,39 +0,0 @@
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:keepScreenOn="true"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/frame_content">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/frame_emulation_fragment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
|
||||
<org.citra.citra_emu.ui.NvidiaShieldWorkaroundView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/image_screenshot"
|
||||
android:transitionName="image_game_screenshot"/>
|
||||
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal"
|
||||
android:baselineAligned="false">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/frame_menu"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight=".25"
|
||||
tools:layout="@layout/fragment_ingame_menu"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</FrameLayout>
|
@ -1,7 +0,0 @@
|
||||
<SurfaceView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/surface_emulation"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="match_parent"
|
||||
android:focusable="false"
|
||||
android:focusableInTouchMode="false"
|
||||
/>
|
@ -1,7 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
</FrameLayout>
|
@ -1,44 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/citra_orange_dark"
|
||||
tools:layout_width="250dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/text_game_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
tools:text="The Legend of Zelda: The Wind Waker"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="20sp"
|
||||
android:layout_margin="32dp"/>
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_options"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<Button
|
||||
android:id="@+id/menu_take_screenshot"
|
||||
android:text="@string/emulation_screenshot"
|
||||
style="@style/InGameMenuOption"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/menu_exit"
|
||||
android:text="@string/emulation_exit"
|
||||
style="@style/InGameMenuOption"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
||||
|
||||
</LinearLayout>
|
@ -1,7 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<org.citra.citra_emu.ui.main.CustomTitleView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/browse_title_group"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="16dp"/>
|
@ -1,31 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.leanback.widget.TitleView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<TextView
|
||||
android:visibility="gone"
|
||||
android:layout_alignTop="@+id/badge"
|
||||
android:layout_alignBottom="@+id/badge"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:id="@+id/title"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"/>
|
||||
|
||||
<ImageView
|
||||
android:visibility="gone"
|
||||
android:layout_toStartOf="@id/title"
|
||||
android:id="@+id/badge"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@mipmap/ic_launcher"/>
|
||||
|
||||
</RelativeLayout>
|
||||
</androidx.leanback.widget.TitleView>
|
@ -97,8 +97,6 @@
|
||||
<string name="loader_error_invalid_format">Invalid ROM format</string>
|
||||
|
||||
<!-- Emulation Menu -->
|
||||
<string name="emulation_screenshot">Take Screenshot</string>
|
||||
<string name="emulation_exit">Exit</string>
|
||||
<string name="emulation_show_fps">Show FPS</string>
|
||||
<string name="emulation_configure_controls">Configure Controls</string>
|
||||
<string name="emulation_edit_layout">Edit Layout</string>
|
||||
|
@ -52,55 +52,6 @@
|
||||
<item name="colorAccent">@color/citra_accent</item>
|
||||
</style>
|
||||
|
||||
<style name="CitraEmulationTvBase" parent="Theme.MaterialComponents.DayNight.NoActionBar">
|
||||
<item name="colorPrimary">@color/citra_orange</item>
|
||||
<item name="colorPrimaryDark">@color/citra_orange_dark</item>
|
||||
<item name="android:windowTranslucentNavigation">true</item>
|
||||
|
||||
<item name="android:windowBackground">@android:color/black</item>
|
||||
|
||||
<!-- Enable window content transitions -->
|
||||
<item name="android:windowContentTransitions">true</item>
|
||||
<item name="android:windowAllowEnterTransitionOverlap">true</item>
|
||||
<item name="android:windowAllowReturnTransitionOverlap">true</item>
|
||||
</style>
|
||||
|
||||
<!-- Inherit from the Base Citra Emulation Theme -->
|
||||
<style name="CitraEmulationTv" parent="CitraEmulationTvBase">
|
||||
<item name="colorAccent">@color/citra_accent</item>
|
||||
</style>
|
||||
|
||||
<!-- Hax to make Tablayout render icons -->
|
||||
|
||||
<!-- Android TV Themes -->
|
||||
<style name="CitraTvBase" parent="Theme.Leanback.Browse">
|
||||
<item name="colorPrimary">@color/citra_orange</item>
|
||||
<item name="colorPrimaryDark">@color/citra_orange_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="CitraTv" parent="CitraTvBase">
|
||||
<item name="colorAccent">@color/citra_accent</item>
|
||||
<item name="browseTitleViewLayout">@layout/titleview</item>
|
||||
</style>
|
||||
|
||||
<style name="InGameMenuOption" parent="Widget.AppCompat.Button.Borderless">
|
||||
<item name="android:textSize">16sp</item>
|
||||
<item name="android:fontFamily">sans-serif-condensed</item>
|
||||
<item name="android:textColor">@android:color/white</item>
|
||||
<item name="android:textAllCaps">false</item>
|
||||
<item name="android:layout_width">match_parent</item>
|
||||
<item name="android:layout_height">48dp</item>
|
||||
<item name="android:gravity">center_vertical|left</item>
|
||||
<item name="android:paddingLeft">32dp</item>
|
||||
<item name="android:paddingRight">32dp</item>
|
||||
<item name="android:layout_margin">0dp</item>
|
||||
</style>
|
||||
|
||||
<!-- Inherit from a base file picker theme that handles day/night -->
|
||||
<style name="FilePickerTheme" parent="FilePickerBaseTheme">
|
||||
<item name="colorPrimary">@color/citra_orange</item>
|
||||
|
Loading…
x
Reference in New Issue
Block a user