From b9fffa2e66025e7f4b3f8a4ff4e6c71a171452f8 Mon Sep 17 00:00:00 2001 From: Charles Lombardo Date: Fri, 11 Nov 2022 20:44:30 -0500 Subject: Android: Add theme mode switcher Similar to app themes, theme modes have to be loaded before directory initialization is ready. So we save the proper key the same way. --- .../features/settings/model/IntSetting.java | 2 + .../settings/ui/SettingsFragmentPresenter.java | 61 +++++++++++++-- .../dolphinemu/utils/DirectoryInitialization.java | 11 +++ .../dolphinemu/dolphinemu/utils/ThemeHelper.java | 91 +++++++++++++++++++--- 4 files changed, 147 insertions(+), 18 deletions(-) (limited to 'Source/Android/app/src/main/java') diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/IntSetting.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/IntSetting.java index 11fc2a0046..c7f2b0c54c 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/IntSetting.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/IntSetting.java @@ -34,6 +34,8 @@ public enum IntSetting implements AbstractIntSetting MAIN_EMULATION_ORIENTATION(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID, "EmulationOrientation", ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE), MAIN_INTERFACE_THEME(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID, "InterfaceTheme", 0), + MAIN_INTERFACE_THEME_MODE(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID, + "InterfaceThemeMode", -1), MAIN_LAST_PLATFORM_TAB(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID, "LastPlatformTab", 0), MAIN_MOTION_CONTROLS(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID, "MotionControls", 1), MAIN_IR_MODE(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID, "IRMode", diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.java index 1f073ace20..3c0838029b 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.java @@ -8,6 +8,8 @@ import android.os.Build; import android.os.Bundle; import android.text.TextUtils; +import androidx.appcompat.app.AppCompatActivity; + import org.dolphinemu.dolphinemu.NativeLibrary; import org.dolphinemu.dolphinemu.R; import org.dolphinemu.dolphinemu.activities.UserDataActivity; @@ -328,33 +330,37 @@ public final class SettingsFragmentPresenter AbstractIntSetting appTheme = new AbstractIntSetting() { - @Override public boolean isOverridden(Settings settings) + @Override + public boolean isOverridden(Settings settings) { return IntSetting.MAIN_INTERFACE_THEME.isOverridden(settings); } - @Override public boolean isRuntimeEditable() + @Override + public boolean isRuntimeEditable() { // This only affects app UI return true; } - @Override public boolean delete(Settings settings) + @Override + public boolean delete(Settings settings) { - ThemeHelper.deleteThemeKey(mView.getActivity()); + ThemeHelper.deleteThemeKey((AppCompatActivity) mView.getActivity()); return IntSetting.MAIN_INTERFACE_THEME.delete(settings); } - @Override public int getInt(Settings settings) + @Override + public int getInt(Settings settings) { return IntSetting.MAIN_INTERFACE_THEME.getInt(settings); } - @Override public void setInt(Settings settings, int newValue) + @Override + public void setInt(Settings settings, int newValue) { - ThemeHelper.saveTheme(mView.getActivity(), newValue); IntSetting.MAIN_INTERFACE_THEME.setInt(settings, newValue); - mView.getActivity().recreate(); + ThemeHelper.saveTheme((AppCompatActivity) mView.getActivity(), newValue); } }; @@ -369,6 +375,45 @@ public final class SettingsFragmentPresenter sl.add(new SingleChoiceSetting(mContext, appTheme, R.string.change_theme, 0, R.array.themeEntries, R.array.themeValues)); } + + AbstractIntSetting themeMode = new AbstractIntSetting() + { + @Override + public boolean isOverridden(Settings settings) + { + return IntSetting.MAIN_INTERFACE_THEME_MODE.isOverridden(settings); + } + + @Override + public boolean isRuntimeEditable() + { + // This only affects app UI + return true; + } + + @Override + public boolean delete(Settings settings) + { + ThemeHelper.deleteThemeModeKey((AppCompatActivity) mView.getActivity()); + return IntSetting.MAIN_INTERFACE_THEME_MODE.delete(settings); + } + + @Override + public int getInt(Settings settings) + { + return IntSetting.MAIN_INTERFACE_THEME_MODE.getInt(settings); + } + + @Override + public void setInt(Settings settings, int newValue) + { + IntSetting.MAIN_INTERFACE_THEME_MODE.setInt(settings, newValue); + ThemeHelper.saveThemeMode((AppCompatActivity) mView.getActivity(), newValue); + } + }; + + sl.add(new SingleChoiceSetting(mContext, themeMode, R.string.change_theme_mode, 0, + R.array.themeModeEntries, R.array.themeModeValues)); } private void addAudioSettings(ArrayList sl) diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/DirectoryInitialization.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/DirectoryInitialization.java index f872802a9f..15cf635615 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/DirectoryInitialization.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/DirectoryInitialization.java @@ -13,6 +13,7 @@ import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatDelegate; import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import androidx.preference.PreferenceManager; @@ -87,6 +88,16 @@ public final class DirectoryInitialization .apply(); } + if (IntSetting.MAIN_INTERFACE_THEME_MODE.getIntGlobal() != + preferences.getInt(ThemeHelper.CURRENT_THEME_MODE, + AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)) + { + preferences.edit() + .putInt(ThemeHelper.CURRENT_THEME_MODE, + IntSetting.MAIN_INTERFACE_THEME_MODE.getIntGlobal()) + .apply(); + } + if (wiimoteIniWritten) { // This has to be done after calling NativeLibrary.Initialize(), diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/ThemeHelper.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/ThemeHelper.java index ff96e033c0..040e20990a 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/ThemeHelper.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/ThemeHelper.java @@ -10,7 +10,10 @@ import androidx.annotation.ColorInt; import androidx.annotation.NonNull; import androidx.annotation.RequiresApi; import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.app.AppCompatDelegate; import androidx.core.content.ContextCompat; +import androidx.core.view.WindowCompat; +import androidx.core.view.WindowInsetsControllerCompat; import androidx.preference.PreferenceManager; import com.google.android.material.appbar.AppBarLayout; @@ -23,6 +26,7 @@ import org.dolphinemu.dolphinemu.ui.main.ThemeProvider; public class ThemeHelper { public static final String CURRENT_THEME = "current_theme"; + public static final String CURRENT_THEME_MODE = "current_theme_mode"; public static final int DEFAULT = 0; public static final int MONET = 1; @@ -38,6 +42,7 @@ public class ThemeHelper // requested theme id is ready before the onCreate method of any given Activity. SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity.getApplicationContext()); + setThemeMode(activity); switch (preferences.getInt(CURRENT_THEME, DEFAULT)) { case DEFAULT: @@ -70,22 +75,88 @@ public class ThemeHelper } } - public static void saveTheme(@NonNull Activity activity, int themeValue) + private static void setThemeMode(@NonNull AppCompatActivity activity) { - SharedPreferences preferences = - PreferenceManager.getDefaultSharedPreferences(activity.getApplicationContext()); - preferences.edit().putInt(CURRENT_THEME, themeValue).apply(); + int themeMode = PreferenceManager.getDefaultSharedPreferences(activity.getApplicationContext()) + .getInt(CURRENT_THEME_MODE, AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM); + activity.getDelegate().setLocalNightMode(themeMode); + + WindowInsetsControllerCompat windowController = + WindowCompat.getInsetsController(activity.getWindow(), + activity.getWindow().getDecorView()); + int systemReportedThemeMode = + activity.getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK; + + switch (themeMode) + { + case AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM: + switch (systemReportedThemeMode) + { + case Configuration.UI_MODE_NIGHT_NO: + setLightModeSystemBars(windowController); + break; + case Configuration.UI_MODE_NIGHT_YES: + setDarkModeSystemBars(windowController); + break; + } + break; + case AppCompatDelegate.MODE_NIGHT_NO: + setLightModeSystemBars(windowController); + break; + case AppCompatDelegate.MODE_NIGHT_YES: + setDarkModeSystemBars(windowController); + break; + } } - public static void deleteThemeKey(@NonNull Activity activity) + private static void setLightModeSystemBars(@NonNull WindowInsetsControllerCompat windowController) { - SharedPreferences preferences = - PreferenceManager.getDefaultSharedPreferences(activity.getApplicationContext()); - preferences.edit().remove(CURRENT_THEME).apply(); - activity.setTheme(R.style.Theme_Dolphin_Main); + windowController.setAppearanceLightStatusBars(true); + windowController.setAppearanceLightNavigationBars(true); + } + + private static void setDarkModeSystemBars(@NonNull WindowInsetsControllerCompat windowController) + { + windowController.setAppearanceLightStatusBars(false); + windowController.setAppearanceLightNavigationBars(false); + } + + public static void saveTheme(@NonNull AppCompatActivity activity, int themeValue) + { + PreferenceManager.getDefaultSharedPreferences(activity.getApplicationContext()) + .edit() + .putInt(CURRENT_THEME, themeValue) + .apply(); + activity.recreate(); + } + + public static void deleteThemeKey(@NonNull AppCompatActivity activity) + { + PreferenceManager.getDefaultSharedPreferences(activity.getApplicationContext()) + .edit() + .remove(CURRENT_THEME) + .apply(); activity.recreate(); } + public static void saveThemeMode(@NonNull AppCompatActivity activity, int themeModeValue) + { + PreferenceManager.getDefaultSharedPreferences(activity.getApplicationContext()) + .edit() + .putInt(CURRENT_THEME_MODE, themeModeValue) + .apply(); + setThemeMode(activity); + } + + public static void deleteThemeModeKey(@NonNull AppCompatActivity activity) + { + PreferenceManager.getDefaultSharedPreferences(activity.getApplicationContext()) + .edit() + .remove(CURRENT_THEME_MODE) + .apply(); + setThemeMode(activity); + } + public static void setCorrectTheme(AppCompatActivity activity) { int currentTheme = ((ThemeProvider) activity).getThemeId(); @@ -110,7 +181,7 @@ public class ThemeHelper } } - public static void setNavigationBarColor(Activity activity, @ColorInt int color) + public static void setNavigationBarColor(@NonNull Activity activity, @ColorInt int color) { int gestureType = InsetsHelper.getSystemGestureType(activity.getApplicationContext()); int orientation = activity.getResources().getConfiguration().orientation; -- cgit v1.2.3