1
0
Fork 0
forked from suyu/suyu

android: Add theme picker

This commit is contained in:
Charles Lombardo 2023-04-20 17:44:19 -04:00 committed by bunnei
parent 5b26ac9293
commit f0ba58f5aa
7 changed files with 127 additions and 3 deletions

View file

@ -107,6 +107,7 @@ class Settings {
const val SECTION_RENDERER = "Renderer" const val SECTION_RENDERER = "Renderer"
const val SECTION_AUDIO = "Audio" const val SECTION_AUDIO = "Audio"
const val SECTION_CPU = "Cpu" const val SECTION_CPU = "Cpu"
const val SECTION_THEME = "Theme"
const val PREF_OVERLAY_INIT = "OverlayInit" const val PREF_OVERLAY_INIT = "OverlayInit"
const val PREF_CONTROL_SCALE = "controlScale" const val PREF_CONTROL_SCALE = "controlScale"
@ -134,6 +135,7 @@ class Settings {
const val PREF_MENU_SETTINGS_SHOW_OVERLAY = "EmulationMenuSettings_ShowOverlay" const val PREF_MENU_SETTINGS_SHOW_OVERLAY = "EmulationMenuSettings_ShowOverlay"
const val PREF_FIRST_APP_LAUNCH = "FirstApplicationLaunch" const val PREF_FIRST_APP_LAUNCH = "FirstApplicationLaunch"
const val PREF_THEME = "Theme"
private val configFileSectionsMap: MutableMap<String, List<String>> = HashMap() private val configFileSectionsMap: MutableMap<String, List<String>> = HashMap()

View file

@ -3,11 +3,15 @@
package org.yuzu.yuzu_emu.features.settings.ui package org.yuzu.yuzu_emu.features.settings.ui
import android.content.SharedPreferences
import android.os.Build
import android.text.TextUtils import android.text.TextUtils
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.preference.PreferenceManager
import org.yuzu.yuzu_emu.R import org.yuzu.yuzu_emu.R
import org.yuzu.yuzu_emu.YuzuApplication
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.AbstractSetting
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.IntSetting
import org.yuzu.yuzu_emu.features.settings.model.Settings import org.yuzu.yuzu_emu.features.settings.model.Settings
import org.yuzu.yuzu_emu.features.settings.model.view.* import org.yuzu.yuzu_emu.features.settings.model.view.*
@ -21,12 +25,15 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
private val settingsActivity get() = fragmentView.activityView as AppCompatActivity private val settingsActivity get() = fragmentView.activityView as AppCompatActivity
private val settings get() = fragmentView.activityView!!.settings private val settings get() = fragmentView.activityView!!.settings
private lateinit var preferences: SharedPreferences
fun onCreate(menuTag: String, gameId: String) { fun onCreate(menuTag: String, gameId: String) {
this.gameId = gameId this.gameId = gameId
this.menuTag = menuTag this.menuTag = menuTag
} }
fun onViewCreated() { fun onViewCreated() {
preferences = PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext)
loadSettingsList() loadSettingsList()
} }
@ -55,6 +62,7 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
Settings.SECTION_SYSTEM -> addSystemSettings(sl) Settings.SECTION_SYSTEM -> addSystemSettings(sl)
Settings.SECTION_RENDERER -> addGraphicsSettings(sl) Settings.SECTION_RENDERER -> addGraphicsSettings(sl)
Settings.SECTION_AUDIO -> addAudioSettings(sl) Settings.SECTION_AUDIO -> addAudioSettings(sl)
Settings.SECTION_THEME -> addThemeSettings(sl)
else -> { else -> {
fragmentView.showToastMessage("Unimplemented menu", false) fragmentView.showToastMessage("Unimplemented menu", false)
return return
@ -99,6 +107,14 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
Settings.SECTION_AUDIO Settings.SECTION_AUDIO
) )
) )
add(
SubmenuSetting(
null,
R.string.preferences_theme,
0,
Settings.SECTION_THEME
)
)
} }
} }
@ -300,4 +316,45 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
) )
) )
} }
private fun addThemeSettings(sl: ArrayList<SettingsItem>) {
settingsActivity.setTitle(R.string.preferences_theme)
sl.apply {
val theme: AbstractIntSetting = object : AbstractIntSetting {
override var int: Int
get() = preferences.getInt(Settings.PREF_THEME, 0)
set(value) {
preferences.edit().putInt(Settings.PREF_THEME, value).apply()
settingsActivity.recreate()
}
override val key: String? = null
override val section: String? = null
override val isRuntimeEditable: Boolean = true
override val valueAsString: String
get() = preferences.getInt(Settings.PREF_THEME, 0).toString()
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
add(
SingleChoiceSetting(
theme,
R.string.change_app_theme,
0,
R.array.themeEntriesA12,
R.array.themeValuesA12
)
)
} else {
add(
SingleChoiceSetting(
theme,
R.string.change_app_theme,
0,
R.array.themeEntries,
R.array.themeValues
)
)
}
}
}
} }

View file

@ -39,12 +39,14 @@ import org.yuzu.yuzu_emu.model.HomeViewModel
import org.yuzu.yuzu_emu.utils.* import org.yuzu.yuzu_emu.utils.*
import java.io.IOException import java.io.IOException
class MainActivity : AppCompatActivity() { class MainActivity : AppCompatActivity(), ThemeProvider {
private lateinit var binding: ActivityMainBinding private lateinit var binding: ActivityMainBinding
private val homeViewModel: HomeViewModel by viewModels() private val homeViewModel: HomeViewModel by viewModels()
private val gamesViewModel: GamesViewModel by viewModels() private val gamesViewModel: GamesViewModel by viewModels()
override var themeId: Int = 0
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
val splashScreen = installSplashScreen() val splashScreen = installSplashScreen()
splashScreen.setKeepOnScreenCondition { !DirectoryInitialization.areDirectoriesReady } splashScreen.setKeepOnScreenCondition { !DirectoryInitialization.areDirectoriesReady }
@ -166,6 +168,11 @@ class MainActivity : AppCompatActivity() {
}.start() }.start()
} }
override fun onResume() {
ThemeHelper.setCorrectTheme(this)
super.onResume()
}
override fun onDestroy() { override fun onDestroy() {
EmulationActivity.tryDismissRunningNotification(this) EmulationActivity.tryDismissRunningNotification(this)
super.onDestroy() super.onDestroy()
@ -180,6 +187,11 @@ class MainActivity : AppCompatActivity() {
windowInsets windowInsets
} }
override fun setTheme(resId: Int) {
super.setTheme(resId)
themeId = resId
}
private fun hasExtension(path: String, extension: String): Boolean { private fun hasExtension(path: String, extension: String): Boolean {
return path.substring(path.lastIndexOf(".") + 1).contains(extension) return path.substring(path.lastIndexOf(".") + 1).contains(extension)
} }

View file

@ -0,0 +1,11 @@
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
package org.yuzu.yuzu_emu.ui.main
interface ThemeProvider {
/**
* Provides theme ID by overriding an activity's 'setTheme' method and returning that result
*/
var themeId: Int
}

View file

@ -10,15 +10,27 @@ import androidx.annotation.ColorInt
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.core.view.WindowCompat import androidx.core.view.WindowCompat
import com.google.android.material.color.MaterialColors import androidx.preference.PreferenceManager
import org.yuzu.yuzu_emu.R 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.ui.main.ThemeProvider
import kotlin.math.roundToInt import kotlin.math.roundToInt
object ThemeHelper { object ThemeHelper {
const val SYSTEM_BAR_ALPHA = 0.9f const val SYSTEM_BAR_ALPHA = 0.9f
private const val DEFAULT = 0
private const val MATERIAL_YOU = 1
@JvmStatic @JvmStatic
fun setTheme(activity: AppCompatActivity) { fun setTheme(activity: AppCompatActivity) {
val preferences = PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext)
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)
}
val windowController = WindowCompat.getInsetsController( val windowController = WindowCompat.getInsetsController(
activity.window, activity.window,
activity.window.decorView activity.window.decorView
@ -60,4 +72,12 @@ object ThemeHelper {
Color.green(color), Color.blue(color) Color.green(color), Color.blue(color)
) )
} }
fun setCorrectTheme(activity: AppCompatActivity) {
val currentTheme = (activity as ThemeProvider).themeId
setTheme(activity)
if (currentTheme != (activity as ThemeProvider).themeId) {
activity.recreate()
}
}
} }

View file

@ -183,4 +183,20 @@
<item>@string/gamepad_screenshot</item> <item>@string/gamepad_screenshot</item>
</string-array> </string-array>
<string-array name="themeEntries">
<item>@string/theme_default</item>
</string-array>
<integer-array name="themeValues">
<item>0</item>
</integer-array>
<string-array name="themeEntriesA12">
<item>@string/theme_default</item>
<item>@string/theme_material_you</item>
</string-array>
<integer-array name="themeValuesA12">
<item>0</item>
<item>1</item>
</integer-array>
</resources> </resources>

View file

@ -103,6 +103,7 @@
<string name="preferences_system">System</string> <string name="preferences_system">System</string>
<string name="preferences_graphics">Graphics</string> <string name="preferences_graphics">Graphics</string>
<string name="preferences_audio">Audio</string> <string name="preferences_audio">Audio</string>
<string name="preferences_theme">Theme and Color</string>
<!-- ROM loading errors --> <!-- ROM loading errors -->
<string name="loader_error_encrypted">Your ROM is encrypted</string> <string name="loader_error_encrypted">Your ROM is encrypted</string>
@ -229,4 +230,9 @@
<string name="preparing_shaders">Preparing shaders</string> <string name="preparing_shaders">Preparing shaders</string>
<string name="building_shaders">Building shaders</string> <string name="building_shaders">Building shaders</string>
<!-- Theme options -->
<string name="change_app_theme">Change App Theme</string>
<string name="theme_default">Default</string>
<string name="theme_material_you">Material You</string>
</resources> </resources>