diff --git a/assets/keylayout/en_us_colemak.key b/assets/keylayout/en_us_colemak.key index 7378cd097..113de0631 100644 --- a/assets/keylayout/en_us_colemak.key +++ b/assets/keylayout/en_us_colemak.key @@ -1,19 +1,19 @@ -{"n":"US Colemak","t":[[""],[undefined], +{"n":"US Colemak","capslock":"back","t":[[""],[undefined], [undefined], [""], [undefined], [""], [""], -["0",")"], -["1","!"], -["2","@"], -["3","#"], -["4","$"], -["5","%"], -["6","^"], -["7","&"], -["8","*"], -["9","("], +["0",")","’","”"], +["1","!","¡","¹"], +["2","@","º","²"], +["3","#","ª","³"], +["4","$","¢","£"], +["5","%","€","¥"], +["6","^","ħ","Ħ"], +["7","&","ð","Ð"], +["8","*","þ","Þ"], +["9","(","‘","“"], ["*"], ["#"], [""], @@ -26,54 +26,54 @@ [""], [""], [""], -["a","A"], -["b","B"], -["c","C"], -["s","S"], -["f","F"], -["t","T"], -["d","D"], -["h","H"], -["u","U"], -["n","N"], -["e","E"], -["i","I"], -["m","M"], -["k","K"], -["y","Y"], -[";",":"], -["q","Q"], -["p","P"], -["r","R"], -["g","G"], -["l","L"], -["v","V"], -["w","W"], -["x","X"], -["j","J"], -["z","Z"], -[",","<"], -[".",">"], +["a","A","á","Á"], +["b","B","\u0306","©"], +["c","C","ç","Ç"], +["s","S","ß","ẞ"], +["f","F","ã","Ã"], +["t","T","\u0301","\u030B"], +["d","D","\u0308","°"], +["h","H","\u030C","±"], +["u","U","ú","Ú"], +["n","N","ñ","Ñ"], +["e","E","é","É"], +["i","I","í","Í"], +["m","M","\u0304","µ"], +["k","K","\u030A","№"], +["y","Y","ü","Ü"], +[";",":","ö","Ö"], +["q","Q","ä","Ä"], +["p","P","ø","Ø"], +["r","R","\u0300","®"], +["g","G","\u0328","¶"], +["l","L","ł","Ł"], +["v","V","œ","Œ"], +["w","W","å","Å"], +["x","X","\u0302","¤"], +["j","J","đ","Đ"], +["z","Z","æ","Æ"], +[",","<","\u0327","·"], +[".",">","\u0307","…"], [""], [""], [""], [""], [""], -[" "], +[" "," ","\u00A0","\u00A0"], [""], [""], [""], ["\n"], ["\x08"], -["`","~"], -["-","_"], -["=","+"], -["[","{"], -["]","}"], -["\\","|"], -["o","O"], -["'",'"'], -["/","?"], +["`","~","\u0303","≈"], +["-","_","–","—"], +["=","+","×","÷"], +["[","{","«","‹"], +["]","}","»","›"], +["\\","|,"~","¦"], +["o","O","ó","Ó"], +["'",'"',"õ","Õ"], +["/","?","¿","§"], [""], [""], [""], diff --git a/assets/keylayout/en_us_colemak_dh.key b/assets/keylayout/en_us_colemak_dh.key index 014b9decb..bb811ea82 100644 --- a/assets/keylayout/en_us_colemak_dh.key +++ b/assets/keylayout/en_us_colemak_dh.key @@ -1,19 +1,19 @@ -{"n":"US Colemak-DH","t":[[""],[undefined], +{"n":"US Colemak-DH","capslock":"back","t":[[""],[undefined], [undefined], [""], [undefined], [""], [""], -["0",")"], -["1","!"], -["2","@"], -["3","#"], -["4","$"], -["5","%"], -["6","^"], -["7","&"], -["8","*"], -["9","("], +["0",")","’","”"], +["1","!","¡","¹"], +["2","@","º","²"], +["3","#","ª","³"], +["4","$","¢","£"], +["5","%","€","¥"], +["6","^","ħ","Ħ"], +["7","&","ð","Ð"], +["8","*","þ","Þ"], +["9","(","‘","“"], ["*"], ["#"], [""], @@ -26,54 +26,54 @@ [""], [""], [""], -["a","A"], -["v","V"], -["c","C"], -["s","S"], -["f","F"], -["t","T"], -["g","G"], -["m","M"], -["u","U"], -["n","N"], -["e","E"], -["i","I"], -["h","H"], -["k","K"], -["y","Y"], -[";",":"], -["q","Q"], -["p","P"], -["r","R"], -["b","B"], -["l","L"], -["d","D"], -["w","W"], -["x","X"], -["j","J"], -["z","Z"], -[",","<"], -[".",">"], +["a","A","á","Á"], +["v","V","œ","Œ"], +["c","C","ç","Ç"], +["s","S","ß","ẞ"], +["f","F","ã","Ã"], +["t","T","\u0301","\u030B"], +["g","G","\u0328","¶"], +["m","M","\u0304","µ"], +["u","U","ú","Ú"], +["n","N","ñ","Ñ"], +["e","E","é","É"], +["i","I","í","Í"], +["h","H","\u030C","±"], +["k","K","\u030A","№"], +["y","Y","ü","Ü"], +[";",":","ö","Ö"], +["q","Q","ä","Ä"], +["p","P","ø","Ø"], +["r","R","\u0300","®"], +["b","B","\u0306","©"], +["l","L","ł","Ł"], +["d","D","\u0308","°"], +["w","W","å","Å"], +["x","X","\u0302","¤"], +["j","J","đ","Đ"], +["z","Z","æ","Æ"], +[",","<","\u0327","·"], +[".",">","\u0307","…"], [""], [""], [""], [""], [""], -[" "], +[" "," ","\u00A0","\u00A0"], [""], [""], [""], ["\n"], ["\x08"], -["`","~"], -["-","_"], -["=","+"], -["[","{"], -["]","}"], -["\\","|"], -["o","O"], -["'",'"'], -["/","?"], +["`","~","\u0303","≈"], +["-","_","–","—"], +["=","+","×","÷"], +["[","{","«","‹"], +["]","}","»","›"], +["\\","|,"~","¦"], +["o","O","ó","Ó"], +["'",'"',"õ","Õ"], +["/","?","¿","§"], [""], [""], [""], diff --git a/assets/keylayout/en_us_qwerty.key b/assets/keylayout/en_us_qwerty.key index f8d98a552..99ec6a0a7 100644 --- a/assets/keylayout/en_us_qwerty.key +++ b/assets/keylayout/en_us_qwerty.key @@ -1,4 +1,4 @@ -{"n":"US Qwerty","t":[[""],[undefined], +{"n":"US Qwerty","capslock":"caps","t":[[""],[undefined], [undefined], [""], [undefined], diff --git a/src/net/torvald/terrarum/gamecontroller/IME.kt b/src/net/torvald/terrarum/gamecontroller/IME.kt index b5f385e6c..c4455ae44 100644 --- a/src/net/torvald/terrarum/gamecontroller/IME.kt +++ b/src/net/torvald/terrarum/gamecontroller/IME.kt @@ -8,9 +8,14 @@ typealias IMEOutput = String data class TerrarumKeyLayout( val name: String, + val capsMode: TerrarumKeyCapsMode, val symbols: Array>? ) +enum class TerrarumKeyCapsMode { + CAPS, SHIFT, BACK +} + data class TerrarumIME( val name: String, val config: TerrarumIMEConf, @@ -101,17 +106,25 @@ object IME { return highLayers.keys.toList() } + private fun String.toCapsMode() = when (this.lowercase()) { + "caps" -> TerrarumKeyCapsMode.CAPS + "shift" -> TerrarumKeyCapsMode.SHIFT + "back" -> TerrarumKeyCapsMode.BACK + else -> throw IllegalArgumentException("Unknown capslock mode: $this") + } + private fun String.toViewCount() = when (this.lowercase()) { "none" -> TerrarumIMEViewCount.NONE "one" -> TerrarumIMEViewCount.ONE "many" -> TerrarumIMEViewCount.MANY - else -> throw IllegalArgumentException(this) + else -> throw IllegalArgumentException("Unknown candidates mode: $this") } private fun parseKeylayoutFile(file: File): TerrarumKeyLayout { val src = file.readText(Charsets.UTF_8) val jsval = context.eval("js", "'use strict';Object.freeze($src)") val name = jsval.getMember("n").asString() + val capsmode = jsval.getMember("capslock").asString().toCapsMode() val out = Array(256) { Array(4) { null } } @@ -131,7 +144,7 @@ object IME { // println("[IME] Test Keymap print for $name:"); for (keycode in 0 until 256) { print("$keycode:\t"); println(out[keycode].joinToString("\t")) } - return TerrarumKeyLayout(name, out) + return TerrarumKeyLayout(name, capsmode, out) } private fun String.toCanditates(): List = diff --git a/src/net/torvald/terrarum/gamecontroller/InputStrober.kt b/src/net/torvald/terrarum/gamecontroller/InputStrober.kt index 783860920..6cda59b4f 100644 --- a/src/net/torvald/terrarum/gamecontroller/InputStrober.kt +++ b/src/net/torvald/terrarum/gamecontroller/InputStrober.kt @@ -57,14 +57,21 @@ object InputStrober { repeatCount += 1 val shiftin = keys.contains(Input.Keys.SHIFT_LEFT) || keys.contains(Input.Keys.SHIFT_RIGHT) + val altgrin = keys.contains(Input.Keys.ALT_RIGHT) val keysym0 = keysToStr(keymap, keys) val newKeysym0 = keysToStr(keymap, keyDiff) - val keysym = if (keysym0 == null) null - else if (shiftin && keysym0[1]?.isNotBlank() == true) keysym0[1] - else keysym0[0] - val newKeysym = if (newKeysym0 == null) null - else if (shiftin && newKeysym0[1]?.isNotBlank() == true) newKeysym0[1] - else newKeysym0[0] + val keysym = + if (keysym0 == null) null + else if (shiftin && altgrin && keysym0[3]?.isNotBlank() == true) keysym0[3] + else if (altgrin && keysym0[2]?.isNotBlank() == true) keysym0[2] + else if (shiftin && keysym0[1]?.isNotBlank() == true) keysym0[1] + else keysym0[0] + val newKeysym = + if (newKeysym0 == null) null + else if (shiftin && altgrin && newKeysym0[3]?.isNotBlank() == true) newKeysym0[3] + else if (altgrin && newKeysym0[2]?.isNotBlank() == true) newKeysym0[2] + else if (shiftin && newKeysym0[1]?.isNotBlank() == true) newKeysym0[1] + else newKeysym0[0] val headKeyCode = if (keyDiff.size < 1) keys[0] else keyDiff[0] diff --git a/src/net/torvald/terrarum/ui/UIItemTextLineInput.kt b/src/net/torvald/terrarum/ui/UIItemTextLineInput.kt index 8262815cb..4927d6ac5 100644 --- a/src/net/torvald/terrarum/ui/UIItemTextLineInput.kt +++ b/src/net/torvald/terrarum/ui/UIItemTextLineInput.kt @@ -170,6 +170,7 @@ class UIItemTextLineInput( fboUpdateLatch = true forceLitCursor() val ime = getIME() + val lowLayer = IME.getLowLayerByName(App.getConfigString("basekeyboardlayout")) if (keycodes.contains(App.getConfigInt("control_key_toggleime")) && repeatCount == 1) { toggleIME() @@ -182,7 +183,7 @@ class UIItemTextLineInput( endComposing() copyToClipboard() } - else if (keycodes.contains(Input.Keys.BACKSPACE)) { + else if (keycodes.contains(Input.Keys.BACKSPACE) || (keycodes.contains(Input.Keys.CAPS_LOCK) && lowLayer.capsMode == TerrarumKeyCapsMode.BACK)) { if (ime != null && ime.composing()) { candidates = ime.backspace().map { CodepointSequence(it.toCodePoints()) } }