Skip to content
Permalink
Browse files
Merge pull request #9004 from JosJuice/android-menu-back
Android: Use Back to open the emulation menu on all devices
  • Loading branch information
JMC47 committed Sep 12, 2020
2 parents 1335df8 + cecec75 commit b1fecbb
Show file tree
Hide file tree
Showing 18 changed files with 344 additions and 564 deletions.

Large diffs are not rendered by default.

@@ -12,7 +12,6 @@
import org.dolphinemu.dolphinemu.features.settings.ui.SettingsAdapter;
import org.dolphinemu.dolphinemu.utils.ControllerMappingHelper;
import org.dolphinemu.dolphinemu.utils.Log;
import org.dolphinemu.dolphinemu.utils.TvUtil;

import java.util.ArrayList;
import java.util.List;
@@ -63,8 +62,8 @@ public boolean onKeyEvent(int keyCode, KeyEvent event)
@Override
public boolean onKeyLongPress(int keyCode, @NonNull KeyEvent event)
{
// Option to clear by long back is only needed on the TV interface
if (TvUtil.isLeanback(getContext()) && keyCode == KeyEvent.KEYCODE_BACK)
// Intended for devices with no touchscreen or mouse
if (keyCode == KeyEvent.KEYCODE_BACK)
{
setting.clearValue(mAdapter.getSettings());
dismiss();
@@ -1,5 +1,7 @@
package org.dolphinemu.dolphinemu.fragments;

import android.content.pm.PackageManager;
import android.graphics.Rect;
import android.os.Bundle;
import android.util.SparseIntArray;
import android.view.LayoutInflater;
@@ -19,8 +21,10 @@

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 SparseIntArray buttonsActionsMap = new SparseIntArray();

@@ -38,8 +42,12 @@ public final class MenuFragment extends Fragment implements View.OnClickListener
.append(R.id.menu_emulation_save_root, EmulationActivity.MENU_ACTION_SAVE_ROOT);
buttonsActionsMap
.append(R.id.menu_emulation_load_root, EmulationActivity.MENU_ACTION_LOAD_ROOT);
buttonsActionsMap
.append(R.id.menu_overlay_controls, EmulationActivity.MENU_ACTION_OVERLAY_CONTROLS);
buttonsActionsMap
.append(R.id.menu_refresh_wiimotes, EmulationActivity.MENU_ACTION_REFRESH_WIIMOTES);
buttonsActionsMap
.append(R.id.menu_screen_orientation, EmulationActivity.MENU_ACTION_SCREEN_ORIENTATION);
buttonsActionsMap.append(R.id.menu_change_disc, EmulationActivity.MENU_ACTION_CHANGE_DISC);
buttonsActionsMap.append(R.id.menu_exit, EmulationActivity.MENU_ACTION_EXIT);
}
@@ -55,6 +63,14 @@ public static MenuFragment newInstance(String title)
return fragment;
}

// This is primarily intended to account for any navigation bar at the bottom of the screen
private int getBottomPaddingRequired()
{
Rect visibleFrame = new Rect();
requireActivity().getWindow().getDecorView().getWindowVisibleDisplayFrame(visibleFrame);
return visibleFrame.bottom - visibleFrame.top - getResources().getDisplayMetrics().heightPixels;
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
@@ -65,10 +81,7 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa
mPauseEmulation = options.findViewById(R.id.menu_pause_emulation);
mUnpauseEmulation = options.findViewById(R.id.menu_unpause_emulation);

if (EmulationActivity.getHasUserPausedEmulation())
{
showUnpauseEmulationButton();
}
updatePauseUnpauseVisibility();

boolean enableSaveStates = ((EmulationActivity) getActivity()).getSettings()
.getSection(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_INI_CORE)
@@ -82,55 +95,90 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa
options.findViewById(R.id.menu_emulation_load_root).setVisibility(View.VISIBLE);
}

PackageManager packageManager = requireActivity().getPackageManager();

if (!packageManager.hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN))
{
options.findViewById(R.id.menu_overlay_controls).setVisibility(View.GONE);
}

if (EmulationActivity.isGameCubeGame())
{
options.findViewById(R.id.menu_refresh_wiimotes).setVisibility(View.GONE);
}

// Old devices which support both portrait and landscape may report support for neither,
// so we only hide the orientation button if the device only supports one orientation
if (packageManager.hasSystemFeature(PackageManager.FEATURE_SCREEN_PORTRAIT) !=
packageManager.hasSystemFeature(PackageManager.FEATURE_SCREEN_LANDSCAPE))
{
options.findViewById(R.id.menu_screen_orientation).setVisibility(View.GONE);
}

int bottomPaddingRequired = getBottomPaddingRequired();

// Provide a safe zone between the navigation bar and Exit Emulation to avoid accidental touches
float density = getResources().getDisplayMetrics().density;
if (bottomPaddingRequired >= 32 * density)
{
bottomPaddingRequired += 32 * density;
}

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

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);
rootView.findViewById(R.id.menu_exit).setOnClickListener(this);

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

return rootView;
}

private void showPauseEmulationButton()
private void updatePauseUnpauseVisibility()
{
mUnpauseEmulation.setVisibility(View.GONE);
mPauseEmulation.setVisibility(View.VISIBLE);
}
boolean paused = EmulationActivity.getHasUserPausedEmulation();

private void showUnpauseEmulationButton()
{
mPauseEmulation.setVisibility(View.GONE);
mUnpauseEmulation.setVisibility(View.VISIBLE);
mUnpauseEmulation.setVisibility(paused ? View.VISIBLE : View.GONE);
mPauseEmulation.setVisibility(paused ? View.GONE : View.VISIBLE);
}

@SuppressWarnings("WrongConstant")
@Override
public void onClick(View button)
{
int action = buttonsActionsMap.get(button.getId());
if (action == EmulationActivity.MENU_ACTION_PAUSE_EMULATION)
EmulationActivity activity = (EmulationActivity) requireActivity();

if (action == EmulationActivity.MENU_ACTION_OVERLAY_CONTROLS)
{
EmulationActivity.setHasUserPausedEmulation(true);
NativeLibrary.PauseEmulation();
showUnpauseEmulationButton();
// 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);
}
else if (action == EmulationActivity.MENU_ACTION_UNPAUSE_EMULATION)
else if (action >= 0)
{
EmulationActivity.setHasUserPausedEmulation(false);
NativeLibrary.UnPauseEmulation();
showPauseEmulationButton();
activity.handleMenuAction(action);
}
else if (action >= 0)

if (action == EmulationActivity.MENU_ACTION_PAUSE_EMULATION ||
action == EmulationActivity.MENU_ACTION_UNPAUSE_EMULATION)
{
((EmulationActivity) getActivity()).handleMenuAction(action);
updatePauseUnpauseVisibility();
}
}
}
@@ -0,0 +1,7 @@
<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"
/>

This file was deleted.

@@ -1,11 +1,36 @@
<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.dolphinemu.dolphinemu.ui.NVidiaShieldWorkaroundView
android:layout_width="match_parent"
android:layout_height="match_parent"/>

<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="260dp"
android:layout_height="match_parent"
tools:layout="@layout/fragment_ingame_menu"/>

<FrameLayout
android:id="@+id/frame_submenu"
android:layout_width="match_parent"
android:layout_height="match_parent"/>

</LinearLayout>

</FrameLayout>
@@ -4,6 +4,7 @@
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="16dp"
android:background="@color/dolphin_blue_dark"
tools:layout_width="250dp">

@@ -14,7 +15,9 @@
tools:text="The Legend of Zelda: The Wind Waker"
android:textColor="@android:color/white"
android:textSize="20sp"
android:layout_margin="32dp"/>
android:layout_marginHorizontal="32dp"
android:layout_marginTop="32dp"
android:layout_marginBottom="16dp"/>

<ScrollView
android:layout_width="match_parent"
@@ -67,23 +70,41 @@
style="@style/InGameMenuOption"
android:visibility="gone"/>

<Button
android:id="@+id/menu_overlay_controls"
android:text="@string/emulation_overlay_controls"
style="@style/InGameMenuOption"/>

<Button
android:id="@+id/menu_refresh_wiimotes"
android:text="@string/emulation_refresh_wiimotes"
style="@style/InGameMenuOption"/>

<Button
android:id="@+id/menu_change_disc"
android:text="@string/emulation_change_disc"
android:id="@+id/menu_screen_orientation"
android:text="@string/emulation_screen_orientation"
style="@style/InGameMenuOption"/>

<Button
android:id="@+id/menu_exit"
android:text="@string/emulation_exit"
android:id="@+id/menu_change_disc"
android:text="@string/emulation_change_disc"
style="@style/InGameMenuOption"/>

</LinearLayout>

</ScrollView>

<View
android:id="@+id/divider"
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#FFFFFF"
android:layout_marginTop="24dp"
android:layout_marginBottom="16dp"/>

<Button
android:id="@+id/menu_exit"
android:text="@string/emulation_exit"
style="@style/InGameMenuOption"/>

</LinearLayout>

0 comments on commit b1fecbb

Please sign in to comment.