Andrew Rudenko
4 years ago
3 changed files with 119 additions and 0 deletions
After Width: | Height: | Size: 1.3 MiB |
@ -0,0 +1,119 @@
|
||||
# Keyboard events handling |
||||
|
||||
## Prerequisites |
||||
|
||||
This tutorial expects set and ready Compose project build similar to which is described in [Getting Started tutorial](../Getting_Started) |
||||
|
||||
## KeySets & ShortcutHandler |
||||
|
||||
Compose for Desktop has a few utilities to work with shortcuts: |
||||
|
||||
`KeysSet` represents a simultaneously pressed chord of keys. You can construct a `KeysSet` using Key's extension function: |
||||
|
||||
``` kotlin |
||||
Key.CtrlLeft + Key.Enter |
||||
``` |
||||
|
||||
`ShortcutHandler` accepts `KeysSet` and returns a handler which could be used as a callback for `keyInputFilter` |
||||
|
||||
## Event handlers |
||||
|
||||
There are two different ways how you can handle key events in Compose for Desktop: |
||||
|
||||
- By setting up an event handler based on a focused component |
||||
- By setting up an event handler in the scope of the window |
||||
|
||||
## Focus related events |
||||
|
||||
It's working in the same way as in Compose for Android, see for details [API Reference](https://developer.android.com/reference/kotlin/androidx/compose/ui/input/key/package-summary#keyinputfilter) |
||||
|
||||
The most common use case is to define keyboard handlers for active controls like `TextField`. Here is an example: |
||||
|
||||
``` kotlin |
||||
import androidx.compose.desktop.Window |
||||
import androidx.compose.foundation.Text |
||||
import androidx.compose.foundation.layout.Arrangement |
||||
import androidx.compose.foundation.layout.Column |
||||
import androidx.compose.foundation.layout.fillMaxSize |
||||
import androidx.compose.material.MaterialTheme |
||||
import androidx.compose.material.TextField |
||||
import androidx.compose.runtime.mutableStateOf |
||||
import androidx.compose.runtime.remember |
||||
import androidx.compose.ui.Modifier |
||||
import androidx.compose.ui.input.key.* |
||||
import androidx.compose.ui.unit.IntSize |
||||
import androidx.compose.ui.unit.dp |
||||
import androidx.compose.runtime.getValue |
||||
import androidx.compose.runtime.setValue |
||||
|
||||
@OptIn(ExperimentalKeyInput::class) |
||||
fun main() = Window(title = "Compose for Desktop", size = IntSize(300, 300)) { |
||||
MaterialTheme { |
||||
var consumedText by remember { mutableStateOf(0) } |
||||
var text by remember { mutableStateOf("") } |
||||
Column(Modifier.fillMaxSize(), Arrangement.spacedBy(5.dp)) { |
||||
Text("Consumed text: $consumedText") |
||||
TextField( |
||||
value = text, |
||||
onValueChange = { text = it }, |
||||
modifier = Modifier.keyInputFilter( |
||||
ShortcutHandler(Key.CtrlLeft + Key.Enter) { |
||||
consumedText += text.length |
||||
text = "" |
||||
} |
||||
) |
||||
) |
||||
} |
||||
} |
||||
} |
||||
``` |
||||
|
||||
|
||||
Note an annotation `@OptIn(ExperimentalKeyInput::class)`. Keyboard-related event handlers are a still-experimental feature of Compose and API changes are possible, so it requires it to use special annotation to emphasize the experimental nature of the code. |
||||
|
||||
![keyInputFilter](keyInputFilter.gif) |
||||
|
||||
## Window-scoped events |
||||
|
||||
`AppWindow` instances have `keyboard` property. Using it, it's possible to define keyboard shortcuts that are always active for the current window. See an example: |
||||
|
||||
``` kotlin |
||||
import androidx.compose.desktop.AppWindow |
||||
import androidx.compose.desktop.Window |
||||
import androidx.compose.foundation.Text |
||||
import androidx.compose.foundation.layout.Arrangement |
||||
import androidx.compose.foundation.layout.Column |
||||
import androidx.compose.foundation.layout.fillMaxSize |
||||
import androidx.compose.foundation.layout.padding |
||||
import androidx.compose.material.Button |
||||
import androidx.compose.material.MaterialTheme |
||||
import androidx.compose.ui.Modifier |
||||
import androidx.compose.ui.input.key.ExperimentalKeyInput |
||||
import androidx.compose.ui.input.key.Key |
||||
import androidx.compose.ui.unit.IntSize |
||||
import androidx.compose.ui.unit.dp |
||||
|
||||
@OptIn(ExperimentalKeyInput::class) |
||||
fun main() = Window(title = "Compose for Desktop", size = IntSize(300, 300)) { |
||||
MaterialTheme { |
||||
Column(Modifier.fillMaxSize(), Arrangement.spacedBy(5.dp)) { |
||||
Button( |
||||
modifier = Modifier.padding(4.dp), |
||||
onClick = { |
||||
AppWindow(size = IntSize(200, 200)).also { |
||||
it.keyboard.shortcut(Key.Escape) { |
||||
it.close() |
||||
} |
||||
}.show { |
||||
Text("I'm popup!") |
||||
} |
||||
} |
||||
) { |
||||
Text("Open popup") |
||||
} |
||||
} |
||||
} |
||||
} |
||||
``` |
||||
|
||||
![window_keyboard](window_keyboard.gif) |
After Width: | Height: | Size: 486 KiB |
Loading…
Reference in new issue