1
0
Fork 0

backspace acceleration function

This commit is contained in:
sspanak 2024-08-26 16:09:35 +03:00 committed by Dimo Karaivanov
parent d8232ebf27
commit 16a8cc8b70
23 changed files with 99 additions and 13 deletions

View file

@ -11,7 +11,7 @@ import io.github.sspanak.tt9.util.Ternary;
abstract public class AbstractHandler extends InputMethodService { abstract public class AbstractHandler extends InputMethodService {
// hardware key handlers // hardware key handlers
abstract protected Ternary onBack(); abstract protected Ternary onBack();
abstract public boolean onBackspace(); abstract public boolean onBackspace(boolean hold);
abstract public boolean onHotkey(int keyCode, boolean repeat, boolean validateOnly); abstract public boolean onHotkey(int keyCode, boolean repeat, boolean validateOnly);
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();

View file

@ -60,7 +60,11 @@ abstract class KeyPadHandler extends UiHandler {
// "backspace" key must repeat its function when held down, so we handle it in a special way // "backspace" key must repeat its function when held down, so we handle it in a special way
if (Key.isBackspace(settings, keyCode)) { if (Key.isBackspace(settings, keyCode)) {
if (onBackspace()) { if (
(settings.getBackspaceAcceleration() && event.getRepeatCount() > 0 && event.getRepeatCount() % SettingsStore.BACKSPACE_ACCELERATION_HARD_KEY_REPEAT_DEBOUNCE == 0 && onBackspace(true))
|| (settings.getBackspaceAcceleration() && event.getRepeatCount() > 0)
|| onBackspace(false)
) {
return Key.setHandled(KeyEvent.KEYCODE_DEL, true); return Key.setHandled(KeyEvent.KEYCODE_DEL, true);
} else { } else {
Key.setHandled(KeyEvent.KEYCODE_DEL, false); Key.setHandled(KeyEvent.KEYCODE_DEL, false);

View file

@ -21,6 +21,7 @@ import io.github.sspanak.tt9.ime.modes.InputMode;
import io.github.sspanak.tt9.ime.modes.ModePredictive; import io.github.sspanak.tt9.ime.modes.ModePredictive;
import io.github.sspanak.tt9.languages.Language; import io.github.sspanak.tt9.languages.Language;
import io.github.sspanak.tt9.languages.LanguageCollection; import io.github.sspanak.tt9.languages.LanguageCollection;
import io.github.sspanak.tt9.preferences.settings.SettingsStore;
import io.github.sspanak.tt9.ui.UI; import io.github.sspanak.tt9.ui.UI;
import io.github.sspanak.tt9.util.Text; import io.github.sspanak.tt9.util.Text;
@ -110,7 +111,7 @@ public abstract class TypingHandler extends KeyPadHandler {
@Override @Override
public boolean onBackspace() { public boolean onBackspace(boolean hold) {
// Dialer fields seem to handle backspace on their own and we must ignore it, // Dialer fields seem to handle backspace on their own and we must ignore it,
// otherwise, keyDown race condition occur for all keys. // otherwise, keyDown race condition occur for all keys.
if (mInputMode.isPassthrough()) { if (mInputMode.isPassthrough()) {
@ -125,11 +126,16 @@ public abstract class TypingHandler extends KeyPadHandler {
suggestionOps.cancelDelayedAccept(); suggestionOps.cancelDelayedAccept();
resetKeyRepeat(); resetKeyRepeat();
if (mInputMode.onBackspace()) { if (!hold && mInputMode.onBackspace()) {
getSuggestions(); getSuggestions();
} else { } else {
suggestionOps.commitCurrent(false); suggestionOps.commitCurrent(false);
super.sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL); mInputMode.reset();
int repeats = hold ? Math.min(Math.max(textField.getWordBeforeCursorLength(), 1), SettingsStore.BACKSPACE_ACCELERATION_MAX_CHARS) : 1;
for (int i = repeats; i > 0; i--) {
super.sendDownUpKeyEvents(KeyEvent.KEYCODE_DEL);
}
} }
return true; return true;

View file

@ -104,6 +104,26 @@ public class TextField extends InputField {
} }
/**
* Returns the length of the word before the cursor. If the cursor is inside a word, 0 is returned,
* because there is no full word before it. The scanning length is up to the maximum returned by
* getTextBeforeCursor().
*/
public int getWordBeforeCursorLength() {
if (getTextAfterCursor(1).startsWithWord()) {
return 0;
}
String before = getStringBeforeCursor();
if (before.isEmpty()) {
return 0;
}
int spaceShift = Math.max(before.lastIndexOf(' '), 0);
return before.length() - spaceShift;
}
/** /**
* deletePrecedingSpace * deletePrecedingSpace
* Deletes the preceding space before the given word. The word must be before the cursor. * Deletes the preceding space before the given word. The word must be before the cursor.

View file

@ -7,6 +7,9 @@ public class SettingsStore extends SettingsUI {
public SettingsStore(Context context) { super(context); } public SettingsStore(Context context) { super(context); }
/************* internal settings *************/ /************* internal settings *************/
public static final int BACKSPACE_ACCELERATION_MAX_CHARS = 10;
public static final int BACKSPACE_ACCELERATION_HARD_KEY_REPEAT_DEBOUNCE = 5;
public static final int BACKSPACE_ACCELERATION_SOFT_KEY_REPEAT_DEBOUNCE = 7;
public final static int CLIPBOARD_PREVIEW_LENGTH = 20; public final static int CLIPBOARD_PREVIEW_LENGTH = 20;
public final static int CUSTOM_WORDS_IMPORT_MAX_LINES = 250; public final static int CUSTOM_WORDS_IMPORT_MAX_LINES = 250;
public final static int CUSTOM_WORDS_MAX = 1000; public final static int CUSTOM_WORDS_MAX = 1000;

View file

@ -15,6 +15,10 @@ class SettingsTyping extends SettingsInput {
return getAutoTextCase() && prefs.getBoolean("auto_capitals_after_newline", false); return getAutoTextCase() && prefs.getBoolean("auto_capitals_after_newline", false);
} }
public boolean getBackspaceAcceleration() {
return prefs.getBoolean("backspace_acceleration", false);
}
public String getDoubleZeroChar() { public String getDoubleZeroChar() {
String character = prefs.getString("pref_double_zero_char", "."); String character = prefs.getString("pref_double_zero_char", ".");

View file

@ -6,10 +6,12 @@ import android.view.KeyEvent;
import io.github.sspanak.tt9.R; import io.github.sspanak.tt9.R;
import io.github.sspanak.tt9.languages.LanguageKind; import io.github.sspanak.tt9.languages.LanguageKind;
import io.github.sspanak.tt9.preferences.settings.SettingsStore;
import io.github.sspanak.tt9.ui.Vibration; import io.github.sspanak.tt9.ui.Vibration;
public class SoftBackspaceKey extends SoftKey { public class SoftBackspaceKey extends SoftKey {
private boolean hold; private boolean hold;
private int repeatCount = 0;
public SoftBackspaceKey(Context context) { public SoftBackspaceKey(Context context) {
super(context); super(context);
@ -27,12 +29,23 @@ public class SoftBackspaceKey extends SoftKey {
final protected boolean handlePress() { final protected boolean handlePress() {
super.handlePress(); super.handlePress();
hold = false; hold = false;
return deleteText(); repeatCount = 0;
return validateTT9Handler() && deleteText();
} }
@Override @Override
final protected void handleHold() { final protected void handleHold() {
hold = true; hold = true;
if (
validateTT9Handler()
&& tt9.getSettings().getBackspaceAcceleration()
&& ++repeatCount < SettingsStore.BACKSPACE_ACCELERATION_SOFT_KEY_REPEAT_DEBOUNCE
) {
return;
}
repeatCount = 0;
deleteText(); deleteText();
} }
@ -44,7 +57,7 @@ public class SoftBackspaceKey extends SoftKey {
} }
private boolean deleteText() { private boolean deleteText() {
if (validateTT9Handler() && !tt9.onBackspace()) { if (!tt9.onBackspace(hold && tt9.getSettings().getBackspaceAcceleration())) {
// Limited or special numeric field (e.g. formatted money or dates) cannot always return // Limited or special numeric field (e.g. formatted money or dates) cannot always return
// the text length, therefore onBackspace() seems them as empty and does nothing. This results // the text length, therefore onBackspace() seems them as empty and does nothing. This results
// in fallback to the default hardware key action. Here we simulate the hardware BACKSPACE. // in fallback to the default hardware key action. Here we simulate the hardware BACKSPACE.

View file

@ -95,9 +95,6 @@ public class Text extends TextTools {
} }
public boolean startsWithWhitespace() { public boolean startsWithWhitespace() {
return text != null && !text.isEmpty() && Character.isWhitespace(text.charAt(0)); return text != null && !text.isEmpty() && Character.isWhitespace(text.charAt(0));
} }
@ -110,6 +107,10 @@ public class Text extends TextTools {
return text != null && !text.isEmpty() && Characters.isGraphic(text.charAt(0)); return text != null && !text.isEmpty() && Characters.isGraphic(text.charAt(0));
} }
public boolean startsWithWord() {
return text != null && !text.isEmpty() && Character.isAlphabetic(text.charAt(0));
}
public String subStringEndingWord(boolean keepApostrophe, boolean keepQuote) { public String subStringEndingWord(boolean keepApostrophe, boolean keepQuote) {
if (text == null) { if (text == null) {
return ""; return "";

View file

@ -167,4 +167,6 @@
<string name="language_selection_title">Избор на езици</string> <string name="language_selection_title">Избор на езици</string>
<string name="language_selection_search_placeholder">Търси езици</string> <string name="language_selection_search_placeholder">Търси езици</string>
<string name="language_selection_words">думи</string> <string name="language_selection_words">думи</string>
<string name="pref_backspace_acceleration">Бързо изтриване</string>
<string name="pref_backspace_acceleration_summary">Изтривай цели думи при задържане на Backspace.\n(Не работи в някои приложения.)</string>
</resources> </resources>

View file

@ -156,4 +156,6 @@
<string name="language_selection_title">Sprachen aktivieren</string> <string name="language_selection_title">Sprachen aktivieren</string>
<string name="language_selection_search_placeholder">Nach Sprachen suchen</string> <string name="language_selection_search_placeholder">Nach Sprachen suchen</string>
<string name="language_selection_words">Wörter</string> <string name="language_selection_words">Wörter</string>
<string name="pref_backspace_acceleration">Schnelles Löschen</string>
<string name="pref_backspace_acceleration_summary">Ganze Wörter löschen, indem Sie die Rücktaste gedrückt halten.\n(Nicht in allen Apps unterstützt)</string>
</resources> </resources>

View file

@ -165,4 +165,6 @@
<string name="language_selection_title">Habilitar idiomas</string> <string name="language_selection_title">Habilitar idiomas</string>
<string name="language_selection_search_placeholder">Buscar idiomas</string> <string name="language_selection_search_placeholder">Buscar idiomas</string>
<string name="language_selection_words">palabras</string> <string name="language_selection_words">palabras</string>
<string name="pref_backspace_acceleration">Eliminación rápida</string>
<string name="pref_backspace_acceleration_summary">Borrar palabras completas manteniendo presionada la tecla Retroceso.\n(No compatible con algunas aplicaciones)</string>
</resources> </resources>

View file

@ -163,4 +163,6 @@
<string name="language_selection_title">Activer les langues</string> <string name="language_selection_title">Activer les langues</string>
<string name="language_selection_search_placeholder">Rechercher des langues</string> <string name="language_selection_search_placeholder">Rechercher des langues</string>
<string name="language_selection_words">mots</string> <string name="language_selection_words">mots</string>
<string name="pref_backspace_acceleration">Suppression rapide</string>
<string name="pref_backspace_acceleration_summary">Effacer des mots entiers en maintenant la touche Retour arrière.\n(Non pris en charge dans certaines applications)</string>
</resources> </resources>

View file

@ -155,5 +155,7 @@
<string name="language_selection_title">Abilita lingue</string> <string name="language_selection_title">Abilita lingue</string>
<string name="language_selection_search_placeholder">Cerca lingue</string> <string name="language_selection_search_placeholder">Cerca lingue</string>
<string name="language_selection_words">parole</string> <string name="language_selection_words">parole</string>
<string name="pref_backspace_acceleration">Cancellazione rapida</string>
<string name="pref_backspace_acceleration_summary">Cancellare intere parole tenendo premuto Backspace.\n(Non supportato in alcune app)</string>
</resources> </resources>

View file

@ -168,4 +168,6 @@
<string name="language_selection_title">הפעל שפות</string> <string name="language_selection_title">הפעל שפות</string>
<string name="language_selection_search_placeholder">חיפוש שפות</string> <string name="language_selection_search_placeholder">חיפוש שפות</string>
<string name="language_selection_words">מילים</string> <string name="language_selection_words">מילים</string>
<string name="pref_backspace_acceleration">מחיקה מהירה</string>
<string name="pref_backspace_acceleration_summary">למחוק מילים שלמות על ידי החזקת מקש Backspace.\n(לא נתמך בחלק מהאפליקציות)</string>
</resources> </resources>

View file

@ -174,4 +174,6 @@
<string name="language_selection_title">Įjungti kalbas</string> <string name="language_selection_title">Įjungti kalbas</string>
<string name="language_selection_search_placeholder">Ieškoti kalbų</string> <string name="language_selection_search_placeholder">Ieškoti kalbų</string>
<string name="language_selection_words">žodžių</string> <string name="language_selection_words">žodžių</string>
<string name="pref_backspace_acceleration">Greitas ištrynimas</string>
<string name="pref_backspace_acceleration_summary">Ištrinti visus žodžius laikant klavišą Backspace.\n(Nepalaikoma kai kuriose programėlėse)</string>
</resources> </resources>

View file

@ -154,4 +154,6 @@
<string name="language_selection_title">Talen inschakelen</string> <string name="language_selection_title">Talen inschakelen</string>
<string name="language_selection_search_placeholder">Zoeken naar talen</string> <string name="language_selection_search_placeholder">Zoeken naar talen</string>
<string name="language_selection_words">woorden</string> <string name="language_selection_words">woorden</string>
<string name="pref_backspace_acceleration">Snel verwijderen</string>
<string name="pref_backspace_acceleration_summary">Hele woorden wissen door Backspace ingedrukt te houden.\n(Niet ondersteund in sommige apps)</string>
</resources> </resources>

View file

@ -36,9 +36,9 @@
<string name="pref_abc_auto_accept_slow">Lento</string> <string name="pref_abc_auto_accept_slow">Lento</string>
<string name="pref_alternative_suggestion_scrolling">Método alternativo de rolagem de sugestões</string> <string name="pref_alternative_suggestion_scrolling">Método alternativo de rolagem de sugestões</string>
<string name="pref_alternative_suggestion_scrolling_summary">Ative se às vezes não conseguir ver todas as sugestões ou tiver problemas para rolá-las (Android 9 ou mais antigo).</string> <string name="pref_alternative_suggestion_scrolling_summary">Ative se às vezes não conseguir ver todas as sugestões ou tiver problemas para rolá-las (Android 9 ou mais antigo).</string>
<string name="pref_auto_space">Espaçamento Automático</string> <string name="pref_auto_space">Espaçamento automático</string>
<string name="pref_auto_space_summary">Insere um espaçamento após ponto final.</string> <string name="pref_auto_space_summary">Insere um espaçamento após ponto final.</string>
<string name="pref_auto_text_case">Maiúsculas Automáticas</string> <string name="pref_auto_text_case">Maiúsculas automáticas</string>
<string name="pref_auto_text_case_summary">Iniciar automaticamente as frases com letras maiúsculas.</string> <string name="pref_auto_text_case_summary">Iniciar automaticamente as frases com letras maiúsculas.</string>
<string name="pref_auto_capitals_after_newline">Letras maiúsculas automáticas em cada linha</string> <string name="pref_auto_capitals_after_newline">Letras maiúsculas automáticas em cada linha</string>
<string name="pref_auto_capitals_after_newline_summary">Começar cada linha com uma letra maiúscula, mesmo que esteja no meio de uma frase.</string> <string name="pref_auto_capitals_after_newline_summary">Começar cada linha com uma letra maiúscula, mesmo que esteja no meio de uma frase.</string>
@ -168,4 +168,6 @@
<string name="language_selection_title">Habilitar idiomas</string> <string name="language_selection_title">Habilitar idiomas</string>
<string name="language_selection_search_placeholder">Buscar por idiomas</string> <string name="language_selection_search_placeholder">Buscar por idiomas</string>
<string name="language_selection_words">palavras</string> <string name="language_selection_words">palavras</string>
<string name="pref_backspace_acceleration">Exclusão rápida</string>
<string name="pref_backspace_acceleration_summary">Apagar palavras inteiras segurando a tecla Backspace.\n(Não suportado em alguns aplicativos)</string>
</resources> </resources>

View file

@ -165,4 +165,6 @@
<string name="language_selection_title">Включить языки</string> <string name="language_selection_title">Включить языки</string>
<string name="language_selection_search_placeholder">Поиск языков</string> <string name="language_selection_search_placeholder">Поиск языков</string>
<string name="language_selection_words">слов</string> <string name="language_selection_words">слов</string>
<string name="pref_backspace_acceleration">Быстрое удаление</string>
<string name="pref_backspace_acceleration_summary">Стирать целые слова, удерживая клавишу Backspace.\n(Не поддерживается в некоторых приложениях)</string>
</resources> </resources>

View file

@ -168,4 +168,6 @@
<string name="language_selection_title">Dilleri etkinleştir</string> <string name="language_selection_title">Dilleri etkinleştir</string>
<string name="language_selection_search_placeholder">Diller için arama</string> <string name="language_selection_search_placeholder">Diller için arama</string>
<string name="language_selection_words">kelime</string> <string name="language_selection_words">kelime</string>
<string name="pref_backspace_acceleration">Hızlı Silme</string>
<string name="pref_backspace_acceleration_summary">Geri tuşunu basılı tutarak tüm kelimeleri silin.\n(Bazı uygulamalarda desteklenmez)</string>
</resources> </resources>

View file

@ -176,4 +176,6 @@
<string name="language_selection_title">Увімкнути мови</string> <string name="language_selection_title">Увімкнути мови</string>
<string name="language_selection_search_placeholder">Пошук мов</string> <string name="language_selection_search_placeholder">Пошук мов</string>
<string name="language_selection_words">слів</string> <string name="language_selection_words">слів</string>
<string name="pref_backspace_acceleration">Швидке видалення</string>
<string name="pref_backspace_acceleration_summary">Видаляти цілі слова, утримуючи клавішу Backspace.\n(Не підтримується в деяких додатках)</string>
</resources> </resources>

View file

@ -23,6 +23,7 @@
<string name="add_word_success">\"%1$s\" added.</string> <string name="add_word_success">\"%1$s\" added.</string>
<string name="add_word_title">Add Word</string> <string name="add_word_title">Add Word</string>
<string name="commands_select_command">Select a Command</string> <string name="commands_select_command">Select a Command</string>
<string name="pref_category_about">About</string> <string name="pref_category_about">About</string>
@ -52,6 +53,8 @@
<string name="pref_auto_text_case_summary">Automatically start sentences with a capital letter.</string> <string name="pref_auto_text_case_summary">Automatically start sentences with a capital letter.</string>
<string name="pref_auto_capitals_after_newline">Automatically Capitalize Every Line</string> <string name="pref_auto_capitals_after_newline">Automatically Capitalize Every Line</string>
<string name="pref_auto_capitals_after_newline_summary">Start every line with a capital letter, even it is in the middle of a sentence.</string> <string name="pref_auto_capitals_after_newline_summary">Start every line with a capital letter, even it is in the middle of a sentence.</string>
<string name="pref_backspace_acceleration">Fast Delete</string>
<string name="pref_backspace_acceleration_summary">Erase entire words by holding Backspace.\n(Not supported in some apps)</string>
<string name="pref_choose_languages">Languages</string> <string name="pref_choose_languages">Languages</string>
<string name="pref_dark_theme">Dark Theme</string> <string name="pref_dark_theme">Dark Theme</string>
<string name="pref_dark_theme_yes">Yes</string> <string name="pref_dark_theme_yes">Yes</string>

View file

@ -14,6 +14,14 @@
app:title="@string/pref_haptic_feedback" app:title="@string/pref_haptic_feedback"
app:summary="@string/pref_haptic_feedback_summary"/> app:summary="@string/pref_haptic_feedback_summary"/>
<PreferenceCategory android:title="@string/function_backspace">
<SwitchPreferenceCompat
app:defaultValue="false"
app:key="backspace_acceleration"
app:title="@string/pref_backspace_acceleration"
app:summary="@string/pref_backspace_acceleration_summary" />
</PreferenceCategory>
<PreferenceCategory android:title="@string/pref_category_predictive_mode"> <PreferenceCategory android:title="@string/pref_category_predictive_mode">
<SwitchPreferenceCompat <SwitchPreferenceCompat