diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index a0a39d0e..bc09741c 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -23,6 +23,7 @@
Зареди речник
Неуспешно зареждане. Липсва речник за „%1$s“.
Речникът е изтрит успешно.
+ Режим АБВ
Облик
Бутони за бърз достъп
Бутони на екрана
@@ -43,6 +44,8 @@
(задръж)
Зареждане на речник
Зареждането е отменено.
+ Автоматичен избор на буква
+ Автоматично избирай текущата буква след кратко изчакване.
Автоматичен интервал
Добавяй автоматично интервал след препинателни знаци и думи.
Автоматични главни букви
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index 78d07e9f..a6457030 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -28,8 +28,11 @@
Клавиатура
Пробел
Новая строка
+ Режим AБВ
Внешний вид
Горячие клавиши
+ Автоматический выбор буквы
+ Автоматически ввести выбранную букву после короткого ожидания.
Авто пробел
Автоматически добавлять пробел после слов и знаков препинания.
Авто заглавные буквы
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index 54a82f79..38f05974 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -26,9 +26,12 @@
Клавіатура
Пробіл
Новий рядок
+ Режим AБВ
Вигляд
Режим підсказки
Гарячі клавіші
+ Автоматичний вибір букви
+ Автоматично ввести вибрану букву після короткої затримки.
Авто пробіл
Автоматично додавати пробіл після слів і розділових знаків.
Авто заголовні букви
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 487e197b..3ef2f1f6 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -15,12 +15,16 @@
Type a word…
About
+ ABC Mode
Appearance
Predictive Mode
Select Hotkeys
Keypad
Initial Setup
+
+ Automatic Letter Select
+ Automatically type the selected letter after a short delay.
Automatic Space
Automatically add a space after punctuation or words.
Automatic Capitalization
diff --git a/res/xml/prefs_screen_keypad.xml b/res/xml/prefs_screen_keypad.xml
index 8a75f2a1..59ac7806 100644
--- a/res/xml/prefs_screen_keypad.xml
+++ b/res/xml/prefs_screen_keypad.xml
@@ -45,4 +45,18 @@
+
+
+
+
+
+
diff --git a/src/io/github/sspanak/tt9/ime/TraditionalT9.java b/src/io/github/sspanak/tt9/ime/TraditionalT9.java
index a04d2f4d..aeedda55 100644
--- a/src/io/github/sspanak/tt9/ime/TraditionalT9.java
+++ b/src/io/github/sspanak/tt9/ime/TraditionalT9.java
@@ -2,6 +2,8 @@ package io.github.sspanak.tt9.ime;
import android.content.Context;
import android.os.Build;
+import android.os.Handler;
+import android.os.Looper;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.EditorInfo;
@@ -31,6 +33,7 @@ public class TraditionalT9 extends KeyPadHandler {
private boolean isActive = false;
@NotNull private TextField textField = new TextField(null, null);
@NotNull private InputType inputType = new InputType(null, null);
+ @NotNull private final Handler autoAcceptHandler = new Handler(Looper.getMainLooper());
// input mode
private ArrayList allowedInputModes = new ArrayList<>();
@@ -136,6 +139,8 @@ public class TraditionalT9 extends KeyPadHandler {
// in case we are back from Settings screen, update the language list
mEnabledLanguages = settings.getEnabledLanguageIds();
validateLanguages();
+
+ resetKeyRepeat();
determineInputMode();
determineTextCase();
}
@@ -192,6 +197,7 @@ public class TraditionalT9 extends KeyPadHandler {
protected void onFinishTyping() {
+ cancelAutoAccept();
isActive = false;
}
@@ -213,6 +219,7 @@ public class TraditionalT9 extends KeyPadHandler {
return false;
}
+ cancelAutoAccept();
resetKeyRepeat();
if (mInputMode.onBackspace()) {
@@ -228,6 +235,8 @@ public class TraditionalT9 extends KeyPadHandler {
public boolean onOK() {
+ cancelAutoAccept();
+
if (!isInputViewShown() && !textField.isThereText()) {
forceShowWindowIfHidden();
return true;
@@ -248,6 +257,7 @@ public class TraditionalT9 extends KeyPadHandler {
protected boolean onUp() {
if (previousSuggestion()) {
+ cancelAutoAccept();
mInputMode.setWordStem(suggestionBar.getCurrentSuggestion(), true);
textField.setComposingTextWithHighlightedStem(suggestionBar.getCurrentSuggestion(), mInputMode);
return true;
@@ -259,6 +269,7 @@ public class TraditionalT9 extends KeyPadHandler {
protected boolean onDown() {
if (nextSuggestion()) {
+ cancelAutoAccept();
mInputMode.setWordStem(suggestionBar.getCurrentSuggestion(), true);
textField.setComposingTextWithHighlightedStem(suggestionBar.getCurrentSuggestion(), mInputMode);
return true;
@@ -269,6 +280,8 @@ public class TraditionalT9 extends KeyPadHandler {
protected boolean onLeft() {
+ cancelAutoAccept();
+
if (mInputMode.clearWordStem()) {
mInputMode.loadSuggestions(this::getSuggestions, getComposingText());
} else {
@@ -280,6 +293,8 @@ public class TraditionalT9 extends KeyPadHandler {
protected boolean onRight(boolean repeat) {
+ cancelAutoAccept();
+
String filter;
if (repeat && !suggestionBar.getSuggestion(1).equals("")) {
filter = suggestionBar.getSuggestion(1);
@@ -306,6 +321,7 @@ public class TraditionalT9 extends KeyPadHandler {
* @return boolean
*/
protected boolean onNumber(int key, boolean hold, int repeat) {
+ cancelAutoAccept();
forceShowWindowIfHidden();
String currentWord = getComposingText();
@@ -329,6 +345,7 @@ public class TraditionalT9 extends KeyPadHandler {
if (mInputMode.shouldSelectNextSuggestion() && !isSuggestionViewHidden()) {
nextSuggestion();
+ scheduleAutoAccept(mInputMode.getAutoAcceptTimeout());
} else {
getSuggestions();
}
@@ -338,6 +355,8 @@ public class TraditionalT9 extends KeyPadHandler {
public boolean onOtherKey(int keyCode) {
+ cancelAutoAccept();
+
String acceptedWord = acceptIncompleteSuggestion();
if (mInputMode.onOtherKey(keyCode)) {
autoCorrectSpace(acceptedWord, false);
@@ -355,6 +374,8 @@ public class TraditionalT9 extends KeyPadHandler {
return false;
}
+ cancelAutoAccept();
+
// accept the previously typed word (if any)
autoCorrectSpace(acceptIncompleteSuggestion(), false);
@@ -371,6 +392,7 @@ public class TraditionalT9 extends KeyPadHandler {
return false;
}
+ cancelAutoAccept();
showAddWord();
return true;
}
@@ -378,6 +400,7 @@ public class TraditionalT9 extends KeyPadHandler {
public boolean onKeyNextLanguage() {
if (nextLang()) {
+ cancelAutoAccept();
commitCurrentSuggestion(false);
mInputMode.changeLanguage(mLanguage);
mInputMode.reset();
@@ -390,12 +413,12 @@ public class TraditionalT9 extends KeyPadHandler {
return true;
}
-
return false;
}
public boolean onKeyNextInputMode() {
+ scheduleAutoAccept(mInputMode.getAutoAcceptTimeout()); // restart the timer
nextInputMode();
mainView.render();
@@ -413,6 +436,7 @@ public class TraditionalT9 extends KeyPadHandler {
return false;
}
+ cancelAutoAccept();
UI.showSettingsScreen(this);
return true;
}
@@ -456,6 +480,32 @@ public class TraditionalT9 extends KeyPadHandler {
}
+ private boolean scheduleAutoAccept(int delay) {
+ cancelAutoAccept();
+
+ if (delay == 0) {
+ this.onOK();
+ return true;
+ } else if (delay > 0) {
+ autoAcceptHandler.postDelayed(this::autoAccept, delay);
+ }
+
+ return false;
+ }
+
+
+ private void cancelAutoAccept() {
+ autoAcceptHandler.removeCallbacksAndMessages(null);
+ }
+
+
+ private void autoAccept() {
+ if (suggestionBar.hasElements()) {
+ this.onOK();
+ }
+ }
+
+
private String acceptIncompleteSuggestion() {
String currentWord = getComposingText();
mInputMode.onAcceptSuggestion(currentWord);
@@ -504,12 +554,11 @@ public class TraditionalT9 extends KeyPadHandler {
return;
}
- // display the list of suggestions
+ // display the word suggestions
setSuggestions(mInputMode.getSuggestions());
- // flush the first suggestion immediately, if the InputMode has requested it
- if (mInputMode.getAutoAcceptTimeout() == 0) {
- onOK();
+ // flush the first suggestion, if the InputMode has requested it
+ if (scheduleAutoAccept(mInputMode.getAutoAcceptTimeout())) {
return;
}
diff --git a/src/io/github/sspanak/tt9/ime/modes/InputMode.java b/src/io/github/sspanak/tt9/ime/modes/InputMode.java
index fb3f9274..7de4f5cb 100644
--- a/src/io/github/sspanak/tt9/ime/modes/InputMode.java
+++ b/src/io/github/sspanak/tt9/ime/modes/InputMode.java
@@ -40,7 +40,7 @@ abstract public class InputMode {
case MODE_PREDICTIVE:
return new ModePredictive(settings, language);
case MODE_ABC:
- return new ModeABC(language);
+ return new ModeABC(settings, language);
case MODE_DIALER:
return new ModeDialer();
default:
diff --git a/src/io/github/sspanak/tt9/ime/modes/ModeABC.java b/src/io/github/sspanak/tt9/ime/modes/ModeABC.java
index 5d9e7c5e..4330a5f6 100644
--- a/src/io/github/sspanak/tt9/ime/modes/ModeABC.java
+++ b/src/io/github/sspanak/tt9/ime/modes/ModeABC.java
@@ -3,13 +3,17 @@ package io.github.sspanak.tt9.ime.modes;
import androidx.annotation.NonNull;
import io.github.sspanak.tt9.languages.Language;
+import io.github.sspanak.tt9.preferences.SettingsStore;
public class ModeABC extends InputMode {
+ private final SettingsStore settings;
+
public int getId() { return MODE_ABC; }
private boolean shouldSelectNextLetter = false;
- ModeABC(Language lang) {
+ ModeABC(SettingsStore settings, Language lang) {
+ this.settings = settings;
changeLanguage(lang);
}
@@ -22,9 +26,11 @@ public class ModeABC extends InputMode {
autoAcceptTimeout = 0;
} else if (repeat > 0) {
shouldSelectNextLetter = true;
+ autoAcceptTimeout = settings.getAbcAutoAcceptTimeout();
} else {
reset();
suggestions.addAll(language.getKeyCharacters(number));
+ autoAcceptTimeout = settings.getAbcAutoAcceptTimeout();
}
return true;
diff --git a/src/io/github/sspanak/tt9/preferences/SettingsStore.java b/src/io/github/sspanak/tt9/preferences/SettingsStore.java
index e2346af2..aaddc2bf 100644
--- a/src/io/github/sspanak/tt9/preferences/SettingsStore.java
+++ b/src/io/github/sspanak/tt9/preferences/SettingsStore.java
@@ -208,6 +208,7 @@ public class SettingsStore {
/************* typing settings *************/
+ public int getAbcAutoAcceptTimeout() { return prefs.getBoolean("abc_auto_accept", true) ? 800 : -1; }
public boolean getAutoSpace() { return prefs.getBoolean("auto_space", true); }
public boolean getAutoTextCase() { return prefs.getBoolean("auto_text_case", true); }
public String getDoubleZeroChar() {