@@ -0,0 +1,181 @@
package org.dolphinemu.dolphinemu.utils;

import android.content.Context;
import android.content.res.Resources;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import androidx.core.widget.NestedScrollView;
import androidx.recyclerview.widget.RecyclerView;
import androidx.slidingpanelayout.widget.SlidingPaneLayout;
import androidx.viewpager.widget.ViewPager;

import com.google.android.material.appbar.AppBarLayout;
import com.google.android.material.color.MaterialColors;
import com.google.android.material.floatingactionbutton.FloatingActionButton;

import org.dolphinemu.dolphinemu.R;

public class InsetsHelper
{
public static final int FAB_INSET = 16;
public static final int EXTRA_NAV_INSET = 32;

public static final int THREE_BUTTON_NAVIGATION = 0;
public static final int TWO_BUTTON_NAVIGATION = 1;
public static final int GESTURE_NAVIGATION = 2;

public static int dpToPx(Context context, int dp)
{
return (int) (dp * ((float) context.getResources().getDisplayMetrics().densityDpi /
DisplayMetrics.DENSITY_DEFAULT) + 0.5f);
}

public static void setUpAppBarWithScrollView(AppCompatActivity activity,
AppBarLayout appBarLayout, NestedScrollView nestedScrollView, View workaroundView)
{
ViewCompat.setOnApplyWindowInsetsListener(appBarLayout, (v, windowInsets) ->
{
Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars());

insetAppBar(insets, appBarLayout);

nestedScrollView.setPadding(insets.left, 0, insets.right, insets.bottom);

applyWorkaround(insets.bottom, workaroundView);

ThemeHelper.setNavigationBarColor(activity,
MaterialColors.getColor(appBarLayout, R.attr.colorSurface));

return windowInsets;
});
}

public static void setUpList(Context context, RecyclerView recyclerView)
{
ViewCompat.setOnApplyWindowInsetsListener(recyclerView, (v, windowInsets) ->
{
Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars());
v.setPadding(0, 0, 0, insets.bottom + dpToPx(context, EXTRA_NAV_INSET));

return windowInsets;
});
}

public static void setUpMainLayout(AppCompatActivity activity, AppBarLayout appBarLayout,
FloatingActionButton fab, ViewPager viewPager, View workaroundView)
{
ViewCompat.setOnApplyWindowInsetsListener(appBarLayout, (v, windowInsets) ->
{
Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars());

insetAppBar(insets, appBarLayout);

ViewGroup.MarginLayoutParams mlpFab = (ViewGroup.MarginLayoutParams) fab.getLayoutParams();
int fabPadding =
InsetsHelper.dpToPx(activity.getApplicationContext(), FAB_INSET);
mlpFab.leftMargin = insets.left + fabPadding;
mlpFab.bottomMargin = insets.bottom + fabPadding;
mlpFab.rightMargin = insets.right + fabPadding;
fab.setLayoutParams(mlpFab);

viewPager.setPadding(insets.left, 0, insets.right, 0);

applyWorkaround(insets.bottom, workaroundView);

ThemeHelper.setNavigationBarColor(activity,
MaterialColors.getColor(appBarLayout, R.attr.colorSurface));

return windowInsets;
});
}

public static void setUpSettingsLayout(AppCompatActivity activity,
AppBarLayout appBarLayout, FrameLayout frameLayout, View workaroundView)
{
ViewCompat.setOnApplyWindowInsetsListener(appBarLayout, (v, windowInsets) ->
{
Insets insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars());

insetAppBar(insets, appBarLayout);

frameLayout.setPadding(insets.left, 0, insets.right, 0);

applyWorkaround(insets.bottom, workaroundView);

ThemeHelper.setNavigationBarColor(activity,
MaterialColors.getColor(appBarLayout, R.attr.colorSurface));

return windowInsets;
});
}

public static void setUpCheatsLayout(AppCompatActivity activity, AppBarLayout appBarLayout,
SlidingPaneLayout slidingPaneLayout, View cheatDetails, View workaroundView)
{
ViewCompat.setOnApplyWindowInsetsListener(appBarLayout, (v, windowInsets) ->
{
Insets barInsets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars());
Insets keyboardInsets = windowInsets.getInsets(WindowInsetsCompat.Type.ime());

insetAppBar(barInsets, appBarLayout);

slidingPaneLayout.setPadding(barInsets.left, barInsets.top, barInsets.right, 0);

if (keyboardInsets.bottom > 0)
{
cheatDetails.setPadding(0, 0, 0, keyboardInsets.bottom);
}
else
{
cheatDetails.setPadding(0, 0, 0, barInsets.bottom);
}

applyWorkaround(barInsets.bottom, workaroundView);

ThemeHelper.setNavigationBarColor(activity,
MaterialColors.getColor(appBarLayout, R.attr.colorSurface));

return windowInsets;
});
}

private static void insetAppBar(Insets insets, AppBarLayout appBarLayout)
{
ViewGroup.MarginLayoutParams mlpAppBar =
(ViewGroup.MarginLayoutParams) appBarLayout.getLayoutParams();
mlpAppBar.leftMargin = insets.left;
mlpAppBar.topMargin = insets.top;
mlpAppBar.rightMargin = insets.right;
appBarLayout.setLayoutParams(mlpAppBar);
}

// Workaround for a bug on Android 13 that allows users to interact with UI behind the
// navigation bar https://issuetracker.google.com/issues/248761842
private static void applyWorkaround(int bottomInset, View workaroundView)
{
if (bottomInset > 0)
{
ViewGroup.LayoutParams lpWorkaround = workaroundView.getLayoutParams();
lpWorkaround.height = bottomInset;
workaroundView.setLayoutParams(lpWorkaround);
}
}

public static int getSystemGestureType(Context context)
{
Resources resources = context.getResources();
int resourceId = resources.getIdentifier("config_navBarInteractionMode", "integer", "android");
if (resourceId != 0)
{
return resources.getInteger(resourceId);
}
return 0;
}
}
@@ -3,10 +3,15 @@
import android.app.Activity;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.graphics.Color;
import android.os.Build;
import android.preference.PreferenceManager;

import androidx.annotation.ColorInt;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;

import com.google.android.material.appbar.AppBarLayout;
import com.google.android.material.appbar.MaterialToolbar;
@@ -25,7 +30,9 @@
public static final int GREEN = 3;
public static final int PINK = 4;

public static void setTheme(Activity activity)
public static final float NAV_BAR_ALPHA = 0.9f;

public static void setTheme(@NonNull AppCompatActivity 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.
@@ -35,63 +42,42 @@ public static void setTheme(Activity activity)
{
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));
activity.getWindow().setStatusBarColor(
ContextCompat.getColor(activity.getApplicationContext(), android.R.color.black));
}
}

public static void saveTheme(Activity activity, int themeValue)
public static void saveTheme(@NonNull Activity activity, int themeValue)
{
SharedPreferences preferences =
PreferenceManager.getDefaultSharedPreferences(activity.getApplicationContext());
preferences.edit().putInt(CURRENT_THEME, themeValue).apply();
}

public static void deleteThemeKey(Activity activity)
public static void deleteThemeKey(@NonNull Activity activity)
{
SharedPreferences preferences =
PreferenceManager.getDefaultSharedPreferences(activity.getApplicationContext());
@@ -100,7 +86,7 @@ public static void deleteThemeKey(Activity activity)
activity.recreate();
}

public static void setCorrectTheme(Activity activity)
public static void setCorrectTheme(AppCompatActivity activity)
{
int currentTheme = ((ThemeProvider) activity).getThemeId();
setTheme(activity);
@@ -111,36 +97,98 @@ public static void setCorrectTheme(Activity activity)
}
}

private static void setStatusBarColor(@ColorInt int color, Activity activity)
public static void setStatusBarColor(AppCompatActivity activity, @ColorInt int color)
{
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M)
{
activity.getWindow()
.setStatusBarColor(activity.getResources().getColor(android.R.color.black));
activity.getWindow().setStatusBarColor(
ContextCompat.getColor(activity.getApplicationContext(), android.R.color.black));
}
else
{
activity.getWindow().setStatusBarColor(color);
}
}

public static void enableScrollTint(MaterialToolbar toolbar, AppBarLayout appBarLayout,
Activity activity)
public static void setNavigationBarColor(Activity activity, @ColorInt int color)
{
int gestureType = InsetsHelper.getSystemGestureType(activity.getApplicationContext());
int orientation = activity.getResources().getConfiguration().orientation;

// Use black if the Android version is too low to support changing button colors
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O_MR1)
{
activity.getWindow().setNavigationBarColor(
ContextCompat.getColor(activity.getApplicationContext(), android.R.color.black));
}
// Use a solid color when the navigation bar is on the left/right edge of the screen
else if ((gestureType == InsetsHelper.THREE_BUTTON_NAVIGATION ||
gestureType == InsetsHelper.TWO_BUTTON_NAVIGATION) &&
orientation == Configuration.ORIENTATION_LANDSCAPE)
{
activity.getWindow().setNavigationBarColor(color);
}
// Use semi-transparent color when in portrait mode with three/two button navigation to
// partially see list items behind the navigation bar
else if (gestureType == InsetsHelper.THREE_BUTTON_NAVIGATION ||
gestureType == InsetsHelper.TWO_BUTTON_NAVIGATION)
{
activity.getWindow().setNavigationBarColor(getColorWithOpacity(color, NAV_BAR_ALPHA));
}
// Use transparent color when using gesture navigation
else
{
activity.getWindow().setNavigationBarColor(
ContextCompat.getColor(activity.getApplicationContext(),
android.R.color.transparent));
}
}

public static void enableScrollTint(AppCompatActivity activity, MaterialToolbar toolbar,
@NonNull AppBarLayout appBarLayout)
{
appBarLayout.addOnOffsetChangedListener((layout, verticalOffset) ->
{
if (-verticalOffset >= (layout.getTotalScrollRange() / 2))
{
@ColorInt int color = MaterialColors.getColor(toolbar, R.attr.colorSurfaceVariant);
toolbar.setBackgroundColor(color);
setStatusBarColor(color, activity);
setStatusBarColor(activity, color);
}
else
{
@ColorInt int color = MaterialColors.getColor(toolbar, R.attr.colorSurface);
toolbar.setBackgroundColor(color);
setStatusBarColor(color, activity);
@ColorInt int statusBarColor = ContextCompat.getColor(activity.getApplicationContext(),
android.R.color.transparent);
@ColorInt int appBarColor = MaterialColors.getColor(toolbar, R.attr.colorSurface);
toolbar.setBackgroundColor(appBarColor);
setStatusBarColor(activity, statusBarColor);
}
});
}

public static void enableStatusBarScrollTint(AppCompatActivity activity,
@NonNull AppBarLayout appBarLayout)
{
appBarLayout.addOnOffsetChangedListener((layout, verticalOffset) ->
{
if (-verticalOffset > 0)
{
@ColorInt int color = MaterialColors.getColor(appBarLayout, R.attr.colorSurface);
setStatusBarColor(activity, color);
}
else
{
@ColorInt int statusBarColor = ContextCompat.getColor(activity.getApplicationContext(),
android.R.color.transparent);
setStatusBarColor(activity, statusBarColor);
}
});
}

@RequiresApi(api = Build.VERSION_CODES.O_MR1) @ColorInt
private static int getColorWithOpacity(@ColorInt int color, float alphaFactor)
{
return Color.argb(Math.round(alphaFactor * Color.alpha(color)), Color.red(color),
Color.green(color), Color.blue(color));
}
}
@@ -4,7 +4,8 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:background="?attr/colorSurface">

<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar_user_data"
@@ -18,6 +19,7 @@
android:id="@+id/toolbar_user_data_layout"
android:layout_width="match_parent"
android:layout_height="?attr/collapsingToolbarLayoutMediumSize"
app:contentScrim="@android:color/transparent"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">

<com.google.android.material.appbar.MaterialToolbar
@@ -33,8 +35,10 @@
</com.google.android.material.appbar.AppBarLayout>

<androidx.core.widget.NestedScrollView
android:id="@+id/scroll_view_user_data"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
app:layout_behavior="@string/appbar_scrolling_view_behavior">

<androidx.constraintlayout.widget.ConstraintLayout
@@ -140,4 +144,12 @@

</androidx.core.widget.NestedScrollView>

<View
android:id="@+id/workaround_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_gravity="bottom"
android:clickable="true"
android:background="@android:color/transparent" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>
@@ -3,7 +3,8 @@
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:background="?attr/colorSurface">

<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar_convert"
@@ -17,6 +18,7 @@
android:id="@+id/toolbar_convert_layout"
android:layout_width="match_parent"
android:layout_height="?attr/collapsingToolbarLayoutMediumSize"
app:contentScrim="@android:color/transparent"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">

<com.google.android.material.appbar.MaterialToolbar
@@ -32,8 +34,10 @@
</com.google.android.material.appbar.AppBarLayout>

<androidx.core.widget.NestedScrollView
android:id="@+id/scroll_view_convert"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
app:layout_behavior="@string/appbar_scrolling_view_behavior">

<androidx.constraintlayout.widget.ConstraintLayout
@@ -79,4 +83,12 @@

</androidx.core.widget.NestedScrollView>

<View
android:id="@+id/workaround_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_gravity="bottom"
android:clickable="true"
android:background="@android:color/transparent" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>
@@ -3,28 +3,30 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/coordinator_main"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:background="?attr/colorSurface">

<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar_cheats"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
app:liftOnScroll="false"
app:elevation="0dp">

<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar_cheats"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorSurface"/>
android:background="?attr/colorSurface" />

</com.google.android.material.appbar.AppBarLayout>

<androidx.slidingpanelayout.widget.SlidingPaneLayout
android:id="@+id/sliding_pane_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="56dp">
android:layout_marginTop="64dp">

<androidx.fragment.app.FragmentContainerView
android:id="@+id/cheat_list"
@@ -40,4 +42,12 @@

</androidx.slidingpanelayout.widget.SlidingPaneLayout>

<View
android:id="@+id/workaround_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_gravity="bottom"
android:clickable="true"
android:background="@android:color/transparent" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>
@@ -3,7 +3,8 @@
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:background="?attr/colorSurface">

<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar_convert"
@@ -17,6 +18,7 @@
android:id="@+id/toolbar_convert_layout"
android:layout_width="match_parent"
android:layout_height="?attr/collapsingToolbarLayoutMediumSize"
app:contentScrim="@android:color/transparent"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">

<com.google.android.material.appbar.MaterialToolbar
@@ -32,8 +34,10 @@
</com.google.android.material.appbar.AppBarLayout>

<androidx.core.widget.NestedScrollView
android:id="@+id/scroll_view_convert"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
app:layout_behavior="@string/appbar_scrolling_view_behavior">

<androidx.constraintlayout.widget.ConstraintLayout
@@ -77,4 +81,12 @@

</androidx.core.widget.NestedScrollView>

<View
android:id="@+id/workaround_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_gravity="bottom"
android:clickable="true"
android:background="@android:color/transparent" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>
@@ -4,12 +4,14 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/coordinator_main"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:background="?attr/colorSurface">

<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar_main"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:liftOnScroll="false"
app:elevation="0dp">

<com.google.android.material.appbar.MaterialToolbar
@@ -40,11 +42,18 @@
android:background="?attr/colorSurface"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />

<View
android:id="@+id/workaround_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_gravity="bottom"
android:clickable="true"
android:background="@android:color/transparent" />

<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/button_add_directory"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:src="@drawable/ic_add"
app:layout_anchor="@+id/pager_platforms"
app:layout_anchorGravity="bottom|right|end" />
@@ -4,7 +4,8 @@
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:background="?attr/colorSurface">

<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar_riivolution"
@@ -18,6 +19,7 @@
android:id="@+id/toolbar_riivolution_layout"
android:layout_width="match_parent"
android:layout_height="?attr/collapsingToolbarLayoutMediumSize"
app:contentScrim="@android:color/transparent"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">

<com.google.android.material.appbar.MaterialToolbar
@@ -33,8 +35,10 @@
</com.google.android.material.appbar.AppBarLayout>

<androidx.core.widget.NestedScrollView
android:id="@+id/scroll_view_riivolution"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
app:layout_behavior="@string/appbar_scrolling_view_behavior">

<androidx.constraintlayout.widget.ConstraintLayout
@@ -94,4 +98,12 @@

</androidx.core.widget.NestedScrollView>

<View
android:id="@+id/workaround_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_gravity="bottom"
android:clickable="true"
android:background="@android:color/transparent" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>
@@ -4,7 +4,8 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/coordinator_main"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:background="?attr/colorSurface">

<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar_settings"
@@ -18,6 +19,7 @@
android:id="@+id/toolbar_settings_layout"
android:layout_width="match_parent"
android:layout_height="?attr/collapsingToolbarLayoutMediumSize"
app:contentScrim="@android:color/transparent"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">

<com.google.android.material.appbar.MaterialToolbar
@@ -32,9 +34,17 @@
</com.google.android.material.appbar.AppBarLayout>

<FrameLayout
android:id="@+id/frame_content"
android:id="@+id/frame_content_settings"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>

<View
android:id="@+id/workaround_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_gravity="bottom"
android:clickable="true"
android:background="@android:color/transparent" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>
@@ -4,7 +4,8 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:background="?attr/colorSurface">

<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar_user_data"
@@ -18,6 +19,7 @@
android:id="@+id/toolbar_user_data_layout"
android:layout_width="match_parent"
android:layout_height="?attr/collapsingToolbarLayoutMediumSize"
app:contentScrim="@android:color/transparent"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">

<com.google.android.material.appbar.MaterialToolbar
@@ -33,8 +35,10 @@
</com.google.android.material.appbar.AppBarLayout>

<androidx.core.widget.NestedScrollView
android:id="@+id/scroll_view_user_data"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clipToPadding="false"
app:layout_behavior="@string/appbar_scrolling_view_behavior">

<androidx.constraintlayout.widget.ConstraintLayout
@@ -117,4 +121,12 @@

</androidx.core.widget.NestedScrollView>

<View
android:id="@+id/workaround_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_gravity="bottom"
android:clickable="true"
android:background="@android:color/transparent" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
@@ -8,37 +9,38 @@
android:clickable="true"
android:clipToPadding="false"
android:focusable="true"
android:orientation="vertical"
android:paddingStart="4dp"
android:paddingTop="8dp"
android:paddingEnd="4dp"
android:paddingBottom="8dp"
android:transitionName="card_game">

<androidx.cardview.widget.CardView
android:id="@+id/card_game_art"
android:layout_width="115dp"
android:layout_height="161dp"
android:layout_gravity="center"
android:layout_marginBottom="8dp"
app:cardCornerRadius="4dp">
app:cardCornerRadius="4dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">

<ImageView
android:id="@+id/image_game_screen"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"/>
android:layout_weight="1" />

<TextView
android:id="@+id/text_game_title_inner"
style="@android:style/TextAppearance.Material.Subhead"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="8dp"
android:paddingLeft="2dp"
android:paddingRight="2dp"
android:ellipsize="end"
android:gravity="center|top"
android:maxLines="2"
android:paddingLeft="2dp"
android:paddingRight="2dp"
android:paddingTop="8dp"
android:visibility="visible"
tools:text="The Legend of Zelda: The Wind Waker" />

@@ -47,26 +49,28 @@
<TextView
android:id="@+id/text_game_title"
style="@android:style/TextAppearance.Material.Subhead"
android:layout_width="wrap_content"
android:layout_width="115dp"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:ellipsize="end"
android:maxLines="2"
tools:layout_width="140dp"
android:paddingTop="8dp"
app:layout_constraintEnd_toEndOf="@+id/card_game_art"
app:layout_constraintStart_toStartOf="@+id/card_game_art"
app:layout_constraintTop_toBottomOf="@+id/card_game_art"
tools:text="The Legend of Zelda: The Wind Waker" />

<TextView
android:id="@+id/text_game_caption"
style="@android:style/TextAppearance.Material.Caption"
android:layout_width="wrap_content"
android:layout_width="115dp"
android:layout_height="wrap_content"
android:layout_gravity="start"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"
android:ellipsize="end"
android:lines="1"
android:maxLines="1"
tools:layout_width="140dp"
android:paddingTop="8dp"
app:layout_constraintEnd_toEndOf="@+id/card_game_art"
app:layout_constraintStart_toStartOf="@+id/card_game_art"
app:layout_constraintTop_toBottomOf="@+id/text_game_title"
tools:text="Nintendo" />

</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
@@ -14,7 +14,7 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toTopOf="@id/barrier">
app:layout_constraintBottom_toTopOf="@id/button_layout">

<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
@@ -119,55 +119,62 @@

</ScrollView>

<androidx.constraintlayout.widget.Barrier
android:id="@+id/barrier"
android:layout_width="wrap_content"
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/button_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:barrierDirection="top"
app:constraint_referenced_ids="button_delete,button_edit,button_cancel,button_ok" />
android:background="@android:color/transparent"
app:layout_constraintBottom_toBottomOf="parent">

<Button
android:id="@+id/button_delete"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="@dimen/spacing_large"
android:text="@string/cheats_delete"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/button_edit"
app:layout_constraintTop_toBottomOf="@id/barrier"
app:layout_constraintBottom_toBottomOf="parent" />

<Button
android:id="@+id/button_edit"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="@dimen/spacing_large"
android:text="@string/cheats_edit"
app:layout_constraintStart_toEndOf="@id/button_delete"
app:layout_constraintEnd_toStartOf="@id/button_cancel"
app:layout_constraintTop_toBottomOf="@id/barrier"
app:layout_constraintBottom_toBottomOf="parent" />

<Button
android:id="@+id/button_cancel"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="@dimen/spacing_large"
android:text="@string/cancel"
app:layout_constraintStart_toEndOf="@id/button_edit"
app:layout_constraintEnd_toStartOf="@id/button_ok"
app:layout_constraintTop_toBottomOf="@id/barrier"
app:layout_constraintBottom_toBottomOf="parent" />

<Button
android:id="@+id/button_ok"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="@dimen/spacing_large"
android:text="@string/ok"
app:layout_constraintStart_toEndOf="@id/button_cancel"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/barrier"
app:layout_constraintBottom_toBottomOf="parent" />
<com.google.android.material.divider.MaterialDivider
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toTopOf="parent" />

<Button
android:id="@+id/button_delete"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="@dimen/spacing_large"
android:text="@string/cheats_delete"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/button_edit"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<Button
android:id="@+id/button_edit"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="@dimen/spacing_large"
android:text="@string/cheats_edit"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/button_cancel"
app:layout_constraintStart_toEndOf="@id/button_delete"
app:layout_constraintTop_toTopOf="parent" />

<Button
android:id="@+id/button_cancel"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="@dimen/spacing_large"
android:text="@string/cancel"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/button_ok"
app:layout_constraintStart_toEndOf="@id/button_edit"
app:layout_constraintTop_toTopOf="parent" />

<Button
android:id="@+id/button_ok"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_margin="@dimen/spacing_large"
android:text="@string/ok"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/button_cancel"
app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

</androidx.constraintlayout.widget.ConstraintLayout>
@@ -10,6 +10,7 @@
android:name="org.dolphinemu.dolphinemu.features.cheats.ui.CheatsDisabledWarningFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorSurfaceVariant"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
@@ -20,6 +21,7 @@
android:name="org.dolphinemu.dolphinemu.features.cheats.ui.GraphicsModsDisabledWarningFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorSurfaceVariant"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/cheats_warning"
@@ -29,6 +31,7 @@
android:id="@+id/cheat_list"
android:layout_width="match_parent"
android:layout_height="0dp"
android:clipToPadding="false"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/gfx_mods_warning"
@@ -6,19 +6,17 @@

<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipe_refresh"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/activity_horizontal_margin"
android:layout_marginRight="@dimen/activity_horizontal_margin">

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/grid_games"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:listitem="@layout/card_game"
android:clipToPadding="false"
android:paddingTop="8dp"
android:paddingBottom="8dp"/>
tools:listitem="@layout/card_game" />

</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

@@ -1,12 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<org.dolphinemu.dolphinemu.features.settings.ui.SettingsFrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<org.dolphinemu.dolphinemu.features.settings.ui.SettingsFrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/list_settings"
android:background="?android:attr/colorBackground"
android:background="?attr/colorSurface"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
android:layout_height="match_parent"
android:clipToPadding="false" />

</org.dolphinemu.dolphinemu.features.settings.ui.SettingsFrameLayout>
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Theme.V27.Dolphin" parent="Theme.Dolphin">
<item name="android:navigationBarColor">@android:color/transparent</item>
<item name="android:windowLightNavigationBar">@bool/lightSystemBars</item>
</style>

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Theme.V29.Dolphin" parent="Theme.V27.Dolphin">
<item name="android:enforceStatusBarContrast">false</item>
<item name="android:enforceNavigationBarContrast">false</item>
</style>

<style name="Theme.Dolphin.Main" parent="Theme.V29.Dolphin" />
</resources>