From 92a4ac541c2c748db595f1cadfe274def1917da9 Mon Sep 17 00:00:00 2001 From: Nehemiah Date: Sun, 3 Dec 2023 19:58:54 -0500 Subject: [PATCH] Slowly getting stable --- app/src/main/java/net/mezimmah/wkt9/IME.kt | 4 +- .../main/java/net/mezimmah/wkt9/WKT9IME.kt | 34 +++- .../java/net/mezimmah/wkt9/dao/WordDao.kt | 7 +- .../wkt9/inputhandler/DefaultInputHandler.kt | 106 ++++++------ .../wkt9/inputhandler/IdleInputHandler.kt | 11 +- .../wkt9/inputhandler/InputHandler.kt | 4 +- .../wkt9/inputhandler/LetterInputHandler.kt | 152 +++++++++++++----- .../wkt9/inputhandler/NumberInputHandler.kt | 7 +- .../wkt9/inputhandler/WordInputHandler.kt | 63 +++++--- .../main/java/net/mezimmah/wkt9/keypad/Key.kt | 3 +- .../java/net/mezimmah/wkt9/layout/Words.kt | 17 +- app/src/main/res/values/strings.xml | 2 +- app/src/main/res/xml/method.xml | 12 ++ 13 files changed, 278 insertions(+), 144 deletions(-) diff --git a/app/src/main/java/net/mezimmah/wkt9/IME.kt b/app/src/main/java/net/mezimmah/wkt9/IME.kt index c6ba781..74ec3ba 100644 --- a/app/src/main/java/net/mezimmah/wkt9/IME.kt +++ b/app/src/main/java/net/mezimmah/wkt9/IME.kt @@ -15,7 +15,7 @@ interface IME { current: Int? = 0 ) - fun onWords(words: List) + fun onWords(words: List, capMode: Int?) fun onNextWord() @@ -23,6 +23,8 @@ interface IME { fun onWordSelected(word: Word) + fun onDeleteWord(word: Word) + fun onCommit(text: CharSequence = "", beforeCursor: Int = 0, afterCursor: Int = 0) fun onCompose(text: CharSequence) diff --git a/app/src/main/java/net/mezimmah/wkt9/WKT9IME.kt b/app/src/main/java/net/mezimmah/wkt9/WKT9IME.kt index a6bb8e6..448aaea 100644 --- a/app/src/main/java/net/mezimmah/wkt9/WKT9IME.kt +++ b/app/src/main/java/net/mezimmah/wkt9/WKT9IME.kt @@ -2,8 +2,10 @@ package net.mezimmah.wkt9 import android.annotation.SuppressLint import android.content.Intent +import android.content.SharedPreferences import android.inputmethodservice.InputMethodService import android.provider.Settings +import android.text.InputType import android.util.Log import android.view.KeyEvent import android.view.View @@ -12,14 +14,15 @@ import android.view.inputmethod.EditorInfo import android.view.inputmethod.InputConnection import android.view.inputmethod.InputMethodManager import android.view.inputmethod.InputMethodSubtype +import androidx.preference.PreferenceManager import net.mezimmah.wkt9.entity.Word import net.mezimmah.wkt9.inputhandler.IdleInputHandler import net.mezimmah.wkt9.inputhandler.InputHandler import net.mezimmah.wkt9.inputhandler.LetterInputHandler import net.mezimmah.wkt9.inputhandler.NumberInputHandler import net.mezimmah.wkt9.inputhandler.WordInputHandler -import net.mezimmah.wkt9.inputmode.InputModeManager import net.mezimmah.wkt9.inputmode.InputMode +import net.mezimmah.wkt9.inputmode.InputModeManager import net.mezimmah.wkt9.keypad.Event import net.mezimmah.wkt9.keypad.Key import net.mezimmah.wkt9.keypad.KeyEventStat @@ -45,6 +48,8 @@ class WKT9IME: IME, InputMethodService() { private var selectionStart: Int = 0 private var selectionEnd: Int = 0 + private var capMode: Int? = null + override fun onCandidates(candidates: ArrayList, current: Int?) { // this.candidates?.load(candidates, current) } @@ -103,6 +108,10 @@ class WKT9IME: IME, InputMethodService() { deleteText(beforeCursor, afterCursor) } + override fun onDeleteWord(word: Word) { + inputHandler?.onDeleteWord(word) + } + override fun onGetTextBeforeCursor(n: Int): CharSequence? { return this.currentInputConnection?.getTextBeforeCursor(n, 0) } @@ -264,12 +273,21 @@ class WKT9IME: IME, InputMethodService() { else showStatusIcon(icon) } - override fun onWords(words: List) { + override fun onWords(words: List, capMode: Int?) { + this.capMode = capMode + wordsView?.words = words } override fun onWordSelected(word: Word) { - this.onCompose(word.word) + val compose = when (capMode) { + InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS -> word.word.uppercase() + InputType.TYPE_TEXT_FLAG_CAP_WORDS, + InputType.TYPE_TEXT_FLAG_CAP_SENTENCES -> word.word.replaceFirstChar { it.uppercase() } + else -> word.word + } + + this.onCompose(compose) this.inputHandler?.onWordSelected(word) } @@ -301,7 +319,15 @@ class WKT9IME: IME, InputMethodService() { private fun switchInputMode(mode: InputMode) { inputHandler = when(mode) { InputMode.Word -> WordInputHandler(this, this, locale) - InputMode.Letter -> LetterInputHandler(this, this, locale) + + InputMode.Letter -> { + val prefs: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(this) + val timeout = prefs.getString(getString(R.string.compose_timeout), "700") + val composeTimeout = timeout?.toLong() ?: 700L + + timeout?.let { LetterInputHandler(this, this, locale, composeTimeout) } + } + InputMode.Number -> NumberInputHandler(this, this) else -> IdleInputHandler(this, this) } diff --git a/app/src/main/java/net/mezimmah/wkt9/dao/WordDao.kt b/app/src/main/java/net/mezimmah/wkt9/dao/WordDao.kt index 5a2731e..bc17392 100644 --- a/app/src/main/java/net/mezimmah/wkt9/dao/WordDao.kt +++ b/app/src/main/java/net/mezimmah/wkt9/dao/WordDao.kt @@ -11,8 +11,8 @@ interface WordDao { @Insert(onConflict = OnConflictStrategy.IGNORE) suspend fun insert(vararg words: Word) - @Query("DELETE FROM word WHERE word = :word AND locale = :locale") - fun delete(word: String, locale: String) + @Query("DELETE FROM word WHERE id = :id") + fun delete(id: Int) @Query("SELECT * FROM word WHERE code LIKE :code || '%' AND locale = :locale " + "ORDER BY length, weight DESC LIMIT :limit") @@ -20,4 +20,7 @@ interface WordDao { @Query("UPDATE word SET weight = weight + 1 WHERE id=:id") suspend fun increaseWeight(id: Int) + + @Query("SELECT * FROM word WHERE word = :word AND locale = :locale COLLATE NOCASE") + suspend fun selectWord(word: String, locale: String): Word? } \ No newline at end of file diff --git a/app/src/main/java/net/mezimmah/wkt9/inputhandler/DefaultInputHandler.kt b/app/src/main/java/net/mezimmah/wkt9/inputhandler/DefaultInputHandler.kt index 1a31c2c..0168cf0 100644 --- a/app/src/main/java/net/mezimmah/wkt9/inputhandler/DefaultInputHandler.kt +++ b/app/src/main/java/net/mezimmah/wkt9/inputhandler/DefaultInputHandler.kt @@ -3,79 +3,73 @@ package net.mezimmah.wkt9.inputhandler import android.text.InputType import android.view.KeyEvent import net.mezimmah.wkt9.WKT9IME -import net.mezimmah.wkt9.IME -import net.mezimmah.wkt9.inputmode.InputMode -import net.mezimmah.wkt9.inputmode.TextPositionInfo -import net.mezimmah.wkt9.keypad.Command import net.mezimmah.wkt9.keypad.Key -import net.mezimmah.wkt9.keypad.KeyEventStat -import net.mezimmah.wkt9.keypad.KeyLayout import net.mezimmah.wkt9.keypad.Keypad -import java.util.Locale open class DefaultInputHandler( - private val wkt9: IME, - private val context: WKT9IME + private val wkt9: WKT9IME ) { + private val capModes = listOf( + InputType.TYPE_TEXT_FLAG_CAP_SENTENCES, + InputType.TYPE_TEXT_FLAG_CAP_WORDS, + InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS, + null + ) + + private var currentCapMode: Int? = null + + protected val punctuationMarks = listOf(" ", ". ", "? ", "! ", ", ", ": ", "; ") + protected val tag = "WKT9" + protected val keypad: Keypad = Keypad() - protected var keypad: Keypad = Keypad() - protected var capMode: Int = InputType.TYPE_TEXT_FLAG_CAP_SENTENCES + protected var wordStart: Boolean = true + protected var sentenceStart: Boolean = true - protected open fun capMode(key: Key): Int? { - val modes = listOf( - InputType.TYPE_TEXT_FLAG_CAP_SENTENCES, - InputType.TYPE_TEXT_FLAG_CAP_WORDS, - InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS, - null - ) - var index = modes.indexOf(capMode) + init { + wkt9.currentInputEditorInfo?.let { + val inputType = it.inputType + val typeFlags = inputType.and(InputType.TYPE_MASK_FLAGS) + + if (typeFlags.and(InputType.TYPE_TEXT_FLAG_CAP_SENTENCES) == InputType.TYPE_TEXT_FLAG_CAP_SENTENCES) { + currentCapMode = InputType.TYPE_TEXT_FLAG_CAP_SENTENCES + } else if (typeFlags.and(InputType.TYPE_TEXT_FLAG_CAP_WORDS) == InputType.TYPE_TEXT_FLAG_CAP_WORDS) { + currentCapMode = InputType.TYPE_TEXT_FLAG_CAP_WORDS + } else if (typeFlags.and(InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS) == InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS) { + currentCapMode = InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS + } + } + } + + protected fun effectiveCapMode(): Int? { + return when (currentCapMode) { + InputType.TYPE_TEXT_FLAG_CAP_WORDS -> { + if (wordStart) InputType.TYPE_TEXT_FLAG_CAP_WORDS + else null + } + + InputType.TYPE_TEXT_FLAG_CAP_SENTENCES -> { + if (sentenceStart) InputType.TYPE_TEXT_FLAG_CAP_SENTENCES + else null + } + + else -> currentCapMode + } + } + + protected open fun toggleCapMode(key: Key) { + var index = capModes.indexOf(currentCapMode) when (key) { Key.B2 -> { - if (index == 0) index = modes.count() + if (index == 0) index = capModes.count() index-- } else -> index++ } - return modes[index % modes.count()] - } - - protected open fun finalizeWordOrSentence(stats: KeyEventStat) { - val candidates = ArrayList() - - wkt9.onCandidates( - candidates = candidates, - current = stats.repeats % candidates.count() - ) - } - - protected open fun getTextPositionInfo(text: CharSequence): TextPositionInfo { - val trimmed = text.trimEnd() - val regex = "[.!?]$".toRegex() - val startSentence = text.isEmpty() || regex.containsMatchIn(trimmed) - val startWord = text.isEmpty() || (startSentence || trimmed.length < text.length) - - return TextPositionInfo( - startSentence = startSentence, - startWord = startWord - ) - } - - protected fun getDefaultCapMode(typeFlags: Int): Int? { - val modes = listOf( - InputType.TYPE_TEXT_FLAG_CAP_SENTENCES, - InputType.TYPE_TEXT_FLAG_CAP_WORDS, - InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS - ) - - modes.forEach { - if (typeFlags.and(it) == it) return it - } - - return null + currentCapMode = capModes[index % capModes.count()] } protected fun triggerKeyEvent(keyCode: Int) { diff --git a/app/src/main/java/net/mezimmah/wkt9/inputhandler/IdleInputHandler.kt b/app/src/main/java/net/mezimmah/wkt9/inputhandler/IdleInputHandler.kt index c9db6f2..506ec2a 100644 --- a/app/src/main/java/net/mezimmah/wkt9/inputhandler/IdleInputHandler.kt +++ b/app/src/main/java/net/mezimmah/wkt9/inputhandler/IdleInputHandler.kt @@ -6,6 +6,7 @@ import android.util.Log import android.view.KeyEvent import net.mezimmah.wkt9.WKT9IME import net.mezimmah.wkt9.IME +import net.mezimmah.wkt9.R import net.mezimmah.wkt9.entity.Word import net.mezimmah.wkt9.keypad.Command import net.mezimmah.wkt9.keypad.Key @@ -15,12 +16,14 @@ import java.util.Locale class IdleInputHandler( val ime: IME, val wkt9: WKT9IME, -) : DefaultInputHandler(ime, wkt9), InputHandler { +) : DefaultInputHandler(wkt9), InputHandler { + init { + wkt9.showStatusIcon(R.drawable.idle_input) + } + override fun onFinishComposing() {} - override fun onLongClickCandidate(text: String) { - TODO("Not yet implemented") - } + override fun onDeleteWord(word: Word) {} override fun onRunCommand(command: Command, key: Key, event: KeyEvent, stats: KeyEventStat) { when (command) { diff --git a/app/src/main/java/net/mezimmah/wkt9/inputhandler/InputHandler.kt b/app/src/main/java/net/mezimmah/wkt9/inputhandler/InputHandler.kt index 39b3877..7da76b0 100644 --- a/app/src/main/java/net/mezimmah/wkt9/inputhandler/InputHandler.kt +++ b/app/src/main/java/net/mezimmah/wkt9/inputhandler/InputHandler.kt @@ -8,9 +8,9 @@ import net.mezimmah.wkt9.keypad.KeyEventStat import java.util.Locale interface InputHandler { - fun onFinishComposing() + fun onDeleteWord(word: Word) - fun onLongClickCandidate(text: String) + fun onFinishComposing() fun onRunCommand(command: Command, key: Key, event: KeyEvent, stats: KeyEventStat) diff --git a/app/src/main/java/net/mezimmah/wkt9/inputhandler/LetterInputHandler.kt b/app/src/main/java/net/mezimmah/wkt9/inputhandler/LetterInputHandler.kt index fd6e2ff..25b2201 100644 --- a/app/src/main/java/net/mezimmah/wkt9/inputhandler/LetterInputHandler.kt +++ b/app/src/main/java/net/mezimmah/wkt9/inputhandler/LetterInputHandler.kt @@ -30,23 +30,22 @@ class LetterInputHandler( val ime: IME, private var wkt9: WKT9IME, private var locale: Locale, -): SpellCheckerSession.SpellCheckerSessionListener, DefaultInputHandler(ime, wkt9), InputHandler { + private var composeTimeout: Long +): SpellCheckerSession.SpellCheckerSessionListener, DefaultInputHandler(wkt9), InputHandler { private val db = AppDatabase.getInstance(wkt9) private val wordDao = db.getWordDao() + private val word = StringBuilder() + private var lastKey: Key? = null private var repeats: Int = 0 + private var lastComposeChar: Char? = null + private var lastIcon: Int? = null private var spellCheckerSession: SpellCheckerSession? = null - private var sentenceStart: Boolean = false - private var wordStart: Boolean = false - - private val timeoutScope = CoroutineScope(Dispatchers.Main + SupervisorJob()) private var timeoutJob: Job? = null - private val content = StringBuilder() - init { val textServiceManager = wkt9.getSystemService(Context.TEXT_SERVICES_MANAGER_SERVICE) as TextServicesManager @@ -56,44 +55,67 @@ class LetterInputHandler( this, false ) + + updateIcon() } - override fun finalizeWordOrSentence(stats: KeyEventStat) { + private fun finalizeWordOrSentence(stats: KeyEventStat) { + if (word.isNotEmpty()) storeWord() + timeoutJob?.cancel() - val ends = listOf(" ", ". ", "? ", "! ", ", ", ": ", "; ") - val index = stats.repeats % ends.count() - val lastIndex = if (stats.repeats > 0) (stats.repeats - 1) % ends.count() else null + val index = stats.repeats % punctuationMarks.count() + val lastIndex = if (stats.repeats > 0) (stats.repeats - 1) % punctuationMarks.count() else null var beforeCursor = 0 - if (lastIndex != null) beforeCursor += ends[lastIndex].length + if (lastIndex != null) beforeCursor += punctuationMarks[lastIndex].length - wkt9.onCommit(ends[index], beforeCursor) + wordStart = true + sentenceStart = index in 1..3 + + wkt9.onCommit(punctuationMarks[index], beforeCursor) + updateIcon() + } + + private fun storeWord() { + val str = word.toString() + val scope = CoroutineScope(Dispatchers.IO + SupervisorJob()) + + word.clear() + + scope.launch { + val word = Word( + word = str, + code = keypad.getCodeForWord(str), + weight = 0, + length = str.length, + locale = locale.language + ) + val result = wordDao.selectWord(str, locale.language) + + if (result == null) wordDao.insert(word) + } } override fun onSwitchLocale(locale: Locale) { this.locale = locale } - override fun onGetSuggestions(results: Array?) { - TODO("Not yet implemented") - } + override fun onDeleteWord(word: Word) {} + override fun onGetSuggestions(results: Array?) {} + override fun onGetSentenceSuggestions(results: Array?) {} + override fun onFinishComposing() {} - override fun onGetSentenceSuggestions(results: Array?) { - TODO("Not yet implemented") - } + override fun toggleCapMode(key: Key) { + super.toggleCapMode(key) - override fun onFinishComposing() { - } - - override fun onLongClickCandidate(text: String) { - TODO("Not yet implemented") + updateIcon() } override fun onRunCommand(command: Command, key: Key, event: KeyEvent, stats: KeyEventStat) { when (command) { - Command.CAP_MODE -> capMode(key) - Command.CHARACTER -> composeCharacter(key, stats) + Command.CAP_MODE -> toggleCapMode(key) + Command.CHARACTER -> composeCharacter(key) Command.DELETE -> delete() Command.INPUT_MODE -> inputMode(key) Command.NUMBER -> triggerOriginalKeyEvent(key) @@ -106,35 +128,75 @@ class LetterInputHandler( override fun onWordSelected(word: Word) {} - private fun composeCharacter(key: Key, stats: KeyEventStat) { - if (lastKey == key) repeats++ - else { - wkt9.onCommit() + private fun composeCharacter(key: Key) { + val composing = timeoutJob?.isActive ?: false - lastKey = key - repeats = 0 + timeoutJob?.cancel() + + if (lastKey == key) { + repeats++ + + word.deleteAt(word.length - 1) + } else { + resetKey(key) + + if (composing) finishComposingChar() } val layout = KeyLayout.chars[key] ?: return val index = repeats % layout.count() + val char = when(effectiveCapMode()) { + null -> layout[index].toString() + else -> layout[index].uppercase() + } - wkt9.onCompose(layout[index].toString()) + lastComposeChar = layout[index] + + word.append(char) + wkt9.onCompose(char) setComposeTimeout() } + private fun resetKey(key: Key? = null) { + lastKey = key + repeats = 0 + } + + private fun finishComposingChar() { + val wordDelimiters = listOf(' ', ',', ':', ';') + val sentenceDelimiters = listOf('.', '?', '!') + + wkt9.onCommit() + + if (sentenceDelimiters.contains(lastComposeChar)) { + sentenceStart = true + wordStart = true + } else if (wordDelimiters.contains(lastComposeChar)) { + sentenceStart = false + wordStart = true + } else { + wordStart = false + sentenceStart = false + } + + updateIcon() + } + private fun setComposeTimeout() { - timeoutJob?.cancel() + val scope = CoroutineScope(Dispatchers.Main + SupervisorJob()) - timeoutJob = timeoutScope.launch { - delay(400L) - wkt9.onCommit("") - - lastKey = null - repeats = 0 + timeoutJob = scope.launch { + delay(composeTimeout) + resetKey() + finishComposingChar() } } private fun delete() { + if (word.isNotEmpty()) word.deleteAt(word.length - 1) + + resetKey() + if (timeoutJob?.isActive == true) { timeoutJob?.cancel() wkt9.onCompose("") @@ -149,14 +211,18 @@ class LetterInputHandler( } private fun updateIcon() { - val icon = when (capMode) { + val icon = when (effectiveCapMode()) { InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS -> R.drawable.letter_upper InputType.TYPE_TEXT_FLAG_CAP_WORDS, - InputType.TYPE_TEXT_FLAG_CAP_SENTENCES -> if (wordStart) R.drawable.letter_cap else R.drawable.letter_lower + InputType.TYPE_TEXT_FLAG_CAP_SENTENCES -> R.drawable.letter_cap else -> R.drawable.letter_lower } -// wkt9.onUpdateStatusIcon(icon) + if (icon == lastIcon) return + + wkt9.onUpdateStatusIcon(icon) + + lastIcon = icon } } // diff --git a/app/src/main/java/net/mezimmah/wkt9/inputhandler/NumberInputHandler.kt b/app/src/main/java/net/mezimmah/wkt9/inputhandler/NumberInputHandler.kt index 298e68c..a912de9 100644 --- a/app/src/main/java/net/mezimmah/wkt9/inputhandler/NumberInputHandler.kt +++ b/app/src/main/java/net/mezimmah/wkt9/inputhandler/NumberInputHandler.kt @@ -4,6 +4,7 @@ import android.util.Log import android.view.KeyEvent import net.mezimmah.wkt9.WKT9IME import net.mezimmah.wkt9.IME +import net.mezimmah.wkt9.R import net.mezimmah.wkt9.entity.Word import net.mezimmah.wkt9.inputmode.InputMode import net.mezimmah.wkt9.keypad.Command @@ -17,9 +18,13 @@ class NumberInputHandler( ) : InputHandler { private val tag = "WKT9" + init { + wkt9.showStatusIcon(R.drawable.number_input) + } + // We don't need to implement methods below override fun onFinishComposing() {} - override fun onLongClickCandidate(text: String) {} + override fun onDeleteWord(word: Word) {} override fun onSwitchLocale(locale: Locale) {} override fun onWordSelected(word: Word) {} diff --git a/app/src/main/java/net/mezimmah/wkt9/inputhandler/WordInputHandler.kt b/app/src/main/java/net/mezimmah/wkt9/inputhandler/WordInputHandler.kt index 6f76c02..0969bc1 100644 --- a/app/src/main/java/net/mezimmah/wkt9/inputhandler/WordInputHandler.kt +++ b/app/src/main/java/net/mezimmah/wkt9/inputhandler/WordInputHandler.kt @@ -1,6 +1,7 @@ package net.mezimmah.wkt9.inputhandler import android.annotation.SuppressLint +import android.text.InputType import android.util.Log import android.view.KeyEvent import kotlinx.coroutines.CoroutineScope @@ -23,7 +24,7 @@ class WordInputHandler( val ime: IME, private var wkt9: WKT9IME, private var locale: Locale, -) : DefaultInputHandler(ime, wkt9), InputHandler { +) : DefaultInputHandler(wkt9), InputHandler { private val codeword = StringBuilder() private var staleCodeword = false private var lastSelectedWord: Word? = null @@ -35,11 +36,17 @@ class WordInputHandler( private val ioScope = CoroutineScope(Dispatchers.IO + SupervisorJob()) private var queryJob: Job? = null - override fun capMode(key: Key): Int? { - return super.capMode(key) + init { + updateIcon() } - override fun finalizeWordOrSentence(stats: KeyEventStat) { + override fun toggleCapMode(key: Key) { + super.toggleCapMode(key) + + updateIcon() + } + + private fun finalizeWordOrSentence(stats: KeyEventStat) { val ends = listOf(" ", ". ", "? ", "! ", ", ", ": ", "; ") val index = stats.repeats % ends.count() val lastIndex = if (stats.repeats > 0) (stats.repeats - 1) % ends.count() else null @@ -48,10 +55,24 @@ class WordInputHandler( if (lastIndex != null) beforeCursor += ends[lastIndex].length wkt9.onCommit(ends[index], beforeCursor) + + sentenceStart = index in 1..3 + + updateIcon() + } + + override fun onDeleteWord(word: Word) { + ioScope.launch { + wordDao.delete(word.id) + + handleCodewordChange(codeword) + } } override fun onSwitchLocale(locale: Locale) { this.locale = locale + + updateIcon() } override fun onFinishComposing() { @@ -63,17 +84,9 @@ class WordInputHandler( lastSelectedWord = null } - override fun onLongClickCandidate(text: String) { - ioScope.launch { - wordDao.delete(text, locale.language) - - handleCodewordChange(codeword) - } - } - override fun onRunCommand(command: Command, key: Key, event: KeyEvent, stats: KeyEventStat) { when (command) { -// Command.CAP_MODE -> capMode(key) + Command.CAP_MODE -> toggleCapMode(key) Command.CHARACTER -> buildCodeword(key) Command.DELETE -> delete() Command.ENTER -> enter(key) @@ -109,7 +122,8 @@ class WordInputHandler( handleCodewordChange(codeword) } else if (codeword.isNotEmpty()) { codeword.clear() - wkt9.onCompose("") + wkt9.onCommit() + wkt9.onDeleteText(1) } else { wkt9.onDeleteText(1) } @@ -129,7 +143,7 @@ class WordInputHandler( // The codeword is stale when it does not yield any candidates in the DB staleCodeword = words.isEmpty() - if (words.isNotEmpty()) wkt9.onWords(words) + if (words.isNotEmpty()) wkt9.onWords(words, effectiveCapMode()) } } @@ -154,15 +168,16 @@ class WordInputHandler( @SuppressLint("DiscouragedApi") private fun updateIcon() { -// val mode = when (capMode) { -// InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS -> "upper" -// InputType.TYPE_TEXT_FLAG_CAP_WORDS, -// InputType.TYPE_TEXT_FLAG_CAP_SENTENCES -> if (wordStart) "cap" else "lower" -// else -> "lower" -// } -// val name = "word_${locale}_${mode}".replace('-', '_').lowercase() -// val icon = context.resources.getIdentifier(name, "drawable", context.packageName) + val mode = when (effectiveCapMode()) { + InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS -> "upper" + InputType.TYPE_TEXT_FLAG_CAP_WORDS, + InputType.TYPE_TEXT_FLAG_CAP_SENTENCES -> "cap" + else -> "lower" + } -// wkt9.onUpdateStatusIcon(icon) + val name = "word_${locale}_${mode}".replace('-', '_').lowercase() + val icon = wkt9.resources.getIdentifier(name, "drawable", wkt9.packageName) + + wkt9.onUpdateStatusIcon(icon) } } \ No newline at end of file diff --git a/app/src/main/java/net/mezimmah/wkt9/keypad/Key.kt b/app/src/main/java/net/mezimmah/wkt9/keypad/Key.kt index 7a0bbfc..e9fb1c5 100644 --- a/app/src/main/java/net/mezimmah/wkt9/keypad/Key.kt +++ b/app/src/main/java/net/mezimmah/wkt9/keypad/Key.kt @@ -133,8 +133,7 @@ enum class Key( ), CommandMapping( - events = listOf(Event.keyDown), - inputModes = listOf(InputMode.Number), + inputModes = listOf(InputMode.Number, InputMode.Idle), overrideConsume = true, consume = null ) diff --git a/app/src/main/java/net/mezimmah/wkt9/layout/Words.kt b/app/src/main/java/net/mezimmah/wkt9/layout/Words.kt index b77b654..876eee0 100644 --- a/app/src/main/java/net/mezimmah/wkt9/layout/Words.kt +++ b/app/src/main/java/net/mezimmah/wkt9/layout/Words.kt @@ -1,10 +1,8 @@ package net.mezimmah.wkt9.layout import android.annotation.SuppressLint -import android.app.PendingIntent.getActivity import android.content.Context import android.util.AttributeSet -import android.util.Log import android.view.ContextThemeWrapper import android.view.View import android.widget.HorizontalScrollView @@ -16,7 +14,6 @@ import net.mezimmah.wkt9.WKT9IME import net.mezimmah.wkt9.entity.Word class Words(context: Context, attributeSet: AttributeSet): HorizontalScrollView(context, attributeSet), View.OnClickListener, View.OnLongClickListener { - private val tag = "WKT9" private var wkt9: WKT9IME private var wordCount: Int = 0 private var current: Int = 0 @@ -94,7 +91,19 @@ class Words(context: Context, attributeSet: AttributeSet): HorizontalScrollView( } override fun onLongClick(v: View?): Boolean { - Log.d(tag, "We need to delete this word from the db") + val words = this.words ?: return true + val wordContainer = findViewById(R.id.words) + + for (i in 0 until wordCount) { + val child: View = wordContainer.getChildAt(i) + + if (v != child) continue + + wordContainer.removeView(child) + wkt9.onDeleteWord(words[i]) + + break + } return true } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 57e7877..67fd763 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -29,6 +29,6 @@ 400 600 800 - 900 + 1000 \ No newline at end of file diff --git a/app/src/main/res/xml/method.xml b/app/src/main/res/xml/method.xml index d936094..69f8d1f 100644 --- a/app/src/main/res/xml/method.xml +++ b/app/src/main/res/xml/method.xml @@ -20,6 +20,12 @@ android:languageTag="es-ES" android:imeSubtypeMode="keyboard" /> + + + +