android: Add game shortcuts to about game dialog (#313)

Adapted from https://github.com/mandarine3ds/mandarine/pull/47

Co-authored-by: Charles Lombardo <clombardo169@gmail.com>
Co-authored-by: Ishan09811 <156402647+Ishan09811@users.noreply.github.com>
Co-authored-by: OpenSauce04 <opensauce04@gmail.com>
This commit is contained in:
Kleidis 2024-10-13 14:49:53 +02:00 committed by GitHub
parent 973faeb9d7
commit 3d1936cf5c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 81 additions and 6 deletions

View File

@ -1,4 +1,4 @@
// Copyright 2023 Citra Emulator Project
// Copyright Citra Emulator Project / Lime3DS Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
@ -95,7 +95,13 @@ class EmulationActivity : AppCompatActivity() {
windowManager.defaultDisplay.rotation
)
EmulationLifecycleUtil.addShutdownHook(hook = { this.finish() })
EmulationLifecycleUtil.addShutdownHook(hook = {
if (intent.getBooleanExtra("launched_from_shortcut", false)) {
finishAffinity()
} else {
this.finish()
}
})
isEmulationRunning = true
instance = this

View File

@ -14,6 +14,10 @@ import android.content.Context
import android.widget.TextView
import android.widget.ImageView
import android.widget.Toast
import android.graphics.drawable.BitmapDrawable
import android.graphics.Bitmap
import android.content.pm.ShortcutInfo
import android.content.pm.ShortcutManager
import androidx.appcompat.app.AppCompatActivity
import androidx.documentfile.provider.DocumentFile
import androidx.lifecycle.ViewModelProvider
@ -23,6 +27,10 @@ import androidx.recyclerview.widget.AsyncDifferConfig
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import android.graphics.drawable.Icon
import kotlinx.coroutines.launch
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.CoroutineScope
import com.google.android.material.color.MaterialColors
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.bottomsheet.BottomSheetBehavior
@ -214,6 +222,24 @@ class GameAdapter(private val activity: AppCompatActivity, private val inflater:
view.findNavController().navigate(action)
}
bottomSheetView.findViewById<MaterialButton>(R.id.game_shortcut).setOnClickListener {
val shortcutManager = activity.getSystemService(ShortcutManager::class.java)
CoroutineScope(Dispatchers.IO).launch {
val bitmap = (bottomSheetView.findViewById<ImageView>(R.id.game_icon).drawable as BitmapDrawable).bitmap
val icon = Icon.createWithBitmap(bitmap)
val shortcut = ShortcutInfo.Builder(context, game.title)
.setShortLabel(game.title)
.setIcon(icon)
.setIntent(game.launchIntent.apply {
putExtra("launched_from_shortcut", true)
})
.build()
shortcutManager.requestPinShortcut(shortcut, null)
}
}
bottomSheetView.findViewById<MaterialButton>(R.id.cheats).setOnClickListener {
val action = CheatsFragmentDirections.actionGlobalCheatsFragment(holder.game.titleId)
view.findNavController().navigate(action)

View File

@ -1,4 +1,4 @@
// Copyright 2023 Citra Emulator Project
// Copyright Citra Emulator Project / Lime3DS Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
@ -60,6 +60,7 @@ class GamesFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
homeViewModel.setNavigationVisibility(visible = true, animated = true)
homeViewModel.setStatusBarShadeVisibility(visible = true)
val inflater = LayoutInflater.from(requireContext())
binding.gridGames.apply {

View File

@ -1,13 +1,17 @@
// Copyright 2023 Citra Emulator Project
// Copyright Citra Emulator Project / Lime3DS Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
package io.github.lime3ds.android.model
import android.os.Parcelable
import android.content.Intent
import android.net.Uri
import java.util.HashSet
import kotlinx.parcelize.Parcelize
import kotlinx.serialization.Serializable
import io.github.lime3ds.android.LimeApplication
import io.github.lime3ds.android.activities.EmulationActivity
@Parcelize
@Serializable
@ -27,6 +31,16 @@ class Game(
val keyAddedToLibraryTime get() = "${filename}_AddedToLibraryTime"
val keyLastPlayedTime get() = "${filename}_LastPlayed"
val launchIntent: Intent
get() = Intent(LimeApplication.appContext, EmulationActivity::class.java).apply {
action = Intent.ACTION_VIEW
data = if (isInstalled) {
LimeApplication.documentsTree.getUri(path)
} else {
Uri.parse(path)
}
}
override fun equals(other: Any?): Boolean {
if (other !is Game) {
return false

View File

@ -1,4 +1,4 @@
// Copyright 2023 Citra Emulator Project
// Copyright Citra Emulator Project / Lime3DS Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
@ -100,6 +100,12 @@ class DocumentsTree {
}
}
@Synchronized
fun getUri(filepath: String): Uri {
val node = resolvePath(filepath) ?: return Uri.EMPTY
return node.uri ?: return Uri.EMPTY
}
@Synchronized
fun isDirectory(filepath: String): Boolean {
val node = resolvePath(filepath) ?: return false

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M280,920Q247,920 223.5,896.5Q200,873 200,840L200,120Q200,87 223.5,63.5Q247,40 280,40L680,40Q713,40 736.5,63.5Q760,87 760,120L760,280L680,280L680,240L280,240L280,720L680,720L680,680L760,680L760,840Q760,873 736.5,896.5Q713,920 680,920L280,920ZM686,520L480,520Q480,520 480,520Q480,520 480,520L480,640L400,640L400,520Q400,487 423.5,463.5Q447,440 480,440L686,440L624,376L680,320L840,480L680,640L624,584L686,520Z"/>
</vector>

View File

@ -109,6 +109,17 @@
android:focusedByDefault="true"
android:text="@string/play"
app:icon="@drawable/ic_play" />
<com.google.android.material.button.MaterialButton
android:id="@+id/game_shortcut"
style="@style/Widget.Material3.Button.IconButton.Filled.Tonal"
android:layout_width="48dp"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:contentDescription="@string/shortcut"
app:icon="@drawable/ic_shortcut"
app:iconGravity="textStart" />
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
@ -141,4 +152,4 @@
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
</LinearLayout>

View File

@ -456,6 +456,7 @@
<!-- About Game Dialog -->
<string name="play">Play</string>
<string name="shortcut">Shortcut</string>
<!-- Cheats -->
<string name="cheats">Cheats</string>