Add global keyevent magagement.
This commit is contained in:
parent
ce51a3be0a
commit
f715b973ff
4 changed files with 68 additions and 2 deletions
|
|
@ -20,6 +20,7 @@ import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.CompositionLocalProvider
|
import androidx.compose.runtime.CompositionLocalProvider
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.compositionLocalOf
|
import androidx.compose.runtime.compositionLocalOf
|
||||||
|
import androidx.compose.runtime.mutableStateListOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
|
|
@ -29,6 +30,8 @@ import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.window.ApplicationScope
|
import androidx.compose.ui.window.ApplicationScope
|
||||||
import androidx.compose.ui.window.Window
|
import androidx.compose.ui.window.Window
|
||||||
import androidx.compose.ui.window.rememberWindowState
|
import androidx.compose.ui.window.rememberWindowState
|
||||||
|
import com.pixelized.desktop.lwa.composable.key.KeyEventHandler
|
||||||
|
import com.pixelized.desktop.lwa.composable.key.LocalKeyEventHandlers
|
||||||
import com.pixelized.desktop.lwa.navigation.screen.MainNavHost
|
import com.pixelized.desktop.lwa.navigation.screen.MainNavHost
|
||||||
import com.pixelized.desktop.lwa.navigation.screen.destination.CharacterSheetDestination
|
import com.pixelized.desktop.lwa.navigation.screen.destination.CharacterSheetDestination
|
||||||
import com.pixelized.desktop.lwa.navigation.screen.destination.CharacterSheetEditDestination
|
import com.pixelized.desktop.lwa.navigation.screen.destination.CharacterSheetEditDestination
|
||||||
|
|
@ -68,11 +71,13 @@ fun ApplicationScope.App() {
|
||||||
val snackHostState = remember { SnackbarHostState() }
|
val snackHostState = remember { SnackbarHostState() }
|
||||||
val errorSnackHostState = remember { SnackbarHostState() }
|
val errorSnackHostState = remember { SnackbarHostState() }
|
||||||
val windowController = remember { WindowController() }
|
val windowController = remember { WindowController() }
|
||||||
|
val keyEventHandlers = remember { mutableStateListOf<KeyEventHandler>() }
|
||||||
|
|
||||||
CompositionLocalProvider(
|
CompositionLocalProvider(
|
||||||
LocalSnackHost provides snackHostState,
|
LocalSnackHost provides snackHostState,
|
||||||
LocalErrorSnackHost provides errorSnackHostState,
|
LocalErrorSnackHost provides errorSnackHostState,
|
||||||
LocalWindowController provides windowController,
|
LocalWindowController provides windowController,
|
||||||
|
LocalKeyEventHandlers provides keyEventHandlers,
|
||||||
) {
|
) {
|
||||||
Window(
|
Window(
|
||||||
onCloseRequest = ::exitApplication,
|
onCloseRequest = ::exitApplication,
|
||||||
|
|
@ -81,6 +86,9 @@ fun ApplicationScope.App() {
|
||||||
height = 900.dp,
|
height = 900.dp,
|
||||||
),
|
),
|
||||||
title = "LwaCharacterSheet",
|
title = "LwaCharacterSheet",
|
||||||
|
onKeyEvent = { event ->
|
||||||
|
keyEventHandlers.reversed().any { it(event) }
|
||||||
|
},
|
||||||
) {
|
) {
|
||||||
LwaTheme {
|
LwaTheme {
|
||||||
Surface(
|
Surface(
|
||||||
|
|
@ -131,7 +139,7 @@ fun ApplicationScope.App() {
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun WindowsHandler(
|
private fun WindowsHandler(
|
||||||
windowController: WindowController
|
windowController: WindowController,
|
||||||
) {
|
) {
|
||||||
WindowsNavHost(
|
WindowsNavHost(
|
||||||
controller = windowController,
|
controller = windowController,
|
||||||
|
|
@ -230,7 +238,7 @@ fun Snackbar(
|
||||||
backgroundColor: Color = SnackbarDefaults.backgroundColor,
|
backgroundColor: Color = SnackbarDefaults.backgroundColor,
|
||||||
contentColor: Color = MaterialTheme.colors.surface,
|
contentColor: Color = MaterialTheme.colors.surface,
|
||||||
actionColor: Color = SnackbarDefaults.primaryActionColor,
|
actionColor: Color = SnackbarDefaults.primaryActionColor,
|
||||||
elevation: Dp = 6.dp
|
elevation: Dp = 6.dp,
|
||||||
) {
|
) {
|
||||||
val actionLabel = snackbarData.actionLabel
|
val actionLabel = snackbarData.actionLabel
|
||||||
val actionComposable: (@Composable () -> Unit)? = if (actionLabel != null) {
|
val actionComposable: (@Composable () -> Unit)? = if (actionLabel != null) {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
package com.pixelized.desktop.lwa.composable.key
|
||||||
|
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.DisposableEffect
|
||||||
|
import androidx.compose.runtime.rememberUpdatedState
|
||||||
|
import androidx.compose.runtime.staticCompositionLocalOf
|
||||||
|
import androidx.compose.ui.input.key.KeyEvent
|
||||||
|
|
||||||
|
typealias KeyEventHandler = (KeyEvent) -> Boolean
|
||||||
|
|
||||||
|
val LocalKeyEventHandlers = staticCompositionLocalOf<MutableList<KeyEventHandler>> {
|
||||||
|
error("LocalKeyEventHandlers is not provided")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun KeyHandler(
|
||||||
|
key: Any = "KeyHandler",
|
||||||
|
enabled: Boolean = true,
|
||||||
|
onKeyPress: (KeyEvent) -> Boolean,
|
||||||
|
) {
|
||||||
|
if (enabled) {
|
||||||
|
val handlerState = rememberUpdatedState(onKeyPress)
|
||||||
|
val eventHandlers = LocalKeyEventHandlers.current
|
||||||
|
DisposableEffect(key) {
|
||||||
|
val localHandler: KeyEventHandler = {
|
||||||
|
handlerState.value(it)
|
||||||
|
}
|
||||||
|
eventHandlers.add(localHandler)
|
||||||
|
onDispose {
|
||||||
|
eventHandlers.remove(localHandler)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -6,10 +6,14 @@ import androidx.compose.runtime.Stable
|
||||||
import androidx.compose.runtime.State
|
import androidx.compose.runtime.State
|
||||||
import androidx.compose.runtime.compositionLocalOf
|
import androidx.compose.runtime.compositionLocalOf
|
||||||
import androidx.compose.runtime.key
|
import androidx.compose.runtime.key
|
||||||
|
import androidx.compose.runtime.mutableStateListOf
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.window.Window
|
import androidx.compose.ui.window.Window
|
||||||
import androidx.compose.ui.window.WindowState
|
import androidx.compose.ui.window.WindowState
|
||||||
import androidx.compose.ui.window.rememberWindowState
|
import androidx.compose.ui.window.rememberWindowState
|
||||||
|
import com.pixelized.desktop.lwa.composable.key.KeyEventHandler
|
||||||
|
import com.pixelized.desktop.lwa.composable.key.LocalKeyEventHandlers
|
||||||
import com.pixelized.desktop.lwa.navigation.window.destination.Window
|
import com.pixelized.desktop.lwa.navigation.window.destination.Window
|
||||||
|
|
||||||
val LocalWindow = compositionLocalOf<Window> {
|
val LocalWindow = compositionLocalOf<Window> {
|
||||||
|
|
@ -45,14 +49,20 @@ fun WindowsNavHost(
|
||||||
controller.windows.value.forEach { (id, window) ->
|
controller.windows.value.forEach { (id, window) ->
|
||||||
key(id) {
|
key(id) {
|
||||||
val state = rememberWindowState(size = window.size)
|
val state = rememberWindowState(size = window.size)
|
||||||
|
val keyEventHandlers = remember { mutableStateListOf<KeyEventHandler>() }
|
||||||
|
|
||||||
CompositionLocalProvider(
|
CompositionLocalProvider(
|
||||||
LocalWindow provides window,
|
LocalWindow provides window,
|
||||||
LocalWindowState provides state,
|
LocalWindowState provides state,
|
||||||
|
LocalKeyEventHandlers provides keyEventHandlers,
|
||||||
) {
|
) {
|
||||||
Window(
|
Window(
|
||||||
onCloseRequest = { controller.hideWindow(id = window.id) },
|
onCloseRequest = { controller.hideWindow(id = window.id) },
|
||||||
state = state,
|
state = state,
|
||||||
title = window.title,
|
title = window.title,
|
||||||
|
onKeyEvent = { event ->
|
||||||
|
keyEventHandlers.reversed().any { it(event) }
|
||||||
|
},
|
||||||
) {
|
) {
|
||||||
content.invoke(window)
|
content.invoke(window)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -41,9 +41,14 @@ import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.geometry.Offset
|
import androidx.compose.ui.geometry.Offset
|
||||||
import androidx.compose.ui.graphics.Shadow
|
import androidx.compose.ui.graphics.Shadow
|
||||||
import androidx.compose.ui.graphics.graphicsLayer
|
import androidx.compose.ui.graphics.graphicsLayer
|
||||||
|
import androidx.compose.ui.input.key.Key
|
||||||
|
import androidx.compose.ui.input.key.KeyEventType
|
||||||
|
import androidx.compose.ui.input.key.key
|
||||||
|
import androidx.compose.ui.input.key.type
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
import androidx.compose.ui.text.style.TextAlign
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import com.pixelized.desktop.lwa.composable.key.KeyHandler
|
||||||
import com.pixelized.desktop.lwa.screen.roll.DifficultyUio.Difficulty
|
import com.pixelized.desktop.lwa.screen.roll.DifficultyUio.Difficulty
|
||||||
import com.pixelized.desktop.lwa.utils.DisableInteractionSource
|
import com.pixelized.desktop.lwa.utils.DisableInteractionSource
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
@ -89,6 +94,15 @@ fun RollPage(
|
||||||
) {
|
) {
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
|
|
||||||
|
KeyHandler {
|
||||||
|
if (it.type == KeyEventType.KeyUp && it.key == Key.Escape) {
|
||||||
|
onDismissRequest()
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier.fillMaxSize()
|
modifier = Modifier.fillMaxSize()
|
||||||
.clickable(
|
.clickable(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue