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 e2804de9c9..f7608506ed 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
@@ -1,5 +1,6 @@
package org.dolphinemu.dolphinemu.activities;
+import android.app.Fragment;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
@@ -26,6 +27,8 @@ import com.squareup.picasso.Picasso;
import org.dolphinemu.dolphinemu.NativeLibrary;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.fragments.EmulationFragment;
+import org.dolphinemu.dolphinemu.fragments.LoadStateFragment;
+import org.dolphinemu.dolphinemu.fragments.SaveStateFragment;
import java.util.List;
@@ -37,13 +40,15 @@ public final class EmulationActivity extends AppCompatActivity
private FrameLayout mFrameEmulation;
private LinearLayout mMenuLayout;
- private boolean mDeviceHasTouchScreen;
- private boolean mSystemUiVisible;
- private boolean mMenuVisible;
+ private String mMenuFragmentTag;
// So that MainActivity knows which view to invalidate before the return animation.
private int mPosition;
+ private boolean mDeviceHasTouchScreen;
+ private boolean mSystemUiVisible;
+ private boolean mMenuVisible;
+
private static Interpolator sDecelerator = new DecelerateInterpolator();
private static Interpolator sAccelerator = new AccelerateInterpolator();
@@ -235,7 +240,14 @@ public final class EmulationActivity extends AppCompatActivity
{
if (!mDeviceHasTouchScreen)
{
- toggleMenu();
+ if (mMenuFragmentTag != null)
+ {
+ removeMenu();
+ }
+ else
+ {
+ toggleMenu();
+ }
}
else
{
@@ -390,6 +402,15 @@ public final class EmulationActivity extends AppCompatActivity
NativeLibrary.LoadState(9);
return;
+ // TV Menu only
+ case R.id.menu_emulation_save_root:
+ showMenu(SaveStateFragment.FRAGMENT_ID);
+ return;
+
+ case R.id.menu_emulation_load_root:
+ showMenu(LoadStateFragment.FRAGMENT_ID);
+ return;
+
// Save state slots
case R.id.menu_emulation_save_1:
NativeLibrary.SaveState(0);
@@ -549,4 +570,73 @@ public final class EmulationActivity extends AppCompatActivity
}
});
}
+
+ private void showMenu(int menuId)
+ {
+ Fragment fragment;
+
+ switch (menuId)
+ {
+ case SaveStateFragment.FRAGMENT_ID:
+ fragment = SaveStateFragment.newInstance();
+ mMenuFragmentTag = SaveStateFragment.FRAGMENT_TAG;
+ break;
+
+ case LoadStateFragment.FRAGMENT_ID:
+ fragment = LoadStateFragment.newInstance();
+ mMenuFragmentTag = LoadStateFragment.FRAGMENT_TAG;
+ break;
+
+ default:
+ return;
+ }
+
+ getFragmentManager().beginTransaction()
+ .setCustomAnimations(R.animator.menu_slide_in, R.animator.menu_slide_out)
+ .replace(R.id.frame_submenu, fragment, mMenuFragmentTag)
+ .commit();
+ }
+
+ private void removeMenu()
+ {
+ if (mMenuFragmentTag != null)
+ {
+ final Fragment fragment = getFragmentManager().findFragmentByTag(mMenuFragmentTag);
+
+ if (fragment != null)
+ {
+ // When removing a fragment without replacement, its aniimation must be done
+ // manually beforehand.
+ fragment.getView().animate()
+ .withLayer()
+ .setDuration(200)
+ .setInterpolator(sAccelerator)
+ .alpha(0.0f)
+ .translationX(600.0f)
+ .withEndAction(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ if (mMenuVisible)
+ {
+ getFragmentManager().beginTransaction()
+ .remove(fragment)
+ .commit();
+ }
+ }
+ });
+ }
+ else
+ {
+ Log.e("DolphinEmu", "[EmulationActivity] Fragment not found, can't remove.");
+ }
+
+ mMenuFragmentTag = null;
+ }
+ else
+ {
+ Log.e("DolphinEmu", "[EmulationActivity] Fragment Tag empty.");
+ }
+ }
}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/LoadStateFragment.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/LoadStateFragment.java
new file mode 100644
index 0000000000..bbd9807b9b
--- /dev/null
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/LoadStateFragment.java
@@ -0,0 +1,55 @@
+package org.dolphinemu.dolphinemu.fragments;
+
+import android.app.Fragment;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.GridLayout;
+
+import org.dolphinemu.dolphinemu.BuildConfig;
+import org.dolphinemu.dolphinemu.R;
+import org.dolphinemu.dolphinemu.activities.EmulationActivity;
+
+public final class LoadStateFragment extends Fragment implements View.OnClickListener
+{
+ public static final String FRAGMENT_TAG = BuildConfig.APPLICATION_ID + ".load_state";
+ public static final int FRAGMENT_ID = R.layout.fragment_state_load;
+
+ public static LoadStateFragment newInstance()
+ {
+ LoadStateFragment fragment = new LoadStateFragment();
+
+ // TODO Add any appropriate arguments to this fragment.
+
+ return fragment;
+ }
+
+ @Nullable
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
+ {
+ View rootView = inflater.inflate(FRAGMENT_ID, container, false);
+
+ GridLayout grid = (GridLayout) rootView.findViewById(R.id.grid_state_slots);
+ for (int childIndex = 0; childIndex < grid.getChildCount(); childIndex++)
+ {
+ Button button = (Button) grid.getChildAt(childIndex);
+
+ button.setOnClickListener(this);
+ }
+
+ // So that item clicked to start this Fragment is no longer the focused item.
+ grid.requestFocus();
+
+ return rootView;
+ }
+
+ @Override
+ public void onClick(View button)
+ {
+ ((EmulationActivity) getActivity()).onMenuItemClicked(button.getId());
+ }
+}
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 f57ca36ede..5c847ee1b1 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
@@ -9,16 +9,20 @@ import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
+import org.dolphinemu.dolphinemu.BuildConfig;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.activities.EmulationActivity;
public final class MenuFragment extends Fragment implements View.OnClickListener
{
+ public static final String FRAGMENT_TAG = BuildConfig.APPLICATION_ID + ".ingame_menu";
+ public static final int FRAGMENT_ID = R.layout.fragment_ingame_menu;
+
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
- LinearLayout rootView = (LinearLayout) inflater.inflate(R.layout.fragment_ingame_menu, container, false);
+ LinearLayout rootView = (LinearLayout) inflater.inflate(FRAGMENT_ID, container, false);
for (int childIndex = 0; childIndex < rootView.getChildCount(); childIndex++)
{
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/SaveStateFragment.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/SaveStateFragment.java
new file mode 100644
index 0000000000..a5e9e6d441
--- /dev/null
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/SaveStateFragment.java
@@ -0,0 +1,55 @@
+package org.dolphinemu.dolphinemu.fragments;
+
+import android.app.Fragment;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.GridLayout;
+
+import org.dolphinemu.dolphinemu.BuildConfig;
+import org.dolphinemu.dolphinemu.R;
+import org.dolphinemu.dolphinemu.activities.EmulationActivity;
+
+public final class SaveStateFragment extends Fragment implements View.OnClickListener
+{
+ public static final String FRAGMENT_TAG = BuildConfig.APPLICATION_ID + ".save_state";
+ public static final int FRAGMENT_ID = R.layout.fragment_state_save;
+
+ public static SaveStateFragment newInstance()
+ {
+ SaveStateFragment fragment = new SaveStateFragment();
+
+ // TODO Add any appropriate arguments to this fragment.
+
+ return fragment;
+ }
+
+ @Nullable
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
+ {
+ View rootView = inflater.inflate(FRAGMENT_ID, container, false);
+
+ GridLayout grid = (GridLayout) rootView.findViewById(R.id.grid_state_slots);
+ for (int childIndex = 0; childIndex < grid.getChildCount(); childIndex++)
+ {
+ Button button = (Button) grid.getChildAt(childIndex);
+
+ button.setOnClickListener(this);
+ }
+
+ // So that item clicked to start this Fragment is no longer the focused item.
+ grid.requestFocus();
+
+ return rootView;
+ }
+
+ @Override
+ public void onClick(View button)
+ {
+ ((EmulationActivity) getActivity()).onMenuItemClicked(button.getId());
+ }
+}
diff --git a/Source/Android/app/src/main/res/animator/menu_slide_in.xml b/Source/Android/app/src/main/res/animator/menu_slide_in.xml
new file mode 100644
index 0000000000..e6f9ae6d8e
--- /dev/null
+++ b/Source/Android/app/src/main/res/animator/menu_slide_in.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/Source/Android/app/src/main/res/animator/menu_slide_out.xml b/Source/Android/app/src/main/res/animator/menu_slide_out.xml
new file mode 100644
index 0000000000..85c2556e48
--- /dev/null
+++ b/Source/Android/app/src/main/res/animator/menu_slide_out.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Source/Android/app/src/main/res/layout/fragment_state_load.xml b/Source/Android/app/src/main/res/layout/fragment_state_load.xml
new file mode 100644
index 0000000000..1b04c6ce59
--- /dev/null
+++ b/Source/Android/app/src/main/res/layout/fragment_state_load.xml
@@ -0,0 +1,65 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Source/Android/app/src/main/res/layout/fragment_state_save.xml b/Source/Android/app/src/main/res/layout/fragment_state_save.xml
new file mode 100644
index 0000000000..b5ca1e1ed8
--- /dev/null
+++ b/Source/Android/app/src/main/res/layout/fragment_state_save.xml
@@ -0,0 +1,65 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Source/Android/app/src/main/res/values/strings.xml b/Source/Android/app/src/main/res/values/strings.xml
index 3843cfb9b1..1d26cd256d 100644
--- a/Source/Android/app/src/main/res/values/strings.xml
+++ b/Source/Android/app/src/main/res/values/strings.xml
@@ -66,6 +66,7 @@
Slot 3
Slot 4
Slot 5
+ Slot 6
Input