summaryrefslogtreecommitdiff
path: root/Source/Android/app/src/main/java
diff options
context:
space:
mode:
authorJosJuice <josjuice@gmail.com>2021-08-10 13:51:32 +0200
committerJosJuice <josjuice@gmail.com>2021-09-16 18:48:39 +0200
commit404eb13e2f5252739a4a778bc549abc1867f284e (patch)
treedbd5b2005e32f6bff11ddcc54dcfe491f710dd7c /Source/Android/app/src/main/java
parent6934b9a21dea3615950affc8bfacf7e72dbc8fd9 (diff)
Android: Add the ability to add cheats
Diffstat (limited to 'Source/Android/app/src/main/java')
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/model/ARCheat.java7
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/model/CheatsViewModel.java103
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/model/GeckoCheat.java7
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/model/PatchCheat.java7
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/ActionViewHolder.java60
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatDetailsFragment.java12
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatItem.java1
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatsAdapter.java61
-rw-r--r--Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsAdapter.java2
9 files changed, 230 insertions, 30 deletions
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/model/ARCheat.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/model/ARCheat.java
index 24b74b489a..8a168e8bc5 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/model/ARCheat.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/model/ARCheat.java
@@ -10,6 +10,11 @@ public class ARCheat extends AbstractCheat
@Keep
private final long mPointer;
+ public ARCheat()
+ {
+ mPointer = createNew();
+ }
+
@Keep
private ARCheat(long pointer)
{
@@ -19,6 +24,8 @@ public class ARCheat extends AbstractCheat
@Override
public native void finalize();
+ private native long createNew();
+
public boolean supportsCreator()
{
return false;
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/model/CheatsViewModel.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/model/CheatsViewModel.java
index cdd68221c6..f405c427a5 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/model/CheatsViewModel.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/model/CheatsViewModel.java
@@ -6,20 +6,25 @@ import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
+import java.util.ArrayList;
+import java.util.Collections;
+
public class CheatsViewModel extends ViewModel
{
private boolean mLoaded = false;
private int mSelectedCheatPosition = -1;
private final MutableLiveData<Cheat> mSelectedCheat = new MutableLiveData<>(null);
+ private final MutableLiveData<Boolean> mIsAdding = new MutableLiveData<>(false);
private final MutableLiveData<Boolean> mIsEditing = new MutableLiveData<>(false);
+ private final MutableLiveData<Integer> mCheatAddedEvent = new MutableLiveData<>(null);
private final MutableLiveData<Integer> mCheatChangedEvent = new MutableLiveData<>(null);
private final MutableLiveData<Boolean> mOpenDetailsViewEvent = new MutableLiveData<>(false);
- private PatchCheat[] mPatchCheats;
- private ARCheat[] mARCheats;
- private GeckoCheat[] mGeckoCheats;
+ private ArrayList<PatchCheat> mPatchCheats;
+ private ArrayList<ARCheat> mARCheats;
+ private ArrayList<GeckoCheat> mGeckoCheats;
private boolean mPatchCheatsNeedSaving = false;
private boolean mARCheatsNeedSaving = false;
@@ -30,9 +35,12 @@ public class CheatsViewModel extends ViewModel
if (mLoaded)
return;
- mPatchCheats = PatchCheat.loadCodes(gameID, revision);
- mARCheats = ARCheat.loadCodes(gameID, revision);
- mGeckoCheats = GeckoCheat.loadCodes(gameID, revision);
+ mPatchCheats = new ArrayList<>();
+ Collections.addAll(mPatchCheats, PatchCheat.loadCodes(gameID, revision));
+ mARCheats = new ArrayList<>();
+ Collections.addAll(mARCheats, ARCheat.loadCodes(gameID, revision));
+ mGeckoCheats = new ArrayList<>();
+ Collections.addAll(mGeckoCheats, GeckoCheat.loadCodes(gameID, revision));
for (PatchCheat cheat : mPatchCheats)
{
@@ -54,19 +62,19 @@ public class CheatsViewModel extends ViewModel
{
if (mPatchCheatsNeedSaving)
{
- PatchCheat.saveCodes(gameID, revision, mPatchCheats);
+ PatchCheat.saveCodes(gameID, revision, mPatchCheats.toArray(new PatchCheat[0]));
mPatchCheatsNeedSaving = false;
}
if (mARCheatsNeedSaving)
{
- ARCheat.saveCodes(gameID, revision, mARCheats);
+ ARCheat.saveCodes(gameID, revision, mARCheats.toArray(new ARCheat[0]));
mARCheatsNeedSaving = false;
}
if (mGeckoCheatsNeedSaving)
{
- GeckoCheat.saveCodes(gameID, revision, mGeckoCheats);
+ GeckoCheat.saveCodes(gameID, revision, mGeckoCheats.toArray(new GeckoCheat[0]));
mGeckoCheatsNeedSaving = false;
}
}
@@ -85,6 +93,56 @@ public class CheatsViewModel extends ViewModel
mSelectedCheatPosition = position;
}
+ public LiveData<Boolean> getIsAdding()
+ {
+ return mIsAdding;
+ }
+
+ public void startAddingCheat(Cheat cheat, int position)
+ {
+ mSelectedCheat.setValue(cheat);
+ mSelectedCheatPosition = position;
+
+ mIsAdding.setValue(true);
+ mIsEditing.setValue(true);
+ }
+
+ public void finishAddingCheat()
+ {
+ if (!mIsAdding.getValue())
+ throw new IllegalStateException();
+
+ mIsAdding.setValue(false);
+ mIsEditing.setValue(false);
+
+ Cheat cheat = mSelectedCheat.getValue();
+
+ if (cheat instanceof PatchCheat)
+ {
+ mPatchCheats.add((PatchCheat) mSelectedCheat.getValue());
+ cheat.setChangedCallback(() -> mPatchCheatsNeedSaving = true);
+ mPatchCheatsNeedSaving = true;
+ }
+ else if (cheat instanceof ARCheat)
+ {
+ mARCheats.add((ARCheat) mSelectedCheat.getValue());
+ cheat.setChangedCallback(() -> mPatchCheatsNeedSaving = true);
+ mARCheatsNeedSaving = true;
+ }
+ else if (cheat instanceof GeckoCheat)
+ {
+ mGeckoCheats.add((GeckoCheat) mSelectedCheat.getValue());
+ cheat.setChangedCallback(() -> mGeckoCheatsNeedSaving = true);
+ mGeckoCheatsNeedSaving = true;
+ }
+ else
+ {
+ throw new UnsupportedOperationException();
+ }
+
+ notifyCheatAdded();
+ }
+
public LiveData<Boolean> getIsEditing()
{
return mIsEditing;
@@ -93,6 +151,27 @@ public class CheatsViewModel extends ViewModel
public void setIsEditing(boolean isEditing)
{
mIsEditing.setValue(isEditing);
+
+ if (mIsAdding.getValue() && !isEditing)
+ {
+ mIsAdding.setValue(false);
+ setSelectedCheat(null, -1);
+ }
+ }
+
+ /**
+ * When a cheat is added, the integer stored in the returned LiveData
+ * changes to the position of that cheat, then changes back to null.
+ */
+ public LiveData<Integer> getCheatAddedEvent()
+ {
+ return mCheatAddedEvent;
+ }
+
+ private void notifyCheatAdded()
+ {
+ mCheatAddedEvent.setValue(mSelectedCheatPosition);
+ mCheatAddedEvent.setValue(null);
}
/**
@@ -132,17 +211,17 @@ public class CheatsViewModel extends ViewModel
mOpenDetailsViewEvent.setValue(false);
}
- public Cheat[] getPatchCheats()
+ public ArrayList<PatchCheat> getPatchCheats()
{
return mPatchCheats;
}
- public ARCheat[] getARCheats()
+ public ArrayList<ARCheat> getARCheats()
{
return mARCheats;
}
- public Cheat[] getGeckoCheats()
+ public ArrayList<GeckoCheat> getGeckoCheats()
{
return mGeckoCheats;
}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/model/GeckoCheat.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/model/GeckoCheat.java
index 1847daa40d..19573723b6 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/model/GeckoCheat.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/model/GeckoCheat.java
@@ -10,6 +10,11 @@ public class GeckoCheat extends AbstractCheat
@Keep
private final long mPointer;
+ public GeckoCheat()
+ {
+ mPointer = createNew();
+ }
+
@Keep
private GeckoCheat(long pointer)
{
@@ -19,6 +24,8 @@ public class GeckoCheat extends AbstractCheat
@Override
public native void finalize();
+ private native long createNew();
+
public boolean supportsCreator()
{
return true;
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/model/PatchCheat.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/model/PatchCheat.java
index 52d88413dd..9dcb9f8111 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/model/PatchCheat.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/model/PatchCheat.java
@@ -10,6 +10,11 @@ public class PatchCheat extends AbstractCheat
@Keep
private final long mPointer;
+ public PatchCheat()
+ {
+ mPointer = createNew();
+ }
+
@Keep
private PatchCheat(long pointer)
{
@@ -19,6 +24,8 @@ public class PatchCheat extends AbstractCheat
@Override
public native void finalize();
+ private native long createNew();
+
public boolean supportsCreator()
{
return false;
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/ActionViewHolder.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/ActionViewHolder.java
new file mode 100644
index 0000000000..72380f8ab1
--- /dev/null
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/ActionViewHolder.java
@@ -0,0 +1,60 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+package org.dolphinemu.dolphinemu.features.cheats.ui;
+
+import android.view.View;
+import android.widget.TextView;
+
+import androidx.annotation.NonNull;
+
+import org.dolphinemu.dolphinemu.R;
+import org.dolphinemu.dolphinemu.features.cheats.model.ARCheat;
+import org.dolphinemu.dolphinemu.features.cheats.model.CheatsViewModel;
+import org.dolphinemu.dolphinemu.features.cheats.model.GeckoCheat;
+import org.dolphinemu.dolphinemu.features.cheats.model.PatchCheat;
+
+public class ActionViewHolder extends CheatItemViewHolder implements View.OnClickListener
+{
+ private final TextView mName;
+
+ private CheatsViewModel mViewModel;
+ private int mString;
+ private int mPosition;
+
+ public ActionViewHolder(@NonNull View itemView)
+ {
+ super(itemView);
+
+ mName = itemView.findViewById(R.id.text_setting_name);
+
+ itemView.setOnClickListener(this);
+ }
+
+ public void bind(CheatsViewModel viewModel, CheatItem item, int position)
+ {
+ mViewModel = viewModel;
+ mString = item.getString();
+ mPosition = position;
+
+ mName.setText(mString);
+ }
+
+ public void onClick(View root)
+ {
+ if (mString == R.string.cheats_add_ar)
+ {
+ mViewModel.startAddingCheat(new ARCheat(), mPosition);
+ mViewModel.openDetailsView();
+ }
+ else if (mString == R.string.cheats_add_gecko)
+ {
+ mViewModel.startAddingCheat(new GeckoCheat(), mPosition);
+ mViewModel.openDetailsView();
+ }
+ else if (mString == R.string.cheats_add_patch)
+ {
+ mViewModel.startAddingCheat(new PatchCheat(), mPosition);
+ mViewModel.openDetailsView();
+ }
+ }
+}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatDetailsFragment.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatDetailsFragment.java
index 2a2896251a..3de19df37a 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatDetailsFragment.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatDetailsFragment.java
@@ -94,8 +94,16 @@ public class CheatDetailsFragment extends Fragment
switch (result)
{
case Cheat.TRY_SET_SUCCESS:
- mViewModel.notifySelectedCheatChanged();
- mViewModel.setIsEditing(false);
+ if (mViewModel.getIsAdding().getValue())
+ {
+ mViewModel.finishAddingCheat();
+ onSelectedCheatUpdated(mCheat);
+ }
+ else
+ {
+ mViewModel.notifySelectedCheatChanged();
+ mViewModel.setIsEditing(false);
+ }
break;
case Cheat.TRY_SET_FAIL_NO_NAME:
mEditName.setError(getString(R.string.cheats_error_no_name));
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatItem.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatItem.java
index dd3ee76ab0..b293cd84d1 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatItem.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatItem.java
@@ -11,6 +11,7 @@ public class CheatItem
{
public static final int TYPE_CHEAT = 0;
public static final int TYPE_HEADER = 1;
+ public static final int TYPE_ACTION = 2;
private final @Nullable Cheat mCheat;
private final int mString;
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatsAdapter.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatsAdapter.java
index f0431c29a6..3406e1b692 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatsAdapter.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatsAdapter.java
@@ -11,8 +11,12 @@ import androidx.lifecycle.LifecycleOwner;
import androidx.recyclerview.widget.RecyclerView;
import org.dolphinemu.dolphinemu.R;
-import org.dolphinemu.dolphinemu.features.cheats.model.Cheat;
+import org.dolphinemu.dolphinemu.features.cheats.model.ARCheat;
import org.dolphinemu.dolphinemu.features.cheats.model.CheatsViewModel;
+import org.dolphinemu.dolphinemu.features.cheats.model.GeckoCheat;
+import org.dolphinemu.dolphinemu.features.cheats.model.PatchCheat;
+
+import java.util.ArrayList;
public class CheatsAdapter extends RecyclerView.Adapter<CheatItemViewHolder>
{
@@ -22,6 +26,12 @@ public class CheatsAdapter extends RecyclerView.Adapter<CheatItemViewHolder>
{
mViewModel = viewModel;
+ mViewModel.getCheatAddedEvent().observe(owner, (position) ->
+ {
+ if (position != null)
+ notifyItemInserted(position);
+ });
+
mViewModel.getCheatChangedEvent().observe(owner, (position) ->
{
if (position != null)
@@ -43,6 +53,9 @@ public class CheatsAdapter extends RecyclerView.Adapter<CheatItemViewHolder>
case CheatItem.TYPE_HEADER:
View headerView = inflater.inflate(R.layout.list_item_header, parent, false);
return new HeaderViewHolder(headerView);
+ case CheatItem.TYPE_ACTION:
+ View actionView = inflater.inflate(R.layout.list_item_submenu, parent, false);
+ return new ActionViewHolder(actionView);
default:
throw new UnsupportedOperationException();
}
@@ -57,8 +70,8 @@ public class CheatsAdapter extends RecyclerView.Adapter<CheatItemViewHolder>
@Override
public int getItemCount()
{
- return mViewModel.getARCheats().length + mViewModel.getGeckoCheats().length +
- mViewModel.getPatchCheats().length + 3;
+ return mViewModel.getARCheats().size() + mViewModel.getGeckoCheats().size() +
+ mViewModel.getPatchCheats().size() + 6;
}
@Override
@@ -69,32 +82,50 @@ public class CheatsAdapter extends RecyclerView.Adapter<CheatItemViewHolder>
private CheatItem getItemAt(int position)
{
+ // Patches
+
if (position == 0)
return new CheatItem(CheatItem.TYPE_HEADER, R.string.cheats_header_patch);
position -= 1;
- Cheat[] patchCheats = mViewModel.getPatchCheats();
- if (position < patchCheats.length)
- return new CheatItem(patchCheats[position]);
- position -= patchCheats.length;
+ ArrayList<PatchCheat> patchCheats = mViewModel.getPatchCheats();
+ if (position < patchCheats.size())
+ return new CheatItem(patchCheats.get(position));
+ position -= patchCheats.size();
+
+ if (position == 0)
+ return new CheatItem(CheatItem.TYPE_ACTION, R.string.cheats_add_patch);
+ position -= 1;
+
+ // AR codes
if (position == 0)
return new CheatItem(CheatItem.TYPE_HEADER, R.string.cheats_header_ar);
position -= 1;
- Cheat[] arCheats = mViewModel.getARCheats();
- if (position < arCheats.length)
- return new CheatItem(arCheats[position]);
- position -= arCheats.length;
+ ArrayList<ARCheat> arCheats = mViewModel.getARCheats();
+ if (position < arCheats.size())
+ return new CheatItem(arCheats.get(position));
+ position -= arCheats.size();
+
+ if (position == 0)
+ return new CheatItem(CheatItem.TYPE_ACTION, R.string.cheats_add_ar);
+ position -= 1;
+
+ // Gecko codes
if (position == 0)
return new CheatItem(CheatItem.TYPE_HEADER, R.string.cheats_header_gecko);
position -= 1;
- Cheat[] geckoCheats = mViewModel.getGeckoCheats();
- if (position < geckoCheats.length)
- return new CheatItem(geckoCheats[position]);
- position -= geckoCheats.length;
+ ArrayList<GeckoCheat> geckoCheats = mViewModel.getGeckoCheats();
+ if (position < geckoCheats.size())
+ return new CheatItem(geckoCheats.get(position));
+ position -= geckoCheats.size();
+
+ if (position == 0)
+ return new CheatItem(CheatItem.TYPE_ACTION, R.string.cheats_add_gecko);
+ position -= 1;
throw new IndexOutOfBoundsException();
}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsAdapter.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsAdapter.java
index e216330280..753dddf522 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsAdapter.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsAdapter.java
@@ -99,7 +99,7 @@ public final class SettingsAdapter extends RecyclerView.Adapter<SettingViewHolde
return new SliderViewHolder(view, this, mContext);
case SettingsItem.TYPE_SUBMENU:
- view = inflater.inflate(R.layout.list_item_setting_submenu, parent, false);
+ view = inflater.inflate(R.layout.list_item_submenu, parent, false);
return new SubmenuViewHolder(view, this);
case SettingsItem.TYPE_INPUT_BINDING: