@@ -11,21 +11,19 @@
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

import org.dolphinemu.dolphinemu.NativeLibrary;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.activities.EmulationActivity;
import org.dolphinemu.dolphinemu.databinding.FragmentIngameMenuBinding;
import org.dolphinemu.dolphinemu.features.settings.model.BooleanSetting;

public final class MenuFragment extends Fragment implements View.OnClickListener
{
private TextView mTitleText;
private View mPauseEmulation;
private View mUnpauseEmulation;

private static final String KEY_TITLE = "title";
private static final String KEY_WII = "wii";
private static SparseIntArray buttonsActionsMap = new SparseIntArray();
@@ -53,6 +51,8 @@ public final class MenuFragment extends Fragment implements View.OnClickListener
buttonsActionsMap.append(R.id.menu_settings, EmulationActivity.MENU_ACTION_SETTINGS);
}

private FragmentIngameMenuBinding mBinding;

public static MenuFragment newInstance()
{
MenuFragment fragment = new MenuFragment();
@@ -76,26 +76,28 @@ private int getBottomPaddingRequired()
return visibleFrame.bottom - visibleFrame.top - getResources().getDisplayMetrics().heightPixels;
}

@NonNull
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
public View onCreateView(@NonNull 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);

mPauseEmulation = options.findViewById(R.id.menu_pause_emulation);
mUnpauseEmulation = options.findViewById(R.id.menu_unpause_emulation);
mBinding = FragmentIngameMenuBinding.inflate(inflater, container, false);
return mBinding.getRoot();
}

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState)
{
updatePauseUnpauseVisibility();

if (!requireActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN))
{
options.findViewById(R.id.menu_overlay_controls).setVisibility(View.GONE);
mBinding.menuOverlayControls.setVisibility(View.GONE);
}

if (!getArguments().getBoolean(KEY_WII, true))
{
options.findViewById(R.id.menu_refresh_wiimotes).setVisibility(View.GONE);
mBinding.menuRefreshWiimotes.setVisibility(View.GONE);
}

int bottomPaddingRequired = getBottomPaddingRequired();
@@ -107,49 +109,45 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa
bottomPaddingRequired += 32 * density;
}

if (bottomPaddingRequired > rootView.getPaddingBottom())
if (bottomPaddingRequired > view.getPaddingBottom())
{
rootView.setPadding(rootView.getPaddingLeft(), rootView.getPaddingTop(),
rootView.getPaddingRight(), bottomPaddingRequired);
view.setPadding(view.getPaddingLeft(), view.getPaddingTop(),
view.getPaddingRight(), bottomPaddingRequired);
}

LinearLayout options = mBinding.layoutOptions;
for (int childIndex = 0; childIndex < options.getChildCount(); childIndex++)
{
Button button = (Button) options.getChildAt(childIndex);

button.setOnClickListener(this);
}

rootView.findViewById(R.id.menu_exit).setOnClickListener(this);
mBinding.menuExit.setOnClickListener(this);

mTitleText = rootView.findViewById(R.id.text_game_title);
String title = getArguments().getString(KEY_TITLE, null);
if (title != null)
{
mTitleText.setText(title);
mBinding.textGameTitle.setText(title);
}

if (getResources().getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_LTR)
{
rootView.post(() -> NativeLibrary.SetObscuredPixelsLeft(rootView.getWidth()));
view.post(() -> NativeLibrary.SetObscuredPixelsLeft(view.getWidth()));
}

return rootView;
}

@Override
public void onResume()
{
super.onResume();

LinearLayout options = requireView().findViewById(R.id.layout_options);

boolean savestatesEnabled = BooleanSetting.MAIN_ENABLE_SAVESTATES.getBooleanGlobal();
int savestateVisibility = savestatesEnabled ? View.VISIBLE : View.GONE;
options.findViewById(R.id.menu_quicksave).setVisibility(savestateVisibility);
options.findViewById(R.id.menu_quickload).setVisibility(savestateVisibility);
options.findViewById(R.id.menu_emulation_save_root).setVisibility(savestateVisibility);
options.findViewById(R.id.menu_emulation_load_root).setVisibility(savestateVisibility);
mBinding.menuQuicksave.setVisibility(savestateVisibility);
mBinding.menuQuickload.setVisibility(savestateVisibility);
mBinding.menuEmulationSaveRoot.setVisibility(savestateVisibility);
mBinding.menuEmulationLoadRoot.setVisibility(savestateVisibility);
}

@Override
@@ -158,14 +156,15 @@ public void onDestroyView()
super.onDestroyView();

NativeLibrary.SetObscuredPixelsLeft(0);
mBinding = null;
}

private void updatePauseUnpauseVisibility()
{
boolean paused = EmulationActivity.getHasUserPausedEmulation();

mUnpauseEmulation.setVisibility(paused ? View.VISIBLE : View.GONE);
mPauseEmulation.setVisibility(paused ? View.GONE : View.VISIBLE);
mBinding.menuUnpauseEmulation.setVisibility(paused ? View.VISIBLE : View.GONE);
mBinding.menuPauseEmulation.setVisibility(paused ? View.GONE : View.VISIBLE);
}

@Override
@@ -178,7 +177,7 @@ public void onClick(View button)
{
// We could use the button parameter as the anchor here, but this often results in a tiny menu
// (because the button often is in the middle of the screen), so let's use mTitleText instead
activity.showOverlayControlsMenu(mTitleText);
activity.showOverlayControlsMenu(mBinding.textGameTitle);
}
else if (action >= 0)
{
@@ -11,12 +11,14 @@
import android.widget.Button;
import android.widget.GridLayout;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

import org.dolphinemu.dolphinemu.NativeLibrary;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.activities.EmulationActivity;
import org.dolphinemu.dolphinemu.databinding.FragmentSaveloadStateBinding;

public final class SaveLoadStateFragment extends Fragment implements View.OnClickListener
{
@@ -59,6 +61,8 @@ public final class SaveLoadStateFragment extends Fragment implements View.OnClic

private SaveOrLoad mSaveOrLoad;

private FragmentSaveloadStateBinding mBinding;

public static SaveLoadStateFragment newInstance(SaveOrLoad saveOrLoad)
{
SaveLoadStateFragment fragment = new SaveLoadStateFragment();
@@ -78,12 +82,19 @@ public void onCreate(@Nullable Bundle savedInstanceState)
mSaveOrLoad = (SaveOrLoad) getArguments().getSerializable(KEY_SAVEORLOAD);
}

@NonNull
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
View rootView = inflater.inflate(R.layout.fragment_saveload_state, container, false);
mBinding = FragmentSaveloadStateBinding.inflate(inflater, container, false);
return mBinding.getRoot();
}

GridLayout grid = rootView.findViewById(R.id.grid_state_slots);
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState)
{
GridLayout grid = mBinding.gridStateSlots;
for (int childIndex = 0; childIndex < grid.getChildCount(); childIndex++)
{
Button button = (Button) grid.getChildAt(childIndex);
@@ -93,8 +104,13 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa

// So that item clicked to start this Fragment is no longer the focused item.
grid.requestFocus();
}

return rootView;
@Override
public void onDestroyView()
{
super.onDestroyView();
mBinding = null;
}

@Override
@@ -9,24 +9,20 @@
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.splashscreen.SplashScreen;
import androidx.core.view.WindowCompat;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import androidx.viewpager.widget.ViewPager;

import com.google.android.material.appbar.AppBarLayout;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.tabs.TabLayout;

import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.activities.EmulationActivity;
import org.dolphinemu.dolphinemu.adapters.PlatformPagerAdapter;
import org.dolphinemu.dolphinemu.databinding.ActivityMainBinding;
import org.dolphinemu.dolphinemu.features.settings.model.IntSetting;
import org.dolphinemu.dolphinemu.features.settings.model.NativeConfig;
import org.dolphinemu.dolphinemu.features.settings.ui.MenuTag;
@@ -51,16 +47,12 @@
public final class MainActivity extends AppCompatActivity
implements MainView, SwipeRefreshLayout.OnRefreshListener, ThemeProvider
{
private ViewPager mViewPager;
private Toolbar mToolbar;
private TabLayout mTabLayout;
private AppBarLayout mAppBarLayout;
private FloatingActionButton mFab;

private int mThemeId;

private final MainPresenter mPresenter = new MainPresenter(this, this);

private ActivityMainBinding mBinding;

@Override
protected void onCreate(Bundle savedInstanceState)
{
@@ -71,19 +63,19 @@ protected void onCreate(Bundle savedInstanceState)
ThemeHelper.setTheme(this);

super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

findViews();
mBinding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(mBinding.getRoot());

View workaroundView = findViewById(R.id.workaround_view);
WindowCompat.setDecorFitsSystemWindows(getWindow(), false);
InsetsHelper.setUpMainLayout(this, mAppBarLayout, mFab, mViewPager, workaroundView);
ThemeHelper.enableStatusBarScrollTint(this, mAppBarLayout);
InsetsHelper.setUpMainLayout(this, mBinding.appbarMain, mBinding.buttonAddDirectory,
mBinding.pagerPlatforms, mBinding.workaroundView);
ThemeHelper.enableStatusBarScrollTint(this, mBinding.appbarMain);

setSupportActionBar(mToolbar);
setSupportActionBar(mBinding.toolbarMain);

// Set up the FAB.
mFab.setOnClickListener(view -> mPresenter.onFabClick());
mBinding.buttonAddDirectory.setOnClickListener(view -> mPresenter.onFabClick());

mPresenter.onCreate();

@@ -154,16 +146,6 @@ else if (DirectoryInitialization.areDolphinDirectoriesReady())
StartupHandler.setSessionTime(this);
}

// TODO: Replace with a ButterKnife injection.
private void findViews()
{
mAppBarLayout = findViewById(R.id.appbar_main);
mToolbar = findViewById(R.id.toolbar_main);
mViewPager = findViewById(R.id.pager_platforms);
mTabLayout = findViewById(R.id.tabs_platforms);
mFab = findViewById(R.id.button_add_directory);
}

@Override
public boolean onCreateOptionsMenu(Menu menu)
{
@@ -190,7 +172,7 @@ public boolean onCreateOptionsMenu(Menu menu)
@Override
public void setVersionString(String version)
{
mToolbar.setSubtitle(version);
mBinding.toolbarMain.setSubtitle(version);
}

@Override
@@ -351,7 +333,8 @@ private void forEachPlatformGamesView(Action1<PlatformGamesView> action)
@Nullable
private PlatformGamesView getPlatformGamesView(Platform platform)
{
String fragmentTag = "android:switcher:" + mViewPager.getId() + ":" + platform.toInt();
String fragmentTag =
"android:switcher:" + mBinding.pagerPlatforms.getId() + ":" + platform.toInt();

return (PlatformGamesView) getSupportFragmentManager().findFragmentByTag(fragmentTag);
}
@@ -361,25 +344,27 @@ private void setPlatformTabsAndStartGameFileCacheService()
{
PlatformPagerAdapter platformPagerAdapter = new PlatformPagerAdapter(
getSupportFragmentManager(), this);
mViewPager.setAdapter(platformPagerAdapter);
mViewPager.setOffscreenPageLimit(platformPagerAdapter.getCount());
mTabLayout.setupWithViewPager(mViewPager);
mTabLayout.addOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(mViewPager)
{
@Override
public void onTabSelected(@NonNull TabLayout.Tab tab)
{
super.onTabSelected(tab);
IntSetting.MAIN_LAST_PLATFORM_TAB.setIntGlobal(NativeConfig.LAYER_BASE, tab.getPosition());
}
});
mBinding.pagerPlatforms.setAdapter(platformPagerAdapter);
mBinding.pagerPlatforms.setOffscreenPageLimit(platformPagerAdapter.getCount());
mBinding.tabsPlatforms.setupWithViewPager(mBinding.pagerPlatforms);
mBinding.tabsPlatforms.addOnTabSelectedListener(
new TabLayout.ViewPagerOnTabSelectedListener(mBinding.pagerPlatforms)
{
@Override
public void onTabSelected(@NonNull TabLayout.Tab tab)
{
super.onTabSelected(tab);
IntSetting.MAIN_LAST_PLATFORM_TAB.setIntGlobal(NativeConfig.LAYER_BASE,
tab.getPosition());
}
});

for (int i = 0; i < PlatformPagerAdapter.TAB_ICONS.length; i++)
{
mTabLayout.getTabAt(i).setIcon(PlatformPagerAdapter.TAB_ICONS[i]);
mBinding.tabsPlatforms.getTabAt(i).setIcon(PlatformPagerAdapter.TAB_ICONS[i]);
}

mViewPager.setCurrentItem(IntSetting.MAIN_LAST_PLATFORM_TAB.getIntGlobal());
mBinding.pagerPlatforms.setCurrentItem(IntSetting.MAIN_LAST_PLATFORM_TAB.getIntGlobal());

showGames();
GameFileCacheManager.startLoad();
@@ -23,6 +23,7 @@
import org.dolphinemu.dolphinemu.activities.EmulationActivity;
import org.dolphinemu.dolphinemu.adapters.GameRowPresenter;
import org.dolphinemu.dolphinemu.adapters.SettingsRowPresenter;
import org.dolphinemu.dolphinemu.databinding.ActivityTvMainBinding;
import org.dolphinemu.dolphinemu.features.settings.ui.MenuTag;
import org.dolphinemu.dolphinemu.features.settings.ui.SettingsActivity;
import org.dolphinemu.dolphinemu.model.GameFile;
@@ -50,6 +51,8 @@ public final class TvMainActivity extends FragmentActivity

private final ArrayList<ArrayObjectAdapter> mGameRows = new ArrayList<>();

private ActivityTvMainBinding mBinding;

@Override
protected void onCreate(Bundle savedInstanceState)
{
@@ -58,7 +61,8 @@ protected void onCreate(Bundle savedInstanceState)
() -> !DirectoryInitialization.areDolphinDirectoriesReady());

super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tv_main);
mBinding = ActivityTvMainBinding.inflate(getLayoutInflater());
setContentView(mBinding.getRoot());

setupUI();

@@ -118,7 +122,7 @@ protected void onStop()

void setupUI()
{
mSwipeRefresh = findViewById(R.id.swipe_refresh);
mSwipeRefresh = mBinding.swipeRefresh;

mSwipeRefresh.setOnRefreshListener(this);

@@ -18,6 +18,7 @@

import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.adapters.GameAdapter;
import org.dolphinemu.dolphinemu.databinding.FragmentGridBinding;
import org.dolphinemu.dolphinemu.services.GameFileCacheManager;
import org.dolphinemu.dolphinemu.utils.InsetsHelper;

@@ -26,10 +27,11 @@ public final class PlatformGamesFragment extends Fragment implements PlatformGam
private static final String ARG_PLATFORM = "platform";

private GameAdapter mAdapter;
private RecyclerView mRecyclerView;
private SwipeRefreshLayout mSwipeRefresh;
private SwipeRefreshLayout.OnRefreshListener mOnRefreshListener;

private FragmentGridBinding mBinding;

public static PlatformGamesFragment newInstance(Platform platform)
{
PlatformGamesFragment fragment = new PlatformGamesFragment();
@@ -47,19 +49,20 @@ public void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
}

@NonNull
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
View rootView = inflater.inflate(R.layout.fragment_grid, container, false);

findViews(rootView);

return rootView;
mBinding = FragmentGridBinding.inflate(inflater, container, false);
return mBinding.getRoot();
}

@Override
public void onViewCreated(@NonNull View view, Bundle savedInstanceState)
{
mSwipeRefresh = mBinding.swipeRefresh;

int columns = getResources().getInteger(R.integer.game_grid_columns);
RecyclerView.LayoutManager layoutManager = new GridLayoutManager(getActivity(), columns);
mAdapter = new GameAdapter();
@@ -72,16 +75,23 @@ public void onViewCreated(@NonNull View view, Bundle savedInstanceState)

mSwipeRefresh.setOnRefreshListener(mOnRefreshListener);

mRecyclerView.setLayoutManager(layoutManager);
mRecyclerView.setAdapter(mAdapter);
mBinding.gridGames.setLayoutManager(layoutManager);
mBinding.gridGames.setAdapter(mAdapter);

InsetsHelper.setUpList(getContext(), mRecyclerView);
InsetsHelper.setUpList(getContext(), mBinding.gridGames);

setRefreshing(GameFileCacheManager.isLoadingOrRescanning());

showGames();
}

@Override
public void onDestroyView()
{
super.onDestroyView();
mBinding = null;
}

@Override
public void refreshScreenshotAtPosition(int position)
{
@@ -115,17 +125,13 @@ public void setOnRefreshListener(@Nullable SwipeRefreshLayout.OnRefreshListener
mOnRefreshListener = listener;

if (mSwipeRefresh != null)
{
mSwipeRefresh.setOnRefreshListener(listener);
}
}

public void setRefreshing(boolean refreshing)
{
mSwipeRefresh.setRefreshing(refreshing);
}

private void findViews(View root)
{
mSwipeRefresh = root.findViewById(R.id.swipe_refresh);
mRecyclerView = root.findViewById(R.id.grid_games);
mBinding.swipeRefresh.setRefreshing(refreshing);
}
}
@@ -23,9 +23,9 @@
import com.bumptech.glide.request.transition.Transition;

import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.adapters.GameAdapter;
import org.dolphinemu.dolphinemu.features.settings.model.BooleanSetting;
import org.dolphinemu.dolphinemu.model.GameFile;
import org.dolphinemu.dolphinemu.viewholders.GameViewHolder;

import java.io.File;
import java.io.FileNotFoundException;
@@ -60,21 +60,21 @@ public static void loadGameBanner(ImageView imageView, GameFile gameFile)
}
}

public static void loadGameCover(GameViewHolder gameViewHolder, ImageView imageView,
public static void loadGameCover(GameAdapter.GameViewHolder gameViewHolder, ImageView imageView,
GameFile gameFile)
{
if (BooleanSetting.MAIN_SHOW_GAME_TITLES.getBooleanGlobal() && gameViewHolder != null)
{
gameViewHolder.textGameTitle.setText(gameFile.getTitle());
gameViewHolder.textGameTitle.setVisibility(View.VISIBLE);
gameViewHolder.textGameTitleInner.setVisibility(View.GONE);
gameViewHolder.textGameCaption.setVisibility(View.VISIBLE);
gameViewHolder.binding.textGameTitle.setText(gameFile.getTitle());
gameViewHolder.binding.textGameTitle.setVisibility(View.VISIBLE);
gameViewHolder.binding.textGameTitleInner.setVisibility(View.GONE);
gameViewHolder.binding.textGameCaption.setVisibility(View.VISIBLE);
}
else if (gameViewHolder != null)
{
gameViewHolder.textGameTitleInner.setText(gameFile.getTitle());
gameViewHolder.textGameTitle.setVisibility(View.GONE);
gameViewHolder.textGameCaption.setVisibility(View.GONE);
gameViewHolder.binding.textGameTitleInner.setText(gameFile.getTitle());
gameViewHolder.binding.textGameTitle.setVisibility(View.GONE);
gameViewHolder.binding.textGameCaption.setVisibility(View.GONE);
}

String customCoverPath = gameFile.getCustomCoverPath();
@@ -198,23 +198,24 @@ public void onLoadCleared(@Nullable Drawable placeholder)
}
}

private static void enableInnerTitle(GameViewHolder gameViewHolder, ImageView imageView)
private static void enableInnerTitle(GameAdapter.GameViewHolder gameViewHolder,
ImageView imageView)
{
Glide.with(imageView.getContext())
.load(R.drawable.no_banner)
.into(imageView);

if (gameViewHolder != null && !BooleanSetting.MAIN_SHOW_GAME_TITLES.getBooleanGlobal())
{
gameViewHolder.textGameTitleInner.setVisibility(View.VISIBLE);
gameViewHolder.binding.textGameTitleInner.setVisibility(View.VISIBLE);
}
}

private static void disableInnerTitle(GameViewHolder gameViewHolder)
private static void disableInnerTitle(GameAdapter.GameViewHolder gameViewHolder)
{
if (gameViewHolder != null && !BooleanSetting.MAIN_SHOW_GAME_TITLES.getBooleanGlobal())
{
gameViewHolder.textGameTitleInner.setVisibility(View.GONE);
gameViewHolder.binding.textGameTitleInner.setVisibility(View.GONE);
}
}
}

This file was deleted.

@@ -1,37 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
<!-- Set nextFocusLeft so checkbox functionality is maintained in rtl layouts -->
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/root"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="true"
android:clickable="true"
android:background="?android:attr/selectableItemBackground"
android:nextFocusLeft="@id/checkbox">

<TextView
android:id="@+id/text_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
style="@style/TextAppearance.MaterialComponents.Headline5"
android:layout_width="wrap_content"
android:layout_height="64dp"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:gravity="center_vertical"
android:layout_marginStart="@dimen/spacing_large"
android:textSize="16sp"
tools:text="Hyrule Field Speed Hack"
android:layout_margin="@dimen/spacing_large"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/checkbox"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
tools:text="Hyrule Field Speed Hack" />

<CheckBox
android:id="@+id/checkbox"
android:layout_width="48dp"
android:layout_height="64dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginEnd="@dimen/spacing_small"
android:focusable="true"
android:gravity="center"
android:nextFocusRight="@id/root"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/text_name"
app:layout_constraintTop_toTopOf="parent" />
android:nextFocusRight="@id/root" />

</androidx.constraintlayout.widget.ConstraintLayout>
</RelativeLayout>
@@ -1,7 +1,14 @@
<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"
/>
<View
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/layout_emulation"
android:layout_height="match_parent"
android:layout_width="match_parent">

<SurfaceView
android:id="@+id/surface_emulation"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:focusable="false"
android:focusableInTouchMode="false" />

</View>
@@ -1,7 +1,14 @@
<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"
/>
<View
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/layout_emulation"
android:layout_height="match_parent"
android:layout_width="match_parent">

<SurfaceView
android:id="@+id/surface_emulation"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:focusable="false"
android:focusableInTouchMode="false" />

</View>
@@ -1,36 +1,42 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:keepScreenOn="true"
tools:context="org.dolphinemu.dolphinemu.fragments.EmulationFragment">
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/layout_emulation"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:keepScreenOn="true"
tools:context="org.dolphinemu.dolphinemu.fragments.EmulationFragment">

<!-- Places the emulation surface to the top half of the screen -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:baselineAligned="false">

<!-- This is what everything is rendered to during emulation -->
<SurfaceView
android:id="@+id/surface_emulation"
android:layout_height="0dp"
android:layout_width="wrap_content"
android:layout_weight="1"
android:focusable="false"
android:focusableInTouchMode="false"/>
android:focusableInTouchMode="false" />

<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1"/>
android:layout_weight="1" />

</LinearLayout>

<!-- This is the onscreen input overlay -->
<org.dolphinemu.dolphinemu.overlay.InputOverlay
android:id="@+id/surface_input_overlay"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:focusable="true"
android:focusableInTouchMode="true"/>
android:focusableInTouchMode="true" />

<Button
android:id="@+id/done_control_config"
@@ -39,6 +45,6 @@
android:layout_gravity="center"
android:padding="@dimen/spacing_small"
android:text="@string/emulation_done"
android:visibility="gone"/>
android:visibility="gone" />

</FrameLayout>
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.appcompat.widget.LinearLayoutCompat
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
@@ -12,7 +12,7 @@
android:layout_weight="1">

<com.google.android.material.slider.Slider
android:id="@+id/slider_width"
android:id="@+id/slider_yaw"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toStartOf="@id/text_ir_yaw"
@@ -26,10 +26,10 @@
android:layout_marginEnd="24dp"
android:layout_marginStart="@dimen/spacing_medlarge"
android:gravity="end"
app:layout_constraintBottom_toBottomOf="@+id/slider_width"
app:layout_constraintBottom_toBottomOf="@+id/slider_yaw"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/slider_width"
app:layout_constraintTop_toTopOf="@+id/slider_width"
app:layout_constraintStart_toEndOf="@id/slider_yaw"
app:layout_constraintTop_toTopOf="@+id/slider_yaw"
tools:text="100" />

<TextView
@@ -39,10 +39,10 @@
android:gravity="start"
android:layout_marginStart="24dp"
android:layout_marginEnd="@dimen/spacing_medlarge"
app:layout_constraintBottom_toBottomOf="@+id/slider_width"
app:layout_constraintEnd_toStartOf="@id/slider_width"
app:layout_constraintBottom_toBottomOf="@+id/slider_yaw"
app:layout_constraintEnd_toStartOf="@id/slider_yaw"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/slider_width"
app:layout_constraintTop_toTopOf="@+id/slider_yaw"
tools:text="Total Yaw" />

</androidx.constraintlayout.widget.ConstraintLayout>
@@ -1,25 +1,27 @@
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:keepScreenOn="true"
tools:context="org.dolphinemu.dolphinemu.fragments.EmulationFragment">
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/layout_emulation"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:keepScreenOn="true"
tools:context="org.dolphinemu.dolphinemu.fragments.EmulationFragment">

<!-- This is what everything is rendered to during emulation -->
<SurfaceView
android:id="@+id/surface_emulation"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:focusable="false"
android:focusableInTouchMode="false"/>
android:focusableInTouchMode="false" />

<!-- This is the onscreen input overlay -->
<org.dolphinemu.dolphinemu.overlay.InputOverlay
android:id="@+id/surface_input_overlay"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:focusable="true"
android:focusableInTouchMode="true"/>
android:focusableInTouchMode="true" />

<Button
android:id="@+id/done_control_config"
@@ -28,6 +30,6 @@
android:layout_gravity="center"
android:padding="@dimen/spacing_small"
android:text="@string/emulation_done"
android:visibility="gone"/>
android:visibility="gone" />

</FrameLayout>
@@ -1,37 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/root"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:focusable="true"
android:clickable="true"
android:background="?android:attr/selectableItemBackground"
android:nextFocusRight="@id/checkbox">

<TextView
android:id="@+id/text_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
style="@style/TextAppearance.MaterialComponents.Headline5"
android:layout_width="wrap_content"
android:layout_height="64dp"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:gravity="center_vertical"
android:layout_marginStart="@dimen/spacing_large"
android:textSize="16sp"
tools:text="Hyrule Field Speed Hack"
android:layout_margin="@dimen/spacing_large"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/checkbox"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent" />
tools:text="Hyrule Field Speed Hack" />

<CheckBox
android:id="@+id/checkbox"
android:layout_width="48dp"
android:layout_height="64dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginEnd="@dimen/spacing_small"
android:focusable="true"
android:gravity="center"
android:nextFocusRight="@id/root"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/text_name"
app:layout_constraintTop_toTopOf="parent" />
android:nextFocusRight="@id/root" />

</androidx.constraintlayout.widget.ConstraintLayout>
</RelativeLayout>
@@ -1,19 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:focusable="true"
android:layout_height="48dp">
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:focusable="true"
android:layout_height="wrap_content">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/text_header_name"
tools:text="CPU Settings"
android:layout_width="wrap_content"
android:layout_height="46dp"
android:gravity="bottom"
android:layout_alignParentTop="true"
android:layout_marginStart="@dimen/spacing_large"
android:layout_marginBottom="@dimen/spacing_small"
android:layout_marginBottom="2dp"
android:textColor="?attr/colorPrimary"
android:textStyle="bold"
android:layout_gravity="start|bottom"/>
tools:text="CPU Settings" />

</FrameLayout>
</RelativeLayout>
@@ -1,12 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="72dp"
android:background="?android:attr/selectableItemBackground"
android:focusable="true"
android:clickable="true">
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="72dp"
android:background="?android:attr/selectableItemBackground"
android:focusable="true"
android:clickable="true">

<TextView
android:layout_width="0dp"
@@ -1,12 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="72dp"
android:background="?android:attr/selectableItemBackground"
android:focusable="true"
android:clickable="true">
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="72dp"
android:background="?android:attr/selectableItemBackground"
android:focusable="true"
android:clickable="true">

<TextView
android:id="@+id/text_setting_name"
@@ -1,12 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="54dp"
android:background="?android:attr/selectableItemBackground"
android:focusable="true"
android:clickable="true">
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="54dp"
android:background="?android:attr/selectableItemBackground"
android:focusable="true"
android:clickable="true">

<TextView
android:layout_width="0dp"
@@ -20,6 +21,6 @@
android:layout_marginEnd="@dimen/spacing_large"
android:layout_marginTop="@dimen/spacing_large"
android:id="@+id/text_setting_name"
android:textSize="16sp"/>
android:textSize="16sp" />

</RelativeLayout>