PadKit
b5d29ffindexedEnables creation of custom virtual gamepads for games and applications. Supports various controls and includes a unique radial layout for organizing components.
Enables creation of custom virtual gamepads for games and applications. Supports various controls and includes a unique radial layout for organizing components.
Surfaced from shared tags and platforms — no rankings paid for.
PadKit is a Compose Multiplatform library that allows developers to create custom virtual gamepads for games and applications. This project is a continuation of the original JamPadCompose by Jam.gg.
The following controls are currently supported:
Controls can be arranged with any composable components, but PadKit also includes the LayoutRadial which places a primary dial in the center, and arranges secondary dials in a circle around it.
Include the library in your project. Check latest tag for version:
implementation("io.github.swordfish90:padkit:x.y.z")
Here's a how you can use PadKit to create a very simple gamepad layout.
Copyright (c) Jam.gg 2024.
Copyright (c) Filippo Scognamiglio 2025.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use except compliance the License.
You may obtain a copy of the License at
http:
Unless applicable law agreed to writing, software
distributed under the License distributed an BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express implied.
See the License the specific language governing permissions
limitations under the License.
fun SampleGamePad() {
PadKit(
hapticFeedbackType = HapticFeedbackType.PRESS,
modifier = Modifier.fillMaxSize(),
onInputStateUpdated = {},
) {
Row(
modifier = Modifier.fillMaxSize(),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.Bottom,
) {
LayoutRadial(
modifier = Modifier.padding(8.dp).weight(1f, fill = false),
primaryDial = {
ControlCross(
modifier = Modifier.fillMaxSize(),
id = Id.DiscreteDirection(0),
)
},
secondaryDials = {
ControlButton(
modifier = Modifier.radialPosition(-60f),
id = Id.Key(0)
)
},
)
LayoutRadial(
modifier = Modifier.padding(8.dp).weight(1f, fill = false),
primaryDial = {
ControlFaceButtons(
modifier = Modifier.fillMaxSize(),
ids =
listOf(1, 2)
.map { Id.Key(it) }
.toPersistentList(),
)
},
secondaryDials = {
ControlButton(
modifier = Modifier.radialPosition(-120f),
id = Id.Key(3)
)
},
)
}
}
}