android: Add warnings to setup screens
This commit is contained in:
parent
71667e4d6d
commit
72247a2324
|
@ -14,7 +14,6 @@ import androidx.core.content.ContextCompat
|
||||||
import androidx.core.view.ViewCompat
|
import androidx.core.view.ViewCompat
|
||||||
import androidx.core.view.WindowInsetsCompat
|
import androidx.core.view.WindowInsetsCompat
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.core.view.updatePadding
|
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.activityViewModels
|
import androidx.fragment.app.activityViewModels
|
||||||
import androidx.navigation.findNavController
|
import androidx.navigation.findNavController
|
||||||
|
@ -38,9 +37,12 @@ class SetupFragment : Fragment() {
|
||||||
|
|
||||||
private lateinit var mainActivity: MainActivity
|
private lateinit var mainActivity: MainActivity
|
||||||
|
|
||||||
|
private lateinit var hasBeenWarned: BooleanArray
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val KEY_NEXT_VISIBILITY = "NextButtonVisibility"
|
const val KEY_NEXT_VISIBILITY = "NextButtonVisibility"
|
||||||
const val KEY_BACK_VISIBILITY = "BackButtonVisibility"
|
const val KEY_BACK_VISIBILITY = "BackButtonVisibility"
|
||||||
|
const val KEY_HAS_BEEN_WARNED = "HasBeenWarned"
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
@ -84,36 +86,51 @@ class SetupFragment : Fragment() {
|
||||||
R.string.welcome_description,
|
R.string.welcome_description,
|
||||||
0,
|
0,
|
||||||
true,
|
true,
|
||||||
R.string.get_started
|
R.string.get_started,
|
||||||
) { pageForward() },
|
{ pageForward() },
|
||||||
|
false
|
||||||
|
),
|
||||||
SetupPage(
|
SetupPage(
|
||||||
R.drawable.ic_key,
|
R.drawable.ic_key,
|
||||||
R.string.keys,
|
R.string.keys,
|
||||||
R.string.keys_description,
|
R.string.keys_description,
|
||||||
R.drawable.ic_add,
|
R.drawable.ic_add,
|
||||||
true,
|
true,
|
||||||
R.string.select_keys
|
R.string.select_keys,
|
||||||
) { mainActivity.getProdKey.launch(arrayOf("*/*")) },
|
{ mainActivity.getProdKey.launch(arrayOf("*/*")) },
|
||||||
|
true,
|
||||||
|
R.string.install_prod_keys_warning,
|
||||||
|
R.string.install_prod_keys_warning_description,
|
||||||
|
R.string.install_prod_keys_warning_help
|
||||||
|
),
|
||||||
SetupPage(
|
SetupPage(
|
||||||
R.drawable.ic_controller,
|
R.drawable.ic_controller,
|
||||||
R.string.games,
|
R.string.games,
|
||||||
R.string.games_description,
|
R.string.games_description,
|
||||||
R.drawable.ic_add,
|
R.drawable.ic_add,
|
||||||
true,
|
true,
|
||||||
R.string.add_games
|
R.string.add_games,
|
||||||
) { mainActivity.getGamesDirectory.launch(Intent(Intent.ACTION_OPEN_DOCUMENT_TREE).data) },
|
{ mainActivity.getGamesDirectory.launch(Intent(Intent.ACTION_OPEN_DOCUMENT_TREE).data) },
|
||||||
|
true,
|
||||||
|
R.string.add_games_warning,
|
||||||
|
R.string.add_games_warning_description,
|
||||||
|
0
|
||||||
|
),
|
||||||
SetupPage(
|
SetupPage(
|
||||||
R.drawable.ic_check,
|
R.drawable.ic_check,
|
||||||
R.string.done,
|
R.string.done,
|
||||||
R.string.done_description,
|
R.string.done_description,
|
||||||
R.drawable.ic_arrow_forward,
|
R.drawable.ic_arrow_forward,
|
||||||
false,
|
false,
|
||||||
R.string.text_continue
|
R.string.text_continue,
|
||||||
) { finishSetup() }
|
{ finishSetup() },
|
||||||
|
false
|
||||||
|
)
|
||||||
)
|
)
|
||||||
binding.viewPager2.apply {
|
binding.viewPager2.apply {
|
||||||
adapter = SetupAdapter(requireActivity() as AppCompatActivity, pages)
|
adapter = SetupAdapter(requireActivity() as AppCompatActivity, pages)
|
||||||
offscreenPageLimit = 2
|
offscreenPageLimit = 2
|
||||||
|
isUserInputEnabled = false
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.viewPager2.registerOnPageChangeCallback(object : OnPageChangeCallback() {
|
binding.viewPager2.registerOnPageChangeCallback(object : OnPageChangeCallback() {
|
||||||
|
@ -138,12 +155,26 @@ class SetupFragment : Fragment() {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
binding.buttonNext.setOnClickListener { pageForward() }
|
binding.buttonNext.setOnClickListener {
|
||||||
|
val index = binding.viewPager2.currentItem
|
||||||
|
val currentPage = pages[index]
|
||||||
|
if (currentPage.hasWarning && !hasBeenWarned[index]) {
|
||||||
|
SetupWarningDialogFragment.newInstance(
|
||||||
|
currentPage.warningTitleId,
|
||||||
|
currentPage.warningDescriptionId,
|
||||||
|
currentPage.warningHelpLinkId,
|
||||||
|
index
|
||||||
|
).show(childFragmentManager, SetupWarningDialogFragment.TAG)
|
||||||
|
} else {
|
||||||
|
pageForward()
|
||||||
|
}
|
||||||
|
}
|
||||||
binding.buttonBack.setOnClickListener { pageBackward() }
|
binding.buttonBack.setOnClickListener { pageBackward() }
|
||||||
|
|
||||||
if (savedInstanceState != null) {
|
if (savedInstanceState != null) {
|
||||||
val nextIsVisible = savedInstanceState.getBoolean(KEY_NEXT_VISIBILITY)
|
val nextIsVisible = savedInstanceState.getBoolean(KEY_NEXT_VISIBILITY)
|
||||||
val backIsVisible = savedInstanceState.getBoolean(KEY_BACK_VISIBILITY)
|
val backIsVisible = savedInstanceState.getBoolean(KEY_BACK_VISIBILITY)
|
||||||
|
hasBeenWarned = savedInstanceState.getBooleanArray(KEY_HAS_BEEN_WARNED)!!
|
||||||
|
|
||||||
if (nextIsVisible) {
|
if (nextIsVisible) {
|
||||||
binding.buttonNext.visibility = View.VISIBLE
|
binding.buttonNext.visibility = View.VISIBLE
|
||||||
|
@ -151,6 +182,8 @@ class SetupFragment : Fragment() {
|
||||||
if (backIsVisible) {
|
if (backIsVisible) {
|
||||||
binding.buttonBack.visibility = View.VISIBLE
|
binding.buttonBack.visibility = View.VISIBLE
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
hasBeenWarned = BooleanArray(pages.size)
|
||||||
}
|
}
|
||||||
|
|
||||||
setInsets()
|
setInsets()
|
||||||
|
@ -160,6 +193,7 @@ class SetupFragment : Fragment() {
|
||||||
super.onSaveInstanceState(outState)
|
super.onSaveInstanceState(outState)
|
||||||
outState.putBoolean(KEY_NEXT_VISIBILITY, binding.buttonNext.isVisible)
|
outState.putBoolean(KEY_NEXT_VISIBILITY, binding.buttonNext.isVisible)
|
||||||
outState.putBoolean(KEY_BACK_VISIBILITY, binding.buttonBack.isVisible)
|
outState.putBoolean(KEY_BACK_VISIBILITY, binding.buttonBack.isVisible)
|
||||||
|
outState.putBooleanArray(KEY_HAS_BEEN_WARNED, hasBeenWarned)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyView() {
|
override fun onDestroyView() {
|
||||||
|
@ -201,14 +235,18 @@ class SetupFragment : Fragment() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun pageForward() {
|
fun pageForward() {
|
||||||
binding.viewPager2.currentItem = binding.viewPager2.currentItem + 1
|
binding.viewPager2.currentItem = binding.viewPager2.currentItem + 1
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun pageBackward() {
|
fun pageBackward() {
|
||||||
binding.viewPager2.currentItem = binding.viewPager2.currentItem - 1
|
binding.viewPager2.currentItem = binding.viewPager2.currentItem - 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun setPageWarned(page: Int) {
|
||||||
|
hasBeenWarned[page] = true
|
||||||
|
}
|
||||||
|
|
||||||
private fun setInsets() =
|
private fun setInsets() =
|
||||||
ViewCompat.setOnApplyWindowInsetsListener(binding.root) { view: View, windowInsets: WindowInsetsCompat ->
|
ViewCompat.setOnApplyWindowInsetsListener(binding.root) { view: View, windowInsets: WindowInsetsCompat ->
|
||||||
val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
|
val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
package org.yuzu.yuzu_emu.fragments
|
||||||
|
|
||||||
|
import android.app.Dialog
|
||||||
|
import android.content.DialogInterface
|
||||||
|
import android.content.Intent
|
||||||
|
import android.net.Uri
|
||||||
|
import android.os.Bundle
|
||||||
|
import androidx.fragment.app.DialogFragment
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
|
import org.yuzu.yuzu_emu.R
|
||||||
|
|
||||||
|
class SetupWarningDialogFragment : DialogFragment() {
|
||||||
|
private var titleId: Int = 0
|
||||||
|
private var descriptionId: Int = 0
|
||||||
|
private var helpLinkId: Int = 0
|
||||||
|
private var page: Int = 0
|
||||||
|
|
||||||
|
private lateinit var setupFragment: SetupFragment
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
titleId = requireArguments().getInt(TITLE)
|
||||||
|
descriptionId = requireArguments().getInt(DESCRIPTION)
|
||||||
|
helpLinkId = requireArguments().getInt(HELP_LINK)
|
||||||
|
page = requireArguments().getInt(PAGE)
|
||||||
|
|
||||||
|
setupFragment = requireParentFragment() as SetupFragment
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
|
||||||
|
val builder = MaterialAlertDialogBuilder(requireContext())
|
||||||
|
.setPositiveButton(R.string.warning_skip) { _: DialogInterface?, _: Int ->
|
||||||
|
setupFragment.pageForward()
|
||||||
|
setupFragment.setPageWarned(page)
|
||||||
|
}
|
||||||
|
.setNegativeButton(R.string.warning_cancel, null)
|
||||||
|
|
||||||
|
if (titleId != 0) {
|
||||||
|
builder.setTitle(titleId)
|
||||||
|
} else {
|
||||||
|
builder.setTitle("")
|
||||||
|
}
|
||||||
|
if (descriptionId != 0) {
|
||||||
|
builder.setMessage(descriptionId)
|
||||||
|
}
|
||||||
|
if (helpLinkId != 0) {
|
||||||
|
builder.setNeutralButton(R.string.warning_help) { _: DialogInterface?, _: Int ->
|
||||||
|
val helpLink = resources.getString(R.string.install_prod_keys_warning_help)
|
||||||
|
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(helpLink))
|
||||||
|
startActivity(intent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return builder.show()
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val TAG = "SetupWarningDialogFragment"
|
||||||
|
|
||||||
|
private const val TITLE = "Title"
|
||||||
|
private const val DESCRIPTION = "Description"
|
||||||
|
private const val HELP_LINK = "HelpLink"
|
||||||
|
private const val PAGE = "Page"
|
||||||
|
|
||||||
|
fun newInstance(
|
||||||
|
titleId: Int,
|
||||||
|
descriptionId: Int,
|
||||||
|
helpLinkId: Int,
|
||||||
|
page: Int
|
||||||
|
): SetupWarningDialogFragment {
|
||||||
|
val dialog = SetupWarningDialogFragment()
|
||||||
|
val bundle = Bundle()
|
||||||
|
bundle.apply {
|
||||||
|
putInt(TITLE, titleId)
|
||||||
|
putInt(DESCRIPTION, descriptionId)
|
||||||
|
putInt(HELP_LINK, helpLinkId)
|
||||||
|
putInt(PAGE, page)
|
||||||
|
}
|
||||||
|
dialog.arguments = bundle
|
||||||
|
return dialog
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,5 +10,9 @@ data class SetupPage(
|
||||||
val buttonIconId: Int,
|
val buttonIconId: Int,
|
||||||
val leftAlignedIcon: Boolean,
|
val leftAlignedIcon: Boolean,
|
||||||
val buttonTextId: Int,
|
val buttonTextId: Int,
|
||||||
val buttonAction: () -> Unit
|
val buttonAction: () -> Unit,
|
||||||
|
val hasWarning: Boolean,
|
||||||
|
val warningTitleId: Int = 0,
|
||||||
|
val warningDescriptionId: Int = 0,
|
||||||
|
val warningHelpLinkId: Int = 0
|
||||||
)
|
)
|
||||||
|
|
|
@ -29,10 +29,18 @@
|
||||||
<string name="home_settings">Settings</string>
|
<string name="home_settings">Settings</string>
|
||||||
<string name="add_games">Add Games</string>
|
<string name="add_games">Add Games</string>
|
||||||
<string name="add_games_description">Select your games folder</string>
|
<string name="add_games_description">Select your games folder</string>
|
||||||
|
<string name="add_games_warning">Skip selecting games folder?</string>
|
||||||
|
<string name="add_games_warning_description">Games won\'t be displayed in the Games list if a folder isn\'t selected.</string>
|
||||||
<string name="home_search_games">Search Games</string>
|
<string name="home_search_games">Search Games</string>
|
||||||
<string name="games_dir_selected">Games directory selected</string>
|
<string name="games_dir_selected">Games directory selected</string>
|
||||||
<string name="install_prod_keys">Install Prod.keys</string>
|
<string name="install_prod_keys">Install Prod.keys</string>
|
||||||
<string name="install_prod_keys_description">Required to decrypt retail games</string>
|
<string name="install_prod_keys_description">Required to decrypt retail games</string>
|
||||||
|
<string name="install_prod_keys_warning">Skip adding keys?</string>
|
||||||
|
<string name="install_prod_keys_warning_description">Valid keys are required to emulate retail games. Only homebrew apps will function if you continue.</string>
|
||||||
|
<string name="install_prod_keys_warning_help">https://yuzu-emu.org/help/quickstart/#guide-introduction</string>
|
||||||
|
<string name="warning_help">Help</string>
|
||||||
|
<string name="warning_skip">Skip</string>
|
||||||
|
<string name="warning_cancel">Cancel</string>
|
||||||
<string name="install_amiibo_keys">Install Amiibo Keys</string>
|
<string name="install_amiibo_keys">Install Amiibo Keys</string>
|
||||||
<string name="install_amiibo_keys_description">Required to use Amiibo in game</string>
|
<string name="install_amiibo_keys_description">Required to use Amiibo in game</string>
|
||||||
<string name="invalid_keys_file">Invalid keys file selected</string>
|
<string name="invalid_keys_file">Invalid keys file selected</string>
|
||||||
|
|
Reference in New Issue