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 6b27c08c4a..00501e10d6 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
@@ -15,6 +15,7 @@ import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.FrameLayout;
import android.widget.ImageView;
+import android.widget.LinearLayout;
import com.squareup.picasso.Callback;
import com.squareup.picasso.Picasso;
@@ -29,10 +30,13 @@ public final class EmulationActivity extends AppCompatActivity
{
private View mDecorView;
private ImageView mImageView;
+
private FrameLayout mFrameEmulation;
+ private LinearLayout mMenuLayout;
private boolean mDeviceHasTouchScreen;
private boolean mSystemUiVisible;
+ private boolean mMenuVisible;
// So that MainActivity knows which view to invalidate before the return animation.
private int mPosition;
@@ -56,49 +60,61 @@ public final class EmulationActivity extends AppCompatActivity
@Override
protected void onCreate(Bundle savedInstanceState)
{
+ mDeviceHasTouchScreen = getPackageManager().hasSystemFeature("android.hardware.touchscreen");
+
+ int themeId;
+ if (mDeviceHasTouchScreen)
+ {
+ themeId = R.style.DolphinEmulationGamecube;
+
+ // Get a handle to the Window containing the UI.
+ mDecorView = getWindow().getDecorView();
+
+ // Set these options now so that the SurfaceView the game renders into is the right size.
+ mDecorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
+ View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
+ View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
+
+ // Set the ActionBar to follow the navigation/status bar's visibility changes.
+ mDecorView.setOnSystemUiVisibilityChangeListener(
+ new View.OnSystemUiVisibilityChangeListener()
+ {
+ @Override
+ public void onSystemUiVisibilityChange(int flags)
+ {
+ mSystemUiVisible = (flags & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0;
+
+ if (mSystemUiVisible)
+ {
+ getSupportActionBar().show();
+ hideSystemUiAfterDelay();
+ }
+ else
+ {
+ getSupportActionBar().hide();
+ }
+ }
+ }
+ );
+ }
+ else
+ {
+ themeId = R.style.DolphinEmulationTvGamecube;
+ }
+
+ setTheme(themeId);
super.onCreate(savedInstanceState);
// Picasso will take a while to load these big-ass screenshots. So don't run
// the animation until we say so.
postponeEnterTransition();
- mDeviceHasTouchScreen = getPackageManager().hasSystemFeature("android.hardware.touchscreen");
-
- // Get a handle to the Window containing the UI.
- mDecorView = getWindow().getDecorView();
-
- // Set these options now so that the SurfaceView the game renders into is the right size.
- mDecorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
- View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
- View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
-
- // Set the ActionBar to follow the navigation/status bar's visibility changes.
- mDecorView.setOnSystemUiVisibilityChangeListener(
- new View.OnSystemUiVisibilityChangeListener()
- {
- @Override
- public void onSystemUiVisibilityChange(int flags)
- {
- mSystemUiVisible = (flags & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0;
-
- if (mSystemUiVisible)
- {
- getSupportActionBar().show();
- hideSystemUiAfterDelay();
- }
- else
- {
- getSupportActionBar().hide();
- }
- }
- }
- );
-
setContentView(R.layout.activity_emulation);
mImageView = (ImageView) findViewById(R.id.image_screenshot);
mFrameContent = (FrameLayout) findViewById(R.id.frame_content);
mFrameEmulation = (FrameLayout) findViewById(R.id.frame_emulation_fragment);
+ mMenuLayout = (LinearLayout) findViewById(R.id.layout_ingame_menu);
Intent gameToEmulate = getIntent();
String path = gameToEmulate.getStringExtra("SelectedGame");
@@ -181,8 +197,11 @@ public final class EmulationActivity extends AppCompatActivity
{
super.onPostCreate(savedInstanceState);
- // Give the user a few seconds to see what the controls look like, then hide them.
- hideSystemUiAfterDelay();
+ if (mDeviceHasTouchScreen)
+ {
+ // Give the user a few seconds to see what the controls look like, then hide them.
+ hideSystemUiAfterDelay();
+ }
}
@Override
@@ -190,36 +209,88 @@ public final class EmulationActivity extends AppCompatActivity
{
super.onWindowFocusChanged(hasFocus);
- if (hasFocus)
+ if (mDeviceHasTouchScreen)
{
- hideSystemUiAfterDelay();
- }
- else
- {
- // If the window loses focus (i.e. a dialog box, or a popup menu is on screen
- // stop hiding the UI.
- mSystemUiHider.removeMessages(0);
+ if (hasFocus)
+ {
+ hideSystemUiAfterDelay();
+ }
+ else
+ {
+ // If the window loses focus (i.e. a dialog box, or a popup menu is on screen
+ // stop hiding the UI.
+ mSystemUiHider.removeMessages(0);
+ }
}
}
@Override
public void onBackPressed()
{
- if (!mDeviceHasTouchScreen && !mSystemUiVisible)
+ if (!mDeviceHasTouchScreen)
{
- showSystemUI();
+ toggleMenu();
}
else
{
- // Let the system handle it; i.e. quit the activity TODO or show "are you sure?" dialog.
- EmulationFragment fragment = (EmulationFragment) getFragmentManager()
- .findFragmentByTag(EmulationFragment.FRAGMENT_TAG);
- fragment.notifyEmulationStopped();
-
- NativeLibrary.StopEmulation();
+ stopEmulation();
}
}
+ private void toggleMenu()
+ {
+ if (mMenuVisible)
+ {
+ mMenuLayout.animate()
+ .withLayer()
+ .setDuration(200)
+ .alpha(0.0f)
+ .scaleX(1.1f)
+ .scaleY(1.1f)
+ .withEndAction(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ mMenuLayout.setVisibility(View.GONE);
+ mMenuVisible = false;
+ }
+ });
+ }
+ else
+ {
+ mMenuLayout.setVisibility(View.VISIBLE);
+
+ mMenuLayout.setScaleX(1.1f);
+ mMenuLayout.setScaleY(1.1f);
+ mMenuLayout.setAlpha(0.0f);
+
+ mMenuLayout.animate()
+ .withLayer()
+ .setDuration(300)
+ .alpha(1.0f)
+ .scaleX(1.0f)
+ .scaleY(1.0f)
+ .withEndAction(new Runnable()
+ {
+ @Override
+ public void run()
+ {
+ mMenuVisible = true;
+ }
+ });
+ }
+ }
+
+ private void stopEmulation()
+ {
+ EmulationFragment fragment = (EmulationFragment) getFragmentManager()
+ .findFragmentByTag(EmulationFragment.FRAGMENT_TAG);
+ fragment.notifyEmulationStopped();
+
+ NativeLibrary.StopEmulation();
+ }
+
public void exitWithAnimation()
{
runOnUiThread(new Runnable()
@@ -257,7 +328,7 @@ public final class EmulationActivity extends AppCompatActivity
mImageView.setVisibility(View.VISIBLE);
mImageView.animate()
.withLayer()
- .setDuration(500)
+ .setDuration(100)
.alpha(1.0f)
.withEndAction(afterShowingScreenshot);
}
@@ -284,7 +355,13 @@ public final class EmulationActivity extends AppCompatActivity
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
- switch (item.getItemId())
+ onMenuItemClicked(item.getItemId());
+ return true;
+ }
+
+ public void onMenuItemClicked(int id)
+ {
+ switch (id)
{
// Enable/Disable input overlay.
case R.id.menu_emulation_input_overlay:
@@ -294,67 +371,69 @@ public final class EmulationActivity extends AppCompatActivity
emulationFragment.toggleInputOverlayVisibility();
- return true;
+ return;
}
// Screenshot capturing
case R.id.menu_emulation_screenshot:
NativeLibrary.SaveScreenShot();
- return true;
+ return;
// Quicksave / Load
case R.id.menu_quicksave:
NativeLibrary.SaveState(9);
- return true;
+ return;
case R.id.menu_quickload:
NativeLibrary.LoadState(9);
- return true;
+ return;
// Save state slots
case R.id.menu_emulation_save_1:
NativeLibrary.SaveState(0);
- return true;
+ return;
case R.id.menu_emulation_save_2:
NativeLibrary.SaveState(1);
- return true;
+ return;
case R.id.menu_emulation_save_3:
NativeLibrary.SaveState(2);
- return true;
+ return;
case R.id.menu_emulation_save_4:
NativeLibrary.SaveState(3);
- return true;
+ return;
case R.id.menu_emulation_save_5:
NativeLibrary.SaveState(4);
- return true;
+ return;
// Load state slots
case R.id.menu_emulation_load_1:
NativeLibrary.LoadState(0);
- return true;
+ return;
case R.id.menu_emulation_load_2:
NativeLibrary.LoadState(1);
- return true;
+ return;
case R.id.menu_emulation_load_3:
NativeLibrary.LoadState(2);
- return true;
+ return;
case R.id.menu_emulation_load_4:
NativeLibrary.LoadState(3);
- return true;
+ return;
case R.id.menu_emulation_load_5:
NativeLibrary.LoadState(4);
- return true;
+ return;
- default:
- return super.onOptionsItemSelected(item);
+ case R.id.menu_exit:
+ toggleMenu();
+ stopEmulation();
+ return;
}
}
@@ -362,6 +441,11 @@ public final class EmulationActivity extends AppCompatActivity
@Override
public boolean dispatchKeyEvent(KeyEvent event)
{
+ if (mMenuVisible)
+ {
+ return super.dispatchKeyEvent(event);
+ }
+
int action = 0;
switch (event.getAction())
@@ -391,6 +475,11 @@ public final class EmulationActivity extends AppCompatActivity
@Override
public boolean dispatchGenericMotionEvent(MotionEvent event)
{
+ if (mMenuVisible)
+ {
+ return false;
+ }
+
if (((event.getSource() & InputDevice.SOURCE_CLASS_JOYSTICK) == 0))
{
return super.dispatchGenericMotionEvent(event);
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/EmulationFragment.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/EmulationFragment.java
index 9d23736cb6..1eb1684531 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/EmulationFragment.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/EmulationFragment.java
@@ -81,9 +81,12 @@ public final class EmulationFragment extends Fragment implements SurfaceHolder.C
mSurfaceView.getHolder().addCallback(this);
// If the input overlay was previously disabled, then don't show it.
- if (!mPreferences.getBoolean("showInputOverlay", true))
+ if (mInputOverlay != null)
{
- mInputOverlay.setVisibility(View.GONE);
+ if (!mPreferences.getBoolean("showInputOverlay", true))
+ {
+ mInputOverlay.setVisibility(View.GONE);
+ }
}
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
new file mode 100644
index 0000000000..f57ca36ede
--- /dev/null
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/MenuFragment.java
@@ -0,0 +1,38 @@
+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.LinearLayout;
+
+import org.dolphinemu.dolphinemu.R;
+import org.dolphinemu.dolphinemu.activities.EmulationActivity;
+
+public final class MenuFragment extends Fragment implements View.OnClickListener
+{
+ @Nullable
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
+ {
+ LinearLayout rootView = (LinearLayout) inflater.inflate(R.layout.fragment_ingame_menu, container, false);
+
+ for (int childIndex = 0; childIndex < rootView.getChildCount(); childIndex++)
+ {
+ Button button = (Button) rootView.getChildAt(childIndex);
+
+ button.setOnClickListener(this);
+ }
+
+ return rootView;
+ }
+
+ @Override
+ public void onClick(View button)
+ {
+ ((EmulationActivity) getActivity()).onMenuItemClicked(button.getId());
+ }
+}
diff --git a/Source/Android/app/src/main/res/layout-television/activity_emulation.xml b/Source/Android/app/src/main/res/layout-television/activity_emulation.xml
new file mode 100644
index 0000000000..8770751fee
--- /dev/null
+++ b/Source/Android/app/src/main/res/layout-television/activity_emulation.xml
@@ -0,0 +1,45 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Source/Android/app/src/main/res/layout-television/fragment_emulation.xml b/Source/Android/app/src/main/res/layout-television/fragment_emulation.xml
new file mode 100644
index 0000000000..787de65186
--- /dev/null
+++ b/Source/Android/app/src/main/res/layout-television/fragment_emulation.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
diff --git a/Source/Android/app/src/main/res/layout/fragment_ingame_menu.xml b/Source/Android/app/src/main/res/layout/fragment_ingame_menu.xml
new file mode 100644
index 0000000000..76572112fb
--- /dev/null
+++ b/Source/Android/app/src/main/res/layout/fragment_ingame_menu.xml
@@ -0,0 +1,64 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Source/Android/app/src/main/res/values/styles.xml b/Source/Android/app/src/main/res/values/styles.xml
index ba80861700..0fce839929 100644
--- a/Source/Android/app/src/main/res/values/styles.xml
+++ b/Source/Android/app/src/main/res/values/styles.xml
@@ -95,9 +95,43 @@
- @color/dolphin_accent_wiiware
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file