summaryrefslogtreecommitdiff
path: root/src/android
diff options
context:
space:
mode:
authorGravatar Charles Lombardo2023-04-20 17:44:19 -0400
committerGravatar bunnei2023-06-03 00:05:54 -0700
commitf0ba58f5aa3524a2f97b268dfd7578ba3ef433bc (patch)
tree3a291344242151e6f2d26c8c9983fa47eaef5f28 /src/android
parentandroid: Prevent potential abstract settings crash (diff)
downloadyuzu-f0ba58f5aa3524a2f97b268dfd7578ba3ef433bc.tar.gz
yuzu-f0ba58f5aa3524a2f97b268dfd7578ba3ef433bc.tar.xz
yuzu-f0ba58f5aa3524a2f97b268dfd7578ba3ef433bc.zip
android: Add theme picker
Diffstat (limited to 'src/android')
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/Settings.kt2
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt59
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt14
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/ThemeProvider.kt11
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/ThemeHelper.kt22
-rw-r--r--src/android/app/src/main/res/values/arrays.xml16
-rw-r--r--src/android/app/src/main/res/values/strings.xml6
7 files changed, 127 insertions, 3 deletions
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/Settings.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/Settings.kt
index 610f281b2..b00110e91 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/Settings.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/Settings.kt
@@ -107,6 +107,7 @@ class Settings {
107 const val SECTION_RENDERER = "Renderer" 107 const val SECTION_RENDERER = "Renderer"
108 const val SECTION_AUDIO = "Audio" 108 const val SECTION_AUDIO = "Audio"
109 const val SECTION_CPU = "Cpu" 109 const val SECTION_CPU = "Cpu"
110 const val SECTION_THEME = "Theme"
110 111
111 const val PREF_OVERLAY_INIT = "OverlayInit" 112 const val PREF_OVERLAY_INIT = "OverlayInit"
112 const val PREF_CONTROL_SCALE = "controlScale" 113 const val PREF_CONTROL_SCALE = "controlScale"
@@ -134,6 +135,7 @@ class Settings {
134 const val PREF_MENU_SETTINGS_SHOW_OVERLAY = "EmulationMenuSettings_ShowOverlay" 135 const val PREF_MENU_SETTINGS_SHOW_OVERLAY = "EmulationMenuSettings_ShowOverlay"
135 136
136 const val PREF_FIRST_APP_LAUNCH = "FirstApplicationLaunch" 137 const val PREF_FIRST_APP_LAUNCH = "FirstApplicationLaunch"
138 const val PREF_THEME = "Theme"
137 139
138 private val configFileSectionsMap: MutableMap<String, List<String>> = HashMap() 140 private val configFileSectionsMap: MutableMap<String, List<String>> = HashMap()
139 141
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt
index 29faed72d..b49a8bbec 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt
@@ -3,11 +3,15 @@
3 3
4package org.yuzu.yuzu_emu.features.settings.ui 4package org.yuzu.yuzu_emu.features.settings.ui
5 5
6import android.content.SharedPreferences
7import android.os.Build
6import android.text.TextUtils 8import android.text.TextUtils
7import androidx.appcompat.app.AppCompatActivity 9import androidx.appcompat.app.AppCompatActivity
10import androidx.preference.PreferenceManager
8import org.yuzu.yuzu_emu.R 11import org.yuzu.yuzu_emu.R
12import org.yuzu.yuzu_emu.YuzuApplication
13import org.yuzu.yuzu_emu.features.settings.model.AbstractIntSetting
9import org.yuzu.yuzu_emu.features.settings.model.AbstractSetting 14import org.yuzu.yuzu_emu.features.settings.model.AbstractSetting
10import org.yuzu.yuzu_emu.features.settings.model.BooleanSetting
11import org.yuzu.yuzu_emu.features.settings.model.IntSetting 15import org.yuzu.yuzu_emu.features.settings.model.IntSetting
12import org.yuzu.yuzu_emu.features.settings.model.Settings 16import org.yuzu.yuzu_emu.features.settings.model.Settings
13import org.yuzu.yuzu_emu.features.settings.model.view.* 17import org.yuzu.yuzu_emu.features.settings.model.view.*
@@ -21,12 +25,15 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
21 private val settingsActivity get() = fragmentView.activityView as AppCompatActivity 25 private val settingsActivity get() = fragmentView.activityView as AppCompatActivity
22 private val settings get() = fragmentView.activityView!!.settings 26 private val settings get() = fragmentView.activityView!!.settings
23 27
28 private lateinit var preferences: SharedPreferences
29
24 fun onCreate(menuTag: String, gameId: String) { 30 fun onCreate(menuTag: String, gameId: String) {
25 this.gameId = gameId 31 this.gameId = gameId
26 this.menuTag = menuTag 32 this.menuTag = menuTag
27 } 33 }
28 34
29 fun onViewCreated() { 35 fun onViewCreated() {
36 preferences = PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext)
30 loadSettingsList() 37 loadSettingsList()
31 } 38 }
32 39
@@ -55,6 +62,7 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
55 Settings.SECTION_SYSTEM -> addSystemSettings(sl) 62 Settings.SECTION_SYSTEM -> addSystemSettings(sl)
56 Settings.SECTION_RENDERER -> addGraphicsSettings(sl) 63 Settings.SECTION_RENDERER -> addGraphicsSettings(sl)
57 Settings.SECTION_AUDIO -> addAudioSettings(sl) 64 Settings.SECTION_AUDIO -> addAudioSettings(sl)
65 Settings.SECTION_THEME -> addThemeSettings(sl)
58 else -> { 66 else -> {
59 fragmentView.showToastMessage("Unimplemented menu", false) 67 fragmentView.showToastMessage("Unimplemented menu", false)
60 return 68 return
@@ -99,6 +107,14 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
99 Settings.SECTION_AUDIO 107 Settings.SECTION_AUDIO
100 ) 108 )
101 ) 109 )
110 add(
111 SubmenuSetting(
112 null,
113 R.string.preferences_theme,
114 0,
115 Settings.SECTION_THEME
116 )
117 )
102 } 118 }
103 } 119 }
104 120
@@ -300,4 +316,45 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
300 ) 316 )
301 ) 317 )
302 } 318 }
319
320 private fun addThemeSettings(sl: ArrayList<SettingsItem>) {
321 settingsActivity.setTitle(R.string.preferences_theme)
322 sl.apply {
323 val theme: AbstractIntSetting = object : AbstractIntSetting {
324 override var int: Int
325 get() = preferences.getInt(Settings.PREF_THEME, 0)
326 set(value) {
327 preferences.edit().putInt(Settings.PREF_THEME, value).apply()
328 settingsActivity.recreate()
329 }
330 override val key: String? = null
331 override val section: String? = null
332 override val isRuntimeEditable: Boolean = true
333 override val valueAsString: String
334 get() = preferences.getInt(Settings.PREF_THEME, 0).toString()
335 }
336
337 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
338 add(
339 SingleChoiceSetting(
340 theme,
341 R.string.change_app_theme,
342 0,
343 R.array.themeEntriesA12,
344 R.array.themeValuesA12
345 )
346 )
347 } else {
348 add(
349 SingleChoiceSetting(
350 theme,
351 R.string.change_app_theme,
352 0,
353 R.array.themeEntries,
354 R.array.themeValues
355 )
356 )
357 }
358 }
359 }
303} 360}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt
index c03c28aa1..a33469644 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt
@@ -39,12 +39,14 @@ import org.yuzu.yuzu_emu.model.HomeViewModel
39import org.yuzu.yuzu_emu.utils.* 39import org.yuzu.yuzu_emu.utils.*
40import java.io.IOException 40import java.io.IOException
41 41
42class MainActivity : AppCompatActivity() { 42class MainActivity : AppCompatActivity(), ThemeProvider {
43 private lateinit var binding: ActivityMainBinding 43 private lateinit var binding: ActivityMainBinding
44 44
45 private val homeViewModel: HomeViewModel by viewModels() 45 private val homeViewModel: HomeViewModel by viewModels()
46 private val gamesViewModel: GamesViewModel by viewModels() 46 private val gamesViewModel: GamesViewModel by viewModels()
47 47
48 override var themeId: Int = 0
49
48 override fun onCreate(savedInstanceState: Bundle?) { 50 override fun onCreate(savedInstanceState: Bundle?) {
49 val splashScreen = installSplashScreen() 51 val splashScreen = installSplashScreen()
50 splashScreen.setKeepOnScreenCondition { !DirectoryInitialization.areDirectoriesReady } 52 splashScreen.setKeepOnScreenCondition { !DirectoryInitialization.areDirectoriesReady }
@@ -166,6 +168,11 @@ class MainActivity : AppCompatActivity() {
166 }.start() 168 }.start()
167 } 169 }
168 170
171 override fun onResume() {
172 ThemeHelper.setCorrectTheme(this)
173 super.onResume()
174 }
175
169 override fun onDestroy() { 176 override fun onDestroy() {
170 EmulationActivity.tryDismissRunningNotification(this) 177 EmulationActivity.tryDismissRunningNotification(this)
171 super.onDestroy() 178 super.onDestroy()
@@ -180,6 +187,11 @@ class MainActivity : AppCompatActivity() {
180 windowInsets 187 windowInsets
181 } 188 }
182 189
190 override fun setTheme(resId: Int) {
191 super.setTheme(resId)
192 themeId = resId
193 }
194
183 private fun hasExtension(path: String, extension: String): Boolean { 195 private fun hasExtension(path: String, extension: String): Boolean {
184 return path.substring(path.lastIndexOf(".") + 1).contains(extension) 196 return path.substring(path.lastIndexOf(".") + 1).contains(extension)
185 } 197 }
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/ThemeProvider.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/ThemeProvider.kt
new file mode 100644
index 000000000..511a6e4fa
--- /dev/null
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/ThemeProvider.kt
@@ -0,0 +1,11 @@
1// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4package org.yuzu.yuzu_emu.ui.main
5
6interface ThemeProvider {
7 /**
8 * Provides theme ID by overriding an activity's 'setTheme' method and returning that result
9 */
10 var themeId: Int
11}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/ThemeHelper.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/ThemeHelper.kt
index 481498f7b..72e2fb75e 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/ThemeHelper.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/ThemeHelper.kt
@@ -10,15 +10,27 @@ import androidx.annotation.ColorInt
10import androidx.appcompat.app.AppCompatActivity 10import androidx.appcompat.app.AppCompatActivity
11import androidx.core.content.ContextCompat 11import androidx.core.content.ContextCompat
12import androidx.core.view.WindowCompat 12import androidx.core.view.WindowCompat
13import com.google.android.material.color.MaterialColors 13import androidx.preference.PreferenceManager
14import org.yuzu.yuzu_emu.R 14import org.yuzu.yuzu_emu.R
15import org.yuzu.yuzu_emu.YuzuApplication
16import org.yuzu.yuzu_emu.features.settings.model.Settings
17import org.yuzu.yuzu_emu.ui.main.ThemeProvider
15import kotlin.math.roundToInt 18import kotlin.math.roundToInt
16 19
17object ThemeHelper { 20object ThemeHelper {
18 const val SYSTEM_BAR_ALPHA = 0.9f 21 const val SYSTEM_BAR_ALPHA = 0.9f
19 22
23 private const val DEFAULT = 0
24 private const val MATERIAL_YOU = 1
25
20 @JvmStatic 26 @JvmStatic
21 fun setTheme(activity: AppCompatActivity) { 27 fun setTheme(activity: AppCompatActivity) {
28 val preferences = PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext)
29 when (preferences.getInt(Settings.PREF_THEME, 0)) {
30 DEFAULT -> activity.setTheme(R.style.Theme_Yuzu_Main)
31 MATERIAL_YOU -> activity.setTheme(R.style.Theme_Yuzu_Main_MaterialYou)
32 }
33
22 val windowController = WindowCompat.getInsetsController( 34 val windowController = WindowCompat.getInsetsController(
23 activity.window, 35 activity.window,
24 activity.window.decorView 36 activity.window.decorView
@@ -60,4 +72,12 @@ object ThemeHelper {
60 Color.green(color), Color.blue(color) 72 Color.green(color), Color.blue(color)
61 ) 73 )
62 } 74 }
75
76 fun setCorrectTheme(activity: AppCompatActivity) {
77 val currentTheme = (activity as ThemeProvider).themeId
78 setTheme(activity)
79 if (currentTheme != (activity as ThemeProvider).themeId) {
80 activity.recreate()
81 }
82 }
63} 83}
diff --git a/src/android/app/src/main/res/values/arrays.xml b/src/android/app/src/main/res/values/arrays.xml
index 628d43197..a98ccd985 100644
--- a/src/android/app/src/main/res/values/arrays.xml
+++ b/src/android/app/src/main/res/values/arrays.xml
@@ -183,4 +183,20 @@
183 <item>@string/gamepad_screenshot</item> 183 <item>@string/gamepad_screenshot</item>
184 </string-array> 184 </string-array>
185 185
186 <string-array name="themeEntries">
187 <item>@string/theme_default</item>
188 </string-array>
189 <integer-array name="themeValues">
190 <item>0</item>
191 </integer-array>
192
193 <string-array name="themeEntriesA12">
194 <item>@string/theme_default</item>
195 <item>@string/theme_material_you</item>
196 </string-array>
197 <integer-array name="themeValuesA12">
198 <item>0</item>
199 <item>1</item>
200 </integer-array>
201
186</resources> 202</resources>
diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml
index 92fe67bf0..90c94d67f 100644
--- a/src/android/app/src/main/res/values/strings.xml
+++ b/src/android/app/src/main/res/values/strings.xml
@@ -103,6 +103,7 @@
103 <string name="preferences_system">System</string> 103 <string name="preferences_system">System</string>
104 <string name="preferences_graphics">Graphics</string> 104 <string name="preferences_graphics">Graphics</string>
105 <string name="preferences_audio">Audio</string> 105 <string name="preferences_audio">Audio</string>
106 <string name="preferences_theme">Theme and Color</string>
106 107
107 <!-- ROM loading errors --> 108 <!-- ROM loading errors -->
108 <string name="loader_error_encrypted">Your ROM is encrypted</string> 109 <string name="loader_error_encrypted">Your ROM is encrypted</string>
@@ -229,4 +230,9 @@
229 <string name="preparing_shaders">Preparing shaders</string> 230 <string name="preparing_shaders">Preparing shaders</string>
230 <string name="building_shaders">Building shaders</string> 231 <string name="building_shaders">Building shaders</string>
231 232
233 <!-- Theme options -->
234 <string name="change_app_theme">Change App Theme</string>
235 <string name="theme_default">Default</string>
236 <string name="theme_material_you">Material You</string>
237
232</resources> 238</resources>