diff --git a/res/layout/main_numpad.xml b/res/layout/main_numpad.xml index 92773a74..76d922b8 100644 --- a/res/layout/main_numpad.xml +++ b/res/layout/main_numpad.xml @@ -34,9 +34,52 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" - android:paddingTop="@dimen/numpad_padding_top" android:paddingBottom="@dimen/numpad_padding_bottom"> + + + + + + + + + + + + + Зелена слушалка Добавяне на нова дума Триене на текст + Изчистване на филтър + Филтриране на думи + Предишна дума + Следваща дума Следващ eзик Режим на писане Настройки diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml index 8456fce0..6b27ab22 100644 --- a/res/values-fr/strings.xml +++ b/res/values-fr/strings.xml @@ -9,7 +9,6 @@ Le mot «%1$s» est déjà dans le dictionnaire. Ajouter un mot - À propos de l\'application Aide Thème sombre @@ -23,6 +22,7 @@ Charger le dictionnaire Echec du chargement. Dictionnaire «%1$s» introuvable. Raccourcis clavier + Saisie ABC Apparance Echec du chargement. Mot inadmissible «%1$s» à la ligne %2$d de langue «%3$s». Le dictionaire est supprimé avec succès. @@ -30,6 +30,8 @@ Chargement du dictionnaire Chargement est annulé. Saisie intuitive + Sélection de lettre automatique + Ajouter automatiquement la lettre sélectionnée après un court délai. Espace automatique Majuscules automatiques Ajouter automatiquement un espace après signes de ponctuation et mots. @@ -37,6 +39,17 @@ Pas de dictionnaire pour langue «%1$s». Veuillez le charger à l\'écran Paramètres. Clavier Espace + Ajouter un mot + Retour arrière + Supprimer le filtre + Filtrer les mots + Mot précédent + Mot suivant + Langue suivante + Mode de saisie suivant + Afficher les paramètres + Restaurer les paramètres par défaut + Paramètres par défaut sont restaurés. État Sélectionnez le clavier par défaut Traditional T9 est activé diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml index 34d42e14..59fc9283 100644 --- a/res/values-ru/strings.xml +++ b/res/values-ru/strings.xml @@ -43,6 +43,10 @@ Отсутствует словарь для языка «%1$s». Вы можете загрузить его в Настройках. Добавить новое слово Стереть + Удалить фильтр + Фильтровать слова + Предыдущее слово + Следующее слово Следующий язык Режим ввода Настройки diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml index 163746ca..1ae92200 100644 --- a/res/values-uk/strings.xml +++ b/res/values-uk/strings.xml @@ -48,7 +48,11 @@ (затиснути) Додати нове слово Стерти - Слідуюча мова + Видалити фільтр + Фільтрувати слова + Попереднє слово + Наступне слово + Наступна мова Режим вводу Налаштування Налаштування кнопок за замовчуванням відновлено diff --git a/res/values/dimens.xml b/res/values/dimens.xml index 1263f984..7139e6fb 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -15,9 +15,9 @@ 19sp - 5dp 15dp 56dp + 10dp 17sp 32dp diff --git a/res/values/strings.xml b/res/values/strings.xml index e21d71f9..c506fbc6 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -56,6 +56,10 @@ Add Word key Backspace key + Clear Filter key + Filter Suggestions key + Previous Suggestion key + Next Suggestion key Next Language key Input Mode key Show Settings key @@ -73,6 +77,10 @@ -- Back Call + + + + Menu Left Func Right Func diff --git a/res/values/styles.xml b/res/values/styles.xml index f2c88d9f..f4d21dae 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -11,4 +11,12 @@ match_parent 1dp + + diff --git a/res/xml/prefs_screen_hotkeys.xml b/res/xml/prefs_screen_hotkeys.xml index 695a42f9..0c7409aa 100644 --- a/res/xml/prefs_screen_hotkeys.xml +++ b/res/xml/prefs_screen_hotkeys.xml @@ -14,6 +14,30 @@ app:layout="@layout/pref_dropdown" app:title="@string/function_backspace_key" /> + + + + + + + + 0); + case KeyEvent.KEYCODE_DPAD_UP: + 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); } @@ -273,14 +273,11 @@ abstract class KeyPadHandler extends InputMethodService { abstract protected boolean shouldTrackLeftRight(); // default hardware key handlers + abstract protected boolean onArrow(int key, boolean repeat); abstract public boolean onBackspace(); - abstract public boolean onOK(); - abstract protected boolean onUp(); - abstract protected boolean onDown(); - abstract protected boolean onLeft(); - abstract protected boolean onRight(boolean repeat); abstract protected boolean onNumber(int key, boolean hold, int repeat); - abstract protected boolean onOtherKey(int keyCode); + abstract public boolean onOK(); + abstract protected boolean onOtherKey(int key); // 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 beb23746..a81aeec6 100644 --- a/src/io/github/sspanak/tt9/ime/TraditionalT9.java +++ b/src/io/github/sspanak/tt9/ime/TraditionalT9.java @@ -210,6 +210,21 @@ public class TraditionalT9 extends KeyPadHandler { } + public boolean onArrow(int key, boolean repeat) { + if (key == settings.getKeyFilterClear()) { + return onKeyFilterClear(); + } else if (key == settings.getKeyFilterSuggestions()) { + return onKeyFilterSuggestions(repeat); + } else if (key == settings.getKeyPreviousSuggestion()) { + return onKeyPreviousSuggestion(); + } else if (key == settings.getKeyNextSuggestion()) { + return onKeyNextSuggestion(); + } + + return false; + } + + public boolean onBackspace() { // 1. Dialer fields seem to handle backspace on their own and we must ignore it, // otherwise, keyDown race condition occur for all keys. @@ -235,84 +250,6 @@ public class TraditionalT9 extends KeyPadHandler { } - public boolean onOK() { - cancelAutoAccept(); - - if (!isInputViewShown() && !textField.isThereText()) { - forceShowWindowIfHidden(); - return true; - } else if (isSuggestionViewHidden()) { - return performOKAction(); - } - - String word = suggestionBar.getCurrentSuggestion(); - - mInputMode.onAcceptSuggestion(word); - commitCurrentSuggestion(); - autoCorrectSpace(word, true, KeyEvent.KEYCODE_ENTER); - resetKeyRepeat(); - - return true; - } - - - protected boolean onUp() { - if (previousSuggestion()) { - cancelAutoAccept(); - mInputMode.setWordStem(suggestionBar.getCurrentSuggestion(), true); - textField.setComposingTextWithHighlightedStem(suggestionBar.getCurrentSuggestion(), mInputMode); - return true; - } - - return false; - } - - - protected boolean onDown() { - if (nextSuggestion()) { - cancelAutoAccept(); - mInputMode.setWordStem(suggestionBar.getCurrentSuggestion(), true); - textField.setComposingTextWithHighlightedStem(suggestionBar.getCurrentSuggestion(), mInputMode); - return true; - } - - return false; - } - - - protected boolean onLeft() { - cancelAutoAccept(); - - if (mInputMode.clearWordStem()) { - mInputMode.loadSuggestions(this::getSuggestions, getComposingText()); - } else { - jumpBeforeComposingText(); - } - - return true; - } - - - protected boolean onRight(boolean repeat) { - cancelAutoAccept(); - - String filter; - if (repeat && !suggestionBar.getSuggestion(1).equals("")) { - filter = suggestionBar.getSuggestion(1); - } else { - filter = getComposingText(); - } - - if (mInputMode.setWordStem(filter, repeat)) { - mInputMode.loadSuggestions(this::getSuggestions, filter); - } else if (filter.length() == 0) { - mInputMode.reset(); - } - - return true; - } - - /** * onNumber * @@ -355,6 +292,27 @@ public class TraditionalT9 extends KeyPadHandler { } + public boolean onOK() { + cancelAutoAccept(); + + if (!isInputViewShown() && !textField.isThereText()) { + forceShowWindowIfHidden(); + return true; + } else if (isSuggestionViewHidden()) { + return performOKAction(); + } + + String word = suggestionBar.getCurrentSuggestion(); + + mInputMode.onAcceptSuggestion(word); + commitCurrentSuggestion(); + autoCorrectSpace(word, true, KeyEvent.KEYCODE_ENTER); + resetKeyRepeat(); + + return true; + } + + public boolean onOtherKey(int keyCode) { cancelAutoAccept(); @@ -399,6 +357,70 @@ public class TraditionalT9 extends KeyPadHandler { } + public boolean onKeyFilterClear() { + if (!suggestionBar.hasElements()) { + return false; + } + + cancelAutoAccept(); + + if (mInputMode.clearWordStem()) { + mInputMode.loadSuggestions(this::getSuggestions, getComposingText()); + return true; + } + + return false; + } + + + public boolean onKeyFilterSuggestions(boolean repeat) { + if (!suggestionBar.hasElements()) { + return false; + } + + cancelAutoAccept(); + + String filter; + if (repeat && !suggestionBar.getSuggestion(1).equals("")) { + filter = suggestionBar.getSuggestion(1); + } else { + filter = getComposingText(); + } + + if (mInputMode.setWordStem(filter, repeat)) { + mInputMode.loadSuggestions(this::getSuggestions, filter); + } else if (filter.length() == 0) { + mInputMode.reset(); + } + + return true; + } + + + public boolean onKeyNextSuggestion() { + if (nextSuggestion()) { + cancelAutoAccept(); + mInputMode.setWordStem(suggestionBar.getCurrentSuggestion(), true); + textField.setComposingTextWithHighlightedStem(suggestionBar.getCurrentSuggestion(), mInputMode); + return true; + } + + return false; + } + + + public boolean onKeyPreviousSuggestion() { + if (previousSuggestion()) { + cancelAutoAccept(); + mInputMode.setWordStem(suggestionBar.getCurrentSuggestion(), true); + textField.setComposingTextWithHighlightedStem(suggestionBar.getCurrentSuggestion(), mInputMode); + return true; + } + + return false; + } + + public boolean onKeyNextLanguage() { if (nextLang()) { cancelAutoAccept(); @@ -660,17 +682,6 @@ public class TraditionalT9 extends KeyPadHandler { } - private void jumpBeforeComposingText() { - String word = getComposingText(); - - textField.setComposingText(word, 0); - textField.finishComposingText(); - mInputMode.onAcceptSuggestion(word); - mInputMode.reset(); - setSuggestions(null); - } - - private void autoCorrectSpace(String currentWord, boolean isWordAcceptedManually, int nextKey) { if (mInputMode.shouldDeletePrecedingSpace(inputType)) { textField.deletePrecedingSpace(currentWord); diff --git a/src/io/github/sspanak/tt9/preferences/SettingsStore.java b/src/io/github/sspanak/tt9/preferences/SettingsStore.java index 653aba4d..877e602e 100644 --- a/src/io/github/sspanak/tt9/preferences/SettingsStore.java +++ b/src/io/github/sspanak/tt9/preferences/SettingsStore.java @@ -160,10 +160,24 @@ public class SettingsStore { return !prefs.getBoolean("hotkeys_initialized", false); } - public void setDefaultKeys(int addWord, int backspace, int nextInputMode, int nextLanguage, int showSettings) { + public void setDefaultKeys( + int addWord, + int backspace, + int filterClear, + int filterSuggestions, + int previousSuggestion, + int nextSuggestion, + int nextInputMode, + int nextLanguage, + int showSettings + ) { prefsEditor .putString(SectionKeymap.ITEM_ADD_WORD, String.valueOf(addWord)) .putString(SectionKeymap.ITEM_BACKSPACE, String.valueOf(backspace)) + .putString(SectionKeymap.ITEM_FILTER_CLEAR, String.valueOf(filterClear)) + .putString(SectionKeymap.ITEM_FILTER_SUGGESTIONS, String.valueOf(filterSuggestions)) + .putString(SectionKeymap.ITEM_PREVIOUS_SUGGESTION, String.valueOf(previousSuggestion)) + .putString(SectionKeymap.ITEM_NEXT_SUGGESTION, String.valueOf(nextSuggestion)) .putString(SectionKeymap.ITEM_NEXT_INPUT_MODE, String.valueOf(nextInputMode)) .putString(SectionKeymap.ITEM_NEXT_LANGUAGE, String.valueOf(nextLanguage)) .putString(SectionKeymap.ITEM_SHOW_SETTINGS, String.valueOf(showSettings)) @@ -185,6 +199,18 @@ public class SettingsStore { public int getKeyBackspace() { return getFunctionKey(SectionKeymap.ITEM_BACKSPACE); } + public int getKeyFilterClear() { + return getFunctionKey(SectionKeymap.ITEM_FILTER_CLEAR); + } + public int getKeyFilterSuggestions() { + return getFunctionKey(SectionKeymap.ITEM_FILTER_SUGGESTIONS); + } + public int getKeyPreviousSuggestion() { + return getFunctionKey(SectionKeymap.ITEM_PREVIOUS_SUGGESTION); + } + public int getKeyNextSuggestion() { + return getFunctionKey(SectionKeymap.ITEM_NEXT_SUGGESTION); + } public int getKeyNextInputMode() { return getFunctionKey(SectionKeymap.ITEM_NEXT_INPUT_MODE); } @@ -195,6 +221,7 @@ public class SettingsStore { return getFunctionKey(SectionKeymap.ITEM_SHOW_SETTINGS); } + /************* UI settings *************/ public boolean getDarkTheme() { return prefs.getBoolean("pref_dark_theme", true); } diff --git a/src/io/github/sspanak/tt9/preferences/helpers/Hotkeys.java b/src/io/github/sspanak/tt9/preferences/helpers/Hotkeys.java index 84346a3d..11c25c08 100644 --- a/src/io/github/sspanak/tt9/preferences/helpers/Hotkeys.java +++ b/src/io/github/sspanak/tt9/preferences/helpers/Hotkeys.java @@ -43,24 +43,36 @@ public class Hotkeys { /** * setDefault * Applies the default hotkey scheme. + * * When a standard "Backspace" hardware key is available, "Backspace" hotkey association is not necessary, * so it will be left out blank, to allow the hardware key do its job. * When the on-screen keyboard is on, "Back" is also not associated, because it will cause weird user * experience. Instead the on-screen "Backspace" key can be used. + * + * Arrow keys for manipulating suggestions are also assigned only if available. */ public static void setDefault(SettingsStore settings) { - int backspaceKeyCode = KeyEvent.KEYCODE_BACK; + int backspace = KeyEvent.KEYCODE_BACK; if ( KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_CLEAR) || KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_DEL) || settings.getShowSoftNumpad() ) { - backspaceKeyCode = 0; + backspace = 0; } + int clearFilter = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_DPAD_LEFT) && !settings.getShowSoftNumpad() ? KeyEvent.KEYCODE_DPAD_LEFT : 0; + int filter = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_DPAD_RIGHT) && !settings.getShowSoftNumpad() ? KeyEvent.KEYCODE_DPAD_RIGHT : 0; + int nextSuggestion = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_DPAD_UP) && !settings.getShowSoftNumpad() ? KeyEvent.KEYCODE_DPAD_UP : 0; + int previousSuggestion = KeyCharacterMap.deviceHasKey(KeyEvent.KEYCODE_DPAD_DOWN) && !settings.getShowSoftNumpad() ? KeyEvent.KEYCODE_DPAD_DOWN : 0; + settings.setDefaultKeys( KeyEvent.KEYCODE_STAR, - backspaceKeyCode, + backspace, + clearFilter, + filter, + nextSuggestion, + previousSuggestion, KeyEvent.KEYCODE_POUND, -KeyEvent.KEYCODE_POUND, // negative means "hold" -KeyEvent.KEYCODE_STAR @@ -140,20 +152,27 @@ public class Hotkeys { addIfDeviceHasKey(KeyEvent.KEYCODE_F2, "F2", true); addIfDeviceHasKey(KeyEvent.KEYCODE_F3, "F3", true); addIfDeviceHasKey(KeyEvent.KEYCODE_F4, "F4", true); + addIfDeviceHasKey(KeyEvent.KEYCODE_MENU, R.string.key_menu, true); addIfDeviceHasKey(KeyEvent.KEYCODE_SOFT_LEFT, R.string.key_soft_left, false); addIfDeviceHasKey(KeyEvent.KEYCODE_SOFT_RIGHT, R.string.key_soft_right, false); - addIfDeviceHasKey(KeyEvent.KEYCODE_VOLUME_DOWN, R.string.key_volume_down, false); - addIfDeviceHasKey(KeyEvent.KEYCODE_VOLUME_UP, R.string.key_volume_up, false); - add(KeyEvent.KEYCODE_POUND, "#", true); add(KeyEvent.KEYCODE_STAR, "✱", true); + addIfDeviceHasKey(KeyEvent.KEYCODE_DPAD_UP, R.string.key_dpad_up, false); + addIfDeviceHasKey(KeyEvent.KEYCODE_DPAD_DOWN, R.string.key_dpad_down, false); + addIfDeviceHasKey(KeyEvent.KEYCODE_DPAD_LEFT, R.string.key_dpad_left, false); + addIfDeviceHasKey(KeyEvent.KEYCODE_DPAD_RIGHT, R.string.key_dpad_right, false); + addIfDeviceHasKey(KeyEvent.KEYCODE_NUMPAD_ADD, "Num +", true); addIfDeviceHasKey(KeyEvent.KEYCODE_NUMPAD_SUBTRACT, "Num -", true); addIfDeviceHasKey(KeyEvent.KEYCODE_NUMPAD_MULTIPLY, "Num *", true); addIfDeviceHasKey(KeyEvent.KEYCODE_NUMPAD_DIVIDE, "Num /", true); addIfDeviceHasKey(KeyEvent.KEYCODE_NUMPAD_DOT, "Num .", true); + + addIfDeviceHasKey(KeyEvent.KEYCODE_VOLUME_DOWN, R.string.key_volume_down, false); + addIfDeviceHasKey(KeyEvent.KEYCODE_VOLUME_UP, R.string.key_volume_up, false); + } } diff --git a/src/io/github/sspanak/tt9/preferences/items/SectionKeymap.java b/src/io/github/sspanak/tt9/preferences/items/SectionKeymap.java index 325e3b44..75339693 100644 --- a/src/io/github/sspanak/tt9/preferences/items/SectionKeymap.java +++ b/src/io/github/sspanak/tt9/preferences/items/SectionKeymap.java @@ -15,6 +15,10 @@ import io.github.sspanak.tt9.preferences.helpers.Hotkeys; public class SectionKeymap { public static final String ITEM_ADD_WORD = "key_add_word"; public static final String ITEM_BACKSPACE = "key_backspace"; + public static final String ITEM_FILTER_CLEAR = "key_filter_clear"; + public static final String ITEM_FILTER_SUGGESTIONS = "key_filter_suggestions"; + public static final String ITEM_PREVIOUS_SUGGESTION = "key_previous_suggestion"; + public static final String ITEM_NEXT_SUGGESTION = "key_next_suggestion"; public static final String ITEM_NEXT_INPUT_MODE = "key_next_input_mode"; public static final String ITEM_NEXT_LANGUAGE = "key_next_language"; public static final String ITEM_SHOW_SETTINGS = "key_show_settings"; diff --git a/src/io/github/sspanak/tt9/preferences/screens/HotkeysScreen.java b/src/io/github/sspanak/tt9/preferences/screens/HotkeysScreen.java index 25582509..b0a4433d 100644 --- a/src/io/github/sspanak/tt9/preferences/screens/HotkeysScreen.java +++ b/src/io/github/sspanak/tt9/preferences/screens/HotkeysScreen.java @@ -21,6 +21,10 @@ public class HotkeysScreen extends BaseScreenFragment { DropDownPreference[] dropDowns = { findPreference(SectionKeymap.ITEM_ADD_WORD), findPreference(SectionKeymap.ITEM_BACKSPACE), + findPreference(SectionKeymap.ITEM_FILTER_CLEAR), + findPreference(SectionKeymap.ITEM_FILTER_SUGGESTIONS), + findPreference(SectionKeymap.ITEM_PREVIOUS_SUGGESTION), + findPreference(SectionKeymap.ITEM_NEXT_SUGGESTION), findPreference(SectionKeymap.ITEM_NEXT_INPUT_MODE), findPreference(SectionKeymap.ITEM_NEXT_LANGUAGE), findPreference(SectionKeymap.ITEM_SHOW_SETTINGS), diff --git a/src/io/github/sspanak/tt9/ui/main/MainLayoutNumpad.java b/src/io/github/sspanak/tt9/ui/main/MainLayoutNumpad.java index 34c6c8e8..d9c7a026 100644 --- a/src/io/github/sspanak/tt9/ui/main/MainLayoutNumpad.java +++ b/src/io/github/sspanak/tt9/ui/main/MainLayoutNumpad.java @@ -78,6 +78,7 @@ class MainLayoutNumpad extends BaseMainLayout { protected ArrayList getSeparators() { // it's fine... it's shorter, faster and easier to read than searching with 3 nested loops return new ArrayList<>(Arrays.asList( + view.findViewById(R.id.separator_0), view.findViewById(R.id.separator_1_1), view.findViewById(R.id.separator_1_2), view.findViewById(R.id.separator_2_1), diff --git a/src/io/github/sspanak/tt9/ui/main/keys/SoftKey.java b/src/io/github/sspanak/tt9/ui/main/keys/SoftKey.java index 3ed3d14f..51259d6c 100644 --- a/src/io/github/sspanak/tt9/ui/main/keys/SoftKey.java +++ b/src/io/github/sspanak/tt9/ui/main/keys/SoftKey.java @@ -136,6 +136,10 @@ public class SoftKey extends androidx.appcompat.widget.AppCompatButton implement int keyId = getId(); if (keyId == R.id.soft_key_add_word) return tt9.onKeyAddWord(); + if (keyId == R.id.soft_key_clear_filter) return tt9.onKeyFilterClear(); + if (keyId == R.id.soft_key_filter_suggestions) return tt9.onKeyFilterSuggestions(repeat); + if (keyId == R.id.soft_key_left_arrow) return tt9.onKeyPreviousSuggestion(); + if (keyId == R.id.soft_key_right_arrow) return tt9.onKeyNextSuggestion(); if (keyId == R.id.soft_key_input_mode) return tt9.onKeyNextInputMode(); if (keyId == R.id.soft_key_language) return tt9.onKeyNextLanguage(); if (keyId == R.id.soft_key_ok) return tt9.onOK();