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