summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCharles Lombardo <clombardo169@gmail.com>2023-08-23 01:46:07 +0200
committerCharles Lombardo <clombardo169@gmail.com>2023-08-30 01:42:41 +0200
commit95a939a49f798c2b4b04d6f8eae33c1d093d43b4 (patch)
treef06b71c8330d743f9951da78547b9448417a9048
parentandroid: Trim settings enums and items (diff)
downloadyuzu-95a939a49f798c2b4b04d6f8eae33c1d093d43b4.tar
yuzu-95a939a49f798c2b4b04d6f8eae33c1d093d43b4.tar.gz
yuzu-95a939a49f798c2b4b04d6f8eae33c1d093d43b4.tar.bz2
yuzu-95a939a49f798c2b4b04d6f8eae33c1d093d43b4.tar.lz
yuzu-95a939a49f798c2b4b04d6f8eae33c1d093d43b4.tar.xz
yuzu-95a939a49f798c2b4b04d6f8eae33c1d093d43b4.tar.zst
yuzu-95a939a49f798c2b4b04d6f8eae33c1d093d43b4.zip
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/YuzuApplication.kt2
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt4
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsActivity.kt176
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsActivityPresenter.kt81
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsActivityView.kt38
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsAdapter.kt47
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragment.kt112
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt68
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentView.kt42
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt11
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/HomeSettingsFragment.kt19
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/model/SettingsViewModel.kt47
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt14
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/DirectoryInitialization.kt10
-rw-r--r--src/android/app/src/main/res/anim-ldrtl/anim_pop_settings_fragment_out.xml16
-rw-r--r--src/android/app/src/main/res/anim-ldrtl/anim_settings_fragment_in.xml16
-rw-r--r--src/android/app/src/main/res/anim/anim_pop_settings_fragment_out.xml16
-rw-r--r--src/android/app/src/main/res/anim/anim_settings_fragment_in.xml16
-rw-r--r--src/android/app/src/main/res/anim/anim_settings_fragment_out.xml10
-rw-r--r--src/android/app/src/main/res/animator/menu_slide_in_from_start.xml20
-rw-r--r--src/android/app/src/main/res/animator/menu_slide_out_to_start.xml21
-rw-r--r--src/android/app/src/main/res/layout/activity_settings.xml52
-rw-r--r--src/android/app/src/main/res/layout/fragment_settings.xml39
-rw-r--r--src/android/app/src/main/res/menu/menu_settings.xml2
-rw-r--r--src/android/app/src/main/res/navigation/emulation_navigation.xml17
-rw-r--r--src/android/app/src/main/res/navigation/home_navigation.xml17
-rw-r--r--src/android/app/src/main/res/navigation/settings_navigation.xml24
-rw-r--r--src/android/app/src/main/res/values/strings.xml1
28 files changed, 371 insertions, 567 deletions
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/YuzuApplication.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/YuzuApplication.kt
index 04ab6a220..9561748cb 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/YuzuApplication.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/YuzuApplication.kt
@@ -46,7 +46,7 @@ class YuzuApplication : Application() {
super.onCreate()
application = this
documentsTree = DocumentsTree()
- DirectoryInitialization.start(applicationContext)
+ DirectoryInitialization.start()
GpuDriverHelper.initializeDriverParameters(applicationContext)
NativeLibrary.logDeviceInfo()
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt
index 6f52a7a8d..dbd602a1d 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt
@@ -85,9 +85,7 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
val navHostFragment =
supportFragmentManager.findFragmentById(R.id.fragment_container) as NavHostFragment
- val navController = navHostFragment.navController
- navController
- .setGraph(R.navigation.emulation_navigation, intent.extras)
+ navHostFragment.navController.setGraph(R.navigation.emulation_navigation, intent.extras)
isActivityRecreated = savedInstanceState != null
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsActivity.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsActivity.kt
index 733a53c8c..7fd83f5f7 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsActivity.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsActivity.kt
@@ -3,10 +3,7 @@
package org.yuzu.yuzu_emu.features.settings.ui
-import android.content.Context
-import android.content.Intent
import android.os.Bundle
-import android.view.Menu
import android.view.View
import android.view.ViewGroup.MarginLayoutParams
import android.widget.Toast
@@ -16,20 +13,26 @@ import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat
-import androidx.core.view.updatePadding
+import androidx.navigation.fragment.NavHostFragment
+import androidx.navigation.navArgs
import com.google.android.material.color.MaterialColors
+import org.yuzu.yuzu_emu.NativeLibrary
import java.io.IOException
import org.yuzu.yuzu_emu.R
import org.yuzu.yuzu_emu.databinding.ActivitySettingsBinding
import org.yuzu.yuzu_emu.features.settings.model.Settings
import org.yuzu.yuzu_emu.features.settings.utils.SettingsFile
+import org.yuzu.yuzu_emu.fragments.ResetSettingsDialogFragment
+import org.yuzu.yuzu_emu.model.SettingsViewModel
import org.yuzu.yuzu_emu.utils.*
-class SettingsActivity : AppCompatActivity(), SettingsActivityView {
- private val presenter = SettingsActivityPresenter(this)
-
+class SettingsActivity : AppCompatActivity() {
private lateinit var binding: ActivitySettingsBinding
+ private val args by navArgs<SettingsActivityArgs>()
+
+ private val settingsViewModel: SettingsViewModel by viewModels()
+
override fun onCreate(savedInstanceState: Bundle?) {
ThemeHelper.setTheme(this)
@@ -38,16 +41,17 @@ class SettingsActivity : AppCompatActivity(), SettingsActivityView {
binding = ActivitySettingsBinding.inflate(layoutInflater)
setContentView(binding.root)
- WindowCompat.setDecorFitsSystemWindows(window, false)
+ settingsViewModel.game = args.game
- val launcher = intent
- val gameID = launcher.getStringExtra(ARG_GAME_ID)
- val menuTag = launcher.getStringExtra(ARG_MENU_TAG)
- presenter.onCreate(savedInstanceState, menuTag!!, gameID!!)
+ val navHostFragment =
+ supportFragmentManager.findFragmentById(R.id.fragment_container) as NavHostFragment
+ navHostFragment.navController.setGraph(R.navigation.settings_navigation, intent.extras)
- // Show "Back" button in the action bar for navigation
- setSupportActionBar(binding.toolbarSettings)
- supportActionBar!!.setDisplayHomeAsUpEnabled(true)
+ WindowCompat.setDecorFitsSystemWindows(window, false)
+
+ if (savedInstanceState != null) {
+ settingsViewModel.shouldSave = savedInstanceState.getBoolean(KEY_SHOULD_SAVE)
+ }
if (InsetsHelper.getSystemGestureType(applicationContext) !=
InsetsHelper.GESTURE_NAVIGATION
@@ -63,6 +67,28 @@ class SettingsActivity : AppCompatActivity(), SettingsActivityView {
)
}
+ settingsViewModel.shouldRecreate.observe(this) {
+ if (it) {
+ settingsViewModel.setShouldRecreate(false)
+ recreate()
+ }
+ }
+ settingsViewModel.shouldNavigateBack.observe(this) {
+ if (it) {
+ settingsViewModel.setShouldNavigateBack(false)
+ navigateBack()
+ }
+ }
+ settingsViewModel.shouldShowResetSettingsDialog.observe(this) {
+ if (it) {
+ settingsViewModel.setShouldShowResetSettingsDialog(false)
+ ResetSettingsDialogFragment().show(
+ supportFragmentManager,
+ ResetSettingsDialogFragment.TAG
+ )
+ }
+ }
+
onBackPressedDispatcher.addCallback(
this,
object : OnBackPressedCallback(true) {
@@ -73,34 +99,28 @@ class SettingsActivity : AppCompatActivity(), SettingsActivityView {
setInsets()
}
- override fun onSupportNavigateUp(): Boolean {
- navigateBack()
- return true
- }
-
- private fun navigateBack() {
- if (supportFragmentManager.backStackEntryCount > 0) {
- supportFragmentManager.popBackStack()
+ fun navigateBack() {
+ val navHostFragment =
+ supportFragmentManager.findFragmentById(R.id.fragment_container) as NavHostFragment
+ if (navHostFragment.childFragmentManager.backStackEntryCount > 0) {
+ navHostFragment.navController.popBackStack()
} else {
finish()
}
}
- override fun onCreateOptionsMenu(menu: Menu): Boolean {
- val inflater = menuInflater
- inflater.inflate(R.menu.menu_settings, menu)
- return true
- }
-
override fun onSaveInstanceState(outState: Bundle) {
// Critical: If super method is not called, rotations will be busted.
super.onSaveInstanceState(outState)
- presenter.saveState(outState)
+ outState.putBoolean(KEY_SHOULD_SAVE, settingsViewModel.shouldSave)
}
override fun onStart() {
super.onStart()
- presenter.onStart()
+ // TODO: Load custom settings contextually
+ if (!DirectoryInitialization.areDirectoriesReady) {
+ DirectoryInitialization.start()
+ }
}
/**
@@ -110,65 +130,21 @@ class SettingsActivity : AppCompatActivity(), SettingsActivityView {
*/
override fun onStop() {
super.onStop()
- presenter.onStop(isFinishing)
- }
-
- override fun showSettingsFragment(menuTag: String, addToStack: Boolean, gameId: String) {
- if (!addToStack && settingsFragment != null) {
- return
- }
-
- val transaction = supportFragmentManager.beginTransaction()
- if (addToStack) {
- if (areSystemAnimationsEnabled()) {
- transaction.setCustomAnimations(
- R.anim.anim_settings_fragment_in,
- R.anim.anim_settings_fragment_out,
- 0,
- R.anim.anim_pop_settings_fragment_out
- )
- }
- transaction.addToBackStack(null)
+ if (isFinishing && settingsViewModel.shouldSave) {
+ Log.debug("[SettingsActivity] Settings activity stopping. Saving settings to INI...")
+ Settings.saveSettings()
+ NativeLibrary.reloadSettings()
}
- transaction.replace(
- R.id.frame_content,
- SettingsFragment.newInstance(menuTag, gameId),
- FRAGMENT_TAG
- )
- transaction.commit()
- }
-
- private fun areSystemAnimationsEnabled(): Boolean {
- val duration = android.provider.Settings.Global.getFloat(
- contentResolver,
- android.provider.Settings.Global.ANIMATOR_DURATION_SCALE,
- 1f
- )
- val transition = android.provider.Settings.Global.getFloat(
- contentResolver,
- android.provider.Settings.Global.TRANSITION_ANIMATION_SCALE,
- 1f
- )
- return duration != 0f && transition != 0f
}
- override fun onSettingsFileLoaded() {
- val fragment: SettingsFragmentView? = settingsFragment
- fragment?.loadSettingsList()
- }
-
- override fun onSettingsFileNotFound() {
- val fragment: SettingsFragmentView? = settingsFragment
- fragment?.loadSettingsList()
- }
-
- override fun onSettingChanged() {
- presenter.onSettingChanged()
+ override fun onDestroy() {
+ settingsViewModel.clear()
+ super.onDestroy()
}
fun onSettingsReset() {
// Prevents saving to a non-existent settings file
- presenter.onSettingsReset()
+ settingsViewModel.shouldSave = false
// Delete settings file because the user may have changed values that do not exist in the UI
val settingsFile = SettingsFile.getSettingsFile(SettingsFile.FILE_NAME_CONFIG)
@@ -185,47 +161,21 @@ class SettingsActivity : AppCompatActivity(), SettingsActivityView {
finish()
}
- fun setToolbarTitle(title: String) {
- binding.toolbarSettingsLayout.title = title
- }
-
- private val settingsFragment: SettingsFragment?
- get() = supportFragmentManager.findFragmentByTag(FRAGMENT_TAG) as SettingsFragment?
-
private fun setInsets() {
ViewCompat.setOnApplyWindowInsetsListener(
- binding.frameContent
+ binding.navigationBarShade
) { view: View, windowInsets: WindowInsetsCompat ->
val barInsets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
- val cutoutInsets = windowInsets.getInsets(WindowInsetsCompat.Type.displayCutout())
- view.updatePadding(
- left = barInsets.left + cutoutInsets.left,
- right = barInsets.right + cutoutInsets.right
- )
- val mlpAppBar = binding.appbarSettings.layoutParams as MarginLayoutParams
- mlpAppBar.leftMargin = barInsets.left + cutoutInsets.left
- mlpAppBar.rightMargin = barInsets.right + cutoutInsets.right
- binding.appbarSettings.layoutParams = mlpAppBar
-
- val mlpShade = binding.navigationBarShade.layoutParams as MarginLayoutParams
+ val mlpShade = view.layoutParams as MarginLayoutParams
mlpShade.height = barInsets.bottom
- binding.navigationBarShade.layoutParams = mlpShade
+ view.layoutParams = mlpShade
windowInsets
}
}
companion object {
- private const val ARG_MENU_TAG = "menu_tag"
- private const val ARG_GAME_ID = "game_id"
- private const val FRAGMENT_TAG = "settings"
-
- fun launch(context: Context, menuTag: String?, gameId: String?) {
- val settings = Intent(context, SettingsActivity::class.java)
- settings.putExtra(ARG_MENU_TAG, menuTag)
- settings.putExtra(ARG_GAME_ID, gameId)
- context.startActivity(settings)
- }
+ private const val KEY_SHOULD_SAVE = "should_save"
}
}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsActivityPresenter.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsActivityPresenter.kt
deleted file mode 100644
index fdbad32bf..000000000
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsActivityPresenter.kt
+++ /dev/null
@@ -1,81 +0,0 @@
-// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-package org.yuzu.yuzu_emu.features.settings.ui
-
-import android.content.Context
-import android.os.Bundle
-import java.io.File
-import org.yuzu.yuzu_emu.NativeLibrary
-import org.yuzu.yuzu_emu.features.settings.model.Settings
-import org.yuzu.yuzu_emu.features.settings.utils.SettingsFile
-import org.yuzu.yuzu_emu.utils.DirectoryInitialization
-import org.yuzu.yuzu_emu.utils.Log
-
-class SettingsActivityPresenter(private val activityView: SettingsActivityView) {
- private var shouldSave = false
- private lateinit var menuTag: String
- private lateinit var gameId: String
-
- fun onCreate(savedInstanceState: Bundle?, menuTag: String, gameId: String) {
- this.menuTag = menuTag
- this.gameId = gameId
- if (savedInstanceState != null) {
- shouldSave = savedInstanceState.getBoolean(KEY_SHOULD_SAVE)
- }
- }
-
- fun onStart() {
- prepareDirectoriesIfNeeded()
- }
-
- private fun loadSettingsUI() {
- // TODO: Load custom settings contextually
- activityView.showSettingsFragment(menuTag, false, gameId)
- activityView.onSettingsFileLoaded()
- }
-
- private fun prepareDirectoriesIfNeeded() {
- val configFile =
- File(
- "${DirectoryInitialization.userDirectory}/config/" +
- "${SettingsFile.FILE_NAME_CONFIG}.ini"
- )
- if (!configFile.exists()) {
- Log.error(
- "${DirectoryInitialization.userDirectory}/config/" +
- "${SettingsFile.FILE_NAME_CONFIG}.ini"
- )
- Log.error("yuzu config file could not be found!")
- }
-
- if (!DirectoryInitialization.areDirectoriesReady) {
- DirectoryInitialization.start(activityView as Context)
- }
- loadSettingsUI()
- }
-
- fun onStop(finishing: Boolean) {
- if (finishing && shouldSave) {
- Log.debug("[SettingsActivity] Settings activity stopping. Saving settings to INI...")
- Settings.saveSettings()
- NativeLibrary.reloadSettings()
- }
- }
-
- fun onSettingChanged() {
- shouldSave = true
- }
-
- fun onSettingsReset() {
- shouldSave = false
- }
-
- fun saveState(outState: Bundle) {
- outState.putBoolean(KEY_SHOULD_SAVE, shouldSave)
- }
-
- companion object {
- private const val KEY_SHOULD_SAVE = "should_save"
- }
-}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsActivityView.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsActivityView.kt
deleted file mode 100644
index 07a58b4ea..000000000
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsActivityView.kt
+++ /dev/null
@@ -1,38 +0,0 @@
-// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-package org.yuzu.yuzu_emu.features.settings.ui
-
-/**
- * Abstraction for the Activity that manages SettingsFragments.
- */
-interface SettingsActivityView {
- /**
- * Show a new SettingsFragment.
- *
- * @param menuTag Identifier for the settings group that should be displayed.
- * @param addToStack Whether or not this fragment should replace a previous one.
- */
- fun showSettingsFragment(menuTag: String, addToStack: Boolean, gameId: String)
-
- /**
- * Called when a load operation completes.
- */
- fun onSettingsFileLoaded()
-
- /**
- * Called when a load operation fails.
- */
- fun onSettingsFileNotFound()
-
- /**
- * End the activity.
- */
- fun finish()
-
- /**
- * Called by a containing Fragment to tell the Activity that a setting was changed;
- * unless this has been called, the Activity will not save to disk.
- */
- fun onSettingChanged()
-}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsAdapter.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsAdapter.kt
index 27eaaa576..9883c2ec7 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsAdapter.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsAdapter.kt
@@ -12,7 +12,8 @@ import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.TextView
import androidx.appcompat.app.AlertDialog
-import androidx.appcompat.app.AppCompatActivity
+import androidx.lifecycle.ViewModelProvider
+import androidx.navigation.findNavController
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.datepicker.MaterialDatePicker
import com.google.android.material.dialog.MaterialAlertDialogBuilder
@@ -20,6 +21,7 @@ import com.google.android.material.slider.Slider
import com.google.android.material.timepicker.MaterialTimePicker
import com.google.android.material.timepicker.TimeFormat
import org.yuzu.yuzu_emu.R
+import org.yuzu.yuzu_emu.SettingsNavigationDirections
import org.yuzu.yuzu_emu.databinding.DialogSliderBinding
import org.yuzu.yuzu_emu.databinding.ListItemSettingBinding
import org.yuzu.yuzu_emu.databinding.ListItemSettingSwitchBinding
@@ -30,18 +32,22 @@ import org.yuzu.yuzu_emu.features.settings.model.FloatSetting
import org.yuzu.yuzu_emu.features.settings.model.ShortSetting
import org.yuzu.yuzu_emu.features.settings.model.view.*
import org.yuzu.yuzu_emu.features.settings.ui.viewholder.*
+import org.yuzu.yuzu_emu.model.SettingsViewModel
class SettingsAdapter(
- private val fragmentView: SettingsFragmentView,
+ private val fragment: SettingsFragment,
private val context: Context
) : RecyclerView.Adapter<SettingViewHolder?>(), DialogInterface.OnClickListener {
- private var settings: ArrayList<SettingsItem>? = null
+ private var settings = ArrayList<SettingsItem>()
private var clickedItem: SettingsItem? = null
private var clickedPosition: Int
private var dialog: AlertDialog? = null
private var sliderProgress = 0
private var textSliderValue: TextView? = null
+ private val settingsViewModel: SettingsViewModel
+ get() = ViewModelProvider(fragment.requireActivity())[SettingsViewModel::class.java]
+
private var defaultCancelListener =
DialogInterface.OnClickListener { _: DialogInterface?, _: Int -> closeDialog() }
@@ -91,30 +97,22 @@ class SettingsAdapter(
holder.bind(getItem(position))
}
- private fun getItem(position: Int): SettingsItem {
- return settings!![position]
- }
+ private fun getItem(position: Int): SettingsItem = settings[position]
- override fun getItemCount(): Int {
- return if (settings != null) {
- settings!!.size
- } else {
- 0
- }
- }
+ override fun getItemCount(): Int = settings.size
override fun getItemViewType(position: Int): Int {
return getItem(position).type
}
- fun setSettingsList(settings: ArrayList<SettingsItem>?) {
+ fun setSettingsList(settings: ArrayList<SettingsItem>) {
this.settings = settings
notifyDataSetChanged()
}
fun onBooleanClick(item: SwitchSetting, position: Int, checked: Boolean) {
item.checked = checked
- fragmentView.onSettingChanged()
+ settingsViewModel.shouldSave = true
}
private fun onSingleChoiceClick(item: SingleChoiceSetting) {
@@ -155,7 +153,7 @@ class SettingsAdapter(
calendar.timeZone = TimeZone.getTimeZone("UTC")
var timeFormat: Int = TimeFormat.CLOCK_12H
- if (DateFormat.is24HourFormat(fragmentView.activityView as AppCompatActivity)) {
+ if (DateFormat.is24HourFormat(context)) {
timeFormat = TimeFormat.CLOCK_24H
}
@@ -172,7 +170,7 @@ class SettingsAdapter(
datePicker.addOnPositiveButtonClickListener {
timePicker.show(
- (fragmentView.activityView as AppCompatActivity).supportFragmentManager,
+ fragment.childFragmentManager,
"TimePicker"
)
}
@@ -181,14 +179,14 @@ class SettingsAdapter(
epochTime += timePicker.hour.toLong() * 60 * 60
epochTime += timePicker.minute.toLong() * 60
if (item.value != epochTime) {
- fragmentView.onSettingChanged()
+ settingsViewModel.shouldSave = true
notifyItemChanged(clickedPosition)
item.value = epochTime
}
clickedItem = null
}
datePicker.show(
- (fragmentView.activityView as AppCompatActivity).supportFragmentManager,
+ fragment.childFragmentManager,
"DatePicker"
)
}
@@ -231,7 +229,8 @@ class SettingsAdapter(
}
fun onSubmenuClick(item: SubmenuSetting) {
- fragmentView.loadSubMenu(item.menuKey)
+ val action = SettingsNavigationDirections.actionGlobalSettingsFragment(item.menuKey, null)
+ fragment.view?.findNavController()?.navigate(action)
}
override fun onClick(dialog: DialogInterface, which: Int) {
@@ -240,7 +239,7 @@ class SettingsAdapter(
val scSetting = clickedItem as SingleChoiceSetting
val value = getValueForSingleChoiceSelection(scSetting, which)
if (scSetting.selectedValue != value) {
- fragmentView.onSettingChanged()
+ settingsViewModel.shouldSave = true
}
// Get the backing Setting, which may be null (if for example it was missing from the file)
@@ -251,7 +250,7 @@ class SettingsAdapter(
is StringSingleChoiceSetting -> {
val scSetting = clickedItem as StringSingleChoiceSetting
val value = scSetting.getValueAt(which)
- if (scSetting.selectedValue != value) fragmentView.onSettingChanged()
+ if (scSetting.selectedValue != value) settingsViewModel.shouldSave = true
scSetting.selectedValue = value!!
closeDialog()
}
@@ -259,7 +258,7 @@ class SettingsAdapter(
is SliderSetting -> {
val sliderSetting = clickedItem as SliderSetting
if (sliderSetting.selectedValue != sliderProgress) {
- fragmentView.onSettingChanged()
+ settingsViewModel.shouldSave = true
}
when (sliderSetting.setting) {
is ByteSetting -> {
@@ -294,7 +293,7 @@ class SettingsAdapter(
.setPositiveButton(android.R.string.ok) { _: DialogInterface, _: Int ->
setting.reset()
notifyItemChanged(position)
- fragmentView.onSettingChanged()
+ settingsViewModel.shouldSave = true
}
.setNegativeButton(android.R.string.cancel, null)
.show()
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragment.kt
index dc1bf6eb1..de6aebd9d 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragment.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragment.kt
@@ -3,39 +3,41 @@
package org.yuzu.yuzu_emu.features.settings.ui
-import android.content.Context
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
+import android.view.ViewGroup.MarginLayoutParams
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.core.view.updatePadding
import androidx.fragment.app.Fragment
+import androidx.fragment.app.activityViewModels
+import androidx.navigation.fragment.navArgs
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.divider.MaterialDividerItemDecoration
+import com.google.android.material.transition.MaterialSharedAxis
+import org.yuzu.yuzu_emu.R
import org.yuzu.yuzu_emu.databinding.FragmentSettingsBinding
-import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem
+import org.yuzu.yuzu_emu.model.SettingsViewModel
-class SettingsFragment : Fragment(), SettingsFragmentView {
- override var activityView: SettingsActivityView? = null
-
- private val fragmentPresenter = SettingsFragmentPresenter(this)
+class SettingsFragment : Fragment() {
+ private lateinit var presenter: SettingsFragmentPresenter
private var settingsAdapter: SettingsAdapter? = null
private var _binding: FragmentSettingsBinding? = null
private val binding get() = _binding!!
- override fun onAttach(context: Context) {
- super.onAttach(context)
- activityView = requireActivity() as SettingsActivityView
- }
+ private val args by navArgs<SettingsFragmentArgs>()
+
+ private val settingsViewModel: SettingsViewModel by activityViewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- val menuTag = requireArguments().getString(ARGUMENT_MENU_TAG)
- val gameId = requireArguments().getString(ARGUMENT_GAME_ID)
- fragmentPresenter.onCreate(menuTag!!, gameId!!)
+ enterTransition = MaterialSharedAxis(MaterialSharedAxis.X, true)
+ returnTransition = MaterialSharedAxis(MaterialSharedAxis.X, false)
+ reenterTransition = MaterialSharedAxis(MaterialSharedAxis.X, false)
+ exitTransition = MaterialSharedAxis(MaterialSharedAxis.X, true)
}
override fun onCreateView(
@@ -48,7 +50,14 @@ class SettingsFragment : Fragment(), SettingsFragmentView {
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- settingsAdapter = SettingsAdapter(this, requireActivity())
+ settingsAdapter = SettingsAdapter(this, requireContext())
+ presenter = SettingsFragmentPresenter(
+ settingsViewModel,
+ settingsAdapter!!,
+ args.menuTag,
+ args.game?.gameId ?: ""
+ )
+
val dividerDecoration = MaterialDividerItemDecoration(
requireContext(),
LinearLayoutManager.VERTICAL
@@ -56,63 +65,52 @@ class SettingsFragment : Fragment(), SettingsFragmentView {
dividerDecoration.isLastItemDecorated = false
binding.listSettings.apply {
adapter = settingsAdapter
- layoutManager = LinearLayoutManager(activity)
+ layoutManager = LinearLayoutManager(requireContext())
addItemDecoration(dividerDecoration)
}
- fragmentPresenter.onViewCreated()
- setInsets()
- }
-
- override fun onDetach() {
- super.onDetach()
- activityView = null
- if (settingsAdapter != null) {
- settingsAdapter!!.closeDialog()
+ binding.toolbarSettings.setNavigationOnClickListener {
+ settingsViewModel.setShouldNavigateBack(true)
}
- }
- override fun showSettingsList(settingsList: ArrayList<SettingsItem>) {
- settingsAdapter!!.setSettingsList(settingsList)
- }
+ settingsViewModel.toolbarTitle.observe(viewLifecycleOwner) {
+ if (it.isNotEmpty()) binding.toolbarSettingsLayout.title = it
+ }
- override fun loadSettingsList() {
- fragmentPresenter.loadSettingsList()
- }
+ presenter.onViewCreated()
- override fun loadSubMenu(menuKey: String) {
- activityView!!.showSettingsFragment(
- menuKey,
- true,
- requireArguments().getString(ARGUMENT_GAME_ID)!!
- )
+ setInsets()
}
- override fun onSettingChanged() {
- activityView!!.onSettingChanged()
+ override fun onDetach() {
+ super.onDetach()
+ settingsAdapter?.closeDialog()
}
private fun setInsets() {
ViewCompat.setOnApplyWindowInsetsListener(
- binding.listSettings
- ) { view: View, windowInsets: WindowInsetsCompat ->
- val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
- view.updatePadding(bottom = insets.bottom)
+ binding.root
+ ) { _: View, windowInsets: WindowInsetsCompat ->
+ val barInsets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
+ val cutoutInsets = windowInsets.getInsets(WindowInsetsCompat.Type.displayCutout())
+
+ val leftInsets = barInsets.left + cutoutInsets.left
+ val rightInsets = barInsets.right + cutoutInsets.right
+
+ val sideMargin = resources.getDimensionPixelSize(R.dimen.spacing_medlarge)
+ val mlpSettingsList = binding.listSettings.layoutParams as MarginLayoutParams
+ mlpSettingsList.leftMargin = sideMargin + leftInsets
+ mlpSettingsList.rightMargin = sideMargin + rightInsets
+ binding.listSettings.layoutParams = mlpSettingsList
+ binding.listSettings.updatePadding(
+ bottom = barInsets.bottom
+ )
+
+ val mlpAppBar = binding.appbarSettings.layoutParams as MarginLayoutParams
+ mlpAppBar.leftMargin = leftInsets
+ mlpAppBar.rightMargin = rightInsets
+ binding.appbarSettings.layoutParams = mlpAppBar
windowInsets
}
}
-
- companion object {
- private const val ARGUMENT_MENU_TAG = "menu_tag"
- private const val ARGUMENT_GAME_ID = "game_id"
-
- fun newInstance(menuTag: String?, gameId: String?): Fragment {
- val fragment = SettingsFragment()
- val arguments = Bundle()
- arguments.putString(ARGUMENT_MENU_TAG, menuTag)
- arguments.putString(ARGUMENT_GAME_ID, gameId)
- fragment.arguments = arguments
- return fragment
- }
- }
}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt
index dddbf65bb..ba45c317d 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt
@@ -3,6 +3,7 @@
package org.yuzu.yuzu_emu.features.settings.ui
+import android.content.Context
import android.content.SharedPreferences
import android.os.Build
import android.text.TextUtils
@@ -20,36 +21,36 @@ import org.yuzu.yuzu_emu.features.settings.model.Settings
import org.yuzu.yuzu_emu.features.settings.model.ShortSetting
import org.yuzu.yuzu_emu.features.settings.model.view.*
import org.yuzu.yuzu_emu.features.settings.utils.SettingsFile
-import org.yuzu.yuzu_emu.fragments.ResetSettingsDialogFragment
-import org.yuzu.yuzu_emu.utils.ThemeHelper
+import org.yuzu.yuzu_emu.model.SettingsViewModel
-class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView) {
- private var menuTag: String? = null
- private lateinit var gameId: String
- private var settingsList: ArrayList<SettingsItem>? = null
+class SettingsFragmentPresenter(
+ private val settingsViewModel: SettingsViewModel,
+ private val adapter: SettingsAdapter,
+ private var menuTag: String,
+ private var gameId: String
+) {
+ private var settingsList = ArrayList<SettingsItem>()
- private val settingsActivity get() = fragmentView.activityView as SettingsActivity
+ private val preferences: SharedPreferences
+ get() = PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext)
- private lateinit var preferences: SharedPreferences
-
- fun onCreate(menuTag: String, gameId: String) {
- this.gameId = gameId
- this.menuTag = menuTag
- }
+ private val context: Context get() = YuzuApplication.appContext
fun onViewCreated() {
- preferences = PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext)
loadSettingsList()
}
- fun loadSettingsList() {
+ private fun loadSettingsList() {
if (!TextUtils.isEmpty(gameId)) {
- settingsActivity.setToolbarTitle("Game Settings: $gameId")
+ settingsViewModel.setToolbarTitle(
+ context.getString(
+ R.string.advanced_settings_game,
+ gameId
+ )
+ )
}
+
val sl = ArrayList<SettingsItem>()
- if (menuTag == null) {
- return
- }
when (menuTag) {
SettingsFile.FILE_NAME_CONFIG -> addConfigSettings(sl)
Settings.SECTION_GENERAL -> addGeneralSettings(sl)
@@ -69,11 +70,11 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
}
}
settingsList = sl
- fragmentView.showSettingsList(settingsList!!)
+ adapter.setSettingsList(settingsList)
}
private fun addConfigSettings(sl: ArrayList<SettingsItem>) {
- settingsActivity.setToolbarTitle(settingsActivity.getString(R.string.advanced_settings))
+ settingsViewModel.setToolbarTitle(context.getString(R.string.advanced_settings))
sl.apply {
add(SubmenuSetting(R.string.preferences_general, 0, Settings.SECTION_GENERAL))
add(SubmenuSetting(R.string.preferences_system, 0, Settings.SECTION_SYSTEM))
@@ -82,17 +83,14 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
add(SubmenuSetting(R.string.preferences_debug, 0, Settings.SECTION_DEBUG))
add(
RunnableSetting(R.string.reset_to_default, 0, false) {
- ResetSettingsDialogFragment().show(
- settingsActivity.supportFragmentManager,
- ResetSettingsDialogFragment.TAG
- )
+ settingsViewModel.setShouldShowResetSettingsDialog(true)
}
)
}
}
private fun addGeneralSettings(sl: ArrayList<SettingsItem>) {
- settingsActivity.setToolbarTitle(settingsActivity.getString(R.string.preferences_general))
+ settingsViewModel.setToolbarTitle(context.getString(R.string.preferences_general))
sl.apply {
add(
SwitchSetting(
@@ -131,7 +129,7 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
}
private fun addSystemSettings(sl: ArrayList<SettingsItem>) {
- settingsActivity.setToolbarTitle(settingsActivity.getString(R.string.preferences_system))
+ settingsViewModel.setToolbarTitle(context.getString(R.string.preferences_system))
sl.apply {
add(
SwitchSetting(
@@ -170,7 +168,7 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
}
private fun addGraphicsSettings(sl: ArrayList<SettingsItem>) {
- settingsActivity.setToolbarTitle(settingsActivity.getString(R.string.preferences_graphics))
+ settingsViewModel.setToolbarTitle(context.getString(R.string.preferences_graphics))
sl.apply {
add(
SingleChoiceSetting(
@@ -267,7 +265,7 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
}
private fun addAudioSettings(sl: ArrayList<SettingsItem>) {
- settingsActivity.setToolbarTitle(settingsActivity.getString(R.string.preferences_audio))
+ settingsViewModel.setToolbarTitle(context.getString(R.string.preferences_audio))
sl.apply {
add(
SingleChoiceSetting(
@@ -292,7 +290,7 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
}
private fun addThemeSettings(sl: ArrayList<SettingsItem>) {
- settingsActivity.setToolbarTitle(settingsActivity.getString(R.string.preferences_theme))
+ settingsViewModel.setToolbarTitle(context.getString(R.string.preferences_theme))
sl.apply {
val theme: AbstractIntSetting = object : AbstractIntSetting {
override val int: Int
@@ -302,7 +300,7 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
preferences.edit()
.putInt(Settings.PREF_THEME, value)
.apply()
- settingsActivity.recreate()
+ settingsViewModel.setShouldRecreate(true)
}
override val key: String? = null
@@ -346,7 +344,7 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
preferences.edit()
.putInt(Settings.PREF_THEME_MODE, value)
.apply()
- ThemeHelper.setThemeMode(settingsActivity)
+ settingsViewModel.setShouldRecreate(true)
}
override val key: String? = null
@@ -357,6 +355,7 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
preferences.edit()
.putInt(Settings.PREF_BLACK_BACKGROUNDS, defaultValue)
.apply()
+ settingsViewModel.setShouldRecreate(true)
}
}
@@ -378,7 +377,7 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
preferences.edit()
.putBoolean(Settings.PREF_BLACK_BACKGROUNDS, value)
.apply()
- settingsActivity.recreate()
+ settingsViewModel.setShouldRecreate(true)
}
override val key: String? = null
@@ -389,6 +388,7 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
preferences.edit()
.putBoolean(Settings.PREF_BLACK_BACKGROUNDS, defaultValue)
.apply()
+ settingsViewModel.setShouldRecreate(true)
}
}
@@ -403,7 +403,7 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
}
private fun addDebugSettings(sl: ArrayList<SettingsItem>) {
- settingsActivity.setToolbarTitle(settingsActivity.getString(R.string.preferences_debug))
+ settingsViewModel.setToolbarTitle(context.getString(R.string.preferences_debug))
sl.apply {
add(HeaderSetting(R.string.gpu))
add(
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentView.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentView.kt
deleted file mode 100644
index a4d7a80aa..000000000
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentView.kt
+++ /dev/null
@@ -1,42 +0,0 @@
-// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-package org.yuzu.yuzu_emu.features.settings.ui
-
-import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem
-
-/**
- * Abstraction for a screen showing a list of settings. Instances of
- * this type of view will each display a layer of the setting hierarchy.
- */
-interface SettingsFragmentView {
- /**
- * Pass an ArrayList to the View so that it can be displayed on screen.
- *
- * @param settingsList The result of converting the HashMap to an ArrayList
- */
- fun showSettingsList(settingsList: ArrayList<SettingsItem>)
-
- /**
- * Instructs the Fragment to load the settings screen.
- */
- fun loadSettingsList()
-
- /**
- * @return The Fragment's containing activity.
- */
- val activityView: SettingsActivityView?
-
- /**
- * Tell the Fragment to tell the containing Activity to show a new
- * Fragment containing a submenu of settings.
- *
- * @param menuKey Identifier for the settings group that should be shown.
- */
- fun loadSubMenu(menuKey: String)
-
- /**
- * Have the fragment tell the containing Activity that a setting was modified.
- */
- fun onSettingChanged()
-}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt
index 09e93a017..70df3af80 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt
@@ -28,6 +28,7 @@ import androidx.fragment.app.Fragment
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
+import androidx.navigation.findNavController
import androidx.navigation.fragment.navArgs
import androidx.preference.PreferenceManager
import androidx.window.layout.FoldingFeature
@@ -37,6 +38,7 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.slider.Slider
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
+import org.yuzu.yuzu_emu.HomeNavigationDirections
import org.yuzu.yuzu_emu.NativeLibrary
import org.yuzu.yuzu_emu.R
import org.yuzu.yuzu_emu.YuzuApplication
@@ -45,7 +47,6 @@ import org.yuzu.yuzu_emu.databinding.DialogOverlayAdjustBinding
import org.yuzu.yuzu_emu.databinding.FragmentEmulationBinding
import org.yuzu.yuzu_emu.features.settings.model.IntSetting
import org.yuzu.yuzu_emu.features.settings.model.Settings
-import org.yuzu.yuzu_emu.features.settings.ui.SettingsActivity
import org.yuzu.yuzu_emu.features.settings.utils.SettingsFile
import org.yuzu.yuzu_emu.overlay.InputOverlay
import org.yuzu.yuzu_emu.utils.*
@@ -139,7 +140,11 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
}
R.id.menu_settings -> {
- SettingsActivity.launch(requireContext(), SettingsFile.FILE_NAME_CONFIG, "")
+ val action = HomeNavigationDirections.actionGlobalSettingsActivity(
+ null,
+ SettingsFile.FILE_NAME_CONFIG
+ )
+ binding.root.findNavController().navigate(action)
true
}
@@ -211,7 +216,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
override fun onResume() {
super.onResume()
if (!DirectoryInitialization.areDirectoriesReady) {
- DirectoryInitialization.start(requireContext())
+ DirectoryInitialization.start()
}
updateScreenLayout()
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/HomeSettingsFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/HomeSettingsFragment.kt
index d5e793491..cbbe14d22 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/HomeSettingsFragment.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/HomeSettingsFragment.kt
@@ -25,17 +25,18 @@ import androidx.core.view.updatePadding
import androidx.documentfile.provider.DocumentFile
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
+import androidx.navigation.findNavController
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.transition.MaterialSharedAxis
import org.yuzu.yuzu_emu.BuildConfig
+import org.yuzu.yuzu_emu.HomeNavigationDirections
import org.yuzu.yuzu_emu.R
import org.yuzu.yuzu_emu.adapters.HomeSettingAdapter
import org.yuzu.yuzu_emu.databinding.FragmentHomeSettingsBinding
import org.yuzu.yuzu_emu.features.DocumentProvider
import org.yuzu.yuzu_emu.features.settings.model.Settings
-import org.yuzu.yuzu_emu.features.settings.ui.SettingsActivity
import org.yuzu.yuzu_emu.features.settings.utils.SettingsFile
import org.yuzu.yuzu_emu.model.HomeSetting
import org.yuzu.yuzu_emu.model.HomeViewModel
@@ -74,7 +75,13 @@ class HomeSettingsFragment : Fragment() {
R.string.advanced_settings,
R.string.settings_description,
R.drawable.ic_settings,
- { SettingsActivity.launch(requireContext(), SettingsFile.FILE_NAME_CONFIG, "") }
+ {
+ val action = HomeNavigationDirections.actionGlobalSettingsActivity(
+ null,
+ SettingsFile.FILE_NAME_CONFIG
+ )
+ binding.root.findNavController().navigate(action)
+ }
)
)
add(
@@ -90,7 +97,13 @@ class HomeSettingsFragment : Fragment() {
R.string.preferences_theme,
R.string.theme_and_color_description,
R.drawable.ic_palette,
- { SettingsActivity.launch(requireContext(), Settings.SECTION_THEME, "") }
+ {
+ val action = HomeNavigationDirections.actionGlobalSettingsActivity(
+ null,
+ Settings.SECTION_THEME
+ )
+ binding.root.findNavController().navigate(action)
+ }
)
)
add(
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/SettingsViewModel.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/SettingsViewModel.kt
new file mode 100644
index 000000000..1763341e2
--- /dev/null
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/SettingsViewModel.kt
@@ -0,0 +1,47 @@
+// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+package org.yuzu.yuzu_emu.model
+
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.MutableLiveData
+import androidx.lifecycle.ViewModel
+
+class SettingsViewModel : ViewModel() {
+ var game: Game? = null
+
+ var shouldSave = false
+
+ private val _toolbarTitle = MutableLiveData("")
+ val toolbarTitle: LiveData<String> get() = _toolbarTitle
+
+ private val _shouldRecreate = MutableLiveData(false)
+ val shouldRecreate: LiveData<Boolean> get() = _shouldRecreate
+
+ private val _shouldNavigateBack = MutableLiveData(false)
+ val shouldNavigateBack: LiveData<Boolean> get() = _shouldNavigateBack
+
+ private val _shouldShowResetSettingsDialog = MutableLiveData(false)
+ val shouldShowResetSettingsDialog: LiveData<Boolean> get() = _shouldShowResetSettingsDialog
+
+ fun setToolbarTitle(value: String) {
+ _toolbarTitle.value = value
+ }
+
+ fun setShouldRecreate(value: Boolean) {
+ _shouldRecreate.value = value
+ }
+
+ fun setShouldNavigateBack(value: Boolean) {
+ _shouldNavigateBack.value = value
+ }
+
+ fun setShouldShowResetSettingsDialog(value: Boolean) {
+ _shouldShowResetSettingsDialog.value = value
+ }
+
+ fun clear() {
+ game = null
+ shouldSave = false
+ }
+}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt
index d8dbf1f45..7735452e5 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt
@@ -33,13 +33,13 @@ import java.io.IOException
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
+import org.yuzu.yuzu_emu.HomeNavigationDirections
import org.yuzu.yuzu_emu.NativeLibrary
import org.yuzu.yuzu_emu.R
import org.yuzu.yuzu_emu.activities.EmulationActivity
import org.yuzu.yuzu_emu.databinding.ActivityMainBinding
import org.yuzu.yuzu_emu.databinding.DialogProgressBarBinding
import org.yuzu.yuzu_emu.features.settings.model.Settings
-import org.yuzu.yuzu_emu.features.settings.ui.SettingsActivity
import org.yuzu.yuzu_emu.features.settings.utils.SettingsFile
import org.yuzu.yuzu_emu.fragments.IndeterminateProgressDialogFragment
import org.yuzu.yuzu_emu.fragments.LongMessageDialogFragment
@@ -105,11 +105,13 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
when (it.itemId) {
R.id.gamesFragment -> gamesViewModel.setShouldScrollToTop(true)
R.id.searchFragment -> gamesViewModel.setSearchFocused(true)
- R.id.homeSettingsFragment -> SettingsActivity.launch(
- this,
- SettingsFile.FILE_NAME_CONFIG,
- ""
- )
+ R.id.homeSettingsFragment -> {
+ val action = HomeNavigationDirections.actionGlobalSettingsActivity(
+ null,
+ SettingsFile.FILE_NAME_CONFIG
+ )
+ navHostFragment.navController.navigate(action)
+ }
}
}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/DirectoryInitialization.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/DirectoryInitialization.kt
index 2ee63697e..3c9f6bad0 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/DirectoryInitialization.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/DirectoryInitialization.kt
@@ -3,18 +3,18 @@
package org.yuzu.yuzu_emu.utils
-import android.content.Context
import java.io.IOException
import org.yuzu.yuzu_emu.NativeLibrary
+import org.yuzu.yuzu_emu.YuzuApplication
object DirectoryInitialization {
private var userPath: String? = null
var areDirectoriesReady: Boolean = false
- fun start(context: Context) {
+ fun start() {
if (!areDirectoriesReady) {
- initializeInternalStorage(context)
+ initializeInternalStorage()
NativeLibrary.initializeEmulation()
areDirectoriesReady = true
}
@@ -26,9 +26,9 @@ object DirectoryInitialization {
return userPath
}
- private fun initializeInternalStorage(context: Context) {
+ private fun initializeInternalStorage() {
try {
- userPath = context.getExternalFilesDir(null)!!.canonicalPath
+ userPath = YuzuApplication.appContext.getExternalFilesDir(null)!!.canonicalPath
NativeLibrary.setAppDirectory(userPath!!)
} catch (e: IOException) {
e.printStackTrace()
diff --git a/src/android/app/src/main/res/anim-ldrtl/anim_pop_settings_fragment_out.xml b/src/android/app/src/main/res/anim-ldrtl/anim_pop_settings_fragment_out.xml
deleted file mode 100644
index 9f49c133a..000000000
--- a/src/android/app/src/main/res/anim-ldrtl/anim_pop_settings_fragment_out.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set xmlns:android="http://schemas.android.com/apk/res/android">
-
- <alpha
- android:duration="125"
- android:interpolator="@android:anim/decelerate_interpolator"
- android:fromAlpha="1"
- android:toAlpha="0" />
-
- <translate
- android:duration="125"
- android:interpolator="@android:anim/decelerate_interpolator"
- android:fromXDelta="0"
- android:toXDelta="-75" />
-
-</set>
diff --git a/src/android/app/src/main/res/anim-ldrtl/anim_settings_fragment_in.xml b/src/android/app/src/main/res/anim-ldrtl/anim_settings_fragment_in.xml
deleted file mode 100644
index 82fd719db..000000000
--- a/src/android/app/src/main/res/anim-ldrtl/anim_settings_fragment_in.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set xmlns:android="http://schemas.android.com/apk/res/android">
-
- <alpha
- android:duration="@android:integer/config_shortAnimTime"
- android:interpolator="@android:anim/decelerate_interpolator"
- android:fromAlpha="0"
- android:toAlpha="1" />
-
- <translate
- android:duration="@android:integer/config_shortAnimTime"
- android:interpolator="@android:anim/decelerate_interpolator"
- android:fromXDelta="-200"
- android:toXDelta="0" />
-
-</set>
diff --git a/src/android/app/src/main/res/anim/anim_pop_settings_fragment_out.xml b/src/android/app/src/main/res/anim/anim_pop_settings_fragment_out.xml
deleted file mode 100644
index 5892128f1..000000000
--- a/src/android/app/src/main/res/anim/anim_pop_settings_fragment_out.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set xmlns:android="http://schemas.android.com/apk/res/android">
-
- <alpha
- android:duration="125"
- android:interpolator="@android:anim/decelerate_interpolator"
- android:fromAlpha="1"
- android:toAlpha="0" />
-
- <translate
- android:duration="125"
- android:interpolator="@android:anim/decelerate_interpolator"
- android:fromXDelta="0"
- android:toXDelta="75" />
-
-</set>
diff --git a/src/android/app/src/main/res/anim/anim_settings_fragment_in.xml b/src/android/app/src/main/res/anim/anim_settings_fragment_in.xml
deleted file mode 100644
index 98e0cf8bd..000000000
--- a/src/android/app/src/main/res/anim/anim_settings_fragment_in.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set xmlns:android="http://schemas.android.com/apk/res/android">
-
- <alpha
- android:duration="@android:integer/config_shortAnimTime"
- android:interpolator="@android:anim/decelerate_interpolator"
- android:fromAlpha="0"
- android:toAlpha="1" />
-
- <translate
- android:duration="@android:integer/config_shortAnimTime"
- android:interpolator="@android:anim/decelerate_interpolator"
- android:fromXDelta="200"
- android:toXDelta="0" />
-
-</set>
diff --git a/src/android/app/src/main/res/anim/anim_settings_fragment_out.xml b/src/android/app/src/main/res/anim/anim_settings_fragment_out.xml
deleted file mode 100644
index 77a40a4d1..000000000
--- a/src/android/app/src/main/res/anim/anim_settings_fragment_out.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set xmlns:android="http://schemas.android.com/apk/res/android">
-
- <alpha
- android:duration="@android:integer/config_shortAnimTime"
- android:interpolator="@android:anim/decelerate_interpolator"
- android:fromAlpha="1"
- android:toAlpha="0" />
-
-</set>
diff --git a/src/android/app/src/main/res/animator/menu_slide_in_from_start.xml b/src/android/app/src/main/res/animator/menu_slide_in_from_start.xml
deleted file mode 100644
index 4612aee13..000000000
--- a/src/android/app/src/main/res/animator/menu_slide_in_from_start.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set xmlns:android="http://schemas.android.com/apk/res/android">
-
- <objectAnimator
- android:propertyName="translationX"
- android:valueType="floatType"
- android:valueFrom="-1280dp"
- android:valueTo="0"
- android:interpolator="@android:interpolator/decelerate_quad"
- android:duration="300"/>
-
- <objectAnimator
- android:propertyName="alpha"
- android:valueType="floatType"
- android:valueFrom="0"
- android:valueTo="1"
- android:interpolator="@android:interpolator/accelerate_quad"
- android:duration="300"/>
-
-</set> \ No newline at end of file
diff --git a/src/android/app/src/main/res/animator/menu_slide_out_to_start.xml b/src/android/app/src/main/res/animator/menu_slide_out_to_start.xml
deleted file mode 100644
index c00478946..000000000
--- a/src/android/app/src/main/res/animator/menu_slide_out_to_start.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<set xmlns:android="http://schemas.android.com/apk/res/android">
-
- <!-- This animation is used ONLY when a submenu is replaced. -->
- <objectAnimator
- android:propertyName="translationX"
- android:valueType="floatType"
- android:valueFrom="0"
- android:valueTo="-1280dp"
- android:interpolator="@android:interpolator/decelerate_quad"
- android:duration="200"/>
-
- <objectAnimator
- android:propertyName="alpha"
- android:valueType="floatType"
- android:valueFrom="1"
- android:valueTo="0"
- android:interpolator="@android:interpolator/decelerate_quad"
- android:duration="200"/>
-
-</set> \ No newline at end of file
diff --git a/src/android/app/src/main/res/layout/activity_settings.xml b/src/android/app/src/main/res/layout/activity_settings.xml
index 14ae83b04..8a026a30a 100644
--- a/src/android/app/src/main/res/layout/activity_settings.xml
+++ b/src/android/app/src/main/res/layout/activity_settings.xml
@@ -1,42 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
-<androidx.coordinatorlayout.widget.CoordinatorLayout
- android:id="@+id/coordinator_main"
+<androidx.constraintlayout.widget.ConstraintLayout
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/constraint_settings"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/colorSurface">
- <com.google.android.material.appbar.AppBarLayout
- android:id="@+id/appbar_settings"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:fitsSystemWindows="true"
- app:elevation="0dp">
-
- <com.google.android.material.appbar.CollapsingToolbarLayout
- style="?attr/collapsingToolbarLayoutMediumStyle"
- android:id="@+id/toolbar_settings_layout"
- android:layout_width="match_parent"
- android:layout_height="?attr/collapsingToolbarLayoutMediumSize"
- app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">
-
- <com.google.android.material.appbar.MaterialToolbar
- android:id="@+id/toolbar_settings"
- android:layout_width="match_parent"
- android:layout_height="?attr/actionBarSize"
- app:layout_collapseMode="pin" />
-
- </com.google.android.material.appbar.CollapsingToolbarLayout>
-
- </com.google.android.material.appbar.AppBarLayout>
-
- <FrameLayout
- android:id="@+id/frame_content"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_marginHorizontal="12dp"
- app:layout_behavior="@string/appbar_scrolling_view_behavior" />
+ <androidx.fragment.app.FragmentContainerView
+ android:id="@+id/fragment_container"
+ android:name="androidx.navigation.fragment.NavHostFragment"
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ app:defaultNavHost="true"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintLeft_toLeftOf="parent"
+ app:layout_constraintRight_toRightOf="parent"
+ app:layout_constraintTop_toTopOf="parent"
+ tools:layout="@layout/fragment_settings" />
<View
android:id="@+id/navigation_bar_shade"
@@ -45,6 +27,8 @@
android:background="@android:color/transparent"
android:clickable="false"
android:focusable="false"
- android:layout_gravity="bottom|center_horizontal" />
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent" />
-</androidx.coordinatorlayout.widget.CoordinatorLayout>
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/src/android/app/src/main/res/layout/fragment_settings.xml b/src/android/app/src/main/res/layout/fragment_settings.xml
index 167720347..ebedbf1ec 100644
--- a/src/android/app/src/main/res/layout/fragment_settings.xml
+++ b/src/android/app/src/main/res/layout/fragment_settings.xml
@@ -1,14 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
-<FrameLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
+<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:id="@+id/coordinator_main"
android:layout_width="match_parent"
- android:layout_height="match_parent">
+ android:layout_height="match_parent"
+ android:background="?attr/colorSurface">
+
+ <com.google.android.material.appbar.AppBarLayout
+ android:id="@+id/appbar_settings"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:fitsSystemWindows="true"
+ app:elevation="0dp">
+
+ <com.google.android.material.appbar.CollapsingToolbarLayout
+ android:id="@+id/toolbar_settings_layout"
+ style="?attr/collapsingToolbarLayoutMediumStyle"
+ android:layout_width="match_parent"
+ android:layout_height="?attr/collapsingToolbarLayoutMediumSize"
+ app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">
+
+ <com.google.android.material.appbar.MaterialToolbar
+ android:id="@+id/toolbar_settings"
+ android:layout_width="match_parent"
+ android:layout_height="?attr/actionBarSize"
+ app:layout_collapseMode="pin"
+ app:navigationIcon="@drawable/ic_back" />
+
+ </com.google.android.material.appbar.CollapsingToolbarLayout>
+
+ </com.google.android.material.appbar.AppBarLayout>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/list_settings"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:background="?attr/colorSurface"
- android:clipToPadding="false" />
+ android:clipToPadding="false"
+ app:layout_behavior="@string/appbar_scrolling_view_behavior" />
-</FrameLayout>
+</androidx.coordinatorlayout.widget.CoordinatorLayout>
diff --git a/src/android/app/src/main/res/menu/menu_settings.xml b/src/android/app/src/main/res/menu/menu_settings.xml
deleted file mode 100644
index 1fe7aa6d4..000000000
--- a/src/android/app/src/main/res/menu/menu_settings.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<menu /> \ No newline at end of file
diff --git a/src/android/app/src/main/res/navigation/emulation_navigation.xml b/src/android/app/src/main/res/navigation/emulation_navigation.xml
index 8208f4c2c..2a3c23d55 100644
--- a/src/android/app/src/main/res/navigation/emulation_navigation.xml
+++ b/src/android/app/src/main/res/navigation/emulation_navigation.xml
@@ -15,4 +15,21 @@
app:argType="org.yuzu.yuzu_emu.model.Game" />
</fragment>
+ <activity
+ android:id="@+id/settingsActivity"
+ android:name="org.yuzu.yuzu_emu.features.settings.ui.SettingsActivity"
+ android:label="SettingsActivity">
+ <argument
+ android:name="game"
+ app:argType="org.yuzu.yuzu_emu.model.Game"
+ app:nullable="true" />
+ <argument
+ android:name="menuTag"
+ app:argType="string" />
+ </activity>
+
+ <action
+ android:id="@+id/action_global_settingsActivity"
+ app:destination="@id/settingsActivity" />
+
</navigation>
diff --git a/src/android/app/src/main/res/navigation/home_navigation.xml b/src/android/app/src/main/res/navigation/home_navigation.xml
index fcebba726..fb8e14448 100644
--- a/src/android/app/src/main/res/navigation/home_navigation.xml
+++ b/src/android/app/src/main/res/navigation/home_navigation.xml
@@ -70,4 +70,21 @@
app:destination="@id/emulationActivity"
app:launchSingleTop="true" />
+ <activity
+ android:id="@+id/settingsActivity"
+ android:name="org.yuzu.yuzu_emu.features.settings.ui.SettingsActivity"
+ android:label="SettingsActivity">
+ <argument
+ android:name="game"
+ app:argType="org.yuzu.yuzu_emu.model.Game"
+ app:nullable="true" />
+ <argument
+ android:name="menuTag"
+ app:argType="string" />
+ </activity>
+
+ <action
+ android:id="@+id/action_global_settingsActivity"
+ app:destination="@id/settingsActivity" />
+
</navigation>
diff --git a/src/android/app/src/main/res/navigation/settings_navigation.xml b/src/android/app/src/main/res/navigation/settings_navigation.xml
new file mode 100644
index 000000000..b36200c65
--- /dev/null
+++ b/src/android/app/src/main/res/navigation/settings_navigation.xml
@@ -0,0 +1,24 @@
+<?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"
+ android:id="@+id/settings_navigation"
+ app:startDestination="@id/settingsFragment">
+
+ <fragment
+ android:id="@+id/settingsFragment"
+ android:name="org.yuzu.yuzu_emu.features.settings.ui.SettingsFragment"
+ android:label="SettingsFragment">
+ <argument
+ android:name="menuTag"
+ app:argType="string" />
+ <argument
+ android:name="game"
+ app:argType="org.yuzu.yuzu_emu.model.Game"
+ app:nullable="true" />
+ </fragment>
+
+ <action
+ android:id="@+id/action_global_settingsFragment"
+ app:destination="@id/settingsFragment" />
+
+</navigation>
diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml
index df76563fc..6b782780a 100644
--- a/src/android/app/src/main/res/values/strings.xml
+++ b/src/android/app/src/main/res/values/strings.xml
@@ -74,6 +74,7 @@
<string name="install_gpu_driver">Install GPU driver</string>
<string name="install_gpu_driver_description">Install alternative drivers for potentially better performance or accuracy</string>
<string name="advanced_settings">Advanced settings</string>
+ <string name="advanced_settings_game">Advanced settings: %1$s</string>
<string name="settings_description">Configure emulator settings</string>
<string name="search_recently_played">Recently played</string>
<string name="search_recently_added">Recently added</string>