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
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.DialogInterface
|
||||
import android.content.Intent
|
||||
import android.graphics.Rect
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.util.SparseIntArray
|
||||
@ -16,6 +16,7 @@ import android.view.View
|
||||
import android.view.ViewGroup.MarginLayoutParams
|
||||
import android.view.WindowManager
|
||||
import android.widget.Toast
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.widget.PopupMenu
|
||||
import androidx.core.view.ViewCompat
|
||||
@ -87,6 +88,92 @@ class EmulationActivity : AppCompatActivity(), ThemeProvider {
|
||||
|
||||
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?) {
|
||||
ThemeHelper.setTheme(this)
|
||||
|
||||
@ -263,70 +350,6 @@ class EmulationActivity : AppCompatActivity(), ThemeProvider {
|
||||
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() {
|
||||
WindowCompat.setDecorFitsSystemWindows(window, false)
|
||||
WindowInsetsControllerCompat(window, window.decorView).let { controller ->
|
||||
@ -480,12 +503,7 @@ class EmulationActivity : AppCompatActivity(), ThemeProvider {
|
||||
MENU_ACTION_LOAD_SLOT4 -> NativeLibrary.LoadState(3)
|
||||
MENU_ACTION_LOAD_SLOT5 -> NativeLibrary.LoadState(4)
|
||||
MENU_ACTION_LOAD_SLOT6 -> NativeLibrary.LoadState(5)
|
||||
MENU_ACTION_CHANGE_DISC -> {
|
||||
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT)
|
||||
intent.addCategory(Intent.CATEGORY_OPENABLE)
|
||||
intent.type = "*/*"
|
||||
startActivityForResult(intent, REQUEST_CHANGE_DISC)
|
||||
}
|
||||
MENU_ACTION_CHANGE_DISC -> requestChangeDisc.launch("*/*")
|
||||
|
||||
MENU_SET_IR_MODE -> setIRMode()
|
||||
MENU_ACTION_CHOOSE_DOUBLETAP -> chooseDoubleTapButton()
|
||||
@ -997,11 +1015,6 @@ class EmulationActivity : AppCompatActivity(), ThemeProvider {
|
||||
companion object {
|
||||
private const val BACKSTACK_NAME_MENU = "menu"
|
||||
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
|
||||
|
||||
|
||||
@ -11,6 +11,8 @@ import android.os.Bundle
|
||||
import android.provider.DocumentsContract
|
||||
import android.view.View
|
||||
import androidx.activity.enableEdgeToEdge
|
||||
import androidx.activity.result.ActivityResult
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
@ -44,6 +46,39 @@ class UserDataActivity : AppCompatActivity(), ThemeProvider {
|
||||
private lateinit var mBinding: ActivityUserDataBinding
|
||||
|
||||
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?) {
|
||||
taskViewModel = ViewModelProvider(this)[TaskViewModel::class.java]
|
||||
@ -108,34 +143,6 @@ class UserDataActivity : AppCompatActivity(), ThemeProvider {
|
||||
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() {
|
||||
MaterialAlertDialogBuilder(this)
|
||||
.setTitle(R.string.reset_dolphin_settings)
|
||||
@ -216,15 +223,14 @@ class UserDataActivity : AppCompatActivity(), ThemeProvider {
|
||||
}
|
||||
|
||||
private fun importUserData() {
|
||||
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT)
|
||||
intent.type = "application/zip"
|
||||
startActivityForResult(intent, REQUEST_CODE_IMPORT)
|
||||
requestImport.launch(arrayOf("application/zip"))
|
||||
}
|
||||
|
||||
fun importUserData(source: Uri): Int {
|
||||
try {
|
||||
if (!isDolphinUserDataBackup(source))
|
||||
if (!isDolphinUserDataBackup(source)) {
|
||||
return R.string.user_data_import_invalid_file
|
||||
}
|
||||
|
||||
taskViewModel.onResultDismiss = {
|
||||
// Restart the app to apply the imported user data.
|
||||
@ -319,10 +325,7 @@ class UserDataActivity : AppCompatActivity(), ThemeProvider {
|
||||
}
|
||||
|
||||
private fun exportUserData() {
|
||||
val intent = Intent(Intent.ACTION_CREATE_DOCUMENT)
|
||||
intent.type = "application/zip"
|
||||
intent.putExtra(Intent.EXTRA_TITLE, "dolphin-emu.zip")
|
||||
startActivityForResult(intent, REQUEST_CODE_EXPORT)
|
||||
requestExport.launch("dolphin-emu.zip")
|
||||
}
|
||||
|
||||
private fun exportUserData(destination: Uri): Int {
|
||||
@ -385,9 +388,6 @@ class UserDataActivity : AppCompatActivity(), ThemeProvider {
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val REQUEST_CODE_IMPORT = 0
|
||||
private const val REQUEST_CODE_EXPORT = 1
|
||||
|
||||
private const val BUFFER_SIZE = 64 * 1024
|
||||
|
||||
@JvmStatic
|
||||
|
||||
@ -50,14 +50,8 @@ class FigureSlotAdapter(
|
||||
}
|
||||
|
||||
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.startActivityForResult(
|
||||
loadFigure,
|
||||
EmulationActivity.REQUEST_INFINITY_FIGURE_FILE
|
||||
)
|
||||
activity.requestInfinityFigureFile.launch("*/*")
|
||||
}
|
||||
|
||||
val inflater = LayoutInflater.from(activity)
|
||||
@ -110,28 +104,11 @@ class FigureSlotAdapter(
|
||||
.show()
|
||||
createDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener {
|
||||
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 name = InfinityConfig.LIST_FIGURES[num]
|
||||
if (name != null) {
|
||||
createFigure.putExtra(
|
||||
Intent.EXTRA_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
|
||||
)
|
||||
val title = if (name != null) "$name.bin" else "Unknown(Number: $num).bin"
|
||||
activity.setInfinityFigureData(num, name ?: "Unknown", figure.position, position)
|
||||
activity.requestCreateInfinityFigure.launch(title)
|
||||
createDialog.dismiss()
|
||||
} else {
|
||||
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
|
||||
|
||||
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.Settings
|
||||
|
||||
class FilePicker(
|
||||
open class FilePicker(
|
||||
context: Context,
|
||||
override var setting: AbstractStringSetting,
|
||||
titleId: Int,
|
||||
descriptionId: Int,
|
||||
val requestType: Int,
|
||||
val launcher: ActivityResultLauncher<Intent>,
|
||||
val defaultPathRelativeToUserDirectory: String?
|
||||
) : SettingsItem(context, titleId, descriptionId) {
|
||||
override val type: Int = TYPE_FILE_PICKER
|
||||
|
||||
@ -81,9 +81,10 @@ abstract class SettingsItem {
|
||||
const val TYPE_STRING_SINGLE_CHOICE = 6
|
||||
const val TYPE_SINGLE_CHOICE_DYNAMIC_DESCRIPTIONS = 8
|
||||
const val TYPE_FILE_PICKER = 9
|
||||
const val TYPE_RUN_RUNNABLE = 10
|
||||
const val TYPE_STRING = 11
|
||||
const val TYPE_HYPERLINK_HEADER = 12
|
||||
const val TYPE_DATETIME_CHOICE = 13
|
||||
const val TYPE_DIRECTORY_PICKER = 10
|
||||
const val TYPE_RUN_RUNNABLE = 11
|
||||
const val TYPE_STRING = 12
|
||||
const val TYPE_HYPERLINK_HEADER = 13
|
||||
const val TYPE_DATETIME_CHOICE = 14
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,15 +1,10 @@
|
||||
// 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
|
||||
|
||||
import android.content.Context
|
||||
import android.content.DialogInterface
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.view.KeyEvent
|
||||
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.ui.main.MainPresenter
|
||||
import org.dolphinemu.dolphinemu.ui.main.ThemeProvider
|
||||
import org.dolphinemu.dolphinemu.utils.FileBrowserHelper
|
||||
import org.dolphinemu.dolphinemu.utils.InsetsHelper
|
||||
import org.dolphinemu.dolphinemu.utils.SerializableHelper.serializable
|
||||
import org.dolphinemu.dolphinemu.utils.ThemeHelper.enableScrollTint
|
||||
@ -177,40 +171,6 @@ class SettingsActivity : AppCompatActivity(), SettingsActivityView, ThemeProvide
|
||||
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 {
|
||||
ControllerInterface.dispatchKeyEvent(event)
|
||||
return super.dispatchKeyEvent(event)
|
||||
@ -221,11 +181,6 @@ class SettingsActivity : AppCompatActivity(), SettingsActivityView, ThemeProvide
|
||||
return super.dispatchGenericMotionEvent(event)
|
||||
}
|
||||
|
||||
private fun canonicalizeIfPossible(uri: Uri): Uri {
|
||||
val canonicalizedUri = contentResolver.canonicalize(uri)
|
||||
return canonicalizedUri ?: uri
|
||||
}
|
||||
|
||||
override fun showLoading() {
|
||||
if (dialog == null) {
|
||||
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),
|
||||
this
|
||||
)
|
||||
SettingsItem.TYPE_FILE_PICKER -> FilePickerViewHolder(
|
||||
SettingsItem.TYPE_FILE_PICKER,
|
||||
SettingsItem.TYPE_DIRECTORY_PICKER -> FilePickerViewHolder(
|
||||
ListItemSettingBinding.inflate(inflater, parent, false),
|
||||
this
|
||||
)
|
||||
@ -357,6 +358,7 @@ class SettingsAdapter(
|
||||
fun onFilePickerDirectoryClick(item: SettingsItem, position: Int) {
|
||||
clickedItem = item
|
||||
clickedPosition = position
|
||||
val directoryPicker = item as DirectoryPicker
|
||||
|
||||
if (!PermissionsHandler.isExternalStorageLegacy()) {
|
||||
MaterialAlertDialogBuilder(context)
|
||||
@ -364,10 +366,11 @@ class SettingsAdapter(
|
||||
.setPositiveButton(R.string.ok) { dialog: DialogInterface, _: Int -> dialog.dismiss() }
|
||||
.show()
|
||||
} else {
|
||||
FileBrowserHelper.openDirectoryPicker(
|
||||
val intent = FileBrowserHelper.createDirectoryPickerIntent(
|
||||
fragmentView.fragmentActivity,
|
||||
FileBrowserHelper.GAME_EXTENSIONS
|
||||
)
|
||||
directoryPicker.launcher.launch(intent)
|
||||
}
|
||||
}
|
||||
|
||||
@ -383,7 +386,7 @@ class SettingsAdapter(
|
||||
intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, filePicker.getSelectedValue())
|
||||
}
|
||||
|
||||
fragmentView.fragmentActivity.startActivityForResult(intent, filePicker.requestType)
|
||||
filePicker.launcher.launch(intent)
|
||||
}
|
||||
|
||||
fun onDateTimeClick(item: DateTimeChoiceSetting, position: Int) {
|
||||
|
||||
@ -1,17 +1,22 @@
|
||||
// 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
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.DialogInterface
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
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.WindowInsetsCompat
|
||||
import androidx.core.view.updatePadding
|
||||
@ -26,7 +31,6 @@ import org.dolphinemu.dolphinemu.R
|
||||
import org.dolphinemu.dolphinemu.databinding.FragmentSettingsBinding
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.Settings
|
||||
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.SerializableHelper.serializable
|
||||
import java.util.*
|
||||
@ -43,10 +47,22 @@ class SettingsFragment : Fragment(), SettingsFragmentView {
|
||||
|
||||
override var adapter: SettingsAdapter? = null
|
||||
|
||||
override val activityResultLaunchers: SettingsActivityResultLaunchers =
|
||||
SettingsActivityResultLaunchers(this) { adapter }
|
||||
|
||||
private var oldControllerSettingsWarningHeight = 0
|
||||
|
||||
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) {
|
||||
super.onAttach(context)
|
||||
|
||||
@ -185,7 +201,7 @@ class SettingsFragment : Fragment(), SettingsFragmentView {
|
||||
if (presenter.gpuDriver == null) {
|
||||
return
|
||||
}
|
||||
val msg = "${presenter!!.gpuDriver!!.name} ${presenter!!.gpuDriver!!.driverVersion}"
|
||||
val msg = "${presenter.gpuDriver!!.name} ${presenter.gpuDriver!!.driverVersion}"
|
||||
|
||||
MaterialAlertDialogBuilder(requireContext())
|
||||
.setTitle(getString(R.string.gpu_driver_dialog_title))
|
||||
@ -209,23 +225,7 @@ class SettingsFragment : Fragment(), SettingsFragmentView {
|
||||
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||
type = "application/zip"
|
||||
}
|
||||
startActivityForResult(intent, MainPresenter.REQUEST_GPU_DRIVER)
|
||||
}
|
||||
|
||||
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)
|
||||
requestGpuDriver.launch(intent)
|
||||
}
|
||||
|
||||
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.view.*
|
||||
import org.dolphinemu.dolphinemu.model.GpuDriverMetadata
|
||||
import org.dolphinemu.dolphinemu.ui.main.MainPresenter
|
||||
import org.dolphinemu.dolphinemu.utils.*
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
import kotlin.math.ceil
|
||||
import kotlin.math.floor
|
||||
@ -584,57 +582,57 @@ class SettingsFragmentPresenter(
|
||||
StringSetting.MAIN_DEFAULT_ISO,
|
||||
R.string.default_ISO,
|
||||
0,
|
||||
MainPresenter.REQUEST_GAME_FILE,
|
||||
fragmentView.activityResultLaunchers.requestGameFile,
|
||||
null
|
||||
)
|
||||
)
|
||||
sl.add(
|
||||
FilePicker(
|
||||
DirectoryPicker(
|
||||
context,
|
||||
StringSetting.MAIN_FS_PATH,
|
||||
R.string.wii_NAND_root,
|
||||
0,
|
||||
MainPresenter.REQUEST_DIRECTORY,
|
||||
fragmentView.activityResultLaunchers.requestDirectory,
|
||||
"/Wii"
|
||||
)
|
||||
)
|
||||
sl.add(
|
||||
FilePicker(
|
||||
DirectoryPicker(
|
||||
context,
|
||||
StringSetting.MAIN_DUMP_PATH,
|
||||
R.string.dump_path,
|
||||
0,
|
||||
MainPresenter.REQUEST_DIRECTORY,
|
||||
fragmentView.activityResultLaunchers.requestDirectory,
|
||||
"/Dump"
|
||||
)
|
||||
)
|
||||
sl.add(
|
||||
FilePicker(
|
||||
DirectoryPicker(
|
||||
context,
|
||||
StringSetting.MAIN_LOAD_PATH,
|
||||
R.string.load_path,
|
||||
0,
|
||||
MainPresenter.REQUEST_DIRECTORY,
|
||||
fragmentView.activityResultLaunchers.requestDirectory,
|
||||
"/Load"
|
||||
)
|
||||
)
|
||||
sl.add(
|
||||
FilePicker(
|
||||
DirectoryPicker(
|
||||
context,
|
||||
StringSetting.MAIN_RESOURCEPACK_PATH,
|
||||
R.string.resource_pack_path,
|
||||
0,
|
||||
MainPresenter.REQUEST_DIRECTORY,
|
||||
fragmentView.activityResultLaunchers.requestDirectory,
|
||||
"/ResourcePacks"
|
||||
)
|
||||
)
|
||||
sl.add(
|
||||
FilePicker(
|
||||
DirectoryPicker(
|
||||
context,
|
||||
StringSetting.MAIN_WFS_PATH,
|
||||
R.string.wfs_path,
|
||||
0,
|
||||
MainPresenter.REQUEST_DIRECTORY,
|
||||
fragmentView.activityResultLaunchers.requestDirectory,
|
||||
"/WFS"
|
||||
)
|
||||
)
|
||||
@ -784,17 +782,17 @@ class SettingsFragmentPresenter(
|
||||
StringSetting.MAIN_WII_SD_CARD_IMAGE_PATH,
|
||||
R.string.wii_sd_card_path,
|
||||
0,
|
||||
MainPresenter.REQUEST_SD_FILE,
|
||||
fragmentView.activityResultLaunchers.requestRawFile,
|
||||
"/Load/WiiSD.raw"
|
||||
)
|
||||
)
|
||||
sl.add(
|
||||
FilePicker(
|
||||
DirectoryPicker(
|
||||
context,
|
||||
StringSetting.MAIN_WII_SD_CARD_SYNC_FOLDER_PATH,
|
||||
R.string.wii_sd_sync_folder,
|
||||
0,
|
||||
MainPresenter.REQUEST_DIRECTORY,
|
||||
fragmentView.activityResultLaunchers.requestDirectory,
|
||||
"/Load/WiiSDSync/"
|
||||
)
|
||||
)
|
||||
|
||||
@ -38,6 +38,11 @@ interface SettingsFragmentView {
|
||||
*/
|
||||
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
|
||||
* 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.SettingsItem
|
||||
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.FileBrowserHelper
|
||||
|
||||
@ -57,7 +56,7 @@ class FilePickerViewHolder(
|
||||
}
|
||||
|
||||
val position = bindingAdapterPosition
|
||||
if (setting.requestType == MainPresenter.REQUEST_DIRECTORY) {
|
||||
if (setting.type == SettingsItem.TYPE_DIRECTORY_PICKER) {
|
||||
adapter.onFilePickerDirectoryClick(setting, position)
|
||||
} else {
|
||||
adapter.onFilePickerFileClick(setting, position)
|
||||
|
||||
@ -46,14 +46,8 @@ class SkylanderSlotAdapter(
|
||||
}
|
||||
|
||||
holder.binding.buttonLoadFigure.setOnClickListener {
|
||||
val loadSkylander = Intent(Intent.ACTION_OPEN_DOCUMENT)
|
||||
loadSkylander.addCategory(Intent.CATEGORY_OPENABLE)
|
||||
loadSkylander.type = "*/*"
|
||||
activity.setSkylanderData(0, 0, "", position)
|
||||
activity.startActivityForResult(
|
||||
loadSkylander,
|
||||
EmulationActivity.REQUEST_SKYLANDER_FILE
|
||||
)
|
||||
activity.requestSkylanderFile.launch("*/*")
|
||||
}
|
||||
|
||||
val inflater = LayoutInflater.from(activity)
|
||||
@ -85,29 +79,12 @@ class SkylanderSlotAdapter(
|
||||
if (binding.skylanderId.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 variant = binding.skylanderVar.text.toString().toInt()
|
||||
val name = SkylanderConfig.LIST_SKYLANDERS[SkylanderPair(id, variant)]
|
||||
if (name != null) {
|
||||
createSkylander.putExtra(
|
||||
Intent.EXTRA_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
|
||||
)
|
||||
val title = if (name != null) "$name.sky" else "Unknown(ID: $id Variant: $variant).sky"
|
||||
activity.setSkylanderData(id, variant, name ?: "Unknown", position)
|
||||
activity.requestCreateSkylander.launch(title)
|
||||
createDialog.dismiss()
|
||||
} else {
|
||||
Toast.makeText(
|
||||
|
||||
@ -15,6 +15,8 @@ import android.view.ViewGroup
|
||||
import android.widget.AdapterView
|
||||
import android.widget.AdapterView.OnItemClickListener
|
||||
import android.widget.ArrayAdapter
|
||||
import androidx.activity.result.ActivityResult
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.annotation.StringRes
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
@ -79,6 +81,15 @@ class ConvertFragment : Fragment(), View.OnClickListener {
|
||||
private var _binding: FragmentConvertBinding? = null
|
||||
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?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
gameFile = GameFileCacheManager.addOrGet(requireArguments().getString(ARG_GAME_PATH))
|
||||
@ -429,13 +440,7 @@ class ConvertFragment : Fragment(), View.OnClickListener {
|
||||
DocumentsContract.EXTRA_INITIAL_URI,
|
||||
originalPath
|
||||
)
|
||||
startActivityForResult(intent, REQUEST_CODE_SAVE_FILE)
|
||||
}
|
||||
|
||||
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||
if (requestCode == REQUEST_CODE_SAVE_FILE && resultCode == Activity.RESULT_OK) {
|
||||
convert(data!!.data.toString())
|
||||
}
|
||||
requestSaveFile.launch(intent)
|
||||
}
|
||||
|
||||
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_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_GCZ = 3
|
||||
private const val BLOB_TYPE_WIA = 7
|
||||
|
||||
@ -2,7 +2,6 @@
|
||||
|
||||
package org.dolphinemu.dolphinemu.ui.main
|
||||
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Bundle
|
||||
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.tabs.TabLayout
|
||||
import org.dolphinemu.dolphinemu.R
|
||||
import org.dolphinemu.dolphinemu.activities.EmulationActivity
|
||||
import org.dolphinemu.dolphinemu.adapters.PlatformPagerAdapter
|
||||
import org.dolphinemu.dolphinemu.databinding.ActivityMainBinding
|
||||
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.utils.AfterDirectoryInitializationRunner
|
||||
import org.dolphinemu.dolphinemu.utils.DirectoryInitialization
|
||||
import org.dolphinemu.dolphinemu.utils.FileBrowserHelper
|
||||
import org.dolphinemu.dolphinemu.utils.InsetsHelper
|
||||
import org.dolphinemu.dolphinemu.utils.PermissionsHandler
|
||||
import org.dolphinemu.dolphinemu.utils.StartupHandler
|
||||
@ -65,7 +62,11 @@ class MainActivity : AppCompatActivity(), MainView, OnRefreshListener, ThemeProv
|
||||
setSupportActionBar(binding.toolbarMain)
|
||||
|
||||
// Set up the FAB.
|
||||
binding.buttonAddDirectory.setOnClickListener { presenter.onFabClick() }
|
||||
binding.buttonAddDirectory.setOnClickListener {
|
||||
AfterDirectoryInitializationRunner().runWithLifecycle(this) {
|
||||
presenter.launchFileListActivity()
|
||||
}
|
||||
}
|
||||
binding.appbarMain.addOnOffsetChangedListener { appBarLayout: AppBarLayout, verticalOffset: Int ->
|
||||
if (verticalOffset == 0) {
|
||||
binding.buttonAddDirectory.extend()
|
||||
@ -145,63 +146,6 @@ class MainActivity : AppCompatActivity(), MainView, OnRefreshListener, ThemeProv
|
||||
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(
|
||||
requestCode: Int,
|
||||
permissions: Array<String>,
|
||||
|
||||
@ -2,9 +2,13 @@
|
||||
|
||||
package org.dolphinemu.dolphinemu.ui.main
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.DialogInterface
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.activity.result.ActivityResult
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
@ -35,6 +39,69 @@ import java.util.concurrent.ExecutionException
|
||||
class MainPresenter(private val mainView: MainView, private val activity: FragmentActivity) {
|
||||
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() {
|
||||
// Ask the user to grant write permission if relevant and not already granted
|
||||
if (DirectoryInitialization.isWaitingForWriteAccess(activity))
|
||||
@ -50,8 +117,17 @@ class MainPresenter(private val mainView: MainView, private val activity: Fragme
|
||||
GameFileCacheManager.isRescanning().observe(activity, refreshObserver)
|
||||
}
|
||||
|
||||
fun onFabClick() {
|
||||
AfterDirectoryInitializationRunner().runWithLifecycle(activity) { mainView.launchFileListActivity() }
|
||||
fun 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 =
|
||||
@ -73,12 +149,12 @@ class MainPresenter(private val mainView: MainView, private val activity: Fragme
|
||||
}
|
||||
|
||||
R.id.button_add_directory -> {
|
||||
AfterDirectoryInitializationRunner().runWithLifecycle(activity) { mainView.launchFileListActivity() }
|
||||
AfterDirectoryInitializationRunner().runWithLifecycle(activity) { launchFileListActivity() }
|
||||
true
|
||||
}
|
||||
|
||||
R.id.menu_open_file -> {
|
||||
mainView.launchOpenFileActivity(REQUEST_GAME_FILE)
|
||||
requestGameFile.launch("*/*")
|
||||
true
|
||||
}
|
||||
|
||||
@ -95,21 +171,21 @@ class MainPresenter(private val mainView: MainView, private val activity: Fragme
|
||||
R.id.menu_install_wad -> {
|
||||
AfterDirectoryInitializationRunner().runWithLifecycle(
|
||||
activity
|
||||
) { mainView.launchOpenFileActivity(REQUEST_WAD_FILE) }
|
||||
) { requestWadFile.launch("*/*") }
|
||||
true
|
||||
}
|
||||
|
||||
R.id.menu_import_wii_save -> {
|
||||
AfterDirectoryInitializationRunner().runWithLifecycle(
|
||||
activity
|
||||
) { mainView.launchOpenFileActivity(REQUEST_WII_SAVE_FILE) }
|
||||
) { requestWiiSaveFile.launch("*/*") }
|
||||
true
|
||||
}
|
||||
|
||||
R.id.menu_import_nand_backup -> {
|
||||
AfterDirectoryInitializationRunner().runWithLifecycle(
|
||||
activity
|
||||
) { mainView.launchOpenFileActivity(REQUEST_NAND_BIN_FILE) }
|
||||
) { requestNandBinFile.launch("*/*") }
|
||||
true
|
||||
}
|
||||
|
||||
@ -280,14 +356,6 @@ class MainPresenter(private val mainView: MainView, private val activity: Fragme
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
@JvmStatic
|
||||
|
||||
@ -20,10 +20,6 @@ interface MainView {
|
||||
|
||||
fun launchSettingsActivity(menuTag: MenuTag?)
|
||||
|
||||
fun launchFileListActivity()
|
||||
|
||||
fun launchOpenFileActivity(requestCode: Int)
|
||||
|
||||
/**
|
||||
* Shows or hides the loading indicator.
|
||||
*/
|
||||
|
||||
@ -125,22 +125,6 @@ class TvMainActivity : FragmentActivity(), MainView, OnRefreshListener {
|
||||
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.
|
||||
*/
|
||||
@ -165,49 +149,6 @@ class TvMainActivity : FragmentActivity(), MainView, OnRefreshListener {
|
||||
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(
|
||||
requestCode: Int,
|
||||
permissions: Array<String>,
|
||||
|
||||
@ -17,7 +17,6 @@ import com.nononsenseapps.filepicker.Utils;
|
||||
import org.dolphinemu.dolphinemu.R;
|
||||
import org.dolphinemu.dolphinemu.activities.CustomFilePickerActivity;
|
||||
import org.dolphinemu.dolphinemu.features.settings.model.StringSetting;
|
||||
import org.dolphinemu.dolphinemu.ui.main.MainPresenter;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
@ -49,7 +48,8 @@ public final class FileBrowserHelper
|
||||
public static final HashSet<String> WAD_EXTENSION = new HashSet<>(Collections.singletonList(
|
||||
"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);
|
||||
|
||||
@ -60,7 +60,7 @@ public final class FileBrowserHelper
|
||||
Environment.getExternalStorageDirectory().getPath());
|
||||
i.putExtra(CustomFilePickerActivity.EXTRA_EXTENSIONS, extensions);
|
||||
|
||||
activity.startActivityForResult(i, MainPresenter.REQUEST_DIRECTORY);
|
||||
return i;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
Loading…
Reference in New Issue
Block a user