android: Add to launcher button
This commit is contained in:
		@@ -3,9 +3,6 @@
 | 
			
		||||
 | 
			
		||||
package org.yuzu.yuzu_emu.adapters
 | 
			
		||||
 | 
			
		||||
import android.content.Intent
 | 
			
		||||
import android.graphics.Bitmap
 | 
			
		||||
import android.graphics.drawable.LayerDrawable
 | 
			
		||||
import android.net.Uri
 | 
			
		||||
import android.text.TextUtils
 | 
			
		||||
import android.view.LayoutInflater
 | 
			
		||||
@@ -15,10 +12,6 @@ import android.widget.Toast
 | 
			
		||||
import androidx.appcompat.app.AppCompatActivity
 | 
			
		||||
import androidx.core.content.pm.ShortcutInfoCompat
 | 
			
		||||
import androidx.core.content.pm.ShortcutManagerCompat
 | 
			
		||||
import androidx.core.content.res.ResourcesCompat
 | 
			
		||||
import androidx.core.graphics.drawable.IconCompat
 | 
			
		||||
import androidx.core.graphics.drawable.toBitmap
 | 
			
		||||
import androidx.core.graphics.drawable.toDrawable
 | 
			
		||||
import androidx.documentfile.provider.DocumentFile
 | 
			
		||||
import androidx.lifecycle.ViewModelProvider
 | 
			
		||||
import androidx.lifecycle.lifecycleScope
 | 
			
		||||
@@ -30,7 +23,6 @@ import kotlinx.coroutines.withContext
 | 
			
		||||
import org.yuzu.yuzu_emu.HomeNavigationDirections
 | 
			
		||||
import org.yuzu.yuzu_emu.R
 | 
			
		||||
import org.yuzu.yuzu_emu.YuzuApplication
 | 
			
		||||
import org.yuzu.yuzu_emu.activities.EmulationActivity
 | 
			
		||||
import org.yuzu.yuzu_emu.databinding.CardGameBinding
 | 
			
		||||
import org.yuzu.yuzu_emu.model.Game
 | 
			
		||||
import org.yuzu.yuzu_emu.model.GamesViewModel
 | 
			
		||||
@@ -89,36 +81,13 @@ class GameAdapter(private val activity: AppCompatActivity) :
 | 
			
		||||
                )
 | 
			
		||||
                .apply()
 | 
			
		||||
 | 
			
		||||
            val openIntent =
 | 
			
		||||
                Intent(YuzuApplication.appContext, EmulationActivity::class.java).apply {
 | 
			
		||||
                    action = Intent.ACTION_VIEW
 | 
			
		||||
                    data = Uri.parse(game.path)
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            activity.lifecycleScope.launch {
 | 
			
		||||
                withContext(Dispatchers.IO) {
 | 
			
		||||
                    val layerDrawable = ResourcesCompat.getDrawable(
 | 
			
		||||
                        YuzuApplication.appContext.resources,
 | 
			
		||||
                        R.drawable.shortcut,
 | 
			
		||||
                        null
 | 
			
		||||
                    ) as LayerDrawable
 | 
			
		||||
                    layerDrawable.setDrawableByLayerId(
 | 
			
		||||
                        R.id.shortcut_foreground,
 | 
			
		||||
                        GameIconUtils.getGameIcon(activity, game)
 | 
			
		||||
                            .toDrawable(YuzuApplication.appContext.resources)
 | 
			
		||||
                    )
 | 
			
		||||
                    val inset = YuzuApplication.appContext.resources
 | 
			
		||||
                        .getDimensionPixelSize(R.dimen.icon_inset)
 | 
			
		||||
                    layerDrawable.setLayerInset(1, inset, inset, inset, inset)
 | 
			
		||||
                    val shortcut =
 | 
			
		||||
                        ShortcutInfoCompat.Builder(YuzuApplication.appContext, game.path)
 | 
			
		||||
                            .setShortLabel(game.title)
 | 
			
		||||
                            .setIcon(
 | 
			
		||||
                                IconCompat.createWithAdaptiveBitmap(
 | 
			
		||||
                                    layerDrawable.toBitmap(config = Bitmap.Config.ARGB_8888)
 | 
			
		||||
                                )
 | 
			
		||||
                            )
 | 
			
		||||
                            .setIntent(openIntent)
 | 
			
		||||
                            .setIcon(GameIconUtils.getShortcutIcon(activity, game))
 | 
			
		||||
                            .setIntent(game.launchIntent)
 | 
			
		||||
                            .build()
 | 
			
		||||
                    ShortcutManagerCompat.pushDynamicShortcut(YuzuApplication.appContext, shortcut)
 | 
			
		||||
                }
 | 
			
		||||
 
 | 
			
		||||
@@ -4,6 +4,8 @@
 | 
			
		||||
package org.yuzu.yuzu_emu.fragments
 | 
			
		||||
 | 
			
		||||
import android.annotation.SuppressLint
 | 
			
		||||
import android.content.pm.ShortcutInfo
 | 
			
		||||
import android.content.pm.ShortcutManager
 | 
			
		||||
import android.os.Bundle
 | 
			
		||||
import android.text.TextUtils
 | 
			
		||||
import android.view.LayoutInflater
 | 
			
		||||
@@ -84,6 +86,24 @@ class GamePropertiesFragment : Fragment() {
 | 
			
		||||
            view.findNavController().popBackStack()
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        val shortcutManager = requireActivity().getSystemService(ShortcutManager::class.java)
 | 
			
		||||
        binding.buttonShortcut.isEnabled = shortcutManager.isRequestPinShortcutSupported
 | 
			
		||||
        binding.buttonShortcut.setOnClickListener {
 | 
			
		||||
            viewLifecycleOwner.lifecycleScope.launch {
 | 
			
		||||
                withContext(Dispatchers.IO) {
 | 
			
		||||
                    val shortcut = ShortcutInfo.Builder(requireContext(), args.game.title)
 | 
			
		||||
                        .setShortLabel(args.game.title)
 | 
			
		||||
                        .setIcon(
 | 
			
		||||
                            GameIconUtils.getShortcutIcon(requireActivity(), args.game)
 | 
			
		||||
                                .toIcon(requireContext())
 | 
			
		||||
                        )
 | 
			
		||||
                        .setIntent(args.game.launchIntent)
 | 
			
		||||
                        .build()
 | 
			
		||||
                    shortcutManager.requestPinShortcut(shortcut, null)
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        GameIconUtils.loadGameIcon(args.game, binding.imageGameScreen)
 | 
			
		||||
        binding.title.text = args.game.title
 | 
			
		||||
        binding.title.postDelayed(
 | 
			
		||||
 
 | 
			
		||||
@@ -3,6 +3,7 @@
 | 
			
		||||
 | 
			
		||||
package org.yuzu.yuzu_emu.model
 | 
			
		||||
 | 
			
		||||
import android.content.Intent
 | 
			
		||||
import android.net.Uri
 | 
			
		||||
import android.os.Parcelable
 | 
			
		||||
import java.util.HashSet
 | 
			
		||||
@@ -11,6 +12,7 @@ import kotlinx.serialization.Serializable
 | 
			
		||||
import org.yuzu.yuzu_emu.NativeLibrary
 | 
			
		||||
import org.yuzu.yuzu_emu.R
 | 
			
		||||
import org.yuzu.yuzu_emu.YuzuApplication
 | 
			
		||||
import org.yuzu.yuzu_emu.activities.EmulationActivity
 | 
			
		||||
import org.yuzu.yuzu_emu.utils.DirectoryInitialization
 | 
			
		||||
import org.yuzu.yuzu_emu.utils.FileUtil
 | 
			
		||||
import java.time.LocalDateTime
 | 
			
		||||
@@ -61,6 +63,12 @@ class Game(
 | 
			
		||||
    val addonDir: String
 | 
			
		||||
        get() = DirectoryInitialization.userDirectory + "/load/" + programIdHex + "/"
 | 
			
		||||
 | 
			
		||||
    val launchIntent: Intent
 | 
			
		||||
        get() = Intent(YuzuApplication.appContext, EmulationActivity::class.java).apply {
 | 
			
		||||
            action = Intent.ACTION_VIEW
 | 
			
		||||
            data = Uri.parse(path)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    override fun equals(other: Any?): Boolean {
 | 
			
		||||
        if (other !is Game) {
 | 
			
		||||
            return false
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,10 @@ package org.yuzu.yuzu_emu.utils
 | 
			
		||||
 | 
			
		||||
import android.graphics.Bitmap
 | 
			
		||||
import android.graphics.BitmapFactory
 | 
			
		||||
import android.graphics.drawable.LayerDrawable
 | 
			
		||||
import android.widget.ImageView
 | 
			
		||||
import androidx.core.content.res.ResourcesCompat
 | 
			
		||||
import androidx.core.graphics.drawable.IconCompat
 | 
			
		||||
import androidx.core.graphics.drawable.toBitmap
 | 
			
		||||
import androidx.core.graphics.drawable.toDrawable
 | 
			
		||||
import androidx.lifecycle.LifecycleOwner
 | 
			
		||||
@@ -85,4 +88,22 @@ object GameIconUtils {
 | 
			
		||||
        return imageLoader.execute(request)
 | 
			
		||||
            .drawable!!.toBitmap(config = Bitmap.Config.ARGB_8888)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    suspend fun getShortcutIcon(lifecycleOwner: LifecycleOwner, game: Game): IconCompat {
 | 
			
		||||
        val layerDrawable = ResourcesCompat.getDrawable(
 | 
			
		||||
            YuzuApplication.appContext.resources,
 | 
			
		||||
            R.drawable.shortcut,
 | 
			
		||||
            null
 | 
			
		||||
        ) as LayerDrawable
 | 
			
		||||
        layerDrawable.setDrawableByLayerId(
 | 
			
		||||
            R.id.shortcut_foreground,
 | 
			
		||||
            getGameIcon(lifecycleOwner, game).toDrawable(YuzuApplication.appContext.resources)
 | 
			
		||||
        )
 | 
			
		||||
        val inset = YuzuApplication.appContext.resources
 | 
			
		||||
            .getDimensionPixelSize(R.dimen.icon_inset)
 | 
			
		||||
        layerDrawable.setLayerInset(1, inset, inset, inset, inset)
 | 
			
		||||
        return IconCompat.createWithAdaptiveBitmap(
 | 
			
		||||
            layerDrawable.toBitmap(config = Bitmap.Config.ARGB_8888)
 | 
			
		||||
        )
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										9
									
								
								src/android/app/src/main/res/drawable/ic_shortcut.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/android/app/src/main/res/drawable/ic_shortcut.xml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
    android:width="24dp"
 | 
			
		||||
    android:height="24dp"
 | 
			
		||||
    android:viewportWidth="960"
 | 
			
		||||
    android:viewportHeight="960">
 | 
			
		||||
    <path
 | 
			
		||||
        android:fillColor="?attr/colorControlNormal"
 | 
			
		||||
        android:pathData="M280,920q-33,0 -56.5,-23.5T200,840v-720q0,-33 23.5,-56.5T280,40h400q33,0 56.5,23.5T760,120v160h-80v-40L280,240v480h400v-40h80v160q0,33 -23.5,56.5T680,920L280,920ZM686,520L480,520v120h-80v-120q0,-33 23.5,-56.5T480,440h206l-62,-64 56,-56 160,160 -160,160 -56,-56 62,-64Z" />
 | 
			
		||||
</vector>
 | 
			
		||||
@@ -43,16 +43,35 @@
 | 
			
		||||
        app:layout_constraintStart_toStartOf="parent"
 | 
			
		||||
        app:layout_constraintTop_toTopOf="parent">
 | 
			
		||||
 | 
			
		||||
        <Button
 | 
			
		||||
            android:id="@+id/button_back"
 | 
			
		||||
            style="?attr/materialIconButtonStyle"
 | 
			
		||||
            android:layout_width="wrap_content"
 | 
			
		||||
        <androidx.constraintlayout.widget.ConstraintLayout
 | 
			
		||||
            android:layout_width="match_parent"
 | 
			
		||||
            android:layout_height="wrap_content"
 | 
			
		||||
            android:layout_gravity="start"
 | 
			
		||||
            android:layout_margin="8dp"
 | 
			
		||||
            app:icon="@drawable/ic_back"
 | 
			
		||||
            app:iconSize="24dp"
 | 
			
		||||
            app:iconTint="?attr/colorOnSurface" />
 | 
			
		||||
            android:orientation="horizontal">
 | 
			
		||||
 | 
			
		||||
            <Button
 | 
			
		||||
                android:id="@+id/button_back"
 | 
			
		||||
                style="?attr/materialIconButtonStyle"
 | 
			
		||||
                android:layout_width="wrap_content"
 | 
			
		||||
                android:layout_height="wrap_content"
 | 
			
		||||
                app:icon="@drawable/ic_back"
 | 
			
		||||
                app:iconSize="24dp"
 | 
			
		||||
                app:iconTint="?attr/colorOnSurface"
 | 
			
		||||
                app:layout_constraintStart_toStartOf="parent"
 | 
			
		||||
                app:layout_constraintTop_toTopOf="parent" />
 | 
			
		||||
 | 
			
		||||
            <Button
 | 
			
		||||
                android:id="@+id/button_shortcut"
 | 
			
		||||
                style="?attr/materialIconButtonStyle"
 | 
			
		||||
                android:layout_width="wrap_content"
 | 
			
		||||
                android:layout_height="wrap_content"
 | 
			
		||||
                app:icon="@drawable/ic_shortcut"
 | 
			
		||||
                app:iconSize="24dp"
 | 
			
		||||
                app:iconTint="?attr/colorOnSurface"
 | 
			
		||||
                app:layout_constraintTop_toTopOf="parent"
 | 
			
		||||
                app:layout_constraintEnd_toEndOf="parent" />
 | 
			
		||||
 | 
			
		||||
        </androidx.constraintlayout.widget.ConstraintLayout>
 | 
			
		||||
 | 
			
		||||
        <com.google.android.material.card.MaterialCardView
 | 
			
		||||
            style="?attr/materialCardViewElevatedStyle"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,5 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<androidx.constraintlayout.widget.ConstraintLayout
 | 
			
		||||
    xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
<androidx.constraintlayout.widget.ConstraintLayout 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"
 | 
			
		||||
@@ -22,16 +21,35 @@
 | 
			
		||||
            android:orientation="vertical"
 | 
			
		||||
            android:gravity="center_horizontal">
 | 
			
		||||
 | 
			
		||||
            <Button
 | 
			
		||||
                android:id="@+id/button_back"
 | 
			
		||||
                style="?attr/materialIconButtonStyle"
 | 
			
		||||
                android:layout_width="wrap_content"
 | 
			
		||||
            <androidx.constraintlayout.widget.ConstraintLayout
 | 
			
		||||
                android:layout_width="match_parent"
 | 
			
		||||
                android:layout_height="wrap_content"
 | 
			
		||||
                android:layout_margin="8dp"
 | 
			
		||||
                android:layout_gravity="start"
 | 
			
		||||
                app:icon="@drawable/ic_back"
 | 
			
		||||
                app:iconSize="24dp"
 | 
			
		||||
                app:iconTint="?attr/colorOnSurface" />
 | 
			
		||||
                android:orientation="horizontal">
 | 
			
		||||
 | 
			
		||||
                <Button
 | 
			
		||||
                    android:id="@+id/button_back"
 | 
			
		||||
                    style="?attr/materialIconButtonStyle"
 | 
			
		||||
                    android:layout_width="wrap_content"
 | 
			
		||||
                    android:layout_height="wrap_content"
 | 
			
		||||
                    app:icon="@drawable/ic_back"
 | 
			
		||||
                    app:iconSize="24dp"
 | 
			
		||||
                    app:iconTint="?attr/colorOnSurface"
 | 
			
		||||
                    app:layout_constraintStart_toStartOf="parent"
 | 
			
		||||
                    app:layout_constraintTop_toTopOf="parent" />
 | 
			
		||||
 | 
			
		||||
                <Button
 | 
			
		||||
                    android:id="@+id/button_shortcut"
 | 
			
		||||
                    style="?attr/materialIconButtonStyle"
 | 
			
		||||
                    android:layout_width="wrap_content"
 | 
			
		||||
                    android:layout_height="wrap_content"
 | 
			
		||||
                    app:icon="@drawable/ic_shortcut"
 | 
			
		||||
                    app:iconSize="24dp"
 | 
			
		||||
                    app:iconTint="?attr/colorOnSurface"
 | 
			
		||||
                    app:layout_constraintEnd_toEndOf="parent"
 | 
			
		||||
                    app:layout_constraintTop_toTopOf="parent" />
 | 
			
		||||
 | 
			
		||||
            </androidx.constraintlayout.widget.ConstraintLayout>
 | 
			
		||||
 | 
			
		||||
            <com.google.android.material.card.MaterialCardView
 | 
			
		||||
                style="?attr/materialCardViewElevatedStyle"
 | 
			
		||||
@@ -45,7 +63,7 @@
 | 
			
		||||
                    android:id="@+id/image_game_screen"
 | 
			
		||||
                    android:layout_width="175dp"
 | 
			
		||||
                    android:layout_height="175dp"
 | 
			
		||||
                    tools:src="@drawable/default_icon"/>
 | 
			
		||||
                    tools:src="@drawable/default_icon" />
 | 
			
		||||
 | 
			
		||||
            </com.google.android.material.card.MaterialCardView>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user