Android: Greatly simplify MotionAlertDialog theming

This commit is contained in:
Charles Lombardo 2022-12-01 18:52:13 -05:00
parent 385dfb60a0
commit 09e350d9a7
3 changed files with 27 additions and 78 deletions

View File

@ -3,29 +3,13 @@
package org.dolphinemu.dolphinemu.dialogs; package org.dolphinemu.dolphinemu.dialogs;
import android.content.Context; 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.InputDevice;
import android.view.KeyEvent; import android.view.KeyEvent;
import android.view.MotionEvent; import android.view.MotionEvent;
import androidx.annotation.AttrRes;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.StyleRes;
import androidx.appcompat.app.AlertDialog; 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.model.view.InputBindingSetting;
import org.dolphinemu.dolphinemu.features.settings.ui.SettingsAdapter; import org.dolphinemu.dolphinemu.features.settings.ui.SettingsAdapter;
import org.dolphinemu.dolphinemu.utils.ControllerMappingHelper; import org.dolphinemu.dolphinemu.utils.ControllerMappingHelper;
@ -34,20 +18,12 @@ import org.dolphinemu.dolphinemu.utils.Log;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import static com.google.android.material.theme.overlay.MaterialThemeOverlay.wrap;
/** /**
* {@link AlertDialog} derivative that listens for * {@link AlertDialog} derivative that listens for
* motion events from controllers and joysticks. * motion events from controllers and joysticks.
*/ */
public final class MotionAlertDialog extends AlertDialog 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 // The selected input preference
private final InputBindingSetting setting; private final InputBindingSetting setting;
private final ArrayList<Float> mPreviousValues = new ArrayList<>(); private final ArrayList<Float> mPreviousValues = new ArrayList<>();
@ -63,63 +39,10 @@ public final class MotionAlertDialog extends AlertDialog
*/ */
public MotionAlertDialog(Context context, InputBindingSetting setting, SettingsAdapter adapter) public MotionAlertDialog(Context context, InputBindingSetting setting, SettingsAdapter adapter)
{ {
super(createMaterialAlertDialogThemedContext(context)); super(context);
this.setting = setting; this.setting = setting;
mAdapter = adapter; 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) public boolean onKeyEvent(int keyCode, KeyEvent event)

View File

@ -5,17 +5,23 @@ package org.dolphinemu.dolphinemu.features.settings.ui;
import android.content.Context; import android.content.Context;
import android.content.DialogInterface; import android.content.DialogInterface;
import android.content.Intent; import android.content.Intent;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.os.Build; import android.os.Build;
import android.provider.DocumentsContract; import android.provider.DocumentsContract;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.ColorInt;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.RecyclerView;
import com.google.android.material.color.MaterialColors;
import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.android.material.elevation.ElevationOverlayProvider;
import com.google.android.material.slider.Slider; import com.google.android.material.slider.Slider;
import com.google.android.material.textfield.TextInputEditText; import com.google.android.material.textfield.TextInputEditText;
@ -300,6 +306,14 @@ public final class SettingsAdapter extends RecyclerView.Adapter<SettingViewHolde
public void onInputBindingClick(final InputBindingSetting item, final int position) public void onInputBindingClick(final InputBindingSetting item, final int position)
{ {
final MotionAlertDialog dialog = new MotionAlertDialog(mContext, item, this); final MotionAlertDialog dialog = new MotionAlertDialog(mContext, item, this);
Drawable background = ContextCompat.getDrawable(mContext, R.drawable.dialog_round);
@ColorInt int color = new ElevationOverlayProvider(dialog.getContext()).compositeOverlay(
MaterialColors.getColor(dialog.getWindow().getDecorView(), R.attr.colorSurface),
dialog.getWindow().getDecorView().getElevation());
background.setColorFilter(color, PorterDuff.Mode.SRC_ATOP);
dialog.getWindow().setBackgroundDrawable(background);
dialog.setTitle(R.string.input_binding); dialog.setTitle(R.string.input_binding);
dialog.setMessage(String.format(mContext.getString( dialog.setMessage(String.format(mContext.getString(
item instanceof RumbleBindingSetting ? item instanceof RumbleBindingSetting ?

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid
android:color="@android:color/white"/>
<corners
android:radius="28dp" />
<padding
android:left="4dp"
android:top="4dp"
android:right="4dp"
android:bottom="4dp" />
</shape>