From dd11b26fae2fe09064efca26c2f0b28e41a66372 Mon Sep 17 00:00:00 2001 From: Dimo Karaivanov Date: Mon, 31 Jul 2023 12:25:57 +0300 Subject: [PATCH] Numeric mode refactoring again (#321) * proper handling of POUND and STAR, when no hotkey function is assigned to them * Mode123 types numbers as text again, instead of using key codes * removed the InputMode.onOtherKey() functionality, all "other" stuff will be typed as text from now on * slightly optimized TraditionalT9.getComposingText() to return faster when there is no text --- .../github/sspanak/tt9/ime/KeyPadHandler.java | 12 ++---- .../github/sspanak/tt9/ime/TraditionalT9.java | 29 ++------------ .../github/sspanak/tt9/ime/helpers/Key.java | 11 ----- .../sspanak/tt9/ime/modes/InputMode.java | 5 +-- .../github/sspanak/tt9/ime/modes/Mode123.java | 40 +++++++++++-------- .../github/sspanak/tt9/ime/modes/ModeABC.java | 16 -------- .../tt9/ime/modes/ModePassthrough.java | 4 +- .../sspanak/tt9/ime/modes/ModePredictive.java | 14 ------- .../tt9/ui/main/keys/SoftPunctuationKey.java | 9 ++--- 9 files changed, 38 insertions(+), 102 deletions(-) diff --git a/src/io/github/sspanak/tt9/ime/KeyPadHandler.java b/src/io/github/sspanak/tt9/ime/KeyPadHandler.java index 13b52932..383e0bd3 100644 --- a/src/io/github/sspanak/tt9/ime/KeyPadHandler.java +++ b/src/io/github/sspanak/tt9/ime/KeyPadHandler.java @@ -134,8 +134,8 @@ abstract class KeyPadHandler extends InputMethodService { return Key.isNumber(keyCode) || Key.isOK(keyCode) || Key.isHotkey(settings, keyCode) || Key.isHotkey(settings, -keyCode) - || keyCode == KeyEvent.KEYCODE_STAR - || keyCode == KeyEvent.KEYCODE_POUND + || (keyCode == KeyEvent.KEYCODE_POUND && onText("#")) + || (keyCode == KeyEvent.KEYCODE_STAR && onText("*")) || ((keyCode == KeyEvent.KEYCODE_DPAD_UP || keyCode == KeyEvent.KEYCODE_DPAD_DOWN) && shouldTrackUpDown()) || ((keyCode == KeyEvent.KEYCODE_DPAD_LEFT || keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) && shouldTrackLeftRight()); } @@ -170,10 +170,6 @@ abstract class KeyPadHandler extends InputMethodService { return onNumber(Key.codeToNumber(settings, keyCode), true, 0); } - if (Key.isPoundOrStar(keyCode) && onOtherKey(keyCode)) { - return true; - } - ignoreNextKeyUp = 0; return false; } @@ -229,8 +225,6 @@ abstract class KeyPadHandler extends InputMethodService { case KeyEvent.KEYCODE_DPAD_DOWN: case KeyEvent.KEYCODE_DPAD_LEFT: case KeyEvent.KEYCODE_DPAD_RIGHT: return onArrow(keyCode, keyRepeatCounter > 0); - case KeyEvent.KEYCODE_STAR: - case KeyEvent.KEYCODE_POUND: return onOtherKey(keyCode); } return false; @@ -275,7 +269,7 @@ abstract class KeyPadHandler extends InputMethodService { abstract public boolean onBackspace(); abstract protected boolean onNumber(int key, boolean hold, int repeat); abstract public boolean onOK(); - abstract protected boolean onOtherKey(int key); + abstract public boolean onText(String text); // customized key handlers abstract protected boolean onKeyAddWord(); diff --git a/src/io/github/sspanak/tt9/ime/TraditionalT9.java b/src/io/github/sspanak/tt9/ime/TraditionalT9.java index 2c6c0de8..3bf79d6f 100644 --- a/src/io/github/sspanak/tt9/ime/TraditionalT9.java +++ b/src/io/github/sspanak/tt9/ime/TraditionalT9.java @@ -306,23 +306,8 @@ public class TraditionalT9 extends KeyPadHandler { } - public boolean onOtherKey(int keyCode) { - cancelAutoAccept(); - - String acceptedWord = acceptIncompleteSuggestion(); - if (mInputMode.onOtherKey(keyCode)) { - autoCorrectSpace(acceptedWord, false, keyCode); - getSuggestions(); - resetKeyRepeat(); - return true; - } - - return acceptedWord.length() > 0; - } - - public boolean onText(String text) { - if (mInputMode.isNumeric() || text.length() == 0) { + if (mInputMode.shouldIgnoreText(text)) { return false; } @@ -331,10 +316,11 @@ public class TraditionalT9 extends KeyPadHandler { // accept the previously typed word (if any) autoCorrectSpace(acceptIncompleteSuggestion(), false, -1); - // "type" and accept the text + // "type" and accept the new word mInputMode.onAcceptSuggestion(text); textField.setText(text); autoCorrectSpace(text, true, -1); + return true; } @@ -586,13 +572,6 @@ public class TraditionalT9 extends KeyPadHandler { mInputMode.determineNextWordTextCase(textField.isThereText(), textField.getTextBeforeCursor()); } - // key code "suggestions" take priority over words - if (mInputMode.getKeyCode() > 0) { - sendDownUpKeyEvents(mInputMode.getKeyCode()); - mInputMode.reset(); - return; - } - // display the word suggestions setSuggestions(mInputMode.getSuggestions()); @@ -622,7 +601,7 @@ public class TraditionalT9 extends KeyPadHandler { private String getComposingText(int maxLength) { - if (maxLength == 0) { + if (maxLength == 0 || !suggestionBar.hasElements()) { return ""; } diff --git a/src/io/github/sspanak/tt9/ime/helpers/Key.java b/src/io/github/sspanak/tt9/ime/helpers/Key.java index ef469002..3ee4eed5 100644 --- a/src/io/github/sspanak/tt9/ime/helpers/Key.java +++ b/src/io/github/sspanak/tt9/ime/helpers/Key.java @@ -29,17 +29,6 @@ public class Key { } - public static boolean isPoundOrStar(int keyCode) { - return keyCode == KeyEvent.KEYCODE_POUND || keyCode == KeyEvent.KEYCODE_STAR; - } - - public static boolean isDecimalSeparator(int keyCode) { - return - keyCode == KeyEvent.KEYCODE_COMMA - || keyCode == KeyEvent.KEYCODE_NUMPAD_DOT - || keyCode == KeyEvent.KEYCODE_PERIOD; - } - public static boolean isOK(int keyCode) { return keyCode == KeyEvent.KEYCODE_DPAD_CENTER diff --git a/src/io/github/sspanak/tt9/ime/modes/InputMode.java b/src/io/github/sspanak/tt9/ime/modes/InputMode.java index 3742bd40..2d4d052b 100644 --- a/src/io/github/sspanak/tt9/ime/modes/InputMode.java +++ b/src/io/github/sspanak/tt9/ime/modes/InputMode.java @@ -32,7 +32,6 @@ abstract public class InputMode { protected int autoAcceptTimeout = -1; protected Language language; protected final ArrayList suggestions = new ArrayList<>(); - protected int keyCode = 0; public static InputMode getInstance(SettingsStore settings, Language language, int mode) { @@ -53,7 +52,6 @@ abstract public class InputMode { // Key handlers. Return "true" when handling the key or "false", when is nothing to do. public boolean onBackspace() { return false; } abstract public boolean onNumber(int number, boolean hold, int repeat); - abstract public boolean onOtherKey(int key); // Suggestions public void onAcceptSuggestion(@NonNull String word) { onAcceptSuggestion(word, false); } @@ -90,7 +88,6 @@ abstract public class InputMode { public int getAutoAcceptTimeout() { return autoAcceptTimeout; } - public int getKeyCode() { return keyCode; } public void changeLanguage(Language newLanguage) { if (newLanguage != null) { language = newLanguage; @@ -102,6 +99,7 @@ abstract public class InputMode { public boolean shouldAcceptPreviousSuggestion(int nextKey) { return false; } public boolean shouldAddAutoSpace(InputType inputType, TextField textField, boolean isWordAcceptedManually, int nextKey) { return false; } public boolean shouldDeletePrecedingSpace(InputType inputType) { return false; } + public boolean shouldIgnoreText(String text) { return text == null || text.isEmpty(); } public boolean shouldSelectNextSuggestion() { return false; } public boolean shouldTrackUpDown() { return false; } @@ -109,7 +107,6 @@ abstract public class InputMode { public void reset() { autoAcceptTimeout = -1; - keyCode = 0; suggestions.clear(); } diff --git a/src/io/github/sspanak/tt9/ime/modes/Mode123.java b/src/io/github/sspanak/tt9/ime/modes/Mode123.java index a7578a69..48035b3d 100644 --- a/src/io/github/sspanak/tt9/ime/modes/Mode123.java +++ b/src/io/github/sspanak/tt9/ime/modes/Mode123.java @@ -1,11 +1,7 @@ package io.github.sspanak.tt9.ime.modes; -import android.view.KeyEvent; - import androidx.annotation.NonNull; -import io.github.sspanak.tt9.ime.helpers.Key; - public class Mode123 extends ModePassthrough { @Override public int getId() { return MODE_123; } @Override @NonNull public String toString() { return "123"; } @@ -13,21 +9,33 @@ public class Mode123 extends ModePassthrough { @Override public final boolean is123() { return true; } @Override public boolean isPassthrough() { return false; } - @Override - public boolean onNumber(int number, boolean hold, int repeat) { + @Override public void reset() { + super.reset(); + autoAcceptTimeout = 0; + } + + @Override public boolean onNumber(int number, boolean hold, int repeat) { reset(); - keyCode = (number == 0 && hold) ? KeyEvent.KEYCODE_PLUS : Key.numberToCode(number); + suggestions.add((number == 0 && hold) ? "+" : String.valueOf(number)); return true; } - @Override - public boolean onOtherKey(int key) { - reset(); - if (Key.isDecimalSeparator(key) || Key.isPoundOrStar(key)) { - keyCode = key; - return true; - } - - return false; + /** + * shouldIgnoreText + * Since this is a numeric mode, we allow typing only numbers and: + * 1. In numeric fields, we must allow math chars + * 2. In dialer fields, we must allow various punctuation chars, because they are used as dialing shortcuts + * at least in Japan. + * More info and discussion: issue 241 on Github. + */ + @Override public boolean shouldIgnoreText(String text) { + return + text == null + || text.length() != 1 + || !( + (text.charAt(0) > 31 && text.charAt(0) < 65) + || (text.charAt(0) > 90 && text.charAt(0) < 97) + || (text.charAt(0) > 122 && text.charAt(0) < 127) + ); } } diff --git a/src/io/github/sspanak/tt9/ime/modes/ModeABC.java b/src/io/github/sspanak/tt9/ime/modes/ModeABC.java index 1819ec17..3b5830d0 100644 --- a/src/io/github/sspanak/tt9/ime/modes/ModeABC.java +++ b/src/io/github/sspanak/tt9/ime/modes/ModeABC.java @@ -17,7 +17,6 @@ public class ModeABC extends InputMode { changeLanguage(lang); } - @Override public boolean onNumber(int number, boolean hold, int repeat) { if (hold) { @@ -36,26 +35,11 @@ public class ModeABC extends InputMode { return true; } - - @Override - public boolean onOtherKey(int key) { - reset(); - - if (key > 0) { - keyCode = key; - return true; - } - - return false; - } - - @Override protected String adjustSuggestionTextCase(String word, int newTextCase) { return newTextCase == CASE_UPPER ? word.toUpperCase(language.getLocale()) : word.toLowerCase(language.getLocale()); } - @Override public void changeLanguage(Language language) { super.changeLanguage(language); diff --git a/src/io/github/sspanak/tt9/ime/modes/ModePassthrough.java b/src/io/github/sspanak/tt9/ime/modes/ModePassthrough.java index 1af7b31c..29cdbd79 100644 --- a/src/io/github/sspanak/tt9/ime/modes/ModePassthrough.java +++ b/src/io/github/sspanak/tt9/ime/modes/ModePassthrough.java @@ -16,6 +16,6 @@ public class ModePassthrough extends InputMode { @Override public boolean isNumeric() { return true; } @Override public boolean isPassthrough() { return true; } - public boolean onNumber(int number, boolean hold, int repeat) { return false; } - public boolean onOtherKey(int key) { return false; } + @Override public boolean onNumber(int number, boolean hold, int repeat) { return false; } + @Override public boolean shouldIgnoreText(String text) { return true; } } diff --git a/src/io/github/sspanak/tt9/ime/modes/ModePredictive.java b/src/io/github/sspanak/tt9/ime/modes/ModePredictive.java index d078d4cd..f5f7c92d 100644 --- a/src/io/github/sspanak/tt9/ime/modes/ModePredictive.java +++ b/src/io/github/sspanak/tt9/ime/modes/ModePredictive.java @@ -89,20 +89,6 @@ public class ModePredictive extends InputMode { } - @Override - public boolean onOtherKey(int key) { - reset(); - - if (key > 0) { - disablePredictions = true; - keyCode = key; - return true; - } - - return false; - } - - @Override public void changeLanguage(Language language) { super.changeLanguage(language); diff --git a/src/io/github/sspanak/tt9/ui/main/keys/SoftPunctuationKey.java b/src/io/github/sspanak/tt9/ui/main/keys/SoftPunctuationKey.java index b75ad9b1..128010e8 100644 --- a/src/io/github/sspanak/tt9/ui/main/keys/SoftPunctuationKey.java +++ b/src/io/github/sspanak/tt9/ui/main/keys/SoftPunctuationKey.java @@ -2,7 +2,6 @@ package io.github.sspanak.tt9.ui.main.keys; import android.content.Context; import android.util.AttributeSet; -import android.view.KeyEvent; import io.github.sspanak.tt9.Logger; import io.github.sspanak.tt9.R; @@ -29,8 +28,8 @@ public class SoftPunctuationKey extends SoftKey { preventRepeat(); int keyId = getId(); - if (keyId == R.id.soft_key_punctuation_1) return tt9.onOtherKey(KeyEvent.KEYCODE_COMMA); - if (keyId == R.id.soft_key_punctuation_2) return tt9.onOtherKey(KeyEvent.KEYCODE_PERIOD); + if (keyId == R.id.soft_key_punctuation_1) return tt9.onText(","); + if (keyId == R.id.soft_key_punctuation_2) return tt9.onText("."); return false; } @@ -44,8 +43,8 @@ public class SoftPunctuationKey extends SoftKey { int keyId = getId(); if (tt9.getInputMode() == InputMode.MODE_123) { - if (keyId == R.id.soft_key_punctuation_1) return tt9.onOtherKey(KeyEvent.KEYCODE_STAR); - if (keyId == R.id.soft_key_punctuation_2) return tt9.onOtherKey(KeyEvent.KEYCODE_POUND); + if (keyId == R.id.soft_key_punctuation_1) return tt9.onText("*"); + if (keyId == R.id.soft_key_punctuation_2) return tt9.onText("#"); } else { if (keyId == R.id.soft_key_punctuation_1) return tt9.onText("!"); if (keyId == R.id.soft_key_punctuation_2) return tt9.onText("?");