mirror of
https://git.ryujinx.app/kenji-nx/ryujinx.git
synced 2025-12-14 16:37:07 +00:00
Keyboard inputs fixed
This commit is contained in:
parent
be176fd367
commit
eee4a6272c
4 changed files with 95 additions and 37 deletions
|
|
@ -97,7 +97,8 @@ val jnaInstance: KenjinxNativeJna = Native.load(
|
|||
|
||||
object KenjinxNative : KenjinxNativeJna by jnaInstance {
|
||||
|
||||
fun loggingSetEnabled(logLevel: LogLevel, enabled: Boolean) = loggingSetEnabled(logLevel.ordinal, enabled)
|
||||
fun loggingSetEnabled(logLevel: LogLevel, enabled: Boolean) =
|
||||
loggingSetEnabled(logLevel.ordinal, enabled)
|
||||
|
||||
@JvmStatic
|
||||
fun frameEnded() = MainActivity.frameEnded()
|
||||
|
|
@ -116,6 +117,10 @@ object KenjinxNative : KenjinxNativeJna by jnaInstance {
|
|||
progress
|
||||
)
|
||||
|
||||
/**
|
||||
* Variant A (Pointer → Strings via NativeHelpers).
|
||||
* Used by older JNI/Interop paths.
|
||||
*/
|
||||
@JvmStatic
|
||||
fun updateUiHandler(
|
||||
newTitlePointer: Long,
|
||||
|
|
@ -127,15 +132,54 @@ object KenjinxNative : KenjinxNativeJna by jnaInstance {
|
|||
nMode: Int,
|
||||
newSubtitlePointer: Long,
|
||||
newInitialTextPointer: Long
|
||||
) = MainActivity.mainViewModel?.activity?.uiHandler?.update(
|
||||
newTitle = NativeHelpers.instance.getStringJava(newTitlePointer),
|
||||
newMessage = NativeHelpers.instance.getStringJava(newMessagePointer),
|
||||
newWatermark = NativeHelpers.instance.getStringJava(newWatermarkPointer),
|
||||
newType,
|
||||
min,
|
||||
max,
|
||||
newMode = KeyboardMode.entries[nMode],
|
||||
newSubtitle = NativeHelpers.instance.getStringJava(newSubtitlePointer),
|
||||
NativeHelpers.instance.getStringJava(newInitialTextPointer)
|
||||
)
|
||||
) {
|
||||
val title = NativeHelpers.instance.getStringJava(newTitlePointer)
|
||||
val message = NativeHelpers.instance.getStringJava(newMessagePointer)
|
||||
val watermark = NativeHelpers.instance.getStringJava(newWatermarkPointer)
|
||||
val subtitle = NativeHelpers.instance.getStringJava(newSubtitlePointer)
|
||||
val initialText = NativeHelpers.instance.getStringJava(newInitialTextPointer)
|
||||
val mode = KeyboardMode.entries.getOrNull(nMode) ?: KeyboardMode.Default
|
||||
|
||||
MainActivity.mainViewModel?.activity?.uiHandler?.update(
|
||||
newTitle = title,
|
||||
newMessage = message,
|
||||
newWatermark = watermark,
|
||||
newType = newType,
|
||||
min = min,
|
||||
max = max,
|
||||
newMode = mode,
|
||||
newSubtitle = subtitle,
|
||||
newInitialText = initialText
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Variant B (strings directly). Used by newer JNI/Interop paths.
|
||||
* Signature exactly matches the C# call in AndroidUIHandler.cs / Interop.UpdateUiHandler(...).
|
||||
*/
|
||||
@JvmStatic
|
||||
fun uiHandlerUpdate(
|
||||
title: String,
|
||||
message: String,
|
||||
watermark: String,
|
||||
type: Int,
|
||||
min: Int,
|
||||
max: Int,
|
||||
nMode: Int,
|
||||
subtitle: String,
|
||||
initialText: String
|
||||
) {
|
||||
val mode = KeyboardMode.entries.getOrNull(nMode) ?: KeyboardMode.Default
|
||||
MainActivity.mainViewModel?.activity?.uiHandler?.update(
|
||||
newTitle = title,
|
||||
newMessage = message,
|
||||
newWatermark = watermark,
|
||||
newType = type,
|
||||
min = min,
|
||||
max = max,
|
||||
newMode = mode,
|
||||
newSubtitle = subtitle,
|
||||
newInitialText = initialText
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@ import org.kenjinx.android.viewmodels.GameModel
|
|||
import org.kenjinx.android.views.MainView
|
||||
import androidx.core.net.toUri
|
||||
|
||||
|
||||
class MainActivity : BaseActivity() {
|
||||
private var physicalControllerManager: PhysicalControllerManager =
|
||||
PhysicalControllerManager(this)
|
||||
|
|
@ -123,8 +122,7 @@ class MainActivity : BaseActivity() {
|
|||
motionSensorManager = MotionSensorManager(this)
|
||||
Thread.setDefaultUncaughtExceptionHandler(crashHandler)
|
||||
|
||||
if (
|
||||
!Environment.isExternalStorageManager()
|
||||
if (!Environment.isExternalStorageManager()
|
||||
) {
|
||||
storageHelper?.storage?.requestFullStorageAccess()
|
||||
}
|
||||
|
|
@ -143,6 +141,9 @@ class MainActivity : BaseActivity() {
|
|||
controller.systemBarsBehavior = WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
|
||||
}
|
||||
|
||||
// >>> Important: Initialize UI handler (for software keyboard/dialog)
|
||||
uiHandler = UiHandler()
|
||||
|
||||
mainViewModel = MainViewModel(this)
|
||||
mainViewModel!!.physicalControllerManager = physicalControllerManager
|
||||
mainViewModel!!.motionSensorManager = motionSensorManager
|
||||
|
|
@ -152,7 +153,6 @@ class MainActivity : BaseActivity() {
|
|||
mainViewModel?.apply {
|
||||
setContent {
|
||||
KenjinxAndroidTheme {
|
||||
// A surface container using the 'background' color from the theme
|
||||
Surface(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
color = MaterialTheme.colorScheme.background
|
||||
|
|
@ -219,7 +219,7 @@ class MainActivity : BaseActivity() {
|
|||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
isActive = true
|
||||
isActive = false
|
||||
|
||||
if (isGameRunning) {
|
||||
mainViewModel?.performanceManager?.setTurboMode(false)
|
||||
|
|
@ -232,7 +232,7 @@ class MainActivity : BaseActivity() {
|
|||
when (storedIntent.action) {
|
||||
Intent.ACTION_VIEW, "org.kenjinx.android.LAUNCH_GAME" -> {
|
||||
val bootPath = storedIntent.getStringExtra("bootPath")
|
||||
val forceNceAndPptc = storedIntent.getBooleanExtra("forceNceAndPptc",false)
|
||||
val forceNceAndPptc = storedIntent.getBooleanExtra("forceNceAndPptc", false)
|
||||
|
||||
if (bootPath != null) {
|
||||
val uri = bootPath.toUri()
|
||||
|
|
@ -260,7 +260,6 @@ class MainActivity : BaseActivity() {
|
|||
|
||||
// Clean up resources if needed
|
||||
mainViewModel?.let {
|
||||
// Perform any critical cleanup
|
||||
it.performanceManager?.setTurboMode(false)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,8 +17,12 @@ import androidx.compose.material3.TextField
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.focus.FocusRequester
|
||||
import androidx.compose.ui.focus.focusRequester
|
||||
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
|
||||
import androidx.compose.ui.text.input.ImeAction
|
||||
import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
|
|
@ -27,6 +31,7 @@ import androidx.compose.ui.window.DialogProperties
|
|||
import com.halilibo.richtext.markdown.Markdown
|
||||
import com.halilibo.richtext.ui.material3.RichText
|
||||
import org.kenjinx.android.widgets.SimpleAlertDialog
|
||||
import kotlinx.coroutines.delay
|
||||
|
||||
enum class KeyboardMode {
|
||||
Default, Numeric, ASCII, FullLatin, Alphabet, SimplifiedChinese, TraditionalChinese, Korean, LanguageSet2, LanguageSet2Latin
|
||||
|
|
@ -46,6 +51,7 @@ class UiHandler {
|
|||
var message: String = ""
|
||||
|
||||
init {
|
||||
// 2.0.3 compatible: no parameters
|
||||
KenjinxNative.uiHandlerSetup()
|
||||
}
|
||||
|
||||
|
|
@ -77,15 +83,21 @@ class UiHandler {
|
|||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun Compose() {
|
||||
val showMessageListener = remember {
|
||||
showMessage
|
||||
}
|
||||
val showMessageListener = remember { showMessage }
|
||||
val inputListener = remember { inputText }
|
||||
val validation = remember { mutableStateOf("") }
|
||||
|
||||
val inputListener = remember {
|
||||
inputText
|
||||
}
|
||||
val validation = remember {
|
||||
mutableStateOf("")
|
||||
// Focus & keyboard control so the popup can be typed immediately like in 2.0.3
|
||||
val focusRequester = remember { FocusRequester() }
|
||||
val keyboard = LocalSoftwareKeyboardController.current
|
||||
|
||||
LaunchedEffect(showMessageListener.value, type) {
|
||||
if (showMessageListener.value && type == 2) {
|
||||
// small delay until the dialog is mounted
|
||||
delay(100)
|
||||
focusRequester.requestFocus()
|
||||
keyboard?.show()
|
||||
}
|
||||
}
|
||||
|
||||
fun validate(): Boolean {
|
||||
|
|
@ -94,7 +106,6 @@ class UiHandler {
|
|||
} else {
|
||||
return inputText.value.length < minLength || inputText.value.length > maxLength
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
|
|
@ -103,9 +114,7 @@ class UiHandler {
|
|||
KeyboardMode.Default -> KeyboardType.Text
|
||||
KeyboardMode.Numeric -> KeyboardType.Decimal
|
||||
KeyboardMode.ASCII -> KeyboardType.Ascii
|
||||
else -> {
|
||||
KeyboardType.Text
|
||||
}
|
||||
else -> KeyboardType.Text
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -160,10 +169,9 @@ class UiHandler {
|
|||
onValueChange = { inputListener.value = it },
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(4.dp),
|
||||
label = {
|
||||
Text(text = watermark)
|
||||
},
|
||||
.padding(4.dp)
|
||||
.focusRequester(focusRequester),
|
||||
label = { Text(text = watermark) },
|
||||
keyboardOptions = KeyboardOptions(keyboardType = getInputType()),
|
||||
isError = validate()
|
||||
)
|
||||
|
|
@ -173,7 +181,8 @@ class UiHandler {
|
|||
onValueChange = { inputListener.value = it },
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(4.dp),
|
||||
.padding(4.dp)
|
||||
.focusRequester(focusRequester),
|
||||
keyboardOptions = KeyboardOptions(
|
||||
keyboardType = getInputType(),
|
||||
imeAction = ImeAction.Done
|
||||
|
|
@ -211,4 +220,3 @@ class UiHandler {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -250,6 +250,13 @@ class GameViews {
|
|||
mutableStateOf(false)
|
||||
}
|
||||
|
||||
// NEW: If the software keyboard is open, catch Back and close ONLY the dialog.
|
||||
val uiHandler = mainViewModel.activity.uiHandler
|
||||
BackHandler(enabled = uiHandler.showMessage.value) {
|
||||
KenjinxNative.uiHandlerSetResponse(false, "")
|
||||
uiHandler.showMessage.value = false
|
||||
}
|
||||
|
||||
BackHandler {
|
||||
showBackNotice.value = true
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue