mirror of
https://git.eden-emu.dev/eden-emu/eden
synced 2026-04-10 05:28:56 +02:00
[android] add qlaunch button (#3439)
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3439 Reviewed-by: DraVee <dravee@eden-emu.dev> Reviewed-by: Maufeat <sahyno1996@gmail.com> Co-authored-by: PavelBARABANOV <pavelbarabanov94@gmail.com> Co-committed-by: PavelBARABANOV <pavelbarabanov94@gmail.com>
This commit is contained in:
parent
5113f503d1
commit
ffdaf7369a
8 changed files with 133 additions and 1 deletions
|
|
@ -36,6 +36,9 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting {
|
||||||
USE_CUSTOM_RTC("custom_rtc_enabled"),
|
USE_CUSTOM_RTC("custom_rtc_enabled"),
|
||||||
BLACK_BACKGROUNDS("black_backgrounds"),
|
BLACK_BACKGROUNDS("black_backgrounds"),
|
||||||
|
|
||||||
|
ENABLE_FOLDER_BUTTON("enable_folder_button"),
|
||||||
|
ENABLE_QLAUNCH_BUTTON("enable_qlaunch_button"),
|
||||||
|
|
||||||
ENABLE_UPDATE_CHECKS("enable_update_checks"),
|
ENABLE_UPDATE_CHECKS("enable_update_checks"),
|
||||||
JOYSTICK_REL_CENTER("joystick_rel_center"),
|
JOYSTICK_REL_CENTER("joystick_rel_center"),
|
||||||
DPAD_SLIDE("dpad_slide"),
|
DPAD_SLIDE("dpad_slide"),
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,11 @@ abstract class SettingsItem(
|
||||||
return NativeInput.getStyleIndex(0) != NpadStyleIndex.Handheld
|
return NativeInput.getStyleIndex(0) != NpadStyleIndex.Handheld
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Can't edit enable_qlaunch_button if firmware is not available
|
||||||
|
if (setting.key == BooleanSetting.ENABLE_QLAUNCH_BUTTON.key) {
|
||||||
|
return NativeLibrary.isFirmwareAvailable()
|
||||||
|
}
|
||||||
|
|
||||||
// Can't edit settings that aren't saveable in per-game config even if they are switchable
|
// Can't edit settings that aren't saveable in per-game config even if they are switchable
|
||||||
if (NativeConfig.isPerGameConfigLoaded() && !setting.isSaveable) {
|
if (NativeConfig.isPerGameConfigLoaded() && !setting.isSaveable) {
|
||||||
return false
|
return false
|
||||||
|
|
@ -794,6 +799,20 @@ abstract class SettingsItem(
|
||||||
descriptionId = R.string.enable_update_checks_description,
|
descriptionId = R.string.enable_update_checks_description,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
put(
|
||||||
|
SwitchSetting(
|
||||||
|
BooleanSetting.ENABLE_FOLDER_BUTTON,
|
||||||
|
titleId = R.string.enable_folder_button,
|
||||||
|
descriptionId = R.string.enable_folder_button_description,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
put(
|
||||||
|
SwitchSetting(
|
||||||
|
BooleanSetting.ENABLE_QLAUNCH_BUTTON,
|
||||||
|
titleId = R.string.enable_qlaunch_button,
|
||||||
|
descriptionId = R.string.enable_qlaunch_button_description,
|
||||||
|
)
|
||||||
|
)
|
||||||
put(
|
put(
|
||||||
SingleChoiceSetting(
|
SingleChoiceSetting(
|
||||||
IntSetting.APP_LANGUAGE,
|
IntSetting.APP_LANGUAGE,
|
||||||
|
|
|
||||||
|
|
@ -1191,6 +1191,13 @@ class SettingsFragmentPresenter(
|
||||||
descriptionId = R.string.use_black_backgrounds_description
|
descriptionId = R.string.use_black_backgrounds_description
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
add(HeaderSetting(R.string.buttons))
|
||||||
|
add(BooleanSetting.ENABLE_FOLDER_BUTTON.key)
|
||||||
|
add(BooleanSetting.ENABLE_QLAUNCH_BUTTON.key)
|
||||||
|
if (!NativeLibrary.isFirmwareAvailable()) {
|
||||||
|
BooleanSetting.ENABLE_QLAUNCH_BUTTON.setBoolean(false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,10 @@ namespace AndroidSettings {
|
||||||
Settings::Setting<s32> app_language{linkage, 0, "app_language", Settings::Category::Android};
|
Settings::Setting<s32> app_language{linkage, 0, "app_language", Settings::Category::Android};
|
||||||
Settings::Setting<bool> enable_update_checks{linkage, true, "enable_update_checks",
|
Settings::Setting<bool> enable_update_checks{linkage, true, "enable_update_checks",
|
||||||
Settings::Category::Android};
|
Settings::Category::Android};
|
||||||
|
Settings::Setting<bool> enable_folder_button{linkage, true, "enable_folder_button",
|
||||||
|
Settings::Category::Android};
|
||||||
|
Settings::Setting<bool> enable_qlaunch_button{linkage, false, "enable_qlaunch_button",
|
||||||
|
Settings::Category::Android};
|
||||||
|
|
||||||
// Input/performance overlay settings
|
// Input/performance overlay settings
|
||||||
std::vector<OverlayControlData> overlay_control_data;
|
std::vector<OverlayControlData> overlay_control_data;
|
||||||
|
|
|
||||||
|
|
@ -220,6 +220,23 @@
|
||||||
android:textColor="?attr/colorOnPrimary"
|
android:textColor="?attr/colorOnPrimary"
|
||||||
app:backgroundTint="?attr/colorPrimary"
|
app:backgroundTint="?attr/colorPrimary"
|
||||||
app:iconTint="?attr/colorOnPrimary"
|
app:iconTint="?attr/colorOnPrimary"
|
||||||
|
app:rippleColor="#99FFFFFF"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
|
||||||
|
android:id="@+id/launch_qlaunch"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="16dp"
|
||||||
|
android:contentDescription="Launch QLaunch"
|
||||||
|
android:text="@string/qlaunch_applet"
|
||||||
|
app:icon="@drawable/ic_home"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
android:textColor="?attr/colorOnPrimary"
|
||||||
|
app:backgroundTint="?attr/colorPrimary"
|
||||||
|
app:iconTint="?attr/colorOnPrimary"
|
||||||
|
app:rippleColor="#99FFFFFF"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
@ -214,6 +214,22 @@
|
||||||
|
|
||||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||||
|
|
||||||
|
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
|
||||||
|
android:id="@+id/launch_qlaunch"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_margin="16dp"
|
||||||
|
android:contentDescription="Launch QLaunch"
|
||||||
|
android:text="@string/qlaunch_applet"
|
||||||
|
app:icon="@drawable/ic_home"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
android:textColor="?attr/colorOnPrimary"
|
||||||
|
app:backgroundTint="?attr/colorPrimary"
|
||||||
|
app:iconTint="?attr/colorOnPrimary"
|
||||||
|
app:rippleColor="#99FFFFFF"
|
||||||
|
/>
|
||||||
|
|
||||||
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
|
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
|
||||||
android:id="@+id/add_directory"
|
android:id="@+id/add_directory"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
|
@ -227,6 +243,7 @@
|
||||||
android:textColor="?attr/colorOnPrimary"
|
android:textColor="?attr/colorOnPrimary"
|
||||||
app:backgroundTint="?attr/colorPrimary"
|
app:backgroundTint="?attr/colorPrimary"
|
||||||
app:iconTint="?attr/colorOnPrimary"
|
app:iconTint="?attr/colorOnPrimary"
|
||||||
|
app:rippleColor="#99FFFFFF"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
@ -1163,6 +1163,12 @@
|
||||||
<string name="use_black_backgrounds">Black backgrounds</string>
|
<string name="use_black_backgrounds">Black backgrounds</string>
|
||||||
<string name="use_black_backgrounds_description">When using the dark theme, apply black backgrounds.</string>
|
<string name="use_black_backgrounds_description">When using the dark theme, apply black backgrounds.</string>
|
||||||
|
|
||||||
|
<!-- Buttons -->
|
||||||
|
<string name="enable_folder_button">Folder</string>
|
||||||
|
<string name="enable_folder_button_description">Show the button to add game folders</string>
|
||||||
|
<string name="enable_qlaunch_button">QLaunch</string>
|
||||||
|
<string name="enable_qlaunch_button_description">Show the button to launch QLaunch</string>
|
||||||
|
|
||||||
<!-- App Language -->
|
<!-- App Language -->
|
||||||
<string name="app_language">App Language</string>
|
<string name="app_language">App Language</string>
|
||||||
<string name="app_language_description">Change the language of the app interface</string>
|
<string name="app_language_description">Change the language of the app interface</string>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue