diff options
| author | Nixyn <contact@innix.space> | 2025-09-15 06:26:06 +0200 |
|---|---|---|
| committer | crueter <crueter@eden-emu.dev> | 2025-09-15 06:26:06 +0200 |
| commit | 4c5d03f5defedd6decf2dfbbaca93a518e6d0adc (patch) | |
| tree | 22feb5e9d52db8386ce1c3d53801a80fa22ac9af /src/android | |
| parent | d207df959a29cc4758c5328a3cdc96d909a96c92 (diff) | |
[android / GameUI] Add grid compact layout and fix ugly borders on grid layout (#401)
Tis PR adds a new layout for the Game Adapter with shorter cards and fixes the ugly borders in Game Adapter's Grid layout.
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/401
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Co-authored-by: Nixyn <contact@innix.space>
Co-committed-by: Nixyn <contact@innix.space>
Diffstat (limited to 'src/android')
7 files changed, 161 insertions, 8 deletions
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<Game, GameAdapter.GameViewHolder>(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 @@ +<?xml version="1.0" encoding="utf-8"?> +<shape xmlns:android="http://schemas.android.com/apk/res/android"> + <gradient + android:angle="270" + android:startColor="@android:color/transparent" + android:centerColor="#66000000" + android:endColor="#AA000000" + android:type="linear" /> +</shape> 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"> <org.yuzu.yuzu_emu.views.GradientBorderCardView android:id="@+id/card_game_grid" app:cardElevation="0dp" app:cardBackgroundColor="@color/eden_card_background" - app:strokeWidth="1dp" - app:strokeColor="@color/eden_border" + app:strokeWidth="0dp" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" + android:layout_margin="4dp" android:clickable="true" android:clipToPadding="true" android:focusable="true" android:transitionName="card_game" - app:cardCornerRadius="16dp"> + app:cardCornerRadius="16dp" + android:foreground="@color/eden_border_gradient_start"> <androidx.constraintlayout.widget.ConstraintLayout android:layout_width="wrap_content" android:layout_height="wrap_content" - android:padding="6dp"> + android:paddingTop="14dp" + android:paddingLeft="6dp" + android:paddingRight="6dp" + android:paddingBottom="6dp"> <com.google.android.material.imageview.ShapeableImageView android:id="@+id/image_game_screen" diff --git a/src/android/app/src/main/res/layout/card_game_grid_compact.xml b/src/android/app/src/main/res/layout/card_game_grid_compact.xml new file mode 100644 index 0000000000..bb86595d5c --- /dev/null +++ b/src/android/app/src/main/res/layout/card_game_grid_compact.xml @@ -0,0 +1,82 @@ +<?xml version="1.0" encoding="utf-8"?> +<FrameLayout 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" + android:layout_height="wrap_content" + android:focusable="false" + android:focusableInTouchMode="false" + android:padding="4dp"> + + <org.yuzu.yuzu_emu.views.GradientBorderCardView + android:id="@+id/card_game_grid_compact" + app:cardElevation="0dp" + app:cardBackgroundColor="@color/eden_card_background" + app:strokeWidth="0dp" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center" + android:layout_margin="4dp" + android:clickable="true" + android:clipToPadding="true" + android:focusable="true" + android:transitionName="card_game_compact" + app:cardCornerRadius="16dp" + android:foreground="@color/eden_border_gradient_start"> + + <androidx.constraintlayout.widget.ConstraintLayout + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:paddingTop="14dp" + android:paddingLeft="6dp" + android:paddingRight="6dp" + android:paddingBottom="6dp"> + + <FrameLayout + android:id="@+id/image_container" + android:layout_width="150dp" + android:layout_height="100dp" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent"> + + <com.google.android.material.imageview.ShapeableImageView + android:id="@+id/image_game_screen_compact" + android:layout_width="match_parent" + android:layout_height="match_parent" + app:shapeAppearance="@style/ShapeAppearance.Material3.Corner.Medium" + android:scaleType="centerCrop" + tools:src="@drawable/default_icon" /> + + <View + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="@drawable/gradient_overlay_bottom" /> + + <com.google.android.material.textview.MaterialTextView + android:id="@+id/text_game_title_compact" + style="@style/SynthwaveText.Body" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_gravity="bottom" + android:layout_margin="6dp" + android:requiresFadingEdge="horizontal" + android:textAlignment="center" + android:textSize="12sp" + android:textStyle="bold" + android:textColor="@android:color/white" + android:shadowColor="@android:color/black" + android:shadowDx="1" + android:shadowDy="1" + android:shadowRadius="2" + android:maxLines="2" + android:ellipsize="end" + tools:text="The Legend of Zelda: Skyward Sword" /> + + </FrameLayout> + + </androidx.constraintlayout.widget.ConstraintLayout> + + </org.yuzu.yuzu_emu.views.GradientBorderCardView> + +</FrameLayout> 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 @@ -5,6 +5,9 @@ android:id="@+id/view_grid" android:title="@string/view_grid"/> <item + android:id="@+id/view_grid_compact" + android:title="@string/view_grid_compact"/> + <item android:id="@+id/view_list" android:title="@string/view_list" android:checked="true"/> diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml index 2c7923d5a3..20c6e85b6c 100644 --- a/src/android/app/src/main/res/values/strings.xml +++ b/src/android/app/src/main/res/values/strings.xml @@ -266,6 +266,7 @@ <string name="alphabetical">Alphabetical</string> <string name="view_list">List</string> <string name="view_grid">Grid</string> + <string name="view_grid_compact">Compact Grid</string> <string name="view_carousel">Carousel</string> <string name="game_image_desc">Screenshot for %1$s</string> <string name="folder">Folder</string> |
