Progress
This commit is contained in:
parent
cb250e64de
commit
f805d8dcf3
@ -88,10 +88,9 @@ class WKT9: InputMethodService(), SpellCheckerSession.SpellCheckerSessionListene
|
|||||||
private var timeout: Int? = null
|
private var timeout: Int? = null
|
||||||
private var lastComposedString: String? = null
|
private var lastComposedString: String? = null
|
||||||
private val commitHistory: MutableList<String> = mutableListOf()
|
private val commitHistory: MutableList<String> = mutableListOf()
|
||||||
private var trackCommits = false
|
|
||||||
|
|
||||||
// Spell checker
|
// Spell checker
|
||||||
private var locale: Locale? = null
|
private lateinit var locale: Locale
|
||||||
private var spellCheckerSession: SpellCheckerSession? = null
|
private var spellCheckerSession: SpellCheckerSession? = null
|
||||||
|
|
||||||
// UI
|
// UI
|
||||||
@ -104,12 +103,17 @@ class WKT9: InputMethodService(), SpellCheckerSession.SpellCheckerSessionListene
|
|||||||
private var recording: File? = null
|
private var recording: File? = null
|
||||||
|
|
||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
Log.d(tag, "WKT9 is loading")
|
val inputMethodManager = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
|
||||||
|
val inputMethodSubtype = inputMethodManager.currentInputMethodSubtype
|
||||||
|
|
||||||
|
locale = Locale.forLanguageTag(inputMethodSubtype.languageTag)
|
||||||
|
|
||||||
|
Log.d(tag, "WKT9 is loading: $locale")
|
||||||
|
|
||||||
db = AppDatabase.getInstance(this)
|
db = AppDatabase.getInstance(this)
|
||||||
wordDao = db.getWordDao()
|
wordDao = db.getWordDao()
|
||||||
settingDao = db.getSettingDao()
|
settingDao = db.getSettingDao()
|
||||||
keypad = Keypad(KeyCodeMapping(KeyCodeMapping.basic), KeyLayout.en_US)
|
keypad = Keypad(KeyCodeMapping(KeyCodeMapping.basic), KeyLayout.en_US, KeyLayout.numeric)
|
||||||
t9 = T9(this, keypad, settingDao, wordDao)
|
t9 = T9(this, keypad, settingDao, wordDao)
|
||||||
alphaInputMode = AlphaInputMode()
|
alphaInputMode = AlphaInputMode()
|
||||||
numericInputMode = NumericInputMode()
|
numericInputMode = NumericInputMode()
|
||||||
@ -117,7 +121,6 @@ class WKT9: InputMethodService(), SpellCheckerSession.SpellCheckerSessionListene
|
|||||||
longPressTimeout = ViewConfiguration.getLongPressTimeout()
|
longPressTimeout = ViewConfiguration.getLongPressTimeout()
|
||||||
lastComposedString = null
|
lastComposedString = null
|
||||||
commitHistory.clear()
|
commitHistory.clear()
|
||||||
trackCommits = false
|
|
||||||
|
|
||||||
t9.initializeWords(languageTag)
|
t9.initializeWords(languageTag)
|
||||||
|
|
||||||
@ -143,7 +146,6 @@ class WKT9: InputMethodService(), SpellCheckerSession.SpellCheckerSessionListene
|
|||||||
cursorPosition = 0
|
cursorPosition = 0
|
||||||
inputStatus = Status.CAP
|
inputStatus = Status.CAP
|
||||||
spellCheckerSession = null
|
spellCheckerSession = null
|
||||||
locale = null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onFinishInputView(finishingInput: Boolean) {
|
override fun onFinishInputView(finishingInput: Boolean) {
|
||||||
@ -194,22 +196,26 @@ class WKT9: InputMethodService(), SpellCheckerSession.SpellCheckerSessionListene
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onStartInput(attribute: EditorInfo?, restarting: Boolean) {
|
override fun onStartInput(attribute: EditorInfo?, restarting: Boolean) {
|
||||||
val inputType = attribute?.inputType?.and(InputType.TYPE_MASK_CLASS) ?: 0
|
val inputType = attribute?.inputType
|
||||||
val inputMethodManager = getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager
|
val inputClass = inputType?.and(InputType.TYPE_MASK_CLASS) ?: 0
|
||||||
val inputMethodSubtype = inputMethodManager.currentInputMethodSubtype
|
val typeVariation = inputType?.and(InputType.TYPE_MASK_VARIATION) ?: 0
|
||||||
val textServiceManager = getSystemService(TEXT_SERVICES_MANAGER_SERVICE) as TextServicesManager
|
// val textServiceManager = getSystemService(TEXT_SERVICES_MANAGER_SERVICE) as TextServicesManager
|
||||||
|
|
||||||
cursorPosition = attribute?.initialSelEnd ?: 0
|
cursorPosition = attribute?.initialSelEnd ?: 0
|
||||||
locale = Locale.forLanguageTag(inputMethodSubtype.languageTag)
|
// spellCheckerSession = textServiceManager.newSpellCheckerSession(null, locale, this, false)
|
||||||
spellCheckerSession = textServiceManager.newSpellCheckerSession(null, locale, this, false)
|
|
||||||
|
|
||||||
when (inputType) {
|
when (inputClass) {
|
||||||
InputType.TYPE_CLASS_DATETIME,
|
InputType.TYPE_CLASS_DATETIME,
|
||||||
InputType.TYPE_CLASS_NUMBER,
|
InputType.TYPE_CLASS_NUMBER,
|
||||||
InputType.TYPE_CLASS_PHONE -> enableInputMode(WKT9InputMode.NUMERIC)
|
InputType.TYPE_CLASS_PHONE -> enableInputMode(WKT9InputMode.NUMERIC)
|
||||||
InputType.TYPE_CLASS_TEXT ->
|
InputType.TYPE_CLASS_TEXT -> {
|
||||||
|
if (typeVariation == InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS) {
|
||||||
|
Log.d(tag, "Heja")
|
||||||
|
}
|
||||||
|
|
||||||
if (lastInputMode == WKT9InputMode.ALPHA) enableInputMode(WKT9InputMode.ALPHA)
|
if (lastInputMode == WKT9InputMode.ALPHA) enableInputMode(WKT9InputMode.ALPHA)
|
||||||
else enableInputMode(WKT9InputMode.WORD)
|
else enableInputMode(WKT9InputMode.WORD)
|
||||||
|
}
|
||||||
else -> Log.d(tag, "Mode without input...")
|
else -> Log.d(tag, "Mode without input...")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -318,9 +324,11 @@ class WKT9: InputMethodService(), SpellCheckerSession.SpellCheckerSessionListene
|
|||||||
return if (composing) {
|
return if (composing) {
|
||||||
composing = false
|
composing = false
|
||||||
|
|
||||||
val lastComposed = lastComposedString
|
lastComposedString?.let {
|
||||||
|
commitHistory.add(it)
|
||||||
|
|
||||||
if (trackCommits && !lastComposed.isNullOrEmpty()) commitHistory.add(lastComposed)
|
lastComposedString = null
|
||||||
|
}
|
||||||
|
|
||||||
updateInputStatus()
|
updateInputStatus()
|
||||||
|
|
||||||
@ -330,20 +338,12 @@ class WKT9: InputMethodService(), SpellCheckerSession.SpellCheckerSessionListene
|
|||||||
|
|
||||||
@SuppressLint("DiscouragedApi")
|
@SuppressLint("DiscouragedApi")
|
||||||
private fun getIconResource(): Int {
|
private fun getIconResource(): Int {
|
||||||
val mode = inputMode?.mode
|
val mode = inputMode?.mode ?: return resources.getIdentifier("wkt9", "drawable", packageName)
|
||||||
val language = locale?.language
|
|
||||||
val country = locale?.country
|
|
||||||
|
|
||||||
if (mode == null ||language == null || country == null) {
|
|
||||||
return resources.getIdentifier("wkt9", "drawable", packageName)
|
|
||||||
}
|
|
||||||
|
|
||||||
val name = mode.plus("_")
|
val name = mode.plus("_")
|
||||||
.plus(language)
|
.plus(locale.toString())
|
||||||
.plus("_")
|
|
||||||
.plus(country)
|
|
||||||
.plus("_")
|
.plus("_")
|
||||||
.plus(inputStatus.toString())
|
.plus(inputStatus.toString())
|
||||||
|
.replace('-', '_')
|
||||||
.lowercase()
|
.lowercase()
|
||||||
|
|
||||||
return resources.getIdentifier(name, "drawable", packageName)
|
return resources.getIdentifier(name, "drawable", packageName)
|
||||||
@ -375,9 +375,7 @@ class WKT9: InputMethodService(), SpellCheckerSession.SpellCheckerSessionListene
|
|||||||
private fun handleKeyEventResult(res: KeyEventResult): Boolean {
|
private fun handleKeyEventResult(res: KeyEventResult): Boolean {
|
||||||
if (res.finishComposing) finishComposingText()
|
if (res.finishComposing) finishComposingText()
|
||||||
if (res.startComposing) markComposingRegion()
|
if (res.startComposing) markComposingRegion()
|
||||||
|
if (res.increaseWeight) onIncreaseWeight()
|
||||||
trackCommits = res.trackCommits
|
|
||||||
|
|
||||||
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.commit.isNullOrEmpty()) onCommit(res.commit)
|
||||||
@ -479,6 +477,16 @@ class WKT9: InputMethodService(), SpellCheckerSession.SpellCheckerSessionListene
|
|||||||
requestShowSelf(InputMethodManager.SHOW_IMPLICIT)
|
requestShowSelf(InputMethodManager.SHOW_IMPLICIT)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun onIncreaseWeight() {
|
||||||
|
val word = commitHistory.last()
|
||||||
|
|
||||||
|
if (word.isEmpty()) return
|
||||||
|
|
||||||
|
queryScope.launch {
|
||||||
|
wordDao.increaseWeight(word)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun onLeft() {
|
private fun onLeft() {
|
||||||
if (candidates.isEmpty()) return
|
if (candidates.isEmpty()) return
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ 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.CHARACTER -> buildCodeWord(key, composing)
|
||||||
Command.SHIFT_MODE -> shiftMode(composing)
|
Command.SHIFT_MODE -> shiftMode(composing)
|
||||||
Command.SPACE -> finalizeWordOrSentence(composing)
|
Command.SPACE -> finalizeWordOrSentence(composing)
|
||||||
else -> KeyEventResult()
|
else -> KeyEventResult()
|
||||||
@ -72,7 +72,7 @@ class WordInputMode: InputMode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun buildCodeWord(key: Key): KeyEventResult {
|
private fun buildCodeWord(key: Key, composing: Boolean): KeyEventResult {
|
||||||
val startComposing = codeWord.isEmpty()
|
val startComposing = codeWord.isEmpty()
|
||||||
val code = KeyLayout.numeric[key]
|
val code = KeyLayout.numeric[key]
|
||||||
|
|
||||||
@ -80,7 +80,7 @@ class WordInputMode: InputMode {
|
|||||||
|
|
||||||
return KeyEventResult(
|
return KeyEventResult(
|
||||||
codeWord = codeWord,
|
codeWord = codeWord,
|
||||||
finishComposing = startComposing,
|
finishComposing = startComposing && composing,
|
||||||
startComposing = startComposing
|
startComposing = startComposing
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -107,13 +107,14 @@ class WordInputMode: InputMode {
|
|||||||
private fun finalizeWordOrSentence(composing: Boolean): KeyEventResult {
|
private fun finalizeWordOrSentence(composing: Boolean): KeyEventResult {
|
||||||
if (composing && !newKey) return navigateRight()
|
if (composing && !newKey) return navigateRight()
|
||||||
|
|
||||||
val finishComposing = codeWord.isNotEmpty()
|
val finishComposing = codeWord.isNotEmpty() && composing
|
||||||
|
|
||||||
codeWord.clear()
|
codeWord.clear()
|
||||||
|
|
||||||
return KeyEventResult(
|
return KeyEventResult(
|
||||||
finishComposing = finishComposing,
|
finishComposing = finishComposing,
|
||||||
startComposing = true,
|
startComposing = true,
|
||||||
|
increaseWeight = true,
|
||||||
candidates = listOf(" ", ". ", "? ", "! ", ", ", ": ", "; "),
|
candidates = listOf(" ", ". ", "? ", "! ", ", ", ": ", "; "),
|
||||||
timeout = 700
|
timeout = 700
|
||||||
)
|
)
|
||||||
|
@ -7,7 +7,7 @@ data class KeyEventResult(
|
|||||||
val consumed: Boolean = true,
|
val consumed: Boolean = true,
|
||||||
val finishComposing: Boolean = false,
|
val finishComposing: Boolean = false,
|
||||||
val startComposing: Boolean = false,
|
val startComposing: Boolean = false,
|
||||||
val trackCommits: Boolean = false,
|
val increaseWeight: 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 commit: String? = null,
|
||||||
|
@ -6,41 +6,36 @@ import java.lang.StringBuilder
|
|||||||
|
|
||||||
class Keypad(
|
class Keypad(
|
||||||
private val keyCodeMapping: KeyCodeMapping,
|
private val keyCodeMapping: KeyCodeMapping,
|
||||||
private val letterLayout: Map<Key, List<Char>>
|
private val letterLayout: Map<Key, List<Char>>,
|
||||||
|
|
||||||
|
numericLayout: Map<Key, Int>
|
||||||
) {
|
) {
|
||||||
private lateinit var letterKeyMap: Map<Char, Key>
|
private val tag = "WKT9"
|
||||||
private lateinit var keyIsLetterMap: Map<Key, Boolean>
|
private val letterCodeMap: MutableMap<Char, Int> = mutableMapOf()
|
||||||
private var emojiCodes = mapOf(
|
|
||||||
"❤️" to "143278",
|
|
||||||
"\uD83D\uDE18" to "15477"
|
|
||||||
)
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
initKeyMaps(letterLayout)
|
Log.d(tag, "Keypad")
|
||||||
|
|
||||||
|
numericLayout.forEach { (key, code) ->
|
||||||
|
indexKeyLetters(key, code)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getKey(keyCode: Int): Key? {
|
private fun indexKeyLetters(key: Key, code: Int) {
|
||||||
return keyCodeMapping.key(keyCode)
|
letterLayout[key]?.map { letter ->
|
||||||
|
letterCodeMap[letter] = code
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getCharacter(key: Key, idx: Int): Char {
|
fun getKey(code: Int): Key? {
|
||||||
val chars = letterLayout[key]!!
|
return keyCodeMapping.key(code)
|
||||||
val length = chars.size
|
|
||||||
val wrappedIdx = idx % (length - 1) + 1
|
|
||||||
return chars[wrappedIdx]
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getDigit(key: Key): Char? {
|
|
||||||
val letters = letterLayout[key] ?: return null
|
|
||||||
return if (letters.isNotEmpty() && letters[0].isDigit()) letters[0] else null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getCodeForWord(word: String): String {
|
fun getCodeForWord(word: String): String {
|
||||||
if (emojiCodes.keys.contains(word)) return emojiCodes[word]!!
|
|
||||||
|
|
||||||
val builder = StringBuilder()
|
val builder = StringBuilder()
|
||||||
|
val normalized = word.lowercase()
|
||||||
|
|
||||||
for (letter in word) {
|
for (letter in normalized) {
|
||||||
val code = codeForLetter(letter) ?: throw MissingLetterCode("No code found for '$letter'")
|
val code = codeForLetter(letter) ?: throw MissingLetterCode("No code found for '$letter'")
|
||||||
|
|
||||||
builder.append(code)
|
builder.append(code)
|
||||||
@ -49,29 +44,7 @@ class Keypad(
|
|||||||
return builder.toString()
|
return builder.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun codeForLetter(letter: Char): Char? {
|
private fun codeForLetter(letter: Char): Int? {
|
||||||
Log.d("wkt9", "Letter key map: letterKeyMap")
|
return letterCodeMap[letter]
|
||||||
return ' ' //letterKeyMap[letter]?.code
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun initKeyMaps(layout: Map<Key, List<Char>>): Map<Char, Key> {
|
|
||||||
val letterKeyMap = HashMap<Char, Key>()
|
|
||||||
val keyIsLetterMap = HashMap<Key, Boolean>()
|
|
||||||
|
|
||||||
this.letterKeyMap = letterKeyMap
|
|
||||||
this.keyIsLetterMap = keyIsLetterMap
|
|
||||||
|
|
||||||
for ((key, characters) in layout) {
|
|
||||||
for (char in characters) {
|
|
||||||
letterKeyMap[char] = key
|
|
||||||
|
|
||||||
if (!KeyLayout.nonAlphaNumeric.contains(char)) {
|
|
||||||
letterKeyMap[char.uppercaseChar()] = key
|
|
||||||
keyIsLetterMap[key] = true
|
|
||||||
} else if (keyIsLetterMap[key] == null) keyIsLetterMap[key] = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return letterKeyMap
|
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user