mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-12-16 04:09:39 +00:00
Merge pull request #13992 from JosJuice/android-register-for-activity-result
Android: Replace deprecated startActivityForResult
This commit is contained in:
commit
b74c3faa48
@ -2,10 +2,10 @@
|
|||||||
|
|
||||||
package org.dolphinemu.dolphinemu.activities
|
package org.dolphinemu.dolphinemu.activities
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.content.DialogInterface
|
import android.content.DialogInterface
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.graphics.Rect
|
import android.graphics.Rect
|
||||||
|
import android.net.Uri
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.SparseIntArray
|
import android.util.SparseIntArray
|
||||||
@ -16,6 +16,7 @@ import android.view.View
|
|||||||
import android.view.ViewGroup.MarginLayoutParams
|
import android.view.ViewGroup.MarginLayoutParams
|
||||||
import android.view.WindowManager
|
import android.view.WindowManager
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.appcompat.widget.PopupMenu
|
import androidx.appcompat.widget.PopupMenu
|
||||||
import androidx.core.view.ViewCompat
|
import androidx.core.view.ViewCompat
|
||||||
@ -87,6 +88,92 @@ class EmulationActivity : AppCompatActivity(), ThemeProvider {
|
|||||||
|
|
||||||
private lateinit var binding: ActivityEmulationBinding
|
private lateinit var binding: ActivityEmulationBinding
|
||||||
|
|
||||||
|
private val requestChangeDisc = registerForActivityResult(
|
||||||
|
ActivityResultContracts.GetContent()
|
||||||
|
) { uri: Uri? ->
|
||||||
|
if (uri != null) {
|
||||||
|
NativeLibrary.ChangeDisc(uri.toString())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val requestSkylanderFile = registerForActivityResult(
|
||||||
|
ActivityResultContracts.GetContent()
|
||||||
|
) { uri: Uri? ->
|
||||||
|
if (uri != null) {
|
||||||
|
val slot = SkylanderConfig.loadSkylander(
|
||||||
|
skylanderSlots[skylanderSlot].portalSlot,
|
||||||
|
uri.toString()
|
||||||
|
)!!
|
||||||
|
clearSkylander(skylanderSlot)
|
||||||
|
skylanderSlots[skylanderSlot].portalSlot = slot.first!!
|
||||||
|
skylanderSlots[skylanderSlot].label = slot.second!!
|
||||||
|
skylandersBinding.figureManager.adapter!!.notifyItemChanged(skylanderSlot)
|
||||||
|
skylanderSlot = -1
|
||||||
|
skylanderData = Skylander.BLANK_SKYLANDER
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val requestCreateSkylander = registerForActivityResult(
|
||||||
|
ActivityResultContracts.CreateDocument("*/*")
|
||||||
|
) { uri: Uri? ->
|
||||||
|
if (uri != null) {
|
||||||
|
if (skylanderData.id != -1 && skylanderData.variant != -1) {
|
||||||
|
val slot = SkylanderConfig.createSkylander(
|
||||||
|
skylanderData.id,
|
||||||
|
skylanderData.variant,
|
||||||
|
uri.toString(),
|
||||||
|
skylanderSlots[skylanderSlot].portalSlot
|
||||||
|
)
|
||||||
|
clearSkylander(skylanderSlot)
|
||||||
|
skylanderSlots[skylanderSlot].portalSlot = slot.first
|
||||||
|
skylanderSlots[skylanderSlot].label = slot.second
|
||||||
|
skylandersBinding.figureManager.adapter?.notifyItemChanged(skylanderSlot)
|
||||||
|
skylanderSlot = -1
|
||||||
|
skylanderData = Skylander.BLANK_SKYLANDER
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val requestInfinityFigureFile = registerForActivityResult(
|
||||||
|
ActivityResultContracts.GetContent()
|
||||||
|
) { uri: Uri? ->
|
||||||
|
if (uri != null) {
|
||||||
|
val label = InfinityConfig.loadFigure(infinityPosition, uri.toString())
|
||||||
|
if (label != null && label != "Unknown Figure") {
|
||||||
|
clearInfinityFigure(infinityPosition)
|
||||||
|
infinityFigures[infinityPosition].label = label
|
||||||
|
infinityBinding.figureManager.adapter?.notifyItemChanged(infinityPosition)
|
||||||
|
infinityPosition = -1
|
||||||
|
infinityFigureData = Figure.BLANK_FIGURE
|
||||||
|
} else {
|
||||||
|
MaterialAlertDialogBuilder(this)
|
||||||
|
.setTitle(R.string.incompatible_figure_selected)
|
||||||
|
.setMessage(R.string.select_compatible_figure)
|
||||||
|
.setPositiveButton(android.R.string.ok, null)
|
||||||
|
.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val requestCreateInfinityFigure = registerForActivityResult(
|
||||||
|
ActivityResultContracts.CreateDocument("*/*")
|
||||||
|
) { uri: Uri? ->
|
||||||
|
if (uri != null) {
|
||||||
|
if (infinityFigureData.number != -1L) {
|
||||||
|
val label = InfinityConfig.createFigure(
|
||||||
|
infinityFigureData.number,
|
||||||
|
uri.toString(),
|
||||||
|
infinityPosition
|
||||||
|
)
|
||||||
|
clearInfinityFigure(infinityPosition)
|
||||||
|
infinityFigures[infinityPosition].label = label!!
|
||||||
|
infinityBinding.figureManager.adapter?.notifyItemChanged(infinityPosition)
|
||||||
|
infinityPosition = -1
|
||||||
|
infinityFigureData = Figure.BLANK_FIGURE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
ThemeHelper.setTheme(this)
|
ThemeHelper.setTheme(this)
|
||||||
|
|
||||||
@ -263,70 +350,6 @@ class EmulationActivity : AppCompatActivity(), ThemeProvider {
|
|||||||
return super.onKeyLongPress(keyCode, event)
|
return super.onKeyLongPress(keyCode, event)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onActivityResult(requestCode: Int, resultCode: Int, result: Intent?) {
|
|
||||||
super.onActivityResult(requestCode, resultCode, result)
|
|
||||||
// If the user picked a file, as opposed to just backing out.
|
|
||||||
if (resultCode == RESULT_OK) {
|
|
||||||
if (requestCode == REQUEST_CHANGE_DISC) {
|
|
||||||
NativeLibrary.ChangeDisc(result!!.data.toString())
|
|
||||||
} else if (requestCode == REQUEST_SKYLANDER_FILE) {
|
|
||||||
val slot = SkylanderConfig.loadSkylander(
|
|
||||||
skylanderSlots[skylanderSlot].portalSlot,
|
|
||||||
result!!.data.toString()
|
|
||||||
)!!
|
|
||||||
clearSkylander(skylanderSlot)
|
|
||||||
skylanderSlots[skylanderSlot].portalSlot = slot.first!!
|
|
||||||
skylanderSlots[skylanderSlot].label = slot.second!!
|
|
||||||
skylandersBinding.figureManager.adapter!!.notifyItemChanged(skylanderSlot)
|
|
||||||
skylanderSlot = -1
|
|
||||||
skylanderData = Skylander.BLANK_SKYLANDER
|
|
||||||
} else if (requestCode == REQUEST_CREATE_SKYLANDER) {
|
|
||||||
if (skylanderData.id != -1 && skylanderData.variant != -1) {
|
|
||||||
val slot = SkylanderConfig.createSkylander(
|
|
||||||
skylanderData.id,
|
|
||||||
skylanderData.variant,
|
|
||||||
result!!.data.toString(),
|
|
||||||
skylanderSlots[skylanderSlot].portalSlot
|
|
||||||
)
|
|
||||||
clearSkylander(skylanderSlot)
|
|
||||||
skylanderSlots[skylanderSlot].portalSlot = slot.first
|
|
||||||
skylanderSlots[skylanderSlot].label = slot.second
|
|
||||||
skylandersBinding.figureManager.adapter?.notifyItemChanged(skylanderSlot)
|
|
||||||
skylanderSlot = -1
|
|
||||||
skylanderData = Skylander.BLANK_SKYLANDER
|
|
||||||
}
|
|
||||||
} else if (requestCode == REQUEST_INFINITY_FIGURE_FILE) {
|
|
||||||
val label = InfinityConfig.loadFigure(infinityPosition, result!!.data.toString())
|
|
||||||
if (label != null && label != "Unknown Figure") {
|
|
||||||
clearInfinityFigure(infinityPosition)
|
|
||||||
infinityFigures[infinityPosition].label = label
|
|
||||||
infinityBinding.figureManager.adapter?.notifyItemChanged(infinityPosition)
|
|
||||||
infinityPosition = -1
|
|
||||||
infinityFigureData = Figure.BLANK_FIGURE
|
|
||||||
} else {
|
|
||||||
MaterialAlertDialogBuilder(this)
|
|
||||||
.setTitle(R.string.incompatible_figure_selected)
|
|
||||||
.setMessage(R.string.select_compatible_figure)
|
|
||||||
.setPositiveButton(android.R.string.ok, null)
|
|
||||||
.show()
|
|
||||||
}
|
|
||||||
} else if (requestCode == REQUEST_CREATE_INFINITY_FIGURE) {
|
|
||||||
if (infinityFigureData.number != -1L) {
|
|
||||||
val label = InfinityConfig.createFigure(
|
|
||||||
infinityFigureData.number,
|
|
||||||
result!!.data.toString(),
|
|
||||||
infinityPosition
|
|
||||||
)
|
|
||||||
clearInfinityFigure(infinityPosition)
|
|
||||||
infinityFigures[infinityPosition].label = label!!
|
|
||||||
infinityBinding.figureManager.adapter?.notifyItemChanged(infinityPosition)
|
|
||||||
infinityPosition = -1
|
|
||||||
infinityFigureData = Figure.BLANK_FIGURE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun enableFullscreenImmersive() {
|
private fun enableFullscreenImmersive() {
|
||||||
WindowCompat.setDecorFitsSystemWindows(window, false)
|
WindowCompat.setDecorFitsSystemWindows(window, false)
|
||||||
WindowInsetsControllerCompat(window, window.decorView).let { controller ->
|
WindowInsetsControllerCompat(window, window.decorView).let { controller ->
|
||||||
@ -480,12 +503,7 @@ class EmulationActivity : AppCompatActivity(), ThemeProvider {
|
|||||||
MENU_ACTION_LOAD_SLOT4 -> NativeLibrary.LoadState(3)
|
MENU_ACTION_LOAD_SLOT4 -> NativeLibrary.LoadState(3)
|
||||||
MENU_ACTION_LOAD_SLOT5 -> NativeLibrary.LoadState(4)
|
MENU_ACTION_LOAD_SLOT5 -> NativeLibrary.LoadState(4)
|
||||||
MENU_ACTION_LOAD_SLOT6 -> NativeLibrary.LoadState(5)
|
MENU_ACTION_LOAD_SLOT6 -> NativeLibrary.LoadState(5)
|
||||||
MENU_ACTION_CHANGE_DISC -> {
|
MENU_ACTION_CHANGE_DISC -> requestChangeDisc.launch("*/*")
|
||||||
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT)
|
|
||||||
intent.addCategory(Intent.CATEGORY_OPENABLE)
|
|
||||||
intent.type = "*/*"
|
|
||||||
startActivityForResult(intent, REQUEST_CHANGE_DISC)
|
|
||||||
}
|
|
||||||
|
|
||||||
MENU_SET_IR_MODE -> setIRMode()
|
MENU_SET_IR_MODE -> setIRMode()
|
||||||
MENU_ACTION_CHOOSE_DOUBLETAP -> chooseDoubleTapButton()
|
MENU_ACTION_CHOOSE_DOUBLETAP -> chooseDoubleTapButton()
|
||||||
@ -997,11 +1015,6 @@ class EmulationActivity : AppCompatActivity(), ThemeProvider {
|
|||||||
companion object {
|
companion object {
|
||||||
private const val BACKSTACK_NAME_MENU = "menu"
|
private const val BACKSTACK_NAME_MENU = "menu"
|
||||||
private const val BACKSTACK_NAME_SUBMENU = "submenu"
|
private const val BACKSTACK_NAME_SUBMENU = "submenu"
|
||||||
const val REQUEST_CHANGE_DISC = 1
|
|
||||||
const val REQUEST_SKYLANDER_FILE = 2
|
|
||||||
const val REQUEST_CREATE_SKYLANDER = 3
|
|
||||||
const val REQUEST_INFINITY_FIGURE_FILE = 4
|
|
||||||
const val REQUEST_CREATE_INFINITY_FIGURE = 5
|
|
||||||
|
|
||||||
private var ignoreLaunchRequests = false
|
private var ignoreLaunchRequests = false
|
||||||
|
|
||||||
|
|||||||
@ -11,6 +11,8 @@ import android.os.Bundle
|
|||||||
import android.provider.DocumentsContract
|
import android.provider.DocumentsContract
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.activity.enableEdgeToEdge
|
import androidx.activity.enableEdgeToEdge
|
||||||
|
import androidx.activity.result.ActivityResult
|
||||||
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.view.ViewCompat
|
import androidx.core.view.ViewCompat
|
||||||
import androidx.core.view.WindowInsetsCompat
|
import androidx.core.view.WindowInsetsCompat
|
||||||
@ -44,6 +46,39 @@ class UserDataActivity : AppCompatActivity(), ThemeProvider {
|
|||||||
private lateinit var mBinding: ActivityUserDataBinding
|
private lateinit var mBinding: ActivityUserDataBinding
|
||||||
|
|
||||||
override var themeId: Int = 0
|
override var themeId: Int = 0
|
||||||
|
private val requestImport = registerForActivityResult(
|
||||||
|
ActivityResultContracts.OpenDocument()
|
||||||
|
) { uri: Uri? ->
|
||||||
|
if (uri != null) {
|
||||||
|
val arguments = Bundle()
|
||||||
|
arguments.putString(
|
||||||
|
UserDataImportWarningDialog.KEY_URI_RESULT,
|
||||||
|
uri.toString()
|
||||||
|
)
|
||||||
|
|
||||||
|
val dialog = UserDataImportWarningDialog()
|
||||||
|
dialog.arguments = arguments
|
||||||
|
dialog.show(supportFragmentManager, UserDataImportWarningDialog.TAG)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val requestExport = registerForActivityResult(
|
||||||
|
ActivityResultContracts.CreateDocument("application/zip")
|
||||||
|
) { uri: Uri? ->
|
||||||
|
if (uri != null) {
|
||||||
|
taskViewModel.clear()
|
||||||
|
taskViewModel.task = { exportUserData(uri) }
|
||||||
|
|
||||||
|
val arguments = Bundle()
|
||||||
|
arguments.putInt(TaskDialog.KEY_TITLE, R.string.export_in_progress)
|
||||||
|
arguments.putInt(TaskDialog.KEY_MESSAGE, 0)
|
||||||
|
arguments.putBoolean(TaskDialog.KEY_CANCELLABLE, true)
|
||||||
|
|
||||||
|
val dialog = TaskDialog()
|
||||||
|
dialog.arguments = arguments
|
||||||
|
dialog.show(supportFragmentManager, TaskDialog.TAG)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
taskViewModel = ViewModelProvider(this)[TaskViewModel::class.java]
|
taskViewModel = ViewModelProvider(this)[TaskViewModel::class.java]
|
||||||
@ -108,34 +143,6 @@ class UserDataActivity : AppCompatActivity(), ThemeProvider {
|
|||||||
this.themeId = themeId
|
this.themeId = themeId
|
||||||
}
|
}
|
||||||
|
|
||||||
public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
|
||||||
super.onActivityResult(requestCode, resultCode, data)
|
|
||||||
|
|
||||||
if (requestCode == REQUEST_CODE_IMPORT && resultCode == RESULT_OK) {
|
|
||||||
val arguments = Bundle()
|
|
||||||
arguments.putString(
|
|
||||||
UserDataImportWarningDialog.KEY_URI_RESULT,
|
|
||||||
data!!.data!!.toString()
|
|
||||||
)
|
|
||||||
|
|
||||||
val dialog = UserDataImportWarningDialog()
|
|
||||||
dialog.arguments = arguments
|
|
||||||
dialog.show(supportFragmentManager, UserDataImportWarningDialog.TAG)
|
|
||||||
} else if (requestCode == REQUEST_CODE_EXPORT && resultCode == RESULT_OK) {
|
|
||||||
taskViewModel.clear()
|
|
||||||
taskViewModel.task = { exportUserData(data!!.data!!) }
|
|
||||||
|
|
||||||
val arguments = Bundle()
|
|
||||||
arguments.putInt(TaskDialog.KEY_TITLE, R.string.export_in_progress)
|
|
||||||
arguments.putInt(TaskDialog.KEY_MESSAGE, 0)
|
|
||||||
arguments.putBoolean(TaskDialog.KEY_CANCELLABLE, true)
|
|
||||||
|
|
||||||
val dialog = TaskDialog()
|
|
||||||
dialog.arguments = arguments
|
|
||||||
dialog.show(supportFragmentManager, TaskDialog.TAG)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun confirmResetSettings() {
|
private fun confirmResetSettings() {
|
||||||
MaterialAlertDialogBuilder(this)
|
MaterialAlertDialogBuilder(this)
|
||||||
.setTitle(R.string.reset_dolphin_settings)
|
.setTitle(R.string.reset_dolphin_settings)
|
||||||
@ -216,15 +223,14 @@ class UserDataActivity : AppCompatActivity(), ThemeProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun importUserData() {
|
private fun importUserData() {
|
||||||
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT)
|
requestImport.launch(arrayOf("application/zip"))
|
||||||
intent.type = "application/zip"
|
|
||||||
startActivityForResult(intent, REQUEST_CODE_IMPORT)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun importUserData(source: Uri): Int {
|
fun importUserData(source: Uri): Int {
|
||||||
try {
|
try {
|
||||||
if (!isDolphinUserDataBackup(source))
|
if (!isDolphinUserDataBackup(source)) {
|
||||||
return R.string.user_data_import_invalid_file
|
return R.string.user_data_import_invalid_file
|
||||||
|
}
|
||||||
|
|
||||||
taskViewModel.onResultDismiss = {
|
taskViewModel.onResultDismiss = {
|
||||||
// Restart the app to apply the imported user data.
|
// Restart the app to apply the imported user data.
|
||||||
@ -319,10 +325,7 @@ class UserDataActivity : AppCompatActivity(), ThemeProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun exportUserData() {
|
private fun exportUserData() {
|
||||||
val intent = Intent(Intent.ACTION_CREATE_DOCUMENT)
|
requestExport.launch("dolphin-emu.zip")
|
||||||
intent.type = "application/zip"
|
|
||||||
intent.putExtra(Intent.EXTRA_TITLE, "dolphin-emu.zip")
|
|
||||||
startActivityForResult(intent, REQUEST_CODE_EXPORT)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun exportUserData(destination: Uri): Int {
|
private fun exportUserData(destination: Uri): Int {
|
||||||
@ -385,9 +388,6 @@ class UserDataActivity : AppCompatActivity(), ThemeProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val REQUEST_CODE_IMPORT = 0
|
|
||||||
private const val REQUEST_CODE_EXPORT = 1
|
|
||||||
|
|
||||||
private const val BUFFER_SIZE = 64 * 1024
|
private const val BUFFER_SIZE = 64 * 1024
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
|
|||||||
@ -50,14 +50,8 @@ class FigureSlotAdapter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
holder.binding.buttonLoadFigure.setOnClickListener {
|
holder.binding.buttonLoadFigure.setOnClickListener {
|
||||||
val loadFigure = Intent(Intent.ACTION_OPEN_DOCUMENT)
|
|
||||||
loadFigure.addCategory(Intent.CATEGORY_OPENABLE)
|
|
||||||
loadFigure.type = "*/*"
|
|
||||||
activity.setInfinityFigureData(0, "", figure.position, position)
|
activity.setInfinityFigureData(0, "", figure.position, position)
|
||||||
activity.startActivityForResult(
|
activity.requestInfinityFigureFile.launch("*/*")
|
||||||
loadFigure,
|
|
||||||
EmulationActivity.REQUEST_INFINITY_FIGURE_FILE
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val inflater = LayoutInflater.from(activity)
|
val inflater = LayoutInflater.from(activity)
|
||||||
@ -110,28 +104,11 @@ class FigureSlotAdapter(
|
|||||||
.show()
|
.show()
|
||||||
createDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener {
|
createDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener {
|
||||||
if (binding.infinityNum.text.toString().isNotBlank()) {
|
if (binding.infinityNum.text.toString().isNotBlank()) {
|
||||||
val createFigure = Intent(Intent.ACTION_CREATE_DOCUMENT)
|
|
||||||
createFigure.addCategory(Intent.CATEGORY_OPENABLE)
|
|
||||||
createFigure.type = "*/*"
|
|
||||||
val num = binding.infinityNum.text.toString().toLong()
|
val num = binding.infinityNum.text.toString().toLong()
|
||||||
val name = InfinityConfig.LIST_FIGURES[num]
|
val name = InfinityConfig.LIST_FIGURES[num]
|
||||||
if (name != null) {
|
val title = if (name != null) "$name.bin" else "Unknown(Number: $num).bin"
|
||||||
createFigure.putExtra(
|
activity.setInfinityFigureData(num, name ?: "Unknown", figure.position, position)
|
||||||
Intent.EXTRA_TITLE,
|
activity.requestCreateInfinityFigure.launch(title)
|
||||||
"$name.bin"
|
|
||||||
)
|
|
||||||
activity.setInfinityFigureData(num, name, figure.position, position)
|
|
||||||
} else {
|
|
||||||
createFigure.putExtra(
|
|
||||||
Intent.EXTRA_TITLE,
|
|
||||||
"Unknown(Number: $num).bin"
|
|
||||||
)
|
|
||||||
activity.setInfinityFigureData(num, "Unknown", figure.position, position)
|
|
||||||
}
|
|
||||||
activity.startActivityForResult(
|
|
||||||
createFigure,
|
|
||||||
EmulationActivity.REQUEST_CREATE_INFINITY_FIGURE
|
|
||||||
)
|
|
||||||
createDialog.dismiss()
|
createDialog.dismiss()
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
|
|||||||
@ -0,0 +1,19 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
package org.dolphinemu.dolphinemu.features.settings.model.view
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import androidx.activity.result.ActivityResultLauncher
|
||||||
|
import org.dolphinemu.dolphinemu.features.settings.model.AbstractStringSetting
|
||||||
|
|
||||||
|
class DirectoryPicker(
|
||||||
|
context: Context,
|
||||||
|
setting: AbstractStringSetting,
|
||||||
|
titleId: Int,
|
||||||
|
descriptionId: Int,
|
||||||
|
launcher: ActivityResultLauncher<Intent>,
|
||||||
|
defaultPathRelativeToUserDirectory: String?
|
||||||
|
) : FilePicker(context, setting, titleId, descriptionId, launcher, defaultPathRelativeToUserDirectory) {
|
||||||
|
override val type: Int = TYPE_DIRECTORY_PICKER
|
||||||
|
}
|
||||||
@ -3,15 +3,17 @@
|
|||||||
package org.dolphinemu.dolphinemu.features.settings.model.view
|
package org.dolphinemu.dolphinemu.features.settings.model.view
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import androidx.activity.result.ActivityResultLauncher
|
||||||
import org.dolphinemu.dolphinemu.features.settings.model.AbstractStringSetting
|
import org.dolphinemu.dolphinemu.features.settings.model.AbstractStringSetting
|
||||||
import org.dolphinemu.dolphinemu.features.settings.model.Settings
|
import org.dolphinemu.dolphinemu.features.settings.model.Settings
|
||||||
|
|
||||||
class FilePicker(
|
open class FilePicker(
|
||||||
context: Context,
|
context: Context,
|
||||||
override var setting: AbstractStringSetting,
|
override var setting: AbstractStringSetting,
|
||||||
titleId: Int,
|
titleId: Int,
|
||||||
descriptionId: Int,
|
descriptionId: Int,
|
||||||
val requestType: Int,
|
val launcher: ActivityResultLauncher<Intent>,
|
||||||
val defaultPathRelativeToUserDirectory: String?
|
val defaultPathRelativeToUserDirectory: String?
|
||||||
) : SettingsItem(context, titleId, descriptionId) {
|
) : SettingsItem(context, titleId, descriptionId) {
|
||||||
override val type: Int = TYPE_FILE_PICKER
|
override val type: Int = TYPE_FILE_PICKER
|
||||||
|
|||||||
@ -81,9 +81,10 @@ abstract class SettingsItem {
|
|||||||
const val TYPE_STRING_SINGLE_CHOICE = 6
|
const val TYPE_STRING_SINGLE_CHOICE = 6
|
||||||
const val TYPE_SINGLE_CHOICE_DYNAMIC_DESCRIPTIONS = 8
|
const val TYPE_SINGLE_CHOICE_DYNAMIC_DESCRIPTIONS = 8
|
||||||
const val TYPE_FILE_PICKER = 9
|
const val TYPE_FILE_PICKER = 9
|
||||||
const val TYPE_RUN_RUNNABLE = 10
|
const val TYPE_DIRECTORY_PICKER = 10
|
||||||
const val TYPE_STRING = 11
|
const val TYPE_RUN_RUNNABLE = 11
|
||||||
const val TYPE_HYPERLINK_HEADER = 12
|
const val TYPE_STRING = 12
|
||||||
const val TYPE_DATETIME_CHOICE = 13
|
const val TYPE_HYPERLINK_HEADER = 13
|
||||||
|
const val TYPE_DATETIME_CHOICE = 14
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,15 +1,10 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
// GPU driver implementation partially based on:
|
|
||||||
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
package org.dolphinemu.dolphinemu.features.settings.ui
|
package org.dolphinemu.dolphinemu.features.settings.ui
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.DialogInterface
|
import android.content.DialogInterface
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.net.Uri
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.KeyEvent
|
import android.view.KeyEvent
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
@ -33,7 +28,6 @@ import org.dolphinemu.dolphinemu.features.settings.model.Settings
|
|||||||
import org.dolphinemu.dolphinemu.features.settings.ui.SettingsFragment.Companion.newInstance
|
import org.dolphinemu.dolphinemu.features.settings.ui.SettingsFragment.Companion.newInstance
|
||||||
import org.dolphinemu.dolphinemu.ui.main.MainPresenter
|
import org.dolphinemu.dolphinemu.ui.main.MainPresenter
|
||||||
import org.dolphinemu.dolphinemu.ui.main.ThemeProvider
|
import org.dolphinemu.dolphinemu.ui.main.ThemeProvider
|
||||||
import org.dolphinemu.dolphinemu.utils.FileBrowserHelper
|
|
||||||
import org.dolphinemu.dolphinemu.utils.InsetsHelper
|
import org.dolphinemu.dolphinemu.utils.InsetsHelper
|
||||||
import org.dolphinemu.dolphinemu.utils.SerializableHelper.serializable
|
import org.dolphinemu.dolphinemu.utils.SerializableHelper.serializable
|
||||||
import org.dolphinemu.dolphinemu.utils.ThemeHelper.enableScrollTint
|
import org.dolphinemu.dolphinemu.utils.ThemeHelper.enableScrollTint
|
||||||
@ -177,40 +171,6 @@ class SettingsActivity : AppCompatActivity(), SettingsActivityView, ThemeProvide
|
|||||||
return duration != 0f && transition != 0f
|
return duration != 0f && transition != 0f
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onActivityResult(requestCode: Int, resultCode: Int, result: Intent?) {
|
|
||||||
super.onActivityResult(requestCode, resultCode, result)
|
|
||||||
|
|
||||||
// If the user picked a file, as opposed to just backing out.
|
|
||||||
if (resultCode != RESULT_OK) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
when (requestCode) {
|
|
||||||
MainPresenter.REQUEST_DIRECTORY -> {
|
|
||||||
val path = FileBrowserHelper.getSelectedPath(result)
|
|
||||||
fragment!!.adapter!!.onFilePickerConfirmation(path!!)
|
|
||||||
}
|
|
||||||
|
|
||||||
MainPresenter.REQUEST_GAME_FILE,
|
|
||||||
MainPresenter.REQUEST_SD_FILE,
|
|
||||||
MainPresenter.REQUEST_WAD_FILE,
|
|
||||||
MainPresenter.REQUEST_WII_SAVE_FILE,
|
|
||||||
MainPresenter.REQUEST_NAND_BIN_FILE -> {
|
|
||||||
val uri = canonicalizeIfPossible(result!!.data!!)
|
|
||||||
val validExtensions: Set<String> =
|
|
||||||
if (requestCode == MainPresenter.REQUEST_GAME_FILE) FileBrowserHelper.GAME_EXTENSIONS else FileBrowserHelper.RAW_EXTENSION
|
|
||||||
var flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
|
|
||||||
if (requestCode != MainPresenter.REQUEST_GAME_FILE) flags =
|
|
||||||
flags or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
|
|
||||||
val takeFlags = flags and result.flags
|
|
||||||
FileBrowserHelper.runAfterExtensionCheck(this, uri, validExtensions) {
|
|
||||||
contentResolver.takePersistableUriPermission(uri, takeFlags)
|
|
||||||
fragment!!.adapter!!.onFilePickerConfirmation(uri.toString())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun dispatchKeyEvent(event: KeyEvent): Boolean {
|
override fun dispatchKeyEvent(event: KeyEvent): Boolean {
|
||||||
ControllerInterface.dispatchKeyEvent(event)
|
ControllerInterface.dispatchKeyEvent(event)
|
||||||
return super.dispatchKeyEvent(event)
|
return super.dispatchKeyEvent(event)
|
||||||
@ -221,11 +181,6 @@ class SettingsActivity : AppCompatActivity(), SettingsActivityView, ThemeProvide
|
|||||||
return super.dispatchGenericMotionEvent(event)
|
return super.dispatchGenericMotionEvent(event)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun canonicalizeIfPossible(uri: Uri): Uri {
|
|
||||||
val canonicalizedUri = contentResolver.canonicalize(uri)
|
|
||||||
return canonicalizedUri ?: uri
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun showLoading() {
|
override fun showLoading() {
|
||||||
if (dialog == null) {
|
if (dialog == null) {
|
||||||
dialog = MaterialAlertDialogBuilder(this)
|
dialog = MaterialAlertDialogBuilder(this)
|
||||||
|
|||||||
@ -0,0 +1,60 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
package org.dolphinemu.dolphinemu.features.settings.ui
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
import android.content.Intent
|
||||||
|
import androidx.activity.result.ActivityResult
|
||||||
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
|
import androidx.fragment.app.Fragment
|
||||||
|
import org.dolphinemu.dolphinemu.utils.FileBrowserHelper
|
||||||
|
|
||||||
|
class SettingsActivityResultLaunchers(
|
||||||
|
private val fragment: Fragment, private val getAdapter: () -> SettingsAdapter?
|
||||||
|
) {
|
||||||
|
val requestDirectory = fragment.registerForActivityResult(
|
||||||
|
ActivityResultContracts.StartActivityForResult()
|
||||||
|
) { result: ActivityResult ->
|
||||||
|
val intent = result.data
|
||||||
|
if (result.resultCode == Activity.RESULT_OK && intent != null) {
|
||||||
|
val path = FileBrowserHelper.getSelectedPath(intent)
|
||||||
|
if (path != null) {
|
||||||
|
getAdapter()?.onFilePickerConfirmation(path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val requestGameFile = fragment.registerForActivityResult(
|
||||||
|
ActivityResultContracts.StartActivityForResult()
|
||||||
|
) { result: ActivityResult ->
|
||||||
|
onFileResult(
|
||||||
|
result,
|
||||||
|
FileBrowserHelper.GAME_EXTENSIONS,
|
||||||
|
Intent.FLAG_GRANT_READ_URI_PERMISSION
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
val requestRawFile = fragment.registerForActivityResult(
|
||||||
|
ActivityResultContracts.StartActivityForResult()
|
||||||
|
) { result: ActivityResult ->
|
||||||
|
onFileResult(
|
||||||
|
result,
|
||||||
|
FileBrowserHelper.RAW_EXTENSION,
|
||||||
|
Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun onFileResult(result: ActivityResult, validExtensions: Set<String>, flags: Int) {
|
||||||
|
val intent = result.data
|
||||||
|
val uri = intent?.data
|
||||||
|
val context = fragment.requireContext()
|
||||||
|
if (result.resultCode == Activity.RESULT_OK && uri != null) {
|
||||||
|
val canonicalizedUri = context.contentResolver.canonicalize(uri) ?: uri
|
||||||
|
val takeFlags = flags and intent.flags
|
||||||
|
FileBrowserHelper.runAfterExtensionCheck(context, canonicalizedUri, validExtensions) {
|
||||||
|
context.contentResolver.takePersistableUriPermission(canonicalizedUri, takeFlags)
|
||||||
|
getAdapter()?.onFilePickerConfirmation(canonicalizedUri.toString())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -94,7 +94,8 @@ class SettingsAdapter(
|
|||||||
ListItemMappingBinding.inflate(inflater, parent, false),
|
ListItemMappingBinding.inflate(inflater, parent, false),
|
||||||
this
|
this
|
||||||
)
|
)
|
||||||
SettingsItem.TYPE_FILE_PICKER -> FilePickerViewHolder(
|
SettingsItem.TYPE_FILE_PICKER,
|
||||||
|
SettingsItem.TYPE_DIRECTORY_PICKER -> FilePickerViewHolder(
|
||||||
ListItemSettingBinding.inflate(inflater, parent, false),
|
ListItemSettingBinding.inflate(inflater, parent, false),
|
||||||
this
|
this
|
||||||
)
|
)
|
||||||
@ -357,6 +358,7 @@ class SettingsAdapter(
|
|||||||
fun onFilePickerDirectoryClick(item: SettingsItem, position: Int) {
|
fun onFilePickerDirectoryClick(item: SettingsItem, position: Int) {
|
||||||
clickedItem = item
|
clickedItem = item
|
||||||
clickedPosition = position
|
clickedPosition = position
|
||||||
|
val directoryPicker = item as DirectoryPicker
|
||||||
|
|
||||||
if (!PermissionsHandler.isExternalStorageLegacy()) {
|
if (!PermissionsHandler.isExternalStorageLegacy()) {
|
||||||
MaterialAlertDialogBuilder(context)
|
MaterialAlertDialogBuilder(context)
|
||||||
@ -364,10 +366,11 @@ class SettingsAdapter(
|
|||||||
.setPositiveButton(R.string.ok) { dialog: DialogInterface, _: Int -> dialog.dismiss() }
|
.setPositiveButton(R.string.ok) { dialog: DialogInterface, _: Int -> dialog.dismiss() }
|
||||||
.show()
|
.show()
|
||||||
} else {
|
} else {
|
||||||
FileBrowserHelper.openDirectoryPicker(
|
val intent = FileBrowserHelper.createDirectoryPickerIntent(
|
||||||
fragmentView.fragmentActivity,
|
fragmentView.fragmentActivity,
|
||||||
FileBrowserHelper.GAME_EXTENSIONS
|
FileBrowserHelper.GAME_EXTENSIONS
|
||||||
)
|
)
|
||||||
|
directoryPicker.launcher.launch(intent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -383,7 +386,7 @@ class SettingsAdapter(
|
|||||||
intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, filePicker.getSelectedValue())
|
intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, filePicker.getSelectedValue())
|
||||||
}
|
}
|
||||||
|
|
||||||
fragmentView.fragmentActivity.startActivityForResult(intent, filePicker.requestType)
|
filePicker.launcher.launch(intent)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onDateTimeClick(item: DateTimeChoiceSetting, position: Int) {
|
fun onDateTimeClick(item: DateTimeChoiceSetting, position: Int) {
|
||||||
|
|||||||
@ -1,17 +1,22 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
// GPU driver implementation partially based on:
|
||||||
|
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
package org.dolphinemu.dolphinemu.features.settings.ui
|
package org.dolphinemu.dolphinemu.features.settings.ui
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.DialogInterface
|
import android.content.DialogInterface
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.net.Uri
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.activity.result.ActivityResult
|
||||||
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
import androidx.core.view.ViewCompat
|
import androidx.core.view.ViewCompat
|
||||||
import androidx.core.view.WindowInsetsCompat
|
import androidx.core.view.WindowInsetsCompat
|
||||||
import androidx.core.view.updatePadding
|
import androidx.core.view.updatePadding
|
||||||
@ -26,7 +31,6 @@ import org.dolphinemu.dolphinemu.R
|
|||||||
import org.dolphinemu.dolphinemu.databinding.FragmentSettingsBinding
|
import org.dolphinemu.dolphinemu.databinding.FragmentSettingsBinding
|
||||||
import org.dolphinemu.dolphinemu.features.settings.model.Settings
|
import org.dolphinemu.dolphinemu.features.settings.model.Settings
|
||||||
import org.dolphinemu.dolphinemu.features.settings.model.view.SettingsItem
|
import org.dolphinemu.dolphinemu.features.settings.model.view.SettingsItem
|
||||||
import org.dolphinemu.dolphinemu.ui.main.MainPresenter
|
|
||||||
import org.dolphinemu.dolphinemu.utils.GpuDriverInstallResult
|
import org.dolphinemu.dolphinemu.utils.GpuDriverInstallResult
|
||||||
import org.dolphinemu.dolphinemu.utils.SerializableHelper.serializable
|
import org.dolphinemu.dolphinemu.utils.SerializableHelper.serializable
|
||||||
import java.util.*
|
import java.util.*
|
||||||
@ -43,10 +47,22 @@ class SettingsFragment : Fragment(), SettingsFragmentView {
|
|||||||
|
|
||||||
override var adapter: SettingsAdapter? = null
|
override var adapter: SettingsAdapter? = null
|
||||||
|
|
||||||
|
override val activityResultLaunchers: SettingsActivityResultLaunchers =
|
||||||
|
SettingsActivityResultLaunchers(this) { adapter }
|
||||||
|
|
||||||
private var oldControllerSettingsWarningHeight = 0
|
private var oldControllerSettingsWarningHeight = 0
|
||||||
|
|
||||||
private var binding: FragmentSettingsBinding? = null
|
private var binding: FragmentSettingsBinding? = null
|
||||||
|
|
||||||
|
private val requestGpuDriver = registerForActivityResult(
|
||||||
|
ActivityResultContracts.StartActivityForResult()
|
||||||
|
) { result: ActivityResult ->
|
||||||
|
val uri = result.data?.data
|
||||||
|
if (result.resultCode == Activity.RESULT_OK && uri != null) {
|
||||||
|
presenter.installDriver(uri)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onAttach(context: Context) {
|
override fun onAttach(context: Context) {
|
||||||
super.onAttach(context)
|
super.onAttach(context)
|
||||||
|
|
||||||
@ -185,7 +201,7 @@ class SettingsFragment : Fragment(), SettingsFragmentView {
|
|||||||
if (presenter.gpuDriver == null) {
|
if (presenter.gpuDriver == null) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val msg = "${presenter!!.gpuDriver!!.name} ${presenter!!.gpuDriver!!.driverVersion}"
|
val msg = "${presenter.gpuDriver!!.name} ${presenter.gpuDriver!!.driverVersion}"
|
||||||
|
|
||||||
MaterialAlertDialogBuilder(requireContext())
|
MaterialAlertDialogBuilder(requireContext())
|
||||||
.setTitle(getString(R.string.gpu_driver_dialog_title))
|
.setTitle(getString(R.string.gpu_driver_dialog_title))
|
||||||
@ -209,23 +225,7 @@ class SettingsFragment : Fragment(), SettingsFragmentView {
|
|||||||
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||||
type = "application/zip"
|
type = "application/zip"
|
||||||
}
|
}
|
||||||
startActivityForResult(intent, MainPresenter.REQUEST_GPU_DRIVER)
|
requestGpuDriver.launch(intent)
|
||||||
}
|
|
||||||
|
|
||||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
|
||||||
super.onActivityResult(requestCode, resultCode, data)
|
|
||||||
|
|
||||||
// If the user picked a file, as opposed to just backing out.
|
|
||||||
if (resultCode != AppCompatActivity.RESULT_OK) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (requestCode != MainPresenter.REQUEST_GPU_DRIVER) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val uri = data?.data ?: return
|
|
||||||
presenter.installDriver(uri)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDriverInstallDone(result: GpuDriverInstallResult) {
|
override fun onDriverInstallDone(result: GpuDriverInstallResult) {
|
||||||
|
|||||||
@ -32,9 +32,7 @@ import org.dolphinemu.dolphinemu.features.input.ui.ProfileDialogPresenter
|
|||||||
import org.dolphinemu.dolphinemu.features.settings.model.*
|
import org.dolphinemu.dolphinemu.features.settings.model.*
|
||||||
import org.dolphinemu.dolphinemu.features.settings.model.view.*
|
import org.dolphinemu.dolphinemu.features.settings.model.view.*
|
||||||
import org.dolphinemu.dolphinemu.model.GpuDriverMetadata
|
import org.dolphinemu.dolphinemu.model.GpuDriverMetadata
|
||||||
import org.dolphinemu.dolphinemu.ui.main.MainPresenter
|
|
||||||
import org.dolphinemu.dolphinemu.utils.*
|
import org.dolphinemu.dolphinemu.utils.*
|
||||||
import java.util.*
|
|
||||||
import kotlin.collections.ArrayList
|
import kotlin.collections.ArrayList
|
||||||
import kotlin.math.ceil
|
import kotlin.math.ceil
|
||||||
import kotlin.math.floor
|
import kotlin.math.floor
|
||||||
@ -584,57 +582,57 @@ class SettingsFragmentPresenter(
|
|||||||
StringSetting.MAIN_DEFAULT_ISO,
|
StringSetting.MAIN_DEFAULT_ISO,
|
||||||
R.string.default_ISO,
|
R.string.default_ISO,
|
||||||
0,
|
0,
|
||||||
MainPresenter.REQUEST_GAME_FILE,
|
fragmentView.activityResultLaunchers.requestGameFile,
|
||||||
null
|
null
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
sl.add(
|
sl.add(
|
||||||
FilePicker(
|
DirectoryPicker(
|
||||||
context,
|
context,
|
||||||
StringSetting.MAIN_FS_PATH,
|
StringSetting.MAIN_FS_PATH,
|
||||||
R.string.wii_NAND_root,
|
R.string.wii_NAND_root,
|
||||||
0,
|
0,
|
||||||
MainPresenter.REQUEST_DIRECTORY,
|
fragmentView.activityResultLaunchers.requestDirectory,
|
||||||
"/Wii"
|
"/Wii"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
sl.add(
|
sl.add(
|
||||||
FilePicker(
|
DirectoryPicker(
|
||||||
context,
|
context,
|
||||||
StringSetting.MAIN_DUMP_PATH,
|
StringSetting.MAIN_DUMP_PATH,
|
||||||
R.string.dump_path,
|
R.string.dump_path,
|
||||||
0,
|
0,
|
||||||
MainPresenter.REQUEST_DIRECTORY,
|
fragmentView.activityResultLaunchers.requestDirectory,
|
||||||
"/Dump"
|
"/Dump"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
sl.add(
|
sl.add(
|
||||||
FilePicker(
|
DirectoryPicker(
|
||||||
context,
|
context,
|
||||||
StringSetting.MAIN_LOAD_PATH,
|
StringSetting.MAIN_LOAD_PATH,
|
||||||
R.string.load_path,
|
R.string.load_path,
|
||||||
0,
|
0,
|
||||||
MainPresenter.REQUEST_DIRECTORY,
|
fragmentView.activityResultLaunchers.requestDirectory,
|
||||||
"/Load"
|
"/Load"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
sl.add(
|
sl.add(
|
||||||
FilePicker(
|
DirectoryPicker(
|
||||||
context,
|
context,
|
||||||
StringSetting.MAIN_RESOURCEPACK_PATH,
|
StringSetting.MAIN_RESOURCEPACK_PATH,
|
||||||
R.string.resource_pack_path,
|
R.string.resource_pack_path,
|
||||||
0,
|
0,
|
||||||
MainPresenter.REQUEST_DIRECTORY,
|
fragmentView.activityResultLaunchers.requestDirectory,
|
||||||
"/ResourcePacks"
|
"/ResourcePacks"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
sl.add(
|
sl.add(
|
||||||
FilePicker(
|
DirectoryPicker(
|
||||||
context,
|
context,
|
||||||
StringSetting.MAIN_WFS_PATH,
|
StringSetting.MAIN_WFS_PATH,
|
||||||
R.string.wfs_path,
|
R.string.wfs_path,
|
||||||
0,
|
0,
|
||||||
MainPresenter.REQUEST_DIRECTORY,
|
fragmentView.activityResultLaunchers.requestDirectory,
|
||||||
"/WFS"
|
"/WFS"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -784,17 +782,17 @@ class SettingsFragmentPresenter(
|
|||||||
StringSetting.MAIN_WII_SD_CARD_IMAGE_PATH,
|
StringSetting.MAIN_WII_SD_CARD_IMAGE_PATH,
|
||||||
R.string.wii_sd_card_path,
|
R.string.wii_sd_card_path,
|
||||||
0,
|
0,
|
||||||
MainPresenter.REQUEST_SD_FILE,
|
fragmentView.activityResultLaunchers.requestRawFile,
|
||||||
"/Load/WiiSD.raw"
|
"/Load/WiiSD.raw"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
sl.add(
|
sl.add(
|
||||||
FilePicker(
|
DirectoryPicker(
|
||||||
context,
|
context,
|
||||||
StringSetting.MAIN_WII_SD_CARD_SYNC_FOLDER_PATH,
|
StringSetting.MAIN_WII_SD_CARD_SYNC_FOLDER_PATH,
|
||||||
R.string.wii_sd_sync_folder,
|
R.string.wii_sd_sync_folder,
|
||||||
0,
|
0,
|
||||||
MainPresenter.REQUEST_DIRECTORY,
|
fragmentView.activityResultLaunchers.requestDirectory,
|
||||||
"/Load/WiiSDSync/"
|
"/Load/WiiSDSync/"
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
@ -38,6 +38,11 @@ interface SettingsFragmentView {
|
|||||||
*/
|
*/
|
||||||
val adapter: SettingsAdapter?
|
val adapter: SettingsAdapter?
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The activity result launchers to use for asking the user to pick a directory or file.
|
||||||
|
*/
|
||||||
|
val activityResultLaunchers: SettingsActivityResultLaunchers
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tell the Fragment to tell the containing Activity to show a new
|
* Tell the Fragment to tell the containing Activity to show a new
|
||||||
* Fragment containing a submenu of settings.
|
* Fragment containing a submenu of settings.
|
||||||
|
|||||||
@ -9,7 +9,6 @@ import org.dolphinemu.dolphinemu.databinding.ListItemSettingBinding
|
|||||||
import org.dolphinemu.dolphinemu.features.settings.model.view.FilePicker
|
import org.dolphinemu.dolphinemu.features.settings.model.view.FilePicker
|
||||||
import org.dolphinemu.dolphinemu.features.settings.model.view.SettingsItem
|
import org.dolphinemu.dolphinemu.features.settings.model.view.SettingsItem
|
||||||
import org.dolphinemu.dolphinemu.features.settings.ui.SettingsAdapter
|
import org.dolphinemu.dolphinemu.features.settings.ui.SettingsAdapter
|
||||||
import org.dolphinemu.dolphinemu.ui.main.MainPresenter
|
|
||||||
import org.dolphinemu.dolphinemu.utils.DirectoryInitialization
|
import org.dolphinemu.dolphinemu.utils.DirectoryInitialization
|
||||||
import org.dolphinemu.dolphinemu.utils.FileBrowserHelper
|
import org.dolphinemu.dolphinemu.utils.FileBrowserHelper
|
||||||
|
|
||||||
@ -57,7 +56,7 @@ class FilePickerViewHolder(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val position = bindingAdapterPosition
|
val position = bindingAdapterPosition
|
||||||
if (setting.requestType == MainPresenter.REQUEST_DIRECTORY) {
|
if (setting.type == SettingsItem.TYPE_DIRECTORY_PICKER) {
|
||||||
adapter.onFilePickerDirectoryClick(setting, position)
|
adapter.onFilePickerDirectoryClick(setting, position)
|
||||||
} else {
|
} else {
|
||||||
adapter.onFilePickerFileClick(setting, position)
|
adapter.onFilePickerFileClick(setting, position)
|
||||||
|
|||||||
@ -46,14 +46,8 @@ class SkylanderSlotAdapter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
holder.binding.buttonLoadFigure.setOnClickListener {
|
holder.binding.buttonLoadFigure.setOnClickListener {
|
||||||
val loadSkylander = Intent(Intent.ACTION_OPEN_DOCUMENT)
|
|
||||||
loadSkylander.addCategory(Intent.CATEGORY_OPENABLE)
|
|
||||||
loadSkylander.type = "*/*"
|
|
||||||
activity.setSkylanderData(0, 0, "", position)
|
activity.setSkylanderData(0, 0, "", position)
|
||||||
activity.startActivityForResult(
|
activity.requestSkylanderFile.launch("*/*")
|
||||||
loadSkylander,
|
|
||||||
EmulationActivity.REQUEST_SKYLANDER_FILE
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val inflater = LayoutInflater.from(activity)
|
val inflater = LayoutInflater.from(activity)
|
||||||
@ -85,29 +79,12 @@ class SkylanderSlotAdapter(
|
|||||||
if (binding.skylanderId.text.toString().isNotBlank() &&
|
if (binding.skylanderId.text.toString().isNotBlank() &&
|
||||||
binding.skylanderVar.text.toString().isNotBlank()
|
binding.skylanderVar.text.toString().isNotBlank()
|
||||||
) {
|
) {
|
||||||
val createSkylander = Intent(Intent.ACTION_CREATE_DOCUMENT)
|
|
||||||
createSkylander.addCategory(Intent.CATEGORY_OPENABLE)
|
|
||||||
createSkylander.type = "*/*"
|
|
||||||
val id = binding.skylanderId.text.toString().toInt()
|
val id = binding.skylanderId.text.toString().toInt()
|
||||||
val variant = binding.skylanderVar.text.toString().toInt()
|
val variant = binding.skylanderVar.text.toString().toInt()
|
||||||
val name = SkylanderConfig.LIST_SKYLANDERS[SkylanderPair(id, variant)]
|
val name = SkylanderConfig.LIST_SKYLANDERS[SkylanderPair(id, variant)]
|
||||||
if (name != null) {
|
val title = if (name != null) "$name.sky" else "Unknown(ID: $id Variant: $variant).sky"
|
||||||
createSkylander.putExtra(
|
activity.setSkylanderData(id, variant, name ?: "Unknown", position)
|
||||||
Intent.EXTRA_TITLE,
|
activity.requestCreateSkylander.launch(title)
|
||||||
"$name.sky"
|
|
||||||
)
|
|
||||||
activity.setSkylanderData(id, variant, name, position)
|
|
||||||
} else {
|
|
||||||
createSkylander.putExtra(
|
|
||||||
Intent.EXTRA_TITLE,
|
|
||||||
"Unknown(ID: " + id + "Variant: " + variant + ").sky"
|
|
||||||
)
|
|
||||||
activity.setSkylanderData(id, variant, "Unknown", position)
|
|
||||||
}
|
|
||||||
activity.startActivityForResult(
|
|
||||||
createSkylander,
|
|
||||||
EmulationActivity.REQUEST_CREATE_SKYLANDER
|
|
||||||
)
|
|
||||||
createDialog.dismiss()
|
createDialog.dismiss()
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
|
|||||||
@ -15,6 +15,8 @@ import android.view.ViewGroup
|
|||||||
import android.widget.AdapterView
|
import android.widget.AdapterView
|
||||||
import android.widget.AdapterView.OnItemClickListener
|
import android.widget.AdapterView.OnItemClickListener
|
||||||
import android.widget.ArrayAdapter
|
import android.widget.ArrayAdapter
|
||||||
|
import androidx.activity.result.ActivityResult
|
||||||
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
@ -79,6 +81,15 @@ class ConvertFragment : Fragment(), View.OnClickListener {
|
|||||||
private var _binding: FragmentConvertBinding? = null
|
private var _binding: FragmentConvertBinding? = null
|
||||||
val binding get() = _binding!!
|
val binding get() = _binding!!
|
||||||
|
|
||||||
|
private val requestSaveFile = registerForActivityResult(
|
||||||
|
ActivityResultContracts.StartActivityForResult()
|
||||||
|
) { result: ActivityResult ->
|
||||||
|
val uri = result.data?.data
|
||||||
|
if (result.resultCode == Activity.RESULT_OK && uri != null) {
|
||||||
|
convert(uri.toString())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
gameFile = GameFileCacheManager.addOrGet(requireArguments().getString(ARG_GAME_PATH))
|
gameFile = GameFileCacheManager.addOrGet(requireArguments().getString(ARG_GAME_PATH))
|
||||||
@ -429,13 +440,7 @@ class ConvertFragment : Fragment(), View.OnClickListener {
|
|||||||
DocumentsContract.EXTRA_INITIAL_URI,
|
DocumentsContract.EXTRA_INITIAL_URI,
|
||||||
originalPath
|
originalPath
|
||||||
)
|
)
|
||||||
startActivityForResult(intent, REQUEST_CODE_SAVE_FILE)
|
requestSaveFile.launch(intent)
|
||||||
}
|
|
||||||
|
|
||||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
|
||||||
if (requestCode == REQUEST_CODE_SAVE_FILE && resultCode == Activity.RESULT_OK) {
|
|
||||||
convert(data!!.data.toString())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun convert(outPath: String) {
|
private fun convert(outPath: String) {
|
||||||
@ -515,8 +520,6 @@ class ConvertFragment : Fragment(), View.OnClickListener {
|
|||||||
private const val KEY_COMPRESSION_LEVEL = "convert_compression_level"
|
private const val KEY_COMPRESSION_LEVEL = "convert_compression_level"
|
||||||
private const val KEY_REMOVE_JUNK_DATA = "remove_junk_data"
|
private const val KEY_REMOVE_JUNK_DATA = "remove_junk_data"
|
||||||
|
|
||||||
private const val REQUEST_CODE_SAVE_FILE = 0
|
|
||||||
|
|
||||||
private const val BLOB_TYPE_ISO = 0
|
private const val BLOB_TYPE_ISO = 0
|
||||||
private const val BLOB_TYPE_GCZ = 3
|
private const val BLOB_TYPE_GCZ = 3
|
||||||
private const val BLOB_TYPE_WIA = 7
|
private const val BLOB_TYPE_WIA = 7
|
||||||
|
|||||||
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
package org.dolphinemu.dolphinemu.ui.main
|
package org.dolphinemu.dolphinemu.ui.main
|
||||||
|
|
||||||
import android.content.Intent
|
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
@ -18,7 +17,6 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout.OnRefreshListener
|
|||||||
import com.google.android.material.appbar.AppBarLayout
|
import com.google.android.material.appbar.AppBarLayout
|
||||||
import com.google.android.material.tabs.TabLayout
|
import com.google.android.material.tabs.TabLayout
|
||||||
import org.dolphinemu.dolphinemu.R
|
import org.dolphinemu.dolphinemu.R
|
||||||
import org.dolphinemu.dolphinemu.activities.EmulationActivity
|
|
||||||
import org.dolphinemu.dolphinemu.adapters.PlatformPagerAdapter
|
import org.dolphinemu.dolphinemu.adapters.PlatformPagerAdapter
|
||||||
import org.dolphinemu.dolphinemu.databinding.ActivityMainBinding
|
import org.dolphinemu.dolphinemu.databinding.ActivityMainBinding
|
||||||
import org.dolphinemu.dolphinemu.features.settings.model.IntSetting
|
import org.dolphinemu.dolphinemu.features.settings.model.IntSetting
|
||||||
@ -31,7 +29,6 @@ import org.dolphinemu.dolphinemu.ui.platform.PlatformGamesView
|
|||||||
import org.dolphinemu.dolphinemu.ui.platform.PlatformTab
|
import org.dolphinemu.dolphinemu.ui.platform.PlatformTab
|
||||||
import org.dolphinemu.dolphinemu.utils.AfterDirectoryInitializationRunner
|
import org.dolphinemu.dolphinemu.utils.AfterDirectoryInitializationRunner
|
||||||
import org.dolphinemu.dolphinemu.utils.DirectoryInitialization
|
import org.dolphinemu.dolphinemu.utils.DirectoryInitialization
|
||||||
import org.dolphinemu.dolphinemu.utils.FileBrowserHelper
|
|
||||||
import org.dolphinemu.dolphinemu.utils.InsetsHelper
|
import org.dolphinemu.dolphinemu.utils.InsetsHelper
|
||||||
import org.dolphinemu.dolphinemu.utils.PermissionsHandler
|
import org.dolphinemu.dolphinemu.utils.PermissionsHandler
|
||||||
import org.dolphinemu.dolphinemu.utils.StartupHandler
|
import org.dolphinemu.dolphinemu.utils.StartupHandler
|
||||||
@ -65,7 +62,11 @@ class MainActivity : AppCompatActivity(), MainView, OnRefreshListener, ThemeProv
|
|||||||
setSupportActionBar(binding.toolbarMain)
|
setSupportActionBar(binding.toolbarMain)
|
||||||
|
|
||||||
// Set up the FAB.
|
// Set up the FAB.
|
||||||
binding.buttonAddDirectory.setOnClickListener { presenter.onFabClick() }
|
binding.buttonAddDirectory.setOnClickListener {
|
||||||
|
AfterDirectoryInitializationRunner().runWithLifecycle(this) {
|
||||||
|
presenter.launchFileListActivity()
|
||||||
|
}
|
||||||
|
}
|
||||||
binding.appbarMain.addOnOffsetChangedListener { appBarLayout: AppBarLayout, verticalOffset: Int ->
|
binding.appbarMain.addOnOffsetChangedListener { appBarLayout: AppBarLayout, verticalOffset: Int ->
|
||||||
if (verticalOffset == 0) {
|
if (verticalOffset == 0) {
|
||||||
binding.buttonAddDirectory.extend()
|
binding.buttonAddDirectory.extend()
|
||||||
@ -145,63 +146,6 @@ class MainActivity : AppCompatActivity(), MainView, OnRefreshListener, ThemeProv
|
|||||||
SettingsActivity.launch(this, menuTag)
|
SettingsActivity.launch(this, menuTag)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun launchFileListActivity() {
|
|
||||||
if (DirectoryInitialization.preferOldFolderPicker(this)) {
|
|
||||||
FileBrowserHelper.openDirectoryPicker(this, FileBrowserHelper.GAME_EXTENSIONS)
|
|
||||||
} else {
|
|
||||||
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
|
|
||||||
startActivityForResult(intent, MainPresenter.REQUEST_DIRECTORY)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun launchOpenFileActivity(requestCode: Int) {
|
|
||||||
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT)
|
|
||||||
intent.addCategory(Intent.CATEGORY_OPENABLE)
|
|
||||||
intent.type = "*/*"
|
|
||||||
startActivityForResult(intent, requestCode)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param requestCode An int describing whether the Activity that is returning did so successfully.
|
|
||||||
* @param resultCode An int describing what Activity is giving us this callback.
|
|
||||||
* @param result The information the returning Activity is providing us.
|
|
||||||
*/
|
|
||||||
override fun onActivityResult(requestCode: Int, resultCode: Int, result: Intent?) {
|
|
||||||
super.onActivityResult(requestCode, resultCode, result)
|
|
||||||
|
|
||||||
// If the user picked a file, as opposed to just backing out.
|
|
||||||
if (resultCode == RESULT_OK) {
|
|
||||||
val uri = result!!.data
|
|
||||||
when (requestCode) {
|
|
||||||
MainPresenter.REQUEST_DIRECTORY -> {
|
|
||||||
if (DirectoryInitialization.preferOldFolderPicker(this)) {
|
|
||||||
presenter.onDirectorySelected(FileBrowserHelper.getSelectedPath(result))
|
|
||||||
} else {
|
|
||||||
presenter.onDirectorySelected(result)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MainPresenter.REQUEST_GAME_FILE -> FileBrowserHelper.runAfterExtensionCheck(
|
|
||||||
this, uri, FileBrowserHelper.GAME_LIKE_EXTENSIONS
|
|
||||||
) { EmulationActivity.launch(this, result.data.toString(), false) }
|
|
||||||
|
|
||||||
MainPresenter.REQUEST_WAD_FILE -> FileBrowserHelper.runAfterExtensionCheck(
|
|
||||||
this, uri, FileBrowserHelper.WAD_EXTENSION
|
|
||||||
) { presenter.installWAD(result.data.toString()) }
|
|
||||||
|
|
||||||
MainPresenter.REQUEST_WII_SAVE_FILE -> FileBrowserHelper.runAfterExtensionCheck(
|
|
||||||
this, uri, FileBrowserHelper.BIN_EXTENSION
|
|
||||||
) { presenter.importWiiSave(result.data.toString()) }
|
|
||||||
|
|
||||||
MainPresenter.REQUEST_NAND_BIN_FILE -> FileBrowserHelper.runAfterExtensionCheck(
|
|
||||||
this, uri, FileBrowserHelper.BIN_EXTENSION
|
|
||||||
) { presenter.importNANDBin(result.data.toString()) }
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
MainPresenter.skipRescanningLibrary()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onRequestPermissionsResult(
|
override fun onRequestPermissionsResult(
|
||||||
requestCode: Int,
|
requestCode: Int,
|
||||||
permissions: Array<String>,
|
permissions: Array<String>,
|
||||||
|
|||||||
@ -2,9 +2,13 @@
|
|||||||
|
|
||||||
package org.dolphinemu.dolphinemu.ui.main
|
package org.dolphinemu.dolphinemu.ui.main
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
import android.content.DialogInterface
|
import android.content.DialogInterface
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
import android.net.Uri
|
||||||
import androidx.activity.ComponentActivity
|
import androidx.activity.ComponentActivity
|
||||||
|
import androidx.activity.result.ActivityResult
|
||||||
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
import androidx.fragment.app.FragmentActivity
|
import androidx.fragment.app.FragmentActivity
|
||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
import androidx.lifecycle.ViewModelProvider
|
import androidx.lifecycle.ViewModelProvider
|
||||||
@ -35,6 +39,69 @@ import java.util.concurrent.ExecutionException
|
|||||||
class MainPresenter(private val mainView: MainView, private val activity: FragmentActivity) {
|
class MainPresenter(private val mainView: MainView, private val activity: FragmentActivity) {
|
||||||
private var dirToAdd: String? = null
|
private var dirToAdd: String? = null
|
||||||
|
|
||||||
|
private val requestDirectory = activity.registerForActivityResult(
|
||||||
|
ActivityResultContracts.StartActivityForResult()
|
||||||
|
) { result: ActivityResult ->
|
||||||
|
val intent = result.data
|
||||||
|
if (result.resultCode == Activity.RESULT_OK && intent != null) {
|
||||||
|
if (DirectoryInitialization.preferOldFolderPicker(activity)) {
|
||||||
|
onDirectorySelected(FileBrowserHelper.getSelectedPath(intent))
|
||||||
|
} else {
|
||||||
|
onDirectorySelected(intent)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
skipRescanningLibrary()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val requestGameFile = activity.registerForActivityResult(
|
||||||
|
ActivityResultContracts.GetContent()
|
||||||
|
) { uri: Uri? ->
|
||||||
|
if (uri != null) {
|
||||||
|
FileBrowserHelper.runAfterExtensionCheck(
|
||||||
|
activity, uri, FileBrowserHelper.GAME_LIKE_EXTENSIONS
|
||||||
|
) { EmulationActivity.launch(activity, uri.toString(), false) }
|
||||||
|
} else {
|
||||||
|
skipRescanningLibrary()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val requestWadFile = activity.registerForActivityResult(
|
||||||
|
ActivityResultContracts.GetContent()
|
||||||
|
) { uri: Uri? ->
|
||||||
|
if (uri != null) {
|
||||||
|
FileBrowserHelper.runAfterExtensionCheck(
|
||||||
|
activity, uri, FileBrowserHelper.WAD_EXTENSION
|
||||||
|
) { installWAD(uri.toString()) }
|
||||||
|
} else {
|
||||||
|
skipRescanningLibrary()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val requestWiiSaveFile = activity.registerForActivityResult(
|
||||||
|
ActivityResultContracts.GetContent()
|
||||||
|
) { uri: Uri? ->
|
||||||
|
if (uri != null) {
|
||||||
|
FileBrowserHelper.runAfterExtensionCheck(
|
||||||
|
activity, uri, FileBrowserHelper.BIN_EXTENSION
|
||||||
|
) { importWiiSave(uri.toString()) }
|
||||||
|
} else {
|
||||||
|
skipRescanningLibrary()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val requestNandBinFile = activity.registerForActivityResult(
|
||||||
|
ActivityResultContracts.GetContent()
|
||||||
|
) { uri: Uri? ->
|
||||||
|
if (uri != null) {
|
||||||
|
FileBrowserHelper.runAfterExtensionCheck(
|
||||||
|
activity, uri, FileBrowserHelper.BIN_EXTENSION
|
||||||
|
) { importNANDBin(uri.toString()) }
|
||||||
|
} else {
|
||||||
|
skipRescanningLibrary()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun onCreate() {
|
fun onCreate() {
|
||||||
// Ask the user to grant write permission if relevant and not already granted
|
// Ask the user to grant write permission if relevant and not already granted
|
||||||
if (DirectoryInitialization.isWaitingForWriteAccess(activity))
|
if (DirectoryInitialization.isWaitingForWriteAccess(activity))
|
||||||
@ -50,8 +117,17 @@ class MainPresenter(private val mainView: MainView, private val activity: Fragme
|
|||||||
GameFileCacheManager.isRescanning().observe(activity, refreshObserver)
|
GameFileCacheManager.isRescanning().observe(activity, refreshObserver)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onFabClick() {
|
fun launchFileListActivity() {
|
||||||
AfterDirectoryInitializationRunner().runWithLifecycle(activity) { mainView.launchFileListActivity() }
|
val intent =
|
||||||
|
if (DirectoryInitialization.preferOldFolderPicker(activity)) {
|
||||||
|
FileBrowserHelper.createDirectoryPickerIntent(
|
||||||
|
activity,
|
||||||
|
FileBrowserHelper.GAME_EXTENSIONS,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
|
||||||
|
}
|
||||||
|
requestDirectory.launch(intent)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun handleOptionSelection(itemId: Int, activity: ComponentActivity): Boolean =
|
fun handleOptionSelection(itemId: Int, activity: ComponentActivity): Boolean =
|
||||||
@ -73,12 +149,12 @@ class MainPresenter(private val mainView: MainView, private val activity: Fragme
|
|||||||
}
|
}
|
||||||
|
|
||||||
R.id.button_add_directory -> {
|
R.id.button_add_directory -> {
|
||||||
AfterDirectoryInitializationRunner().runWithLifecycle(activity) { mainView.launchFileListActivity() }
|
AfterDirectoryInitializationRunner().runWithLifecycle(activity) { launchFileListActivity() }
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
R.id.menu_open_file -> {
|
R.id.menu_open_file -> {
|
||||||
mainView.launchOpenFileActivity(REQUEST_GAME_FILE)
|
requestGameFile.launch("*/*")
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,21 +171,21 @@ class MainPresenter(private val mainView: MainView, private val activity: Fragme
|
|||||||
R.id.menu_install_wad -> {
|
R.id.menu_install_wad -> {
|
||||||
AfterDirectoryInitializationRunner().runWithLifecycle(
|
AfterDirectoryInitializationRunner().runWithLifecycle(
|
||||||
activity
|
activity
|
||||||
) { mainView.launchOpenFileActivity(REQUEST_WAD_FILE) }
|
) { requestWadFile.launch("*/*") }
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
R.id.menu_import_wii_save -> {
|
R.id.menu_import_wii_save -> {
|
||||||
AfterDirectoryInitializationRunner().runWithLifecycle(
|
AfterDirectoryInitializationRunner().runWithLifecycle(
|
||||||
activity
|
activity
|
||||||
) { mainView.launchOpenFileActivity(REQUEST_WII_SAVE_FILE) }
|
) { requestWiiSaveFile.launch("*/*") }
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
R.id.menu_import_nand_backup -> {
|
R.id.menu_import_nand_backup -> {
|
||||||
AfterDirectoryInitializationRunner().runWithLifecycle(
|
AfterDirectoryInitializationRunner().runWithLifecycle(
|
||||||
activity
|
activity
|
||||||
) { mainView.launchOpenFileActivity(REQUEST_NAND_BIN_FILE) }
|
) { requestNandBinFile.launch("*/*") }
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -280,14 +356,6 @@ class MainPresenter(private val mainView: MainView, private val activity: Fragme
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val REQUEST_DIRECTORY = 1
|
|
||||||
const val REQUEST_GAME_FILE = 2
|
|
||||||
const val REQUEST_SD_FILE = 3
|
|
||||||
const val REQUEST_WAD_FILE = 4
|
|
||||||
const val REQUEST_WII_SAVE_FILE = 5
|
|
||||||
const val REQUEST_NAND_BIN_FILE = 6
|
|
||||||
const val REQUEST_GPU_DRIVER = 7
|
|
||||||
|
|
||||||
private var shouldRescanLibrary = true
|
private var shouldRescanLibrary = true
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
|
|||||||
@ -20,10 +20,6 @@ interface MainView {
|
|||||||
|
|
||||||
fun launchSettingsActivity(menuTag: MenuTag?)
|
fun launchSettingsActivity(menuTag: MenuTag?)
|
||||||
|
|
||||||
fun launchFileListActivity()
|
|
||||||
|
|
||||||
fun launchOpenFileActivity(requestCode: Int)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shows or hides the loading indicator.
|
* Shows or hides the loading indicator.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -125,22 +125,6 @@ class TvMainActivity : FragmentActivity(), MainView, OnRefreshListener {
|
|||||||
SettingsActivity.launch(this, menuTag)
|
SettingsActivity.launch(this, menuTag)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun launchFileListActivity() {
|
|
||||||
if (DirectoryInitialization.preferOldFolderPicker(this)) {
|
|
||||||
FileBrowserHelper.openDirectoryPicker(this, FileBrowserHelper.GAME_EXTENSIONS)
|
|
||||||
} else {
|
|
||||||
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
|
|
||||||
startActivityForResult(intent, MainPresenter.REQUEST_DIRECTORY)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun launchOpenFileActivity(requestCode: Int) {
|
|
||||||
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT)
|
|
||||||
intent.addCategory(Intent.CATEGORY_OPENABLE)
|
|
||||||
intent.type = "*/*"
|
|
||||||
startActivityForResult(intent, requestCode)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shows or hides the loading indicator.
|
* Shows or hides the loading indicator.
|
||||||
*/
|
*/
|
||||||
@ -165,49 +149,6 @@ class TvMainActivity : FragmentActivity(), MainView, OnRefreshListener {
|
|||||||
GridOptionDialogFragment().show(supportFragmentManager, "gridOptions")
|
GridOptionDialogFragment().show(supportFragmentManager, "gridOptions")
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Callback from AddDirectoryActivity. Applies any changes necessary to the GameGridActivity.
|
|
||||||
*
|
|
||||||
* @param requestCode An int describing whether the Activity that is returning did so successfully.
|
|
||||||
* @param resultCode An int describing what Activity is giving us this callback.
|
|
||||||
* @param result The information the returning Activity is providing us.
|
|
||||||
*/
|
|
||||||
override fun onActivityResult(requestCode: Int, resultCode: Int, result: Intent?) {
|
|
||||||
super.onActivityResult(requestCode, resultCode, result)
|
|
||||||
|
|
||||||
// If the user picked a file, as opposed to just backing out.
|
|
||||||
if (resultCode == RESULT_OK) {
|
|
||||||
val uri = result!!.data
|
|
||||||
when (requestCode) {
|
|
||||||
MainPresenter.REQUEST_DIRECTORY -> {
|
|
||||||
if (DirectoryInitialization.preferOldFolderPicker(this)) {
|
|
||||||
presenter.onDirectorySelected(FileBrowserHelper.getSelectedPath(result))
|
|
||||||
} else {
|
|
||||||
presenter.onDirectorySelected(result)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MainPresenter.REQUEST_GAME_FILE -> FileBrowserHelper.runAfterExtensionCheck(
|
|
||||||
this, uri, FileBrowserHelper.GAME_LIKE_EXTENSIONS
|
|
||||||
) { EmulationActivity.launch(this, result.data.toString(), false) }
|
|
||||||
|
|
||||||
MainPresenter.REQUEST_WAD_FILE -> FileBrowserHelper.runAfterExtensionCheck(
|
|
||||||
this, uri, FileBrowserHelper.WAD_EXTENSION
|
|
||||||
) { presenter.installWAD(result.data.toString()) }
|
|
||||||
|
|
||||||
MainPresenter.REQUEST_WII_SAVE_FILE -> FileBrowserHelper.runAfterExtensionCheck(
|
|
||||||
this, uri, FileBrowserHelper.BIN_EXTENSION
|
|
||||||
) { presenter.importWiiSave(result.data.toString()) }
|
|
||||||
|
|
||||||
MainPresenter.REQUEST_NAND_BIN_FILE -> FileBrowserHelper.runAfterExtensionCheck(
|
|
||||||
this, uri, FileBrowserHelper.BIN_EXTENSION
|
|
||||||
) { presenter.importNANDBin(result.data.toString()) }
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
MainPresenter.skipRescanningLibrary()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onRequestPermissionsResult(
|
override fun onRequestPermissionsResult(
|
||||||
requestCode: Int,
|
requestCode: Int,
|
||||||
permissions: Array<String>,
|
permissions: Array<String>,
|
||||||
|
|||||||
@ -17,7 +17,6 @@ import com.nononsenseapps.filepicker.Utils;
|
|||||||
import org.dolphinemu.dolphinemu.R;
|
import org.dolphinemu.dolphinemu.R;
|
||||||
import org.dolphinemu.dolphinemu.activities.CustomFilePickerActivity;
|
import org.dolphinemu.dolphinemu.activities.CustomFilePickerActivity;
|
||||||
import org.dolphinemu.dolphinemu.features.settings.model.StringSetting;
|
import org.dolphinemu.dolphinemu.features.settings.model.StringSetting;
|
||||||
import org.dolphinemu.dolphinemu.ui.main.MainPresenter;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -49,7 +48,8 @@ public final class FileBrowserHelper
|
|||||||
public static final HashSet<String> WAD_EXTENSION = new HashSet<>(Collections.singletonList(
|
public static final HashSet<String> WAD_EXTENSION = new HashSet<>(Collections.singletonList(
|
||||||
"wad"));
|
"wad"));
|
||||||
|
|
||||||
public static void openDirectoryPicker(FragmentActivity activity, HashSet<String> extensions)
|
public static Intent createDirectoryPickerIntent(FragmentActivity activity,
|
||||||
|
HashSet<String> extensions)
|
||||||
{
|
{
|
||||||
Intent i = new Intent(activity, CustomFilePickerActivity.class);
|
Intent i = new Intent(activity, CustomFilePickerActivity.class);
|
||||||
|
|
||||||
@ -60,7 +60,7 @@ public final class FileBrowserHelper
|
|||||||
Environment.getExternalStorageDirectory().getPath());
|
Environment.getExternalStorageDirectory().getPath());
|
||||||
i.putExtra(CustomFilePickerActivity.EXTRA_EXTENSIONS, extensions);
|
i.putExtra(CustomFilePickerActivity.EXTRA_EXTENSIONS, extensions);
|
||||||
|
|
||||||
activity.startActivityForResult(i, MainPresenter.REQUEST_DIRECTORY);
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user