diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/GameAdapter.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/GameAdapter.kt index 98f342c274..0a2cb41745 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/GameAdapter.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/GameAdapter.kt @@ -36,17 +36,18 @@ import androidx.core.net.toUri import androidx.core.content.edit import com.google.android.material.dialog.MaterialAlertDialogBuilder import org.yuzu.yuzu_emu.NativeLibrary +import org.yuzu.yuzu_emu.databinding.CardGameGridCompactBinding import org.yuzu.yuzu_emu.features.settings.model.BooleanSetting import org.yuzu.yuzu_emu.features.settings.model.Settings -import org.yuzu.yuzu_emu.utils.NativeConfig class GameAdapter(private val activity: AppCompatActivity) : AbstractDiffAdapter(exact = false) { companion object { const val VIEW_TYPE_GRID = 0 - const val VIEW_TYPE_LIST = 1 - const val VIEW_TYPE_CAROUSEL = 2 + const val VIEW_TYPE_GRID_COMPACT = 1 + const val VIEW_TYPE_LIST = 2 + const val VIEW_TYPE_CAROUSEL = 3 } private var viewType = 0 @@ -80,6 +81,7 @@ class GameAdapter(private val activity: AppCompatActivity) : listBinding.root.layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT listBinding.root.layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT } + VIEW_TYPE_GRID -> { val gridBinding = holder.binding as CardGameGridBinding gridBinding.cardGameGrid.scaleX = 1f @@ -89,6 +91,17 @@ class GameAdapter(private val activity: AppCompatActivity) : gridBinding.root.layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT gridBinding.root.layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT } + + VIEW_TYPE_GRID_COMPACT -> { + val gridCompactBinding = holder.binding as CardGameGridCompactBinding + gridCompactBinding.cardGameGridCompact.scaleX = 1f + gridCompactBinding.cardGameGridCompact.scaleY = 1f + gridCompactBinding.cardGameGridCompact.alpha = 1f + // Reset layout params to XML defaults (same as normal grid) + gridCompactBinding.root.layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT + gridCompactBinding.root.layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT + } + VIEW_TYPE_CAROUSEL -> { val carouselBinding = holder.binding as CardGameCarouselBinding // soothens transient flickering @@ -105,16 +118,25 @@ class GameAdapter(private val activity: AppCompatActivity) : parent, false ) + VIEW_TYPE_GRID -> CardGameGridBinding.inflate( LayoutInflater.from(parent.context), parent, false ) + + VIEW_TYPE_GRID_COMPACT -> CardGameGridCompactBinding.inflate( + LayoutInflater.from(parent.context), + parent, + false + ) + VIEW_TYPE_CAROUSEL -> CardGameCarouselBinding.inflate( LayoutInflater.from(parent.context), parent, false ) + else -> throw IllegalArgumentException("Invalid view type") } return GameViewHolder(binding, viewType) @@ -130,6 +152,7 @@ class GameAdapter(private val activity: AppCompatActivity) : VIEW_TYPE_LIST -> bindListView(model) VIEW_TYPE_GRID -> bindGridView(model) VIEW_TYPE_CAROUSEL -> bindCarouselView(model) + VIEW_TYPE_GRID_COMPACT -> bindGridCompactView(model) } } @@ -168,6 +191,23 @@ class GameAdapter(private val activity: AppCompatActivity) : gridBinding.root.layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT } + private fun bindGridCompactView(model: Game) { + val gridCompactBinding = binding as CardGameGridCompactBinding + + gridCompactBinding.imageGameScreenCompact.scaleType = ImageView.ScaleType.CENTER_CROP + GameIconUtils.loadGameIcon(model, gridCompactBinding.imageGameScreenCompact) + + gridCompactBinding.textGameTitleCompact.text = model.title.replace("[\\t\\n\\r]+".toRegex(), " ") + + gridCompactBinding.textGameTitleCompact.marquee() + gridCompactBinding.cardGameGridCompact.setOnClickListener { onClick(model) } + gridCompactBinding.cardGameGridCompact.setOnLongClickListener { onLongClick(model) } + + // Reset layout params to XML defaults (same as normal grid) + gridCompactBinding.root.layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT + gridCompactBinding.root.layoutParams.height = ViewGroup.LayoutParams.WRAP_CONTENT + } + private fun bindCarouselView(model: Game) { val carouselBinding = binding as CardGameCarouselBinding 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 03fa1a3a2e..80055628e1 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 @@ -194,6 +194,10 @@ class GamesFragment : Fragment() { val columns = resources.getInteger(R.integer.game_columns_grid) GridLayoutManager(context, columns) } + GameAdapter.VIEW_TYPE_GRID_COMPACT -> { + val columns = resources.getInteger(R.integer.game_columns_grid) + GridLayoutManager(context, columns) + } GameAdapter.VIEW_TYPE_LIST -> { val columns = resources.getInteger(R.integer.game_columns_list) GridLayoutManager(context, columns) @@ -300,6 +304,7 @@ class GamesFragment : Fragment() { val currentViewType = getCurrentViewType() when (currentViewType) { GameAdapter.VIEW_TYPE_LIST -> popup.menu.findItem(R.id.view_list).isChecked = true + GameAdapter.VIEW_TYPE_GRID_COMPACT -> popup.menu.findItem(R.id.view_grid_compact).isChecked = true GameAdapter.VIEW_TYPE_GRID -> popup.menu.findItem(R.id.view_grid).isChecked = true GameAdapter.VIEW_TYPE_CAROUSEL -> popup.menu.findItem(R.id.view_carousel).isChecked = true } @@ -314,6 +319,14 @@ class GamesFragment : Fragment() { true } + R.id.view_grid_compact -> { + if (getCurrentViewType() == GameAdapter.VIEW_TYPE_CAROUSEL) onPause() + setCurrentViewType(GameAdapter.VIEW_TYPE_GRID_COMPACT) + applyGridGamesBinding() + item.isChecked = true + true + } + R.id.view_list -> { if (getCurrentViewType() == GameAdapter.VIEW_TYPE_CAROUSEL) onPause() setCurrentViewType(GameAdapter.VIEW_TYPE_LIST) diff --git a/src/android/app/src/main/res/drawable/gradient_overlay_bottom.xml b/src/android/app/src/main/res/drawable/gradient_overlay_bottom.xml new file mode 100644 index 0000000000..f74cfa0d05 --- /dev/null +++ b/src/android/app/src/main/res/drawable/gradient_overlay_bottom.xml @@ -0,0 +1,9 @@ + + + + diff --git a/src/android/app/src/main/res/layout/card_game_grid.xml b/src/android/app/src/main/res/layout/card_game_grid.xml index 3e0bf6005c..f03a77c4f1 100644 --- a/src/android/app/src/main/res/layout/card_game_grid.xml +++ b/src/android/app/src/main/res/layout/card_game_grid.xml @@ -5,27 +5,32 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:focusable="false" - android:focusableInTouchMode="false"> + android:focusableInTouchMode="false" + android:padding="4dp"> + app:cardCornerRadius="16dp" + android:foreground="@color/eden_border_gradient_start"> + android:paddingTop="14dp" + android:paddingLeft="6dp" + android:paddingRight="6dp" + android:paddingBottom="6dp"> + + + + + + + + + + + + + + + + + + + + + diff --git a/src/android/app/src/main/res/menu/menu_game_views.xml b/src/android/app/src/main/res/menu/menu_game_views.xml index 241cdcb4b5..11bf3e695e 100644 --- a/src/android/app/src/main/res/menu/menu_game_views.xml +++ b/src/android/app/src/main/res/menu/menu_game_views.xml @@ -4,6 +4,9 @@ + Alphabetical List Grid + Compact Grid Carousel Screenshot for %1$s Folder