diff options
| author | sigmabeta <bastos.eder@gmail.com> | 2015-07-02 23:54:32 -0400 |
|---|---|---|
| committer | sigmabeta <bastos.eder@gmail.com> | 2015-07-14 17:45:00 -0400 |
| commit | 957691444d2c59939ecbf96b2ea0a52bccf720a9 (patch) | |
| tree | f93fd06d77cfeeb566721b718cd218a15fadf454 /Source/Android | |
| parent | a12a4520d8b677c160108a8e8ce93d8c937219d7 (diff) | |
Android TV: Replace toolbar on EmulationActivity with a full-screen menu.
Diffstat (limited to 'Source/Android')
7 files changed, 353 insertions, 66 deletions
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) { - 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(); + int themeId; + if (mDeviceHasTouchScreen) + { + themeId = R.style.DolphinEmulationGamecube; - // 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); + // Get a handle to the Window containing the UI. + mDecorView = getWindow().getDecorView(); - // 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; + // 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); - if (mSystemUiVisible) - { - getSupportActionBar().show(); - hideSystemUiAfterDelay(); - } - else + // Set the ActionBar to follow the navigation/status bar's visibility changes. + mDecorView.setOnSystemUiVisibilityChangeListener( + new View.OnSystemUiVisibilityChangeListener() + { + @Override + public void onSystemUiVisibilityChange(int flags) { - getSupportActionBar().hide(); + 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(); 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(); + stopEmulation(); + } + } - NativeLibrary.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 @@ +<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>
\ 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 @@ +<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> 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 @@ +<?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>
\ 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 @@ <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>
\ No newline at end of file |
