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 deleted file mode 100644 index 3335795c75..0000000000 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatsAdapter.java +++ /dev/null @@ -1,176 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -package org.dolphinemu.dolphinemu.features.cheats.ui; - -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; - -import androidx.annotation.NonNull; -import androidx.recyclerview.widget.RecyclerView; - -import org.dolphinemu.dolphinemu.R; -import org.dolphinemu.dolphinemu.databinding.ListItemCheatBinding; -import org.dolphinemu.dolphinemu.databinding.ListItemHeaderBinding; -import org.dolphinemu.dolphinemu.databinding.ListItemSubmenuBinding; -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.GraphicsMod; -import org.dolphinemu.dolphinemu.features.cheats.model.PatchCheat; - -import java.util.ArrayList; - -public class CheatsAdapter extends RecyclerView.Adapter -{ - private final CheatsActivity mActivity; - private final CheatsViewModel mViewModel; - - public CheatsAdapter(CheatsActivity activity, CheatsViewModel viewModel) - { - mActivity = activity; - mViewModel = viewModel; - - mViewModel.getCheatAddedEvent().observe(activity, (position) -> - { - if (position != null) - notifyItemInserted(position); - }); - - mViewModel.getCheatChangedEvent().observe(activity, (position) -> - { - if (position != null) - notifyItemChanged(position); - }); - - mViewModel.getCheatDeletedEvent().observe(activity, (position) -> - { - if (position != null) - notifyItemRemoved(position); - }); - - mViewModel.getGeckoCheatsDownloadedEvent().observe(activity, (cheatsAdded) -> - { - if (cheatsAdded != null) - { - int positionEnd = getItemCount() - 2; // Skip "Add Gecko Code" and "Download Gecko Codes" - int positionStart = positionEnd - cheatsAdded; - notifyItemRangeInserted(positionStart, cheatsAdded); - } - }); - } - - @NonNull - @Override - public CheatItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) - { - LayoutInflater inflater = LayoutInflater.from(parent.getContext()); - - switch (viewType) - { - case CheatItem.TYPE_CHEAT: - ListItemCheatBinding listItemCheatBinding = ListItemCheatBinding.inflate(inflater); - addViewListeners(listItemCheatBinding.getRoot()); - return new CheatViewHolder(listItemCheatBinding); - case CheatItem.TYPE_HEADER: - ListItemHeaderBinding listItemHeaderBinding = ListItemHeaderBinding.inflate(inflater); - addViewListeners(listItemHeaderBinding.getRoot()); - return new HeaderViewHolder(listItemHeaderBinding); - case CheatItem.TYPE_ACTION: - ListItemSubmenuBinding listItemSubmenuBinding = ListItemSubmenuBinding.inflate(inflater); - addViewListeners(listItemSubmenuBinding.getRoot()); - return new ActionViewHolder(listItemSubmenuBinding); - default: - throw new UnsupportedOperationException(); - } - } - - @Override - public void onBindViewHolder(@NonNull CheatItemViewHolder holder, int position) - { - holder.bind(mActivity, getItemAt(position), position); - } - - @Override - public int getItemCount() - { - return mViewModel.getGraphicsMods().size() + mViewModel.getPatchCheats().size() + - mViewModel.getARCheats().size() + mViewModel.getGeckoCheats().size() + 8; - } - - @Override - public int getItemViewType(int position) - { - return getItemAt(position).getType(); - } - - private void addViewListeners(View view) - { - CheatsActivity.setOnFocusChangeListenerRecursively(view, - (v, hasFocus) -> mActivity.onListViewFocusChange(hasFocus)); - } - - private CheatItem getItemAt(int position) - { - // Graphics mods - - if (position == 0) - return new CheatItem(CheatItem.TYPE_HEADER, R.string.cheats_header_graphics_mod); - position -= 1; - - ArrayList graphicsMods = mViewModel.getGraphicsMods(); - if (position < graphicsMods.size()) - return new CheatItem(graphicsMods.get(position)); - position -= graphicsMods.size(); - - // Patches - - if (position == 0) - return new CheatItem(CheatItem.TYPE_HEADER, R.string.cheats_header_patch); - position -= 1; - - ArrayList 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; - - ArrayList 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; - - ArrayList 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; - - if (position == 0) - return new CheatItem(CheatItem.TYPE_ACTION, R.string.cheats_download_gecko); - - throw new IndexOutOfBoundsException(); - } -} diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatsAdapter.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatsAdapter.kt new file mode 100644 index 0000000000..c75330375d --- /dev/null +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatsAdapter.kt @@ -0,0 +1,138 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +package org.dolphinemu.dolphinemu.features.cheats.ui + +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView +import org.dolphinemu.dolphinemu.R +import org.dolphinemu.dolphinemu.databinding.ListItemCheatBinding +import org.dolphinemu.dolphinemu.databinding.ListItemHeaderBinding +import org.dolphinemu.dolphinemu.databinding.ListItemSubmenuBinding +import org.dolphinemu.dolphinemu.features.cheats.model.CheatsViewModel +import org.dolphinemu.dolphinemu.features.cheats.ui.CheatsActivity.Companion.setOnFocusChangeListenerRecursively + +class CheatsAdapter( + private val activity: CheatsActivity, + private val viewModel: CheatsViewModel +) : RecyclerView.Adapter() { + init { + viewModel.cheatAddedEvent.observe(activity) { position: Int? -> + position?.let { notifyItemInserted(it) } + } + + viewModel.cheatChangedEvent.observe(activity) { position: Int? -> + position?.let { notifyItemChanged(it) } + } + + viewModel.cheatDeletedEvent.observe(activity) { position: Int? -> + position?.let { notifyItemRemoved(it) } + } + + viewModel.geckoCheatsDownloadedEvent.observe(activity) { cheatsAdded: Int? -> + cheatsAdded?.let { + val positionEnd = itemCount - 2 // Skip "Add Gecko Code" and "Download Gecko Codes" + val positionStart = positionEnd - it + notifyItemRangeInserted(positionStart, it) + } + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CheatItemViewHolder { + val inflater = LayoutInflater.from(parent.context) + return when (viewType) { + CheatItem.TYPE_CHEAT -> { + val listItemCheatBinding = ListItemCheatBinding.inflate(inflater) + addViewListeners(listItemCheatBinding.getRoot()) + CheatViewHolder(listItemCheatBinding) + } + CheatItem.TYPE_HEADER -> { + val listItemHeaderBinding = ListItemHeaderBinding.inflate(inflater) + addViewListeners(listItemHeaderBinding.root) + HeaderViewHolder(listItemHeaderBinding) + } + CheatItem.TYPE_ACTION -> { + val listItemSubmenuBinding = ListItemSubmenuBinding.inflate(inflater) + addViewListeners(listItemSubmenuBinding.root) + ActionViewHolder(listItemSubmenuBinding) + } + else -> throw UnsupportedOperationException() + } + } + + override fun onBindViewHolder(holder: CheatItemViewHolder, position: Int) { + holder.bind(activity, getItemAt(position), position) + } + + override fun getItemCount(): Int { + return viewModel.graphicsMods.size + viewModel.patchCheats.size + viewModel.aRCheats.size + + viewModel.geckoCheats.size + 8 + } + + override fun getItemViewType(position: Int): Int { + return getItemAt(position).type + } + + private fun addViewListeners(view: View) { + setOnFocusChangeListenerRecursively(view) { _: View?, hasFocus: Boolean -> + activity.onListViewFocusChange( + hasFocus + ) + } + } + + private fun getItemAt(position: Int): CheatItem { + // Graphics mods + var itemPosition = position + if (itemPosition == 0) return CheatItem( + CheatItem.TYPE_HEADER, + R.string.cheats_header_graphics_mod + ) + itemPosition -= 1 + + val graphicsMods = viewModel.graphicsMods + if (itemPosition < graphicsMods.size) return CheatItem(graphicsMods[itemPosition]) + itemPosition -= graphicsMods.size + + // Patches + if (itemPosition == 0) return CheatItem(CheatItem.TYPE_HEADER, R.string.cheats_header_patch) + itemPosition -= 1 + + val patchCheats = viewModel.patchCheats + if (itemPosition < patchCheats.size) return CheatItem(patchCheats[itemPosition]) + itemPosition -= patchCheats.size + + if (itemPosition == 0) return CheatItem(CheatItem.TYPE_ACTION, R.string.cheats_add_patch) + itemPosition -= 1 + + // AR codes + if (itemPosition == 0) return CheatItem(CheatItem.TYPE_HEADER, R.string.cheats_header_ar) + itemPosition -= 1 + + val arCheats = viewModel.aRCheats + if (itemPosition < arCheats.size) return CheatItem(arCheats[itemPosition]) + itemPosition -= arCheats.size + + if (itemPosition == 0) return CheatItem(CheatItem.TYPE_ACTION, R.string.cheats_add_ar) + itemPosition -= 1 + + // Gecko codes + if (itemPosition == 0) return CheatItem(CheatItem.TYPE_HEADER, R.string.cheats_header_gecko) + itemPosition -= 1 + + val geckoCheats = viewModel.geckoCheats + if (itemPosition < geckoCheats.size) return CheatItem(geckoCheats[itemPosition]) + itemPosition -= geckoCheats.size + + if (itemPosition == 0) return CheatItem(CheatItem.TYPE_ACTION, R.string.cheats_add_gecko) + itemPosition -= 1 + + if (itemPosition == 0) return CheatItem( + CheatItem.TYPE_ACTION, + R.string.cheats_download_gecko + ) + + throw IndexOutOfBoundsException() + } +}