mirror of
https://git.suyu.dev/suyu/suyu
synced 2024-12-25 19:02:45 -06:00
android: Add theme picker
This commit is contained in:
parent
5b26ac9293
commit
f0ba58f5aa
7 changed files with 127 additions and 3 deletions
|
@ -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()
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
|
@ -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()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
Loading…
Reference in a new issue