diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsActivity.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsActivity.kt index a92fc10756..ea3d47d829 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsActivity.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsActivity.kt @@ -15,6 +15,7 @@ import androidx.appcompat.app.AppCompatActivity import androidx.core.view.ViewCompat import androidx.core.view.WindowCompat import androidx.core.view.WindowInsetsCompat +import android.view.ViewGroup.MarginLayoutParams import androidx.core.view.updatePadding import com.google.android.material.color.MaterialColors import org.yuzu.yuzu_emu.NativeLibrary @@ -52,12 +53,14 @@ class SettingsActivity : AppCompatActivity(), SettingsActivityView { setSupportActionBar(binding.toolbarSettings) supportActionBar!!.setDisplayHomeAsUpEnabled(true) - binding.navigationBarShade.setBackgroundColor( - ThemeHelper.getColorWithOpacity( - MaterialColors.getColor(binding.navigationBarShade, R.attr.colorSurface), - ThemeHelper.SYSTEM_BAR_ALPHA + if (InsetsHelper.getSystemGestureType(applicationContext) != InsetsHelper.GESTURE_NAVIGATION) { + binding.navigationBarShade.setBackgroundColor( + ThemeHelper.getColorWithOpacity( + MaterialColors.getColor(binding.navigationBarShade, R.attr.colorSurface), + ThemeHelper.SYSTEM_BAR_ALPHA + ) ) - ) + } setInsets() } @@ -164,12 +167,20 @@ class SettingsActivity : AppCompatActivity(), SettingsActivityView { private fun setInsets() { ViewCompat.setOnApplyWindowInsetsListener(binding.frameContent) { view: View, windowInsets: WindowInsetsCompat -> - val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) - view.updatePadding(left = insets.left, right = insets.right) - InsetsHelper.insetAppBar(insets, binding.appbarSettings) + val barInsets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) + val cutoutInsets = windowInsets.getInsets(WindowInsetsCompat.Type.displayCutout()) + view.updatePadding( + left = barInsets.left + cutoutInsets.left, + right = barInsets.right + cutoutInsets.right + ) - val mlpShade = binding.navigationBarShade.layoutParams as ViewGroup.MarginLayoutParams - mlpShade.height = insets.bottom + val mlpAppBar = binding.appbarSettings.layoutParams as MarginLayoutParams + mlpAppBar.leftMargin = barInsets.left + cutoutInsets.left + mlpAppBar.rightMargin = barInsets.right + cutoutInsets.right + binding.appbarSettings.layoutParams = mlpAppBar + + val mlpShade = binding.navigationBarShade.layoutParams as MarginLayoutParams + mlpShade.height = barInsets.bottom binding.navigationBarShade.layoutParams = mlpShade windowInsets diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/HomeSettingsFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/HomeSettingsFragment.kt index eb29d6c964..d651732bf2 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/HomeSettingsFragment.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/HomeSettingsFragment.kt @@ -20,6 +20,7 @@ import androidx.core.app.NotificationCompat import androidx.core.app.NotificationManagerCompat import androidx.core.view.ViewCompat import androidx.core.view.WindowInsetsCompat +import androidx.core.view.updatePadding import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels import androidx.recyclerview.widget.LinearLayoutManager @@ -107,26 +108,30 @@ class HomeSettingsFragment : Fragment() { try { startActivity(getFileManagerIntentOnDocumentProvider(Intent.ACTION_VIEW)) return - } catch (_: ActivityNotFoundException) {} + } catch (_: ActivityNotFoundException) { + } try { startActivity(getFileManagerIntentOnDocumentProvider("android.provider.action.BROWSE")) return - } catch (_: ActivityNotFoundException) {} + } catch (_: ActivityNotFoundException) { + } // Just try to open the file manager, try the package name used on "normal" phones try { startActivity(getFileManagerIntent("com.google.android.documentsui")) showNoLinkNotification() return - } catch (_: ActivityNotFoundException) {} + } catch (_: ActivityNotFoundException) { + } try { // Next, try the AOSP package name startActivity(getFileManagerIntent("com.android.documentsui")) showNoLinkNotification() return - } catch (_: ActivityNotFoundException) {} + } catch (_: ActivityNotFoundException) { + } Toast.makeText( requireContext(), @@ -153,7 +158,10 @@ class HomeSettingsFragment : Fragment() { } private fun showNoLinkNotification() { - val builder = NotificationCompat.Builder(requireContext(), getString(R.string.notice_notification_channel_id)) + val builder = NotificationCompat.Builder( + requireContext(), + getString(R.string.notice_notification_channel_id) + ) .setSmallIcon(R.drawable.ic_stat_notification_logo) .setContentTitle(getString(R.string.notification_no_directory_link)) .setContentText(getString(R.string.notification_no_directory_link_description)) @@ -204,14 +212,28 @@ class HomeSettingsFragment : Fragment() { } private fun setInsets() = - ViewCompat.setOnApplyWindowInsetsListener(binding.scrollViewSettings) { view: View, windowInsets: WindowInsetsCompat -> - val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) - view.setPadding( - insets.left, - insets.top, - insets.right, - insets.bottom + resources.getDimensionPixelSize(R.dimen.spacing_navigation) + ViewCompat.setOnApplyWindowInsetsListener(binding.root) { view: View, windowInsets: WindowInsetsCompat -> + val barInsets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) + val cutoutInsets = windowInsets.getInsets(WindowInsetsCompat.Type.displayCutout()) + val spacingNavigation = resources.getDimensionPixelSize(R.dimen.spacing_navigation) + val spacingNavigationRail = + resources.getDimensionPixelSize(R.dimen.spacing_navigation_rail) + + binding.scrollViewSettings.setPadding( + barInsets.left + cutoutInsets.left, + barInsets.top, + barInsets.right + cutoutInsets.right, + barInsets.bottom ) + + binding.linearLayoutSettings.updatePadding(bottom = spacingNavigation) + + if (ViewCompat.getLayoutDirection(view) == ViewCompat.LAYOUT_DIRECTION_LTR) { + binding.linearLayoutSettings.updatePadding(left = spacingNavigationRail) + } else { + binding.linearLayoutSettings.updatePadding(right = spacingNavigationRail) + } + windowInsets } } diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/SearchFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/SearchFragment.kt index 5babd9bbff..f6aa370f07 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/SearchFragment.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/SearchFragment.kt @@ -141,7 +141,8 @@ class SearchFragment : Fragment() { } if (binding.searchText.text.toString().isEmpty() - && binding.chipGroup.checkedChipId != View.NO_ID) { + && binding.chipGroup.checkedChipId != View.NO_ID + ) { gamesViewModel.setSearchedGames(filteredList) return } @@ -182,41 +183,51 @@ class SearchFragment : Fragment() { } private fun setInsets() = - ViewCompat.setOnApplyWindowInsetsListener(binding.root) { _: View, windowInsets: WindowInsetsCompat -> - val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) + ViewCompat.setOnApplyWindowInsetsListener(binding.root) { view: View, windowInsets: WindowInsetsCompat -> + val barInsets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) + val cutoutInsets = windowInsets.getInsets(WindowInsetsCompat.Type.displayCutout()) val extraListSpacing = resources.getDimensionPixelSize(R.dimen.spacing_med) - val navigationSpacing = resources.getDimensionPixelSize(R.dimen.spacing_navigation) + val spacingNavigation = resources.getDimensionPixelSize(R.dimen.spacing_navigation) + val spacingNavigationRail = + resources.getDimensionPixelSize(R.dimen.spacing_navigation_rail) val chipSpacing = resources.getDimensionPixelSize(R.dimen.spacing_chip) - binding.frameSearch.updatePadding( - left = insets.left, - top = insets.top, - right = insets.right + binding.constraintSearch.updatePadding( + left = barInsets.left + cutoutInsets.left, + top = barInsets.top, + right = barInsets.right + cutoutInsets.right ) - binding.gridGamesSearch.setPadding( - insets.left, - extraListSpacing, - insets.right, - insets.bottom + resources.getDimensionPixelSize(R.dimen.spacing_navigation) + extraListSpacing - ) - - binding.noResultsView.updatePadding( - left = insets.left, - right = insets.right, - bottom = insets.bottom + navigationSpacing + binding.gridGamesSearch.updatePadding( + top = extraListSpacing, + bottom = barInsets.bottom + spacingNavigation + extraListSpacing ) + binding.noResultsView.updatePadding(bottom = spacingNavigation + barInsets.bottom) val mlpDivider = binding.divider.layoutParams as ViewGroup.MarginLayoutParams - mlpDivider.leftMargin = insets.left + chipSpacing - mlpDivider.rightMargin = insets.right + chipSpacing + if (ViewCompat.getLayoutDirection(view) == ViewCompat.LAYOUT_DIRECTION_LTR) { + binding.frameSearch.updatePadding(left = spacingNavigationRail) + binding.gridGamesSearch.updatePadding(left = spacingNavigationRail) + binding.noResultsView.updatePadding(left = spacingNavigationRail) + binding.chipGroup.updatePadding( + left = chipSpacing + spacingNavigationRail, + right = chipSpacing + ) + mlpDivider.leftMargin = chipSpacing + spacingNavigationRail + mlpDivider.rightMargin = chipSpacing + } else { + binding.frameSearch.updatePadding(right = spacingNavigationRail) + binding.gridGamesSearch.updatePadding(right = spacingNavigationRail) + binding.noResultsView.updatePadding(right = spacingNavigationRail) + binding.chipGroup.updatePadding( + left = chipSpacing, + right = chipSpacing + spacingNavigationRail + ) + mlpDivider.leftMargin = chipSpacing + mlpDivider.rightMargin = chipSpacing + spacingNavigationRail + } binding.divider.layoutParams = mlpDivider - binding.chipGroup.updatePadding( - left = insets.left + chipSpacing, - right = insets.right + chipSpacing - ) - windowInsets } } diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/GamesFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/GamesFragment.kt index 6f9e04f7eb..cc17b86264 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/GamesFragment.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/GamesFragment.kt @@ -8,27 +8,20 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.view.ViewGroup.MarginLayoutParams -import androidx.activity.OnBackPressedCallback import androidx.appcompat.app.AppCompatActivity import androidx.core.view.ViewCompat import androidx.core.view.WindowInsetsCompat import androidx.core.view.updatePadding -import androidx.core.widget.doOnTextChanged import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels import com.google.android.material.color.MaterialColors -import com.google.android.material.search.SearchView -import com.google.android.material.search.SearchView.TransitionState import com.google.android.material.transition.MaterialFadeThrough -import info.debatty.java.stringsimilarity.Jaccard import org.yuzu.yuzu_emu.R import org.yuzu.yuzu_emu.adapters.GameAdapter import org.yuzu.yuzu_emu.databinding.FragmentGamesBinding import org.yuzu.yuzu_emu.layout.AutofitGridLayoutManager -import org.yuzu.yuzu_emu.model.Game import org.yuzu.yuzu_emu.model.GamesViewModel import org.yuzu.yuzu_emu.model.HomeViewModel -import java.util.Locale class GamesFragment : Fragment() { private var _binding: FragmentGamesBinding? = null @@ -127,24 +120,37 @@ class GamesFragment : Fragment() { private fun setInsets() = ViewCompat.setOnApplyWindowInsetsListener(binding.root) { view: View, windowInsets: WindowInsetsCompat -> - val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) + val barInsets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) + val cutoutInsets = windowInsets.getInsets(WindowInsetsCompat.Type.displayCutout()) val extraListSpacing = resources.getDimensionPixelSize(R.dimen.spacing_large) + val spacingNavigation = resources.getDimensionPixelSize(R.dimen.spacing_navigation) + val spacingNavigationRail = + resources.getDimensionPixelSize(R.dimen.spacing_navigation_rail) binding.gridGames.updatePadding( - top = insets.top + extraListSpacing, - bottom = insets.bottom + resources.getDimensionPixelSize(R.dimen.spacing_navigation) + extraListSpacing + top = barInsets.top + extraListSpacing, + bottom = barInsets.bottom + spacingNavigation + extraListSpacing ) binding.swipeRefresh.setProgressViewEndTarget( false, - insets.top + resources.getDimensionPixelSize(R.dimen.spacing_refresh_end) + barInsets.top + resources.getDimensionPixelSize(R.dimen.spacing_refresh_end) ) + val leftInsets = barInsets.left + cutoutInsets.left + val rightInsets = barInsets.right + cutoutInsets.right val mlpSwipe = binding.swipeRefresh.layoutParams as MarginLayoutParams - mlpSwipe.rightMargin = insets.right - mlpSwipe.leftMargin = insets.left + if (ViewCompat.getLayoutDirection(view) == ViewCompat.LAYOUT_DIRECTION_LTR) { + mlpSwipe.leftMargin = leftInsets + spacingNavigationRail + mlpSwipe.rightMargin = rightInsets + } else { + mlpSwipe.leftMargin = leftInsets + mlpSwipe.rightMargin = rightInsets + spacingNavigationRail + } binding.swipeRefresh.layoutParams = mlpSwipe + binding.noticeText.updatePadding(bottom = spacingNavigation) + windowInsets } } diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt index 35b66d1f20..c620c3c7c7 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt @@ -67,16 +67,16 @@ class MainActivity : AppCompatActivity(), ThemeProvider { ContextCompat.getColor(applicationContext, android.R.color.transparent) ThemeHelper.setNavigationBarColor( this, - ElevationOverlayProvider(binding.navigationBar.context).compositeOverlay( - MaterialColors.getColor(binding.navigationBar, R.attr.colorSurface), - binding.navigationBar.elevation + ElevationOverlayProvider(binding.navigationView.context).compositeOverlay( + MaterialColors.getColor(binding.navigationView, R.attr.colorSurface), + binding.navigationView.elevation ) ) val navHostFragment = supportFragmentManager.findFragmentById(R.id.fragment_container) as NavHostFragment setUpNavigation(navHostFragment.navController) - (binding.navigationBar as NavigationBarView).setOnItemReselectedListener { + (binding.navigationView as NavigationBarView).setOnItemReselectedListener { when (it.itemId) { R.id.gamesFragment -> gamesViewModel.setShouldScrollToTop(true) R.id.searchFragment -> gamesViewModel.setSearchFocused(true) @@ -95,7 +95,7 @@ class MainActivity : AppCompatActivity(), ThemeProvider { // Prevents navigation from being drawn for a short time on recreation if set to hidden if (!homeViewModel.navigationVisible.value?.first!!) { - binding.navigationBar.visibility = View.INVISIBLE + binding.navigationView.visibility = View.INVISIBLE binding.statusBarShade.visibility = View.INVISIBLE } @@ -114,14 +114,14 @@ class MainActivity : AppCompatActivity(), ThemeProvider { fun finishSetup(navController: NavController) { navController.navigate(R.id.action_firstTimeSetupFragment_to_gamesFragment) - binding.navigationBar.setupWithNavController(navController) + (binding.navigationView as NavigationBarView).setupWithNavController(navController) showNavigation(visible = true, animated = true) ThemeHelper.setNavigationBarColor( this, - ElevationOverlayProvider(binding.navigationBar.context).compositeOverlay( - MaterialColors.getColor(binding.navigationBar, R.attr.colorSurface), - binding.navigationBar.elevation + ElevationOverlayProvider(binding.navigationView.context).compositeOverlay( + MaterialColors.getColor(binding.navigationView, R.attr.colorSurface), + binding.navigationView.elevation ) ) } @@ -134,35 +134,35 @@ class MainActivity : AppCompatActivity(), ThemeProvider { navController.navigate(R.id.firstTimeSetupFragment) homeViewModel.navigatedToSetup = true } else { - binding.navigationBar.setupWithNavController(navController) + (binding.navigationView as NavigationBarView).setupWithNavController(navController) } } private fun showNavigation(visible: Boolean, animated: Boolean) { if (!animated) { if (visible) { - binding.navigationBar.visibility = View.VISIBLE + binding.navigationView.visibility = View.VISIBLE } else { - binding.navigationBar.visibility = View.INVISIBLE + binding.navigationView.visibility = View.INVISIBLE } return } - binding.navigationBar.animate().apply { + binding.navigationView.animate().apply { if (visible) { - binding.navigationBar.visibility = View.VISIBLE - binding.navigationBar.translationY = binding.navigationBar.height.toFloat() * 2 + binding.navigationView.visibility = View.VISIBLE + binding.navigationView.translationY = binding.navigationView.height.toFloat() * 2 duration = 300 translationY(0f) interpolator = PathInterpolator(0.05f, 0.7f, 0.1f, 1f) } else { duration = 300 - translationY(binding.navigationBar.height.toFloat() * 2) + translationY(binding.navigationView.height.toFloat() * 2) interpolator = PathInterpolator(0.3f, 0f, 0.8f, 0.15f) } }.withEndAction { if (!visible) { - binding.navigationBar.visibility = View.INVISIBLE + binding.navigationView.visibility = View.INVISIBLE } }.start() } @@ -177,7 +177,7 @@ class MainActivity : AppCompatActivity(), ThemeProvider { interpolator = PathInterpolator(0.05f, 0.7f, 0.1f, 1f) } else { duration = 300 - translationY(binding.navigationBar.height.toFloat() * -2) + translationY(binding.navigationView.height.toFloat() * -2) interpolator = PathInterpolator(0.3f, 0f, 0.8f, 0.15f) } }.withEndAction { diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/InsetsHelper.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/InsetsHelper.kt index e7a04d9178..e587fea061 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/InsetsHelper.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/InsetsHelper.kt @@ -4,22 +4,12 @@ import android.annotation.SuppressLint import android.app.Activity import android.content.Context import android.graphics.Rect -import android.view.ViewGroup.MarginLayoutParams -import androidx.core.graphics.Insets -import com.google.android.material.appbar.AppBarLayout object InsetsHelper { const val THREE_BUTTON_NAVIGATION = 0 const val TWO_BUTTON_NAVIGATION = 1 const val GESTURE_NAVIGATION = 2 - fun insetAppBar(insets: Insets, appBarLayout: AppBarLayout) { - val mlpAppBar = appBarLayout.layoutParams as MarginLayoutParams - mlpAppBar.leftMargin = insets.left - mlpAppBar.rightMargin = insets.right - appBarLayout.layoutParams = mlpAppBar - } - @SuppressLint("DiscouragedApi") fun getSystemGestureType(context: Context): Int { val resources = context.resources diff --git a/src/android/app/src/main/res/layout-w600dp/activity_main.xml b/src/android/app/src/main/res/layout-w600dp/activity_main.xml new file mode 100644 index 0000000000..39b61a13e7 --- /dev/null +++ b/src/android/app/src/main/res/layout-w600dp/activity_main.xml @@ -0,0 +1,46 @@ + + + + + + + + + + diff --git a/src/android/app/src/main/res/layout/activity_main.xml b/src/android/app/src/main/res/layout/activity_main.xml index 6ca426b54a..214acb041d 100644 --- a/src/android/app/src/main/res/layout/activity_main.xml +++ b/src/android/app/src/main/res/layout/activity_main.xml @@ -21,7 +21,7 @@ tools:layout="@layout/fragment_games" /> + android:background="?attr/colorSurface" + android:clipToPadding="false"> diff --git a/src/android/app/src/main/res/menu-w600dp/menu_navigation.xml b/src/android/app/src/main/res/menu-w600dp/menu_navigation.xml new file mode 100644 index 0000000000..073d00cab7 --- /dev/null +++ b/src/android/app/src/main/res/menu-w600dp/menu_navigation.xml @@ -0,0 +1,19 @@ + + + + + + + + + + diff --git a/src/android/app/src/main/res/values-w600dp/dimens.xml b/src/android/app/src/main/res/values-w600dp/dimens.xml new file mode 100644 index 0000000000..128319e274 --- /dev/null +++ b/src/android/app/src/main/res/values-w600dp/dimens.xml @@ -0,0 +1,5 @@ + + + 0dp + 80dp + diff --git a/src/android/app/src/main/res/values/dimens.xml b/src/android/app/src/main/res/values/dimens.xml index 28a6d25cf5..00757e5e8e 100644 --- a/src/android/app/src/main/res/values/dimens.xml +++ b/src/android/app/src/main/res/values/dimens.xml @@ -7,6 +7,7 @@ 64dp 20dp 80dp + 0dp 128dp 72dp 256dp diff --git a/src/android/app/src/main/res/values/themes.xml b/src/android/app/src/main/res/values/themes.xml index f32e2f5d09..60388b71e2 100644 --- a/src/android/app/src/main/res/values/themes.xml +++ b/src/android/app/src/main/res/values/themes.xml @@ -42,7 +42,7 @@ @style/YuzuSlider @style/YuzuMaterialDialog - default + shortEdges false false