mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-01-09 23:59:27 +01:00
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.
This commit is contained in:
parent
385dfb60a0
commit
b9fffa2e66
@ -96,7 +96,7 @@ android {
|
||||
dependencies {
|
||||
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
|
||||
|
||||
implementation 'androidx.appcompat:appcompat:1.5.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.5.1'
|
||||
implementation 'androidx.exifinterface:exifinterface:1.3.3'
|
||||
implementation 'androidx.cardview:cardview:1.0.0'
|
||||
implementation 'androidx.recyclerview:recyclerview:1.2.1'
|
||||
|
@ -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",
|
||||
|
@ -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<SettingsItem> sl)
|
||||
|
@ -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(),
|
||||
|
@ -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;
|
||||
|
@ -1,9 +0,0 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="?attr/colorOnSurface"
|
||||
android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z"/>
|
||||
</vector>
|
@ -2,7 +2,7 @@
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item
|
||||
android:state_selected="true"
|
||||
android:drawable="@color/dolphin_primary"/>
|
||||
android:drawable="@color/dolphin_blue"/>
|
||||
<item
|
||||
android:drawable="@color/tv_card_unselected"/>
|
||||
</selector>
|
||||
|
@ -1,4 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<bool name="lightSystemBars">false</bool>
|
||||
</resources>
|
@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<style name="Theme.V27.Dolphin" parent="Theme.Dolphin">
|
||||
<item name="android:windowLightNavigationBar">@bool/lightSystemBars</item>
|
||||
</style>
|
||||
|
||||
<style name="Theme.Dolphin.Main" parent="Theme.V27.Dolphin" />
|
||||
</resources>
|
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<style name="Theme.V29.Dolphin" parent="Theme.V27.Dolphin">
|
||||
<style name="Theme.V29.Dolphin" parent="Theme.Dolphin">
|
||||
<item name="android:enforceStatusBarContrast">false</item>
|
||||
<item name="android:enforceNavigationBarContrast">false</item>
|
||||
</style>
|
||||
|
@ -507,6 +507,17 @@
|
||||
<item>4</item>
|
||||
</integer-array>
|
||||
|
||||
<string-array name="themeModeEntries">
|
||||
<item>Follow System</item>
|
||||
<item>Light</item>
|
||||
<item>Dark</item>
|
||||
</string-array>
|
||||
<integer-array name="themeModeValues">
|
||||
<item>-1</item>
|
||||
<item>1</item>
|
||||
<item>2</item>
|
||||
</integer-array>
|
||||
|
||||
<string-array name="synchronizeGpuThreadEntries">
|
||||
<item>Never</item>
|
||||
<item>On Idle Skipping</item>
|
||||
|
@ -1,4 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<bool name="lightSystemBars">true</bool>
|
||||
</resources>
|
@ -196,6 +196,7 @@
|
||||
<string name="show_titles_in_game_list">Show Titles in Game List</string>
|
||||
<string name="show_titles_in_game_list_description">Show the title and creator below each game cover.</string>
|
||||
<string name="change_theme">Change App Theme</string>
|
||||
<string name="change_theme_mode">Change Theme Mode</string>
|
||||
|
||||
<!-- Online Update Region Select Fragment -->
|
||||
<string name="region_select_title">Please select a region</string>
|
||||
|
@ -42,7 +42,7 @@
|
||||
|
||||
<style name="DolphinTVDialog" parent="Theme.Material3.DayNight.Dialog.Alert">
|
||||
<item name="colorSurface">@color/dolphin_inverseOnSurface</item>
|
||||
<item name="colorPrimary">@color/dolphin_primary</item>
|
||||
<item name="colorPrimary">@color/dolphin_blue</item>
|
||||
</style>
|
||||
|
||||
<style name="DolphinButton" parent="Widget.Material3.Button.TextButton.Dialog">
|
||||
|
@ -47,9 +47,6 @@
|
||||
<item name="android:windowAllowEnterTransitionOverlap">true</item>
|
||||
<item name="android:windowAllowReturnTransitionOverlap">true</item>
|
||||
|
||||
<item name="homeAsUpIndicator">@drawable/ic_back</item>
|
||||
|
||||
<item name="android:windowLightStatusBar" tools:targetApi="m">@bool/lightSystemBars</item>
|
||||
<item name="android:windowLayoutInDisplayCutoutMode" tools:targetApi="o_mr1">default</item>
|
||||
|
||||
<item name="materialAlertDialogTheme">@style/DolphinMaterialDialog</item>
|
||||
@ -58,7 +55,7 @@
|
||||
<item name="materialDividerStyle">@style/DolphinDivider</item>
|
||||
</style>
|
||||
|
||||
<!-- Trick for API >= 27 specific changes -->
|
||||
<!-- Trick for API >= 29 specific changes -->
|
||||
<style name="Theme.Dolphin.Main" parent="Theme.Dolphin" />
|
||||
|
||||
<style name="Theme.Dolphin.Main.Material" parent="Theme.Dolphin.Main">
|
||||
|
@ -39,10 +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<const char*, 12> android_setting_saveable = {
|
||||
"ControlScale", "ControlOpacity", "EmulationOrientation", "JoystickRelCenter",
|
||||
"LastPlatformTab", "MotionControls", "PhoneRumble", "ShowInputOverlay",
|
||||
"IRMode", "IRAlwaysRecenter", "ShowGameTitles", "InterfaceTheme"};
|
||||
static constexpr std::array<const char*, 13> android_setting_saveable = {
|
||||
"ControlScale", "ControlOpacity", "EmulationOrientation",
|
||||
"JoystickRelCenter", "LastPlatformTab", "MotionControls",
|
||||
"PhoneRumble", "ShowInputOverlay", "IRMode",
|
||||
"IRAlwaysRecenter", "ShowGameTitles", "InterfaceTheme",
|
||||
"InterfaceThemeMode"};
|
||||
|
||||
return std::any_of(
|
||||
android_setting_saveable.cbegin(), android_setting_saveable.cend(),
|
||||
|
Loading…
x
Reference in New Issue
Block a user