Skip to content

Commit

Permalink
Android: Pad menu fragment when expanding to cutout area
Browse files Browse the repository at this point in the history
  • Loading branch information
t895 committed Dec 2, 2022
1 parent 385dfb6 commit a90588c
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 63 deletions.
Expand Up @@ -16,6 +16,7 @@
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.TextView;
import android.widget.Toast;
Expand All @@ -25,6 +26,9 @@
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.PopupMenu;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
Expand Down Expand Up @@ -342,6 +346,8 @@ protected void onCreate(Bundle savedInstanceState)
ActivityEmulationBinding binding = ActivityEmulationBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());

setInsets(binding.frameMenu);

// Find or create the EmulationFragment
mEmulationFragment = (EmulationFragment) getSupportFragmentManager()
.findFragmentById(R.id.frame_emulation_fragment);
Expand Down Expand Up @@ -538,6 +544,26 @@ private void toggleMenu()
}
}

private void setInsets(View view)
{
ViewCompat.setOnApplyWindowInsetsListener(view, (v, windowInsets) ->
{
Insets cutInsets = windowInsets.getInsets(WindowInsetsCompat.Type.displayCutout());
ViewGroup.MarginLayoutParams mlpMenu =
(ViewGroup.MarginLayoutParams) v.getLayoutParams();
int menuWidth = getResources().getDimensionPixelSize(R.dimen.menu_width);
if (ViewCompat.getLayoutDirection(v) == ViewCompat.LAYOUT_DIRECTION_LTR)
{
mlpMenu.width = cutInsets.left + menuWidth;
}
else
{
mlpMenu.width = cutInsets.right + menuWidth;
}
return windowInsets;
});
}

public void showOverlayControlsMenu(@NonNull View anchor)
{
PopupMenu popup = new PopupMenu(this, anchor);
Expand Down
Expand Up @@ -3,7 +3,6 @@
package org.dolphinemu.dolphinemu.fragments;

import android.content.pm.PackageManager;
import android.graphics.Rect;
import android.os.Bundle;
import android.util.SparseIntArray;
import android.view.LayoutInflater;
Expand All @@ -14,13 +13,17 @@

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import androidx.fragment.app.Fragment;

import org.dolphinemu.dolphinemu.NativeLibrary;
import org.dolphinemu.dolphinemu.R;
import org.dolphinemu.dolphinemu.activities.EmulationActivity;
import org.dolphinemu.dolphinemu.databinding.FragmentIngameMenuBinding;
import org.dolphinemu.dolphinemu.features.settings.model.BooleanSetting;
import org.dolphinemu.dolphinemu.utils.InsetsHelper;

public final class MenuFragment extends Fragment implements View.OnClickListener
{
Expand Down Expand Up @@ -68,14 +71,6 @@ public static MenuFragment newInstance()
return fragment;
}

// This is primarily intended to account for any navigation bar at the bottom of the screen
private int getBottomPaddingRequired()
{
Rect visibleFrame = new Rect();
requireActivity().getWindow().getDecorView().getWindowVisibleDisplayFrame(visibleFrame);
return visibleFrame.bottom - visibleFrame.top - getResources().getDisplayMetrics().heightPixels;
}

@NonNull
@Override
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
Expand All @@ -88,6 +83,7 @@ public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container,
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState)
{
setInsets();
updatePauseUnpauseVisibility();

if (!requireActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN))
Expand All @@ -100,21 +96,6 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat
mBinding.menuRefreshWiimotes.setVisibility(View.GONE);
}

int bottomPaddingRequired = getBottomPaddingRequired();

// Provide a safe zone between the navigation bar and Exit Emulation to avoid accidental touches
float density = getResources().getDisplayMetrics().density;
if (bottomPaddingRequired >= 32 * density)
{
bottomPaddingRequired += 32 * density;
}

if (bottomPaddingRequired > view.getPaddingBottom())
{
view.setPadding(view.getPaddingLeft(), view.getPaddingTop(),
view.getPaddingRight(), bottomPaddingRequired);
}

LinearLayout options = mBinding.layoutOptions;
for (int childIndex = 0; childIndex < options.getChildCount(); childIndex++)
{
Expand All @@ -137,6 +118,37 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat
}
}

private void setInsets()
{
ViewCompat.setOnApplyWindowInsetsListener(mBinding.getRoot(), (v, windowInsets) ->
{
Insets cutInsets = windowInsets.getInsets(WindowInsetsCompat.Type.displayCutout());
int left = 0;
int right = 0;
if (ViewCompat.getLayoutDirection(v) == ViewCompat.LAYOUT_DIRECTION_LTR)
{
left = cutInsets.left;
}
else
{
right = cutInsets.right;
}

// Don't use padding if the navigation bar isn't in the way
if (InsetsHelper.getBottomPaddingRequired(requireActivity()) > 0)
{
v.setPadding(left, cutInsets.top, right,
cutInsets.bottom + InsetsHelper.getNavigationBarHeight(requireContext()));
}
else
{
v.setPadding(left, cutInsets.top, right,
cutInsets.bottom + getResources().getDimensionPixelSize(R.dimen.spacing_large));
}
return windowInsets;
});
}

@Override
public void onResume()
{
Expand Down
@@ -1,7 +1,9 @@
package org.dolphinemu.dolphinemu.utils;

import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Rect;
import android.util.DisplayMetrics;
import android.view.View;
import android.view.ViewGroup;
Expand Down Expand Up @@ -222,4 +224,23 @@ public static int getSystemGestureType(Context context)
}
return 0;
}

public static int getNavigationBarHeight(Context context)
{
Resources resources = context.getResources();
int resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android");
if (resourceId > 0)
{
return resources.getDimensionPixelSize(resourceId);
}
return 0;
}

// This is primarily intended to account for any navigation bar at the bottom of the screen
public static int getBottomPaddingRequired(Activity activity)
{
Rect visibleFrame = new Rect();
activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(visibleFrame);
return visibleFrame.bottom - visibleFrame.top - activity.getResources().getDisplayMetrics().heightPixels;
}
}
Expand Up @@ -22,7 +22,7 @@

<FrameLayout
android:id="@+id/frame_menu"
android:layout_width="260dp"
android:layout_width="@dimen/menu_width"
android:layout_height="match_parent"
tools:layout="@layout/fragment_ingame_menu"/>

Expand Down
58 changes: 24 additions & 34 deletions Source/Android/app/src/main/res/layout/fragment_ingame_menu.xml
@@ -1,33 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="16dp"
android:background="?attr/colorSurface"
tools:layout_width="250dp">
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="?attr/colorSurface"
tools:layout_width="250dp">

<TextView
android:id="@+id/text_game_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:layout_marginHorizontal="32dp"
android:layout_marginTop="32dp"
android:layout_marginVertical="24dp"
android:ellipsize="end"
android:letterSpacing="0"
android:maxLines="@integer/game_title_lines"
android:textSize="20sp"
android:textColor="?attr/colorOnSurface"
tools:text="The Legend of Zelda: The Wind Waker" />

<com.google.android.material.divider.MaterialDivider
android:id="@+id/divider"
android:layout_width="match_parent"
android:layout_height="wrap_content" />

<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:scrollbarSize="8dp"
android:fadeScrollbars="false">
android:scrollbarSize="4dp">

<LinearLayout
android:id="@+id/layout_options"
Expand All @@ -38,73 +41,62 @@
<Button
android:id="@+id/menu_pause_emulation"
style="@style/InGameMenuOption"
android:letterSpacing="0"
android:text="@string/pause_emulation" />

<Button
android:id="@+id/menu_unpause_emulation"
style="@style/InGameMenuOption"
android:letterSpacing="0"
android:text="@string/unpause_emulation"
android:visibility="gone"/>
android:visibility="gone" />

<Button
android:id="@+id/menu_take_screenshot"
style="@style/InGameMenuOption"
android:letterSpacing="0"
android:text="@string/emulation_screenshot" />

<Button
android:id="@+id/menu_quicksave"
style="@style/InGameMenuOption"
android:letterSpacing="0"
android:text="@string/emulation_quicksave"
android:visibility="gone"/>
android:visibility="gone" />

<Button
android:id="@+id/menu_quickload"
style="@style/InGameMenuOption"
android:letterSpacing="0"
android:text="@string/emulation_quickload"
android:visibility="gone"/>
android:visibility="gone" />

<Button
android:id="@+id/menu_emulation_save_root"
style="@style/InGameMenuOption"
android:letterSpacing="0"
android:text="@string/emulation_savestate"
android:visibility="gone"/>
android:visibility="gone" />

<Button
android:id="@+id/menu_emulation_load_root"
style="@style/InGameMenuOption"
android:letterSpacing="0"
android:text="@string/emulation_loadstate"
android:visibility="gone"/>
android:visibility="gone" />

<Button
android:id="@+id/menu_settings"
style="@style/InGameMenuOption"
android:letterSpacing="0"
android:text="@string/grid_menu_settings" />

<Button
android:id="@+id/menu_overlay_controls"
style="@style/InGameMenuOption"
android:letterSpacing="0"
android:text="@string/emulation_overlay_controls" />

<Button
android:id="@+id/menu_refresh_wiimotes"
android:text="@string/emulation_refresh_wiimotes"
android:letterSpacing="0"
style="@style/InGameMenuOption"/>
style="@style/InGameMenuOption" />

<Button
android:id="@+id/menu_change_disc"
android:text="@string/emulation_change_disc"
android:letterSpacing="0"
style="@style/InGameMenuOption"/>
style="@style/InGameMenuOption" />

</LinearLayout>

Expand All @@ -113,14 +105,12 @@
<com.google.android.material.divider.MaterialDivider
android:id="@+id/divider_2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:layout_marginBottom="16dp" />
android:layout_height="wrap_content" />

<Button
android:id="@+id/menu_exit"
style="@style/InGameMenuOption"
android:letterSpacing="0"
android:layout_marginTop="@dimen/spacing_large"
android:text="@string/emulation_exit" />

</LinearLayout>
1 change: 1 addition & 0 deletions Source/Android/app/src/main/res/values/dimens.xml
Expand Up @@ -2,5 +2,6 @@
<dimen name="spacing_small">4dp</dimen>
<dimen name="spacing_medlarge">12dp</dimen>
<dimen name="spacing_large">16dp</dimen>
<dimen name="menu_width">256dp</dimen>
<dimen name="card_width">135dp</dimen>
</resources>
6 changes: 2 additions & 4 deletions Source/Android/app/src/main/res/values/styles.xml
Expand Up @@ -2,16 +2,14 @@
<resources>
<!-- Custom button styles -->
<style name="InGameMenuOption" parent="Widget.Material3.Button.TextButton">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">48dp</item>
<item name="android:textColor">?attr/colorOnSurface</item>
<item name="android:textSize">16sp</item>
<item name="android:fontFamily">sans-serif-condensed</item>
<item name="android:textAllCaps">false</item>
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">48dp</item>
<item name="android:gravity">center_vertical|left</item>
<item name="android:paddingLeft">32dp</item>
<item name="android:paddingRight">32dp</item>
<item name="android:layout_margin">0dp</item>
</style>

<style name="OverlayInGameMenuOption" parent="InGameMenuOption">
Expand Down

0 comments on commit a90588c

Please sign in to comment.