|
|
@ -1,4 +1,4 @@ |
|
|
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project |
|
|
|
|
|
|
|
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project |
|
|
// SPDX-License-Identifier: GPL-3.0-or-later |
|
|
// SPDX-License-Identifier: GPL-3.0-or-later |
|
|
|
|
|
|
|
|
package org.yuzu.yuzu_emu.ui |
|
|
package org.yuzu.yuzu_emu.ui |
|
|
@ -13,6 +13,7 @@ import android.view.View |
|
|
import android.view.ViewGroup |
|
|
import android.view.ViewGroup |
|
|
import android.view.inputmethod.InputMethodManager |
|
|
import android.view.inputmethod.InputMethodManager |
|
|
import android.widget.PopupMenu |
|
|
import android.widget.PopupMenu |
|
|
|
|
|
import android.widget.Toast |
|
|
import androidx.activity.result.contract.ActivityResultContracts |
|
|
import androidx.activity.result.contract.ActivityResultContracts |
|
|
import androidx.appcompat.app.AppCompatActivity |
|
|
import androidx.appcompat.app.AppCompatActivity |
|
|
import androidx.core.view.ViewCompat |
|
|
import androidx.core.view.ViewCompat |
|
|
@ -27,10 +28,14 @@ import androidx.recyclerview.widget.RecyclerView |
|
|
import androidx.recyclerview.widget.GridLayoutManager |
|
|
import androidx.recyclerview.widget.GridLayoutManager |
|
|
import androidx.recyclerview.widget.LinearLayoutManager |
|
|
import androidx.recyclerview.widget.LinearLayoutManager |
|
|
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout |
|
|
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout |
|
|
|
|
|
import org.yuzu.yuzu_emu.HomeNavigationDirections |
|
|
|
|
|
import org.yuzu.yuzu_emu.NativeLibrary |
|
|
import org.yuzu.yuzu_emu.R |
|
|
import org.yuzu.yuzu_emu.R |
|
|
import org.yuzu.yuzu_emu.YuzuApplication |
|
|
import org.yuzu.yuzu_emu.YuzuApplication |
|
|
import org.yuzu.yuzu_emu.adapters.GameAdapter |
|
|
import org.yuzu.yuzu_emu.adapters.GameAdapter |
|
|
import org.yuzu.yuzu_emu.databinding.FragmentGamesBinding |
|
|
import org.yuzu.yuzu_emu.databinding.FragmentGamesBinding |
|
|
|
|
|
import org.yuzu.yuzu_emu.features.settings.model.BooleanSetting |
|
|
|
|
|
import org.yuzu.yuzu_emu.model.AppletInfo |
|
|
import org.yuzu.yuzu_emu.model.Game |
|
|
import org.yuzu.yuzu_emu.model.Game |
|
|
import org.yuzu.yuzu_emu.model.GamesViewModel |
|
|
import org.yuzu.yuzu_emu.model.GamesViewModel |
|
|
import org.yuzu.yuzu_emu.model.HomeViewModel |
|
|
import org.yuzu.yuzu_emu.model.HomeViewModel |
|
|
@ -173,10 +178,16 @@ class GamesFragment : Fragment() { |
|
|
|
|
|
|
|
|
setupTopView() |
|
|
setupTopView() |
|
|
|
|
|
|
|
|
|
|
|
updateButtonsVisibility() |
|
|
|
|
|
|
|
|
binding.addDirectory.setOnClickListener { |
|
|
binding.addDirectory.setOnClickListener { |
|
|
getGamesDirectory.launch(Intent(Intent.ACTION_OPEN_DOCUMENT_TREE).data) |
|
|
getGamesDirectory.launch(Intent(Intent.ACTION_OPEN_DOCUMENT_TREE).data) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
binding.launchQlaunch?.setOnClickListener { |
|
|
|
|
|
launchQLaunch() |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
setInsets() |
|
|
setInsets() |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -445,6 +456,47 @@ class GamesFragment : Fragment() { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private fun launchQLaunch() { |
|
|
|
|
|
try { |
|
|
|
|
|
val appletPath = NativeLibrary.getAppletLaunchPath(AppletInfo.QLaunch.entryId) |
|
|
|
|
|
if (appletPath.isEmpty()) { |
|
|
|
|
|
Toast.makeText( |
|
|
|
|
|
requireContext(), |
|
|
|
|
|
R.string.applets_error_applet, |
|
|
|
|
|
Toast.LENGTH_SHORT |
|
|
|
|
|
).show() |
|
|
|
|
|
return |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
NativeLibrary.setCurrentAppletId(AppletInfo.QLaunch.appletId) |
|
|
|
|
|
|
|
|
|
|
|
val qlaunchGame = Game( |
|
|
|
|
|
title = getString(R.string.qlaunch_applet), |
|
|
|
|
|
path = appletPath |
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
val action = HomeNavigationDirections.actionGlobalEmulationActivity(qlaunchGame) |
|
|
|
|
|
findNavController().navigate(action) |
|
|
|
|
|
} catch (e: Exception) { |
|
|
|
|
|
Toast.makeText( |
|
|
|
|
|
requireContext(), |
|
|
|
|
|
"Failed to launch QLaunch: ${e.message}", |
|
|
|
|
|
Toast.LENGTH_SHORT |
|
|
|
|
|
).show() |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private fun updateButtonsVisibility() { |
|
|
|
|
|
val showQLaunch = BooleanSetting.ENABLE_QLAUNCH_BUTTON.getBoolean() |
|
|
|
|
|
val showFolder = BooleanSetting.ENABLE_FOLDER_BUTTON.getBoolean() |
|
|
|
|
|
val isFirmwareAvailable = NativeLibrary.isFirmwareAvailable() |
|
|
|
|
|
|
|
|
|
|
|
val shouldShowQLaunch = showQLaunch && isFirmwareAvailable |
|
|
|
|
|
binding.launchQlaunch.visibility = if (shouldShowQLaunch) View.VISIBLE else View.GONE |
|
|
|
|
|
|
|
|
|
|
|
binding.addDirectory.visibility = if (showFolder) View.VISIBLE else View.GONE |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
private fun setInsets() = |
|
|
private fun setInsets() = |
|
|
ViewCompat.setOnApplyWindowInsetsListener( |
|
|
ViewCompat.setOnApplyWindowInsetsListener( |
|
|
binding.root |
|
|
binding.root |
|
|
@ -498,6 +550,13 @@ class GamesFragment : Fragment() { |
|
|
mlpFab.rightMargin = rightInset + fabPadding |
|
|
mlpFab.rightMargin = rightInset + fabPadding |
|
|
binding.addDirectory.layoutParams = mlpFab |
|
|
binding.addDirectory.layoutParams = mlpFab |
|
|
|
|
|
|
|
|
|
|
|
binding.launchQlaunch?.let { qlaunchButton -> |
|
|
|
|
|
val mlpQLaunch = qlaunchButton.layoutParams as ViewGroup.MarginLayoutParams |
|
|
|
|
|
mlpQLaunch.leftMargin = leftInset + fabPadding |
|
|
|
|
|
mlpQLaunch.bottomMargin = barInsets.bottom + fabPadding |
|
|
|
|
|
qlaunchButton.layoutParams = mlpQLaunch |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
val navInsets = windowInsets.getInsets(WindowInsetsCompat.Type.navigationBars()) |
|
|
val navInsets = windowInsets.getInsets(WindowInsetsCompat.Type.navigationBars()) |
|
|
val gestureInsets = windowInsets.getInsets(WindowInsetsCompat.Type.systemGestures()) |
|
|
val gestureInsets = windowInsets.getInsets(WindowInsetsCompat.Type.systemGestures()) |
|
|
val bottomInset = maxOf(navInsets.bottom, gestureInsets.bottom, cutoutInsets.bottom) |
|
|
val bottomInset = maxOf(navInsets.bottom, gestureInsets.bottom, cutoutInsets.bottom) |
|
|
|