diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/BooleanSetting.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/BooleanSetting.java index 9c6e2ce476..79d76ada40 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/BooleanSetting.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/model/BooleanSetting.java @@ -81,6 +81,8 @@ public enum BooleanSetting implements AbstractBooleanSetting MAIN_SHOW_GAME_TITLES(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID, "ShowGameTitles", true), + MAIN_USE_BLACK_BACKGROUNDS(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID, + "UseBlackBackgrounds", false), MAIN_JOYSTICK_REL_CENTER(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID, "JoystickRelCenter", true), MAIN_PHONE_RUMBLE(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID, 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 3c0838029b..e15f343a40 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 @@ -13,6 +13,7 @@ import androidx.appcompat.app.AppCompatActivity; import org.dolphinemu.dolphinemu.NativeLibrary; import org.dolphinemu.dolphinemu.R; import org.dolphinemu.dolphinemu.activities.UserDataActivity; +import org.dolphinemu.dolphinemu.features.settings.model.AbstractBooleanSetting; import org.dolphinemu.dolphinemu.features.settings.model.AbstractIntSetting; import org.dolphinemu.dolphinemu.features.settings.model.AbstractStringSetting; import org.dolphinemu.dolphinemu.features.settings.model.AdHocBooleanSetting; @@ -414,6 +415,44 @@ public final class SettingsFragmentPresenter sl.add(new SingleChoiceSetting(mContext, themeMode, R.string.change_theme_mode, 0, R.array.themeModeEntries, R.array.themeModeValues)); + + AbstractBooleanSetting blackBackgrounds = new AbstractBooleanSetting() + { + @Override + public boolean isOverridden(Settings settings) + { + return BooleanSetting.MAIN_USE_BLACK_BACKGROUNDS.isOverridden(settings); + } + + @Override + public boolean isRuntimeEditable() + { + return true; + } + + @Override + public boolean delete(Settings settings) + { + ThemeHelper.deleteBackgroundSetting((AppCompatActivity) mView.getActivity()); + return BooleanSetting.MAIN_USE_BLACK_BACKGROUNDS.delete(settings); + } + + @Override + public boolean getBoolean(Settings settings) + { + return BooleanSetting.MAIN_USE_BLACK_BACKGROUNDS.getBoolean(settings); + } + + @Override + public void setBoolean(Settings settings, boolean newValue) + { + BooleanSetting.MAIN_USE_BLACK_BACKGROUNDS.setBoolean(settings, newValue); + ThemeHelper.saveBackgroundSetting((AppCompatActivity) mView.getActivity(), newValue); + } + }; + + sl.add(new CheckBoxSetting(mContext, blackBackgrounds, R.string.use_black_backgrounds, + R.string.use_black_backgrounds_description)); } 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 15cf635615..b1584df1be 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 @@ -21,6 +21,7 @@ import androidx.preference.PreferenceManager; import org.dolphinemu.dolphinemu.NativeLibrary; import org.dolphinemu.dolphinemu.R; import org.dolphinemu.dolphinemu.activities.EmulationActivity; +import org.dolphinemu.dolphinemu.features.settings.model.BooleanSetting; import org.dolphinemu.dolphinemu.features.settings.model.IntSetting; import java.io.File; @@ -79,24 +80,7 @@ public final class DirectoryInitialization areDirectoriesAvailable = true; - SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); - if (IntSetting.MAIN_INTERFACE_THEME.getIntGlobal() != - preferences.getInt(ThemeHelper.CURRENT_THEME, ThemeHelper.DEFAULT)) - { - preferences.edit() - .putInt(ThemeHelper.CURRENT_THEME, IntSetting.MAIN_INTERFACE_THEME.getIntGlobal()) - .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(); - } + checkThemeSettings(context); if (wiimoteIniWritten) { @@ -418,6 +402,37 @@ public final class DirectoryInitialization return preferLegacyUserDirectory(context) && !PermissionsHandler.hasWriteAccess(context); } + private static void checkThemeSettings(Context context) + { + SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context); + if (IntSetting.MAIN_INTERFACE_THEME.getIntGlobal() != + preferences.getInt(ThemeHelper.CURRENT_THEME, ThemeHelper.DEFAULT)) + { + preferences.edit() + .putInt(ThemeHelper.CURRENT_THEME, IntSetting.MAIN_INTERFACE_THEME.getIntGlobal()) + .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 (BooleanSetting.MAIN_USE_BLACK_BACKGROUNDS.getBooleanGlobal() != + preferences.getBoolean(ThemeHelper.USE_BLACK_BACKGROUNDS, false)) + { + preferences.edit() + .putBoolean(ThemeHelper.USE_BLACK_BACKGROUNDS, + BooleanSetting.MAIN_USE_BLACK_BACKGROUNDS.getBooleanGlobal()) + .apply(); + } + } + private static native void CreateUserDirectories(); private static native void SetSysDirectory(String path); 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 040e20990a..866b8659a9 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 @@ -27,6 +27,7 @@ public class ThemeHelper { public static final String CURRENT_THEME = "current_theme"; public static final String CURRENT_THEME_MODE = "current_theme_mode"; + public static final String USE_BLACK_BACKGROUNDS = "use_black_backgrounds"; public static final int DEFAULT = 0; public static final int MONET = 1; @@ -66,6 +67,11 @@ public class ThemeHelper break; } + if (preferences.getBoolean(USE_BLACK_BACKGROUNDS, false)) + { + activity.setTheme(R.style.ThemeOverlay_Dolphin_Dark); + } + // Since the top app bar matches the color of the status bar, devices below API 23 have to get a // black status bar since their icons do not adapt based on background color if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) @@ -157,6 +163,24 @@ public class ThemeHelper setThemeMode(activity); } + public static void saveBackgroundSetting(AppCompatActivity activity, boolean backgroundValue) + { + PreferenceManager.getDefaultSharedPreferences(activity.getApplicationContext()) + .edit() + .putBoolean(USE_BLACK_BACKGROUNDS, backgroundValue) + .apply(); + activity.recreate(); + } + + public static void deleteBackgroundSetting(AppCompatActivity activity) + { + PreferenceManager.getDefaultSharedPreferences(activity.getApplicationContext()) + .edit() + .remove(USE_BLACK_BACKGROUNDS) + .apply(); + activity.recreate(); + } + public static void setCorrectTheme(AppCompatActivity activity) { int currentTheme = ((ThemeProvider) activity).getThemeId(); diff --git a/Source/Android/app/src/main/res/values-night/themes.xml b/Source/Android/app/src/main/res/values-night/themes.xml new file mode 100644 index 0000000000..87bc2caf63 --- /dev/null +++ b/Source/Android/app/src/main/res/values-night/themes.xml @@ -0,0 +1,7 @@ + + + + diff --git a/Source/Android/app/src/main/res/values/dolphin_colors.xml b/Source/Android/app/src/main/res/values/dolphin_colors.xml index cd11b64fd4..eddde118d9 100644 --- a/Source/Android/app/src/main/res/values/dolphin_colors.xml +++ b/Source/Android/app/src/main/res/values/dolphin_colors.xml @@ -39,4 +39,6 @@ #444444 #36ff0000 + + #000000 diff --git a/Source/Android/app/src/main/res/values/strings.xml b/Source/Android/app/src/main/res/values/strings.xml index 8b6f1a5cf4..fd356227f2 100644 --- a/Source/Android/app/src/main/res/values/strings.xml +++ b/Source/Android/app/src/main/res/values/strings.xml @@ -197,6 +197,8 @@ Show the title and creator below each game cover. Change App Theme Change Theme Mode + Use Black Backgrounds + When using the dark theme, apply black backgrounds. Please select a region diff --git a/Source/Core/Core/ConfigLoaders/IsSettingSaveable.cpp b/Source/Core/Core/ConfigLoaders/IsSettingSaveable.cpp index 9c50002204..c93375c148 100644 --- a/Source/Core/Core/ConfigLoaders/IsSettingSaveable.cpp +++ b/Source/Core/Core/ConfigLoaders/IsSettingSaveable.cpp @@ -39,12 +39,12 @@ bool IsSettingSaveable(const Config::Location& config_location) // TODO: Kill the current Android controller mappings system if (config_location.section == "Android") { - static constexpr std::array android_setting_saveable = { - "ControlScale", "ControlOpacity", "EmulationOrientation", - "JoystickRelCenter", "LastPlatformTab", "MotionControls", - "PhoneRumble", "ShowInputOverlay", "IRMode", - "IRAlwaysRecenter", "ShowGameTitles", "InterfaceTheme", - "InterfaceThemeMode"}; + static constexpr std::array android_setting_saveable = { + "ControlScale", "ControlOpacity", "EmulationOrientation", + "JoystickRelCenter", "LastPlatformTab", "MotionControls", + "PhoneRumble", "ShowInputOverlay", "IRMode", + "IRAlwaysRecenter", "ShowGameTitles", "InterfaceTheme", + "InterfaceThemeMode", "UseBlackBackgrounds"}; return std::any_of( android_setting_saveable.cbegin(), android_setting_saveable.cend(),