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
This commit is contained in:
parent
005683bb7e
commit
dd11b26fae
9 changed files with 38 additions and 102 deletions
|
|
@ -134,8 +134,8 @@ abstract class KeyPadHandler extends InputMethodService {
|
||||||
return Key.isNumber(keyCode)
|
return Key.isNumber(keyCode)
|
||||||
|| Key.isOK(keyCode)
|
|| Key.isOK(keyCode)
|
||||||
|| Key.isHotkey(settings, keyCode) || Key.isHotkey(settings, -keyCode)
|
|| Key.isHotkey(settings, keyCode) || Key.isHotkey(settings, -keyCode)
|
||||||
|| keyCode == KeyEvent.KEYCODE_STAR
|
|| (keyCode == KeyEvent.KEYCODE_POUND && onText("#"))
|
||||||
|| keyCode == KeyEvent.KEYCODE_POUND
|
|| (keyCode == KeyEvent.KEYCODE_STAR && onText("*"))
|
||||||
|| ((keyCode == KeyEvent.KEYCODE_DPAD_UP || keyCode == KeyEvent.KEYCODE_DPAD_DOWN) && shouldTrackUpDown())
|
|| ((keyCode == KeyEvent.KEYCODE_DPAD_UP || keyCode == KeyEvent.KEYCODE_DPAD_DOWN) && shouldTrackUpDown())
|
||||||
|| ((keyCode == KeyEvent.KEYCODE_DPAD_LEFT || keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) && shouldTrackLeftRight());
|
|| ((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);
|
return onNumber(Key.codeToNumber(settings, keyCode), true, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Key.isPoundOrStar(keyCode) && onOtherKey(keyCode)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
ignoreNextKeyUp = 0;
|
ignoreNextKeyUp = 0;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -229,8 +225,6 @@ abstract class KeyPadHandler extends InputMethodService {
|
||||||
case KeyEvent.KEYCODE_DPAD_DOWN:
|
case KeyEvent.KEYCODE_DPAD_DOWN:
|
||||||
case KeyEvent.KEYCODE_DPAD_LEFT:
|
case KeyEvent.KEYCODE_DPAD_LEFT:
|
||||||
case KeyEvent.KEYCODE_DPAD_RIGHT: return onArrow(keyCode, keyRepeatCounter > 0);
|
case KeyEvent.KEYCODE_DPAD_RIGHT: return onArrow(keyCode, keyRepeatCounter > 0);
|
||||||
case KeyEvent.KEYCODE_STAR:
|
|
||||||
case KeyEvent.KEYCODE_POUND: return onOtherKey(keyCode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -275,7 +269,7 @@ abstract class KeyPadHandler extends InputMethodService {
|
||||||
abstract public boolean onBackspace();
|
abstract public boolean onBackspace();
|
||||||
abstract protected boolean onNumber(int key, boolean hold, int repeat);
|
abstract protected boolean onNumber(int key, boolean hold, int repeat);
|
||||||
abstract public boolean onOK();
|
abstract public boolean onOK();
|
||||||
abstract protected boolean onOtherKey(int key);
|
abstract public boolean onText(String text);
|
||||||
|
|
||||||
// customized key handlers
|
// customized key handlers
|
||||||
abstract protected boolean onKeyAddWord();
|
abstract protected boolean onKeyAddWord();
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
public boolean onText(String text) {
|
||||||
if (mInputMode.isNumeric() || text.length() == 0) {
|
if (mInputMode.shouldIgnoreText(text)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -331,10 +316,11 @@ public class TraditionalT9 extends KeyPadHandler {
|
||||||
// accept the previously typed word (if any)
|
// accept the previously typed word (if any)
|
||||||
autoCorrectSpace(acceptIncompleteSuggestion(), false, -1);
|
autoCorrectSpace(acceptIncompleteSuggestion(), false, -1);
|
||||||
|
|
||||||
// "type" and accept the text
|
// "type" and accept the new word
|
||||||
mInputMode.onAcceptSuggestion(text);
|
mInputMode.onAcceptSuggestion(text);
|
||||||
textField.setText(text);
|
textField.setText(text);
|
||||||
autoCorrectSpace(text, true, -1);
|
autoCorrectSpace(text, true, -1);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -586,13 +572,6 @@ public class TraditionalT9 extends KeyPadHandler {
|
||||||
mInputMode.determineNextWordTextCase(textField.isThereText(), textField.getTextBeforeCursor());
|
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
|
// display the word suggestions
|
||||||
setSuggestions(mInputMode.getSuggestions());
|
setSuggestions(mInputMode.getSuggestions());
|
||||||
|
|
||||||
|
|
@ -622,7 +601,7 @@ public class TraditionalT9 extends KeyPadHandler {
|
||||||
|
|
||||||
|
|
||||||
private String getComposingText(int maxLength) {
|
private String getComposingText(int maxLength) {
|
||||||
if (maxLength == 0) {
|
if (maxLength == 0 || !suggestionBar.hasElements()) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
public static boolean isOK(int keyCode) {
|
||||||
return
|
return
|
||||||
keyCode == KeyEvent.KEYCODE_DPAD_CENTER
|
keyCode == KeyEvent.KEYCODE_DPAD_CENTER
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,6 @@ abstract public class InputMode {
|
||||||
protected int autoAcceptTimeout = -1;
|
protected int autoAcceptTimeout = -1;
|
||||||
protected Language language;
|
protected Language language;
|
||||||
protected final ArrayList<String> suggestions = new ArrayList<>();
|
protected final ArrayList<String> suggestions = new ArrayList<>();
|
||||||
protected int keyCode = 0;
|
|
||||||
|
|
||||||
|
|
||||||
public static InputMode getInstance(SettingsStore settings, Language language, int mode) {
|
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.
|
// Key handlers. Return "true" when handling the key or "false", when is nothing to do.
|
||||||
public boolean onBackspace() { return false; }
|
public boolean onBackspace() { return false; }
|
||||||
abstract public boolean onNumber(int number, boolean hold, int repeat);
|
abstract public boolean onNumber(int number, boolean hold, int repeat);
|
||||||
abstract public boolean onOtherKey(int key);
|
|
||||||
|
|
||||||
// Suggestions
|
// Suggestions
|
||||||
public void onAcceptSuggestion(@NonNull String word) { onAcceptSuggestion(word, false); }
|
public void onAcceptSuggestion(@NonNull String word) { onAcceptSuggestion(word, false); }
|
||||||
|
|
@ -90,7 +88,6 @@ abstract public class InputMode {
|
||||||
public int getAutoAcceptTimeout() {
|
public int getAutoAcceptTimeout() {
|
||||||
return autoAcceptTimeout;
|
return autoAcceptTimeout;
|
||||||
}
|
}
|
||||||
public int getKeyCode() { return keyCode; }
|
|
||||||
public void changeLanguage(Language newLanguage) {
|
public void changeLanguage(Language newLanguage) {
|
||||||
if (newLanguage != null) {
|
if (newLanguage != null) {
|
||||||
language = newLanguage;
|
language = newLanguage;
|
||||||
|
|
@ -102,6 +99,7 @@ abstract public class InputMode {
|
||||||
public boolean shouldAcceptPreviousSuggestion(int nextKey) { return false; }
|
public boolean shouldAcceptPreviousSuggestion(int nextKey) { return false; }
|
||||||
public boolean shouldAddAutoSpace(InputType inputType, TextField textField, boolean isWordAcceptedManually, 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 shouldDeletePrecedingSpace(InputType inputType) { return false; }
|
||||||
|
public boolean shouldIgnoreText(String text) { return text == null || text.isEmpty(); }
|
||||||
public boolean shouldSelectNextSuggestion() { return false; }
|
public boolean shouldSelectNextSuggestion() { return false; }
|
||||||
|
|
||||||
public boolean shouldTrackUpDown() { return false; }
|
public boolean shouldTrackUpDown() { return false; }
|
||||||
|
|
@ -109,7 +107,6 @@ abstract public class InputMode {
|
||||||
|
|
||||||
public void reset() {
|
public void reset() {
|
||||||
autoAcceptTimeout = -1;
|
autoAcceptTimeout = -1;
|
||||||
keyCode = 0;
|
|
||||||
suggestions.clear();
|
suggestions.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,7 @@
|
||||||
package io.github.sspanak.tt9.ime.modes;
|
package io.github.sspanak.tt9.ime.modes;
|
||||||
|
|
||||||
import android.view.KeyEvent;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
import io.github.sspanak.tt9.ime.helpers.Key;
|
|
||||||
|
|
||||||
public class Mode123 extends ModePassthrough {
|
public class Mode123 extends ModePassthrough {
|
||||||
@Override public int getId() { return MODE_123; }
|
@Override public int getId() { return MODE_123; }
|
||||||
@Override @NonNull public String toString() { return "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 final boolean is123() { return true; }
|
||||||
@Override public boolean isPassthrough() { return false; }
|
@Override public boolean isPassthrough() { return false; }
|
||||||
|
|
||||||
@Override
|
@Override public void reset() {
|
||||||
public boolean onNumber(int number, boolean hold, int repeat) {
|
super.reset();
|
||||||
|
autoAcceptTimeout = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public boolean onNumber(int number, boolean hold, int repeat) {
|
||||||
reset();
|
reset();
|
||||||
keyCode = (number == 0 && hold) ? KeyEvent.KEYCODE_PLUS : Key.numberToCode(number);
|
suggestions.add((number == 0 && hold) ? "+" : String.valueOf(number));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
public boolean onOtherKey(int key) {
|
* shouldIgnoreText
|
||||||
reset();
|
* Since this is a numeric mode, we allow typing only numbers and:
|
||||||
if (Key.isDecimalSeparator(key) || Key.isPoundOrStar(key)) {
|
* 1. In numeric fields, we must allow math chars
|
||||||
keyCode = key;
|
* 2. In dialer fields, we must allow various punctuation chars, because they are used as dialing shortcuts
|
||||||
return true;
|
* at least in Japan.
|
||||||
}
|
* More info and discussion: <a href="https://github.com/sspanak/tt9/issues/241">issue 241 on Github</a>.
|
||||||
|
*/
|
||||||
return false;
|
@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)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,6 @@ public class ModeABC extends InputMode {
|
||||||
changeLanguage(lang);
|
changeLanguage(lang);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onNumber(int number, boolean hold, int repeat) {
|
public boolean onNumber(int number, boolean hold, int repeat) {
|
||||||
if (hold) {
|
if (hold) {
|
||||||
|
|
@ -36,26 +35,11 @@ public class ModeABC extends InputMode {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onOtherKey(int key) {
|
|
||||||
reset();
|
|
||||||
|
|
||||||
if (key > 0) {
|
|
||||||
keyCode = key;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String adjustSuggestionTextCase(String word, int newTextCase) {
|
protected String adjustSuggestionTextCase(String word, int newTextCase) {
|
||||||
return newTextCase == CASE_UPPER ? word.toUpperCase(language.getLocale()) : word.toLowerCase(language.getLocale());
|
return newTextCase == CASE_UPPER ? word.toUpperCase(language.getLocale()) : word.toLowerCase(language.getLocale());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void changeLanguage(Language language) {
|
public void changeLanguage(Language language) {
|
||||||
super.changeLanguage(language);
|
super.changeLanguage(language);
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,6 @@ public class ModePassthrough extends InputMode {
|
||||||
@Override public boolean isNumeric() { return true; }
|
@Override public boolean isNumeric() { return true; }
|
||||||
@Override public boolean isPassthrough() { return true; }
|
@Override public boolean isPassthrough() { return true; }
|
||||||
|
|
||||||
public boolean onNumber(int number, boolean hold, int repeat) { return false; }
|
@Override public boolean onNumber(int number, boolean hold, int repeat) { return false; }
|
||||||
public boolean onOtherKey(int key) { return false; }
|
@Override public boolean shouldIgnoreText(String text) { return true; }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
@Override
|
||||||
public void changeLanguage(Language language) {
|
public void changeLanguage(Language language) {
|
||||||
super.changeLanguage(language);
|
super.changeLanguage(language);
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ package io.github.sspanak.tt9.ui.main.keys;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.KeyEvent;
|
|
||||||
|
|
||||||
import io.github.sspanak.tt9.Logger;
|
import io.github.sspanak.tt9.Logger;
|
||||||
import io.github.sspanak.tt9.R;
|
import io.github.sspanak.tt9.R;
|
||||||
|
|
@ -29,8 +28,8 @@ public class SoftPunctuationKey extends SoftKey {
|
||||||
|
|
||||||
preventRepeat();
|
preventRepeat();
|
||||||
int keyId = getId();
|
int keyId = getId();
|
||||||
if (keyId == R.id.soft_key_punctuation_1) return tt9.onOtherKey(KeyEvent.KEYCODE_COMMA);
|
if (keyId == R.id.soft_key_punctuation_1) return tt9.onText(",");
|
||||||
if (keyId == R.id.soft_key_punctuation_2) return tt9.onOtherKey(KeyEvent.KEYCODE_PERIOD);
|
if (keyId == R.id.soft_key_punctuation_2) return tt9.onText(".");
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -44,8 +43,8 @@ public class SoftPunctuationKey extends SoftKey {
|
||||||
|
|
||||||
int keyId = getId();
|
int keyId = getId();
|
||||||
if (tt9.getInputMode() == InputMode.MODE_123) {
|
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_1) return tt9.onText("*");
|
||||||
if (keyId == R.id.soft_key_punctuation_2) return tt9.onOtherKey(KeyEvent.KEYCODE_POUND);
|
if (keyId == R.id.soft_key_punctuation_2) return tt9.onText("#");
|
||||||
} else {
|
} else {
|
||||||
if (keyId == R.id.soft_key_punctuation_1) return tt9.onText("!");
|
if (keyId == R.id.soft_key_punctuation_1) return tt9.onText("!");
|
||||||
if (keyId == R.id.soft_key_punctuation_2) return tt9.onText("?");
|
if (keyId == R.id.soft_key_punctuation_2) return tt9.onText("?");
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue