Android TV: Implement Save and Load state menus
This commit is contained in:
parent
d191d8851a
commit
c0315fcf78
|
@ -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.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -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++)
|
||||
{
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<objectAnimator
|
||||
android:propertyName="translationX"
|
||||
android:valueType="floatType"
|
||||
android:valueFrom="1280"
|
||||
android:valueTo="0"
|
||||
android:interpolator="@android:interpolator/decelerate_quad"
|
||||
android:duration="300"/>
|
||||
<objectAnimator
|
||||
android:propertyName="alpha"
|
||||
android:valueType="floatType"
|
||||
android:valueFrom="0"
|
||||
android:valueTo="1"
|
||||
android:interpolator="@android:interpolator/accelerate_quad"
|
||||
android:duration="300"/>
|
||||
</set>
|
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<!-- This animation is used ONLY when a submenu is replaced. -->
|
||||
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:propertyName="translationX"
|
||||
android:valueType="floatType"
|
||||
android:valueFrom="0"
|
||||
android:valueTo="1280"
|
||||
android:interpolator="@android:interpolator/decelerate_quad"
|
||||
android:duration="300"/>
|
||||
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:propertyName="alpha"
|
||||
android:valueType="floatType"
|
||||
android:valueFrom="1"
|
||||
android:valueTo="0"
|
||||
android:interpolator="@android:interpolator/decelerate_quad"
|
||||
android:duration="300"/>
|
||||
</set>
|
|
@ -0,0 +1,65 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#af000000"
|
||||
android:orientation="vertical"
|
||||
>
|
||||
|
||||
<GridLayout
|
||||
android:id="@+id/grid_state_slots"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:columnCount="3"
|
||||
android:rowCount="2"
|
||||
android:layout_gravity="center">
|
||||
|
||||
<Button
|
||||
android:id="@+id/menu_emulation_load_1"
|
||||
android:layout_width="128dp"
|
||||
android:layout_height="128dp"
|
||||
android:text="@string/overlay_slot1"
|
||||
style="@style/InGameMenuOption"
|
||||
/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/menu_emulation_load_2"
|
||||
android:layout_width="128dp"
|
||||
android:layout_height="128dp"
|
||||
android:text="@string/overlay_slot2"
|
||||
style="@style/InGameMenuOption"
|
||||
/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/menu_emulation_load_3"
|
||||
android:layout_width="128dp"
|
||||
android:layout_height="128dp"
|
||||
android:text="@string/overlay_slot3"
|
||||
style="@style/InGameMenuOption"
|
||||
/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/menu_emulation_load_4"
|
||||
android:layout_width="128dp"
|
||||
android:layout_height="128dp"
|
||||
android:text="@string/overlay_slot4"
|
||||
style="@style/InGameMenuOption"
|
||||
/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/menu_emulation_load_5"
|
||||
android:layout_width="128dp"
|
||||
android:layout_height="128dp"
|
||||
android:text="@string/overlay_slot5"
|
||||
style="@style/InGameMenuOption"
|
||||
/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/menu_emulation_load_6"
|
||||
android:layout_width="128dp"
|
||||
android:layout_height="128dp"
|
||||
android:text="@string/overlay_slot6"
|
||||
style="@style/InGameMenuOption"
|
||||
/>
|
||||
</GridLayout>
|
||||
</FrameLayout>
|
|
@ -0,0 +1,65 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#af000000"
|
||||
android:orientation="vertical"
|
||||
>
|
||||
|
||||
<GridLayout
|
||||
android:id="@+id/grid_state_slots"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:columnCount="3"
|
||||
android:rowCount="2"
|
||||
android:layout_gravity="center">
|
||||
|
||||
<Button
|
||||
android:id="@+id/menu_emulation_save_1"
|
||||
android:layout_width="128dp"
|
||||
android:layout_height="128dp"
|
||||
android:text="@string/overlay_slot1"
|
||||
style="@style/InGameMenuOption"
|
||||
/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/menu_emulation_save_2"
|
||||
android:layout_width="128dp"
|
||||
android:layout_height="128dp"
|
||||
android:text="@string/overlay_slot2"
|
||||
style="@style/InGameMenuOption"
|
||||
/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/menu_emulation_save_3"
|
||||
android:layout_width="128dp"
|
||||
android:layout_height="128dp"
|
||||
android:text="@string/overlay_slot3"
|
||||
style="@style/InGameMenuOption"
|
||||
/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/menu_emulation_save_4"
|
||||
android:layout_width="128dp"
|
||||
android:layout_height="128dp"
|
||||
android:text="@string/overlay_slot4"
|
||||
style="@style/InGameMenuOption"
|
||||
/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/menu_emulation_save_5"
|
||||
android:layout_width="128dp"
|
||||
android:layout_height="128dp"
|
||||
android:text="@string/overlay_slot5"
|
||||
style="@style/InGameMenuOption"
|
||||
/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/menu_emulation_save_6"
|
||||
android:layout_width="128dp"
|
||||
android:layout_height="128dp"
|
||||
android:text="@string/overlay_slot6"
|
||||
style="@style/InGameMenuOption"
|
||||
/>
|
||||
</GridLayout>
|
||||
</FrameLayout>
|
|
@ -66,6 +66,7 @@
|
|||
<string name="overlay_slot3">Slot 3</string>
|
||||
<string name="overlay_slot4">Slot 4</string>
|
||||
<string name="overlay_slot5">Slot 5</string>
|
||||
<string name="overlay_slot6">Slot 6</string>
|
||||
|
||||
<!-- Input Config Fragment -->
|
||||
<string name="input_settings">Input</string>
|
||||
|
|
Loading…
Reference in New Issue