diff options
| author | PavelBARABANOV <pavelbarabanov94@gmail.com> | 2026-02-01 22:03:35 +0100 |
|---|---|---|
| committer | crueter <crueter@eden-emu.dev> | 2026-02-01 22:03:35 +0100 |
| commit | ffdaf7369a5bc964b05a1803cd796aadfea13f4b (patch) | |
| tree | 8f58b1278047f2823436c41cc2327eabfa2aade7 /src/android | |
| parent | 5113f503d140c1edd8670d03d44bcb79fb1a9518 (diff) | |
[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>
Diffstat (limited to 'src/android')
8 files changed, 133 insertions, 1 deletions
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt index 40e75acff7..2059177621 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/BooleanSetting.kt @@ -36,6 +36,9 @@ enum class BooleanSetting(override val key: String) : AbstractBooleanSetting { USE_CUSTOM_RTC("custom_rtc_enabled"), BLACK_BACKGROUNDS("black_backgrounds"), + ENABLE_FOLDER_BUTTON("enable_folder_button"), + ENABLE_QLAUNCH_BUTTON("enable_qlaunch_button"), + ENABLE_UPDATE_CHECKS("enable_update_checks"), JOYSTICK_REL_CENTER("joystick_rel_center"), DPAD_SLIDE("dpad_slide"), diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt index afa76362ff..870eec1a1b 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt @@ -60,6 +60,11 @@ abstract class SettingsItem( 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 if (NativeConfig.isPerGameConfigLoaded() && !setting.isSaveable) { return false @@ -795,6 +800,20 @@ abstract class SettingsItem( ) ) 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( SingleChoiceSetting( IntSetting.APP_LANGUAGE, titleId = R.string.app_language, diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt index b6cb7acf1e..490f2a97a5 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt @@ -1191,6 +1191,13 @@ class SettingsFragmentPresenter( 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) + } } } 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 280631fa4e..6931a1f9d5 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 @@ -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 package org.yuzu.yuzu_emu.ui @@ -13,6 +13,7 @@ import android.view.View import android.view.ViewGroup import android.view.inputmethod.InputMethodManager import android.widget.PopupMenu +import android.widget.Toast import androidx.activity.result.contract.ActivityResultContracts import androidx.appcompat.app.AppCompatActivity import androidx.core.view.ViewCompat @@ -27,10 +28,14 @@ import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.LinearLayoutManager 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.YuzuApplication import org.yuzu.yuzu_emu.adapters.GameAdapter 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.GamesViewModel import org.yuzu.yuzu_emu.model.HomeViewModel @@ -173,10 +178,16 @@ class GamesFragment : Fragment() { setupTopView() + updateButtonsVisibility() + binding.addDirectory.setOnClickListener { getGamesDirectory.launch(Intent(Intent.ACTION_OPEN_DOCUMENT_TREE).data) } + binding.launchQlaunch?.setOnClickListener { + launchQLaunch() + } + 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() = ViewCompat.setOnApplyWindowInsetsListener( binding.root @@ -498,6 +550,13 @@ class GamesFragment : Fragment() { mlpFab.rightMargin = rightInset + fabPadding 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 gestureInsets = windowInsets.getInsets(WindowInsetsCompat.Type.systemGestures()) val bottomInset = maxOf(navInsets.bottom, gestureInsets.bottom, cutoutInsets.bottom) diff --git a/src/android/app/src/main/jni/android_settings.h b/src/android/app/src/main/jni/android_settings.h index f8260e183a..b6fd37c9dd 100644 --- a/src/android/app/src/main/jni/android_settings.h +++ b/src/android/app/src/main/jni/android_settings.h @@ -65,6 +65,10 @@ namespace AndroidSettings { Settings::Setting<s32> app_language{linkage, 0, "app_language", Settings::Category::Android}; Settings::Setting<bool> enable_update_checks{linkage, true, "enable_update_checks", 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 std::vector<OverlayControlData> overlay_control_data; diff --git a/src/android/app/src/main/res/layout-land/fragment_games.xml b/src/android/app/src/main/res/layout-land/fragment_games.xml index d264f58baf..da778eab69 100644 --- a/src/android/app/src/main/res/layout-land/fragment_games.xml +++ b/src/android/app/src/main/res/layout-land/fragment_games.xml @@ -220,6 +220,23 @@ android:textColor="?attr/colorOnPrimary" app:backgroundTint="?attr/colorPrimary" 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>
\ No newline at end of file diff --git a/src/android/app/src/main/res/layout/fragment_games.xml b/src/android/app/src/main/res/layout/fragment_games.xml index 1f151955d9..921625e42b 100644 --- a/src/android/app/src/main/res/layout/fragment_games.xml +++ b/src/android/app/src/main/res/layout/fragment_games.xml @@ -215,6 +215,22 @@ </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 android:id="@+id/add_directory" android:layout_width="wrap_content" android:layout_height="wrap_content" @@ -227,6 +243,7 @@ android:textColor="?attr/colorOnPrimary" app:backgroundTint="?attr/colorPrimary" app:iconTint="?attr/colorOnPrimary" + app:rippleColor="#99FFFFFF" /> </androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml index 3740a54639..1e49450b95 100644 --- a/src/android/app/src/main/res/values/strings.xml +++ b/src/android/app/src/main/res/values/strings.xml @@ -1163,6 +1163,12 @@ <string name="use_black_backgrounds">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 --> <string name="app_language">App Language</string> <string name="app_language_description">Change the language of the app interface</string> |
