From f14536635cb60386aa436326414285aff003ad17 Mon Sep 17 00:00:00 2001 From: SSimco <37044560+SSimco@users.noreply.github.com> Date: Wed, 18 Jun 2025 19:07:29 +0300 Subject: [PATCH] Add emulation settings --- .../cemu/cemu/emulation/EmulationActivity.kt | 16 ++++++-- .../cemu/guicore/components/DrawerLayout.kt | 37 +++++++++++------ .../cemu/cemu/settings/SettingsManager.kt | 40 +++++++++++++++++++ .../settings/general/GeneralSettingsScreen.kt | 16 +++++++- .../general/GeneralSettingsViewModel.kt | 29 ++++++++++++++ .../app/src/main/res/values/strings.xml | 2 + 6 files changed, 124 insertions(+), 16 deletions(-) create mode 100644 src/android/app/src/main/java/info/cemu/cemu/settings/SettingsManager.kt create mode 100644 src/android/app/src/main/java/info/cemu/cemu/settings/general/GeneralSettingsViewModel.kt diff --git a/src/android/app/src/main/java/info/cemu/cemu/emulation/EmulationActivity.kt b/src/android/app/src/main/java/info/cemu/cemu/emulation/EmulationActivity.kt index fa575032..0b8468b4 100644 --- a/src/android/app/src/main/java/info/cemu/cemu/emulation/EmulationActivity.kt +++ b/src/android/app/src/main/java/info/cemu/cemu/emulation/EmulationActivity.kt @@ -38,6 +38,8 @@ import info.cemu.cemu.inputoverlay.OverlaySettings import info.cemu.cemu.nativeinterface.NativeEmulation import info.cemu.cemu.nativeinterface.NativeException import info.cemu.cemu.nativeinterface.NativeSwkbd.setCurrentInputText +import info.cemu.cemu.settings.EmulationScreenSettings +import info.cemu.cemu.settings.SettingsManager import java.lang.ref.WeakReference import kotlin.system.exitProcess @@ -80,6 +82,7 @@ class EmulationActivity : AppCompatActivity() { private lateinit var binding: ActivityEmulationBinding private var isMotionEnabled = false private lateinit var overlaySettings: OverlaySettings + private lateinit var emulationScreenSettings: EmulationScreenSettings private lateinit var inputOverlaySurfaceView: InputOverlaySurfaceView private lateinit var sensorManager: SensorManager private var hasEmulationError = false @@ -118,8 +121,8 @@ class EmulationActivity : AppCompatActivity() { super.onCreate(savedInstanceState) emulationActivityInstance = WeakReference(this) - val inputOverlaySettingsManager = InputOverlaySettingsManager(this) - overlaySettings = inputOverlaySettingsManager.overlaySettings + overlaySettings = InputOverlaySettingsManager(this).overlaySettings + emulationScreenSettings = SettingsManager(this).emulationScreenSettings sensorManager = SensorManager(this) sensorManager.setDeviceRotationProvider(deviceRotationProvider = { display.rotation }) @@ -240,7 +243,14 @@ class EmulationActivity : AppCompatActivity() { binding.editInputsLayout.visibility = View.GONE toastMessage(R.string.input_mode_default) } - binding.emulationSettingsButton.setOnClickListener { binding.drawerLayout.open() } + + if (emulationScreenSettings.isDrawerButtonVisible) { + binding.emulationSettingsButton.setOnClickListener { binding.drawerLayout.open() } + binding.drawerLayout.setLockedMode(true) + } else { + binding.emulationSettingsButton.visibility = View.GONE + } + val mainCanvas = binding.mainCanvas try { val testSurfaceTexture = SurfaceTexture(0) diff --git a/src/android/app/src/main/java/info/cemu/cemu/guicore/components/DrawerLayout.kt b/src/android/app/src/main/java/info/cemu/cemu/guicore/components/DrawerLayout.kt index 137e33e7..d66426a8 100644 --- a/src/android/app/src/main/java/info/cemu/cemu/guicore/components/DrawerLayout.kt +++ b/src/android/app/src/main/java/info/cemu/cemu/guicore/components/DrawerLayout.kt @@ -8,21 +8,34 @@ import androidx.drawerlayout.widget.DrawerLayout as AndroidxDrawerLayout class DrawerLayout @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, ) : AndroidxDrawerLayout(context, attrs) { - init { - setDrawerLockMode(LOCK_MODE_LOCKED_CLOSED) - addDrawerListener(object : DrawerListener { - override fun onDrawerSlide(drawerView: View, slideOffset: Float) {} + private var isLocked = false + private val lockedModeDrawerListener = object : DrawerListener { + override fun onDrawerSlide(drawerView: View, slideOffset: Float) {} - override fun onDrawerOpened(drawerView: View) { - setDrawerLockMode(LOCK_MODE_UNLOCKED) - } + override fun onDrawerOpened(drawerView: View) { + setDrawerLockMode(LOCK_MODE_UNLOCKED) + } - override fun onDrawerClosed(drawerView: View) { - setDrawerLockMode(LOCK_MODE_LOCKED_CLOSED) - } + override fun onDrawerClosed(drawerView: View) { + setDrawerLockMode(LOCK_MODE_LOCKED_CLOSED) + } - override fun onDrawerStateChanged(newState: Int) {} - }) + override fun onDrawerStateChanged(newState: Int) {} } + fun setLockedMode(isLocked: Boolean) { + if (this.isLocked == isLocked) { + return + } + + this.isLocked = isLocked + if (isLocked) { + setDrawerLockMode(LOCK_MODE_LOCKED_CLOSED) + addDrawerListener(lockedModeDrawerListener) + return + } + + setDrawerLockMode(LOCK_MODE_UNLOCKED) + removeDrawerListener(lockedModeDrawerListener) + } } \ No newline at end of file diff --git a/src/android/app/src/main/java/info/cemu/cemu/settings/SettingsManager.kt b/src/android/app/src/main/java/info/cemu/cemu/settings/SettingsManager.kt new file mode 100644 index 00000000..105bd832 --- /dev/null +++ b/src/android/app/src/main/java/info/cemu/cemu/settings/SettingsManager.kt @@ -0,0 +1,40 @@ +package info.cemu.cemu.settings + +import android.content.Context +import android.content.SharedPreferences + +class EmulationScreenSettings( + var isDrawerButtonVisible: Boolean, +) { + companion object { + private const val IS_BUTTON_VISIBLE_KEY = "IS_BUTTON_VISIBLE" + } + + constructor(sharedPreferences: SharedPreferences) : this( + isDrawerButtonVisible = sharedPreferences.getBoolean( + IS_BUTTON_VISIBLE_KEY, + false + ), + ) + + fun save(sharedPreferences: SharedPreferences) { + sharedPreferences.edit().apply { + putBoolean(IS_BUTTON_VISIBLE_KEY, isDrawerButtonVisible) + apply() + } + } +} + +class SettingsManager(context: Context) { + private val sharedPreferences: SharedPreferences = + context.getSharedPreferences(SETTINGS_NAME, Context.MODE_PRIVATE) + + var emulationScreenSettings: EmulationScreenSettings + get() = EmulationScreenSettings(sharedPreferences) + set(value) = value.save(sharedPreferences) + + + companion object { + private const val SETTINGS_NAME = "SETTINGS" + } +} diff --git a/src/android/app/src/main/java/info/cemu/cemu/settings/general/GeneralSettingsScreen.kt b/src/android/app/src/main/java/info/cemu/cemu/settings/general/GeneralSettingsScreen.kt index 85c73f74..eb76c824 100644 --- a/src/android/app/src/main/java/info/cemu/cemu/settings/general/GeneralSettingsScreen.kt +++ b/src/android/app/src/main/java/info/cemu/cemu/settings/general/GeneralSettingsScreen.kt @@ -3,15 +3,21 @@ package info.cemu.cemu.settings.general import androidx.compose.runtime.Composable import androidx.compose.ui.res.stringResource import androidx.lifecycle.compose.dropUnlessResumed +import androidx.lifecycle.viewmodel.compose.viewModel import info.cemu.cemu.R import info.cemu.cemu.guicore.components.Button import info.cemu.cemu.guicore.components.ScreenContent import info.cemu.cemu.guicore.components.SingleSelection +import info.cemu.cemu.guicore.components.Toggle import info.cemu.cemu.guicore.nativeenummapper.consoleLanguageToStringId import info.cemu.cemu.nativeinterface.NativeSettings @Composable -fun GeneralSettingsScreen(navigateBack: () -> Unit, goToGamePathsSettings: () -> Unit) { +fun GeneralSettingsScreen( + navigateBack: () -> Unit, + goToGamePathsSettings: () -> Unit, + generalSettingsViewModel: GeneralSettingsViewModel = viewModel(factory = GeneralSettingsViewModel.Factory), +) { ScreenContent( appBarText = stringResource(R.string.general_settings), navigateBack = navigateBack, @@ -41,5 +47,13 @@ fun GeneralSettingsScreen(navigateBack: () -> Unit, goToGamePathsSettings: () -> NativeSettings.CONSOLE_LANGUAGE_TAIWANESE, ), ) + Toggle( + label = stringResource(R.string.side_menu_button), + description = stringResource(R.string.side_menu_button_description), + initialCheckedState = { generalSettingsViewModel.emulationScreenSettings.isDrawerButtonVisible }, + onCheckedChanged = { + generalSettingsViewModel.emulationScreenSettings.isDrawerButtonVisible = it + } + ) } } \ No newline at end of file diff --git a/src/android/app/src/main/java/info/cemu/cemu/settings/general/GeneralSettingsViewModel.kt b/src/android/app/src/main/java/info/cemu/cemu/settings/general/GeneralSettingsViewModel.kt new file mode 100644 index 00000000..c71fad12 --- /dev/null +++ b/src/android/app/src/main/java/info/cemu/cemu/settings/general/GeneralSettingsViewModel.kt @@ -0,0 +1,29 @@ +package info.cemu.cemu.settings.general + +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.viewmodel.initializer +import androidx.lifecycle.viewmodel.viewModelFactory +import info.cemu.cemu.CemuApplication +import info.cemu.cemu.settings.SettingsManager + +class GeneralSettingsViewModel( + private val settingsManager: SettingsManager, +) : ViewModel() { + val emulationScreenSettings = settingsManager.emulationScreenSettings + + override fun onCleared() { + super.onCleared() + settingsManager.emulationScreenSettings = emulationScreenSettings + } + + companion object { + val Factory: ViewModelProvider.Factory = viewModelFactory { + initializer { + GeneralSettingsViewModel( + SettingsManager(CemuApplication.Application) + ) + } + } + } +} \ 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 ceb598d5..5ba96cfa 100644 --- a/src/android/app/src/main/res/values/strings.xml +++ b/src/android/app/src/main/res/values/strings.xml @@ -335,4 +335,6 @@ Setup all inputs No controllers available Select a controller + Side menu button + Show the emulation side menu button \ No newline at end of file