From 1470dfcf81e9e7f71b2548f6f7253423140e29dd Mon Sep 17 00:00:00 2001 From: JosJuice Date: Tue, 10 Aug 2021 15:42:35 +0200 Subject: [PATCH] Android: Add the ability to delete cheats --- .../cheats/model/CheatsViewModel.java | 36 +++++++++++++++++++ .../cheats/ui/CheatDetailsFragment.java | 16 +++++++++ .../features/cheats/ui/CheatsAdapter.java | 6 ++++ .../res/layout/fragment_cheat_details.xml | 15 ++++++-- .../app/src/main/res/values/strings.xml | 2 ++ 5 files changed, 73 insertions(+), 2 deletions(-) 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 f405c427a5..750c921c94 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 @@ -20,6 +20,7 @@ public class CheatsViewModel extends ViewModel private final MutableLiveData mCheatAddedEvent = new MutableLiveData<>(null); private final MutableLiveData mCheatChangedEvent = new MutableLiveData<>(null); + private final MutableLiveData mCheatDeletedEvent = new MutableLiveData<>(null); private final MutableLiveData mOpenDetailsViewEvent = new MutableLiveData<>(false); private ArrayList mPatchCheats; @@ -200,6 +201,41 @@ public class CheatsViewModel extends ViewModel mCheatChangedEvent.setValue(null); } + /** + * When a cheat is deleted, the integer stored in the returned LiveData + * changes to the position of that cheat, then changes back to null. + */ + public LiveData getCheatDeletedEvent() + { + return mCheatDeletedEvent; + } + + public void deleteSelectedCheat() + { + Cheat cheat = mSelectedCheat.getValue(); + int position = mSelectedCheatPosition; + + setSelectedCheat(null, -1); + + if (mPatchCheats.remove(cheat)) + mPatchCheatsNeedSaving = true; + if (mARCheats.remove(cheat)) + mARCheatsNeedSaving = true; + if (mGeckoCheats.remove(cheat)) + mGeckoCheatsNeedSaving = true; + + notifyCheatDeleted(position); + } + + /** + * Notifies that the cheat at the given position has been deleted. + */ + private void notifyCheatDeleted(int position) + { + mCheatDeletedEvent.setValue(position); + mCheatDeletedEvent.setValue(null); + } + public LiveData getOpenDetailsViewEvent() { return mOpenDetailsViewEvent; 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 3de19df37a..421b0aa094 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 @@ -13,6 +13,7 @@ import android.widget.TextView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.appcompat.app.AlertDialog; import androidx.fragment.app.Fragment; import androidx.lifecycle.LiveData; import androidx.lifecycle.ViewModelProvider; @@ -32,6 +33,7 @@ public class CheatDetailsFragment extends Fragment private TextView mLabelNotes; private EditText mEditNotes; private EditText mEditCode; + private Button mButtonDelete; private Button mButtonEdit; private Button mButtonCancel; private Button mButtonOk; @@ -59,6 +61,7 @@ public class CheatDetailsFragment extends Fragment mLabelNotes = view.findViewById(R.id.label_notes); mEditNotes = view.findViewById(R.id.edit_notes); mEditCode = view.findViewById(R.id.edit_code); + mButtonDelete = view.findViewById(R.id.button_delete); mButtonEdit = view.findViewById(R.id.button_edit); mButtonCancel = view.findViewById(R.id.button_cancel); mButtonOk = view.findViewById(R.id.button_ok); @@ -69,6 +72,7 @@ public class CheatDetailsFragment extends Fragment mViewModel.getSelectedCheat().observe(getViewLifecycleOwner(), this::onSelectedCheatUpdated); mViewModel.getIsEditing().observe(getViewLifecycleOwner(), this::onIsEditingUpdated); + mButtonDelete.setOnClickListener(this::onDeleteClicked); mButtonEdit.setOnClickListener((v) -> mViewModel.setIsEditing(true)); mButtonCancel.setOnClickListener((v) -> { @@ -84,6 +88,16 @@ public class CheatDetailsFragment extends Fragment mEditCode.setError(null); } + private void onDeleteClicked(View view) + { + AlertDialog.Builder builder = + new AlertDialog.Builder(requireContext(), R.style.DolphinDialogBase); + builder.setMessage(getString(R.string.cheats_delete_confirmation, mCheat.getName())); + builder.setPositiveButton(R.string.yes, (dialog, i) -> mViewModel.deleteSelectedCheat()); + builder.setNegativeButton(R.string.no, null); + builder.show(); + } + private void onOkClicked(View view) { clearEditErrors(); @@ -138,6 +152,7 @@ public class CheatDetailsFragment extends Fragment mEditNotes.setVisibility(notesVisibility); boolean userDefined = cheat != null && cheat.getUserDefined(); + mButtonDelete.setEnabled(userDefined); mButtonEdit.setEnabled(userDefined); // If the fragment was recreated while editing a cheat, it's vital that we @@ -162,6 +177,7 @@ public class CheatDetailsFragment extends Fragment mEditNotes.setEnabled(isEditing); mEditCode.setEnabled(isEditing); + mButtonDelete.setVisibility(isEditing ? View.GONE : View.VISIBLE); mButtonEdit.setVisibility(isEditing ? View.GONE : View.VISIBLE); mButtonCancel.setVisibility(isEditing ? View.VISIBLE : View.GONE); mButtonOk.setVisibility(isEditing ? View.VISIBLE : View.GONE); 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 3406e1b692..c12cd58c9f 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 @@ -37,6 +37,12 @@ public class CheatsAdapter extends RecyclerView.Adapter if (position != null) notifyItemChanged(position); }); + + mViewModel.getCheatDeletedEvent().observe(owner, (position) -> + { + if (position != null) + notifyItemRemoved(position); + }); } @NonNull diff --git a/Source/Android/app/src/main/res/layout/fragment_cheat_details.xml b/Source/Android/app/src/main/res/layout/fragment_cheat_details.xml index e970d829b2..c758b919ba 100644 --- a/Source/Android/app/src/main/res/layout/fragment_cheat_details.xml +++ b/Source/Android/app/src/main/res/layout/fragment_cheat_details.xml @@ -141,7 +141,18 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" app:barrierDirection="top" - app:constraint_referenced_ids="button_edit,button_cancel,button_ok" /> + app:constraint_referenced_ids="button_delete,button_edit,button_cancel,button_ok" /> + +