android: Migrate theme settings to ini
This commit is contained in:
		| @@ -18,7 +18,8 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting { | ||||
|     RENDERER_REACTIVE_FLUSHING("use_reactive_flushing"), | ||||
|     RENDERER_DEBUG("debug"), | ||||
|     PICTURE_IN_PICTURE("picture_in_picture"), | ||||
|     USE_CUSTOM_RTC("custom_rtc_enabled"); | ||||
|     USE_CUSTOM_RTC("custom_rtc_enabled"), | ||||
|     BLACK_BACKGROUNDS("black_backgrounds"); | ||||
|  | ||||
|     override fun getBoolean(needsGlobal: Boolean): Boolean = | ||||
|         NativeConfig.getBoolean(key, needsGlobal) | ||||
|   | ||||
| @@ -19,7 +19,9 @@ enum class IntSetting(override val key: String) : AbstractIntSetting { | ||||
|     RENDERER_SCREEN_LAYOUT("screen_layout"), | ||||
|     RENDERER_ASPECT_RATIO("aspect_ratio"), | ||||
|     AUDIO_OUTPUT_ENGINE("output_engine"), | ||||
|     MAX_ANISOTROPY("max_anisotropy"); | ||||
|     MAX_ANISOTROPY("max_anisotropy"), | ||||
|     THEME("theme"), | ||||
|     THEME_MODE("theme_mode"); | ||||
|  | ||||
|     override fun getInt(needsGlobal: Boolean): Int = NativeConfig.getInt(key, needsGlobal) | ||||
|  | ||||
|   | ||||
| @@ -54,6 +54,7 @@ object Settings { | ||||
|     const val PREF_MENU_SETTINGS_SHOW_FPS = "EmulationMenuSettings_ShowFps" | ||||
|     const val PREF_MENU_SETTINGS_SHOW_OVERLAY = "EmulationMenuSettings_ShowOverlay" | ||||
|  | ||||
|     // Deprecated theme preference keys | ||||
|     const val PREF_FIRST_APP_LAUNCH = "FirstApplicationLaunch" | ||||
|     const val PREF_THEME = "Theme" | ||||
|     const val PREF_THEME_MODE = "ThemeMode" | ||||
|   | ||||
| @@ -3,10 +3,8 @@ | ||||
|  | ||||
| package org.yuzu.yuzu_emu.features.settings.ui | ||||
|  | ||||
| import android.content.SharedPreferences | ||||
| import android.os.Build | ||||
| import android.widget.Toast | ||||
| import androidx.preference.PreferenceManager | ||||
| import org.yuzu.yuzu_emu.NativeLibrary | ||||
| import org.yuzu.yuzu_emu.R | ||||
| import org.yuzu.yuzu_emu.YuzuApplication | ||||
| @@ -29,9 +27,6 @@ class SettingsFragmentPresenter( | ||||
| ) { | ||||
|     private var settingsList = ArrayList<SettingsItem>() | ||||
|  | ||||
|     private val preferences: SharedPreferences | ||||
|         get() = PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext) | ||||
|  | ||||
|     // Extension for altering settings list based on each setting's properties | ||||
|     fun ArrayList<SettingsItem>.add(key: String) { | ||||
|         val item = SettingsItem.settingsItems[key]!! | ||||
| @@ -170,25 +165,19 @@ class SettingsFragmentPresenter( | ||||
|     private fun addThemeSettings(sl: ArrayList<SettingsItem>) { | ||||
|         sl.apply { | ||||
|             val theme: AbstractIntSetting = object : AbstractIntSetting { | ||||
|                 override fun getInt(needsGlobal: Boolean): Int = | ||||
|                     preferences.getInt(Settings.PREF_THEME, 0) | ||||
|  | ||||
|                 override fun getInt(needsGlobal: Boolean): Int = IntSetting.THEME.getInt() | ||||
|                 override fun setInt(value: Int) { | ||||
|                     preferences.edit() | ||||
|                         .putInt(Settings.PREF_THEME, value) | ||||
|                         .apply() | ||||
|                     IntSetting.THEME.setInt(value) | ||||
|                     settingsViewModel.setShouldRecreate(true) | ||||
|                 } | ||||
|  | ||||
|                 override val key: String = Settings.PREF_THEME | ||||
|                 override val isRuntimeModifiable: Boolean = false | ||||
|                 override fun getValueAsString(needsGlobal: Boolean): String = getInt().toString() | ||||
|                 override val defaultValue: Int = 0 | ||||
|                 override fun reset() { | ||||
|                     preferences.edit() | ||||
|                         .putInt(Settings.PREF_THEME, defaultValue) | ||||
|                         .apply() | ||||
|                 } | ||||
|                 override val key: String = IntSetting.THEME.key | ||||
|                 override val isRuntimeModifiable: Boolean = IntSetting.THEME.isRuntimeModifiable | ||||
|                 override fun getValueAsString(needsGlobal: Boolean): String = | ||||
|                     IntSetting.THEME.getValueAsString() | ||||
|  | ||||
|                 override val defaultValue: Int = IntSetting.THEME.defaultValue | ||||
|                 override fun reset() = IntSetting.THEME.setInt(defaultValue) | ||||
|             } | ||||
|  | ||||
|             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { | ||||
| @@ -214,24 +203,22 @@ class SettingsFragmentPresenter( | ||||
|             } | ||||
|  | ||||
|             val themeMode: AbstractIntSetting = object : AbstractIntSetting { | ||||
|                 override fun getInt(needsGlobal: Boolean): Int = | ||||
|                     preferences.getInt(Settings.PREF_THEME_MODE, -1) | ||||
|  | ||||
|                 override fun getInt(needsGlobal: Boolean): Int = IntSetting.THEME_MODE.getInt() | ||||
|                 override fun setInt(value: Int) { | ||||
|                     preferences.edit() | ||||
|                         .putInt(Settings.PREF_THEME_MODE, value) | ||||
|                         .apply() | ||||
|                     IntSetting.THEME_MODE.setInt(value) | ||||
|                     settingsViewModel.setShouldRecreate(true) | ||||
|                 } | ||||
|  | ||||
|                 override val key: String = Settings.PREF_THEME_MODE | ||||
|                 override val isRuntimeModifiable: Boolean = false | ||||
|                 override fun getValueAsString(needsGlobal: Boolean): String = getInt().toString() | ||||
|                 override val defaultValue: Int = -1 | ||||
|                 override val key: String = IntSetting.THEME_MODE.key | ||||
|                 override val isRuntimeModifiable: Boolean = | ||||
|                     IntSetting.THEME_MODE.isRuntimeModifiable | ||||
|  | ||||
|                 override fun getValueAsString(needsGlobal: Boolean): String = | ||||
|                     IntSetting.THEME_MODE.getValueAsString() | ||||
|  | ||||
|                 override val defaultValue: Int = IntSetting.THEME_MODE.defaultValue | ||||
|                 override fun reset() { | ||||
|                     preferences.edit() | ||||
|                         .putInt(Settings.PREF_BLACK_BACKGROUNDS, defaultValue) | ||||
|                         .apply() | ||||
|                     IntSetting.THEME_MODE.setInt(defaultValue) | ||||
|                     settingsViewModel.setShouldRecreate(true) | ||||
|                 } | ||||
|             } | ||||
| @@ -248,25 +235,24 @@ class SettingsFragmentPresenter( | ||||
|  | ||||
|             val blackBackgrounds: AbstractBooleanSetting = object : AbstractBooleanSetting { | ||||
|                 override fun getBoolean(needsGlobal: Boolean): Boolean = | ||||
|                     preferences.getBoolean(Settings.PREF_BLACK_BACKGROUNDS, false) | ||||
|                     BooleanSetting.BLACK_BACKGROUNDS.getBoolean() | ||||
|  | ||||
|                 override fun setBoolean(value: Boolean) { | ||||
|                     preferences.edit() | ||||
|                         .putBoolean(Settings.PREF_BLACK_BACKGROUNDS, value) | ||||
|                         .apply() | ||||
|                     BooleanSetting.BLACK_BACKGROUNDS.setBoolean(value) | ||||
|                     settingsViewModel.setShouldRecreate(true) | ||||
|                 } | ||||
|  | ||||
|                 override val key: String = Settings.PREF_BLACK_BACKGROUNDS | ||||
|                 override val isRuntimeModifiable: Boolean = false | ||||
|                 override fun getValueAsString(needsGlobal: Boolean): String = | ||||
|                     getBoolean().toString() | ||||
|                 override val key: String = BooleanSetting.BLACK_BACKGROUNDS.key | ||||
|                 override val isRuntimeModifiable: Boolean = | ||||
|                     BooleanSetting.BLACK_BACKGROUNDS.isRuntimeModifiable | ||||
|  | ||||
|                 override val defaultValue: Boolean = false | ||||
|                 override fun getValueAsString(needsGlobal: Boolean): String = | ||||
|                     BooleanSetting.BLACK_BACKGROUNDS.getValueAsString() | ||||
|  | ||||
|                 override val defaultValue: Boolean = BooleanSetting.BLACK_BACKGROUNDS.defaultValue | ||||
|                 override fun reset() { | ||||
|                     preferences.edit() | ||||
|                         .putBoolean(Settings.PREF_BLACK_BACKGROUNDS, defaultValue) | ||||
|                         .apply() | ||||
|                     BooleanSetting.BLACK_BACKGROUNDS | ||||
|                         .setBoolean(BooleanSetting.BLACK_BACKGROUNDS.defaultValue) | ||||
|                     settingsViewModel.setShouldRecreate(true) | ||||
|                 } | ||||
|             } | ||||
|   | ||||
| @@ -3,9 +3,14 @@ | ||||
|  | ||||
| package org.yuzu.yuzu_emu.utils | ||||
|  | ||||
| import androidx.preference.PreferenceManager | ||||
| import java.io.IOException | ||||
| import org.yuzu.yuzu_emu.NativeLibrary | ||||
| import org.yuzu.yuzu_emu.YuzuApplication | ||||
| import org.yuzu.yuzu_emu.features.settings.model.BooleanSetting | ||||
| import org.yuzu.yuzu_emu.features.settings.model.IntSetting | ||||
| import org.yuzu.yuzu_emu.features.settings.model.Settings | ||||
| import org.yuzu.yuzu_emu.utils.PreferenceUtil.migratePreference | ||||
|  | ||||
| object DirectoryInitialization { | ||||
|     private var userPath: String? = null | ||||
| @@ -17,6 +22,7 @@ object DirectoryInitialization { | ||||
|             initializeInternalStorage() | ||||
|             NativeLibrary.initializeSystem(false) | ||||
|             NativeConfig.initializeGlobalConfig() | ||||
|             migrateSettings() | ||||
|             areDirectoriesReady = true | ||||
|         } | ||||
|     } | ||||
| @@ -35,4 +41,31 @@ object DirectoryInitialization { | ||||
|             e.printStackTrace() | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private fun migrateSettings() { | ||||
|         val preferences = PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext) | ||||
|         var saveConfig = false | ||||
|         val theme = preferences.migratePreference<Int>(Settings.PREF_THEME) | ||||
|         if (theme != null) { | ||||
|             IntSetting.THEME.setInt(theme) | ||||
|             saveConfig = true | ||||
|         } | ||||
|  | ||||
|         val themeMode = preferences.migratePreference<Int>(Settings.PREF_THEME_MODE) | ||||
|         if (themeMode != null) { | ||||
|             IntSetting.THEME_MODE.setInt(themeMode) | ||||
|             saveConfig = true | ||||
|         } | ||||
|  | ||||
|         val blackBackgrounds = | ||||
|             preferences.migratePreference<Boolean>(Settings.PREF_BLACK_BACKGROUNDS) | ||||
|         if (blackBackgrounds != null) { | ||||
|             BooleanSetting.BLACK_BACKGROUNDS.setBoolean(blackBackgrounds) | ||||
|             saveConfig = true | ||||
|         } | ||||
|  | ||||
|         if (saveConfig) { | ||||
|             NativeConfig.saveGlobalConfig() | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -0,0 +1,37 @@ | ||||
| // SPDX-FileCopyrightText: 2023 yuzu Emulator Project | ||||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||||
|  | ||||
| package org.yuzu.yuzu_emu.utils | ||||
|  | ||||
| import android.content.SharedPreferences | ||||
|  | ||||
| object PreferenceUtil { | ||||
|     /** | ||||
|      * Retrieves a shared preference value and then deletes the value in storage. | ||||
|      * @param key Associated key for the value in this preferences instance | ||||
|      * @return Typed value associated with [key]. Null if no such key exists. | ||||
|      */ | ||||
|     inline fun <reified T> SharedPreferences.migratePreference(key: String): T? { | ||||
|         if (!this.contains(key)) { | ||||
|             return null | ||||
|         } | ||||
|  | ||||
|         val value: Any = when (T::class) { | ||||
|             String::class -> this.getString(key, "")!! | ||||
|  | ||||
|             Boolean::class -> this.getBoolean(key, false) | ||||
|  | ||||
|             Int::class -> this.getInt(key, 0) | ||||
|  | ||||
|             Float::class -> this.getFloat(key, 0f) | ||||
|  | ||||
|             Long::class -> this.getLong(key, 0) | ||||
|  | ||||
|             else -> throw IllegalStateException("Tried to migrate preference with invalid type!") | ||||
|         } | ||||
|         deletePreference(key) | ||||
|         return value as T | ||||
|     } | ||||
|  | ||||
|     fun SharedPreferences.deletePreference(key: String) = this.edit().remove(key).apply() | ||||
| } | ||||
| @@ -10,33 +10,26 @@ import androidx.appcompat.app.AppCompatActivity | ||||
| import androidx.appcompat.app.AppCompatDelegate | ||||
| import androidx.core.view.WindowCompat | ||||
| import androidx.core.view.WindowInsetsControllerCompat | ||||
| import androidx.preference.PreferenceManager | ||||
| import kotlin.math.roundToInt | ||||
| import org.yuzu.yuzu_emu.R | ||||
| import org.yuzu.yuzu_emu.YuzuApplication | ||||
| import org.yuzu.yuzu_emu.features.settings.model.Settings | ||||
| import org.yuzu.yuzu_emu.features.settings.model.BooleanSetting | ||||
| import org.yuzu.yuzu_emu.features.settings.model.IntSetting | ||||
| import org.yuzu.yuzu_emu.ui.main.ThemeProvider | ||||
|  | ||||
| object ThemeHelper { | ||||
|     const val SYSTEM_BAR_ALPHA = 0.9f | ||||
|  | ||||
|     private const val DEFAULT = 0 | ||||
|     private const val MATERIAL_YOU = 1 | ||||
|  | ||||
|     fun setTheme(activity: AppCompatActivity) { | ||||
|         val preferences = PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext) | ||||
|         setThemeMode(activity) | ||||
|         when (preferences.getInt(Settings.PREF_THEME, 0)) { | ||||
|             DEFAULT -> activity.setTheme(R.style.Theme_Yuzu_Main) | ||||
|             MATERIAL_YOU -> activity.setTheme(R.style.Theme_Yuzu_Main_MaterialYou) | ||||
|         when (Theme.from(IntSetting.THEME.getInt())) { | ||||
|             Theme.Default -> activity.setTheme(R.style.Theme_Yuzu_Main) | ||||
|             Theme.MaterialYou -> activity.setTheme(R.style.Theme_Yuzu_Main_MaterialYou) | ||||
|         } | ||||
|  | ||||
|         // Using a specific night mode check because this could apply incorrectly when using the | ||||
|         // light app mode, dark system mode, and black backgrounds. Launching the settings activity | ||||
|         // will then show light mode colors/navigation bars but with black backgrounds. | ||||
|         if (preferences.getBoolean(Settings.PREF_BLACK_BACKGROUNDS, false) && | ||||
|             isNightMode(activity) | ||||
|         ) { | ||||
|         if (BooleanSetting.BLACK_BACKGROUNDS.getBoolean() && isNightMode(activity)) { | ||||
|             activity.setTheme(R.style.ThemeOverlay_Yuzu_Dark) | ||||
|         } | ||||
|     } | ||||
| @@ -60,8 +53,7 @@ object ThemeHelper { | ||||
|     } | ||||
|  | ||||
|     fun setThemeMode(activity: AppCompatActivity) { | ||||
|         val themeMode = PreferenceManager.getDefaultSharedPreferences(activity.applicationContext) | ||||
|             .getInt(Settings.PREF_THEME_MODE, AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM) | ||||
|         val themeMode = IntSetting.THEME_MODE.getInt() | ||||
|         activity.delegate.localNightMode = themeMode | ||||
|         val windowController = WindowCompat.getInsetsController( | ||||
|             activity.window, | ||||
| @@ -95,3 +87,12 @@ object ThemeHelper { | ||||
|         windowController.isAppearanceLightNavigationBars = false | ||||
|     } | ||||
| } | ||||
|  | ||||
| enum class Theme(val int: Int) { | ||||
|     Default(0), | ||||
|     MaterialYou(1); | ||||
|  | ||||
|     companion object { | ||||
|         fun from(int: Int): Theme = entries.firstOrNull { it.int == int } ?: Default | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -33,6 +33,11 @@ struct Values { | ||||
|  | ||||
|     Settings::SwitchableSetting<std::string, false> driver_path{linkage, "", "driver_path", | ||||
|                                                                 Settings::Category::GpuDriver}; | ||||
|  | ||||
|     Settings::Setting<s32> theme{linkage, 0, "theme", Settings::Category::Android}; | ||||
|     Settings::Setting<s32> theme_mode{linkage, -1, "theme_mode", Settings::Category::Android}; | ||||
|     Settings::Setting<bool> black_backgrounds{linkage, false, "black_backgrounds", | ||||
|                                               Settings::Category::Android}; | ||||
| }; | ||||
|  | ||||
| extern Values values; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 t895
					t895