Android: Convert CheatsActivity to Kotlin
This commit is contained in:
parent
3bcc4a0a59
commit
23d9def613
|
@ -1,342 +0,0 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
package org.dolphinemu.dolphinemu.features.cheats.ui;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.view.Menu;
|
|
||||||
import android.view.MenuInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
|
|
||||||
import androidx.annotation.ColorInt;
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.appcompat.app.AlertDialog;
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
|
||||||
import androidx.core.graphics.Insets;
|
|
||||||
import androidx.core.view.ViewCompat;
|
|
||||||
import androidx.core.view.WindowCompat;
|
|
||||||
import androidx.core.view.WindowInsetsAnimationCompat;
|
|
||||||
import androidx.core.view.WindowInsetsCompat;
|
|
||||||
import androidx.lifecycle.ViewModelProvider;
|
|
||||||
import androidx.slidingpanelayout.widget.SlidingPaneLayout;
|
|
||||||
|
|
||||||
import com.google.android.material.color.MaterialColors;
|
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
|
||||||
import com.google.android.material.elevation.ElevationOverlayProvider;
|
|
||||||
|
|
||||||
import org.dolphinemu.dolphinemu.R;
|
|
||||||
import org.dolphinemu.dolphinemu.databinding.ActivityCheatsBinding;
|
|
||||||
import org.dolphinemu.dolphinemu.features.cheats.model.Cheat;
|
|
||||||
import org.dolphinemu.dolphinemu.features.cheats.model.CheatsViewModel;
|
|
||||||
import org.dolphinemu.dolphinemu.features.cheats.model.GeckoCheat;
|
|
||||||
import org.dolphinemu.dolphinemu.features.settings.model.Settings;
|
|
||||||
import org.dolphinemu.dolphinemu.ui.TwoPaneOnBackPressedCallback;
|
|
||||||
import org.dolphinemu.dolphinemu.ui.main.MainPresenter;
|
|
||||||
import org.dolphinemu.dolphinemu.utils.InsetsHelper;
|
|
||||||
import org.dolphinemu.dolphinemu.utils.ThemeHelper;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class CheatsActivity extends AppCompatActivity
|
|
||||||
implements SlidingPaneLayout.PanelSlideListener
|
|
||||||
{
|
|
||||||
private static final String ARG_GAME_ID = "game_id";
|
|
||||||
private static final String ARG_GAMETDB_ID = "gametdb_id";
|
|
||||||
private static final String ARG_REVISION = "revision";
|
|
||||||
private static final String ARG_IS_WII = "is_wii";
|
|
||||||
|
|
||||||
private String mGameId;
|
|
||||||
private String mGameTdbId;
|
|
||||||
private int mRevision;
|
|
||||||
private boolean mIsWii;
|
|
||||||
private CheatsViewModel mViewModel;
|
|
||||||
|
|
||||||
private View mCheatListLastFocus;
|
|
||||||
private View mCheatDetailsLastFocus;
|
|
||||||
|
|
||||||
private ActivityCheatsBinding mBinding;
|
|
||||||
|
|
||||||
public static void launch(Context context, String gameId, String gameTdbId, int revision,
|
|
||||||
boolean isWii)
|
|
||||||
{
|
|
||||||
Intent intent = new Intent(context, CheatsActivity.class);
|
|
||||||
intent.putExtra(ARG_GAME_ID, gameId);
|
|
||||||
intent.putExtra(ARG_GAMETDB_ID, gameTdbId);
|
|
||||||
intent.putExtra(ARG_REVISION, revision);
|
|
||||||
intent.putExtra(ARG_IS_WII, isWii);
|
|
||||||
context.startActivity(intent);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(Bundle savedInstanceState)
|
|
||||||
{
|
|
||||||
ThemeHelper.setTheme(this);
|
|
||||||
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
|
|
||||||
MainPresenter.skipRescanningLibrary();
|
|
||||||
|
|
||||||
Intent intent = getIntent();
|
|
||||||
mGameId = intent.getStringExtra(ARG_GAME_ID);
|
|
||||||
mGameTdbId = intent.getStringExtra(ARG_GAMETDB_ID);
|
|
||||||
mRevision = intent.getIntExtra(ARG_REVISION, 0);
|
|
||||||
mIsWii = intent.getBooleanExtra(ARG_IS_WII, true);
|
|
||||||
|
|
||||||
setTitle(getString(R.string.cheats_with_game_id, mGameId));
|
|
||||||
|
|
||||||
mViewModel = new ViewModelProvider(this).get(CheatsViewModel.class);
|
|
||||||
mViewModel.load(mGameId, mRevision);
|
|
||||||
|
|
||||||
mBinding = ActivityCheatsBinding.inflate(getLayoutInflater());
|
|
||||||
setContentView(mBinding.getRoot());
|
|
||||||
|
|
||||||
WindowCompat.setDecorFitsSystemWindows(getWindow(), false);
|
|
||||||
|
|
||||||
mCheatListLastFocus = mBinding.cheatList;
|
|
||||||
mCheatDetailsLastFocus = mBinding.cheatDetails;
|
|
||||||
|
|
||||||
mBinding.slidingPaneLayout.addPanelSlideListener(this);
|
|
||||||
|
|
||||||
getOnBackPressedDispatcher().addCallback(this,
|
|
||||||
new TwoPaneOnBackPressedCallback(mBinding.slidingPaneLayout));
|
|
||||||
|
|
||||||
mViewModel.getSelectedCheat().observe(this, this::onSelectedCheatChanged);
|
|
||||||
onSelectedCheatChanged(mViewModel.getSelectedCheat().getValue());
|
|
||||||
|
|
||||||
mViewModel.getOpenDetailsViewEvent().observe(this, this::openDetailsView);
|
|
||||||
|
|
||||||
setSupportActionBar(mBinding.toolbarCheats);
|
|
||||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
|
||||||
|
|
||||||
setInsets();
|
|
||||||
|
|
||||||
@ColorInt int color =
|
|
||||||
new ElevationOverlayProvider(mBinding.toolbarCheats.getContext()).compositeOverlay(
|
|
||||||
MaterialColors.getColor(mBinding.toolbarCheats, R.attr.colorSurface),
|
|
||||||
getResources().getDimensionPixelSize(R.dimen.elevated_app_bar));
|
|
||||||
mBinding.toolbarCheats.setBackgroundColor(color);
|
|
||||||
ThemeHelper.setStatusBarColor(this, color);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onCreateOptionsMenu(Menu menu)
|
|
||||||
{
|
|
||||||
MenuInflater inflater = getMenuInflater();
|
|
||||||
inflater.inflate(R.menu.menu_settings, menu);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onStop()
|
|
||||||
{
|
|
||||||
super.onStop();
|
|
||||||
|
|
||||||
mViewModel.saveIfNeeded(mGameId, mRevision);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPanelSlide(@NonNull View panel, float slideOffset)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPanelOpened(@NonNull View panel)
|
|
||||||
{
|
|
||||||
boolean rtl = ViewCompat.getLayoutDirection(panel) == ViewCompat.LAYOUT_DIRECTION_RTL;
|
|
||||||
mCheatDetailsLastFocus.requestFocus(rtl ? View.FOCUS_LEFT : View.FOCUS_RIGHT);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPanelClosed(@NonNull View panel)
|
|
||||||
{
|
|
||||||
boolean rtl = ViewCompat.getLayoutDirection(panel) == ViewCompat.LAYOUT_DIRECTION_RTL;
|
|
||||||
mCheatListLastFocus.requestFocus(rtl ? View.FOCUS_RIGHT : View.FOCUS_LEFT);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void onSelectedCheatChanged(Cheat selectedCheat)
|
|
||||||
{
|
|
||||||
boolean cheatSelected = selectedCheat != null;
|
|
||||||
|
|
||||||
if (!cheatSelected && mBinding.slidingPaneLayout.isOpen())
|
|
||||||
mBinding.slidingPaneLayout.close();
|
|
||||||
|
|
||||||
mBinding.slidingPaneLayout.setLockMode(cheatSelected ?
|
|
||||||
SlidingPaneLayout.LOCK_MODE_UNLOCKED : SlidingPaneLayout.LOCK_MODE_LOCKED_CLOSED);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onListViewFocusChange(boolean hasFocus)
|
|
||||||
{
|
|
||||||
if (hasFocus)
|
|
||||||
{
|
|
||||||
mCheatListLastFocus = mBinding.cheatList.findFocus();
|
|
||||||
if (mCheatListLastFocus == null)
|
|
||||||
throw new NullPointerException();
|
|
||||||
|
|
||||||
mBinding.slidingPaneLayout.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onDetailsViewFocusChange(boolean hasFocus)
|
|
||||||
{
|
|
||||||
if (hasFocus)
|
|
||||||
{
|
|
||||||
mCheatDetailsLastFocus = mBinding.cheatDetails.findFocus();
|
|
||||||
if (mCheatDetailsLastFocus == null)
|
|
||||||
throw new NullPointerException();
|
|
||||||
|
|
||||||
mBinding.slidingPaneLayout.open();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onSupportNavigateUp()
|
|
||||||
{
|
|
||||||
onBackPressed();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void openDetailsView(boolean open)
|
|
||||||
{
|
|
||||||
if (open)
|
|
||||||
mBinding.slidingPaneLayout.open();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Settings loadGameSpecificSettings()
|
|
||||||
{
|
|
||||||
Settings settings = new Settings();
|
|
||||||
settings.loadSettings(null, mGameId, mRevision, mIsWii);
|
|
||||||
return settings;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void downloadGeckoCodes()
|
|
||||||
{
|
|
||||||
AlertDialog progressDialog = new MaterialAlertDialogBuilder(this)
|
|
||||||
.setTitle(R.string.cheats_downloading)
|
|
||||||
.setView(R.layout.dialog_indeterminate_progress)
|
|
||||||
.setCancelable(false)
|
|
||||||
.show();
|
|
||||||
|
|
||||||
new Thread(() ->
|
|
||||||
{
|
|
||||||
GeckoCheat[] codes = GeckoCheat.downloadCodes(mGameTdbId);
|
|
||||||
|
|
||||||
runOnUiThread(() ->
|
|
||||||
{
|
|
||||||
progressDialog.dismiss();
|
|
||||||
|
|
||||||
if (codes == null)
|
|
||||||
{
|
|
||||||
new MaterialAlertDialogBuilder(this)
|
|
||||||
.setMessage(getString(R.string.cheats_download_failed))
|
|
||||||
.setPositiveButton(R.string.ok, null)
|
|
||||||
.show();
|
|
||||||
}
|
|
||||||
else if (codes.length == 0)
|
|
||||||
{
|
|
||||||
new MaterialAlertDialogBuilder(this)
|
|
||||||
.setMessage(getString(R.string.cheats_download_empty))
|
|
||||||
.setPositiveButton(R.string.ok, null)
|
|
||||||
.show();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int cheatsAdded = mViewModel.addDownloadedGeckoCodes(codes);
|
|
||||||
String message = getString(R.string.cheats_download_succeeded, codes.length, cheatsAdded);
|
|
||||||
|
|
||||||
new MaterialAlertDialogBuilder(this)
|
|
||||||
.setMessage(message)
|
|
||||||
.setPositiveButton(R.string.ok, null)
|
|
||||||
.show();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}).start();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void setOnFocusChangeListenerRecursively(@NonNull View view,
|
|
||||||
View.OnFocusChangeListener listener)
|
|
||||||
{
|
|
||||||
view.setOnFocusChangeListener(listener);
|
|
||||||
|
|
||||||
if (view instanceof ViewGroup)
|
|
||||||
{
|
|
||||||
ViewGroup viewGroup = (ViewGroup) view;
|
|
||||||
for (int i = 0; i < viewGroup.getChildCount(); i++)
|
|
||||||
{
|
|
||||||
View child = viewGroup.getChildAt(i);
|
|
||||||
setOnFocusChangeListenerRecursively(child, listener);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setInsets()
|
|
||||||
{
|
|
||||||
ViewCompat.setOnApplyWindowInsetsListener(mBinding.appbarCheats, (v, windowInsets) ->
|
|
||||||
{
|
|
||||||
Insets barInsets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars());
|
|
||||||
Insets keyboardInsets = windowInsets.getInsets(WindowInsetsCompat.Type.ime());
|
|
||||||
|
|
||||||
InsetsHelper.insetAppBar(barInsets, mBinding.appbarCheats);
|
|
||||||
|
|
||||||
mBinding.slidingPaneLayout.setPadding(barInsets.left, 0, barInsets.right, 0);
|
|
||||||
|
|
||||||
// Set keyboard insets if the system supports smooth keyboard animations
|
|
||||||
ViewGroup.MarginLayoutParams mlpDetails =
|
|
||||||
(ViewGroup.MarginLayoutParams) mBinding.cheatDetails.getLayoutParams();
|
|
||||||
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.R)
|
|
||||||
{
|
|
||||||
if (keyboardInsets.bottom > 0)
|
|
||||||
{
|
|
||||||
mlpDetails.bottomMargin = keyboardInsets.bottom;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mlpDetails.bottomMargin = barInsets.bottom;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (mlpDetails.bottomMargin == 0)
|
|
||||||
{
|
|
||||||
mlpDetails.bottomMargin = barInsets.bottom;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mBinding.cheatDetails.setLayoutParams(mlpDetails);
|
|
||||||
|
|
||||||
InsetsHelper.applyNavbarWorkaround(barInsets.bottom, mBinding.workaroundView);
|
|
||||||
|
|
||||||
ThemeHelper.setNavigationBarColor(this,
|
|
||||||
MaterialColors.getColor(mBinding.appbarCheats, R.attr.colorSurface));
|
|
||||||
|
|
||||||
return windowInsets;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Update the layout for every frame that the keyboard animates in
|
|
||||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R)
|
|
||||||
{
|
|
||||||
ViewCompat.setWindowInsetsAnimationCallback(mBinding.cheatDetails,
|
|
||||||
new WindowInsetsAnimationCompat.Callback(
|
|
||||||
WindowInsetsAnimationCompat.Callback.DISPATCH_MODE_STOP)
|
|
||||||
{
|
|
||||||
int keyboardInsets = 0;
|
|
||||||
int barInsets = 0;
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
@Override
|
|
||||||
public WindowInsetsCompat onProgress(@NonNull WindowInsetsCompat insets,
|
|
||||||
@NonNull List<WindowInsetsAnimationCompat> runningAnimations)
|
|
||||||
{
|
|
||||||
ViewGroup.MarginLayoutParams mlpDetails =
|
|
||||||
(ViewGroup.MarginLayoutParams) mBinding.cheatDetails.getLayoutParams();
|
|
||||||
keyboardInsets = insets.getInsets(WindowInsetsCompat.Type.ime()).bottom;
|
|
||||||
barInsets = insets.getInsets(WindowInsetsCompat.Type.systemBars()).bottom;
|
|
||||||
mlpDetails.bottomMargin = Math.max(keyboardInsets, barInsets);
|
|
||||||
mBinding.cheatDetails.setLayoutParams(mlpDetails);
|
|
||||||
return insets;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,293 @@
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
package org.dolphinemu.dolphinemu.features.cheats.ui
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Build
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.Menu
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.view.ViewGroup.MarginLayoutParams
|
||||||
|
import androidx.annotation.ColorInt
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.core.view.ViewCompat
|
||||||
|
import androidx.core.view.WindowCompat
|
||||||
|
import androidx.core.view.WindowInsetsAnimationCompat
|
||||||
|
import androidx.core.view.WindowInsetsCompat
|
||||||
|
import androidx.lifecycle.ViewModelProvider
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import androidx.slidingpanelayout.widget.SlidingPaneLayout
|
||||||
|
import androidx.slidingpanelayout.widget.SlidingPaneLayout.PanelSlideListener
|
||||||
|
import com.google.android.material.color.MaterialColors
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
|
import com.google.android.material.elevation.ElevationOverlayProvider
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
import org.dolphinemu.dolphinemu.R
|
||||||
|
import org.dolphinemu.dolphinemu.databinding.ActivityCheatsBinding
|
||||||
|
import org.dolphinemu.dolphinemu.features.cheats.model.Cheat
|
||||||
|
import org.dolphinemu.dolphinemu.features.cheats.model.CheatsViewModel
|
||||||
|
import org.dolphinemu.dolphinemu.features.cheats.model.GeckoCheat.Companion.downloadCodes
|
||||||
|
import org.dolphinemu.dolphinemu.features.settings.model.Settings
|
||||||
|
import org.dolphinemu.dolphinemu.ui.TwoPaneOnBackPressedCallback
|
||||||
|
import org.dolphinemu.dolphinemu.ui.main.MainPresenter
|
||||||
|
import org.dolphinemu.dolphinemu.utils.InsetsHelper
|
||||||
|
import org.dolphinemu.dolphinemu.utils.ThemeHelper
|
||||||
|
|
||||||
|
class CheatsActivity : AppCompatActivity(), PanelSlideListener {
|
||||||
|
private var gameId: String? = null
|
||||||
|
private var gameTdbId: String? = null
|
||||||
|
private var revision = 0
|
||||||
|
private var isWii = false
|
||||||
|
private lateinit var viewModel: CheatsViewModel
|
||||||
|
|
||||||
|
private var cheatListLastFocus: View? = null
|
||||||
|
private var cheatDetailsLastFocus: View? = null
|
||||||
|
|
||||||
|
private lateinit var binding: ActivityCheatsBinding
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
ThemeHelper.setTheme(this)
|
||||||
|
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
|
MainPresenter.skipRescanningLibrary()
|
||||||
|
|
||||||
|
gameId = intent.getStringExtra(ARG_GAME_ID)
|
||||||
|
gameTdbId = intent.getStringExtra(ARG_GAMETDB_ID)
|
||||||
|
revision = intent.getIntExtra(ARG_REVISION, 0)
|
||||||
|
isWii = intent.getBooleanExtra(ARG_IS_WII, true)
|
||||||
|
|
||||||
|
title = getString(R.string.cheats_with_game_id, gameId)
|
||||||
|
|
||||||
|
viewModel = ViewModelProvider(this)[CheatsViewModel::class.java]
|
||||||
|
viewModel.load(gameId!!, revision)
|
||||||
|
|
||||||
|
binding = ActivityCheatsBinding.inflate(layoutInflater)
|
||||||
|
setContentView(binding.root)
|
||||||
|
|
||||||
|
WindowCompat.setDecorFitsSystemWindows(window, false)
|
||||||
|
|
||||||
|
cheatListLastFocus = binding.cheatList
|
||||||
|
cheatDetailsLastFocus = binding.cheatDetails
|
||||||
|
|
||||||
|
binding.slidingPaneLayout.addPanelSlideListener(this)
|
||||||
|
|
||||||
|
onBackPressedDispatcher.addCallback(
|
||||||
|
this,
|
||||||
|
TwoPaneOnBackPressedCallback(binding.slidingPaneLayout)
|
||||||
|
)
|
||||||
|
|
||||||
|
viewModel.selectedCheat.observe(this) { selectedCheat: Cheat? ->
|
||||||
|
onSelectedCheatChanged(
|
||||||
|
selectedCheat
|
||||||
|
)
|
||||||
|
}
|
||||||
|
onSelectedCheatChanged(viewModel.selectedCheat.value)
|
||||||
|
|
||||||
|
viewModel.openDetailsViewEvent.observe(this) { open: Boolean -> openDetailsView(open) }
|
||||||
|
|
||||||
|
setSupportActionBar(binding.toolbarCheats)
|
||||||
|
supportActionBar!!.setDisplayHomeAsUpEnabled(true)
|
||||||
|
|
||||||
|
setInsets()
|
||||||
|
|
||||||
|
@ColorInt val color =
|
||||||
|
ElevationOverlayProvider(binding.toolbarCheats.context).compositeOverlay(
|
||||||
|
MaterialColors.getColor(binding.toolbarCheats, R.attr.colorSurface),
|
||||||
|
resources.getDimensionPixelSize(R.dimen.elevated_app_bar).toFloat()
|
||||||
|
)
|
||||||
|
binding.toolbarCheats.setBackgroundColor(color)
|
||||||
|
ThemeHelper.setStatusBarColor(this, color)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||||
|
val inflater = menuInflater
|
||||||
|
inflater.inflate(R.menu.menu_settings, menu)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStop() {
|
||||||
|
super.onStop()
|
||||||
|
viewModel.saveIfNeeded(gameId!!, revision)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onPanelSlide(panel: View, slideOffset: Float) {}
|
||||||
|
override fun onPanelOpened(panel: View) {
|
||||||
|
val rtl = ViewCompat.getLayoutDirection(panel) == ViewCompat.LAYOUT_DIRECTION_RTL
|
||||||
|
cheatDetailsLastFocus!!.requestFocus(if (rtl) View.FOCUS_LEFT else View.FOCUS_RIGHT)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onPanelClosed(panel: View) {
|
||||||
|
val rtl = ViewCompat.getLayoutDirection(panel) == ViewCompat.LAYOUT_DIRECTION_RTL
|
||||||
|
cheatListLastFocus!!.requestFocus(if (rtl) View.FOCUS_RIGHT else View.FOCUS_LEFT)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun onSelectedCheatChanged(selectedCheat: Cheat?) {
|
||||||
|
val cheatSelected = selectedCheat != null
|
||||||
|
if (!cheatSelected && binding.slidingPaneLayout.isOpen) binding.slidingPaneLayout.close()
|
||||||
|
|
||||||
|
binding.slidingPaneLayout.lockMode =
|
||||||
|
if (cheatSelected) SlidingPaneLayout.LOCK_MODE_UNLOCKED else SlidingPaneLayout.LOCK_MODE_LOCKED_CLOSED
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onListViewFocusChange(hasFocus: Boolean) {
|
||||||
|
if (hasFocus) {
|
||||||
|
cheatListLastFocus = binding.cheatList.findFocus()
|
||||||
|
if (cheatListLastFocus == null) throw NullPointerException()
|
||||||
|
binding.slidingPaneLayout.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun onDetailsViewFocusChange(hasFocus: Boolean) {
|
||||||
|
if (hasFocus) {
|
||||||
|
cheatDetailsLastFocus = binding.cheatDetails.findFocus()
|
||||||
|
if (cheatDetailsLastFocus == null) throw NullPointerException()
|
||||||
|
binding.slidingPaneLayout.open()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onSupportNavigateUp(): Boolean {
|
||||||
|
onBackPressed()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun openDetailsView(open: Boolean) {
|
||||||
|
if (open) binding.slidingPaneLayout.open()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun loadGameSpecificSettings(): Settings {
|
||||||
|
val settings = Settings()
|
||||||
|
settings.loadSettings(null, gameId, revision, isWii)
|
||||||
|
return settings
|
||||||
|
}
|
||||||
|
|
||||||
|
fun downloadGeckoCodes() {
|
||||||
|
val progressDialog = MaterialAlertDialogBuilder(this)
|
||||||
|
.setTitle(R.string.cheats_downloading)
|
||||||
|
.setView(R.layout.dialog_indeterminate_progress)
|
||||||
|
.setCancelable(false)
|
||||||
|
.show()
|
||||||
|
|
||||||
|
lifecycleScope.launchWhenResumed {
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
val codes = downloadCodes(gameTdbId!!)
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
progressDialog.dismiss()
|
||||||
|
if (codes == null) {
|
||||||
|
MaterialAlertDialogBuilder(binding.root.context)
|
||||||
|
.setMessage(getString(R.string.cheats_download_failed))
|
||||||
|
.setPositiveButton(R.string.ok, null)
|
||||||
|
.show()
|
||||||
|
} else if (codes.isEmpty()) {
|
||||||
|
MaterialAlertDialogBuilder(binding.root.context)
|
||||||
|
.setMessage(getString(R.string.cheats_download_empty))
|
||||||
|
.setPositiveButton(R.string.ok, null)
|
||||||
|
.show()
|
||||||
|
} else {
|
||||||
|
val cheatsAdded = viewModel.addDownloadedGeckoCodes(codes)
|
||||||
|
val message =
|
||||||
|
getString(R.string.cheats_download_succeeded, codes.size, cheatsAdded)
|
||||||
|
MaterialAlertDialogBuilder(binding.root.context)
|
||||||
|
.setMessage(message)
|
||||||
|
.setPositiveButton(R.string.ok, null)
|
||||||
|
.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setInsets() {
|
||||||
|
ViewCompat.setOnApplyWindowInsetsListener(binding.appbarCheats) { _: View?, windowInsets: WindowInsetsCompat ->
|
||||||
|
val barInsets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
|
||||||
|
val keyboardInsets = windowInsets.getInsets(WindowInsetsCompat.Type.ime())
|
||||||
|
|
||||||
|
InsetsHelper.insetAppBar(barInsets, binding.appbarCheats)
|
||||||
|
binding.slidingPaneLayout.setPadding(barInsets.left, 0, barInsets.right, 0)
|
||||||
|
|
||||||
|
// Set keyboard insets if the system supports smooth keyboard animations
|
||||||
|
val mlpDetails = binding.cheatDetails.layoutParams as MarginLayoutParams
|
||||||
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
|
||||||
|
if (keyboardInsets.bottom > 0) {
|
||||||
|
mlpDetails.bottomMargin = keyboardInsets.bottom
|
||||||
|
} else {
|
||||||
|
mlpDetails.bottomMargin = barInsets.bottom
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (mlpDetails.bottomMargin == 0) {
|
||||||
|
mlpDetails.bottomMargin = barInsets.bottom
|
||||||
|
}
|
||||||
|
}
|
||||||
|
binding.cheatDetails.layoutParams = mlpDetails
|
||||||
|
|
||||||
|
InsetsHelper.applyNavbarWorkaround(barInsets.bottom, binding.workaroundView)
|
||||||
|
ThemeHelper.setNavigationBarColor(
|
||||||
|
this,
|
||||||
|
MaterialColors.getColor(binding.appbarCheats, R.attr.colorSurface)
|
||||||
|
)
|
||||||
|
|
||||||
|
windowInsets
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the layout for every frame that the keyboard animates in
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||||
|
ViewCompat.setWindowInsetsAnimationCallback(
|
||||||
|
binding.cheatDetails,
|
||||||
|
object : WindowInsetsAnimationCompat.Callback(DISPATCH_MODE_STOP) {
|
||||||
|
var keyboardInsets = 0
|
||||||
|
var barInsets = 0
|
||||||
|
override fun onProgress(
|
||||||
|
insets: WindowInsetsCompat,
|
||||||
|
runningAnimations: List<WindowInsetsAnimationCompat>
|
||||||
|
): WindowInsetsCompat {
|
||||||
|
val mlpDetails = binding.cheatDetails.layoutParams as MarginLayoutParams
|
||||||
|
keyboardInsets = insets.getInsets(WindowInsetsCompat.Type.ime()).bottom
|
||||||
|
barInsets = insets.getInsets(WindowInsetsCompat.Type.systemBars()).bottom
|
||||||
|
mlpDetails.bottomMargin = keyboardInsets.coerceAtLeast(barInsets)
|
||||||
|
binding.cheatDetails.layoutParams = mlpDetails
|
||||||
|
return insets
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val ARG_GAME_ID = "game_id"
|
||||||
|
private const val ARG_GAMETDB_ID = "gametdb_id"
|
||||||
|
private const val ARG_REVISION = "revision"
|
||||||
|
private const val ARG_IS_WII = "is_wii"
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun launch(
|
||||||
|
context: Context,
|
||||||
|
gameId: String,
|
||||||
|
gameTdbId: String,
|
||||||
|
revision: Int,
|
||||||
|
isWii: Boolean
|
||||||
|
) {
|
||||||
|
val intent = Intent(context, CheatsActivity::class.java)
|
||||||
|
intent.putExtra(ARG_GAME_ID, gameId)
|
||||||
|
intent.putExtra(ARG_GAMETDB_ID, gameTdbId)
|
||||||
|
intent.putExtra(ARG_REVISION, revision)
|
||||||
|
intent.putExtra(ARG_IS_WII, isWii)
|
||||||
|
context.startActivity(intent)
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun setOnFocusChangeListenerRecursively(
|
||||||
|
view: View,
|
||||||
|
listener: View.OnFocusChangeListener?
|
||||||
|
) {
|
||||||
|
view.onFocusChangeListener = listener
|
||||||
|
if (view is ViewGroup) {
|
||||||
|
for (i in 0 until view.childCount) {
|
||||||
|
val child = view.getChildAt(i)
|
||||||
|
setOnFocusChangeListenerRecursively(child, listener)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue