diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml index 374dbefc60..8dcd20a8f6 100644 --- a/.idea/inspectionProfiles/Project_Default.xml +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -8,5 +8,22 @@ + + + + + + + + + + + + + + + + + - \ No newline at end of file + diff --git a/core/src/com/unciv/ui/components/KeyCharAndCode.kt b/core/src/com/unciv/ui/components/KeyCharAndCode.kt index 069cc0fac3..48e7dd228d 100644 --- a/core/src/com/unciv/ui/components/KeyCharAndCode.kt +++ b/core/src/com/unciv/ui/components/KeyCharAndCode.kt @@ -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) + } } } diff --git a/core/src/com/unciv/ui/components/KeysSelectBox.kt b/core/src/com/unciv/ui/components/KeysSelectBox.kt index e8615339a1..20e91d6dbb 100644 --- a/core/src/com/unciv/ui/components/KeysSelectBox.kt +++ b/core/src/com/unciv/ui/components/KeysSelectBox.kt @@ -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(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?) { diff --git a/core/src/com/unciv/ui/components/extensions/Scene2dExtensions.kt b/core/src/com/unciv/ui/components/extensions/Scene2dExtensions.kt index b5abe9b501..5df0dc13bd 100644 --- a/core/src/com/unciv/ui/components/extensions/Scene2dExtensions.kt +++ b/core/src/com/unciv/ui/components/extensions/Scene2dExtensions.kt @@ -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) + } +}