mirror of
https://github.com/yairm210/Unciv.git
synced 2025-07-07 00:41:39 +07:00
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:
19
.idea/inspectionProfiles/Project_Default.xml
generated
19
.idea/inspectionProfiles/Project_Default.xml
generated
@ -8,5 +8,22 @@
|
|||||||
<constraint name="Params" minCount="0" maxCount="2147483647" within="" contains="" />
|
<constraint name="Params" minCount="0" maxCount="2147483647" within="" contains="" />
|
||||||
</searchConfiguration>
|
</searchConfiguration>
|
||||||
</inspection_tool>
|
</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>
|
</profile>
|
||||||
</component>
|
</component>
|
||||||
|
@ -3,6 +3,7 @@ package com.unciv.ui.components
|
|||||||
import com.badlogic.gdx.Input
|
import com.badlogic.gdx.Input
|
||||||
import com.badlogic.gdx.utils.Json
|
import com.badlogic.gdx.utils.Json
|
||||||
import com.badlogic.gdx.utils.JsonValue
|
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 */
|
/** express keys that only have a keyCode like F1 */
|
||||||
constructor(code: Int): this(Char.MIN_VALUE, code)
|
constructor(code: Int): this(Char.MIN_VALUE, code)
|
||||||
|
|
||||||
|
//** debug helper, but also used for tooltips */
|
||||||
override fun toString(): String {
|
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 {
|
return when {
|
||||||
char == Char.MIN_VALUE -> fixedKeysToString(code)
|
char == Char.MIN_VALUE -> GdxKeyCodeFixes.toString(code)
|
||||||
this == ESC -> "ESC"
|
this == ESC -> "ESC"
|
||||||
char < ' ' -> "Ctrl-" + (char.toCode() + 64).makeChar()
|
char < ' ' -> "Ctrl-" + (char.toCode() + 64).makeChar()
|
||||||
else -> "\"$char\""
|
else -> "\"$char\""
|
||||||
@ -56,7 +52,7 @@ data class KeyCharAndCode(val char: Char, val code: Int) {
|
|||||||
/** Automatically assigned for [RETURN] */
|
/** Automatically assigned for [RETURN] */
|
||||||
val NUMPAD_ENTER = KeyCharAndCode(Input.Keys.NUMPAD_ENTER)
|
val NUMPAD_ENTER = KeyCharAndCode(Input.Keys.NUMPAD_ENTER)
|
||||||
val SPACE = KeyCharAndCode(Input.Keys.SPACE)
|
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)
|
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 */
|
/** 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)
|
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 */
|
/** mini-factory for control codes from keyCodes */
|
||||||
fun ctrlFromCode(keyCode: Int): KeyCharAndCode {
|
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)
|
if (name.length != 1 || !name[0].isLetter()) return KeyCharAndCode(Char.MIN_VALUE, keyCode)
|
||||||
return ctrl(name[0])
|
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 */
|
/** factory maps a Char to a keyCode if possible, returns a Char-based instance otherwise */
|
||||||
fun mapChar(char: Char): KeyCharAndCode {
|
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)
|
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 == 3 && text[0] == '"' && text[2] == '"' -> KeyCharAndCode(text[1])
|
||||||
text.length == 6 && text.startsWith("Ctrl-") -> ctrl(text[5])
|
text.length == 6 && text.startsWith("Ctrl-") -> ctrl(text[5])
|
||||||
text == "ESC" -> ESC
|
text == "ESC" -> ESC
|
||||||
text == "Backspace" -> KeyCharAndCode(Input.Keys.BACKSPACE)
|
else -> {
|
||||||
text == "Del" -> DEL
|
val code = GdxKeyCodeFixes.valueOf(text)
|
||||||
Input.Keys.valueOf(text) != -1 -> KeyCharAndCode(Input.Keys.valueOf(text))
|
if (code == -1) UNKNOWN else KeyCharAndCode(code)
|
||||||
else -> UNKNOWN
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,9 @@ import com.badlogic.gdx.graphics.Color
|
|||||||
import com.badlogic.gdx.scenes.scene2d.Actor
|
import com.badlogic.gdx.scenes.scene2d.Actor
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.SelectBox
|
import com.badlogic.gdx.scenes.scene2d.ui.SelectBox
|
||||||
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener
|
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener
|
||||||
|
import com.badlogic.gdx.utils.Align
|
||||||
import com.unciv.models.translations.tr
|
import com.unciv.models.translations.tr
|
||||||
|
import com.unciv.ui.components.extensions.GdxKeyCodeFixes
|
||||||
import com.unciv.ui.screens.basescreen.BaseScreen
|
import com.unciv.ui.screens.basescreen.BaseScreen
|
||||||
import com.badlogic.gdx.utils.Array as GdxArray
|
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...
|
// but it's private and only used for valueOf() - So we do the same here...
|
||||||
private val keyCodeMap = LinkedHashMap<String, Int>(200).apply {
|
private val keyCodeMap = LinkedHashMap<String, Int>(200).apply {
|
||||||
for (code in 0..Input.Keys.MAX_KEYCODE) {
|
for (code in 0..Input.Keys.MAX_KEYCODE) {
|
||||||
val name = Input.Keys.toString(code) ?: continue
|
val name = GdxKeyCodeFixes.toString(code) ?: continue
|
||||||
put(name, code)
|
put(name, code)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -108,6 +110,8 @@ class KeysSelectBox(
|
|||||||
setSelected(default)
|
setSelected(default)
|
||||||
|
|
||||||
maxListCount = 12 // or else the dropdown will fill as much vertical space as it can, including upwards
|
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() {
|
addListener(object : ChangeListener() {
|
||||||
override fun changed(event: ChangeEvent?, actor: Actor?) {
|
override fun changed(event: ChangeEvent?, actor: Actor?) {
|
||||||
|
@ -552,3 +552,35 @@ fun Group.addToCenter(actor: Actor) {
|
|||||||
addActor(actor)
|
addActor(actor)
|
||||||
actor.center(this)
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user