This commit is contained in:
Nehemiah of Zebulun 2023-08-29 21:09:20 +02:00
parent e5f7caab0f
commit 65d278d907
4 changed files with 238 additions and 58 deletions

View File

@ -174,10 +174,10 @@ class WKT9: InputMethodService() {
when (inputType) { when (inputType) {
InputType.TYPE_CLASS_DATETIME, InputType.TYPE_CLASS_DATETIME,
InputType.TYPE_CLASS_NUMBER, InputType.TYPE_CLASS_NUMBER,
InputType.TYPE_CLASS_PHONE -> enableInputMode(WKT9InputMode.NUMERIC, inputType) InputType.TYPE_CLASS_PHONE -> enableInputMode(WKT9InputMode.NUMERIC)
InputType.TYPE_CLASS_TEXT -> InputType.TYPE_CLASS_TEXT ->
if (lastInputMode == WKT9InputMode.ALPHA) enableInputMode(WKT9InputMode.ALPHA, inputType) if (lastInputMode == WKT9InputMode.ALPHA) enableInputMode(WKT9InputMode.ALPHA)
else enableInputMode(WKT9InputMode.WORD, inputType) else enableInputMode(WKT9InputMode.WORD)
else -> Log.d(tag, "Mode without input...") else -> Log.d(tag, "Mode without input...")
} }
@ -254,12 +254,9 @@ class WKT9: InputMethodService() {
} }
// Todo: inputType // Todo: inputType
private fun enableInputMode(mode: WKT9InputMode, inputType: Int) { private fun enableInputMode(mode: WKT9InputMode) {
lastInputMode = mode lastInputMode = mode
if (inputType.and(InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS) == InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS)
Log.d(tag, "InputConnection expects email address")
inputMode = when(mode) { inputMode = when(mode) {
WKT9InputMode.ALPHA -> alphaInputMode WKT9InputMode.ALPHA -> alphaInputMode
WKT9InputMode.NUMERIC -> numericInputMode WKT9InputMode.NUMERIC -> numericInputMode
@ -277,6 +274,24 @@ class WKT9: InputMethodService() {
} else false } else false
} }
@SuppressLint("DiscouragedApi")
private fun getIconResource(): Int {
val name = inputMode?.let {
val inputMethodManager = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
val inputMethodSubtype = inputMethodManager.currentInputMethodSubtype
it.mode
.plus("_")
.plus(inputMethodSubtype.languageTag)
.plus("_")
.plus(inputStatus.toString())
.replace("-", "_")
.lowercase()
} ?: "wkt9"
return resources.getIdentifier(name, "drawable", packageName)
}
private fun goHome() { private fun goHome() {
with(Intent(Intent.ACTION_MAIN)) { with(Intent(Intent.ACTION_MAIN)) {
this.addCategory(Intent.CATEGORY_HOME) this.addCategory(Intent.CATEGORY_HOME)
@ -314,6 +329,7 @@ class WKT9: InputMethodService() {
if (res.updateInputStatus) updateInputStatus() if (res.updateInputStatus) updateInputStatus()
if (res.updateWordStatus) onUpdateWordStatus() if (res.updateWordStatus) onUpdateWordStatus()
if (res.focus) onFocus() if (res.focus) onFocus()
if (res.switchInputMode != null) onSwitchInputMode(res.switchInputMode)
return res.consumed return res.consumed
} }
@ -359,7 +375,14 @@ class WKT9: InputMethodService() {
clearCandidates() clearCandidates()
candidates.forEach { candidates.forEach {
this.candidates.add(it) val candidate =
when (inputStatus) {
Status.CAP -> it.replaceFirstChar { char -> char.uppercase() }
Status.UPPER -> it.uppercase()
else -> it
}
this.candidates.add(candidate)
} }
loadCandidates(candidateIndex) loadCandidates(candidateIndex)
@ -453,6 +476,17 @@ class WKT9: InputMethodService() {
handleComposeTimeout(this.timeout) handleComposeTimeout(this.timeout)
} }
private fun onSwitchInputMode(mode: WKT9InputMode) {
when (mode) {
WKT9InputMode.ALPHA -> enableInputMode(WKT9InputMode.ALPHA)
WKT9InputMode.NUMERIC -> enableInputMode(WKT9InputMode.NUMERIC)
WKT9InputMode.WORD -> enableInputMode(WKT9InputMode.WORD)
}
clearCandidates()
updateInputStatus()
}
private fun onTranscribe() { private fun onTranscribe() {
val recorder = this.recorder ?: return val recorder = this.recorder ?: return
@ -510,24 +544,6 @@ class WKT9: InputMethodService() {
composeText(candidates[candidateIndex]) composeText(candidates[candidateIndex])
} }
@SuppressLint("DiscouragedApi")
private fun getIconResource(): Int {
val name = inputMode?.let {
val inputMethodManager = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
val inputMethodSubtype = inputMethodManager.currentInputMethodSubtype
it.mode
.plus("_")
.plus(inputMethodSubtype.languageTag)
.plus("_")
.plus(inputStatus.toString())
.replace('-', '_')
.lowercase()
} ?: "wkt9"
return resources.getIdentifier(name, "drawable", packageName)
}
private fun updateInputStatus() { private fun updateInputStatus() {
inputStatus = inputMode?.status ?: Status.CAP inputStatus = inputMode?.status ?: Status.CAP

View File

@ -1,31 +1,188 @@
package net.mezimmah.wkt9.inputmode package net.mezimmah.wkt9.inputmode
import android.util.Log
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.KeyEventResult import net.mezimmah.wkt9.keypad.KeyEventResult
import net.mezimmah.wkt9.keypad.KeyLayout
class AlphaInputMode: InputMode { class AlphaInputMode: InputMode {
private val tag = "WKT9"
private val keyCommandResolver: KeyCommandResolver = KeyCommandResolver.getBasic()
private var newKey = true
private var keyIndex = 0
private var lastKey: Key? = null
override val mode: String = "alpha" override val mode: String = "alpha"
override var status: Status = Status.CAP override var status: Status = Status.CAP
private set private set
override fun onKeyDown(key: Key, sentenceStart: Boolean): KeyEventResult { init {
return KeyEventResult(consumed = false) Log.d(tag, "Started alpha input mode.")
} }
override fun onKeyLongDown(key: Key, sentenceStart: Boolean): KeyEventResult { override fun onKeyDown(key: Key, composing: Boolean): KeyEventResult {
return KeyEventResult(consumed = false) keyStats(key)
return when(keyCommandResolver.getCommand(key)) {
Command.BACK -> KeyEventResult(consumed = false)
Command.CHARACTER -> composeCharacter(key, composing)
Command.DELETE -> deleteCharacter(composing)
Command.SPACE -> finalizeWordOrSentence(composing)
Command.LEFT -> navigateLeft()
Command.RIGHT -> navigateRight()
Command.SELECT -> focus()
else -> KeyEventResult()
}
} }
override fun onKeyDownRepeatedly(key: Key, repeat: Int, sentenceStart: Boolean): KeyEventResult { override fun onKeyLongDown(key: Key, composing: Boolean): KeyEventResult {
return KeyEventResult(consumed = false) return when(keyCommandResolver.getCommand(key, true)) {
Command.RECORD -> record(composing)
Command.SWITCH_MODE -> switchMode(composing)
else -> KeyEventResult(true)
}
} }
override fun afterKeyDown(key: Key, sentenceStart: Boolean): KeyEventResult { override fun onKeyDownRepeatedly(key: Key, repeat: Int, composing: Boolean): KeyEventResult {
return KeyEventResult(consumed = false) return when(keyCommandResolver.getCommand(key, repeat = repeat)) {
Command.HOME -> goHome(repeat, composing)
Command.DELETE -> deleteCharacter(composing)
else -> KeyEventResult()
}
} }
override fun afterKeyLongDown(key: Key, keyDownMS: Long, sentenceStart: Boolean): KeyEventResult { override fun afterKeyDown(key: Key, composing: Boolean): KeyEventResult {
return KeyEventResult(consumed = false) return when(keyCommandResolver.getCommand(key, after = true)) {
Command.BACK -> goBack(composing)
Command.SHIFT_MODE -> shiftMode()
else -> KeyEventResult()
}
}
override fun afterKeyLongDown(key: Key, keyDownMS: Long, composing: Boolean): KeyEventResult {
return when(keyCommandResolver.getCommand(key, after = true, longPress = true)) {
Command.TRANSCRIBE -> transcribe(composing)
else -> KeyEventResult()
}
}
private fun deleteCharacter(composing: Boolean): KeyEventResult {
return KeyEventResult(
finishComposing = composing,
deleteBeforeCursor = 1
)
}
private fun composeCharacter(key: Key, composing: Boolean): KeyEventResult {
if (composing && !newKey) return navigateRight()
val layout = KeyLayout.en_US[key] ?: return KeyEventResult(true)
val candidates = layout.map { it.toString() }
return KeyEventResult(
consumed = true,
finishComposing = composing,
startComposing = true,
candidates = candidates,
timeout = 400
)
}
private fun finalizeWordOrSentence(composing: Boolean): KeyEventResult {
if (composing && !newKey) return navigateRight()
return KeyEventResult(
finishComposing = composing,
startComposing = true,
candidates = listOf(" ", ". ", "? ", "! ", ", ", ": ", "; "),
timeout = 700
)
}
private fun focus(): KeyEventResult {
return KeyEventResult(
consumed = true,
focus = true
)
}
private fun goBack(composing: Boolean): KeyEventResult {
return KeyEventResult(
consumed = false,
finishComposing = composing
)
}
private fun goHome(repeat: Int, composing: Boolean): KeyEventResult {
if (repeat > 1) return KeyEventResult(true)
return KeyEventResult(
consumed = true,
finishComposing = composing,
goHome = true
)
}
private fun keyStats(key: Key) {
when (key != lastKey) {
true -> {
newKey = true
keyIndex = 0
}
false -> {
newKey = false
keyIndex++
}
}
lastKey = key
}
private fun navigateLeft(): KeyEventResult {
return KeyEventResult(left = true)
}
private fun navigateRight(): KeyEventResult {
return KeyEventResult(right = true)
}
private fun record(composing: Boolean): KeyEventResult {
return KeyEventResult(
consumed = true,
finishComposing = composing,
record = true
)
}
private fun shiftMode(): KeyEventResult {
status = when(status) {
Status.CAP -> Status.UPPER
Status.UPPER -> Status.LOWER
else -> Status.CAP
}
return KeyEventResult(
consumed = true,
updateInputStatus = true
)
}
private fun switchMode(composing: Boolean): KeyEventResult {
return KeyEventResult(
consumed = true,
finishComposing = composing,
switchInputMode = WKT9InputMode.WORD
)
}
private fun transcribe(composing: Boolean): KeyEventResult {
return KeyEventResult(
consumed = true,
finishComposing = composing,
transcribe = true
)
} }
} }

View File

@ -28,9 +28,9 @@ class WordInputMode: InputMode {
keyStats(key) keyStats(key)
return when(keyCommandResolver.getCommand(key)) { return when(keyCommandResolver.getCommand(key)) {
Command.BACK -> KeyEventResult(false) Command.BACK -> KeyEventResult(consumed = false)
Command.CHARACTER -> buildCodeWord(key) Command.CHARACTER -> buildCodeWord(key)
Command.DELETE -> deleteCharacter() Command.DELETE -> deleteCharacter(0, composing)
Command.SPACE -> finalizeWordOrSentence(composing) Command.SPACE -> finalizeWordOrSentence(composing)
Command.LEFT -> navigateLeft() Command.LEFT -> navigateLeft()
Command.RIGHT -> navigateRight() Command.RIGHT -> navigateRight()
@ -41,23 +41,23 @@ class WordInputMode: 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() Command.RECORD -> record(composing)
Command.SWITCH_MODE -> switchMode() Command.SWITCH_MODE -> switchMode(composing)
else -> KeyEventResult(true) else -> KeyEventResult(true)
} }
} }
override fun onKeyDownRepeatedly(key: Key, repeat: Int, composing: Boolean): KeyEventResult { override fun onKeyDownRepeatedly(key: Key, repeat: Int, composing: Boolean): KeyEventResult {
return when(keyCommandResolver.getCommand(key, repeat = repeat)) { return when(keyCommandResolver.getCommand(key, repeat = repeat)) {
Command.HOME -> goHome(repeat) Command.HOME -> goHome(repeat, composing)
Command.DELETE -> deleteCharacter(repeat) Command.DELETE -> deleteCharacter(repeat, composing)
else -> KeyEventResult() else -> KeyEventResult()
} }
} }
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() Command.BACK -> goBack(composing)
Command.SHIFT_MODE -> shiftMode(composing) Command.SHIFT_MODE -> shiftMode(composing)
else -> KeyEventResult() else -> KeyEventResult()
} }
@ -65,7 +65,7 @@ class WordInputMode: InputMode {
override fun afterKeyLongDown(key: Key, keyDownMS: Long, composing: Boolean): KeyEventResult { override fun afterKeyLongDown(key: Key, keyDownMS: Long, composing: Boolean): KeyEventResult {
return when(keyCommandResolver.getCommand(key, after = true, longPress = true)) { return when(keyCommandResolver.getCommand(key, after = true, longPress = true)) {
Command.TRANSCRIBE -> transcribe() Command.TRANSCRIBE -> transcribe(composing)
else -> KeyEventResult() else -> KeyEventResult()
} }
} }
@ -82,11 +82,11 @@ class WordInputMode: InputMode {
) )
} }
private fun deleteCharacter(repeat: Int = 0): KeyEventResult { private fun deleteCharacter(repeat: Int = 0, composing: Boolean): KeyEventResult {
if (repeat == 0) codeWord.clear() if (repeat == 0) codeWord.clear()
return KeyEventResult( return KeyEventResult(
finishComposing = true, finishComposing = composing,
deleteBeforeCursor = 1 deleteBeforeCursor = 1
) )
} }
@ -113,23 +113,23 @@ class WordInputMode: InputMode {
) )
} }
private fun goBack(): KeyEventResult { private fun goBack(composing: Boolean): KeyEventResult {
reset() reset()
return KeyEventResult( return KeyEventResult(
consumed = false, consumed = false,
finishComposing = true finishComposing = composing
) )
} }
private fun goHome(repeat: Int): KeyEventResult { private fun goHome(repeat: Int, composing: Boolean): KeyEventResult {
if (repeat > 1) return KeyEventResult(true) if (repeat > 1) return KeyEventResult(true)
reset() reset()
return KeyEventResult( return KeyEventResult(
consumed = true, consumed = true,
finishComposing = true, finishComposing = composing,
goHome = true goHome = true
) )
} }
@ -157,12 +157,12 @@ class WordInputMode: InputMode {
return KeyEventResult(right = true) return KeyEventResult(right = true)
} }
private fun record(): KeyEventResult { private fun record(composing: Boolean): KeyEventResult {
codeWord.clear() codeWord.clear()
return KeyEventResult( return KeyEventResult(
consumed = true, consumed = true,
finishComposing = true, finishComposing = composing,
record = true record = true
) )
} }
@ -190,15 +190,20 @@ class WordInputMode: InputMode {
) )
} }
private fun switchMode(): KeyEventResult { private fun switchMode(composing: Boolean): KeyEventResult {
reset() reset()
return KeyEventResult(true)
}
private fun transcribe(): KeyEventResult {
return KeyEventResult( return KeyEventResult(
consumed = true, consumed = true,
finishComposing = composing,
switchInputMode = WKT9InputMode.ALPHA
)
}
private fun transcribe(composing: Boolean): KeyEventResult {
return KeyEventResult(
consumed = true,
finishComposing = composing,
transcribe = true transcribe = true
) )
} }

View File

@ -1,5 +1,6 @@
package net.mezimmah.wkt9.keypad package net.mezimmah.wkt9.keypad
import net.mezimmah.wkt9.inputmode.WKT9InputMode
import java.lang.StringBuilder import java.lang.StringBuilder
data class KeyEventResult( data class KeyEventResult(
@ -18,5 +19,6 @@ data class KeyEventResult(
val transcribe: Boolean = false, val transcribe: Boolean = false,
val updateInputStatus: Boolean = false, val updateInputStatus: Boolean = false,
val updateWordStatus: Boolean = false, val updateWordStatus: Boolean = false,
val focus: Boolean = false val focus: Boolean = false,
val switchInputMode: WKT9InputMode? = null
) )