diff --git a/Source/Android/app/src/main/AndroidManifest.xml b/Source/Android/app/src/main/AndroidManifest.xml
index cb493596e8..812b19e325 100644
--- a/Source/Android/app/src/main/AndroidManifest.xml
+++ b/Source/Android/app/src/main/AndroidManifest.xml
@@ -76,19 +76,19 @@
android:name=".features.settings.ui.SettingsActivity"
android:exported="false"
android:configChanges="orientation|screenSize"
- android:theme="@style/Theme.Dolphin.Settings"
+ android:theme="@style/Theme.Dolphin.Main"
android:label="@string/settings"/>
+ android:theme="@style/Theme.Dolphin.Main" />
- SettingsActivity.launch(activity, MenuTag.CONFIG_PATHS));
- builder.setNeutralButton(R.string.continue_anyway, (dialogInterface, i) ->
- continueCallback.run());
- builder.show();
+ new MaterialAlertDialogBuilder(activity)
+ .setMessage(R.string.unavailable_paths)
+ .setPositiveButton(R.string.yes,
+ (dialogInterface, i) -> SettingsActivity.launch(activity,
+ MenuTag.CONFIG_PATHS))
+ .setNeutralButton(R.string.continue_anyway,
+ (dialogInterface, i) -> continueCallback.run())
+ .show();
}
else if (!FileBrowserHelper.isPathEmptyOrValid(StringSetting.MAIN_WII_SD_CARD_IMAGE_PATH) ||
!FileBrowserHelper.isPathEmptyOrValid(
StringSetting.MAIN_WII_SD_CARD_SYNC_FOLDER_PATH))
{
- AlertDialog.Builder builder = new AlertDialog.Builder(activity);
- builder.setMessage(R.string.unavailable_paths);
- builder.setPositiveButton(R.string.yes, (dialogInterface, i) ->
- SettingsActivity.launch(activity, MenuTag.CONFIG_WII));
- builder.setNeutralButton(R.string.continue_anyway, (dialogInterface, i) ->
- continueCallback.run());
- builder.show();
+ new MaterialAlertDialogBuilder(activity)
+ .setMessage(R.string.unavailable_paths)
+ .setPositiveButton(R.string.yes,
+ (dialogInterface, i) -> SettingsActivity.launch(activity,
+ MenuTag.CONFIG_WII))
+ .setNeutralButton(R.string.continue_anyway,
+ (dialogInterface, i) -> continueCallback.run())
+ .show();
}
else
{
@@ -295,6 +303,8 @@ public final class EmulationActivity extends AppCompatActivity
@Override
protected void onCreate(Bundle savedInstanceState)
{
+ ThemeHelper.setTheme(this);
+
super.onCreate(savedInstanceState);
MainPresenter.skipRescanningLibrary();
@@ -382,6 +392,8 @@ public final class EmulationActivity extends AppCompatActivity
@Override
protected void onResume()
{
+ ThemeHelper.setCorrectTheme(this);
+
super.onResume();
// Only android 9+ support this feature.
@@ -816,8 +828,8 @@ public final class EmulationActivity extends AppCompatActivity
private void toggleControls()
{
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
- builder.setTitle(R.string.emulation_toggle_controls);
+ MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(this)
+ .setTitle(R.string.emulation_toggle_controls);
int currentController = InputOverlay.getConfiguredControllerType(this);
@@ -873,17 +885,14 @@ public final class EmulationActivity extends AppCompatActivity
}
builder.setNeutralButton(R.string.emulation_toggle_all,
- (dialogInterface, i) -> mEmulationFragment.toggleInputOverlayVisibility(mSettings));
- builder.setPositiveButton(R.string.ok, (dialogInterface, i) ->
- mEmulationFragment.refreshInputOverlay());
-
- builder.show();
+ (dialogInterface, i) -> mEmulationFragment.toggleInputOverlayVisibility(mSettings))
+ .setPositiveButton(R.string.ok, (dialogInterface, i) ->
+ mEmulationFragment.refreshInputOverlay())
+ .show();
}
public void chooseDoubleTapButton()
{
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
-
int currentValue = IntSetting.MAIN_DOUBLE_TAP_BUTTON.getInt(mSettings);
int buttonList = InputOverlay.getConfiguredControllerType(this) ==
@@ -900,14 +909,13 @@ public final class EmulationActivity extends AppCompatActivity
}
}
- builder.setSingleChoiceItems(buttonList, checkedItem,
- (DialogInterface dialog, int which) -> IntSetting.MAIN_DOUBLE_TAP_BUTTON
- .setInt(mSettings, InputOverlayPointer.DOUBLE_TAP_OPTIONS.get(which)));
-
- builder.setPositiveButton(R.string.ok, (dialogInterface, i) ->
- mEmulationFragment.initInputPointer());
-
- builder.show();
+ new MaterialAlertDialogBuilder(this)
+ .setSingleChoiceItems(buttonList, checkedItem,
+ (DialogInterface dialog, int which) -> IntSetting.MAIN_DOUBLE_TAP_BUTTON.setInt(
+ mSettings, InputOverlayPointer.DOUBLE_TAP_OPTIONS.get(which)))
+ .setPositiveButton(R.string.ok,
+ (dialogInterface, i) -> mEmulationFragment.initInputPointer())
+ .show();
}
private void adjustScale()
@@ -915,130 +923,96 @@ public final class EmulationActivity extends AppCompatActivity
LayoutInflater inflater = LayoutInflater.from(this);
View view = inflater.inflate(R.layout.dialog_input_adjust, null);
- final SeekBar scaleSeekbar = view.findViewById(R.id.input_scale_seekbar);
+ final Slider scaleSlider = view.findViewById(R.id.input_scale_slider);
final TextView scaleValue = view.findViewById(R.id.input_scale_value);
-
- scaleSeekbar.setMax(150);
- scaleSeekbar.setProgress(IntSetting.MAIN_CONTROL_SCALE.getInt(mSettings));
- scaleSeekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener()
- {
- public void onStartTrackingTouch(SeekBar seekBar)
- {
- // Do nothing
- }
-
- public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
- {
- scaleValue.setText((progress + 50) + "%");
- }
-
- public void onStopTrackingTouch(SeekBar seekBar)
- {
- // Do nothing
- }
- });
-
- scaleValue.setText((scaleSeekbar.getProgress() + 50) + "%");
+ scaleSlider.setValueTo(150);
+ scaleSlider.setValue(IntSetting.MAIN_CONTROL_SCALE.getInt(mSettings));
+ scaleSlider.setStepSize(1);
+ scaleSlider.addOnChangeListener(
+ (slider, progress, fromUser) -> scaleValue.setText(((int) progress + 50) + "%"));
+ scaleValue.setText(((int) scaleSlider.getValue() + 50) + "%");
// alpha
- final SeekBar seekbarOpacity = view.findViewById(R.id.input_opacity_seekbar);
+ final Slider sliderOpacity = view.findViewById(R.id.input_opacity_slider);
final TextView valueOpacity = view.findViewById(R.id.input_opacity_value);
+ sliderOpacity.setValueTo(100);
+ sliderOpacity.setValue(IntSetting.MAIN_CONTROL_OPACITY.getInt(mSettings));
+ sliderOpacity.setStepSize(1);
+ sliderOpacity.addOnChangeListener(
+ (slider, progress, fromUser) -> valueOpacity.setText(((int) progress) + "%"));
+ valueOpacity.setText(((int) sliderOpacity.getValue()) + "%");
- seekbarOpacity.setMax(100);
- seekbarOpacity.setProgress(IntSetting.MAIN_CONTROL_OPACITY.getInt(mSettings));
- seekbarOpacity.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener()
- {
- public void onStartTrackingTouch(SeekBar seekBar)
- {
- // Do nothing
- }
- public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
- {
- valueOpacity.setText(progress + "%");
- }
-
- public void onStopTrackingTouch(SeekBar seekBar)
- {
- // Do nothing
- }
- });
- valueOpacity.setText(seekbarOpacity.getProgress() + "%");
-
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
- builder.setTitle(R.string.emulation_control_adjustments);
- builder.setView(view);
- builder.setPositiveButton(R.string.ok, (dialogInterface, i) ->
- {
- IntSetting.MAIN_CONTROL_SCALE.setInt(mSettings, scaleSeekbar.getProgress());
- IntSetting.MAIN_CONTROL_OPACITY.setInt(mSettings, seekbarOpacity.getProgress());
- mEmulationFragment.refreshInputOverlay();
- });
- builder.setNeutralButton(R.string.default_values, (dialogInterface, i) ->
- {
- IntSetting.MAIN_CONTROL_SCALE.delete(mSettings);
- IntSetting.MAIN_CONTROL_OPACITY.delete(mSettings);
- mEmulationFragment.refreshInputOverlay();
- });
-
- builder.show();
+ new MaterialAlertDialogBuilder(this)
+ .setTitle(R.string.emulation_control_adjustments)
+ .setView(view)
+ .setPositiveButton(R.string.ok, (dialog, which) ->
+ {
+ IntSetting.MAIN_CONTROL_SCALE.setInt(mSettings, (int) scaleSlider.getValue());
+ IntSetting.MAIN_CONTROL_OPACITY.setInt(mSettings, (int) sliderOpacity.getValue());
+ mEmulationFragment.refreshInputOverlay();
+ })
+ .setNeutralButton(R.string.default_values, (dialog, which) ->
+ {
+ IntSetting.MAIN_CONTROL_SCALE.delete(mSettings);
+ IntSetting.MAIN_CONTROL_OPACITY.delete(mSettings);
+ mEmulationFragment.refreshInputOverlay();
+ })
+ .show();
}
private void chooseController()
{
final SharedPreferences.Editor editor = mPreferences.edit();
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
- builder.setTitle(R.string.emulation_choose_controller);
- builder.setSingleChoiceItems(R.array.controllersEntries,
- InputOverlay.getConfiguredControllerType(this),
- (dialog, indexSelected) ->
+ new MaterialAlertDialogBuilder(this)
+ .setTitle(R.string.emulation_choose_controller)
+ .setSingleChoiceItems(R.array.controllersEntries,
+ InputOverlay.getConfiguredControllerType(this),
+ (dialog, indexSelected) ->
+ {
+ editor.putInt("wiiController", indexSelected);
+
+ updateWiimoteNewController(indexSelected, this);
+ NativeLibrary.ReloadWiimoteConfig();
+ })
+ .setPositiveButton(R.string.ok, (dialogInterface, i) ->
{
- editor.putInt("wiiController", indexSelected);
-
- updateWiimoteNewController(indexSelected, this);
- NativeLibrary.ReloadWiimoteConfig();
- });
- builder.setPositiveButton(R.string.ok, (dialogInterface, i) ->
- {
- editor.apply();
- mEmulationFragment.refreshInputOverlay();
- });
-
- builder.show();
+ editor.apply();
+ mEmulationFragment.refreshInputOverlay();
+ })
+ .show();
}
private void showMotionControlsOptions()
{
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
- builder.setTitle(R.string.emulation_motion_controls);
- builder.setSingleChoiceItems(R.array.motionControlsEntries,
- IntSetting.MAIN_MOTION_CONTROLS.getInt(mSettings),
- (dialog, indexSelected) ->
- {
- IntSetting.MAIN_MOTION_CONTROLS.setInt(mSettings, indexSelected);
+ new MaterialAlertDialogBuilder(this)
+ .setTitle(R.string.emulation_motion_controls)
+ .setSingleChoiceItems(R.array.motionControlsEntries,
+ IntSetting.MAIN_MOTION_CONTROLS.getInt(mSettings),
+ (dialog, indexSelected) ->
+ {
+ IntSetting.MAIN_MOTION_CONTROLS.setInt(mSettings, indexSelected);
- updateMotionListener();
+ updateMotionListener();
- updateWiimoteNewImuIr(indexSelected);
- NativeLibrary.ReloadWiimoteConfig();
- });
- builder.setPositiveButton(R.string.ok, (dialogInterface, i) -> dialogInterface.dismiss());
-
- builder.show();
+ updateWiimoteNewImuIr(indexSelected);
+ NativeLibrary.ReloadWiimoteConfig();
+ })
+ .setPositiveButton(R.string.ok, (dialogInterface, i) -> dialogInterface.dismiss())
+ .show();
}
private void setIRMode()
{
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
- builder.setTitle(R.string.emulation_ir_mode);
- builder.setSingleChoiceItems(R.array.irModeEntries,
- IntSetting.MAIN_IR_MODE.getInt(mSettings),
- (dialog, indexSelected) ->
- IntSetting.MAIN_IR_MODE.setInt(mSettings, indexSelected));
- builder.setPositiveButton(R.string.ok, (dialogInterface, i) ->
- mEmulationFragment.refreshOverlayPointer(mSettings));
-
- builder.show();
+ new MaterialAlertDialogBuilder(this)
+ .setTitle(R.string.emulation_ir_mode)
+ .setSingleChoiceItems(R.array.irModeEntries,
+ IntSetting.MAIN_IR_MODE.getInt(mSettings),
+ (dialog, indexSelected) ->
+ IntSetting.MAIN_IR_MODE.setInt(mSettings, indexSelected))
+ .setPositiveButton(R.string.ok, (dialogInterface, i) ->
+ mEmulationFragment.refreshOverlayPointer(mSettings))
+ .show();
}
private void setIRSensitivity()
@@ -1054,59 +1028,30 @@ public final class EmulationActivity extends AppCompatActivity
TextView text_slider_value_pitch = view.findViewById(R.id.text_ir_pitch);
TextView units = view.findViewById(R.id.text_ir_pitch_units);
- SeekBar seekbar_pitch = view.findViewById(R.id.seekbar_pitch);
+ Slider slider_pitch = view.findViewById(R.id.slider_pitch);
text_slider_value_pitch.setText(String.valueOf(ir_pitch));
units.setText(getString(R.string.pitch));
- seekbar_pitch.setMax(100);
- seekbar_pitch.setProgress(ir_pitch);
- seekbar_pitch.setKeyProgressIncrement(5);
- seekbar_pitch.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener()
- {
- @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
- {
- text_slider_value_pitch.setText(String.valueOf(progress));
- }
-
- @Override public void onStartTrackingTouch(SeekBar seekBar)
- {
- // Do nothing
- }
-
- @Override public void onStopTrackingTouch(SeekBar seekBar)
- {
- // Do nothing
- }
- });
+ slider_pitch.setValueTo(100);
+ slider_pitch.setValue(ir_pitch);
+ slider_pitch.setStepSize(1);
+ slider_pitch.addOnChangeListener(
+ (slider, progress, fromUser) -> text_slider_value_pitch.setText(
+ String.valueOf((int) progress)));
int ir_yaw = ini.getInt(Settings.SECTION_CONTROLS, SettingsFile.KEY_WIIBIND_IR_YAW, 25);
TextView text_slider_value_yaw = view.findViewById(R.id.text_ir_yaw);
TextView units_yaw = view.findViewById(R.id.text_ir_yaw_units);
- SeekBar seekbar_yaw = view.findViewById(R.id.seekbar_width);
+ Slider seekbar_yaw = view.findViewById(R.id.slider_width);
text_slider_value_yaw.setText(String.valueOf(ir_yaw));
units_yaw.setText(getString(R.string.yaw));
- seekbar_yaw.setMax(100);
- seekbar_yaw.setProgress(ir_yaw);
- seekbar_yaw.setKeyProgressIncrement(5);
- seekbar_yaw.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener()
- {
- @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
- {
- text_slider_value_yaw.setText(String.valueOf(progress));
- }
-
- @Override public void onStartTrackingTouch(SeekBar seekBar)
- {
- // Do nothing
- }
-
- @Override public void onStopTrackingTouch(SeekBar seekBar)
- {
- // Do nothing
- }
- });
+ seekbar_yaw.setValueTo(100);
+ seekbar_yaw.setValue(ir_yaw);
+ seekbar_yaw.setStepSize(1);
+ seekbar_yaw.addOnChangeListener((slider, progress, fromUser) -> text_slider_value_yaw.setText(
+ String.valueOf((int) progress)));
int ir_vertical_offset =
@@ -1114,71 +1059,52 @@ public final class EmulationActivity extends AppCompatActivity
TextView text_slider_value_vertical_offset = view.findViewById(R.id.text_ir_vertical_offset);
TextView units_vertical_offset = view.findViewById(R.id.text_ir_vertical_offset_units);
- SeekBar seekbar_vertical_offset = view.findViewById(R.id.seekbar_vertical_offset);
+ Slider seekbar_vertical_offset = view.findViewById(R.id.slider_vertical_offset);
text_slider_value_vertical_offset.setText(String.valueOf(ir_vertical_offset));
units_vertical_offset.setText(getString(R.string.vertical_offset));
- seekbar_vertical_offset.setMax(100);
- seekbar_vertical_offset.setProgress(ir_vertical_offset);
- seekbar_vertical_offset.setKeyProgressIncrement(5);
- seekbar_vertical_offset.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener()
- {
- @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
- {
- text_slider_value_vertical_offset.setText(String.valueOf(progress));
- }
+ seekbar_vertical_offset.setValueTo(100);
+ seekbar_vertical_offset.setValue(ir_vertical_offset);
+ seekbar_vertical_offset.setStepSize(1);
+ seekbar_vertical_offset.addOnChangeListener(
+ (slider, progress, fromUser) -> text_slider_value_vertical_offset.setText(
+ String.valueOf((int) progress)));
- @Override public void onStartTrackingTouch(SeekBar seekBar)
- {
- // Do nothing
- }
+ new MaterialAlertDialogBuilder(this)
+ .setTitle(getString(R.string.emulation_ir_sensitivity))
+ .setView(view)
+ .setPositiveButton(R.string.ok, (dialogInterface, i) ->
+ {
+ ini.setString(Settings.SECTION_CONTROLS, SettingsFile.KEY_WIIBIND_IR_PITCH,
+ text_slider_value_pitch.getText().toString());
+ ini.setString(Settings.SECTION_CONTROLS, SettingsFile.KEY_WIIBIND_IR_YAW,
+ text_slider_value_yaw.getText().toString());
+ ini.setString(Settings.SECTION_CONTROLS, SettingsFile.KEY_WIIBIND_IR_VERTICAL_OFFSET,
+ text_slider_value_vertical_offset.getText().toString());
+ ini.save(file);
- @Override public void onStopTrackingTouch(SeekBar seekBar)
- {
- // Do nothing
- }
- });
+ NativeLibrary.ReloadWiimoteConfig();
+ })
+ .setNegativeButton(R.string.cancel, null)
+ .setNeutralButton(R.string.default_values, (dialogInterface, i) ->
+ {
+ ini.deleteKey(Settings.SECTION_CONTROLS, SettingsFile.KEY_WIIBIND_IR_PITCH);
+ ini.deleteKey(Settings.SECTION_CONTROLS, SettingsFile.KEY_WIIBIND_IR_YAW);
+ ini.deleteKey(Settings.SECTION_CONTROLS, SettingsFile.KEY_WIIBIND_IR_VERTICAL_OFFSET);
+ ini.save(file);
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
- builder.setTitle(getString(R.string.emulation_ir_sensitivity));
- builder.setView(view);
- builder.setPositiveButton(R.string.ok, (dialogInterface, i) ->
- {
- ini.setString(Settings.SECTION_CONTROLS, SettingsFile.KEY_WIIBIND_IR_PITCH,
- text_slider_value_pitch.getText().toString());
- ini.setString(Settings.SECTION_CONTROLS, SettingsFile.KEY_WIIBIND_IR_YAW,
- text_slider_value_yaw.getText().toString());
- ini.setString(Settings.SECTION_CONTROLS, SettingsFile.KEY_WIIBIND_IR_VERTICAL_OFFSET,
- text_slider_value_vertical_offset.getText().toString());
- ini.save(file);
-
- NativeLibrary.ReloadWiimoteConfig();
- });
- builder.setNegativeButton(R.string.cancel, (dialogInterface, i) ->
- {
- // Do nothing
- });
- builder.setNeutralButton(R.string.default_values, (dialogInterface, i) ->
- {
- ini.deleteKey(Settings.SECTION_CONTROLS, SettingsFile.KEY_WIIBIND_IR_PITCH);
- ini.deleteKey(Settings.SECTION_CONTROLS, SettingsFile.KEY_WIIBIND_IR_YAW);
- ini.deleteKey(Settings.SECTION_CONTROLS, SettingsFile.KEY_WIIBIND_IR_VERTICAL_OFFSET);
- ini.save(file);
-
- NativeLibrary.ReloadWiimoteConfig();
- });
- builder.show();
+ NativeLibrary.ReloadWiimoteConfig();
+ })
+ .show();
}
private void resetOverlay()
{
- new AlertDialog.Builder(this)
+ new MaterialAlertDialogBuilder(this)
.setTitle(getString(R.string.emulation_touch_overlay_reset))
- .setPositiveButton(R.string.yes, (dialogInterface, i) ->
- mEmulationFragment.resetInputOverlay())
- .setNegativeButton(R.string.cancel, (dialogInterface, i) ->
- {
- })
+ .setPositiveButton(R.string.yes,
+ (dialogInterface, i) -> mEmulationFragment.resetInputOverlay())
+ .setNegativeButton(R.string.cancel, null)
.show();
}
@@ -1300,4 +1226,17 @@ public final class EmulationActivity extends AppCompatActivity
{
mEmulationFragment.initInputPointer();
}
+
+ @Override
+ public void setTheme(int themeId)
+ {
+ super.setTheme(themeId);
+ this.mThemeId = themeId;
+ }
+
+ @Override
+ public int getThemeId()
+ {
+ return mThemeId;
+ }
}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/UserDataActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/UserDataActivity.java
index 0ab446a67d..fddbad7e28 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/UserDataActivity.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/UserDataActivity.java
@@ -14,12 +14,15 @@ import android.widget.Button;
import android.widget.TextView;
import androidx.annotation.Nullable;
-import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
+import androidx.appcompat.widget.Toolbar;
+
+import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.utils.DirectoryInitialization;
import org.dolphinemu.dolphinemu.utils.Log;
+import org.dolphinemu.dolphinemu.utils.ThemeHelper;
import org.dolphinemu.dolphinemu.utils.ThreadUtil;
import java.io.File;
@@ -50,6 +53,8 @@ public class UserDataActivity extends AppCompatActivity
@Override
protected void onCreate(Bundle savedInstanceState)
{
+ ThemeHelper.setTheme(this);
+
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_user_data);
@@ -80,7 +85,8 @@ public class UserDataActivity extends AppCompatActivity
buttonExportUserData.setOnClickListener(view -> exportUserData());
- // show up button
+ Toolbar tb = findViewById(R.id.toolbar_user_data);
+ setSupportActionBar(tb);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
@@ -100,26 +106,25 @@ public class UserDataActivity extends AppCompatActivity
{
Uri uri = data.getData();
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ new MaterialAlertDialogBuilder(this)
+ .setMessage(R.string.user_data_import_warning)
+ .setNegativeButton(R.string.no, (dialog, i) -> dialog.dismiss())
+ .setPositiveButton(R.string.yes, (dialog, i) ->
+ {
+ dialog.dismiss();
- builder.setMessage(R.string.user_data_import_warning);
- builder.setNegativeButton(R.string.no, (dialog, i) -> dialog.dismiss());
- builder.setPositiveButton(R.string.yes, (dialog, i) ->
- {
- dialog.dismiss();
-
- ThreadUtil.runOnThreadAndShowResult(this, R.string.import_in_progress,
- R.string.do_not_close_app, () -> getResources().getString(importUserData(uri)),
- (dialogInterface) ->
- {
- if (sMustRestartApp)
- {
- System.exit(0);
- }
- });
- });
-
- builder.show();
+ ThreadUtil.runOnThreadAndShowResult(this, R.string.import_in_progress,
+ R.string.do_not_close_app,
+ () -> getResources().getString(importUserData(uri)),
+ (dialogInterface) ->
+ {
+ if (sMustRestartApp)
+ {
+ System.exit(0);
+ }
+ });
+ })
+ .show();
}
else if (requestCode == REQUEST_CODE_EXPORT && resultCode == Activity.RESULT_OK)
{
@@ -148,7 +153,7 @@ public class UserDataActivity extends AppCompatActivity
{
// Activity not found. Perhaps it was removed by the OEM, or by some new Android version
// that didn't exist at the time of writing. Not much we can do other than tell the user
- new AlertDialog.Builder(this)
+ new MaterialAlertDialogBuilder(this)
.setMessage(R.string.user_data_open_system_file_manager_failed)
.setPositiveButton(R.string.ok, null)
.show();
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/PlatformPagerAdapter.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/PlatformPagerAdapter.java
index b0541a57ec..e8d97e3fb2 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/PlatformPagerAdapter.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/PlatformPagerAdapter.java
@@ -62,7 +62,8 @@ public class PlatformPagerAdapter extends FragmentPagerAdapter
// Apparently a workaround for TabLayout not supporting icons.
// TODO: This workaround will eventually not be necessary; switch to more legit methods when that is the case
// TODO: Also remove additional hax from styles.xml
- Drawable drawable = mContext.getResources().getDrawable(TAB_ICONS[position]);
+ Drawable drawable =
+ mContext.getResources().getDrawable(TAB_ICONS[position], mContext.getTheme());
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
ImageSpan imageSpan = new ImageSpan(drawable, ImageSpan.ALIGN_BOTTOM);
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/AlertMessage.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/AlertMessage.java
index b8ba6fcbb2..69cf5ef280 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/AlertMessage.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/AlertMessage.java
@@ -6,9 +6,10 @@ import android.app.Dialog;
import android.os.Bundle;
import androidx.annotation.NonNull;
-import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.DialogFragment;
+import com.google.android.material.dialog.MaterialAlertDialogBuilder;
+
import org.dolphinemu.dolphinemu.NativeLibrary;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.activities.EmulationActivity;
@@ -47,7 +48,7 @@ public final class AlertMessage extends DialogFragment
boolean isWarning = requireArguments().getBoolean(ARG_IS_WARNING);
setCancelable(false);
- AlertDialog.Builder builder = new AlertDialog.Builder(emulationActivity)
+ MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(emulationActivity)
.setTitle(title)
.setMessage(message);
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/GameDetailsDialog.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/GameDetailsDialog.java
index 2b1bf87bee..4da860ddc4 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/GameDetailsDialog.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/GameDetailsDialog.java
@@ -9,9 +9,10 @@ import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
-import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.DialogFragment;
+import com.google.android.material.dialog.MaterialAlertDialogBuilder;
+
import org.dolphinemu.dolphinemu.NativeLibrary;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.model.GameFile;
@@ -38,7 +39,6 @@ public final class GameDetailsDialog extends DialogFragment
{
GameFile gameFile = GameFileCacheManager.addOrGet(getArguments().getString(ARG_GAME_PATH));
- AlertDialog.Builder builder = new AlertDialog.Builder(requireActivity());
ViewGroup contents = (ViewGroup) getActivity().getLayoutInflater()
.inflate(R.layout.dialog_game_details, null);
@@ -116,7 +116,8 @@ public final class GameDetailsDialog extends DialogFragment
PicassoUtils.loadGameBanner(banner, gameFile);
- builder.setView(contents);
- return builder.create();
+ return new MaterialAlertDialogBuilder(requireActivity())
+ .setView(contents)
+ .create();
}
}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/GamePropertiesDialog.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/GamePropertiesDialog.java
index 0c9b16cb01..339434e8e3 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/GamePropertiesDialog.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/GamePropertiesDialog.java
@@ -8,9 +8,10 @@ import android.os.Bundle;
import android.widget.Toast;
import androidx.annotation.NonNull;
-import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.DialogFragment;
+import com.google.android.material.dialog.MaterialAlertDialogBuilder;
+
import org.dolphinemu.dolphinemu.DolphinApplication;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.activities.ConvertActivity;
@@ -117,16 +118,16 @@ public class GamePropertiesDialog extends DialogFragment
itemsBuilder.add(R.string.properties_clear_game_settings, (dialog, i) ->
clearGameSettingsWithConfirmation(gameId));
- AlertDialog.Builder builder = new AlertDialog.Builder(requireContext());
+ MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(requireContext())
+ .setTitle(requireContext()
+ .getString(R.string.preferences_game_properties_with_game_id, gameId));
itemsBuilder.applyToBuilder(builder);
- builder.setTitle(requireContext()
- .getString(R.string.preferences_game_properties_with_game_id, gameId));
return builder.create();
}
private void clearGameSettingsWithConfirmation(String gameId)
{
- new AlertDialog.Builder(requireContext())
+ new MaterialAlertDialogBuilder(requireContext())
.setTitle(R.string.properties_clear_game_settings)
.setMessage(R.string.properties_clear_game_settings_confirmation)
.setPositiveButton(R.string.yes, (dialog, i) -> clearGameSettings(gameId))
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/MotionAlertDialog.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/MotionAlertDialog.java
index b0316f94cc..72c44cd58a 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/MotionAlertDialog.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/dialogs/MotionAlertDialog.java
@@ -3,13 +3,29 @@
package org.dolphinemu.dolphinemu.dialogs;
import android.content.Context;
+import android.content.res.ColorStateList;
+import android.content.res.Resources;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.os.Build;
+import android.util.TypedValue;
import android.view.InputDevice;
import android.view.KeyEvent;
import android.view.MotionEvent;
+import androidx.annotation.AttrRes;
import androidx.annotation.NonNull;
+import androidx.annotation.StyleRes;
import androidx.appcompat.app.AlertDialog;
+import androidx.appcompat.view.ContextThemeWrapper;
+import androidx.core.view.ViewCompat;
+import com.google.android.material.color.MaterialColors;
+import com.google.android.material.dialog.MaterialDialogs;
+import com.google.android.material.resources.MaterialAttributes;
+import com.google.android.material.shape.MaterialShapeDrawable;
+
+import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.features.settings.model.view.InputBindingSetting;
import org.dolphinemu.dolphinemu.features.settings.ui.SettingsAdapter;
import org.dolphinemu.dolphinemu.utils.ControllerMappingHelper;
@@ -18,12 +34,20 @@ import org.dolphinemu.dolphinemu.utils.Log;
import java.util.ArrayList;
import java.util.List;
+import static com.google.android.material.theme.overlay.MaterialThemeOverlay.wrap;
+
/**
* {@link AlertDialog} derivative that listens for
* motion events from controllers and joysticks.
*/
public final class MotionAlertDialog extends AlertDialog
{
+ @AttrRes private static final int DEF_STYLE_ATTR = R.attr.alertDialogStyle;
+ @StyleRes private static final int DEF_STYLE_RES = R.style.MaterialAlertDialog_MaterialComponents;
+
+ @AttrRes
+ private static final int MATERIAL_ALERT_DIALOG_THEME_OVERLAY = R.attr.materialAlertDialogTheme;
+
// The selected input preference
private final InputBindingSetting setting;
private final ArrayList mPreviousValues = new ArrayList<>();
@@ -39,10 +63,63 @@ public final class MotionAlertDialog extends AlertDialog
*/
public MotionAlertDialog(Context context, InputBindingSetting setting, SettingsAdapter adapter)
{
- super(context);
+ super(createMaterialAlertDialogThemedContext(context));
this.setting = setting;
mAdapter = adapter;
+
+ // Using code from MaterialAlertDialogBuilder allows us to nearly perfectly recreate its look
+ context = getContext();
+ Resources.Theme theme = context.getTheme();
+
+ int surfaceColor =
+ MaterialColors.getColor(context, R.attr.colorSurface, getClass().getCanonicalName());
+ MaterialShapeDrawable materialShapeDrawable =
+ new MaterialShapeDrawable(context, null, R.attr.alertDialogStyle,
+ R.style.MaterialAlertDialog_MaterialComponents);
+ materialShapeDrawable.initializeElevationOverlay(context);
+ materialShapeDrawable.setFillColor(ColorStateList.valueOf(surfaceColor));
+ materialShapeDrawable.setElevation(ViewCompat.getElevation(this.getWindow().getDecorView()));
+ this.getWindow().setBackgroundDrawable(materialShapeDrawable);
+
+ Rect backgroundInsets =
+ MaterialDialogs.getDialogBackgroundInsets(context, R.attr.alertDialogStyle,
+ R.style.MaterialAlertDialog_MaterialComponents);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P)
+ {
+ TypedValue dialogCornerRadiusValue = new TypedValue();
+ theme.resolveAttribute(android.R.attr.dialogCornerRadius, dialogCornerRadiusValue, true);
+ float dialogCornerRadius =
+ dialogCornerRadiusValue.getDimension(context.getResources().getDisplayMetrics());
+ if (dialogCornerRadiusValue.type == TypedValue.TYPE_DIMENSION && dialogCornerRadius >= 0)
+ {
+ materialShapeDrawable.setCornerSize(dialogCornerRadius);
+ }
+ }
+ Drawable insetDrawable = MaterialDialogs.insetDrawable(materialShapeDrawable, backgroundInsets);
+ this.getWindow().setBackgroundDrawable(insetDrawable);
+ }
+
+ private static Context createMaterialAlertDialogThemedContext(@NonNull Context context)
+ {
+ int themeOverlayId = getMaterialAlertDialogThemeOverlay(context);
+ Context themedContext = wrap(context, null, DEF_STYLE_ATTR, DEF_STYLE_RES);
+ if (themeOverlayId == 0)
+ {
+ return themedContext;
+ }
+ return new ContextThemeWrapper(themedContext, themeOverlayId);
+ }
+
+ private static int getMaterialAlertDialogThemeOverlay(@NonNull Context context)
+ {
+ TypedValue materialAlertDialogThemeOverlay =
+ MaterialAttributes.resolve(context, MATERIAL_ALERT_DIALOG_THEME_OVERLAY);
+ if (materialAlertDialogThemeOverlay == null)
+ {
+ return 0;
+ }
+ return materialAlertDialogThemeOverlay.data;
}
public boolean onKeyEvent(int keyCode, KeyEvent event)
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatDetailsFragment.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatDetailsFragment.java
index 9c207996bb..f08b04abec 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatDetailsFragment.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatDetailsFragment.java
@@ -7,16 +7,17 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
-import android.widget.EditText;
import android.widget.ScrollView;
-import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProvider;
+import com.google.android.material.dialog.MaterialAlertDialogBuilder;
+import com.google.android.material.textfield.TextInputEditText;
+import com.google.android.material.textfield.TextInputLayout;
+
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.features.cheats.model.Cheat;
import org.dolphinemu.dolphinemu.features.cheats.model.CheatsViewModel;
@@ -25,14 +26,14 @@ public class CheatDetailsFragment extends Fragment
{
private View mRoot;
private ScrollView mScrollView;
- private TextView mLabelName;
- private EditText mEditName;
- private TextView mLabelCreator;
- private EditText mEditCreator;
- private TextView mLabelNotes;
- private EditText mEditNotes;
- private TextView mLabelCode;
- private EditText mEditCode;
+ private TextInputLayout mEditNameLayout;
+ private TextInputEditText mEditName;
+ private TextInputLayout mEditCreatorLayout;
+ private TextInputEditText mEditCreator;
+ private TextInputLayout mEditNotesLayout;
+ private TextInputEditText mEditNotes;
+ private TextInputLayout mEditCodeLayout;
+ private TextInputEditText mEditCode;
private Button mButtonDelete;
private Button mButtonEdit;
private Button mButtonCancel;
@@ -54,14 +55,14 @@ public class CheatDetailsFragment extends Fragment
{
mRoot = view.findViewById(R.id.root);
mScrollView = view.findViewById(R.id.scroll_view);
- mLabelName = view.findViewById(R.id.label_name);
- mEditName = view.findViewById(R.id.edit_name);
- mLabelCreator = view.findViewById(R.id.label_creator);
- mEditCreator = view.findViewById(R.id.edit_creator);
- mLabelNotes = view.findViewById(R.id.label_notes);
- mEditNotes = view.findViewById(R.id.edit_notes);
- mLabelCode = view.findViewById(R.id.label_code);
- mEditCode = view.findViewById(R.id.edit_code);
+ mEditNameLayout = view.findViewById(R.id.edit_name);
+ mEditName = view.findViewById(R.id.edit_name_input);
+ mEditCreatorLayout = view.findViewById(R.id.edit_creator);
+ mEditCreator = view.findViewById(R.id.edit_creator_input);
+ mEditNotesLayout = view.findViewById(R.id.edit_notes);
+ mEditNotes = view.findViewById(R.id.edit_notes_input);
+ mEditCodeLayout = view.findViewById(R.id.edit_code);
+ mEditCode = view.findViewById(R.id.edit_code_input);
mButtonDelete = view.findViewById(R.id.button_delete);
mButtonEdit = view.findViewById(R.id.button_edit);
mButtonCancel = view.findViewById(R.id.button_cancel);
@@ -84,18 +85,17 @@ public class CheatDetailsFragment extends Fragment
private void clearEditErrors()
{
- mEditName.setError(null);
- mEditCode.setError(null);
+ mEditNameLayout.setError(null);
+ mEditCodeLayout.setError(null);
}
private void onDeleteClicked(View view)
{
- AlertDialog.Builder builder =
- new AlertDialog.Builder(requireContext());
- builder.setMessage(getString(R.string.cheats_delete_confirmation, mCheat.getName()));
- builder.setPositiveButton(R.string.yes, (dialog, i) -> mViewModel.deleteSelectedCheat());
- builder.setNegativeButton(R.string.no, null);
- builder.show();
+ new MaterialAlertDialogBuilder(requireContext())
+ .setMessage(getString(R.string.cheats_delete_confirmation, mCheat.getName()))
+ .setPositiveButton(R.string.yes, (dialog, i) -> mViewModel.deleteSelectedCheat())
+ .setNegativeButton(R.string.no, null)
+ .show();
}
private void onEditClicked(View view)
@@ -134,19 +134,19 @@ public class CheatDetailsFragment extends Fragment
mButtonEdit.requestFocus();
break;
case Cheat.TRY_SET_FAIL_NO_NAME:
- mEditName.setError(getString(R.string.cheats_error_no_name));
- mScrollView.smoothScrollTo(0, mLabelName.getTop());
+ mEditNameLayout.setError(getString(R.string.cheats_error_no_name));
+ mScrollView.smoothScrollTo(0, mEditName.getTop());
break;
case Cheat.TRY_SET_FAIL_NO_CODE_LINES:
- mEditCode.setError(getString(R.string.cheats_error_no_code_lines));
+ mEditCodeLayout.setError(getString(R.string.cheats_error_no_code_lines));
mScrollView.smoothScrollTo(0, mEditCode.getBottom());
break;
case Cheat.TRY_SET_FAIL_CODE_MIXED_ENCRYPTION:
- mEditCode.setError(getString(R.string.cheats_error_mixed_encryption));
+ mEditCodeLayout.setError(getString(R.string.cheats_error_mixed_encryption));
mScrollView.smoothScrollTo(0, mEditCode.getBottom());
break;
default:
- mEditCode.setError(getString(R.string.cheats_error_on_line, result));
+ mEditCodeLayout.setError(getString(R.string.cheats_error_on_line, result));
mScrollView.smoothScrollTo(0, mEditCode.getBottom());
break;
}
@@ -161,12 +161,9 @@ public class CheatDetailsFragment extends Fragment
int creatorVisibility = cheat != null && cheat.supportsCreator() ? View.VISIBLE : View.GONE;
int notesVisibility = cheat != null && cheat.supportsNotes() ? View.VISIBLE : View.GONE;
int codeVisibility = cheat != null && cheat.supportsCode() ? View.VISIBLE : View.GONE;
- mLabelCreator.setVisibility(creatorVisibility);
- mEditCreator.setVisibility(creatorVisibility);
- mLabelNotes.setVisibility(notesVisibility);
- mEditNotes.setVisibility(notesVisibility);
- mLabelCode.setVisibility(codeVisibility);
- mEditCode.setVisibility(codeVisibility);
+ mEditCreatorLayout.setVisibility(creatorVisibility);
+ mEditNotesLayout.setVisibility(notesVisibility);
+ mEditCodeLayout.setVisibility(codeVisibility);
boolean userDefined = cheat != null && cheat.getUserDefined();
mButtonDelete.setEnabled(userDefined);
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatsActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatsActivity.java
index b3bb5cb0cd..c89aea45dc 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatsActivity.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/cheats/ui/CheatsActivity.java
@@ -13,10 +13,13 @@ import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
+import androidx.appcompat.widget.Toolbar;
import androidx.core.view.ViewCompat;
import androidx.lifecycle.ViewModelProvider;
import androidx.slidingpanelayout.widget.SlidingPaneLayout;
+import com.google.android.material.dialog.MaterialAlertDialogBuilder;
+
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.features.cheats.model.Cheat;
import org.dolphinemu.dolphinemu.features.cheats.model.CheatsViewModel;
@@ -24,6 +27,7 @@ import org.dolphinemu.dolphinemu.features.cheats.model.GeckoCheat;
import org.dolphinemu.dolphinemu.features.settings.model.Settings;
import org.dolphinemu.dolphinemu.ui.TwoPaneOnBackPressedCallback;
import org.dolphinemu.dolphinemu.ui.main.MainPresenter;
+import org.dolphinemu.dolphinemu.utils.ThemeHelper;
public class CheatsActivity extends AppCompatActivity
implements SlidingPaneLayout.PanelSlideListener
@@ -60,6 +64,8 @@ public class CheatsActivity extends AppCompatActivity
@Override
protected void onCreate(Bundle savedInstanceState)
{
+ ThemeHelper.setTheme(this);
+
super.onCreate(savedInstanceState);
MainPresenter.skipRescanningLibrary();
@@ -94,7 +100,8 @@ public class CheatsActivity extends AppCompatActivity
mViewModel.getOpenDetailsViewEvent().observe(this, this::openDetailsView);
- // show up button
+ Toolbar tb = findViewById(R.id.toolbar_cheats);
+ setSupportActionBar(tb);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
@@ -191,10 +198,10 @@ public class CheatsActivity extends AppCompatActivity
public void downloadGeckoCodes()
{
- AlertDialog progressDialog = new AlertDialog.Builder(this).create();
- progressDialog.setTitle(R.string.cheats_downloading);
- progressDialog.setCancelable(false);
- progressDialog.show();
+ AlertDialog progressDialog = new MaterialAlertDialogBuilder(this)
+ .setMessage(R.string.cheats_downloading)
+ .setCancelable(false)
+ .show();
new Thread(() ->
{
@@ -206,14 +213,14 @@ public class CheatsActivity extends AppCompatActivity
if (codes == null)
{
- new AlertDialog.Builder(this)
+ new MaterialAlertDialogBuilder(this)
.setMessage(getString(R.string.cheats_download_failed))
.setPositiveButton(R.string.ok, null)
.show();
}
else if (codes.length == 0)
{
- new AlertDialog.Builder(this)
+ new MaterialAlertDialogBuilder(this)
.setMessage(getString(R.string.cheats_download_empty))
.setPositiveButton(R.string.ok, null)
.show();
@@ -223,7 +230,7 @@ public class CheatsActivity extends AppCompatActivity
int cheatsAdded = mViewModel.addDownloadedGeckoCodes(codes);
String message = getString(R.string.cheats_download_succeeded, codes.length, cheatsAdded);
- new AlertDialog.Builder(this)
+ new MaterialAlertDialogBuilder(this)
.setMessage(message)
.setPositiveButton(R.string.ok, null)
.show();
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/riivolution/ui/RiivolutionBootActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/riivolution/ui/RiivolutionBootActivity.java
index 7509aaf37a..4cc014d646 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/riivolution/ui/RiivolutionBootActivity.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/riivolution/ui/RiivolutionBootActivity.java
@@ -17,6 +17,7 @@ import org.dolphinemu.dolphinemu.activities.EmulationActivity;
import org.dolphinemu.dolphinemu.features.riivolution.model.RiivolutionPatches;
import org.dolphinemu.dolphinemu.features.settings.model.StringSetting;
import org.dolphinemu.dolphinemu.utils.DirectoryInitialization;
+import org.dolphinemu.dolphinemu.utils.ThemeHelper;
public class RiivolutionBootActivity extends AppCompatActivity
{
@@ -41,6 +42,8 @@ public class RiivolutionBootActivity extends AppCompatActivity
@Override
protected void onCreate(Bundle savedInstanceState)
{
+ ThemeHelper.setTheme(this);
+
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_riivolution_boot);
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 a06c4f8d61..8685c20a90 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
@@ -33,6 +33,7 @@ public enum IntSetting implements AbstractIntSetting
MAIN_CONTROL_OPACITY(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID, "ControlOpacity", 65),
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_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/SettingsActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsActivity.java
index 8f3d587b3f..1139688418 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsActivity.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsActivity.java
@@ -2,7 +2,6 @@
package org.dolphinemu.dolphinemu.features.settings.ui;
-import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
@@ -15,13 +14,18 @@ import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
+import androidx.appcompat.widget.Toolbar;
import androidx.fragment.app.FragmentTransaction;
import androidx.lifecycle.ViewModelProvider;
+import com.google.android.material.appbar.CollapsingToolbarLayout;
+import com.google.android.material.dialog.MaterialAlertDialogBuilder;
+
import org.dolphinemu.dolphinemu.NativeLibrary;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.ui.main.MainPresenter;
import org.dolphinemu.dolphinemu.utils.FileBrowserHelper;
+import org.dolphinemu.dolphinemu.utils.ThemeHelper;
import java.util.Set;
@@ -34,7 +38,9 @@ public final class SettingsActivity extends AppCompatActivity implements Setting
private static final String FRAGMENT_TAG = "settings";
private SettingsActivityPresenter mPresenter;
- private ProgressDialog dialog;
+ private AlertDialog dialog;
+
+ private CollapsingToolbarLayout mToolbarLayout;
public static void launch(Context context, MenuTag menuTag, String gameId, int revision,
boolean isWii)
@@ -58,6 +64,8 @@ public final class SettingsActivity extends AppCompatActivity implements Setting
@Override
protected void onCreate(Bundle savedInstanceState)
{
+ ThemeHelper.setTheme(this);
+
super.onCreate(savedInstanceState);
// If we came here from the game list, we don't want to rescan when returning to the game list.
@@ -80,7 +88,9 @@ public final class SettingsActivity extends AppCompatActivity implements Setting
mPresenter = new SettingsActivityPresenter(this, getSettings());
mPresenter.onCreate(savedInstanceState, menuTag, gameID, revision, isWii, this);
- // show up button
+ Toolbar tb = findViewById(R.id.toolbar_settings);
+ mToolbarLayout = findViewById(R.id.toolbar_settings_layout);
+ setSupportActionBar(tb);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
@@ -211,11 +221,12 @@ public final class SettingsActivity extends AppCompatActivity implements Setting
{
if (dialog == null)
{
- dialog = new ProgressDialog(this);
- dialog.setMessage(getString(R.string.load_settings));
- dialog.setIndeterminate(true);
+ dialog = new MaterialAlertDialogBuilder(this)
+ .setTitle(getString(R.string.load_settings))
+ .setView(getLayoutInflater().inflate(R.layout.dialog_indeterminate_progress, null,
+ false))
+ .create();
}
-
dialog.show();
}
@@ -228,7 +239,7 @@ public final class SettingsActivity extends AppCompatActivity implements Setting
@Override
public void showGameIniJunkDeletionQuestion()
{
- new AlertDialog.Builder(this)
+ new MaterialAlertDialogBuilder(this)
.setTitle(getString(R.string.game_ini_junk_title))
.setMessage(getString(R.string.game_ini_junk_question))
.setPositiveButton(R.string.yes, (dialogInterface, i) -> mPresenter.clearSettings())
@@ -312,4 +323,9 @@ public final class SettingsActivity extends AppCompatActivity implements Setting
{
return (SettingsFragment) getSupportFragmentManager().findFragmentByTag(FRAGMENT_TAG);
}
+
+ public void setToolbarTitle(String title)
+ {
+ mToolbarLayout.setTitle(title);
+ }
}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsActivityView.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsActivityView.java
index b1b5ec8bd6..da14f5c5cb 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsActivityView.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsActivityView.java
@@ -108,4 +108,9 @@ public interface SettingsActivityView
* Tell the user that there is junk in the game INI and ask if they want to delete the whole file.
*/
void showGameIniJunkDeletionQuestion();
+
+ /**
+ * Accesses the material toolbar layout and changes the title
+ */
+ void setToolbarTitle(String title);
}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsAdapter.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsAdapter.java
index 893773dbd0..d8ceb5ba29 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsAdapter.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsAdapter.java
@@ -10,13 +10,16 @@ import android.provider.DocumentsContract;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
-import android.widget.EditText;
-import android.widget.SeekBar;
import android.widget.TextView;
+import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.recyclerview.widget.RecyclerView;
+import com.google.android.material.dialog.MaterialAlertDialogBuilder;
+import com.google.android.material.slider.Slider;
+import com.google.android.material.textfield.TextInputEditText;
+
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.dialogs.MotionAlertDialog;
import org.dolphinemu.dolphinemu.features.settings.model.Settings;
@@ -56,7 +59,7 @@ import java.io.RandomAccessFile;
import java.util.ArrayList;
public final class SettingsAdapter extends RecyclerView.Adapter
- implements DialogInterface.OnClickListener, SeekBar.OnSeekBarChangeListener
+ implements DialogInterface.OnClickListener, Slider.OnChangeListener
{
private final SettingsFragmentView mView;
private final Context mContext;
@@ -64,7 +67,6 @@ public final class SettingsAdapter extends RecyclerView.Adapter
- {
- String editTextInput = input.getText().toString();
+ mDialog = new MaterialAlertDialogBuilder(mView.getActivity())
+ .setView(dialogView)
+ .setMessage(item.getDescription())
+ .setPositiveButton(R.string.ok, (dialogInterface, i) ->
+ {
+ String editTextInput = input.getText().toString();
- if (!item.getSelectedValue(mView.getSettings()).equals(editTextInput))
- {
- notifyItemChanged(position);
- mView.onSettingChanged();
- }
+ if (!item.getSelectedValue(mView.getSettings()).equals(editTextInput))
+ {
+ notifyItemChanged(position);
+ mView.onSettingChanged();
+ }
- item.setSelectedValue(mView.getSettings(), editTextInput);
- });
- builder.setNegativeButton(R.string.cancel, null);
-
- mDialog = builder.show();
+ item.setSelectedValue(mView.getSettings(), editTextInput);
+ })
+ .setNegativeButton(R.string.cancel, null)
+ .show();
}
public void onSingleChoiceClick(SingleChoiceSetting item, int position)
@@ -235,12 +236,10 @@ public final class SettingsAdapter extends RecyclerView.Adapter dialog.dismiss());
- builder.show();
+ new MaterialAlertDialogBuilder(mContext)
+ .setMessage(R.string.path_not_changeable_scoped_storage)
+ .setPositiveButton(R.string.ok, (dialog, i) -> dialog.dismiss())
+ .show();
}
else
{
@@ -509,22 +499,12 @@ public final class SettingsAdapter extends RecyclerView.Adapter= Build.VERSION_CODES.S)
+ {
+ sl.add(new SingleChoiceSetting(mContext, appTheme, R.string.change_theme, 0,
+ R.array.themeEntriesA12, R.array.themeValuesA12));
+ }
+ else
+ {
+ sl.add(new SingleChoiceSetting(mContext, appTheme, R.string.change_theme, 0,
+ R.array.themeEntries, R.array.themeValues));
+ }
}
private void addAudioSettings(ArrayList sl)
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/HeaderHyperLinkViewHolder.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/HeaderHyperLinkViewHolder.java
index 8a30e34fff..c3abf79c24 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/HeaderHyperLinkViewHolder.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/HeaderHyperLinkViewHolder.java
@@ -6,7 +6,7 @@ import android.content.Context;
import android.text.method.LinkMovementMethod;
import android.view.View;
-import androidx.core.content.ContextCompat;
+import com.google.android.material.color.MaterialColors;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.features.settings.model.view.SettingsItem;
@@ -27,7 +27,8 @@ public final class HeaderHyperLinkViewHolder extends HeaderViewHolder
public void bind(SettingsItem item)
{
super.bind(item);
+
mHeaderName.setMovementMethod(LinkMovementMethod.getInstance());
- mHeaderName.setLinkTextColor(ContextCompat.getColor(mContext, R.color.dolphin_blue_secondary));
+ mHeaderName.setLinkTextColor(MaterialColors.getColor(itemView, R.attr.colorTertiary));
}
}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/RunRunnableViewHolder.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/RunRunnableViewHolder.java
index cecc88fd21..8d7966ab14 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/RunRunnableViewHolder.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/RunRunnableViewHolder.java
@@ -8,7 +8,8 @@ import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.Nullable;
-import androidx.appcompat.app.AlertDialog;
+
+import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.features.settings.model.view.RunRunnable;
@@ -54,19 +55,16 @@ public final class RunRunnableViewHolder extends SettingViewHolder
if (alertTextID > 0)
{
- AlertDialog.Builder builder = new AlertDialog.Builder(mContext)
+ new MaterialAlertDialogBuilder(mContext)
.setTitle(mItem.getName())
- .setMessage(alertTextID);
-
- builder
+ .setMessage(alertTextID)
.setPositiveButton(R.string.ok, (dialog, whichButton) ->
{
runRunnable();
dialog.dismiss();
})
- .setNegativeButton(R.string.cancel, (dialog, whichButton) -> dialog.dismiss());
-
- builder.show();
+ .setNegativeButton(R.string.cancel, (dialog, whichButton) -> dialog.dismiss())
+ .show();
}
else
{
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/SettingViewHolder.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/SettingViewHolder.java
index a82a7cdb0a..634c75c223 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/SettingViewHolder.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/viewholder/SettingViewHolder.java
@@ -10,9 +10,10 @@ import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.Nullable;
-import androidx.appcompat.app.AlertDialog;
import androidx.recyclerview.widget.RecyclerView;
+import com.google.android.material.dialog.MaterialAlertDialogBuilder;
+
import org.dolphinemu.dolphinemu.DolphinApplication;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.features.settings.model.view.SettingsItem;
@@ -96,10 +97,8 @@ public abstract class SettingViewHolder extends RecyclerView.ViewHolder
Context context = clicked.getContext();
- AlertDialog.Builder builder = new AlertDialog.Builder(context)
- .setMessage(R.string.setting_clear_confirm);
-
- builder
+ new MaterialAlertDialogBuilder(context)
+ .setMessage(R.string.setting_clear_confirm)
.setPositiveButton(R.string.ok, (dialog, whichButton) ->
{
getAdapter().clearSetting(item, getBindingAdapterPosition());
@@ -107,9 +106,8 @@ public abstract class SettingViewHolder extends RecyclerView.ViewHolder
Toast.makeText(context, R.string.setting_cleared, Toast.LENGTH_SHORT).show();
dialog.dismiss();
})
- .setNegativeButton(R.string.cancel, (dialog, whichButton) -> dialog.dismiss());
-
- builder.show();
+ .setNegativeButton(R.string.cancel, (dialog, whichButton) -> dialog.dismiss())
+ .show();
return true;
}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/OnlineUpdateRegionSelectDialogFragment.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/OnlineUpdateRegionSelectDialogFragment.java
index d5bc94b11c..7184c7ba39 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/OnlineUpdateRegionSelectDialogFragment.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/OnlineUpdateRegionSelectDialogFragment.java
@@ -7,10 +7,11 @@ import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
-import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.DialogFragment;
import androidx.lifecycle.ViewModelProvider;
+import com.google.android.material.dialog.MaterialAlertDialogBuilder;
+
import org.dolphinemu.dolphinemu.R;
public class OnlineUpdateRegionSelectDialogFragment extends DialogFragment
@@ -23,7 +24,7 @@ public class OnlineUpdateRegionSelectDialogFragment extends DialogFragment
R.string.japan), getString(R.string.korea), getString(R.string.united_states)};
int checkedItem = -1;
- return new AlertDialog.Builder(requireContext())
+ return new MaterialAlertDialogBuilder(requireContext())
.setTitle(R.string.region_select_title)
.setSingleChoiceItems(items, checkedItem, (dialog, which) ->
{
@@ -35,8 +36,6 @@ public class OnlineUpdateRegionSelectDialogFragment extends DialogFragment
new SystemUpdateProgressBarDialogFragment();
progressBarFragment
.show(getParentFragmentManager(), "OnlineUpdateProgressBarDialogFragment");
- progressBarFragment.setCancelable(false);
-
dismiss();
})
.create();
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemMenuNotInstalledDialogFragment.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemMenuNotInstalledDialogFragment.java
index 9acf238042..671750e1d6 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemMenuNotInstalledDialogFragment.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemMenuNotInstalledDialogFragment.java
@@ -5,10 +5,11 @@ package org.dolphinemu.dolphinemu.features.sysupdate.ui;
import android.app.Dialog;
import android.os.Bundle;
-import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.FragmentManager;
+import com.google.android.material.dialog.MaterialAlertDialogBuilder;
+
import org.dolphinemu.dolphinemu.R;
public class SystemMenuNotInstalledDialogFragment extends DialogFragment
@@ -16,7 +17,7 @@ public class SystemMenuNotInstalledDialogFragment extends DialogFragment
@Override
public Dialog onCreateDialog(Bundle savedInstanceState)
{
- return new AlertDialog.Builder(requireContext())
+ return new MaterialAlertDialogBuilder(requireContext())
.setTitle(R.string.system_menu_not_installed_title)
.setMessage(R.string.system_menu_not_installed_message)
.setPositiveButton(R.string.yes, (dialog, which) ->
@@ -27,10 +28,7 @@ public class SystemMenuNotInstalledDialogFragment extends DialogFragment
dialogFragment.show(fragmentManager, "OnlineUpdateRegionSelectDialogFragment");
dismiss();
})
- .setNegativeButton(R.string.no, (dialog, which) ->
- {
- dismiss();
- })
+ .setNegativeButton(R.string.no, (dialog, which) -> dismiss())
.create();
}
}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemUpdateProgressBarDialogFragment.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemUpdateProgressBarDialogFragment.java
index 2cb520552a..152e1aca64 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemUpdateProgressBarDialogFragment.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemUpdateProgressBarDialogFragment.java
@@ -3,15 +3,20 @@
package org.dolphinemu.dolphinemu.features.sysupdate.ui;
import android.app.Dialog;
-import android.app.ProgressDialog;
import android.content.pm.ActivityInfo;
import android.os.Bundle;
+import android.view.View;
+import android.widget.Button;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.DialogFragment;
import androidx.lifecycle.ViewModelProvider;
+import com.google.android.material.dialog.MaterialAlertDialogBuilder;
+import com.google.android.material.progressindicator.LinearProgressIndicator;
+
import org.dolphinemu.dolphinemu.R;
public class SystemUpdateProgressBarDialogFragment extends DialogFragment
@@ -28,28 +33,20 @@ public class SystemUpdateProgressBarDialogFragment extends DialogFragment
SystemUpdateViewModel viewModel =
new ViewModelProvider(requireActivity()).get(SystemUpdateViewModel.class);
- ProgressDialog progressDialog = new ProgressDialog(requireContext());
- progressDialog.setTitle(getString(R.string.updating));
- // We need to set the message to something here, otherwise the text will not appear when we set it later.
- progressDialog.setMessage("");
- progressDialog.setButton(Dialog.BUTTON_NEGATIVE, getString(R.string.cancel), (dialog, i) ->
- {
- });
- progressDialog.setOnShowListener((dialogInterface) ->
- {
- // By default, the ProgressDialog will immediately dismiss itself upon a button being pressed.
- // Setting the OnClickListener again after the dialog is shown overrides this behavior.
- progressDialog.getButton(Dialog.BUTTON_NEGATIVE).setOnClickListener((view) ->
- {
- viewModel.setCanceled();
- });
- });
- progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
+ View dialogView = getLayoutInflater().inflate(R.layout.dialog_progress, null, false);
+ LinearProgressIndicator progressBar = dialogView.findViewById(R.id.update_progress);
- viewModel.getProgressData().observe(this, (@Nullable Integer progress) ->
- {
- progressDialog.setProgress(progress.intValue());
- });
+ // We need to set the message to something here, otherwise the text will not appear when we set it later.
+ AlertDialog progressDialog = new MaterialAlertDialogBuilder(requireContext())
+ .setTitle(getString(R.string.updating))
+ .setMessage("")
+ .setNegativeButton(getString(R.string.cancel), null)
+ .setView(dialogView)
+ .setCancelable(false)
+ .create();
+
+ viewModel.getProgressData()
+ .observe(this, (@Nullable Integer progress) -> progressBar.setProgress(progress));
viewModel.getTotalData().observe(this, (@Nullable Integer total) ->
{
@@ -58,13 +55,11 @@ public class SystemUpdateProgressBarDialogFragment extends DialogFragment
return;
}
- progressDialog.setMax(total.intValue());
+ progressBar.setMax(total);
});
- viewModel.getTitleIdData().observe(this, (@Nullable Long titleId) ->
- {
- progressDialog.setMessage(getString(R.string.updating_message, titleId));
- });
+ viewModel.getTitleIdData().observe(this, (@Nullable Long titleId) -> progressDialog.setMessage(
+ getString(R.string.updating_message, titleId)));
viewModel.getResultData().observe(this, (@Nullable Integer result) ->
{
@@ -88,4 +83,17 @@ public class SystemUpdateProgressBarDialogFragment extends DialogFragment
}
return progressDialog;
}
+
+ // By default, the ProgressDialog will immediately dismiss itself upon a button being pressed.
+ // Setting the OnClickListener again after the dialog is shown overrides this behavior.
+ @Override
+ public void onResume()
+ {
+ super.onResume();
+ AlertDialog alertDialog = (AlertDialog) getDialog();
+ SystemUpdateViewModel viewModel =
+ new ViewModelProvider(requireActivity()).get(SystemUpdateViewModel.class);
+ Button negativeButton = alertDialog.getButton(Dialog.BUTTON_NEGATIVE);
+ negativeButton.setOnClickListener(v -> viewModel.setCanceled());
+ }
}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemUpdateResultFragment.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemUpdateResultFragment.java
index 292aadbd7e..a8e638ad90 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemUpdateResultFragment.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/sysupdate/ui/SystemUpdateResultFragment.java
@@ -6,10 +6,11 @@ import android.app.Dialog;
import android.os.Bundle;
import androidx.annotation.NonNull;
-import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.DialogFragment;
import androidx.lifecycle.ViewModelProvider;
+import com.google.android.material.dialog.MaterialAlertDialogBuilder;
+
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.utils.WiiUtils;
@@ -88,13 +89,10 @@ public class SystemUpdateResultFragment extends DialogFragment
throw new IllegalStateException("Unexpected value: " + mResult);
}
- return new AlertDialog.Builder(requireContext())
+ return new MaterialAlertDialogBuilder(requireContext())
.setTitle(title)
.setMessage(message)
- .setPositiveButton(R.string.ok, (dialog, which) ->
- {
- dismiss();
- })
+ .setPositiveButton(R.string.ok, (dialog, which) -> dismiss())
.create();
}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/ConvertFragment.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/ConvertFragment.java
index dbae87c437..0225f118a3 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/ConvertFragment.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/ConvertFragment.java
@@ -3,7 +3,6 @@
package org.dolphinemu.dolphinemu.fragments;
import android.app.Activity;
-import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
@@ -22,6 +21,9 @@ import androidx.annotation.StringRes;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;
+import com.google.android.material.dialog.MaterialAlertDialogBuilder;
+import com.google.android.material.progressindicator.LinearProgressIndicator;
+
import org.dolphinemu.dolphinemu.NativeLibrary;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.model.GameFile;
@@ -361,12 +363,11 @@ public class ConvertFragment extends Fragment implements View.OnClickListener
return () ->
{
Context context = requireContext();
- AlertDialog.Builder builder = new AlertDialog.Builder(context);
- builder.setMessage(warning_text)
+ new MaterialAlertDialogBuilder(context)
+ .setMessage(warning_text)
.setPositiveButton(R.string.yes, (dialog, i) -> action.run())
- .setNegativeButton(R.string.no, null);
- AlertDialog alert = builder.create();
- alert.show();
+ .setNegativeButton(R.string.no, null)
+ .show();
};
}
@@ -422,20 +423,16 @@ public class ConvertFragment extends Fragment implements View.OnClickListener
mCanceled = false;
- // For some reason, setting R.style.DolphinDialogBase as the theme here gives us white text
- // on a white background when the device is set to dark mode, so let's not set a theme.
- ProgressDialog progressDialog = new ProgressDialog(context);
+ View dialogView = getLayoutInflater().inflate(R.layout.dialog_progress, null, false);
+ LinearProgressIndicator progressBar = dialogView.findViewById(R.id.update_progress);
+ progressBar.setMax(PROGRESS_RESOLUTION);
- progressDialog.setTitle(R.string.convert_converting);
-
- progressDialog.setIndeterminate(false);
- progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
- progressDialog.setMax(PROGRESS_RESOLUTION);
-
- progressDialog.setCancelable(true);
- progressDialog.setOnCancelListener((dialog) -> mCanceled = true);
-
- progressDialog.show();
+ AlertDialog progressDialog = new MaterialAlertDialogBuilder(context)
+ .setTitle(R.string.convert_converting)
+ .setOnCancelListener((dialog) -> mCanceled = true)
+ .setNegativeButton(getString(R.string.cancel), (dialog, i) -> dialog.dismiss())
+ .setView(dialogView)
+ .show();
mThread = new Thread(() ->
{
@@ -447,9 +444,8 @@ public class ConvertFragment extends Fragment implements View.OnClickListener
requireActivity().runOnUiThread(() ->
{
progressDialog.setMessage(text);
- progressDialog.setProgress((int) (completion * PROGRESS_RESOLUTION));
+ progressBar.setProgress((int) (completion * PROGRESS_RESOLUTION));
});
-
return !mCanceled;
});
@@ -459,7 +455,7 @@ public class ConvertFragment extends Fragment implements View.OnClickListener
{
progressDialog.dismiss();
- AlertDialog.Builder builder = new AlertDialog.Builder(context);
+ MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder(context);
if (success)
{
builder.setMessage(R.string.convert_success_message)
@@ -475,8 +471,7 @@ public class ConvertFragment extends Fragment implements View.OnClickListener
builder.setMessage(R.string.convert_failure_message)
.setPositiveButton(R.string.ok, (dialog, i) -> dialog.dismiss());
}
- AlertDialog alert = builder.create();
- alert.show();
+ builder.show();
});
}
});
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainActivity.java
index 4954a4cf90..7f472632ce 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainActivity.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainActivity.java
@@ -37,6 +37,7 @@ import org.dolphinemu.dolphinemu.utils.DirectoryInitialization;
import org.dolphinemu.dolphinemu.utils.FileBrowserHelper;
import org.dolphinemu.dolphinemu.utils.PermissionsHandler;
import org.dolphinemu.dolphinemu.utils.StartupHandler;
+import org.dolphinemu.dolphinemu.utils.ThemeHelper;
import org.dolphinemu.dolphinemu.utils.WiiUtils;
/**
@@ -44,13 +45,15 @@ import org.dolphinemu.dolphinemu.utils.WiiUtils;
* individually display a grid of available games for each Fragment, in a tabbed layout.
*/
public final class MainActivity extends AppCompatActivity
- implements MainView, SwipeRefreshLayout.OnRefreshListener
+ implements MainView, SwipeRefreshLayout.OnRefreshListener, ThemeProvider
{
private ViewPager mViewPager;
private Toolbar mToolbar;
private TabLayout mTabLayout;
private FloatingActionButton mFab;
+ private int mThemeId;
+
private final MainPresenter mPresenter = new MainPresenter(this, this);
@Override
@@ -60,6 +63,8 @@ public final class MainActivity extends AppCompatActivity
splashScreen.setKeepOnScreenCondition(
() -> !DirectoryInitialization.areDolphinDirectoriesReady());
+ ThemeHelper.setTheme(this);
+
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
@@ -74,7 +79,10 @@ public final class MainActivity extends AppCompatActivity
// Stuff in this block only happens when this activity is newly created (i.e. not a rotation)
if (savedInstanceState == null)
+ {
StartupHandler.HandleInit(this);
+ new AfterDirectoryInitializationRunner().runWithLifecycle(this, this::checkTheme);
+ }
if (!DirectoryInitialization.isWaitingForWriteAccess(this))
{
@@ -86,6 +94,8 @@ public final class MainActivity extends AppCompatActivity
@Override
protected void onResume()
{
+ ThemeHelper.setCorrectTheme(this);
+
super.onResume();
if (DirectoryInitialization.shouldStart(this))
@@ -355,4 +365,22 @@ public final class MainActivity extends AppCompatActivity
showGames();
GameFileCacheManager.startLoad(this);
}
+
+ @Override
+ public void setTheme(int themeId)
+ {
+ super.setTheme(themeId);
+ this.mThemeId = themeId;
+ }
+
+ @Override
+ public int getThemeId()
+ {
+ return mThemeId;
+ }
+
+ private void checkTheme()
+ {
+ ThemeHelper.setCorrectTheme(this);
+ }
}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainPresenter.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainPresenter.java
index b34ffff66c..382dbc274d 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainPresenter.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/MainPresenter.java
@@ -7,11 +7,12 @@ import android.content.Intent;
import android.net.Uri;
import androidx.activity.ComponentActivity;
-import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.FragmentActivity;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProvider;
+import com.google.android.material.dialog.MaterialAlertDialogBuilder;
+
import org.dolphinemu.dolphinemu.BuildConfig;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.activities.EmulationActivity;
@@ -171,11 +172,12 @@ public final class MainPresenter
if (Arrays.stream(childNames).noneMatch((name) -> FileBrowserHelper.GAME_EXTENSIONS.contains(
FileBrowserHelper.getExtension(name, false))))
{
- AlertDialog.Builder builder = new AlertDialog.Builder(mActivity);
- builder.setMessage(mActivity.getString(R.string.wrong_file_extension_in_directory,
- FileBrowserHelper.setToSortedDelimitedString(FileBrowserHelper.GAME_EXTENSIONS)));
- builder.setPositiveButton(R.string.ok, null);
- builder.show();
+ new MaterialAlertDialogBuilder(mActivity)
+ .setMessage(mActivity.getString(R.string.wrong_file_extension_in_directory,
+ FileBrowserHelper.setToSortedDelimitedString(
+ FileBrowserHelper.GAME_EXTENSIONS)))
+ .setPositiveButton(R.string.ok, null)
+ .show();
}
ContentResolver contentResolver = mActivity.getContentResolver();
@@ -209,13 +211,12 @@ public final class MainPresenter
{
mActivity.runOnUiThread(() ->
{
- AlertDialog.Builder builder =
- new AlertDialog.Builder(mActivity);
- builder.setMessage(R.string.wii_save_exists);
- builder.setCancelable(false);
- builder.setPositiveButton(R.string.yes, (dialog, i) -> canOverwriteFuture.complete(true));
- builder.setNegativeButton(R.string.no, (dialog, i) -> canOverwriteFuture.complete(false));
- builder.show();
+ new MaterialAlertDialogBuilder(mActivity)
+ .setMessage(R.string.wii_save_exists)
+ .setCancelable(false)
+ .setPositiveButton(R.string.yes, (dialog, i) -> canOverwriteFuture.complete(true))
+ .setNegativeButton(R.string.no, (dialog, i) -> canOverwriteFuture.complete(false))
+ .show();
});
try
@@ -255,26 +256,23 @@ public final class MainPresenter
public void importNANDBin(String path)
{
- AlertDialog.Builder builder =
- new AlertDialog.Builder(mActivity);
+ new MaterialAlertDialogBuilder(mActivity)
+ .setMessage(R.string.nand_import_warning)
+ .setNegativeButton(R.string.no, (dialog, i) -> dialog.dismiss())
+ .setPositiveButton(R.string.yes, (dialog, i) ->
+ {
+ dialog.dismiss();
- builder.setMessage(R.string.nand_import_warning);
- builder.setNegativeButton(R.string.no, (dialog, i) -> dialog.dismiss());
- builder.setPositiveButton(R.string.yes, (dialog, i) ->
- {
- dialog.dismiss();
-
- ThreadUtil.runOnThreadAndShowResult(mActivity, R.string.import_in_progress,
- R.string.do_not_close_app, () ->
- {
- // ImportNANDBin unfortunately doesn't provide any result value...
- // It does however show a panic alert if something goes wrong.
- WiiUtils.importNANDBin(path);
- return null;
- });
- });
-
- builder.show();
+ ThreadUtil.runOnThreadAndShowResult(mActivity, R.string.import_in_progress,
+ R.string.do_not_close_app, () ->
+ {
+ // ImportNANDBin unfortunately doesn't provide any result value...
+ // It does however show a panic alert if something goes wrong.
+ WiiUtils.importNANDBin(path);
+ return null;
+ });
+ })
+ .show();
}
public static void skipRescanningLibrary()
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/ThemeProvider.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/ThemeProvider.java
new file mode 100644
index 0000000000..1be137f33e
--- /dev/null
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/ThemeProvider.java
@@ -0,0 +1,9 @@
+package org.dolphinemu.dolphinemu.ui.main;
+
+public interface ThemeProvider
+{
+ /**
+ * Provides theme ID by overriding an activity's 'setTheme' method and returning that result
+ */
+ int getThemeId();
+}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/TvMainActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/TvMainActivity.java
index 8e9c96442c..4b2b22de33 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/TvMainActivity.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/main/TvMainActivity.java
@@ -6,7 +6,6 @@ import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
-import android.util.TypedValue;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
@@ -121,10 +120,6 @@ public final class TvMainActivity extends FragmentActivity
{
mSwipeRefresh = findViewById(R.id.swipe_refresh);
- TypedValue typedValue = new TypedValue();
- getTheme().resolveAttribute(R.attr.colorPrimary, typedValue, true);
- mSwipeRefresh.setColorSchemeColors(typedValue.data);
-
mSwipeRefresh.setOnRefreshListener(this);
setRefreshing(GameFileCacheManager.isLoadingOrRescanning());
@@ -138,7 +133,7 @@ public final class TvMainActivity extends FragmentActivity
// Set display parameters for the BrowseFragment
mBrowseFragment.setHeadersState(BrowseSupportFragment.HEADERS_ENABLED);
- mBrowseFragment.setBrandColor(ContextCompat.getColor(this, R.color.dolphin_blue_secondary));
+ mBrowseFragment.setBrandColor(ContextCompat.getColor(this, R.color.dolphin_blue));
buildRowsAdapter();
mBrowseFragment.setOnItemViewClickedListener(
@@ -364,7 +359,7 @@ public final class TvMainActivity extends FragmentActivity
ArrayObjectAdapter rowItems = new ArrayObjectAdapter(new SettingsRowPresenter());
rowItems.add(new TvSettingsItem(R.id.menu_settings,
- R.drawable.ic_settings,
+ R.drawable.ic_settings_tv,
R.string.grid_menu_settings));
rowItems.add(new TvSettingsItem(R.id.button_add_directory,
@@ -372,31 +367,31 @@ public final class TvMainActivity extends FragmentActivity
R.string.add_directory_title));
rowItems.add(new TvSettingsItem(R.id.menu_refresh,
- R.drawable.ic_refresh,
+ R.drawable.ic_refresh_tv,
R.string.grid_menu_refresh));
rowItems.add(new TvSettingsItem(R.id.menu_open_file,
- R.drawable.ic_play,
+ R.drawable.ic_play_tv,
R.string.grid_menu_open_file));
rowItems.add(new TvSettingsItem(R.id.menu_install_wad,
- R.drawable.ic_folder,
+ R.drawable.ic_folder_tv,
R.string.grid_menu_install_wad));
rowItems.add(new TvSettingsItem(R.id.menu_load_wii_system_menu,
- R.drawable.ic_folder,
+ R.drawable.ic_folder_tv,
R.string.grid_menu_load_wii_system_menu));
rowItems.add(new TvSettingsItem(R.id.menu_import_wii_save,
- R.drawable.ic_folder,
+ R.drawable.ic_folder_tv,
R.string.grid_menu_import_wii_save));
rowItems.add(new TvSettingsItem(R.id.menu_import_nand_backup,
- R.drawable.ic_folder,
+ R.drawable.ic_folder_tv,
R.string.grid_menu_import_nand_backup));
rowItems.add(new TvSettingsItem(R.id.menu_online_system_update,
- R.drawable.ic_folder,
+ R.drawable.ic_folder_tv,
R.string.grid_menu_online_system_update));
// Create a header for this row.
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/platform/PlatformGamesFragment.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/platform/PlatformGamesFragment.java
index feb08adfcd..8cebf28645 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/platform/PlatformGamesFragment.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/ui/platform/PlatformGamesFragment.java
@@ -3,7 +3,6 @@
package org.dolphinemu.dolphinemu.ui.platform;
import android.os.Bundle;
-import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -15,6 +14,8 @@ import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
+import com.google.android.material.color.MaterialColors;
+
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.adapters.GameAdapter;
import org.dolphinemu.dolphinemu.services.GameFileCacheManager;
@@ -62,9 +63,10 @@ public final class PlatformGamesFragment extends Fragment implements PlatformGam
RecyclerView.LayoutManager layoutManager = new GridLayoutManager(getActivity(), columns);
mAdapter = new GameAdapter();
- TypedValue typedValue = new TypedValue();
- requireActivity().getTheme().resolveAttribute(R.attr.colorPrimary, typedValue, true);
- mSwipeRefresh.setColorSchemeColors(typedValue.data);
+ // Set theme color to the refresh animation's background
+ mSwipeRefresh.setProgressBackgroundColorSchemeColor(
+ MaterialColors.getColor(mSwipeRefresh, R.attr.colorSurfaceVariant));
+ mSwipeRefresh.setColorSchemeColors(MaterialColors.getColor(mSwipeRefresh, R.attr.colorPrimary));
mSwipeRefresh.setOnRefreshListener(mOnRefreshListener);
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/AlertDialogItemsBuilder.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/AlertDialogItemsBuilder.java
index 8a357ff7a2..503e543d72 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/AlertDialogItemsBuilder.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/AlertDialogItemsBuilder.java
@@ -5,7 +5,7 @@ package org.dolphinemu.dolphinemu.utils;
import android.content.Context;
import android.content.DialogInterface.OnClickListener;
-import androidx.appcompat.app.AlertDialog;
+import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import java.util.ArrayList;
@@ -33,7 +33,7 @@ public class AlertDialogItemsBuilder
mListeners.add(listener);
}
- public void applyToBuilder(AlertDialog.Builder builder)
+ public void applyToBuilder(MaterialAlertDialogBuilder builder)
{
CharSequence[] labels = new CharSequence[mLabels.size()];
labels = mLabels.toArray(labels);
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/Analytics.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/Analytics.java
index a39a52267b..961620213a 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/Analytics.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/Analytics.java
@@ -6,10 +6,10 @@ import android.content.Context;
import android.os.Build;
import androidx.annotation.Keep;
-import androidx.appcompat.app.AlertDialog;
import com.android.volley.Request;
import com.android.volley.toolbox.StringRequest;
+import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import org.dolphinemu.dolphinemu.DolphinApplication;
import org.dolphinemu.dolphinemu.R;
@@ -36,17 +36,11 @@ public class Analytics
private static void showMessage(Context context)
{
- new AlertDialog.Builder(context)
+ new MaterialAlertDialogBuilder(context)
.setTitle(context.getString(R.string.analytics))
.setMessage(context.getString(R.string.analytics_desc))
- .setPositiveButton(R.string.yes, (dialogInterface, i) ->
- {
- firstAnalyticsAdd(true);
- })
- .setNegativeButton(R.string.no, (dialogInterface, i) ->
- {
- firstAnalyticsAdd(false);
- })
+ .setPositiveButton(R.string.yes, (dialogInterface, i) -> firstAnalyticsAdd(true))
+ .setNegativeButton(R.string.no, (dialogInterface, i) -> firstAnalyticsAdd(false))
.show();
}
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 6f8ec2c805..7810b5c607 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
@@ -20,6 +20,7 @@ import androidx.lifecycle.MutableLiveData;
import org.dolphinemu.dolphinemu.NativeLibrary;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.activities.EmulationActivity;
+import org.dolphinemu.dolphinemu.features.settings.model.IntSetting;
import java.io.File;
import java.io.FileOutputStream;
@@ -77,6 +78,15 @@ 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 (wiimoteIniWritten)
{
// This has to be done after calling NativeLibrary.Initialize(),
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/FileBrowserHelper.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/FileBrowserHelper.java
index 937c13259b..f1cb504d8a 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/FileBrowserHelper.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/FileBrowserHelper.java
@@ -8,9 +8,9 @@ import android.net.Uri;
import android.os.Environment;
import androidx.annotation.Nullable;
-import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.FragmentActivity;
+import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.nononsenseapps.filepicker.FilePickerActivity;
import com.nononsenseapps.filepicker.Utils;
@@ -126,7 +126,7 @@ public final class FileBrowserHelper
setToSortedDelimitedString(validExtensions));
}
- new AlertDialog.Builder(context)
+ new MaterialAlertDialogBuilder(context)
.setMessage(message)
.setPositiveButton(R.string.yes, (dialogInterface, i) -> runnable.run())
.setNegativeButton(R.string.no, null)
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
new file mode 100644
index 0000000000..5cc4f5b4ec
--- /dev/null
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/ThemeHelper.java
@@ -0,0 +1,107 @@
+package org.dolphinemu.dolphinemu.utils;
+
+import android.app.Activity;
+import android.content.SharedPreferences;
+import android.content.res.Configuration;
+import android.os.Build;
+import android.preference.PreferenceManager;
+
+import org.dolphinemu.dolphinemu.R;
+import org.dolphinemu.dolphinemu.ui.main.ThemeProvider;
+
+public class ThemeHelper
+{
+ public static final String CURRENT_THEME = "current_theme";
+
+ public static final int DEFAULT = 0;
+ public static final int MONET = 1;
+ public static final int MATERIAL_DEFAULT = 2;
+ public static final int GREEN = 3;
+ public static final int PINK = 4;
+
+ public static void setTheme(Activity activity)
+ {
+ // We have to use shared preferences in addition to Dolphin's settings to guarantee that the
+ // requested theme id is ready before the onCreate method of any given Activity.
+ SharedPreferences preferences =
+ PreferenceManager.getDefaultSharedPreferences(activity.getApplicationContext());
+ switch (preferences.getInt(CURRENT_THEME, DEFAULT))
+ {
+ case DEFAULT:
+ activity.setTheme(R.style.Theme_Dolphin_Main);
+ activity.getWindow()
+ .setStatusBarColor(activity.getResources().getColor(R.color.dolphin_surface));
+ break;
+
+ case MONET:
+ activity.setTheme(R.style.Theme_Dolphin_Main_MaterialYou);
+ int currentNightMode = activity.getResources().getConfiguration().uiMode &
+ Configuration.UI_MODE_NIGHT_MASK;
+ switch (currentNightMode)
+ {
+ case Configuration.UI_MODE_NIGHT_NO:
+ activity.getWindow().setStatusBarColor(
+ activity.getResources().getColor(R.color.m3_sys_color_dynamic_light_surface));
+ break;
+ case Configuration.UI_MODE_NIGHT_YES:
+ activity.getWindow().setStatusBarColor(
+ activity.getResources().getColor(R.color.m3_sys_color_dynamic_dark_surface));
+ break;
+ }
+ break;
+
+ case MATERIAL_DEFAULT:
+ activity.setTheme(R.style.Theme_Dolphin_Main_Material);
+ activity.getWindow()
+ .setStatusBarColor(activity.getResources().getColor(R.color.dolphin_surface));
+ break;
+
+ case GREEN:
+ activity.setTheme(R.style.Theme_Dolphin_Main_Green);
+ activity.getWindow()
+ .setStatusBarColor(activity.getResources().getColor(R.color.green_surface));
+ break;
+
+ case PINK:
+ activity.setTheme(R.style.Theme_Dolphin_Main_Pink);
+ activity.getWindow()
+ .setStatusBarColor(activity.getResources().getColor(R.color.pink_surface));
+ break;
+ }
+
+ // 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)
+ {
+ activity.getWindow()
+ .setStatusBarColor(activity.getResources().getColor(android.R.color.black));
+ }
+ }
+
+ public static void saveTheme(Activity activity, int themeValue)
+ {
+ SharedPreferences preferences =
+ PreferenceManager.getDefaultSharedPreferences(activity.getApplicationContext());
+ preferences.edit().putInt(CURRENT_THEME, themeValue).apply();
+ }
+
+ public static void deleteThemeKey(Activity activity)
+ {
+ SharedPreferences preferences =
+ PreferenceManager.getDefaultSharedPreferences(activity.getApplicationContext());
+ preferences.edit().remove(CURRENT_THEME).apply();
+ activity.setTheme(R.style.Theme_Dolphin_Main);
+ activity.recreate();
+ }
+
+ public static void setCorrectTheme(Activity activity)
+ {
+ int currentTheme = ((ThemeProvider) activity).getThemeId();
+ setTheme(activity);
+
+ if (currentTheme != ((ThemeProvider) activity).getThemeId())
+ {
+ activity.recreate();
+ }
+ }
+}
diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/ThreadUtil.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/ThreadUtil.java
index 8c2dcb7673..2321c6a5d6 100644
--- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/ThreadUtil.java
+++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/ThreadUtil.java
@@ -10,6 +10,8 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
+import com.google.android.material.dialog.MaterialAlertDialogBuilder;
+
import org.dolphinemu.dolphinemu.R;
import java.util.function.Supplier;
@@ -27,12 +29,14 @@ public class ThreadUtil
@Nullable DialogInterface.OnDismissListener onResultDismiss)
{
Resources resources = activity.getResources();
- AlertDialog progressDialog = new AlertDialog.Builder(activity)
+ AlertDialog progressDialog = new MaterialAlertDialogBuilder(activity)
+ .setTitle(progressTitle)
+ .setCancelable(false)
.create();
- progressDialog.setTitle(progressTitle);
+
if (progressMessage != 0)
progressDialog.setMessage(resources.getString(progressMessage));
- progressDialog.setCancelable(false);
+
progressDialog.show();
new Thread(() ->
@@ -44,12 +48,11 @@ public class ThreadUtil
if (result != null)
{
- AlertDialog.Builder builder =
- new AlertDialog.Builder(activity);
- builder.setMessage(result);
- builder.setPositiveButton(R.string.ok, (dialog, i) -> dialog.dismiss());
- builder.setOnDismissListener(onResultDismiss);
- builder.show();
+ new MaterialAlertDialogBuilder(activity)
+ .setMessage(result)
+ .setPositiveButton(R.string.ok, (dialog, i) -> dialog.dismiss())
+ .setOnDismissListener(onResultDismiss)
+ .show();
}
});
}, resources.getString(progressTitle)).start();
diff --git a/Source/Android/app/src/main/res/color/button_text_color.xml b/Source/Android/app/src/main/res/color/button_text_color.xml
deleted file mode 100644
index 0f38d0d449..0000000000
--- a/Source/Android/app/src/main/res/color/button_text_color.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
-
diff --git a/Source/Android/app/src/main/res/drawable/ic_add.xml b/Source/Android/app/src/main/res/drawable/ic_add.xml
index bdd99f48d5..64360e8d92 100644
--- a/Source/Android/app/src/main/res/drawable/ic_add.xml
+++ b/Source/Android/app/src/main/res/drawable/ic_add.xml
@@ -4,6 +4,6 @@
android:viewportWidth="24"
android:viewportHeight="24">
diff --git a/Source/Android/app/src/main/res/drawable/ic_back.xml b/Source/Android/app/src/main/res/drawable/ic_back.xml
index 45a504f227..344d5e6974 100644
--- a/Source/Android/app/src/main/res/drawable/ic_back.xml
+++ b/Source/Android/app/src/main/res/drawable/ic_back.xml
@@ -4,6 +4,6 @@
android:viewportWidth="24"
android:viewportHeight="24">
diff --git a/Source/Android/app/src/main/res/drawable/ic_folder.xml b/Source/Android/app/src/main/res/drawable/ic_folder.xml
index c66a174f4b..31e1dfc895 100644
--- a/Source/Android/app/src/main/res/drawable/ic_folder.xml
+++ b/Source/Android/app/src/main/res/drawable/ic_folder.xml
@@ -4,6 +4,6 @@
android:viewportWidth="24"
android:viewportHeight="24">
diff --git a/Source/Android/app/src/main/res/drawable/ic_quicksave.xml b/Source/Android/app/src/main/res/drawable/ic_folder_tv.xml
similarity index 55%
rename from Source/Android/app/src/main/res/drawable/ic_quicksave.xml
rename to Source/Android/app/src/main/res/drawable/ic_folder_tv.xml
index aa71b08c00..c66a174f4b 100644
--- a/Source/Android/app/src/main/res/drawable/ic_quicksave.xml
+++ b/Source/Android/app/src/main/res/drawable/ic_folder_tv.xml
@@ -5,5 +5,5 @@
android:viewportHeight="24">
+ android:pathData="M10,4H4c-1.1,0 -1.99,0.9 -1.99,2L2,18c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2V8c0,-1.1 -0.9,-2 -2,-2h-8l-2,-2z"/>
diff --git a/Source/Android/app/src/main/res/drawable/ic_gamecube.xml b/Source/Android/app/src/main/res/drawable/ic_gamecube.xml
index 48f7d23a95..ab75643e72 100644
--- a/Source/Android/app/src/main/res/drawable/ic_gamecube.xml
+++ b/Source/Android/app/src/main/res/drawable/ic_gamecube.xml
@@ -3,14 +3,14 @@
android:width="24dp"
android:viewportHeight="1402"
android:viewportWidth="1402" >
-
-
-
-
-
diff --git a/Source/Android/app/src/main/res/drawable/ic_play.xml b/Source/Android/app/src/main/res/drawable/ic_play.xml
index 8986c1d045..12c9b8fe52 100644
--- a/Source/Android/app/src/main/res/drawable/ic_play.xml
+++ b/Source/Android/app/src/main/res/drawable/ic_play.xml
@@ -4,6 +4,6 @@
android:viewportWidth="24"
android:viewportHeight="24">
diff --git a/Source/Android/app/src/main/res/drawable/ic_play_tv.xml b/Source/Android/app/src/main/res/drawable/ic_play_tv.xml
new file mode 100644
index 0000000000..8986c1d045
--- /dev/null
+++ b/Source/Android/app/src/main/res/drawable/ic_play_tv.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/Source/Android/app/src/main/res/drawable/ic_refresh.xml b/Source/Android/app/src/main/res/drawable/ic_refresh.xml
index 5ab492cabe..7f482d0e2d 100644
--- a/Source/Android/app/src/main/res/drawable/ic_refresh.xml
+++ b/Source/Android/app/src/main/res/drawable/ic_refresh.xml
@@ -4,6 +4,6 @@
android:viewportWidth="24"
android:viewportHeight="24">
diff --git a/Source/Android/app/src/main/res/drawable/ic_refresh_tv.xml b/Source/Android/app/src/main/res/drawable/ic_refresh_tv.xml
new file mode 100644
index 0000000000..5ab492cabe
--- /dev/null
+++ b/Source/Android/app/src/main/res/drawable/ic_refresh_tv.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/Source/Android/app/src/main/res/drawable/ic_screenshot.xml b/Source/Android/app/src/main/res/drawable/ic_screenshot.xml
deleted file mode 100644
index 5b075cd027..0000000000
--- a/Source/Android/app/src/main/res/drawable/ic_screenshot.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
diff --git a/Source/Android/app/src/main/res/drawable/ic_settings.xml b/Source/Android/app/src/main/res/drawable/ic_settings.xml
index b86b554dff..9987fdf239 100644
--- a/Source/Android/app/src/main/res/drawable/ic_settings.xml
+++ b/Source/Android/app/src/main/res/drawable/ic_settings.xml
@@ -4,6 +4,6 @@
android:viewportWidth="24"
android:viewportHeight="24">
diff --git a/Source/Android/app/src/main/res/drawable/ic_settings_tv.xml b/Source/Android/app/src/main/res/drawable/ic_settings_tv.xml
new file mode 100644
index 0000000000..b86b554dff
--- /dev/null
+++ b/Source/Android/app/src/main/res/drawable/ic_settings_tv.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/Source/Android/app/src/main/res/drawable/ic_wii.xml b/Source/Android/app/src/main/res/drawable/ic_wii.xml
index 3efe3227db..a357172b4f 100644
--- a/Source/Android/app/src/main/res/drawable/ic_wii.xml
+++ b/Source/Android/app/src/main/res/drawable/ic_wii.xml
@@ -4,14 +4,14 @@
android:width="24dp"
android:viewportHeight="2157"
android:viewportWidth="2157">
-
-
-
-
-
diff --git a/Source/Android/app/src/main/res/drawable/tv_card_background.xml b/Source/Android/app/src/main/res/drawable/tv_card_background.xml
index 58ae5f09a8..ee4320d5b3 100644
--- a/Source/Android/app/src/main/res/drawable/tv_card_background.xml
+++ b/Source/Android/app/src/main/res/drawable/tv_card_background.xml
@@ -2,7 +2,7 @@
+ android:drawable="@color/dolphin_primary"/>
diff --git a/Source/Android/app/src/main/res/layout-land/activity_user_data.xml b/Source/Android/app/src/main/res/layout-land/activity_user_data.xml
index a67af96768..c60fd3b07f 100644
--- a/Source/Android/app/src/main/res/layout-land/activity_user_data.xml
+++ b/Source/Android/app/src/main/res/layout-land/activity_user_data.xml
@@ -1,22 +1,39 @@
-
+
+
+
+
+
+
+ app:layout_constraintWidth_max="400dp"
+ tools:text="@string/user_data_new_location" />
@@ -88,8 +104,7 @@
android:layout_height="wrap_content"
android:layout_margin="@dimen/spacing_small"
android:text="@string/user_data_import"
- android:textColor="@color/dolphin_white"
- app:layout_constraintStart_toEndOf="@id/divider"
+ app:layout_constraintStart_toEndOf="@id/barrier_text"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/button_open_system_file_manager"
app:layout_constraintBottom_toTopOf="@id/button_export_user_data"
@@ -101,8 +116,7 @@
android:layout_height="wrap_content"
android:layout_margin="@dimen/spacing_small"
android:text="@string/user_data_export"
- android:textColor="@color/dolphin_white"
- app:layout_constraintStart_toEndOf="@id/divider"
+ app:layout_constraintStart_toEndOf="@id/barrier_text"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/button_import_user_data"
app:layout_constraintBottom_toBottomOf="parent"
diff --git a/Source/Android/app/src/main/res/layout-ldrtl/list_item_cheat.xml b/Source/Android/app/src/main/res/layout-ldrtl/list_item_cheat.xml
index 7842f5330b..2a151e8a2d 100644
--- a/Source/Android/app/src/main/res/layout-ldrtl/list_item_cheat.xml
+++ b/Source/Android/app/src/main/res/layout-ldrtl/list_item_cheat.xml
@@ -29,7 +29,6 @@
android:focusable="true"
android:gravity="center"
android:nextFocusRight="@id/root"
- android:buttonTint="@color/dolphin_blue"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/text_name"
diff --git a/Source/Android/app/src/main/res/layout-port/fragment_emulation.xml b/Source/Android/app/src/main/res/layout-port/fragment_emulation.xml
index 64d27bdf12..f90c67a5ec 100644
--- a/Source/Android/app/src/main/res/layout-port/fragment_emulation.xml
+++ b/Source/Android/app/src/main/res/layout-port/fragment_emulation.xml
@@ -38,8 +38,6 @@
android:layout_height="wrap_content"
android:layout_gravity="center"
android:padding="@dimen/spacing_small"
- android:background="@color/dolphin_blue"
- android:textColor="@color/lb_tv_white"
android:text="@string/emulation_done"
android:visibility="gone"/>
diff --git a/Source/Android/app/src/main/res/layout/activity_cheats.xml b/Source/Android/app/src/main/res/layout/activity_cheats.xml
index 0f89b488e1..0bdfb7059b 100644
--- a/Source/Android/app/src/main/res/layout/activity_cheats.xml
+++ b/Source/Android/app/src/main/res/layout/activity_cheats.xml
@@ -1,22 +1,42 @@
-
-
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Source/Android/app/src/main/res/layout/activity_main.xml b/Source/Android/app/src/main/res/layout/activity_main.xml
index 775e8183d7..7ff71af045 100644
--- a/Source/Android/app/src/main/res/layout/activity_main.xml
+++ b/Source/Android/app/src/main/res/layout/activity_main.xml
@@ -1,35 +1,34 @@
-
+ android:layout_height="wrap_content">
-
+ android:background="?attr/colorSurface"
+ app:layout_scrollFlags="scroll|enterAlways|snap"
+ app:subtitleTextColor="?attr/colorOnSurface"
+ app:titleTextColor="?attr/colorOnSurface" />
+ app:tabMode="fixed" />
@@ -37,6 +36,7 @@
android:id="@+id/pager_platforms"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:background="?attr/colorSurface"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
+ app:layout_anchorGravity="bottom|right|end" />
diff --git a/Source/Android/app/src/main/res/layout/activity_settings.xml b/Source/Android/app/src/main/res/layout/activity_settings.xml
index 492fbf04ec..a7ad7b842a 100644
--- a/Source/Android/app/src/main/res/layout/activity_settings.xml
+++ b/Source/Android/app/src/main/res/layout/activity_settings.xml
@@ -1,5 +1,39 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Source/Android/app/src/main/res/layout/activity_user_data.xml b/Source/Android/app/src/main/res/layout/activity_user_data.xml
index caa37b85ed..39484b7778 100644
--- a/Source/Android/app/src/main/res/layout/activity_user_data.xml
+++ b/Source/Android/app/src/main/res/layout/activity_user_data.xml
@@ -1,22 +1,39 @@
-
+
+
+
+
+
+
+ app:layout_constraintWidth_max="400dp"
+ tools:text="@string/user_data_new_location" />
+
+
+
+
+
diff --git a/Source/Android/app/src/main/res/layout/dialog_input_adjust.xml b/Source/Android/app/src/main/res/layout/dialog_input_adjust.xml
index 5818a6ab57..f1d2620c2a 100644
--- a/Source/Android/app/src/main/res/layout/dialog_input_adjust.xml
+++ b/Source/Android/app/src/main/res/layout/dialog_input_adjust.xml
@@ -1,102 +1,91 @@
-
-
+ android:layout_height="wrap_content">
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toStartOf="@id/input_scale_slider"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent" />
+
+
+ android:layout_marginStart="@dimen/spacing_medlarge"
+ android:layout_marginEnd="24dp"
+ android:gravity="end"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toEndOf="@id/input_scale_slider"
+ app:layout_constraintTop_toTopOf="parent"
+ tools:text="100%" />
-
+
-
-
-
+ android:layout_height="wrap_content">
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toStartOf="@id/input_opacity_slider"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent" />
+
+
+ android:layout_marginStart="@dimen/spacing_medlarge"
+ android:layout_marginEnd="24dp"
+ android:gravity="end"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toEndOf="@id/input_opacity_slider"
+ app:layout_constraintTop_toTopOf="parent"
+ tools:text="100%" />
-
+
-
-
-
+
diff --git a/Source/Android/app/src/main/res/layout/dialog_input_string.xml b/Source/Android/app/src/main/res/layout/dialog_input_string.xml
index 0af48d47fe..c3dd1cd77c 100644
--- a/Source/Android/app/src/main/res/layout/dialog_input_string.xml
+++ b/Source/Android/app/src/main/res/layout/dialog_input_string.xml
@@ -1,19 +1,27 @@
-
+ android:layout_height="wrap_content"
+ android:hint="@string/cheats_name"
+ android:paddingTop="@dimen/spacing_medlarge"
+ android:layout_marginHorizontal="@dimen/spacing_large"
+ android:layout_marginVertical="@dimen/spacing_small">
+
+
+
+
diff --git a/Source/Android/app/src/main/res/layout/dialog_ir_sensitivity.xml b/Source/Android/app/src/main/res/layout/dialog_ir_sensitivity.xml
index 49f3434a38..daa84c0071 100644
--- a/Source/Android/app/src/main/res/layout/dialog_ir_sensitivity.xml
+++ b/Source/Android/app/src/main/res/layout/dialog_ir_sensitivity.xml
@@ -1,115 +1,132 @@
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
-
-
+ app:layout_constraintEnd_toStartOf="@id/text_ir_yaw"
+ app:layout_constraintStart_toEndOf="@id/text_ir_yaw_units"
+ app:layout_constraintTop_toTopOf="parent" />
+ android:layout_marginEnd="24dp"
+ android:layout_marginStart="@dimen/spacing_medlarge"
+ android:gravity="end"
+ app:layout_constraintBottom_toBottomOf="@+id/slider_width"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toEndOf="@id/slider_width"
+ app:layout_constraintTop_toTopOf="@+id/slider_width"
+ tools:text="100" />
-
+ android:gravity="start"
+ android:layout_marginStart="24dp"
+ android:layout_marginEnd="@dimen/spacing_medlarge"
+ app:layout_constraintBottom_toBottomOf="@+id/slider_width"
+ app:layout_constraintEnd_toStartOf="@id/slider_width"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="@+id/slider_width"
+ tools:text="Total Yaw" />
-
+
+
-
+ app:layout_constraintEnd_toStartOf="@id/text_ir_pitch"
+ app:layout_constraintStart_toEndOf="@id/text_ir_pitch_units"
+ app:layout_constraintTop_toTopOf="parent" />
+ android:layout_marginEnd="24dp"
+ android:layout_marginStart="@dimen/spacing_medlarge"
+ android:gravity="end"
+ app:layout_constraintBottom_toBottomOf="@+id/slider_pitch"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toEndOf="@id/slider_pitch"
+ app:layout_constraintTop_toTopOf="@+id/slider_pitch"
+ tools:text="100" />
+ android:gravity="start"
+ android:layout_marginStart="24dp"
+ android:layout_marginEnd="@dimen/spacing_medlarge"
+ app:layout_constraintBottom_toBottomOf="@+id/slider_pitch"
+ app:layout_constraintEnd_toStartOf="@id/slider_pitch"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="@+id/slider_pitch"
+ tools:text="Total Pitch" />
-
+
-
-
+ app:layout_constraintEnd_toStartOf="@id/text_ir_vertical_offset"
+ app:layout_constraintStart_toEndOf="@id/text_ir_vertical_offset_units"
+ app:layout_constraintTop_toTopOf="parent" />
+ android:layout_marginEnd="24dp"
+ android:layout_marginStart="@dimen/spacing_medlarge"
+ android:gravity="end"
+ app:layout_constraintBottom_toBottomOf="@+id/slider_vertical_offset"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toEndOf="@id/slider_vertical_offset"
+ app:layout_constraintTop_toTopOf="@+id/slider_vertical_offset"
+ tools:text="100" />
+ android:gravity="start"
+ android:layout_marginStart="24dp"
+ android:layout_marginEnd="@dimen/spacing_medlarge"
+ app:layout_constraintBottom_toBottomOf="@+id/slider_vertical_offset"
+ app:layout_constraintEnd_toStartOf="@id/slider_vertical_offset"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="@+id/slider_vertical_offset"
+ tools:text="Vertical Offset" />
-
+
-
\ No newline at end of file
+
diff --git a/Source/Android/app/src/main/res/layout/dialog_progress.xml b/Source/Android/app/src/main/res/layout/dialog_progress.xml
new file mode 100644
index 0000000000..49e59ed6bb
--- /dev/null
+++ b/Source/Android/app/src/main/res/layout/dialog_progress.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
diff --git a/Source/Android/app/src/main/res/layout/dialog_seekbar.xml b/Source/Android/app/src/main/res/layout/dialog_seekbar.xml
deleted file mode 100644
index 314f348261..0000000000
--- a/Source/Android/app/src/main/res/layout/dialog_seekbar.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Source/Android/app/src/main/res/layout/dialog_slider.xml b/Source/Android/app/src/main/res/layout/dialog_slider.xml
new file mode 100644
index 0000000000..a83befbb8c
--- /dev/null
+++ b/Source/Android/app/src/main/res/layout/dialog_slider.xml
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/Source/Android/app/src/main/res/layout/fragment_cheat_details.xml b/Source/Android/app/src/main/res/layout/fragment_cheat_details.xml
index 5cbadebc3d..208bd9b450 100644
--- a/Source/Android/app/src/main/res/layout/fragment_cheat_details.xml
+++ b/Source/Android/app/src/main/res/layout/fragment_cheat_details.xml
@@ -20,117 +20,100 @@
android:layout_width="match_parent"
android:layout_height="wrap_content">
-
-
-
+ app:layout_constraintTop_toBottomOf="parent"
+ app:layout_constraintBottom_toTopOf="@id/edit_creator">
-
+
-
+
+
+ app:layout_constraintTop_toBottomOf="@id/edit_name"
+ app:layout_constraintBottom_toTopOf="@id/edit_notes">
-
+
-
+
+
+ app:layout_constraintTop_toBottomOf="@id/edit_creator"
+ app:layout_constraintBottom_toTopOf="@id/edit_code">
-
+
-
+
+
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@id/edit_notes">
+
+
+
+
diff --git a/Source/Android/app/src/main/res/layout/fragment_cheat_warning.xml b/Source/Android/app/src/main/res/layout/fragment_cheat_warning.xml
index 6ed47961e2..159274bdef 100644
--- a/Source/Android/app/src/main/res/layout/fragment_cheat_warning.xml
+++ b/Source/Android/app/src/main/res/layout/fragment_cheat_warning.xml
@@ -23,7 +23,6 @@
android:layout_height="wrap_content"
android:layout_margin="@dimen/spacing_small"
android:text="@string/cheats_open_settings"
- android:textColor="@color/dolphin_white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/text_warning"
diff --git a/Source/Android/app/src/main/res/layout/fragment_emulation.xml b/Source/Android/app/src/main/res/layout/fragment_emulation.xml
index 2ba3186324..eb9ba4cceb 100644
--- a/Source/Android/app/src/main/res/layout/fragment_emulation.xml
+++ b/Source/Android/app/src/main/res/layout/fragment_emulation.xml
@@ -27,8 +27,6 @@
android:layout_height="wrap_content"
android:layout_gravity="center"
android:padding="@dimen/spacing_small"
- android:background="@color/dolphin_blue"
- android:textColor="@color/lb_tv_white"
android:text="@string/emulation_done"
android:visibility="gone"/>
diff --git a/Source/Android/app/src/main/res/layout/fragment_ingame_menu.xml b/Source/Android/app/src/main/res/layout/fragment_ingame_menu.xml
index 71dd4b6ad8..23aa8d6152 100644
--- a/Source/Android/app/src/main/res/layout/fragment_ingame_menu.xml
+++ b/Source/Android/app/src/main/res/layout/fragment_ingame_menu.xml
@@ -5,7 +5,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="16dp"
- android:background="@color/dolphin_blue"
+ android:background="?attr/colorSurface"
tools:layout_width="250dp">
diff --git a/Source/Android/app/src/main/res/layout/list_item_cheat.xml b/Source/Android/app/src/main/res/layout/list_item_cheat.xml
index bcfc2d8341..4611502560 100644
--- a/Source/Android/app/src/main/res/layout/list_item_cheat.xml
+++ b/Source/Android/app/src/main/res/layout/list_item_cheat.xml
@@ -29,7 +29,6 @@
android:focusable="true"
android:gravity="center"
android:nextFocusRight="@id/root"
- android:buttonTint="@color/dolphin_blue"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/text_name"
diff --git a/Source/Android/app/src/main/res/layout/list_item_header.xml b/Source/Android/app/src/main/res/layout/list_item_header.xml
index fc17c23d06..6ea68e9c4f 100644
--- a/Source/Android/app/src/main/res/layout/list_item_header.xml
+++ b/Source/Android/app/src/main/res/layout/list_item_header.xml
@@ -12,7 +12,7 @@
tools:text="CPU Settings"
android:layout_marginStart="@dimen/spacing_large"
android:layout_marginBottom="@dimen/spacing_small"
- android:textColor="@color/dolphin_blue"
+ android:textColor="?attr/colorPrimary"
android:textStyle="bold"
android:layout_gravity="start|bottom"/>
diff --git a/Source/Android/app/src/main/res/layout/list_item_setting_checkbox.xml b/Source/Android/app/src/main/res/layout/list_item_setting_checkbox.xml
index 2ed37c3a0d..7a6fc011cd 100644
--- a/Source/Android/app/src/main/res/layout/list_item_setting_checkbox.xml
+++ b/Source/Android/app/src/main/res/layout/list_item_setting_checkbox.xml
@@ -43,7 +43,6 @@
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_marginEnd="@dimen/spacing_large"
- android:buttonTint="@color/dolphin_blue"
android:clickable="false"
android:focusable="false"
android:minHeight="0dp"
diff --git a/Source/Android/app/src/main/res/menu/menu_game_grid.xml b/Source/Android/app/src/main/res/menu/menu_game_grid.xml
index b0fb121779..b6232e830b 100644
--- a/Source/Android/app/src/main/res/menu/menu_game_grid.xml
+++ b/Source/Android/app/src/main/res/menu/menu_game_grid.xml
@@ -16,7 +16,7 @@
diff --git a/Source/Android/app/src/main/res/values-night-v31/themes.xml b/Source/Android/app/src/main/res/values-night-v31/themes.xml
new file mode 100644
index 0000000000..fac737af73
--- /dev/null
+++ b/Source/Android/app/src/main/res/values-night-v31/themes.xml
@@ -0,0 +1,33 @@
+
+
+
+
diff --git a/Source/Android/app/src/main/res/values-night/bools.xml b/Source/Android/app/src/main/res/values-night/bools.xml
new file mode 100644
index 0000000000..14d6d1cbc8
--- /dev/null
+++ b/Source/Android/app/src/main/res/values-night/bools.xml
@@ -0,0 +1,4 @@
+
+
+ false
+
diff --git a/Source/Android/app/src/main/res/values-night/colors.xml b/Source/Android/app/src/main/res/values-night/colors.xml
deleted file mode 100644
index d792ba7d42..0000000000
--- a/Source/Android/app/src/main/res/values-night/colors.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
- #1976d2
- #2196f3
- #FFFFFF
-
- #1A1C1E
-
- #444444
-
- #36ff0000
-
diff --git a/Source/Android/app/src/main/res/values-night/dolphin_colors.xml b/Source/Android/app/src/main/res/values-night/dolphin_colors.xml
new file mode 100644
index 0000000000..39e5ccc882
--- /dev/null
+++ b/Source/Android/app/src/main/res/values-night/dolphin_colors.xml
@@ -0,0 +1,31 @@
+
+
+
+ #9ECAFF
+ #003258
+ #00497D
+ #D1E4FF
+ #BBC7DB
+ #253140
+ #3B4858
+ #D7E3F7
+ #D6BEE4
+ #3B2948
+ #523F5F
+ #F2DAFF
+ #FFB4AB
+ #93000A
+ #690005
+ #FFDAD6
+ #1A1C1E
+ #E2E2E6
+ #1A1C1E
+ #E2E2E6
+ #43474E
+ #C3C7CF
+ #8D9199
+ #1A1C1E
+ #E2E2E6
+ #0061A4
+ #000000
+
diff --git a/Source/Android/app/src/main/res/values-night/green_colors.xml b/Source/Android/app/src/main/res/values-night/green_colors.xml
new file mode 100644
index 0000000000..405de3f9f4
--- /dev/null
+++ b/Source/Android/app/src/main/res/values-night/green_colors.xml
@@ -0,0 +1,29 @@
+
+
+
+ #70DBA8
+ #003824
+ #005236
+ #8CF7C3
+ #B4CCBC
+ #20352A
+ #364B3F
+ #D0E8D8
+ #A4CDDE
+ #063543
+ #234C5A
+ #C0E9FA
+ #93000A
+ #690005
+ #FFDAD6
+ #191C1A
+ #E1E3DF
+ #191C1A
+ #E1E3DF
+ #404943
+ #C0C9C1
+ #8A938C
+ #191C1A
+ #E1E3DF
+ #006C49
+
diff --git a/Source/Android/app/src/main/res/values-night/pink_colors.xml b/Source/Android/app/src/main/res/values-night/pink_colors.xml
new file mode 100644
index 0000000000..79973fba8b
--- /dev/null
+++ b/Source/Android/app/src/main/res/values-night/pink_colors.xml
@@ -0,0 +1,29 @@
+
+
+
+ #FFB1C4
+ #65002E
+ #8F0044
+ #FFD9E1
+ #E3BDC5
+ #422930
+ #5B3F46
+ #FFD9E1
+ #EDBD92
+ #472A0A
+ #61401E
+ #FFDCBF
+ #93000A
+ #690005
+ #FFDAD6
+ #201A1B
+ #ECE0E1
+ #201A1B
+ #ECE0E1
+ #514346
+ #D6C2C5
+ #9E8C8F
+ #201A1B
+ #ECE0E1
+ #B5195B
+
diff --git a/Source/Android/app/src/main/res/values-v31/themes.xml b/Source/Android/app/src/main/res/values-v31/themes.xml
new file mode 100644
index 0000000000..0b7905858d
--- /dev/null
+++ b/Source/Android/app/src/main/res/values-v31/themes.xml
@@ -0,0 +1,33 @@
+
+
+
+
diff --git a/Source/Android/app/src/main/res/values/arrays.xml b/Source/Android/app/src/main/res/values/arrays.xml
index b398bf805a..0089d6eef6 100644
--- a/Source/Android/app/src/main/res/values/arrays.xml
+++ b/Source/Android/app/src/main/res/values/arrays.xml
@@ -479,6 +479,34 @@
- -1
+
+
+ - Default
+ - Material Default
+ - Green
+ - Pink
+
+
+ - 0
+ - 2
+ - 3
+ - 4
+
+
+ - Default
+ - Material You
+ - Material Default
+ - Green
+ - Pink
+
+
+ - 0
+ - 1
+ - 2
+ - 3
+ - 4
+
+
- Never
- On Idle Skipping
diff --git a/Source/Android/app/src/main/res/values/bools.xml b/Source/Android/app/src/main/res/values/bools.xml
new file mode 100644
index 0000000000..d0bda19f24
--- /dev/null
+++ b/Source/Android/app/src/main/res/values/bools.xml
@@ -0,0 +1,4 @@
+
+
+ true
+
diff --git a/Source/Android/app/src/main/res/values/colors.xml b/Source/Android/app/src/main/res/values/colors.xml
deleted file mode 100644
index e6dc65f906..0000000000
--- a/Source/Android/app/src/main/res/values/colors.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
- #2196f3
- #21b0f3
- #ffffff
-
- #FDFCFF
-
- #444444
-
- #36ff0000
-
diff --git a/Source/Android/app/src/main/res/values/dolphin_colors.xml b/Source/Android/app/src/main/res/values/dolphin_colors.xml
new file mode 100644
index 0000000000..cd11b64fd4
--- /dev/null
+++ b/Source/Android/app/src/main/res/values/dolphin_colors.xml
@@ -0,0 +1,42 @@
+
+
+
+ #2196f3
+ #FFFFFF
+ #D1E4FF
+ #001D36
+ #535F70
+ #FFFFFF
+ #D7E3F7
+ #101C2B
+ #6B5778
+ #FFFFFF
+ #F2DAFF
+ #251431
+ #BA1A1A
+ #FFDAD6
+ #FFFFFF
+ #410002
+ #FDFCFF
+ #1A1C1E
+ #FDFCFF
+ #1A1C1E
+ #DFE2EB
+ #43474E
+ #73777F
+ #F1F0F4
+ #2F3033
+ #9ECAFF
+ #000000
+
+ #2196f3
+
+ #2196f3
+
+ #9e9e9e
+ #2979ff
+
+ #444444
+
+ #36ff0000
+
diff --git a/Source/Android/app/src/main/res/values/green_colors.xml b/Source/Android/app/src/main/res/values/green_colors.xml
new file mode 100644
index 0000000000..113dbd1812
--- /dev/null
+++ b/Source/Android/app/src/main/res/values/green_colors.xml
@@ -0,0 +1,29 @@
+
+
+
+ #006C49
+ #FFFFFF
+ #8CF7C3
+ #002113
+ #4D6356
+ #FFFFFF
+ #D0E8D8
+ #0A1F15
+ #3D6472
+ #FFFFFF
+ #C0E9FA
+ #001F28
+ #FFDAD6
+ #FFFFFF
+ #410002
+ #FBFDF8
+ #191C1A
+ #FBFDF8
+ #191C1A
+ #DCE5DD
+ #404943
+ #707973
+ #EFF1ED
+ #2E312F
+ #70DBA8
+
diff --git a/Source/Android/app/src/main/res/values/pink_colors.xml b/Source/Android/app/src/main/res/values/pink_colors.xml
new file mode 100644
index 0000000000..c550d4c719
--- /dev/null
+++ b/Source/Android/app/src/main/res/values/pink_colors.xml
@@ -0,0 +1,29 @@
+
+
+
+ #B5195B
+ #FFFFFF
+ #FFD9E1
+ #3F001A
+ #75565D
+ #FFFFFF
+ #FFD9E1
+ #2B151B
+ #7B5733
+ #FFFFFF
+ #FFDCBF
+ #2D1600
+ #FFDAD6
+ #FFFFFF
+ #410002
+ #FFFBFF
+ #201A1B
+ #FFFBFF
+ #201A1B
+ #F3DDE1
+ #514346
+ #847376
+ #FAEEEF
+ #352F30
+ #FFB1C4
+
diff --git a/Source/Android/app/src/main/res/values/strings.xml b/Source/Android/app/src/main/res/values/strings.xml
index 5a2157e7ac..3ef0f39d58 100644
--- a/Source/Android/app/src/main/res/values/strings.xml
+++ b/Source/Android/app/src/main/res/values/strings.xml
@@ -195,6 +195,7 @@
Download Game Covers from GameTDB.com
Show Titles in Game List
Show the title and creator below each game cover.
+ Change App Theme
Please select a region
@@ -563,8 +564,8 @@ It can efficiently compress both junk data and encrypted Wii data.
Done
Toggle Controls
Toggle All
- Adjust Scale
- Adjust Opacity
+ Scale
+ Opacity
Adjust Controls
Relative Stick Center
Rumble
diff --git a/Source/Android/app/src/main/res/values/styles.xml b/Source/Android/app/src/main/res/values/styles.xml
index b29ec7e045..55a8a35754 100644
--- a/Source/Android/app/src/main/res/values/styles.xml
+++ b/Source/Android/app/src/main/res/values/styles.xml
@@ -1,12 +1,5 @@
-
-
+
+
+
+
+
+
+
+
+
+
diff --git a/Source/Android/app/src/main/res/values/themes.xml b/Source/Android/app/src/main/res/values/themes.xml
index 34f476380f..4407e5a5aa 100644
--- a/Source/Android/app/src/main/res/values/themes.xml
+++ b/Source/Android/app/src/main/res/values/themes.xml
@@ -1,5 +1,5 @@
-
+
-
-
-
+
+
+
+
diff --git a/Source/Core/Core/ConfigLoaders/IsSettingSaveable.cpp b/Source/Core/Core/ConfigLoaders/IsSettingSaveable.cpp
index 92411968b4..9f83c28cc5 100644
--- a/Source/Core/Core/ConfigLoaders/IsSettingSaveable.cpp
+++ b/Source/Core/Core/ConfigLoaders/IsSettingSaveable.cpp
@@ -39,10 +39,10 @@ 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 = {
+ static constexpr std::array android_setting_saveable = {
"ControlScale", "ControlOpacity", "EmulationOrientation", "JoystickRelCenter",
"LastPlatformTab", "MotionControls", "PhoneRumble", "ShowInputOverlay",
- "IRMode", "IRAlwaysRecenter", "ShowGameTitles"};
+ "IRMode", "IRAlwaysRecenter", "ShowGameTitles", "InterfaceTheme"};
return std::any_of(
android_setting_saveable.cbegin(), android_setting_saveable.cend(),