diff options
| author | 2023-04-20 17:44:19 -0400 | |
|---|---|---|
| committer | 2023-06-03 00:05:54 -0700 | |
| commit | f0ba58f5aa3524a2f97b268dfd7578ba3ef433bc (patch) | |
| tree | 3a291344242151e6f2d26c8c9983fa47eaef5f28 /src/android | |
| parent | android: Prevent potential abstract settings crash (diff) | |
| download | yuzu-f0ba58f5aa3524a2f97b268dfd7578ba3ef433bc.tar.gz yuzu-f0ba58f5aa3524a2f97b268dfd7578ba3ef433bc.tar.xz yuzu-f0ba58f5aa3524a2f97b268dfd7578ba3ef433bc.zip | |
android: Add theme picker
Diffstat (limited to 'src/android')
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 | ||
| 4 | package org.yuzu.yuzu_emu.features.settings.ui | 4 | package org.yuzu.yuzu_emu.features.settings.ui |
| 5 | 5 | ||
| 6 | import android.content.SharedPreferences | ||
| 7 | import android.os.Build | ||
| 6 | import android.text.TextUtils | 8 | import android.text.TextUtils |
| 7 | import androidx.appcompat.app.AppCompatActivity | 9 | import androidx.appcompat.app.AppCompatActivity |
| 10 | import androidx.preference.PreferenceManager | ||
| 8 | import org.yuzu.yuzu_emu.R | 11 | import org.yuzu.yuzu_emu.R |
| 12 | import org.yuzu.yuzu_emu.YuzuApplication | ||
| 13 | import org.yuzu.yuzu_emu.features.settings.model.AbstractIntSetting | ||
| 9 | import org.yuzu.yuzu_emu.features.settings.model.AbstractSetting | 14 | import org.yuzu.yuzu_emu.features.settings.model.AbstractSetting |
| 10 | import org.yuzu.yuzu_emu.features.settings.model.BooleanSetting | ||
| 11 | import org.yuzu.yuzu_emu.features.settings.model.IntSetting | 15 | import org.yuzu.yuzu_emu.features.settings.model.IntSetting |
| 12 | import org.yuzu.yuzu_emu.features.settings.model.Settings | 16 | import org.yuzu.yuzu_emu.features.settings.model.Settings |
| 13 | import org.yuzu.yuzu_emu.features.settings.model.view.* | 17 | import 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 | |||
| 39 | import org.yuzu.yuzu_emu.utils.* | 39 | import org.yuzu.yuzu_emu.utils.* |
| 40 | import java.io.IOException | 40 | import java.io.IOException |
| 41 | 41 | ||
| 42 | class MainActivity : AppCompatActivity() { | 42 | class 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 | |||
| 4 | package org.yuzu.yuzu_emu.ui.main | ||
| 5 | |||
| 6 | interface 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 | |||
| 10 | import androidx.appcompat.app.AppCompatActivity | 10 | import androidx.appcompat.app.AppCompatActivity |
| 11 | import androidx.core.content.ContextCompat | 11 | import androidx.core.content.ContextCompat |
| 12 | import androidx.core.view.WindowCompat | 12 | import androidx.core.view.WindowCompat |
| 13 | import com.google.android.material.color.MaterialColors | 13 | import androidx.preference.PreferenceManager |
| 14 | import org.yuzu.yuzu_emu.R | 14 | import org.yuzu.yuzu_emu.R |
| 15 | import org.yuzu.yuzu_emu.YuzuApplication | ||
| 16 | import org.yuzu.yuzu_emu.features.settings.model.Settings | ||
| 17 | import org.yuzu.yuzu_emu.ui.main.ThemeProvider | ||
| 15 | import kotlin.math.roundToInt | 18 | import kotlin.math.roundToInt |
| 16 | 19 | ||
| 17 | object ThemeHelper { | 20 | object 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> |