From cf51642c17878ddeebee4397b03b46f10871bf47 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Tue, 7 Apr 2020 18:02:35 +0200 Subject: Android: Use Back to open the emulation menu on all devices https://bugs.dolphin-emu.org/issues/12029 We currently have one way of opening the menu on touch screen devices (swiping down from the top of the screen to bring up the action bar and selecting the menu in the action bar), and another way of opening the menu on Android TV (pressing Back). However, some devices that claim to support touch (or don't support leanback? Dolphin currently conflates the two) don't actually let you swipe down from the top of the screen in the way that Dolphin expects, notably Chromebooks. There are also some phones where you can swipe down from the top of the screen but this for some reason doesn't lead to the action bar becoming visible, though we are getting less reports about this nowadays than in the past. This change makes us use the Back method on all devices, since it should work on all devices with no significant drawbacks. Unfortunately, we not only have two different ways of triggering the menu but actually two entirely different menus, with the non-touch menu not implementing options that only are revelant when using a touch screen. A later commit will add the missing features to the menu that we now use on all devices. --- .../dolphinemu/activities/EmulationActivity.java | 94 ++++++---------------- 1 file changed, 25 insertions(+), 69 deletions(-) (limited to 'Source/Android/app/src/main/java/org') diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java index 090e22a1bb..3ec233a117 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java @@ -6,7 +6,6 @@ import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.ActivityInfo; import android.os.Bundle; -import android.os.Handler; import android.preference.PreferenceManager; import android.text.TextUtils; import android.util.SparseIntArray; @@ -62,7 +61,6 @@ public final class EmulationActivity extends AppCompatActivity private static final String BACKSTACK_NAME_SUBMENU = "submenu"; public static final int REQUEST_CHANGE_DISC = 1; - private View mDecorView; private EmulationFragment mEmulationFragment; private SharedPreferences mPreferences; @@ -85,7 +83,6 @@ public final class EmulationActivity extends AppCompatActivity private int mPlatform; private String[] mPaths; private static boolean sUserPausedEmulation; - private boolean backPressedOnce = false; public static final String EXTRA_SELECTED_GAMES = "SelectedGames"; public static final String EXTRA_SELECTED_TITLE = "SelectedTitle"; @@ -317,33 +314,10 @@ public final class EmulationActivity extends AppCompatActivity mDeviceHasTouchScreen = getPackageManager().hasSystemFeature("android.hardware.touchscreen"); mMotionListener = new MotionListener(this); - int themeId; - if (mDeviceHasTouchScreen) - { - themeId = R.style.DolphinEmulationBase; - - // Get a handle to the Window containing the UI. - mDecorView = getWindow().getDecorView(); - mDecorView.setOnSystemUiVisibilityChangeListener(visibility -> - { - if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) - { - // Go back to immersive fullscreen mode in 3s - Handler handler = new Handler(getMainLooper()); - handler.postDelayed(this::enableFullscreenImmersive, 3000 /* 3s */); - } - }); - // Set these options now so that the SurfaceView the game renders into is the right size. - enableFullscreenImmersive(); - Toast.makeText(this, getString(R.string.emulation_touch_button_help), Toast.LENGTH_LONG) - .show(); - } - else - { - themeId = R.style.DolphinEmulationTvBase; - } + // Set these options now so that the SurfaceView the game renders into is the right size. + enableFullscreenImmersive(); - setTheme(themeId); + Toast.makeText(this, getString(R.string.emulation_menu_help), Toast.LENGTH_LONG).show(); Rumble.initRumble(this); @@ -360,10 +334,7 @@ public final class EmulationActivity extends AppCompatActivity .commit(); } - if (mDeviceHasTouchScreen) - { - setTitle(mSelectedTitle); - } + setTitle(mSelectedTitle); } @Override @@ -390,10 +361,20 @@ public final class EmulationActivity extends AppCompatActivity sUserPausedEmulation = savedInstanceState.getBoolean(EXTRA_USER_PAUSED_EMULATION); } + @Override + public void onWindowFocusChanged(boolean hasFocus) + { + if (hasFocus) + { + enableFullscreenImmersive(); + } + } + @Override protected void onResume() { super.onResume(); + if (!sIsGameCubeGame && mPreferences.getInt("motionControlsEnabled", 0) != 2) mMotionListener.enable(); } @@ -414,28 +395,11 @@ public final class EmulationActivity extends AppCompatActivity @Override public void onBackPressed() { - if (!mDeviceHasTouchScreen) + boolean popResult = getSupportFragmentManager().popBackStackImmediate( + BACKSTACK_NAME_SUBMENU, FragmentManager.POP_BACK_STACK_INCLUSIVE); + if (!popResult) { - boolean popResult = getSupportFragmentManager().popBackStackImmediate( - BACKSTACK_NAME_SUBMENU, FragmentManager.POP_BACK_STACK_INCLUSIVE); - if (!popResult) - { - toggleMenu(); - } - } - else - { - if (backPressedOnce) - { - mEmulationFragment.stopEmulation(); - finish(); - } - else - { - backPressedOnce = true; - Toast.makeText(this, "Press back again to exit", Toast.LENGTH_LONG).show(); - new Handler().postDelayed(() -> backPressedOnce = false, 3000); - } + toggleMenu(); } } @@ -459,14 +423,13 @@ public final class EmulationActivity extends AppCompatActivity private void enableFullscreenImmersive() { - // It would be nice to use IMMERSIVE_STICKY, but that doesn't show the toolbar. - mDecorView.setSystemUiVisibility( + getWindow().getDecorView().setSystemUiVisibility( View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN | - View.SYSTEM_UI_FLAG_IMMERSIVE); + View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY); } private void updateOrientation() @@ -631,19 +594,12 @@ public final class EmulationActivity extends AppCompatActivity NativeLibrary.LoadState(9); return; - // TV Menu only case MENU_ACTION_SAVE_ROOT: - if (!mDeviceHasTouchScreen) - { - showSubMenu(SaveLoadStateFragment.SaveOrLoad.SAVE); - } + showSubMenu(SaveLoadStateFragment.SaveOrLoad.SAVE); return; case MENU_ACTION_LOAD_ROOT: - if (!mDeviceHasTouchScreen) - { - showSubMenu(SaveLoadStateFragment.SaveOrLoad.LOAD); - } + showSubMenu(SaveLoadStateFragment.SaveOrLoad.LOAD); return; // Save state slots @@ -718,9 +674,9 @@ public final class EmulationActivity extends AppCompatActivity return; case MENU_ACTION_EXIT: - // ATV menu is built using a fragment, this will pop that fragment before emulation ends. - if (TvUtil.isLeanback(getApplicationContext())) - toggleMenu(); // Hide the menu (it will be showing since we just clicked it) + // Hide the menu (it will be showing since we just clicked it) + toggleMenu(); + mEmulationFragment.stopEmulation(); finish(); return; -- cgit v1.2.3 From 27554d2f265289b5f4c7ca0235377b9bdba92a9a Mon Sep 17 00:00:00 2001 From: JosJuice Date: Wed, 29 Jul 2020 17:29:15 +0200 Subject: Android: Remove inappropriate leanback checks Android TV devices aren't the only devices without touchscreens. Regarding MotionAlertDialog, I could've replaced the leanback check with a touchscreen check instead of just removing it, but I thought there was no reason to prevent people with touchscreens from doing a long back press if they want to. --- .../java/org/dolphinemu/dolphinemu/dialogs/MotionAlertDialog.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'Source/Android/app/src/main/java/org') diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/MotionAlertDialog.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/MotionAlertDialog.java index 39140c4829..6b633e9aec 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/MotionAlertDialog.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/MotionAlertDialog.java @@ -12,7 +12,6 @@ import org.dolphinemu.dolphinemu.features.settings.model.view.InputBindingSettin 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 final class MotionAlertDialog extends AlertDialog @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(); -- cgit v1.2.3 From 48c34bba8a3b4243527c9e4d6c18d7865787acb9 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Tue, 28 Jul 2020 17:48:43 +0200 Subject: Android: Don't hide the menu when pressing Exit Removing the menu for a split second before showing the transition back to the main activity looks janky. --- .../java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java | 3 --- 1 file changed, 3 deletions(-) (limited to 'Source/Android/app/src/main/java/org') diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java index 3ec233a117..0af915ddea 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java @@ -674,9 +674,6 @@ public final class EmulationActivity extends AppCompatActivity return; case MENU_ACTION_EXIT: - // Hide the menu (it will be showing since we just clicked it) - toggleMenu(); - mEmulationFragment.stopEmulation(); finish(); return; -- cgit v1.2.3 From 48de1333df628caa1774972ca45750d0ae87386f Mon Sep 17 00:00:00 2001 From: JosJuice Date: Tue, 28 Jul 2020 18:50:51 +0200 Subject: Android: Close the menu when tapping outside of it --- .../dolphinemu/activities/EmulationActivity.java | 69 +++++++++++++++++++--- 1 file changed, 62 insertions(+), 7 deletions(-) (limited to 'Source/Android/app/src/main/java/org') diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java index 0af915ddea..888ff331a0 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java @@ -5,6 +5,7 @@ import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.ActivityInfo; +import android.graphics.Rect; import android.os.Bundle; import android.preference.PreferenceManager; import android.text.TextUtils; @@ -22,6 +23,7 @@ import android.widget.Toast; import androidx.annotation.IntDef; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; import androidx.fragment.app.Fragment; @@ -395,9 +397,7 @@ public final class EmulationActivity extends AppCompatActivity @Override public void onBackPressed() { - boolean popResult = getSupportFragmentManager().popBackStackImmediate( - BACKSTACK_NAME_SUBMENU, FragmentManager.POP_BACK_STACK_INCLUSIVE); - if (!popResult) + if (!closeSubmenu()) { toggleMenu(); } @@ -438,13 +438,22 @@ public final class EmulationActivity extends AppCompatActivity ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE)); } - private void toggleMenu() + private boolean closeSubmenu() + { + return getSupportFragmentManager().popBackStackImmediate(BACKSTACK_NAME_SUBMENU, + FragmentManager.POP_BACK_STACK_INCLUSIVE); + } + + private boolean closeMenu() { - boolean result = getSupportFragmentManager().popBackStackImmediate( - BACKSTACK_NAME_MENU, FragmentManager.POP_BACK_STACK_INCLUSIVE); mMenuVisible = false; + return getSupportFragmentManager().popBackStackImmediate(BACKSTACK_NAME_MENU, + FragmentManager.POP_BACK_STACK_INCLUSIVE); + } - if (!result) + private void toggleMenu() + { + if (!closeMenu()) { // Removing the menu failed, so that means it wasn't visible. Add it. Fragment fragment = MenuFragment.newInstance(mSelectedTitle); @@ -1129,6 +1138,52 @@ public final class EmulationActivity extends AppCompatActivity .show(); } + private static boolean areCoordinatesOutside(@Nullable View view, float x, float y) + { + if (view == null) + { + return true; + } + + Rect viewBounds = new Rect(); + view.getGlobalVisibleRect(viewBounds); + return !viewBounds.contains(Math.round(x), Math.round(y)); + } + + @Override + public boolean dispatchTouchEvent(MotionEvent event) + { + if (event.getActionMasked() == MotionEvent.ACTION_DOWN) + { + boolean anyMenuClosed = false; + + Fragment submenu = getSupportFragmentManager().findFragmentById(R.id.frame_submenu); + if (submenu != null && areCoordinatesOutside(submenu.getView(), event.getX(), event.getY())) + { + closeSubmenu(); + submenu = null; + anyMenuClosed = true; + } + + if (submenu == null) + { + Fragment menu = getSupportFragmentManager().findFragmentById(R.id.frame_menu); + if (menu != null && areCoordinatesOutside(menu.getView(), event.getX(), event.getY())) + { + closeMenu(); + anyMenuClosed = true; + } + } + + if (anyMenuClosed) + { + return true; + } + } + + return super.dispatchTouchEvent(event); + } + @Override public boolean dispatchGenericMotionEvent(MotionEvent event) { -- cgit v1.2.3 From 36a3b54c1f92d7f7c176a6804ce8495552586e33 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Tue, 4 Aug 2020 15:22:59 +0200 Subject: Android: Port over settings from the old menu --- .../dolphinemu/activities/EmulationActivity.java | 72 ++++------------------ .../dolphinemu/fragments/MenuFragment.java | 36 ++++++++++- 2 files changed, 46 insertions(+), 62 deletions(-) (limited to 'Source/Android/app/src/main/java/org') diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java index 888ff331a0..e2b637ba4e 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java @@ -26,6 +26,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.PopupMenu; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentManager; @@ -103,7 +104,7 @@ public final class EmulationActivity extends AppCompatActivity MENU_ACTION_LOAD_SLOT6, MENU_ACTION_EXIT, MENU_ACTION_CHANGE_DISC, MENU_ACTION_RESET_OVERLAY, MENU_SET_IR_SENSITIVITY, MENU_ACTION_CHOOSE_DOUBLETAP, MENU_ACTION_SCREEN_ORIENTATION, MENU_ACTION_MOTION_CONTROLS, MENU_ACTION_PAUSE_EMULATION, - MENU_ACTION_UNPAUSE_EMULATION}) + MENU_ACTION_UNPAUSE_EMULATION, MENU_ACTION_OVERLAY_CONTROLS}) public @interface MenuAction { } @@ -141,7 +142,7 @@ public final class EmulationActivity extends AppCompatActivity public static final int MENU_ACTION_MOTION_CONTROLS = 30; public static final int MENU_ACTION_PAUSE_EMULATION = 31; public static final int MENU_ACTION_UNPAUSE_EMULATION = 32; - + public static final int MENU_ACTION_OVERLAY_CONTROLS = 33; private static SparseIntArray buttonsActionsMap = new SparseIntArray(); @@ -155,33 +156,6 @@ public final class EmulationActivity extends AppCompatActivity .append(R.id.menu_emulation_adjust_scale, EmulationActivity.MENU_ACTION_ADJUST_SCALE); buttonsActionsMap.append(R.id.menu_emulation_choose_controller, EmulationActivity.MENU_ACTION_CHOOSE_CONTROLLER); - buttonsActionsMap - .append(R.id.menu_refresh_wiimotes, EmulationActivity.MENU_ACTION_REFRESH_WIIMOTES); - buttonsActionsMap - .append(R.id.menu_emulation_pause, EmulationActivity.MENU_ACTION_PAUSE_EMULATION); - buttonsActionsMap - .append(R.id.menu_emulation_unpause, EmulationActivity.MENU_ACTION_UNPAUSE_EMULATION); - buttonsActionsMap - .append(R.id.menu_emulation_screenshot, EmulationActivity.MENU_ACTION_TAKE_SCREENSHOT); - - buttonsActionsMap.append(R.id.menu_quicksave, EmulationActivity.MENU_ACTION_QUICK_SAVE); - buttonsActionsMap.append(R.id.menu_quickload, EmulationActivity.MENU_ACTION_QUICK_LOAD); - buttonsActionsMap - .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_emulation_save_1, EmulationActivity.MENU_ACTION_SAVE_SLOT1); - buttonsActionsMap.append(R.id.menu_emulation_save_2, EmulationActivity.MENU_ACTION_SAVE_SLOT2); - buttonsActionsMap.append(R.id.menu_emulation_save_3, EmulationActivity.MENU_ACTION_SAVE_SLOT3); - buttonsActionsMap.append(R.id.menu_emulation_save_4, EmulationActivity.MENU_ACTION_SAVE_SLOT4); - buttonsActionsMap.append(R.id.menu_emulation_save_5, EmulationActivity.MENU_ACTION_SAVE_SLOT5); - buttonsActionsMap.append(R.id.menu_emulation_load_1, EmulationActivity.MENU_ACTION_LOAD_SLOT1); - buttonsActionsMap.append(R.id.menu_emulation_load_2, EmulationActivity.MENU_ACTION_LOAD_SLOT2); - buttonsActionsMap.append(R.id.menu_emulation_load_3, EmulationActivity.MENU_ACTION_LOAD_SLOT3); - buttonsActionsMap.append(R.id.menu_emulation_load_4, EmulationActivity.MENU_ACTION_LOAD_SLOT4); - buttonsActionsMap.append(R.id.menu_emulation_load_5, EmulationActivity.MENU_ACTION_LOAD_SLOT5); - buttonsActionsMap.append(R.id.menu_change_disc, EmulationActivity.MENU_ACTION_CHANGE_DISC); - buttonsActionsMap.append(R.id.menu_exit, EmulationActivity.MENU_ACTION_EXIT); buttonsActionsMap.append(R.id.menu_emulation_joystick_rel_center, EmulationActivity.MENU_ACTION_JOYSTICK_REL_CENTER); buttonsActionsMap.append(R.id.menu_emulation_rumble, EmulationActivity.MENU_ACTION_RUMBLE); @@ -191,8 +165,6 @@ public final class EmulationActivity extends AppCompatActivity EmulationActivity.MENU_SET_IR_SENSITIVITY); buttonsActionsMap.append(R.id.menu_emulation_choose_doubletap, EmulationActivity.MENU_ACTION_CHOOSE_DOUBLETAP); - buttonsActionsMap.append(R.id.menu_screen_orientation, - EmulationActivity.MENU_ACTION_SCREEN_ORIENTATION); buttonsActionsMap.append(R.id.menu_emulation_motion_controls, EmulationActivity.MENU_ACTION_MOTION_CONTROLS); } @@ -470,35 +442,13 @@ public final class EmulationActivity extends AppCompatActivity } } - @Override - public boolean onCreateOptionsMenu(Menu menu) + public void showOverlayControlsMenu(@NonNull View anchor) { - // Inflate the menu; this adds items to the action bar if it is present. - if (sIsGameCubeGame) - { - getMenuInflater().inflate(R.menu.menu_emulation, menu); - } - else - { - getMenuInflater().inflate(R.menu.menu_emulation_wii, menu); - } + PopupMenu popup = new PopupMenu(this, anchor); + Menu menu = popup.getMenu(); - mPauseEmulationButton = menu.findItem(R.id.menu_emulation_pause); - mUnpauseEmulationButton = menu.findItem(R.id.menu_emulation_unpause); - - if (sUserPausedEmulation) - { - showUnpauseEmulationButton(); - } - - if (mSettings.getSection(SettingsFile.FILE_NAME_DOLPHIN, Settings.SECTION_INI_CORE) - .getBoolean(SettingsFile.KEY_ENABLE_SAVE_STATES, false)) - { - menu.findItem(R.id.menu_quicksave).setVisible(true); - menu.findItem(R.id.menu_quickload).setVisible(true); - menu.findItem(R.id.menu_emulation_save_root).setVisible(true); - menu.findItem(R.id.menu_emulation_load_root).setVisible(true); - } + int id = sIsGameCubeGame ? R.menu.menu_overlay_controls_gc : R.menu.menu_overlay_controls_wii; + popup.getMenuInflater().inflate(id, menu); // Populate the checkbox value for joystick center on touch menu.findItem(R.id.menu_emulation_joystick_rel_center) @@ -506,7 +456,9 @@ public final class EmulationActivity extends AppCompatActivity menu.findItem(R.id.menu_emulation_rumble) .setChecked(mPreferences.getBoolean("phoneRumble", true)); - return true; + popup.setOnMenuItemClickListener(this::onOptionsItemSelected); + + popup.show(); } @SuppressWarnings("WrongConstant") @@ -735,6 +687,8 @@ public final class EmulationActivity extends AppCompatActivity } else { + closeSubmenu(); + closeMenu(); mEmulationFragment.startConfiguringControls(); } } diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/MenuFragment.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/MenuFragment.java index 2e55d0df70..256a1a8188 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/MenuFragment.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/MenuFragment.java @@ -1,5 +1,6 @@ package org.dolphinemu.dolphinemu.fragments; +import android.content.pm.PackageManager; import android.os.Bundle; import android.util.SparseIntArray; import android.view.LayoutInflater; @@ -19,8 +20,10 @@ import org.dolphinemu.dolphinemu.features.settings.utils.SettingsFile; 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 +41,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); } @@ -82,6 +89,21 @@ public final class MenuFragment extends Fragment implements View.OnClickListener 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); + } + + // 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); + } + for (int childIndex = 0; childIndex < options.getChildCount(); childIndex++) { Button button = (Button) options.getChildAt(childIndex); @@ -89,11 +111,11 @@ public final class MenuFragment extends Fragment implements View.OnClickListener button.setOnClickListener(this); } - TextView titleText = rootView.findViewById(R.id.text_game_title); + 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; @@ -116,6 +138,8 @@ public final class MenuFragment extends Fragment implements View.OnClickListener public void onClick(View button) { int action = buttonsActionsMap.get(button.getId()); + EmulationActivity activity = (EmulationActivity) requireActivity(); + if (action == EmulationActivity.MENU_ACTION_PAUSE_EMULATION) { EmulationActivity.setHasUserPausedEmulation(true); @@ -128,9 +152,15 @@ public final class MenuFragment extends Fragment implements View.OnClickListener NativeLibrary.UnPauseEmulation(); showPauseEmulationButton(); } + else if (action == EmulationActivity.MENU_ACTION_OVERLAY_CONTROLS) + { + // 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 >= 0) { - ((EmulationActivity) getActivity()).handleMenuAction(action); + activity.handleMenuAction(action); } } } -- cgit v1.2.3 From 7aa9222dac1321507e07fbe27fe47f1ea41b3e27 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Tue, 4 Aug 2020 15:43:35 +0200 Subject: Android: Hide Refresh Wii Remotes menu entry for GameCube games --- .../main/java/org/dolphinemu/dolphinemu/fragments/MenuFragment.java | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'Source/Android/app/src/main/java/org') diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/MenuFragment.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/MenuFragment.java index 256a1a8188..36eb22ffd5 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/MenuFragment.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/MenuFragment.java @@ -96,6 +96,11 @@ public final class MenuFragment extends Fragment implements View.OnClickListener 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) != -- cgit v1.2.3 From 1fdabc74812a9589b32e6ea1f91f9eb1f35c9157 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Fri, 7 Aug 2020 00:36:11 +0200 Subject: Android: Exit emulation by long pressing Back --- .../dolphinemu/activities/EmulationActivity.java | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'Source/Android/app/src/main/java/org') diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java index e2b637ba4e..87ee2f8e2a 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java @@ -375,6 +375,18 @@ public final class EmulationActivity extends AppCompatActivity } } + @Override + public boolean onKeyLongPress(int keyCode, @NonNull KeyEvent event) + { + if (keyCode == KeyEvent.KEYCODE_BACK) + { + mEmulationFragment.stopEmulation(); + finish(); + return true; + } + return super.onKeyLongPress(keyCode, event); + } + @Override protected void onActivityResult(int requestCode, int resultCode, Intent result) { @@ -697,7 +709,7 @@ public final class EmulationActivity extends AppCompatActivity @Override public boolean dispatchKeyEvent(KeyEvent event) { - if (mMenuVisible) + if (mMenuVisible || event.getKeyCode() == KeyEvent.KEYCODE_BACK) { return super.dispatchKeyEvent(event); } @@ -707,14 +719,6 @@ public final class EmulationActivity extends AppCompatActivity switch (event.getAction()) { case KeyEvent.ACTION_DOWN: - // Handling the case where the back button is pressed. - if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) - { - onBackPressed(); - return true; - } - - // Normal key events. action = NativeLibrary.ButtonState.PRESSED; break; case KeyEvent.ACTION_UP: -- cgit v1.2.3 From 6b68b76aed90f0a2a275774375dd899c0f5874ab Mon Sep 17 00:00:00 2001 From: JosJuice Date: Sat, 8 Aug 2020 12:25:18 +0200 Subject: Android: Remove redundant pause/unpause code --- .../dolphinemu/activities/EmulationActivity.java | 23 -------------- .../dolphinemu/fragments/MenuFragment.java | 37 +++++++--------------- 2 files changed, 12 insertions(+), 48 deletions(-) (limited to 'Source/Android/app/src/main/java/org') diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java index 87ee2f8e2a..2e5430d9ee 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/EmulationActivity.java @@ -71,9 +71,6 @@ public final class EmulationActivity extends AppCompatActivity private Settings mSettings; - private MenuItem mPauseEmulationButton; - private MenuItem mUnpauseEmulationButton; - private boolean mDeviceHasTouchScreen; private boolean mMenuVisible; @@ -544,13 +541,11 @@ public final class EmulationActivity extends AppCompatActivity case MENU_ACTION_PAUSE_EMULATION: sUserPausedEmulation = true; NativeLibrary.PauseEmulation(); - showUnpauseEmulationButton(); return; case MENU_ACTION_UNPAUSE_EMULATION: sUserPausedEmulation = false; NativeLibrary.UnPauseEmulation(); - showPauseEmulationButton(); return; // Screenshot capturing @@ -653,28 +648,11 @@ public final class EmulationActivity extends AppCompatActivity } } - private void showPauseEmulationButton() - { - mUnpauseEmulationButton.setVisible(false); - mPauseEmulationButton.setVisible(true); - } - - private void showUnpauseEmulationButton() - { - mPauseEmulationButton.setVisible(false); - mUnpauseEmulationButton.setVisible(true); - } - public static boolean getHasUserPausedEmulation() { return sUserPausedEmulation; } - public static void setHasUserPausedEmulation(boolean value) - { - sUserPausedEmulation = value; - } - private void toggleJoystickRelCenter(boolean state) { final SharedPreferences.Editor editor = mPreferences.edit(); @@ -690,7 +668,6 @@ public final class EmulationActivity extends AppCompatActivity Rumble.setPhoneVibrator(state, this); } - private void editControlsPlacement() { if (mEmulationFragment.isConfiguringControls()) diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/MenuFragment.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/MenuFragment.java index 36eb22ffd5..6b46937667 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/MenuFragment.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/MenuFragment.java @@ -72,10 +72,7 @@ public final class MenuFragment extends Fragment implements View.OnClickListener 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) @@ -126,16 +123,12 @@ public final class MenuFragment extends Fragment implements View.OnClickListener 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") @@ -145,19 +138,7 @@ public final class MenuFragment extends Fragment implements View.OnClickListener int action = buttonsActionsMap.get(button.getId()); EmulationActivity activity = (EmulationActivity) requireActivity(); - if (action == EmulationActivity.MENU_ACTION_PAUSE_EMULATION) - { - EmulationActivity.setHasUserPausedEmulation(true); - NativeLibrary.PauseEmulation(); - showUnpauseEmulationButton(); - } - else if (action == EmulationActivity.MENU_ACTION_UNPAUSE_EMULATION) - { - EmulationActivity.setHasUserPausedEmulation(false); - NativeLibrary.UnPauseEmulation(); - showPauseEmulationButton(); - } - else if (action == EmulationActivity.MENU_ACTION_OVERLAY_CONTROLS) + if (action == EmulationActivity.MENU_ACTION_OVERLAY_CONTROLS) { // 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 @@ -167,5 +148,11 @@ public final class MenuFragment extends Fragment implements View.OnClickListener { activity.handleMenuAction(action); } + + if (action == EmulationActivity.MENU_ACTION_PAUSE_EMULATION || + action == EmulationActivity.MENU_ACTION_UNPAUSE_EMULATION) + { + updatePauseUnpauseVisibility(); + } } } -- cgit v1.2.3 From cecec756ec50f49802b594c59a44efe2af2328d7 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Sun, 16 Aug 2020 16:22:41 +0200 Subject: Android: Always show Exit Emulation at bottom of menu To make it easier to access on touchscreens. --- .../dolphinemu/fragments/MenuFragment.java | 26 ++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'Source/Android/app/src/main/java/org') diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/MenuFragment.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/MenuFragment.java index 6b46937667..2d053a99d7 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/MenuFragment.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/MenuFragment.java @@ -1,6 +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; @@ -62,6 +63,14 @@ public final class MenuFragment extends Fragment implements View.OnClickListener 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) { @@ -106,6 +115,21 @@ public final class MenuFragment extends Fragment implements View.OnClickListener 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); @@ -113,6 +137,8 @@ public final class MenuFragment extends Fragment implements View.OnClickListener button.setOnClickListener(this); } + 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) -- cgit v1.2.3