Android TV: Replace toolbar on EmulationActivity with a full-screen menu.
This commit is contained in:
parent
a12a4520d8
commit
957691444d
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
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"
|
||||
android:visibility="invisible"/>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/layout_ingame_menu"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#af000000"
|
||||
android:orientation="horizontal"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible"
|
||||
android:baselineAligned="false">
|
||||
|
||||
<fragment
|
||||
android:id="@+id/fragment_menu"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:name="org.dolphinemu.dolphinemu.fragments.MenuFragment"
|
||||
tools:layout="@layout/fragment_ingame_menu"/>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/frame_submenu"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="2"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/image_screenshot"
|
||||
android:transitionName="image_game_screenshot"/>
|
||||
|
||||
</FrameLayout>
|
|
@ -0,0 +1,14 @@
|
|||
<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"
|
||||
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"/>
|
||||
</FrameLayout>
|
|
@ -0,0 +1,64 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:padding="32dp">
|
||||
|
||||
<Button
|
||||
android:id="@+id/menu_take_screenshot"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/overlay_screenshot"
|
||||
android:layout_margin="8dp"
|
||||
style="@style/InGameMenuOption"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/menu_quicksave"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/emulation_quicksave"
|
||||
android:layout_margin="8dp"
|
||||
style="@style/InGameMenuOption"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/menu_quickload"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/emulation_quickload"
|
||||
android:layout_margin="8dp"
|
||||
style="@style/InGameMenuOption"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/menu_emulation_save_root"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/overlay_savestate"
|
||||
android:layout_margin="8dp"
|
||||
style="@style/InGameMenuOption"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/menu_emulation_load_root"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/overlay_loadstate"
|
||||
android:layout_margin="8dp"
|
||||
style="@style/InGameMenuOption"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/menu_ingame_settings"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/settings"
|
||||
android:layout_margin="8dp"
|
||||
style="@style/InGameMenuOption"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/menu_exit"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/overlay_exit_emulation"
|
||||
android:layout_margin="8dp"
|
||||
style="@style/InGameMenuOption"/>
|
||||
|
||||
</LinearLayout>
|
|
@ -95,9 +95,43 @@
|
|||
<item name="colorAccent">@color/dolphin_accent_wiiware</item>
|
||||
</style>
|
||||
|
||||
<style name="DolphinEmulationTvBase" parent="Theme.AppCompat.NoActionBar">
|
||||
<item name="colorPrimary">@color/dolphin_blue</item>
|
||||
<item name="colorPrimaryDark">@color/dolphin_blue_dark</item>
|
||||
<item name="android:windowTranslucentNavigation">true</item>
|
||||
|
||||
<item name="android:windowBackground">@android:color/black</item>
|
||||
|
||||
<!--enable window content transitions-->
|
||||
<item name="android:windowContentTransitions">true</item>
|
||||
<item name="android:windowAllowEnterTransitionOverlap">true</item>
|
||||
<item name="android:windowAllowReturnTransitionOverlap">true</item>
|
||||
</style>
|
||||
|
||||
<!-- Inherit from the Base Dolphin Emulation Theme-->
|
||||
<style name="DolphinEmulationTvWii" parent="DolphinEmulationTvBase">
|
||||
<item name="colorAccent">@color/dolphin_accent_wii</item>
|
||||
</style>
|
||||
|
||||
<style name="DolphinEmulationTvGamecube" parent="DolphinEmulationTvBase">
|
||||
<item name="colorAccent">@color/dolphin_accent_gamecube</item>
|
||||
</style>
|
||||
|
||||
<style name="DolphinEmulationTvWiiware" parent="DolphinEmulationTvBase">
|
||||
<item name="colorAccent">@color/dolphin_accent_wiiware</item>
|
||||
</style>
|
||||
|
||||
<!-- Hax to make Tablayout render icons -->
|
||||
<style name="MyCustomTextAppearance" parent="TextAppearance.Design.Tab">
|
||||
<item name="textAllCaps">false</item>
|
||||
</style>
|
||||
|
||||
<style name="InGameMenuOption" parent="Widget.AppCompat.Button.Borderless">
|
||||
<item name="android:textSize">24dp</item>
|
||||
<item name="android:fontFamily">sans-serif-condensed</item>
|
||||
<item name="android:textColor">@android:color/white</item>
|
||||
<item name="android:textAllCaps">false</item>
|
||||
<item name="android:gravity">left</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
Loading…
Reference in New Issue