From d786d19880fbeddf4356d978ec858c4c4874935a Mon Sep 17 00:00:00 2001 From: Charles Lombardo Date: Tue, 22 Aug 2023 23:32:10 -0400 Subject: [PATCH] android: Implement paired settings Enables and disables editing on settings that rely on other boolean settings. --- .../settings/model/AbstractSetting.kt | 7 +- .../settings/model/view/SettingsItem.kt | 235 ++++++++++++++++ .../features/settings/ui/SettingsAdapter.kt | 34 ++- .../features/settings/ui/SettingsFragment.kt | 7 + .../settings/ui/SettingsFragmentPresenter.kt | 265 +++--------------- .../ui/viewholder/SwitchSettingViewHolder.kt | 4 +- .../yuzu/yuzu_emu/model/SettingsViewModel.kt | 7 + .../org/yuzu/yuzu_emu/utils/NativeConfig.kt | 2 + .../app/src/main/jni/native_config.cpp | 15 +- 9 files changed, 335 insertions(+), 241 deletions(-) diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/AbstractSetting.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/AbstractSetting.kt index 724a2ecb8..73215c247 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/AbstractSetting.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/AbstractSetting.kt @@ -6,14 +6,17 @@ package org.yuzu.yuzu_emu.features.settings.model import org.yuzu.yuzu_emu.utils.NativeConfig interface AbstractSetting { - val key: String? + val key: String val category: Settings.Category val defaultValue: Any val valueAsString: String get() = "" val isRuntimeModifiable: Boolean - get() = NativeConfig.getIsRuntimeModifiable(key!!) + get() = NativeConfig.getIsRuntimeModifiable(key) + + val pairedSettingKey: String + get() = NativeConfig.getPairedSettingKey(key) fun reset() } diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt index 3bdcc5bca..b3b3fc209 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt @@ -4,8 +4,15 @@ package org.yuzu.yuzu_emu.features.settings.model.view import org.yuzu.yuzu_emu.NativeLibrary +import org.yuzu.yuzu_emu.R +import org.yuzu.yuzu_emu.features.settings.model.AbstractBooleanSetting import org.yuzu.yuzu_emu.features.settings.model.AbstractSetting +import org.yuzu.yuzu_emu.features.settings.model.BooleanSetting +import org.yuzu.yuzu_emu.features.settings.model.ByteSetting +import org.yuzu.yuzu_emu.features.settings.model.IntSetting +import org.yuzu.yuzu_emu.features.settings.model.LongSetting import org.yuzu.yuzu_emu.features.settings.model.Settings +import org.yuzu.yuzu_emu.features.settings.model.ShortSetting /** * ViewModel abstraction for an Item in the RecyclerView powering SettingsFragments. @@ -37,11 +44,239 @@ abstract class SettingsItem( const val TYPE_DATETIME_SETTING = 6 const val TYPE_RUNNABLE = 7 + const val FASTMEM_COMBINED = "fastmem_combined" + val emptySetting = object : AbstractSetting { override val key: String = "" override val category: Settings.Category = Settings.Category.Ui override val defaultValue: Any = false override fun reset() {} } + + // Extension for putting SettingsItems into a hashmap without repeating yourself + fun HashMap.put(item: SettingsItem) { + put(item.setting.key, item) + } + + // List of all general + val settingsItems = HashMap().apply { + put( + SwitchSetting( + BooleanSetting.RENDERER_USE_SPEED_LIMIT, + R.string.frame_limit_enable, + R.string.frame_limit_enable_description + ) + ) + put( + SliderSetting( + ShortSetting.RENDERER_SPEED_LIMIT, + R.string.frame_limit_slider, + R.string.frame_limit_slider_description, + 1, + 200, + "%" + ) + ) + put( + SingleChoiceSetting( + IntSetting.CPU_ACCURACY, + R.string.cpu_accuracy, + 0, + R.array.cpuAccuracyNames, + R.array.cpuAccuracyValues + ) + ) + put( + SwitchSetting( + BooleanSetting.PICTURE_IN_PICTURE, + R.string.picture_in_picture, + R.string.picture_in_picture_description + ) + ) + put( + SwitchSetting( + BooleanSetting.USE_DOCKED_MODE, + R.string.use_docked_mode, + R.string.use_docked_mode_description + ) + ) + put( + SingleChoiceSetting( + IntSetting.REGION_INDEX, + R.string.emulated_region, + 0, + R.array.regionNames, + R.array.regionValues + ) + ) + put( + SingleChoiceSetting( + IntSetting.LANGUAGE_INDEX, + R.string.emulated_language, + 0, + R.array.languageNames, + R.array.languageValues + ) + ) + put( + SwitchSetting( + BooleanSetting.USE_CUSTOM_RTC, + R.string.use_custom_rtc, + R.string.use_custom_rtc_description + ) + ) + put(DateTimeSetting(LongSetting.CUSTOM_RTC, R.string.set_custom_rtc, 0)) + put( + SingleChoiceSetting( + IntSetting.RENDERER_ACCURACY, + R.string.renderer_accuracy, + 0, + R.array.rendererAccuracyNames, + R.array.rendererAccuracyValues + ) + ) + put( + SingleChoiceSetting( + IntSetting.RENDERER_RESOLUTION, + R.string.renderer_resolution, + 0, + R.array.rendererResolutionNames, + R.array.rendererResolutionValues + ) + ) + put( + SingleChoiceSetting( + IntSetting.RENDERER_VSYNC, + R.string.renderer_vsync, + 0, + R.array.rendererVSyncNames, + R.array.rendererVSyncValues + ) + ) + put( + SingleChoiceSetting( + IntSetting.RENDERER_SCALING_FILTER, + R.string.renderer_scaling_filter, + 0, + R.array.rendererScalingFilterNames, + R.array.rendererScalingFilterValues + ) + ) + put( + SingleChoiceSetting( + IntSetting.RENDERER_ANTI_ALIASING, + R.string.renderer_anti_aliasing, + 0, + R.array.rendererAntiAliasingNames, + R.array.rendererAntiAliasingValues + ) + ) + put( + SingleChoiceSetting( + IntSetting.RENDERER_SCREEN_LAYOUT, + R.string.renderer_screen_layout, + 0, + R.array.rendererScreenLayoutNames, + R.array.rendererScreenLayoutValues + ) + ) + put( + SingleChoiceSetting( + IntSetting.RENDERER_ASPECT_RATIO, + R.string.renderer_aspect_ratio, + 0, + R.array.rendererAspectRatioNames, + R.array.rendererAspectRatioValues + ) + ) + put( + SwitchSetting( + BooleanSetting.RENDERER_USE_DISK_SHADER_CACHE, + R.string.use_disk_shader_cache, + R.string.use_disk_shader_cache_description + ) + ) + put( + SwitchSetting( + BooleanSetting.RENDERER_FORCE_MAX_CLOCK, + R.string.renderer_force_max_clock, + R.string.renderer_force_max_clock_description + ) + ) + put( + SwitchSetting( + BooleanSetting.RENDERER_ASYNCHRONOUS_SHADERS, + R.string.renderer_asynchronous_shaders, + R.string.renderer_asynchronous_shaders_description + ) + ) + put( + SwitchSetting( + BooleanSetting.RENDERER_REACTIVE_FLUSHING, + R.string.renderer_reactive_flushing, + R.string.renderer_reactive_flushing_description + ) + ) + put( + SingleChoiceSetting( + IntSetting.AUDIO_OUTPUT_ENGINE, + R.string.audio_output_engine, + 0, + R.array.outputEngineEntries, + R.array.outputEngineValues + ) + ) + put( + SliderSetting( + ByteSetting.AUDIO_VOLUME, + R.string.audio_volume, + R.string.audio_volume_description, + 0, + 100, + "%" + ) + ) + put( + SingleChoiceSetting( + IntSetting.RENDERER_BACKEND, + R.string.renderer_api, + 0, + R.array.rendererApiNames, + R.array.rendererApiValues + ) + ) + put( + SwitchSetting( + BooleanSetting.RENDERER_DEBUG, + R.string.renderer_debug, + R.string.renderer_debug_description + ) + ) + put( + SwitchSetting( + BooleanSetting.CPU_DEBUG_MODE, + R.string.cpu_debug_mode, + R.string.cpu_debug_mode_description + ) + ) + + val fastmem = object : AbstractBooleanSetting { + override val boolean: Boolean + get() = + BooleanSetting.FASTMEM.boolean && BooleanSetting.FASTMEM_EXCLUSIVES.boolean + + override fun setBoolean(value: Boolean) { + BooleanSetting.FASTMEM.setBoolean(value) + BooleanSetting.FASTMEM_EXCLUSIVES.setBoolean(value) + } + + override val key: String = FASTMEM_COMBINED + override val category = Settings.Category.Cpu + override val isRuntimeModifiable: Boolean = false + override val defaultValue: Boolean = true + override fun reset() = setBoolean(defaultValue) + } + put(SwitchSetting(fastmem, R.string.fastmem, 0)) + } } } 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 9883c2ec7..ff1e64e0a 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 @@ -14,7 +14,9 @@ import android.widget.TextView import androidx.appcompat.app.AlertDialog import androidx.lifecycle.ViewModelProvider import androidx.navigation.findNavController -import androidx.recyclerview.widget.RecyclerView +import androidx.recyclerview.widget.AsyncDifferConfig +import androidx.recyclerview.widget.DiffUtil +import androidx.recyclerview.widget.ListAdapter import com.google.android.material.datepicker.MaterialDatePicker import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.slider.Slider @@ -37,8 +39,8 @@ import org.yuzu.yuzu_emu.model.SettingsViewModel class SettingsAdapter( private val fragment: SettingsFragment, private val context: Context -) : RecyclerView.Adapter(), DialogInterface.OnClickListener { - private var settings = ArrayList() +) : ListAdapter(AsyncDifferConfig.Builder(DiffCallback()).build()), + DialogInterface.OnClickListener { private var clickedItem: SettingsItem? = null private var clickedPosition: Int private var dialog: AlertDialog? = null @@ -94,24 +96,18 @@ class SettingsAdapter( } override fun onBindViewHolder(holder: SettingViewHolder, position: Int) { - holder.bind(getItem(position)) + holder.bind(currentList[position]) } - private fun getItem(position: Int): SettingsItem = settings[position] - - override fun getItemCount(): Int = settings.size + override fun getItemCount(): Int = currentList.size override fun getItemViewType(position: Int): Int { - return getItem(position).type + return currentList[position].type } - fun setSettingsList(settings: ArrayList) { - this.settings = settings - notifyDataSetChanged() - } - - fun onBooleanClick(item: SwitchSetting, position: Int, checked: Boolean) { + fun onBooleanClick(item: SwitchSetting, checked: Boolean) { item.checked = checked + settingsViewModel.setShouldReloadSettingsList(true) settingsViewModel.shouldSave = true } @@ -338,4 +334,14 @@ class SettingsAdapter( } return -1 } + + private class DiffCallback : DiffUtil.ItemCallback() { + override fun areItemsTheSame(oldItem: SettingsItem, newItem: SettingsItem): Boolean { + return oldItem.setting.key == newItem.setting.key + } + + override fun areContentsTheSame(oldItem: SettingsItem, newItem: SettingsItem): Boolean { + return oldItem.setting.key == newItem.setting.key + } + } } 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 de6aebd9d..5890b0642 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 @@ -77,6 +77,13 @@ class SettingsFragment : Fragment() { if (it.isNotEmpty()) binding.toolbarSettingsLayout.title = it } + settingsViewModel.shouldReloadSettingsList.observe(viewLifecycleOwner) { + if (it) { + settingsViewModel.setShouldReloadSettingsList(false) + presenter.loadSettingsList() + } + } + presenter.onViewCreated() setInsets() 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 ba45c317d..22a529b1b 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 @@ -22,6 +22,7 @@ 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.model.SettingsViewModel +import org.yuzu.yuzu_emu.utils.NativeConfig class SettingsFragmentPresenter( private val settingsViewModel: SettingsViewModel, @@ -36,11 +37,22 @@ class SettingsFragmentPresenter( private val context: Context get() = YuzuApplication.appContext + // Extension for populating settings list based on paired settings + fun ArrayList.add(key: String) { + val item = SettingsItem.settingsItems[key]!! + val pairedSettingKey = item.setting.pairedSettingKey + if (pairedSettingKey.isNotEmpty()) { + val pairedSettingValue = NativeConfig.getBoolean(pairedSettingKey, false) + if (!pairedSettingValue) return + } + add(item) + } + fun onViewCreated() { loadSettingsList() } - private fun loadSettingsList() { + fun loadSettingsList() { if (!TextUtils.isEmpty(gameId)) { settingsViewModel.setToolbarTitle( context.getString( @@ -70,7 +82,7 @@ class SettingsFragmentPresenter( } } settingsList = sl - adapter.setSettingsList(settingsList) + adapter.submitList(settingsList) } private fun addConfigSettings(sl: ArrayList) { @@ -92,200 +104,46 @@ class SettingsFragmentPresenter( private fun addGeneralSettings(sl: ArrayList) { settingsViewModel.setToolbarTitle(context.getString(R.string.preferences_general)) sl.apply { - add( - SwitchSetting( - BooleanSetting.RENDERER_USE_SPEED_LIMIT, - R.string.frame_limit_enable, - R.string.frame_limit_enable_description - ) - ) - add( - SliderSetting( - ShortSetting.RENDERER_SPEED_LIMIT, - R.string.frame_limit_slider, - R.string.frame_limit_slider_description, - 1, - 200, - "%" - ) - ) - add( - SingleChoiceSetting( - IntSetting.CPU_ACCURACY, - R.string.cpu_accuracy, - 0, - R.array.cpuAccuracyNames, - R.array.cpuAccuracyValues - ) - ) - add( - SwitchSetting( - BooleanSetting.PICTURE_IN_PICTURE, - R.string.picture_in_picture, - R.string.picture_in_picture_description - ) - ) + add(BooleanSetting.RENDERER_USE_SPEED_LIMIT.key) + add(ShortSetting.RENDERER_SPEED_LIMIT.key) + add(IntSetting.CPU_ACCURACY.key) + add(BooleanSetting.PICTURE_IN_PICTURE.key) } } private fun addSystemSettings(sl: ArrayList) { settingsViewModel.setToolbarTitle(context.getString(R.string.preferences_system)) sl.apply { - add( - SwitchSetting( - BooleanSetting.USE_DOCKED_MODE, - R.string.use_docked_mode, - R.string.use_docked_mode_description - ) - ) - add( - SingleChoiceSetting( - IntSetting.REGION_INDEX, - R.string.emulated_region, - 0, - R.array.regionNames, - R.array.regionValues - ) - ) - add( - SingleChoiceSetting( - IntSetting.LANGUAGE_INDEX, - R.string.emulated_language, - 0, - R.array.languageNames, - R.array.languageValues - ) - ) - add( - SwitchSetting( - BooleanSetting.USE_CUSTOM_RTC, - R.string.use_custom_rtc, - R.string.use_custom_rtc_description - ) - ) - add(DateTimeSetting(LongSetting.CUSTOM_RTC, R.string.set_custom_rtc, 0)) + add(BooleanSetting.USE_DOCKED_MODE.key) + add(IntSetting.REGION_INDEX.key) + add(IntSetting.LANGUAGE_INDEX.key) + add(BooleanSetting.USE_CUSTOM_RTC.key) + add(LongSetting.CUSTOM_RTC.key) } } private fun addGraphicsSettings(sl: ArrayList) { settingsViewModel.setToolbarTitle(context.getString(R.string.preferences_graphics)) sl.apply { - add( - SingleChoiceSetting( - IntSetting.RENDERER_ACCURACY, - R.string.renderer_accuracy, - 0, - R.array.rendererAccuracyNames, - R.array.rendererAccuracyValues - ) - ) - add( - SingleChoiceSetting( - IntSetting.RENDERER_RESOLUTION, - R.string.renderer_resolution, - 0, - R.array.rendererResolutionNames, - R.array.rendererResolutionValues - ) - ) - add( - SingleChoiceSetting( - IntSetting.RENDERER_VSYNC, - R.string.renderer_vsync, - 0, - R.array.rendererVSyncNames, - R.array.rendererVSyncValues - ) - ) - add( - SingleChoiceSetting( - IntSetting.RENDERER_SCALING_FILTER, - R.string.renderer_scaling_filter, - 0, - R.array.rendererScalingFilterNames, - R.array.rendererScalingFilterValues - ) - ) - add( - SingleChoiceSetting( - IntSetting.RENDERER_ANTI_ALIASING, - R.string.renderer_anti_aliasing, - 0, - R.array.rendererAntiAliasingNames, - R.array.rendererAntiAliasingValues - ) - ) - add( - SingleChoiceSetting( - IntSetting.RENDERER_SCREEN_LAYOUT, - R.string.renderer_screen_layout, - 0, - R.array.rendererScreenLayoutNames, - R.array.rendererScreenLayoutValues - ) - ) - add( - SingleChoiceSetting( - IntSetting.RENDERER_ASPECT_RATIO, - R.string.renderer_aspect_ratio, - 0, - R.array.rendererAspectRatioNames, - R.array.rendererAspectRatioValues - ) - ) - add( - SwitchSetting( - BooleanSetting.RENDERER_USE_DISK_SHADER_CACHE, - R.string.use_disk_shader_cache, - R.string.use_disk_shader_cache_description - ) - ) - add( - SwitchSetting( - BooleanSetting.RENDERER_FORCE_MAX_CLOCK, - R.string.renderer_force_max_clock, - R.string.renderer_force_max_clock_description - ) - ) - add( - SwitchSetting( - BooleanSetting.RENDERER_ASYNCHRONOUS_SHADERS, - R.string.renderer_asynchronous_shaders, - R.string.renderer_asynchronous_shaders_description - ) - ) - add( - SwitchSetting( - BooleanSetting.RENDERER_REACTIVE_FLUSHING, - R.string.renderer_reactive_flushing, - R.string.renderer_reactive_flushing_description - ) - ) + add(IntSetting.RENDERER_ACCURACY.key) + add(IntSetting.RENDERER_RESOLUTION.key) + add(IntSetting.RENDERER_VSYNC.key) + add(IntSetting.RENDERER_SCALING_FILTER.key) + add(IntSetting.RENDERER_ANTI_ALIASING.key) + add(IntSetting.RENDERER_SCREEN_LAYOUT.key) + add(IntSetting.RENDERER_ASPECT_RATIO.key) + add(BooleanSetting.RENDERER_USE_DISK_SHADER_CACHE.key) + add(BooleanSetting.RENDERER_FORCE_MAX_CLOCK.key) + add(BooleanSetting.RENDERER_ASYNCHRONOUS_SHADERS.key) + add(BooleanSetting.RENDERER_REACTIVE_FLUSHING.key) } } private fun addAudioSettings(sl: ArrayList) { settingsViewModel.setToolbarTitle(context.getString(R.string.preferences_audio)) sl.apply { - add( - SingleChoiceSetting( - IntSetting.AUDIO_OUTPUT_ENGINE, - R.string.audio_output_engine, - 0, - R.array.outputEngineEntries, - R.array.outputEngineValues - ) - ) - add( - SliderSetting( - ByteSetting.AUDIO_VOLUME, - R.string.audio_volume, - R.string.audio_volume_description, - 0, - 100, - "%" - ) - ) + add(IntSetting.AUDIO_OUTPUT_ENGINE.key) + add(ByteSetting.AUDIO_VOLUME.key) } } @@ -303,7 +161,7 @@ class SettingsFragmentPresenter( settingsViewModel.setShouldRecreate(true) } - override val key: String? = null + override val key: String = Settings.PREF_THEME override val category = Settings.Category.UiGeneral override val isRuntimeModifiable: Boolean = false override val defaultValue: Int = 0 @@ -347,7 +205,7 @@ class SettingsFragmentPresenter( settingsViewModel.setShouldRecreate(true) } - override val key: String? = null + override val key: String = Settings.PREF_THEME_MODE override val category = Settings.Category.UiGeneral override val isRuntimeModifiable: Boolean = false override val defaultValue: Int = -1 @@ -380,7 +238,7 @@ class SettingsFragmentPresenter( settingsViewModel.setShouldRecreate(true) } - override val key: String? = null + override val key: String = Settings.PREF_BLACK_BACKGROUNDS override val category = Settings.Category.UiGeneral override val isRuntimeModifiable: Boolean = false override val defaultValue: Boolean = false @@ -406,49 +264,12 @@ class SettingsFragmentPresenter( settingsViewModel.setToolbarTitle(context.getString(R.string.preferences_debug)) sl.apply { add(HeaderSetting(R.string.gpu)) - add( - SingleChoiceSetting( - IntSetting.RENDERER_BACKEND, - R.string.renderer_api, - 0, - R.array.rendererApiNames, - R.array.rendererApiValues - ) - ) - add( - SwitchSetting( - BooleanSetting.RENDERER_DEBUG, - R.string.renderer_debug, - R.string.renderer_debug_description - ) - ) + add(IntSetting.RENDERER_BACKEND.key) + add(BooleanSetting.RENDERER_DEBUG.key) add(HeaderSetting(R.string.cpu)) - add( - SwitchSetting( - BooleanSetting.CPU_DEBUG_MODE, - R.string.cpu_debug_mode, - R.string.cpu_debug_mode_description - ) - ) - - val fastmem = object : AbstractBooleanSetting { - override val boolean: Boolean - get() = - BooleanSetting.FASTMEM.boolean && BooleanSetting.FASTMEM_EXCLUSIVES.boolean - - override fun setBoolean(value: Boolean) { - BooleanSetting.FASTMEM.setBoolean(value) - BooleanSetting.FASTMEM_EXCLUSIVES.setBoolean(value) - } - - override val key: String? = null - override val category = Settings.Category.Cpu - override val isRuntimeModifiable: Boolean = false - override val defaultValue: Boolean = true - override fun reset() = setBoolean(defaultValue) - } - add(SwitchSetting(fastmem, R.string.fastmem, 0)) + add(BooleanSetting.CPU_DEBUG_MODE.key) + add(SettingsItem.FASTMEM_COMBINED) } } } diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SwitchSettingViewHolder.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SwitchSettingViewHolder.kt index 25b689d66..0a37d3624 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SwitchSettingViewHolder.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SwitchSettingViewHolder.kt @@ -29,7 +29,7 @@ class SwitchSettingViewHolder(val binding: ListItemSettingSwitchBinding, adapter binding.switchWidget.setOnCheckedChangeListener(null) binding.switchWidget.isChecked = setting.checked binding.switchWidget.setOnCheckedChangeListener { _: CompoundButton, _: Boolean -> - adapter.onBooleanClick(item, bindingAdapterPosition, binding.switchWidget.isChecked) + adapter.onBooleanClick(item, binding.switchWidget.isChecked) } setStyle(setting.isEditable, binding) @@ -43,7 +43,7 @@ class SwitchSettingViewHolder(val binding: ListItemSettingSwitchBinding, adapter override fun onLongClick(clicked: View): Boolean { if (setting.isEditable) { - return adapter.onLongClick(setting.setting!!, bindingAdapterPosition) + return adapter.onLongClick(setting.setting, bindingAdapterPosition) } return false } 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 index 1763341e2..6f2276293 100644 --- 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 @@ -24,6 +24,9 @@ class SettingsViewModel : ViewModel() { private val _shouldShowResetSettingsDialog = MutableLiveData(false) val shouldShowResetSettingsDialog: LiveData get() = _shouldShowResetSettingsDialog + private val _shouldReloadSettingsList = MutableLiveData(false) + val shouldReloadSettingsList: LiveData get() = _shouldReloadSettingsList + fun setToolbarTitle(value: String) { _toolbarTitle.value = value } @@ -40,6 +43,10 @@ class SettingsViewModel : ViewModel() { _shouldShowResetSettingsDialog.value = value } + fun setShouldReloadSettingsList(value: Boolean) { + _shouldReloadSettingsList.value = value + } + fun clear() { game = null shouldSave = false diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/NativeConfig.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/NativeConfig.kt index d4d981f9e..9425f8b99 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/NativeConfig.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/NativeConfig.kt @@ -28,4 +28,6 @@ object NativeConfig { external fun getIsRuntimeModifiable(key: String): Boolean external fun getConfigHeader(category: Int): String + + external fun getPairedSettingKey(key: String): String } diff --git a/src/android/app/src/main/jni/native_config.cpp b/src/android/app/src/main/jni/native_config.cpp index 6123b3d08..8a704960c 100644 --- a/src/android/app/src/main/jni/native_config.cpp +++ b/src/android/app/src/main/jni/native_config.cpp @@ -216,9 +216,22 @@ jboolean Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getIsRuntimeModifiable(JNIEn } jstring Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getConfigHeader(JNIEnv* env, jobject obj, - jint jcategory) { + jint jcategory) { auto category = static_cast(jcategory); return ToJString(env, Settings::TranslateCategory(category)); } +jstring Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getPairedSettingKey(JNIEnv* env, jobject obj, + jstring jkey) { + auto setting = getSetting(env, jkey); + if (setting == nullptr) { + return ToJString(env, ""); + } + if (setting->PairedSetting() == nullptr) { + return ToJString(env, ""); + } + + return ToJString(env, setting->PairedSetting()->GetLabel()); +} + } // extern "C"