android: Button to reset all settings
This commit is contained in:
parent
0f06e73a7c
commit
ee57aa83a4
21 changed files with 138 additions and 23 deletions
|
@ -32,5 +32,7 @@ enum class BooleanSetting(
|
|||
|
||||
fun from(key: String): BooleanSetting? =
|
||||
BooleanSetting.values().firstOrNull { it.key == key }
|
||||
|
||||
fun clear() = BooleanSetting.values().forEach { it.boolean = it.defaultValue }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,5 +30,7 @@ enum class FloatSetting(
|
|||
private val NOT_RUNTIME_EDITABLE = emptyList<FloatSetting>()
|
||||
|
||||
fun from(key: String): FloatSetting? = FloatSetting.values().firstOrNull { it.key == key }
|
||||
|
||||
fun clear() = FloatSetting.values().forEach { it.float = it.defaultValue }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -119,5 +119,7 @@ enum class IntSetting(
|
|||
)
|
||||
|
||||
fun from(key: String): IntSetting? = IntSetting.values().firstOrNull { it.key == key }
|
||||
|
||||
fun clear() = IntSetting.values().forEach { it.int = it.defaultValue }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.yuzu.yuzu_emu.features.settings.model
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
|
|
|
@ -31,5 +31,7 @@ enum class StringSetting(
|
|||
)
|
||||
|
||||
fun from(key: String): StringSetting? = StringSetting.values().firstOrNull { it.key == key }
|
||||
|
||||
fun clear() = StringSetting.values().forEach { it.string = it.defaultValue }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ import org.yuzu.yuzu_emu.features.settings.model.AbstractSetting
|
|||
class HeaderSetting(
|
||||
setting: AbstractSetting?,
|
||||
titleId: Int,
|
||||
descriptionId: Int?
|
||||
descriptionId: Int
|
||||
) : SettingsItem(setting, titleId, descriptionId) {
|
||||
override val type = TYPE_HEADER
|
||||
}
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.yuzu.yuzu_emu.features.settings.model.view
|
||||
|
||||
class RunnableSetting(
|
||||
titleId: Int,
|
||||
descriptionId: Int,
|
||||
val runnable: () -> Unit
|
||||
) : SettingsItem(null, titleId, descriptionId) {
|
||||
override val type = TYPE_RUNNABLE
|
||||
}
|
|
@ -16,7 +16,7 @@ import org.yuzu.yuzu_emu.features.settings.model.AbstractSetting
|
|||
abstract class SettingsItem(
|
||||
var setting: AbstractSetting?,
|
||||
val nameId: Int,
|
||||
val descriptionId: Int?
|
||||
val descriptionId: Int
|
||||
) {
|
||||
abstract val type: Int
|
||||
|
||||
|
@ -34,5 +34,6 @@ abstract class SettingsItem(
|
|||
const val TYPE_SUBMENU = 4
|
||||
const val TYPE_STRING_SINGLE_CHOICE = 5
|
||||
const val TYPE_DATETIME_SETTING = 6
|
||||
const val TYPE_RUNNABLE = 7
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,9 +6,6 @@ package org.yuzu.yuzu_emu.features.settings.model.view
|
|||
import org.yuzu.yuzu_emu.features.settings.model.AbstractBooleanSetting
|
||||
import org.yuzu.yuzu_emu.features.settings.model.AbstractIntSetting
|
||||
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.IntSetting
|
||||
import org.yuzu.yuzu_emu.utils.Log
|
||||
|
||||
class SwitchSetting(
|
||||
setting: AbstractSetting,
|
||||
|
|
|
@ -8,7 +8,6 @@ import android.content.Intent
|
|||
import android.os.Bundle
|
||||
import android.view.Menu
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Toast
|
||||
import androidx.activity.viewModels
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
|
@ -21,9 +20,15 @@ import com.google.android.material.color.MaterialColors
|
|||
import org.yuzu.yuzu_emu.NativeLibrary
|
||||
import org.yuzu.yuzu_emu.R
|
||||
import org.yuzu.yuzu_emu.databinding.ActivitySettingsBinding
|
||||
import org.yuzu.yuzu_emu.features.settings.model.BooleanSetting
|
||||
import org.yuzu.yuzu_emu.features.settings.model.FloatSetting
|
||||
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.model.SettingsViewModel
|
||||
import org.yuzu.yuzu_emu.features.settings.model.StringSetting
|
||||
import org.yuzu.yuzu_emu.features.settings.utils.SettingsFile
|
||||
import org.yuzu.yuzu_emu.utils.*
|
||||
import java.io.IOException
|
||||
|
||||
class SettingsActivity : AppCompatActivity(), SettingsActivityView {
|
||||
private val presenter = SettingsActivityPresenter(this)
|
||||
|
@ -165,6 +170,26 @@ class SettingsActivity : AppCompatActivity(), SettingsActivityView {
|
|||
presenter.onSettingChanged()
|
||||
}
|
||||
|
||||
fun onSettingsReset() {
|
||||
// Prevents saving to a non-existent settings file
|
||||
presenter.onSettingsReset()
|
||||
|
||||
// Reset the static memory representation of each setting
|
||||
BooleanSetting.clear()
|
||||
FloatSetting.clear()
|
||||
IntSetting.clear()
|
||||
StringSetting.clear()
|
||||
|
||||
// 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)
|
||||
if (!settingsFile.delete()) {
|
||||
throw IOException("Failed to delete $settingsFile")
|
||||
}
|
||||
|
||||
showToastMessage(getString(R.string.settings_reset), true)
|
||||
finish()
|
||||
}
|
||||
|
||||
private val settingsFragment: SettingsFragment?
|
||||
get() = supportFragmentManager.findFragmentByTag(FRAGMENT_TAG) as SettingsFragment?
|
||||
|
||||
|
|
|
@ -70,6 +70,10 @@ class SettingsActivityPresenter(private val activityView: SettingsActivityView)
|
|||
shouldSave = true
|
||||
}
|
||||
|
||||
fun onSettingsReset() {
|
||||
shouldSave = false
|
||||
}
|
||||
|
||||
fun saveState(outState: Bundle) {
|
||||
outState.putBoolean(KEY_SHOULD_SAVE, shouldSave)
|
||||
}
|
||||
|
|
|
@ -79,6 +79,10 @@ class SettingsAdapter(
|
|||
DateTimeViewHolder(ListItemSettingBinding.inflate(inflater), this)
|
||||
}
|
||||
|
||||
SettingsItem.TYPE_RUNNABLE -> {
|
||||
RunnableViewHolder(ListItemSettingBinding.inflate(inflater), this)
|
||||
}
|
||||
|
||||
else -> {
|
||||
// TODO: Create an error view since we can't return null now
|
||||
HeaderViewHolder(ListItemSettingsHeaderBinding.inflate(inflater), this)
|
||||
|
|
|
@ -6,8 +6,8 @@ package org.yuzu.yuzu_emu.features.settings.ui
|
|||
import android.content.SharedPreferences
|
||||
import android.os.Build
|
||||
import android.text.TextUtils
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.preference.PreferenceManager
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||
import org.yuzu.yuzu_emu.R
|
||||
import org.yuzu.yuzu_emu.YuzuApplication
|
||||
import org.yuzu.yuzu_emu.features.settings.model.AbstractBooleanSetting
|
||||
|
@ -26,7 +26,7 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
|
|||
private lateinit var gameId: String
|
||||
private var settingsList: ArrayList<SettingsItem>? = null
|
||||
|
||||
private val settingsActivity get() = fragmentView.activityView as AppCompatActivity
|
||||
private val settingsActivity get() = fragmentView.activityView as SettingsActivity
|
||||
private val settings get() = fragmentView.activityView!!.settings
|
||||
|
||||
private lateinit var preferences: SharedPreferences
|
||||
|
@ -111,6 +111,12 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
|
|||
Settings.SECTION_AUDIO
|
||||
)
|
||||
)
|
||||
add(
|
||||
RunnableSetting(
|
||||
R.string.reset_to_default,
|
||||
0
|
||||
) { resetSettings() }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -338,7 +344,9 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
|
|||
override var int: Int
|
||||
get() = preferences.getInt(Settings.PREF_THEME, 0)
|
||||
set(value) {
|
||||
preferences.edit().putInt(Settings.PREF_THEME, value).apply()
|
||||
preferences.edit()
|
||||
.putInt(Settings.PREF_THEME, value)
|
||||
.apply()
|
||||
settingsActivity.recreate()
|
||||
}
|
||||
override val key: String? = null
|
||||
|
@ -375,7 +383,9 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
|
|||
override var int: Int
|
||||
get() = preferences.getInt(Settings.PREF_THEME_MODE, -1)
|
||||
set(value) {
|
||||
preferences.edit().putInt(Settings.PREF_THEME_MODE, value).apply()
|
||||
preferences.edit()
|
||||
.putInt(Settings.PREF_THEME_MODE, value)
|
||||
.apply()
|
||||
ThemeHelper.setThemeMode(settingsActivity)
|
||||
}
|
||||
override val key: String? = null
|
||||
|
@ -400,14 +410,17 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
|
|||
override var boolean: Boolean
|
||||
get() = preferences.getBoolean(Settings.PREF_BLACK_BACKGROUNDS, false)
|
||||
set(value) {
|
||||
preferences.edit().putBoolean(Settings.PREF_BLACK_BACKGROUNDS, value).apply()
|
||||
preferences.edit()
|
||||
.putBoolean(Settings.PREF_BLACK_BACKGROUNDS, value)
|
||||
.apply()
|
||||
settingsActivity.recreate()
|
||||
}
|
||||
override val key: String? = null
|
||||
override val section: String? = null
|
||||
override val isRuntimeEditable: Boolean = false
|
||||
override val valueAsString: String
|
||||
get() = preferences.getBoolean(Settings.PREF_BLACK_BACKGROUNDS, false).toString()
|
||||
get() = preferences.getBoolean(Settings.PREF_BLACK_BACKGROUNDS, false)
|
||||
.toString()
|
||||
override val defaultValue: Any = false
|
||||
}
|
||||
|
||||
|
@ -420,4 +433,15 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun resetSettings() {
|
||||
MaterialAlertDialogBuilder(settingsActivity)
|
||||
.setTitle(R.string.reset_all_settings)
|
||||
.setMessage(R.string.reset_all_settings_description)
|
||||
.setPositiveButton(android.R.string.ok) { _, _ ->
|
||||
settingsActivity.onSettingsReset()
|
||||
}
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.show()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ class DateTimeViewHolder(val binding: ListItemSettingBinding, adapter: SettingsA
|
|||
override fun bind(item: SettingsItem) {
|
||||
setting = item as DateTimeSetting
|
||||
binding.textSettingName.setText(item.nameId)
|
||||
if (item.descriptionId!! > 0) {
|
||||
if (item.descriptionId != 0) {
|
||||
binding.textSettingDescription.setText(item.descriptionId)
|
||||
binding.textSettingDescription.visibility = View.VISIBLE
|
||||
} else {
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
package org.yuzu.yuzu_emu.features.settings.ui.viewholder
|
||||
|
||||
import android.view.View
|
||||
import org.yuzu.yuzu_emu.databinding.ListItemSettingBinding
|
||||
import org.yuzu.yuzu_emu.features.settings.model.view.RunnableSetting
|
||||
import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem
|
||||
import org.yuzu.yuzu_emu.features.settings.ui.SettingsAdapter
|
||||
|
||||
class RunnableViewHolder(val binding: ListItemSettingBinding, adapter: SettingsAdapter) :
|
||||
SettingViewHolder(binding.root, adapter) {
|
||||
private lateinit var setting: RunnableSetting
|
||||
|
||||
override fun bind(item: SettingsItem) {
|
||||
setting = item as RunnableSetting
|
||||
binding.textSettingName.setText(item.nameId)
|
||||
if (item.descriptionId != 0) {
|
||||
binding.textSettingDescription.setText(item.descriptionId)
|
||||
binding.textSettingDescription.visibility = View.VISIBLE
|
||||
} else {
|
||||
binding.textSettingDescription.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
override fun onClick(clicked: View) {
|
||||
setting.runnable.invoke()
|
||||
}
|
||||
|
||||
override fun onLongClick(clicked: View): Boolean {
|
||||
// no-op
|
||||
return true
|
||||
}
|
||||
}
|
|
@ -18,7 +18,7 @@ class SingleChoiceViewHolder(val binding: ListItemSettingBinding, adapter: Setti
|
|||
setting = item
|
||||
binding.textSettingName.setText(item.nameId)
|
||||
binding.textSettingDescription.visibility = View.VISIBLE
|
||||
if (item.descriptionId!! > 0) {
|
||||
if (item.descriptionId != 0) {
|
||||
binding.textSettingDescription.setText(item.descriptionId)
|
||||
} else if (item is SingleChoiceSetting) {
|
||||
val resMgr = binding.textSettingDescription.context.resources
|
||||
|
|
|
@ -16,7 +16,7 @@ class SliderViewHolder(val binding: ListItemSettingBinding, adapter: SettingsAda
|
|||
override fun bind(item: SettingsItem) {
|
||||
setting = item as SliderSetting
|
||||
binding.textSettingName.setText(item.nameId)
|
||||
if (item.descriptionId!! > 0) {
|
||||
if (item.descriptionId != 0) {
|
||||
binding.textSettingDescription.setText(item.descriptionId)
|
||||
binding.textSettingDescription.visibility = View.VISIBLE
|
||||
} else {
|
||||
|
|
|
@ -16,7 +16,7 @@ class SubmenuViewHolder(val binding: ListItemSettingBinding, adapter: SettingsAd
|
|||
override fun bind(item: SettingsItem) {
|
||||
this.item = item as SubmenuSetting
|
||||
binding.textSettingName.setText(item.nameId)
|
||||
if (item.descriptionId!! > 0) {
|
||||
if (item.descriptionId != 0) {
|
||||
binding.textSettingDescription.setText(item.descriptionId)
|
||||
binding.textSettingDescription.visibility = View.VISIBLE
|
||||
} else {
|
||||
|
|
|
@ -18,7 +18,7 @@ class SwitchSettingViewHolder(val binding: ListItemSettingSwitchBinding, adapter
|
|||
override fun bind(item: SettingsItem) {
|
||||
setting = item as SwitchSetting
|
||||
binding.textSettingName.setText(item.nameId)
|
||||
if (item.descriptionId!! > 0) {
|
||||
if (item.descriptionId != 0) {
|
||||
binding.textSettingDescription.setText(item.descriptionId)
|
||||
binding.textSettingDescription.visibility = View.VISIBLE
|
||||
} else {
|
||||
|
|
|
@ -22,7 +22,7 @@ import java.util.*
|
|||
object SettingsFile {
|
||||
const val FILE_NAME_CONFIG = "config"
|
||||
|
||||
private val sectionsMap = BiMap<String?, String?>()
|
||||
private var sectionsMap = BiMap<String?, String?>()
|
||||
|
||||
/**
|
||||
* Reads a given .ini file from disk and returns it as a HashMap of Settings, themselves
|
||||
|
@ -154,7 +154,7 @@ object SettingsFile {
|
|||
} else generalSectionName
|
||||
}
|
||||
|
||||
private fun getSettingsFile(fileName: String): File {
|
||||
fun getSettingsFile(fileName: String): File {
|
||||
return File(
|
||||
DirectoryInitialization.userDirectory + "/config/" + fileName + ".ini"
|
||||
)
|
||||
|
@ -182,13 +182,11 @@ object SettingsFile {
|
|||
private fun settingFromLine(line: String): AbstractSetting? {
|
||||
val splitLine = line.split("=".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
|
||||
if (splitLine.size != 2) {
|
||||
Log.warning("Skipping invalid config line \"$line\"")
|
||||
return null
|
||||
}
|
||||
val key = splitLine[0].trim { it <= ' ' }
|
||||
val value = splitLine[1].trim { it <= ' ' }
|
||||
if (value.isEmpty()) {
|
||||
Log.warning("Skipping null value in config line \"$line\"")
|
||||
return null
|
||||
}
|
||||
|
||||
|
@ -216,7 +214,7 @@ object SettingsFile {
|
|||
return stringSetting
|
||||
}
|
||||
|
||||
return StringSetting.from(key)
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -143,8 +143,12 @@
|
|||
<string name="ini_saved">Saved settings</string>
|
||||
<string name="gameid_saved">Saved settings for %1$s</string>
|
||||
<string name="error_saving">Error saving %1$s.ini: %2$s</string>
|
||||
<string name="loading">Loading...</string>
|
||||
<string name="loading">Loading…</string>
|
||||
<string name="reset_setting_confirmation">Do you want to reset this setting back to its default value?</string>
|
||||
<string name="reset_to_default">Reset to default</string>
|
||||
<string name="reset_all_settings">Reset all settings?</string>
|
||||
<string name="reset_all_settings_description">All Advanced Settings will be reset to their default configuration. This can not be undone.</string>
|
||||
<string name="settings_reset">Settings reset</string>
|
||||
|
||||
<!-- GPU driver installation -->
|
||||
<string name="select_gpu_driver">Select GPU driver</string>
|
||||
|
|
Loading…
Reference in a new issue