Browse Source
[android,ui] chore: settings subscreens transition and other minor conformances (#3699)
[android,ui] chore: settings subscreens transition and other minor conformances (#3699)
- Fix black screen in transition animations - Adjustments to about fragment made about text more label and less button like, header transparency, spacing adjustments, word Contributors replaced by People in Contributors field for de-duplication. - installable actions code de-duplication Extracted install/update/import firmware/user data flows into InstallableActions.kt and reused it from MainActivity and InstallableFragment, reducing duplicated logic, ensuring single source of truth. Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3699 Reviewed-by: DraVee <chimera@dravee.dev> Reviewed-by: Lizzie <lizzie@eden-emu.dev> Co-authored-by: xbzk <xbzk@eden-emu.dev> Co-committed-by: xbzk <xbzk@eden-emu.dev>pull/3719/head
committed by
crueter
No known key found for this signature in database
GPG Key ID: 425ACD2D4830EBC6
24 changed files with 1063 additions and 475 deletions
-
5src/android/app/src/main/AndroidManifest.xml
-
14src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/AppletAdapter.kt
-
12src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsActivity.kt
-
152src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsSubscreenActivity.kt
-
12src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/AboutFragment.kt
-
3src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/AddonsFragment.kt
-
5src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/AppletLauncherFragment.kt
-
3src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/DriverFetcherFragment.kt
-
12src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/DriverManagerFragment.kt
-
71src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/GameFoldersFragment.kt
-
5src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/GameInfoFragment.kt
-
28src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/GamePropertiesFragment.kt
-
50src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/HomeSettingsFragment.kt
-
163src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/InstallableFragment.kt
-
5src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/LicensesFragment.kt
-
2src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/ProfileManagerFragment.kt
-
304src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt
-
327src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/InstallableActions.kt
-
78src/android/app/src/main/res/layout-w600dp/fragment_about.xml
-
88src/android/app/src/main/res/layout/fragment_about.xml
-
6src/android/app/src/main/res/navigation/emulation_navigation.xml
-
52src/android/app/src/main/res/navigation/home_navigation.xml
-
139src/android/app/src/main/res/navigation/settings_subscreen_navigation.xml
-
2src/android/app/src/main/res/values/strings.xml
@ -0,0 +1,152 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project |
|||
// SPDX-License-Identifier: GPL-3.0-or-later |
|||
|
|||
package org.yuzu.yuzu_emu.features.settings.ui |
|||
|
|||
import android.content.Context |
|||
import android.os.Bundle |
|||
import android.view.View |
|||
import android.view.ViewGroup.MarginLayoutParams |
|||
import androidx.activity.OnBackPressedCallback |
|||
import androidx.appcompat.app.AppCompatActivity |
|||
import androidx.core.os.bundleOf |
|||
import androidx.core.view.ViewCompat |
|||
import androidx.core.view.WindowCompat |
|||
import androidx.core.view.WindowInsetsCompat |
|||
import androidx.navigation.fragment.NavHostFragment |
|||
import androidx.navigation.navArgs |
|||
import com.google.android.material.color.MaterialColors |
|||
import org.yuzu.yuzu_emu.R |
|||
import org.yuzu.yuzu_emu.YuzuApplication |
|||
import org.yuzu.yuzu_emu.databinding.ActivitySettingsBinding |
|||
import org.yuzu.yuzu_emu.utils.DirectoryInitialization |
|||
import org.yuzu.yuzu_emu.utils.InsetsHelper |
|||
import org.yuzu.yuzu_emu.utils.ThemeHelper |
|||
|
|||
enum class SettingsSubscreen { |
|||
PROFILE_MANAGER, |
|||
DRIVER_MANAGER, |
|||
DRIVER_FETCHER, |
|||
FREEDRENO_SETTINGS, |
|||
APPLET_LAUNCHER, |
|||
INSTALLABLE, |
|||
GAME_FOLDERS, |
|||
ABOUT, |
|||
LICENSES, |
|||
GAME_INFO, |
|||
ADDONS, |
|||
} |
|||
|
|||
class SettingsSubscreenActivity : AppCompatActivity() { |
|||
private lateinit var binding: ActivitySettingsBinding |
|||
|
|||
private val args by navArgs<SettingsSubscreenActivityArgs>() |
|||
|
|||
override fun attachBaseContext(base: Context) { |
|||
super.attachBaseContext(YuzuApplication.applyLanguage(base)) |
|||
} |
|||
|
|||
override fun onCreate(savedInstanceState: Bundle?) { |
|||
ThemeHelper.setTheme(this) |
|||
|
|||
super.onCreate(savedInstanceState) |
|||
|
|||
binding = ActivitySettingsBinding.inflate(layoutInflater) |
|||
setContentView(binding.root) |
|||
|
|||
val navHostFragment = |
|||
supportFragmentManager.findFragmentById(R.id.fragment_container) as NavHostFragment |
|||
if (savedInstanceState == null) { |
|||
val navController = navHostFragment.navController |
|||
val navGraph = navController.navInflater.inflate( |
|||
R.navigation.settings_subscreen_navigation |
|||
) |
|||
navGraph.setStartDestination(resolveStartDestination()) |
|||
navController.setGraph(navGraph, createStartDestinationArgs()) |
|||
} |
|||
|
|||
WindowCompat.setDecorFitsSystemWindows(window, false) |
|||
|
|||
if (InsetsHelper.getSystemGestureType(applicationContext) != |
|||
InsetsHelper.GESTURE_NAVIGATION |
|||
) { |
|||
binding.navigationBarShade.setBackgroundColor( |
|||
ThemeHelper.getColorWithOpacity( |
|||
MaterialColors.getColor( |
|||
binding.navigationBarShade, |
|||
com.google.android.material.R.attr.colorSurface |
|||
), |
|||
ThemeHelper.SYSTEM_BAR_ALPHA |
|||
) |
|||
) |
|||
} |
|||
|
|||
onBackPressedDispatcher.addCallback( |
|||
this, |
|||
object : OnBackPressedCallback(true) { |
|||
override fun handleOnBackPressed() = navigateBack() |
|||
} |
|||
) |
|||
|
|||
setInsets() |
|||
} |
|||
|
|||
override fun onStart() { |
|||
super.onStart() |
|||
if (!DirectoryInitialization.areDirectoriesReady) { |
|||
DirectoryInitialization.start() |
|||
} |
|||
} |
|||
|
|||
fun navigateBack() { |
|||
val navHostFragment = |
|||
supportFragmentManager.findFragmentById(R.id.fragment_container) as NavHostFragment |
|||
if (!navHostFragment.navController.popBackStack()) { |
|||
finish() |
|||
} |
|||
} |
|||
|
|||
private fun resolveStartDestination(): Int = |
|||
when (args.destination) { |
|||
SettingsSubscreen.PROFILE_MANAGER -> R.id.profileManagerFragment |
|||
SettingsSubscreen.DRIVER_MANAGER -> R.id.driverManagerFragment |
|||
SettingsSubscreen.DRIVER_FETCHER -> R.id.driverFetcherFragment |
|||
SettingsSubscreen.FREEDRENO_SETTINGS -> R.id.freedrenoSettingsFragment |
|||
SettingsSubscreen.APPLET_LAUNCHER -> R.id.appletLauncherFragment |
|||
SettingsSubscreen.INSTALLABLE -> R.id.installableFragment |
|||
SettingsSubscreen.GAME_FOLDERS -> R.id.gameFoldersFragment |
|||
SettingsSubscreen.ABOUT -> R.id.aboutFragment |
|||
SettingsSubscreen.LICENSES -> R.id.licensesFragment |
|||
SettingsSubscreen.GAME_INFO -> R.id.gameInfoFragment |
|||
SettingsSubscreen.ADDONS -> R.id.addonsFragment |
|||
} |
|||
|
|||
private fun createStartDestinationArgs(): Bundle = |
|||
when (args.destination) { |
|||
SettingsSubscreen.DRIVER_MANAGER, |
|||
SettingsSubscreen.FREEDRENO_SETTINGS -> bundleOf("game" to args.game) |
|||
|
|||
SettingsSubscreen.GAME_INFO, |
|||
SettingsSubscreen.ADDONS -> bundleOf( |
|||
"game" to requireNotNull(args.game) { |
|||
"Game is required for ${args.destination}" |
|||
} |
|||
) |
|||
|
|||
else -> Bundle() |
|||
} |
|||
|
|||
private fun setInsets() { |
|||
ViewCompat.setOnApplyWindowInsetsListener( |
|||
binding.navigationBarShade |
|||
) { _: View, windowInsets: WindowInsetsCompat -> |
|||
val barInsets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) |
|||
|
|||
val mlpNavShade = binding.navigationBarShade.layoutParams as MarginLayoutParams |
|||
mlpNavShade.height = barInsets.bottom |
|||
binding.navigationBarShade.layoutParams = mlpNavShade |
|||
|
|||
windowInsets |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,327 @@ |
|||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project |
|||
// SPDX-License-Identifier: GPL-3.0-or-later |
|||
|
|||
package org.yuzu.yuzu_emu.utils |
|||
|
|||
import android.content.Intent |
|||
import android.net.Uri |
|||
import android.widget.Toast |
|||
import androidx.fragment.app.FragmentActivity |
|||
import androidx.fragment.app.FragmentManager |
|||
import org.yuzu.yuzu_emu.NativeLibrary |
|||
import org.yuzu.yuzu_emu.R |
|||
import org.yuzu.yuzu_emu.fragments.MessageDialogFragment |
|||
import org.yuzu.yuzu_emu.fragments.ProgressDialogFragment |
|||
import org.yuzu.yuzu_emu.model.AddonViewModel |
|||
import org.yuzu.yuzu_emu.model.DriverViewModel |
|||
import org.yuzu.yuzu_emu.model.GamesViewModel |
|||
import org.yuzu.yuzu_emu.model.HomeViewModel |
|||
import org.yuzu.yuzu_emu.model.InstallResult |
|||
import org.yuzu.yuzu_emu.model.TaskState |
|||
import java.io.BufferedInputStream |
|||
import java.io.BufferedOutputStream |
|||
import java.io.File |
|||
import java.io.FilenameFilter |
|||
import java.util.zip.ZipEntry |
|||
import java.util.zip.ZipInputStream |
|||
|
|||
object InstallableActions { |
|||
fun processKey( |
|||
activity: FragmentActivity, |
|||
fragmentManager: FragmentManager, |
|||
gamesViewModel: GamesViewModel, |
|||
result: Uri, |
|||
extension: String = "keys" |
|||
) { |
|||
activity.contentResolver.takePersistableUriPermission( |
|||
result, |
|||
Intent.FLAG_GRANT_READ_URI_PERMISSION |
|||
) |
|||
|
|||
val resultCode = NativeLibrary.installKeys(result.toString(), extension) |
|||
if (resultCode == 0) { |
|||
Toast.makeText( |
|||
activity.applicationContext, |
|||
R.string.keys_install_success, |
|||
Toast.LENGTH_SHORT |
|||
).show() |
|||
gamesViewModel.reloadGames(true) |
|||
return |
|||
} |
|||
|
|||
val resultString = activity.resources.getStringArray(R.array.installKeysResults)[resultCode] |
|||
MessageDialogFragment.newInstance( |
|||
titleId = R.string.keys_failed, |
|||
descriptionString = resultString, |
|||
helpLinkId = R.string.keys_missing_help |
|||
).show(fragmentManager, MessageDialogFragment.TAG) |
|||
} |
|||
|
|||
fun processFirmware( |
|||
activity: FragmentActivity, |
|||
fragmentManager: FragmentManager, |
|||
homeViewModel: HomeViewModel, |
|||
result: Uri, |
|||
onComplete: (() -> Unit)? = null |
|||
) { |
|||
val filterNCA = FilenameFilter { _, dirName -> dirName.endsWith(".nca") } |
|||
val firmwarePath = File(NativeConfig.getNandDir() + "/system/Contents/registered/") |
|||
val cacheFirmwareDir = File("${activity.cacheDir.path}/registered/") |
|||
|
|||
ProgressDialogFragment.newInstance( |
|||
activity, |
|||
R.string.firmware_installing |
|||
) { progressCallback, _ -> |
|||
var messageToShow: Any |
|||
try { |
|||
FileUtil.unzipToInternalStorage( |
|||
result.toString(), |
|||
cacheFirmwareDir, |
|||
progressCallback |
|||
) |
|||
val unfilteredNumOfFiles = cacheFirmwareDir.list()?.size ?: -1 |
|||
val filteredNumOfFiles = cacheFirmwareDir.list(filterNCA)?.size ?: -2 |
|||
messageToShow = if (unfilteredNumOfFiles != filteredNumOfFiles) { |
|||
MessageDialogFragment.newInstance( |
|||
activity, |
|||
titleId = R.string.firmware_installed_failure, |
|||
descriptionId = R.string.firmware_installed_failure_description |
|||
) |
|||
} else { |
|||
firmwarePath.deleteRecursively() |
|||
cacheFirmwareDir.copyRecursively(firmwarePath, overwrite = true) |
|||
NativeLibrary.initializeSystem(true) |
|||
homeViewModel.setCheckKeys(true) |
|||
activity.getString(R.string.save_file_imported_success) |
|||
} |
|||
} catch (_: Exception) { |
|||
messageToShow = activity.getString(R.string.fatal_error) |
|||
} finally { |
|||
cacheFirmwareDir.deleteRecursively() |
|||
} |
|||
messageToShow |
|||
}.apply { |
|||
onDialogComplete = onComplete |
|||
}.show(fragmentManager, ProgressDialogFragment.TAG) |
|||
} |
|||
|
|||
fun uninstallFirmware( |
|||
activity: FragmentActivity, |
|||
fragmentManager: FragmentManager, |
|||
homeViewModel: HomeViewModel |
|||
) { |
|||
val firmwarePath = File(NativeConfig.getNandDir() + "/system/Contents/registered/") |
|||
ProgressDialogFragment.newInstance( |
|||
activity, |
|||
R.string.firmware_uninstalling |
|||
) { _, _ -> |
|||
val messageToShow: Any = try { |
|||
if (firmwarePath.exists()) { |
|||
firmwarePath.deleteRecursively() |
|||
NativeLibrary.initializeSystem(true) |
|||
homeViewModel.setCheckKeys(true) |
|||
activity.getString(R.string.firmware_uninstalled_success) |
|||
} else { |
|||
activity.getString(R.string.firmware_uninstalled_failure) |
|||
} |
|||
} catch (_: Exception) { |
|||
activity.getString(R.string.fatal_error) |
|||
} |
|||
messageToShow |
|||
}.show(fragmentManager, ProgressDialogFragment.TAG) |
|||
} |
|||
|
|||
fun installContent( |
|||
activity: FragmentActivity, |
|||
fragmentManager: FragmentManager, |
|||
addonViewModel: AddonViewModel, |
|||
documents: List<Uri> |
|||
) { |
|||
ProgressDialogFragment.newInstance( |
|||
activity, |
|||
R.string.installing_game_content |
|||
) { progressCallback, messageCallback -> |
|||
var installSuccess = 0 |
|||
var installOverwrite = 0 |
|||
var errorBaseGame = 0 |
|||
var error = 0 |
|||
documents.forEach { |
|||
messageCallback.invoke(FileUtil.getFilename(it)) |
|||
when ( |
|||
InstallResult.from( |
|||
NativeLibrary.installFileToNand( |
|||
it.toString(), |
|||
progressCallback |
|||
) |
|||
) |
|||
) { |
|||
InstallResult.Success -> installSuccess += 1 |
|||
InstallResult.Overwrite -> installOverwrite += 1 |
|||
InstallResult.BaseInstallAttempted -> errorBaseGame += 1 |
|||
InstallResult.Failure -> error += 1 |
|||
} |
|||
} |
|||
|
|||
addonViewModel.refreshAddons(force = true) |
|||
|
|||
val separator = System.lineSeparator() ?: "\n" |
|||
val installResult = StringBuilder() |
|||
if (installSuccess > 0) { |
|||
installResult.append( |
|||
activity.getString( |
|||
R.string.install_game_content_success_install, |
|||
installSuccess |
|||
) |
|||
) |
|||
installResult.append(separator) |
|||
} |
|||
if (installOverwrite > 0) { |
|||
installResult.append( |
|||
activity.getString( |
|||
R.string.install_game_content_success_overwrite, |
|||
installOverwrite |
|||
) |
|||
) |
|||
installResult.append(separator) |
|||
} |
|||
val errorTotal = errorBaseGame + error |
|||
if (errorTotal > 0) { |
|||
installResult.append(separator) |
|||
installResult.append( |
|||
activity.getString( |
|||
R.string.install_game_content_failed_count, |
|||
errorTotal |
|||
) |
|||
) |
|||
installResult.append(separator) |
|||
if (errorBaseGame > 0) { |
|||
installResult.append(separator) |
|||
installResult.append(activity.getString(R.string.install_game_content_failure_base)) |
|||
installResult.append(separator) |
|||
} |
|||
if (error > 0) { |
|||
installResult.append( |
|||
activity.getString(R.string.install_game_content_failure_description) |
|||
) |
|||
installResult.append(separator) |
|||
} |
|||
return@newInstance MessageDialogFragment.newInstance( |
|||
activity, |
|||
titleId = R.string.install_game_content_failure, |
|||
descriptionString = installResult.toString().trim(), |
|||
helpLinkId = R.string.install_game_content_help_link |
|||
) |
|||
} else { |
|||
return@newInstance MessageDialogFragment.newInstance( |
|||
activity, |
|||
titleId = R.string.install_game_content_success, |
|||
descriptionString = installResult.toString().trim() |
|||
) |
|||
} |
|||
}.show(fragmentManager, ProgressDialogFragment.TAG) |
|||
} |
|||
|
|||
fun exportUserData( |
|||
activity: FragmentActivity, |
|||
fragmentManager: FragmentManager, |
|||
result: Uri |
|||
) { |
|||
val userDirectory = DirectoryInitialization.userDirectory |
|||
if (userDirectory == null) { |
|||
Toast.makeText( |
|||
activity.applicationContext, |
|||
R.string.fatal_error, |
|||
Toast.LENGTH_SHORT |
|||
).show() |
|||
return |
|||
} |
|||
|
|||
ProgressDialogFragment.newInstance( |
|||
activity, |
|||
R.string.exporting_user_data, |
|||
true |
|||
) { progressCallback, _ -> |
|||
val zipResult = FileUtil.zipFromInternalStorage( |
|||
File(userDirectory), |
|||
userDirectory, |
|||
BufferedOutputStream(activity.contentResolver.openOutputStream(result)), |
|||
progressCallback, |
|||
compression = false |
|||
) |
|||
return@newInstance when (zipResult) { |
|||
TaskState.Completed -> activity.getString(R.string.user_data_export_success) |
|||
TaskState.Failed -> R.string.export_failed |
|||
TaskState.Cancelled -> R.string.user_data_export_cancelled |
|||
} |
|||
}.show(fragmentManager, ProgressDialogFragment.TAG) |
|||
} |
|||
|
|||
fun importUserData( |
|||
activity: FragmentActivity, |
|||
fragmentManager: FragmentManager, |
|||
gamesViewModel: GamesViewModel, |
|||
driverViewModel: DriverViewModel, |
|||
result: Uri |
|||
) { |
|||
val userDirectory = DirectoryInitialization.userDirectory |
|||
if (userDirectory == null) { |
|||
Toast.makeText( |
|||
activity.applicationContext, |
|||
R.string.fatal_error, |
|||
Toast.LENGTH_SHORT |
|||
).show() |
|||
return |
|||
} |
|||
|
|||
ProgressDialogFragment.newInstance( |
|||
activity, |
|||
R.string.importing_user_data |
|||
) { progressCallback, _ -> |
|||
val checkStream = ZipInputStream( |
|||
BufferedInputStream(activity.contentResolver.openInputStream(result)) |
|||
) |
|||
var isYuzuBackup = false |
|||
checkStream.use { stream -> |
|||
var ze: ZipEntry? = null |
|||
while (stream.nextEntry?.also { ze = it } != null) { |
|||
val itemName = ze!!.name.trim() |
|||
if (itemName == "/config/config.ini" || itemName == "config/config.ini") { |
|||
isYuzuBackup = true |
|||
return@use |
|||
} |
|||
} |
|||
} |
|||
if (!isYuzuBackup) { |
|||
return@newInstance MessageDialogFragment.newInstance( |
|||
activity, |
|||
titleId = R.string.invalid_yuzu_backup, |
|||
descriptionId = R.string.user_data_import_failed_description |
|||
) |
|||
} |
|||
|
|||
NativeConfig.unloadGlobalConfig() |
|||
File(userDirectory).deleteRecursively() |
|||
|
|||
try { |
|||
FileUtil.unzipToInternalStorage( |
|||
result.toString(), |
|||
File(userDirectory), |
|||
progressCallback |
|||
) |
|||
} catch (_: Exception) { |
|||
return@newInstance MessageDialogFragment.newInstance( |
|||
activity, |
|||
titleId = R.string.import_failed, |
|||
descriptionId = R.string.user_data_import_failed_description |
|||
) |
|||
} |
|||
|
|||
NativeLibrary.initializeSystem(true) |
|||
NativeConfig.initializeGlobalConfig() |
|||
gamesViewModel.reloadGames(false) |
|||
driverViewModel.reloadDriverData() |
|||
|
|||
return@newInstance activity.getString(R.string.user_data_import_success) |
|||
}.show(fragmentManager, ProgressDialogFragment.TAG) |
|||
} |
|||
} |
|||
@ -0,0 +1,139 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<navigation xmlns:android="http://schemas.android.com/apk/res/android" |
|||
xmlns:app="http://schemas.android.com/apk/res-auto" |
|||
xmlns:tools="http://schemas.android.com/tools" |
|||
android:id="@+id/settings_subscreen_navigation" |
|||
app:startDestination="@id/profileManagerFragment"> |
|||
|
|||
<fragment |
|||
android:id="@+id/profileManagerFragment" |
|||
android:name="org.yuzu.yuzu_emu.fragments.ProfileManagerFragment" |
|||
android:label="ProfileManagerFragment"> |
|||
<action |
|||
android:id="@+id/action_profileManagerFragment_to_newUserDialog" |
|||
app:destination="@id/newUserDialogFragment" /> |
|||
</fragment> |
|||
|
|||
<fragment |
|||
android:id="@+id/newUserDialogFragment" |
|||
android:name="org.yuzu.yuzu_emu.fragments.EditUserDialogFragment" |
|||
android:label="NewUserDialogFragment" /> |
|||
|
|||
<fragment |
|||
android:id="@+id/driverManagerFragment" |
|||
android:name="org.yuzu.yuzu_emu.fragments.DriverManagerFragment" |
|||
android:label="DriverManagerFragment"> |
|||
<argument |
|||
android:name="game" |
|||
app:argType="org.yuzu.yuzu_emu.model.Game" |
|||
app:nullable="true" |
|||
android:defaultValue="@null" /> |
|||
</fragment> |
|||
|
|||
<fragment |
|||
android:id="@+id/driverFetcherFragment" |
|||
android:name="org.yuzu.yuzu_emu.fragments.DriverFetcherFragment" |
|||
android:label="fragment_driver_fetcher" |
|||
tools:layout="@layout/fragment_driver_fetcher" /> |
|||
|
|||
<fragment |
|||
android:id="@+id/freedrenoSettingsFragment" |
|||
android:name="org.yuzu.yuzu_emu.fragments.FreedrenoSettingsFragment" |
|||
android:label="@string/freedreno_settings_title"> |
|||
<argument |
|||
android:name="game" |
|||
app:argType="org.yuzu.yuzu_emu.model.Game" |
|||
app:nullable="true" |
|||
android:defaultValue="@null" /> |
|||
</fragment> |
|||
|
|||
<fragment |
|||
android:id="@+id/appletLauncherFragment" |
|||
android:name="org.yuzu.yuzu_emu.fragments.AppletLauncherFragment" |
|||
android:label="AppletLauncherFragment"> |
|||
<action |
|||
android:id="@+id/action_appletLauncherFragment_to_cabinetLauncherDialogFragment" |
|||
app:destination="@id/cabinetLauncherDialogFragment" /> |
|||
</fragment> |
|||
|
|||
<dialog |
|||
android:id="@+id/cabinetLauncherDialogFragment" |
|||
android:name="org.yuzu.yuzu_emu.fragments.CabinetLauncherDialogFragment" |
|||
android:label="CabinetLauncherDialogFragment" /> |
|||
|
|||
<fragment |
|||
android:id="@+id/aboutFragment" |
|||
android:name="org.yuzu.yuzu_emu.fragments.AboutFragment" |
|||
android:label="AboutFragment" /> |
|||
|
|||
<fragment |
|||
android:id="@+id/licensesFragment" |
|||
android:name="org.yuzu.yuzu_emu.fragments.LicensesFragment" |
|||
android:label="LicensesFragment" /> |
|||
|
|||
<fragment |
|||
android:id="@+id/gameInfoFragment" |
|||
android:name="org.yuzu.yuzu_emu.fragments.GameInfoFragment" |
|||
android:label="GameInfoFragment"> |
|||
<argument |
|||
android:name="game" |
|||
app:argType="org.yuzu.yuzu_emu.model.Game" /> |
|||
</fragment> |
|||
|
|||
<fragment |
|||
android:id="@+id/addonsFragment" |
|||
android:name="org.yuzu.yuzu_emu.fragments.AddonsFragment" |
|||
android:label="AddonsFragment"> |
|||
<argument |
|||
android:name="game" |
|||
app:argType="org.yuzu.yuzu_emu.model.Game" /> |
|||
</fragment> |
|||
|
|||
<fragment |
|||
android:id="@+id/installableFragment" |
|||
android:name="org.yuzu.yuzu_emu.fragments.InstallableFragment" |
|||
android:label="InstallableFragment" /> |
|||
|
|||
<fragment |
|||
android:id="@+id/gameFoldersFragment" |
|||
android:name="org.yuzu.yuzu_emu.fragments.GameFoldersFragment" |
|||
android:label="GameFoldersFragment" /> |
|||
|
|||
<activity |
|||
android:id="@+id/emulationActivity" |
|||
android:name="org.yuzu.yuzu_emu.activities.EmulationActivity" |
|||
android:label="EmulationActivity"> |
|||
<argument |
|||
android:name="game" |
|||
app:argType="org.yuzu.yuzu_emu.model.Game" |
|||
app:nullable="true" |
|||
android:defaultValue="@null" /> |
|||
<argument |
|||
android:name="custom" |
|||
app:argType="boolean" |
|||
android:defaultValue="false" /> |
|||
</activity> |
|||
|
|||
<action |
|||
android:id="@+id/action_global_emulationActivity" |
|||
app:destination="@id/emulationActivity" |
|||
app:launchSingleTop="true" /> |
|||
|
|||
<activity |
|||
android:id="@+id/settingsSubscreenActivity" |
|||
android:name="org.yuzu.yuzu_emu.features.settings.ui.SettingsSubscreenActivity" |
|||
android:label="SettingsSubscreenActivity"> |
|||
<argument |
|||
android:name="destination" |
|||
app:argType="org.yuzu.yuzu_emu.features.settings.ui.SettingsSubscreen" /> |
|||
<argument |
|||
android:name="game" |
|||
app:argType="org.yuzu.yuzu_emu.model.Game" |
|||
app:nullable="true" |
|||
android:defaultValue="@null" /> |
|||
</activity> |
|||
|
|||
<action |
|||
android:id="@+id/action_global_settingsSubscreenActivity" |
|||
app:destination="@id/settingsSubscreenActivity" /> |
|||
</navigation> |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue