Safe progress
This commit is contained in:
parent
a356774001
commit
113a3b994d
@ -320,6 +320,7 @@ class WKT9: InputMethodService() {
|
|||||||
if (res.startComposing) markComposingRegion()
|
if (res.startComposing) markComposingRegion()
|
||||||
if (!res.codeWord.isNullOrEmpty()) onCodeWordUpdate(res.codeWord, res.timeout)
|
if (!res.codeWord.isNullOrEmpty()) onCodeWordUpdate(res.codeWord, res.timeout)
|
||||||
if (!res.candidates.isNullOrEmpty()) onCandidates(res.candidates, res.timeout)
|
if (!res.candidates.isNullOrEmpty()) onCandidates(res.candidates, res.timeout)
|
||||||
|
if (!res.commit.isNullOrEmpty()) onCommit(res.commit)
|
||||||
if (res.deleteBeforeCursor > 0 || res.deleteAfterCursor > 0) onDelete(res.deleteBeforeCursor, res.deleteAfterCursor)
|
if (res.deleteBeforeCursor > 0 || res.deleteAfterCursor > 0) onDelete(res.deleteBeforeCursor, res.deleteAfterCursor)
|
||||||
if (res.goHome) goHome()
|
if (res.goHome) goHome()
|
||||||
if (res.left) onLeft()
|
if (res.left) onLeft()
|
||||||
@ -405,6 +406,10 @@ class WKT9: InputMethodService() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun onCommit(text: String) {
|
||||||
|
commitText(text, cursorPosition, cursorPosition)
|
||||||
|
}
|
||||||
|
|
||||||
private fun onDelete(beforeCursor: Int, afterCursor: Int) {
|
private fun onDelete(beforeCursor: Int, afterCursor: Int) {
|
||||||
clearCandidates()
|
clearCandidates()
|
||||||
deleteText(beforeCursor, afterCursor)
|
deleteText(beforeCursor, afterCursor)
|
||||||
@ -444,7 +449,7 @@ class WKT9: InputMethodService() {
|
|||||||
recorder = MediaRecorder(this).also {
|
recorder = MediaRecorder(this).also {
|
||||||
recording = File.createTempFile("recording.3gp", null, cacheDir)
|
recording = File.createTempFile("recording.3gp", null, cacheDir)
|
||||||
|
|
||||||
it.setAudioSource(MediaRecorder.AudioSource.VOICE_RECOGNITION)
|
it.setAudioSource(MediaRecorder.AudioSource.MIC)
|
||||||
it.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP)
|
it.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP)
|
||||||
it.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB)
|
it.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB)
|
||||||
it.setOutputFile(recording)
|
it.setOutputFile(recording)
|
||||||
|
@ -28,9 +28,7 @@ class AlphaInputMode: InputMode {
|
|||||||
|
|
||||||
return when(keyCommandResolver.getCommand(key)) {
|
return when(keyCommandResolver.getCommand(key)) {
|
||||||
Command.BACK -> KeyEventResult(consumed = false)
|
Command.BACK -> KeyEventResult(consumed = false)
|
||||||
Command.CHARACTER -> composeCharacter(key, composing)
|
|
||||||
Command.DELETE -> deleteCharacter(composing)
|
Command.DELETE -> deleteCharacter(composing)
|
||||||
Command.SPACE -> finalizeWordOrSentence(composing)
|
|
||||||
Command.LEFT -> navigateLeft()
|
Command.LEFT -> navigateLeft()
|
||||||
Command.RIGHT -> navigateRight()
|
Command.RIGHT -> navigateRight()
|
||||||
Command.SELECT -> focus()
|
Command.SELECT -> focus()
|
||||||
@ -41,6 +39,7 @@ class AlphaInputMode: InputMode {
|
|||||||
override fun onKeyLongDown(key: Key, composing: Boolean): KeyEventResult {
|
override fun onKeyLongDown(key: Key, composing: Boolean): KeyEventResult {
|
||||||
return when(keyCommandResolver.getCommand(key, true)) {
|
return when(keyCommandResolver.getCommand(key, true)) {
|
||||||
Command.RECORD -> record(composing)
|
Command.RECORD -> record(composing)
|
||||||
|
Command.NUMBER -> commitNumber(key, composing)
|
||||||
Command.SWITCH_MODE -> switchMode(composing)
|
Command.SWITCH_MODE -> switchMode(composing)
|
||||||
else -> KeyEventResult(true)
|
else -> KeyEventResult(true)
|
||||||
}
|
}
|
||||||
@ -57,7 +56,9 @@ class AlphaInputMode: InputMode {
|
|||||||
override fun afterKeyDown(key: Key, composing: Boolean): KeyEventResult {
|
override fun afterKeyDown(key: Key, composing: Boolean): KeyEventResult {
|
||||||
return when(keyCommandResolver.getCommand(key, after = true)) {
|
return when(keyCommandResolver.getCommand(key, after = true)) {
|
||||||
Command.BACK -> goBack(composing)
|
Command.BACK -> goBack(composing)
|
||||||
|
Command.CHARACTER -> composeCharacter(key, composing)
|
||||||
Command.SHIFT_MODE -> shiftMode()
|
Command.SHIFT_MODE -> shiftMode()
|
||||||
|
Command.SPACE -> finalizeWordOrSentence(composing)
|
||||||
else -> KeyEventResult()
|
else -> KeyEventResult()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -76,6 +77,16 @@ class AlphaInputMode: InputMode {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun commitNumber(key: Key, composing: Boolean): KeyEventResult {
|
||||||
|
val code = KeyLayout.numeric[key] ?: return KeyEventResult(true)
|
||||||
|
|
||||||
|
return KeyEventResult(
|
||||||
|
consumed = true,
|
||||||
|
finishComposing = composing,
|
||||||
|
commit = code.toString()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private fun composeCharacter(key: Key, composing: Boolean): KeyEventResult {
|
private fun composeCharacter(key: Key, composing: Boolean): KeyEventResult {
|
||||||
if (composing && !newKey) return navigateRight()
|
if (composing && !newKey) return navigateRight()
|
||||||
|
|
||||||
|
@ -12,6 +12,20 @@ class NumericInputMode: InputMode {
|
|||||||
private val parentKeyCommandResolver: KeyCommandResolver = KeyCommandResolver.getBasic()
|
private val parentKeyCommandResolver: KeyCommandResolver = KeyCommandResolver.getBasic()
|
||||||
private val keyCommandResolver: KeyCommandResolver = KeyCommandResolver(
|
private val keyCommandResolver: KeyCommandResolver = KeyCommandResolver(
|
||||||
parent = parentKeyCommandResolver,
|
parent = parentKeyCommandResolver,
|
||||||
|
|
||||||
|
onLong = HashMap(mapOf(
|
||||||
|
Key.N0 to Command.SPACE,
|
||||||
|
Key.N1 to Command.CHARACTER,
|
||||||
|
Key.N2 to Command.CHARACTER,
|
||||||
|
Key.N3 to Command.CHARACTER,
|
||||||
|
Key.N4 to Command.CHARACTER,
|
||||||
|
Key.N5 to Command.CHARACTER,
|
||||||
|
Key.N6 to Command.CHARACTER,
|
||||||
|
Key.N7 to Command.CHARACTER,
|
||||||
|
Key.N8 to Command.CHARACTER,
|
||||||
|
Key.N9 to Command.CHARACTER
|
||||||
|
)),
|
||||||
|
|
||||||
afterShort = HashMap(mapOf(
|
afterShort = HashMap(mapOf(
|
||||||
Key.N0 to Command.NUMBER,
|
Key.N0 to Command.NUMBER,
|
||||||
Key.N1 to Command.NUMBER,
|
Key.N1 to Command.NUMBER,
|
||||||
@ -52,6 +66,8 @@ class NumericInputMode: InputMode {
|
|||||||
|
|
||||||
override fun onKeyLongDown(key: Key, composing: Boolean): KeyEventResult {
|
override fun onKeyLongDown(key: Key, composing: Boolean): KeyEventResult {
|
||||||
return when(keyCommandResolver.getCommand(key, true)) {
|
return when(keyCommandResolver.getCommand(key, true)) {
|
||||||
|
Command.CHARACTER -> composeCharacter(key, composing)
|
||||||
|
Command.SPACE -> insertSpace(composing)
|
||||||
Command.SWITCH_MODE -> switchMode(composing)
|
Command.SWITCH_MODE -> switchMode(composing)
|
||||||
else -> KeyEventResult(true)
|
else -> KeyEventResult(true)
|
||||||
}
|
}
|
||||||
@ -86,10 +102,8 @@ class NumericInputMode: InputMode {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun composeNumber(key: Key, composing: Boolean): KeyEventResult {
|
private fun composeCharacter(key: Key, composing: Boolean): KeyEventResult {
|
||||||
if (composing && !newKey) return navigateRight()
|
val layout = KeyLayout.en_US[key] ?: return KeyEventResult(true)
|
||||||
|
|
||||||
val layout = KeyLayout.numeric[key] ?: return KeyEventResult(true)
|
|
||||||
val candidates = layout.map { it.toString() }
|
val candidates = layout.map { it.toString() }
|
||||||
|
|
||||||
return KeyEventResult(
|
return KeyEventResult(
|
||||||
@ -97,14 +111,17 @@ class NumericInputMode: InputMode {
|
|||||||
finishComposing = composing,
|
finishComposing = composing,
|
||||||
startComposing = true,
|
startComposing = true,
|
||||||
candidates = candidates,
|
candidates = candidates,
|
||||||
timeout = 400
|
timeout = 1200
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun focus(): KeyEventResult {
|
private fun composeNumber(key: Key, composing: Boolean): KeyEventResult {
|
||||||
|
val code = KeyLayout.numeric[key] ?: return KeyEventResult(true)
|
||||||
|
|
||||||
return KeyEventResult(
|
return KeyEventResult(
|
||||||
consumed = true,
|
consumed = true,
|
||||||
focus = true
|
finishComposing = composing,
|
||||||
|
commit = code.toString()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,6 +142,14 @@ class NumericInputMode: InputMode {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun insertSpace(composing: Boolean): KeyEventResult {
|
||||||
|
return KeyEventResult(
|
||||||
|
consumed = true,
|
||||||
|
finishComposing = composing,
|
||||||
|
commit = " "
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private fun keyStats(key: Key) {
|
private fun keyStats(key: Key) {
|
||||||
when (key != lastKey) {
|
when (key != lastKey) {
|
||||||
true -> {
|
true -> {
|
||||||
|
@ -5,6 +5,7 @@ import net.mezimmah.wkt9.keypad.Command
|
|||||||
import net.mezimmah.wkt9.keypad.Key
|
import net.mezimmah.wkt9.keypad.Key
|
||||||
import net.mezimmah.wkt9.keypad.KeyCommandResolver
|
import net.mezimmah.wkt9.keypad.KeyCommandResolver
|
||||||
import net.mezimmah.wkt9.keypad.KeyEventResult
|
import net.mezimmah.wkt9.keypad.KeyEventResult
|
||||||
|
import net.mezimmah.wkt9.keypad.KeyLayout
|
||||||
import java.lang.StringBuilder
|
import java.lang.StringBuilder
|
||||||
|
|
||||||
class WordInputMode: InputMode {
|
class WordInputMode: InputMode {
|
||||||
@ -29,9 +30,7 @@ class WordInputMode: InputMode {
|
|||||||
|
|
||||||
return when(keyCommandResolver.getCommand(key)) {
|
return when(keyCommandResolver.getCommand(key)) {
|
||||||
Command.BACK -> KeyEventResult(consumed = false)
|
Command.BACK -> KeyEventResult(consumed = false)
|
||||||
Command.CHARACTER -> buildCodeWord(key)
|
|
||||||
Command.DELETE -> deleteCharacter(0, composing)
|
Command.DELETE -> deleteCharacter(0, composing)
|
||||||
Command.SPACE -> finalizeWordOrSentence(composing)
|
|
||||||
Command.LEFT -> navigateLeft()
|
Command.LEFT -> navigateLeft()
|
||||||
Command.RIGHT -> navigateRight()
|
Command.RIGHT -> navigateRight()
|
||||||
Command.SELECT -> focus()
|
Command.SELECT -> focus()
|
||||||
@ -43,6 +42,7 @@ class WordInputMode: InputMode {
|
|||||||
return when(keyCommandResolver.getCommand(key, true)) {
|
return when(keyCommandResolver.getCommand(key, true)) {
|
||||||
Command.RECORD -> record(composing)
|
Command.RECORD -> record(composing)
|
||||||
Command.SWITCH_MODE -> switchMode(composing)
|
Command.SWITCH_MODE -> switchMode(composing)
|
||||||
|
Command.NUMBER -> commitNumber(key, composing)
|
||||||
else -> KeyEventResult(true)
|
else -> KeyEventResult(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -58,7 +58,9 @@ class WordInputMode: InputMode {
|
|||||||
override fun afterKeyDown(key: Key, composing: Boolean): KeyEventResult {
|
override fun afterKeyDown(key: Key, composing: Boolean): KeyEventResult {
|
||||||
return when(keyCommandResolver.getCommand(key, after = true)) {
|
return when(keyCommandResolver.getCommand(key, after = true)) {
|
||||||
Command.BACK -> goBack(composing)
|
Command.BACK -> goBack(composing)
|
||||||
|
Command.CHARACTER -> buildCodeWord(key)
|
||||||
Command.SHIFT_MODE -> shiftMode(composing)
|
Command.SHIFT_MODE -> shiftMode(composing)
|
||||||
|
Command.SPACE -> finalizeWordOrSentence(composing)
|
||||||
else -> KeyEventResult()
|
else -> KeyEventResult()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -72,8 +74,9 @@ class WordInputMode: InputMode {
|
|||||||
|
|
||||||
private fun buildCodeWord(key: Key): KeyEventResult {
|
private fun buildCodeWord(key: Key): KeyEventResult {
|
||||||
val startComposing = codeWord.isEmpty()
|
val startComposing = codeWord.isEmpty()
|
||||||
|
val code = KeyLayout.numeric[key]
|
||||||
|
|
||||||
codeWord.append(key.code)
|
codeWord.append(code)
|
||||||
|
|
||||||
return KeyEventResult(
|
return KeyEventResult(
|
||||||
codeWord = codeWord,
|
codeWord = codeWord,
|
||||||
@ -82,6 +85,16 @@ class WordInputMode: InputMode {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun commitNumber(key: Key, composing: Boolean): KeyEventResult {
|
||||||
|
val number = KeyLayout.numeric[key] ?: return KeyEventResult(true)
|
||||||
|
|
||||||
|
return KeyEventResult(
|
||||||
|
consumed = true,
|
||||||
|
finishComposing = composing,
|
||||||
|
commit = number.toString()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private fun deleteCharacter(repeat: Int = 0, composing: Boolean): KeyEventResult {
|
private fun deleteCharacter(repeat: Int = 0, composing: Boolean): KeyEventResult {
|
||||||
if (repeat == 0) codeWord.clear()
|
if (repeat == 0) codeWord.clear()
|
||||||
|
|
||||||
|
@ -6,7 +6,6 @@ enum class Command {
|
|||||||
SPACE,
|
SPACE,
|
||||||
NEWLINE,
|
NEWLINE,
|
||||||
DELETE,
|
DELETE,
|
||||||
CYCLE_CANDIDATES,
|
|
||||||
SELECT,
|
SELECT,
|
||||||
SHIFT_MODE,
|
SHIFT_MODE,
|
||||||
SWITCH_MODE,
|
SWITCH_MODE,
|
||||||
@ -16,5 +15,6 @@ enum class Command {
|
|||||||
RECORD,
|
RECORD,
|
||||||
TRANSCRIBE,
|
TRANSCRIBE,
|
||||||
BACK,
|
BACK,
|
||||||
HOME
|
HOME,
|
||||||
|
FN
|
||||||
}
|
}
|
@ -1,23 +1,24 @@
|
|||||||
package net.mezimmah.wkt9.keypad
|
package net.mezimmah.wkt9.keypad
|
||||||
|
|
||||||
enum class Key(val code: Char) {
|
enum class Key() {
|
||||||
N0('0'),
|
N0,
|
||||||
N1('1'),
|
N1,
|
||||||
N2('2'),
|
N2,
|
||||||
N3('3'),
|
N3,
|
||||||
N4('4'),
|
N4,
|
||||||
N5('5'),
|
N5,
|
||||||
N6('6'),
|
N6,
|
||||||
N7('7'),
|
N7,
|
||||||
N8('8'),
|
N8,
|
||||||
N9('9'),
|
N9,
|
||||||
STAR('*'),
|
FN,
|
||||||
POUND('#'),
|
STAR,
|
||||||
UP('a'),
|
POUND,
|
||||||
DOWN('b'),
|
UP,
|
||||||
LEFT('c'),
|
DOWN,
|
||||||
RIGHT('d'),
|
LEFT,
|
||||||
SELECT('e'),
|
RIGHT,
|
||||||
DELETE('f'),
|
SELECT,
|
||||||
BACK('g'),
|
DELETE,
|
||||||
|
BACK,
|
||||||
}
|
}
|
@ -25,7 +25,7 @@ class KeyCodeMapping(
|
|||||||
16 to Key.N9,
|
16 to Key.N9,
|
||||||
17 to Key.STAR,
|
17 to Key.STAR,
|
||||||
18 to Key.POUND,
|
18 to Key.POUND,
|
||||||
82 to Key.DELETE,
|
82 to Key.FN,
|
||||||
19 to Key.UP,
|
19 to Key.UP,
|
||||||
20 to Key.DOWN,
|
20 to Key.DOWN,
|
||||||
21 to Key.LEFT,
|
21 to Key.LEFT,
|
||||||
|
@ -28,17 +28,6 @@ class KeyCommandResolver (
|
|||||||
return KeyCommandResolver(
|
return KeyCommandResolver(
|
||||||
onShort = HashMap(mapOf(
|
onShort = HashMap(mapOf(
|
||||||
Key.BACK to Command.BACK,
|
Key.BACK to Command.BACK,
|
||||||
Key.N0 to Command.SPACE,
|
|
||||||
|
|
||||||
Key.N1 to Command.CHARACTER,
|
|
||||||
Key.N2 to Command.CHARACTER,
|
|
||||||
Key.N3 to Command.CHARACTER,
|
|
||||||
Key.N4 to Command.CHARACTER,
|
|
||||||
Key.N5 to Command.CHARACTER,
|
|
||||||
Key.N6 to Command.CHARACTER,
|
|
||||||
Key.N7 to Command.CHARACTER,
|
|
||||||
Key.N8 to Command.CHARACTER,
|
|
||||||
Key.N9 to Command.CHARACTER,
|
|
||||||
|
|
||||||
Key.LEFT to Command.LEFT,
|
Key.LEFT to Command.LEFT,
|
||||||
Key.RIGHT to Command.RIGHT,
|
Key.RIGHT to Command.RIGHT,
|
||||||
@ -46,7 +35,6 @@ class KeyCommandResolver (
|
|||||||
Key.DOWN to Command.NAVIGATE,
|
Key.DOWN to Command.NAVIGATE,
|
||||||
|
|
||||||
Key.STAR to Command.DELETE,
|
Key.STAR to Command.DELETE,
|
||||||
Key.DELETE to Command.DELETE,
|
|
||||||
Key.SELECT to Command.SELECT
|
Key.SELECT to Command.SELECT
|
||||||
)),
|
)),
|
||||||
|
|
||||||
@ -67,6 +55,18 @@ class KeyCommandResolver (
|
|||||||
)),
|
)),
|
||||||
|
|
||||||
afterShort = HashMap(mapOf(
|
afterShort = HashMap(mapOf(
|
||||||
|
Key.N0 to Command.SPACE,
|
||||||
|
|
||||||
|
Key.N1 to Command.CHARACTER,
|
||||||
|
Key.N2 to Command.CHARACTER,
|
||||||
|
Key.N3 to Command.CHARACTER,
|
||||||
|
Key.N4 to Command.CHARACTER,
|
||||||
|
Key.N5 to Command.CHARACTER,
|
||||||
|
Key.N6 to Command.CHARACTER,
|
||||||
|
Key.N7 to Command.CHARACTER,
|
||||||
|
Key.N8 to Command.CHARACTER,
|
||||||
|
Key.N9 to Command.CHARACTER,
|
||||||
|
|
||||||
Key.BACK to Command.BACK,
|
Key.BACK to Command.BACK,
|
||||||
Key.POUND to Command.SHIFT_MODE,
|
Key.POUND to Command.SHIFT_MODE,
|
||||||
)),
|
)),
|
||||||
|
@ -9,6 +9,7 @@ data class KeyEventResult(
|
|||||||
val startComposing: Boolean = false,
|
val startComposing: Boolean = false,
|
||||||
val codeWord: StringBuilder? = null,
|
val codeWord: StringBuilder? = null,
|
||||||
val candidates: List<String>? = null,
|
val candidates: List<String>? = null,
|
||||||
|
val commit: String? = null,
|
||||||
val timeout: Int? = null,
|
val timeout: Int? = null,
|
||||||
val deleteBeforeCursor: Int = 0,
|
val deleteBeforeCursor: Int = 0,
|
||||||
val deleteAfterCursor: Int = 0,
|
val deleteAfterCursor: Int = 0,
|
||||||
|
@ -3,16 +3,16 @@ package net.mezimmah.wkt9.keypad
|
|||||||
object KeyLayout {
|
object KeyLayout {
|
||||||
// Map for number input mode
|
// Map for number input mode
|
||||||
val numeric = mapOf(
|
val numeric = mapOf(
|
||||||
Key.N0 to listOf('0'),
|
Key.N0 to 0,
|
||||||
Key.N1 to listOf('1'),
|
Key.N1 to 1,
|
||||||
Key.N2 to listOf('2'),
|
Key.N2 to 2,
|
||||||
Key.N3 to listOf('3'),
|
Key.N3 to 3,
|
||||||
Key.N4 to listOf('4'),
|
Key.N4 to 4,
|
||||||
Key.N5 to listOf('5'),
|
Key.N5 to 5,
|
||||||
Key.N6 to listOf('6'),
|
Key.N6 to 6,
|
||||||
Key.N7 to listOf('7'),
|
Key.N7 to 7,
|
||||||
Key.N8 to listOf('8'),
|
Key.N8 to 8,
|
||||||
Key.N9 to listOf('9'),
|
Key.N9 to 9,
|
||||||
)
|
)
|
||||||
|
|
||||||
val en_US = mapOf(
|
val en_US = mapOf(
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package net.mezimmah.wkt9.keypad
|
package net.mezimmah.wkt9.keypad
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
import net.mezimmah.wkt9.exception.MissingLetterCode
|
import net.mezimmah.wkt9.exception.MissingLetterCode
|
||||||
import java.lang.StringBuilder
|
import java.lang.StringBuilder
|
||||||
|
|
||||||
@ -49,7 +50,8 @@ class Keypad(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun codeForLetter(letter: Char): Char? {
|
private fun codeForLetter(letter: Char): Char? {
|
||||||
return letterKeyMap[letter]?.code
|
Log.d("wkt9", "Letter key map: letterKeyMap")
|
||||||
|
return ' ' //letterKeyMap[letter]?.code
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initKeyMaps(layout: Map<Key, List<Char>>): Map<Char, Key> {
|
private fun initKeyMaps(layout: Map<Key, List<Char>>): Map<Char, Key> {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user