Keyboard Bindings small fix : (#8929)

* Del and Backspace mappable
* Inspection warns about direct uses of buggy functions
* Keybinding SelectBox centers
This commit is contained in:
SomeTroglodyte 2023-03-16 21:40:45 +01:00 committed by GitHub
parent ba63f9a62b
commit c5993e0392
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 65 additions and 16 deletions

View File

@ -8,5 +8,22 @@
<constraint name="Params" minCount="0" maxCount="2147483647" within="" contains="" />
</searchConfiguration>
</inspection_tool>
<inspection_tool class="SSBasedInspection" enabled="true" level="WARNING" enabled_by_default="true">
<searchConfiguration name="Gdx Input.Keys toString" description="Gdx Input.Keys has a buggy definition for DEL that makes the Del and Backspace keys misbehave. See KeyCharAndCode.toString." suppressId="GDX_KEYS_BUG" problemDescriptor="Gdx bug - Wrong results for BACKSPACE DEL and FORWARD_DEL." text="Input.Keys.toString($Params$)" recursive="true" caseInsensitive="true" type="Kotlin" pattern_context="default">
<constraint name="__context__" within="" contains="" />
<constraint name="Params" minCount="0" maxCount="2147483647" within="" contains="" />
</searchConfiguration>
</inspection_tool>
<inspection_tool class="SSBasedInspection" enabled="true" level="WARNING" enabled_by_default="true">
<searchConfiguration name="Gdx Input.Keys valueOf" description="Gdx Input.Keys has a buggy definition for DEL that makes the Del and Backspace keys misbehave. See GdxKeyCodeFixes." suppressId="GDX_KEYS_BUG" problemDescriptor="Gdx bug - Wrong results for BACKSPACE DEL and FORWARD_DEL." text="Input.Keys.valueOf($Params$)" recursive="true" caseInsensitive="true" type="Kotlin" pattern_context="default">
<constraint name="__context__" within="" contains="" />
<constraint name="Params" minCount="0" maxCount="2147483647" within="" contains="" />
</searchConfiguration>
</inspection_tool>
<inspection_tool class="SSBasedInspection" enabled="true" level="WARNING" enabled_by_default="true">
<searchConfiguration name="Gdx Input.Keys DEL" description="Gdx Input.Keys has a buggy definition for DEL that makes the Del and Backspace keys misbehave. See GdxKeyCodeFixes." suppressId="GDX_KEYS_BUG" problemDescriptor="Gdx bug - Wrong results for BACKSPACE DEL and FORWARD_DEL." text="Input.Keys.DEL" recursive="false" caseInsensitive="true" type="Kotlin" pattern_context="default">
<constraint name="__context__" within="" contains="" />
</searchConfiguration>
</inspection_tool>
</profile>
</component>
</component>

View File

@ -3,6 +3,7 @@ package com.unciv.ui.components
import com.badlogic.gdx.Input
import com.badlogic.gdx.utils.Json
import com.badlogic.gdx.utils.JsonValue
import com.unciv.ui.components.extensions.GdxKeyCodeFixes
/*
@ -30,15 +31,10 @@ data class KeyCharAndCode(val char: Char, val code: Int) {
/** express keys that only have a keyCode like F1 */
constructor(code: Int): this(Char.MIN_VALUE, code)
//** debug helper, but also used for tooltips */
override fun toString(): String {
// debug helper, but also used for tooltips
fun fixedKeysToString(code: Int) = when (code) {
Input.Keys.BACKSPACE -> "Backspace" // Gdx displaying this as "Delete" is Bullshit!
Input.Keys.FORWARD_DEL -> "Del" // Likewise
else -> Input.Keys.toString(code)
}
return when {
char == Char.MIN_VALUE -> fixedKeysToString(code)
char == Char.MIN_VALUE -> GdxKeyCodeFixes.toString(code)
this == ESC -> "ESC"
char < ' ' -> "Ctrl-" + (char.toCode() + 64).makeChar()
else -> "\"$char\""
@ -56,7 +52,7 @@ data class KeyCharAndCode(val char: Char, val code: Int) {
/** Automatically assigned for [RETURN] */
val NUMPAD_ENTER = KeyCharAndCode(Input.Keys.NUMPAD_ENTER)
val SPACE = KeyCharAndCode(Input.Keys.SPACE)
val DEL = KeyCharAndCode(Input.Keys.FORWARD_DEL) // Gdx "DEL" is just plain wrong!
val DEL = KeyCharAndCode(GdxKeyCodeFixes.DEL)
val TAB = KeyCharAndCode(Input.Keys.TAB)
/** Guaranteed to be ignored by [KeyShortcutDispatcher] and never to be generated for an actual event, used as fallback to ensure no action is taken */
val UNKNOWN = KeyCharAndCode(Input.Keys.UNKNOWN)
@ -69,7 +65,7 @@ data class KeyCharAndCode(val char: Char, val code: Int) {
/** mini-factory for control codes from keyCodes */
fun ctrlFromCode(keyCode: Int): KeyCharAndCode {
val name = Input.Keys.toString(keyCode)
val name = GdxKeyCodeFixes.toString(keyCode)
if (name.length != 1 || !name[0].isLetter()) return KeyCharAndCode(Char.MIN_VALUE, keyCode)
return ctrl(name[0])
}
@ -79,7 +75,7 @@ data class KeyCharAndCode(val char: Char, val code: Int) {
/** factory maps a Char to a keyCode if possible, returns a Char-based instance otherwise */
fun mapChar(char: Char): KeyCharAndCode {
val code = Input.Keys.valueOf(char.uppercaseChar().toString())
val code = GdxKeyCodeFixes.valueOf(char.uppercaseChar().toString())
return if (code == -1) KeyCharAndCode(char,0) else KeyCharAndCode(Char.MIN_VALUE, code)
}
@ -88,10 +84,10 @@ data class KeyCharAndCode(val char: Char, val code: Int) {
text.length == 3 && text[0] == '"' && text[2] == '"' -> KeyCharAndCode(text[1])
text.length == 6 && text.startsWith("Ctrl-") -> ctrl(text[5])
text == "ESC" -> ESC
text == "Backspace" -> KeyCharAndCode(Input.Keys.BACKSPACE)
text == "Del" -> DEL
Input.Keys.valueOf(text) != -1 -> KeyCharAndCode(Input.Keys.valueOf(text))
else -> UNKNOWN
else -> {
val code = GdxKeyCodeFixes.valueOf(text)
if (code == -1) UNKNOWN else KeyCharAndCode(code)
}
}
}

View File

@ -5,7 +5,9 @@ import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.scenes.scene2d.Actor
import com.badlogic.gdx.scenes.scene2d.ui.SelectBox
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener
import com.badlogic.gdx.utils.Align
import com.unciv.models.translations.tr
import com.unciv.ui.components.extensions.GdxKeyCodeFixes
import com.unciv.ui.screens.basescreen.BaseScreen
import com.badlogic.gdx.utils.Array as GdxArray
@ -44,7 +46,7 @@ class KeysSelectBox(
// but it's private and only used for valueOf() - So we do the same here...
private val keyCodeMap = LinkedHashMap<String, Int>(200).apply {
for (code in 0..Input.Keys.MAX_KEYCODE) {
val name = Input.Keys.toString(code) ?: continue
val name = GdxKeyCodeFixes.toString(code) ?: continue
put(name, code)
}
}
@ -108,6 +110,8 @@ class KeysSelectBox(
setSelected(default)
maxListCount = 12 // or else the dropdown will fill as much vertical space as it can, including upwards
list.alignment = Align.center // default left is ugly, especially when a Mod Skin removes padding
setAlignment(Align.center)
addListener(object : ChangeListener() {
override fun changed(event: ChangeEvent?, actor: Actor?) {

View File

@ -552,3 +552,35 @@ fun Group.addToCenter(actor: Actor) {
addActor(actor)
actor.center(this)
}
/**
* These methods deal with a mistake in Gdx.Input.Keys, where DEL is defined as the keycode actually
* produced by the physical Backspace key, while the physical Del key fires the keycode Gdx lists as
* FORWARD_DEL. Neither valueOf("Del") and valueOf("Backspace") work as expected.
*
* | Identifier | KeyCode | Physical key | toString() | valueOf(name.TitleCase) | valueOf(toString) |
* | ---- |:----:|:----:|:----:|:----:|:----:|
* | DEL | 67 | Backspace | Delete | -1 | 67 |
* | BACKSPACE | 67 | Backspace | Delete | -1 | 67 |
* | FORWARD_DEL | 112 | Del | Forward Delete | -1 | 112 |
*
* This acts as proxy, you replace [Input.Keys] by [GdxKeyCodeFixes] and get sensible [DEL], [toString] and [valueOf].
*/
@Suppress("GDX_KEYS_BUG", "MemberVisibilityCanBePrivate")
object GdxKeyCodeFixes {
const val DEL = Input.Keys.FORWARD_DEL
const val BACKSPACE = Input.Keys.BACKSPACE
fun toString(keyCode: Int): String = when(keyCode) {
DEL -> "Del"
BACKSPACE -> "Backspace"
else -> Input.Keys.toString(keyCode)
}
fun valueOf(name: String): Int = when (name) {
"Del" -> DEL
"Backspace" -> BACKSPACE
else -> Input.Keys.valueOf(name)
}
}