mirror of
https://gitlab.futo.org/keyboard/latinime.git
synced 2024-09-28 14:54:30 +01:00
Add delete whole words during backspace option
This commit is contained in:
parent
e181717692
commit
6613e3e57f
@ -1217,7 +1217,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element,
|
||||
// Don't start key repeat when we are in the dragging finger mode.
|
||||
if (mIsInDraggingFinger) return;
|
||||
final int startRepeatCount = 1;
|
||||
startKeyRepeatTimer(startRepeatCount);
|
||||
startKeyRepeatTimer(key.getCode(), startRepeatCount);
|
||||
}
|
||||
|
||||
public void onKeyRepeat(final int code, final int repeatCount) {
|
||||
@ -1229,15 +1229,20 @@ public final class PointerTracker implements PointerTrackerQueue.Element,
|
||||
mCurrentRepeatingKeyCode = code;
|
||||
mIsDetectingGesture = false;
|
||||
final int nextRepeatCount = repeatCount + 1;
|
||||
startKeyRepeatTimer(nextRepeatCount);
|
||||
startKeyRepeatTimer(code, nextRepeatCount);
|
||||
callListenerOnPressAndCheckKeyboardLayoutChange(key, repeatCount);
|
||||
callListenerOnCodeInput(key, code, mKeyX, mKeyY, SystemClock.uptimeMillis(),
|
||||
true /* isKeyRepeat */);
|
||||
}
|
||||
|
||||
private void startKeyRepeatTimer(final int repeatCount) {
|
||||
final int delay =
|
||||
(repeatCount == 1) ? sParams.mKeyRepeatStartTimeout : sParams.mKeyRepeatInterval;
|
||||
private void startKeyRepeatTimer(final int code, final int repeatCount) {
|
||||
int delay = (repeatCount == 1) ? sParams.mKeyRepeatStartTimeout : sParams.mKeyRepeatInterval;
|
||||
|
||||
// Slow down the repeat key if we are deleting whole words
|
||||
if(code == Constants.CODE_DELETE && Settings.getInstance().getCurrent().mBackspaceMode == Settings.BACKSPACE_MODE_WORDS && repeatCount > 1) {
|
||||
delay = (int)((float)delay * (7.0f * (1.0f / ((float)(repeatCount - 1))) + 1.0f));
|
||||
}
|
||||
|
||||
sTimerProxy.startKeyRepeatTimerOf(this, repeatCount, delay);
|
||||
}
|
||||
|
||||
|
@ -60,7 +60,7 @@ public final class AudioAndHapticFeedbackManager {
|
||||
|
||||
public void performHapticAndAudioFeedback(final int code,
|
||||
final View viewToPerformHapticFeedbackOn) {
|
||||
performHapticFeedback(viewToPerformHapticFeedbackOn);
|
||||
performHapticFeedback(viewToPerformHapticFeedbackOn, false);
|
||||
performAudioFeedback(code);
|
||||
}
|
||||
|
||||
@ -108,12 +108,12 @@ public final class AudioAndHapticFeedbackManager {
|
||||
mAudioManager.playSoundEffect(sound, mSettingsValues.mKeypressSoundVolume);
|
||||
}
|
||||
|
||||
public void performHapticFeedback(final View viewToPerformHapticFeedbackOn) {
|
||||
public void performHapticFeedback(final View viewToPerformHapticFeedbackOn, final boolean repeatKey) {
|
||||
if (!mSettingsValues.mVibrateOn) {
|
||||
return;
|
||||
}
|
||||
if (mSettingsValues.mKeypressVibrationDuration >= 0) {
|
||||
vibrate(mSettingsValues.mKeypressVibrationDuration);
|
||||
vibrate(mSettingsValues.mKeypressVibrationDuration / (repeatKey ? 2 : 1));
|
||||
return;
|
||||
}
|
||||
// Go ahead with the system default
|
||||
|
@ -1304,14 +1304,12 @@ public class LatinIMELegacy implements KeyboardActionListener,
|
||||
@Override
|
||||
public void onMoveDeletePointer(int steps) {
|
||||
if (mInputLogic.mConnection.hasCursorPosition()) {
|
||||
steps = mInputLogic.mConnection.getUnicodeSteps(steps, false);
|
||||
final int end = mInputLogic.mConnection.getExpectedSelectionEnd();
|
||||
final int start = mInputLogic.mConnection.getExpectedSelectionStart() + steps;
|
||||
if (start > end)
|
||||
return;
|
||||
|
||||
mInputLogic.finishInput();
|
||||
mInputLogic.mConnection.setSelection(start, end);
|
||||
boolean stepOverWords = mSettings.getCurrent().mBackspaceMode == Settings.BACKSPACE_MODE_WORDS;
|
||||
if(steps < 0) {
|
||||
mInputLogic.cursorLeft(steps, stepOverWords, true);
|
||||
} else {
|
||||
mInputLogic.cursorRight(steps, stepOverWords, true);
|
||||
}
|
||||
} else {
|
||||
for (; steps < 0; steps++)
|
||||
onCodeInput(
|
||||
@ -1691,10 +1689,7 @@ public class LatinIMELegacy implements KeyboardActionListener,
|
||||
}
|
||||
final AudioAndHapticFeedbackManager feedbackManager =
|
||||
AudioAndHapticFeedbackManager.getInstance();
|
||||
if (repeatCount == 0) {
|
||||
// TODO: Reconsider how to perform haptic feedback when repeating key.
|
||||
feedbackManager.performHapticFeedback(keyboardView);
|
||||
}
|
||||
feedbackManager.performHapticFeedback(keyboardView, repeatCount > 0);
|
||||
feedbackManager.performAudioFeedback(code);
|
||||
}
|
||||
|
||||
|
@ -1077,7 +1077,7 @@ public final class RichInputConnection implements PrivateCommandPerformer {
|
||||
public int getUnicodeSteps(int chars, boolean rightSidePointer) {
|
||||
int steps = 0;
|
||||
if (chars < 0) {
|
||||
CharSequence charsBeforeCursor = rightSidePointer && hasSelection() ?
|
||||
CharSequence charsBeforeCursor = !rightSidePointer && hasSelection() ?
|
||||
getSelectedText(0) :
|
||||
getTextBeforeCursor(-chars * 2, 0);
|
||||
if (charsBeforeCursor != null) {
|
||||
@ -1089,7 +1089,7 @@ public final class RichInputConnection implements PrivateCommandPerformer {
|
||||
}
|
||||
}
|
||||
} else if (chars > 0) {
|
||||
CharSequence charsAfterCursor = !rightSidePointer && hasSelection() ?
|
||||
CharSequence charsAfterCursor = rightSidePointer && hasSelection() ?
|
||||
getSelectedText(0) :
|
||||
getTextAfterCursor(chars * 2, 0);
|
||||
if (charsAfterCursor != null) {
|
||||
@ -1105,7 +1105,7 @@ public final class RichInputConnection implements PrivateCommandPerformer {
|
||||
}
|
||||
|
||||
private int getCharacterClass(char c) {
|
||||
if(Character.isLetter(c) || c == '_' || Character.isDigit(c)) return 1;
|
||||
if(Character.isLetter(c) || c == '_' || Character.isDigit(c) || c == '\'') return 1;
|
||||
else if(Character.isWhitespace(c)) return 2;
|
||||
else return 3;
|
||||
}
|
||||
|
@ -49,6 +49,7 @@ import org.futo.inputmethod.latin.common.Constants;
|
||||
import org.futo.inputmethod.latin.common.InputPointers;
|
||||
import org.futo.inputmethod.latin.common.StringUtils;
|
||||
import org.futo.inputmethod.latin.define.DebugFlags;
|
||||
import org.futo.inputmethod.latin.settings.Settings;
|
||||
import org.futo.inputmethod.latin.settings.SettingsValues;
|
||||
import org.futo.inputmethod.latin.settings.SettingsValuesForSuggestion;
|
||||
import org.futo.inputmethod.latin.settings.SpacingAndPunctuations;
|
||||
@ -1053,6 +1054,10 @@ public final class InputLogic {
|
||||
mConnection.getExpectedSelectionEnd(), true /* clearSuggestionStrip */);
|
||||
// When we exit this if-clause, mWordComposer.isComposingWord() will return false.
|
||||
}
|
||||
|
||||
final boolean deleteWholeWords = event.isKeyRepeat()
|
||||
&& Settings.getInstance().getCurrent().mBackspaceMode == Settings.BACKSPACE_MODE_WORDS;
|
||||
|
||||
if (mWordComposer.isComposingWord()) {
|
||||
if (mWordComposer.isBatchMode()) {
|
||||
final String rejectedSuggestion = mWordComposer.getTypedWord();
|
||||
@ -1063,6 +1068,13 @@ public final class InputLogic {
|
||||
Constants.EVENT_REJECTION);
|
||||
}
|
||||
StatsUtils.onBackspaceWordDelete(rejectedSuggestion.length());
|
||||
} else if(deleteWholeWords) {
|
||||
final String removedWord = mWordComposer.getTypedWord();
|
||||
mWordComposer.reset();
|
||||
if (!TextUtils.isEmpty(removedWord)) {
|
||||
unlearnWord(removedWord, inputTransaction.mSettingsValues,
|
||||
Constants.EVENT_BACKSPACE);
|
||||
}
|
||||
} else {
|
||||
mWordComposer.applyProcessedEvent(event);
|
||||
StatsUtils.onBackspacePressed(1);
|
||||
@ -1195,13 +1207,23 @@ public final class InputLogic {
|
||||
Character.isSupplementaryCodePoint(codePointBeforeCursor) ? 2 : 1;
|
||||
|
||||
// Handle emoji sequences (flags, etc)
|
||||
CharSequence textBeforeCursor = mConnection.getTextBeforeCursor(8, 0);
|
||||
CharSequence textBeforeCursor = mConnection.getTextBeforeCursor(deleteWholeWords ? 48 : 8, 0);
|
||||
if (textBeforeCursor != null && textBeforeCursor.length() > 0) {
|
||||
BreakIterator breakIterator = BreakIterator.getCharacterInstance();
|
||||
BreakIterator breakIterator;
|
||||
|
||||
if(deleteWholeWords) {
|
||||
breakIterator = BreakIterator.getWordInstance();
|
||||
} else {
|
||||
breakIterator = BreakIterator.getCharacterInstance();
|
||||
}
|
||||
breakIterator.setText(textBeforeCursor.toString());
|
||||
int end = breakIterator.last();
|
||||
int start = breakIterator.previous();
|
||||
|
||||
if(deleteWholeWords && textBeforeCursor.subSequence(start, end).toString().equals(" ")) {
|
||||
start = breakIterator.previous();
|
||||
}
|
||||
|
||||
if (start != BreakIterator.DONE) {
|
||||
lengthToDelete = end - start;
|
||||
textDeleted = textBeforeCursor.subSequence(start, end).toString();
|
||||
|
@ -114,6 +114,16 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
|
||||
private static final String PREF_CORPUS_HANDLES_FOR_PERSONALIZATION =
|
||||
"pref_corpus_handles_for_personalization";
|
||||
|
||||
public static final String PREF_SPACEBAR_MODE = "pref_spacebar_mode";
|
||||
public static final int SPACEBAR_MODE_SWIPE_CURSOR = 0; // Long-Press switches language, swipe moves cursor
|
||||
public static final int SPACEBAR_MODE_SWIPE_LANGUAGE = 1; // Swipe switches language, long-press+drag moves cursor
|
||||
public static final int SPACEBAR_MODE_SWIPE_CURSOR_ONLY = 2; // Swipe and long-press+drag moves cursor
|
||||
|
||||
public static final String PREF_BACKSPACE_MODE = "pref_backspace_mode";
|
||||
public static final int BACKSPACE_MODE_CHARACTERS = 0; // Long-press backspace and swipe backspace removes just characters
|
||||
public static final int BACKSPACE_MODE_WORDS = 1; // Long-press backspace and swipe backspace removes entire words
|
||||
|
||||
|
||||
// Emoji
|
||||
public static final String PREF_EMOJI_RECENT_KEYS = "emoji_recent_keys";
|
||||
public static final String PREF_EMOJI_CATEGORY_LAST_TYPED_ID = "emoji_category_last_typed_id";
|
||||
|
@ -93,6 +93,9 @@ public class SettingsValues {
|
||||
public final boolean mIsNumberRowEnabled;
|
||||
public final int mScreenMetrics;
|
||||
|
||||
public final int mSpacebarMode;
|
||||
public final int mBackspaceMode;
|
||||
|
||||
// From the input box
|
||||
@Nonnull
|
||||
public final InputAttributes mInputAttributes;
|
||||
@ -164,6 +167,9 @@ public class SettingsValues {
|
||||
mIsSplitKeyboardEnabled = prefs.getBoolean(Settings.PREF_ENABLE_SPLIT_KEYBOARD, false);
|
||||
mScreenMetrics = Settings.readScreenMetrics(res);
|
||||
|
||||
mSpacebarMode = prefs.getInt(Settings.PREF_SPACEBAR_MODE, Settings.SPACEBAR_MODE_SWIPE_CURSOR);
|
||||
mBackspaceMode = prefs.getInt(Settings.PREF_BACKSPACE_MODE, Settings.BACKSPACE_MODE_CHARACTERS);
|
||||
|
||||
mShouldShowLxxSuggestionUi = Settings.SHOULD_SHOW_LXX_SUGGESTION_UI
|
||||
&& prefs.getBoolean(DebugSettings.PREF_SHOULD_SHOW_LXX_SUGGESTION_UI, true);
|
||||
// Compute other readable settings
|
||||
|
@ -282,15 +282,13 @@ fun<T> SettingRadio(
|
||||
title: String,
|
||||
options: List<T>,
|
||||
optionNames: List<String>,
|
||||
setting: SettingsKey<T>,
|
||||
setting: DataStoreItem<T>,
|
||||
) {
|
||||
val (value, setValue) = useDataStore(key = setting.key, default = setting.default)
|
||||
|
||||
ScreenTitle(title, showBack = false)
|
||||
Column {
|
||||
options.zip(optionNames).forEach {
|
||||
SettingItem(title = it.second, onClick = { setValue(it.first) }, icon = {
|
||||
RadioButton(selected = value == it.first, onClick = null)
|
||||
SettingItem(title = it.second, onClick = { setting.setValue(it.first) }, icon = {
|
||||
RadioButton(selected = setting.value == it.first, onClick = null)
|
||||
}) {
|
||||
|
||||
}
|
||||
|
@ -83,6 +83,7 @@ import org.futo.inputmethod.latin.uix.settings.ScreenTitle
|
||||
import org.futo.inputmethod.latin.uix.settings.ScrollableList
|
||||
import org.futo.inputmethod.latin.uix.settings.SettingItem
|
||||
import org.futo.inputmethod.latin.uix.settings.SettingListLazy
|
||||
import org.futo.inputmethod.latin.uix.settings.SettingRadio
|
||||
import org.futo.inputmethod.latin.uix.settings.SettingSlider
|
||||
import org.futo.inputmethod.latin.uix.settings.SettingSliderSharedPrefsInt
|
||||
import org.futo.inputmethod.latin.uix.settings.SettingToggleDataStore
|
||||
@ -364,17 +365,43 @@ fun LongPressScreen(navController: NavHostController = rememberNavController())
|
||||
)
|
||||
}
|
||||
|
||||
/*
|
||||
SettingRadio(
|
||||
title = "Spacebar behavior",
|
||||
options = listOf(0, 1, 2),
|
||||
optionNames = listOf(
|
||||
"Swiping moves cursor, long-pressing switches language",
|
||||
"Swiping changes language, long-pressing moves cursor",
|
||||
"Swiping and long-pressing only moves cursor"
|
||||
),
|
||||
setting =
|
||||
)*/
|
||||
item {
|
||||
SettingRadio(
|
||||
title = "Backspace Behavior when holding/swiping",
|
||||
options = listOf(
|
||||
Settings.BACKSPACE_MODE_CHARACTERS,
|
||||
Settings.BACKSPACE_MODE_WORDS
|
||||
),
|
||||
optionNames = listOf(
|
||||
"Delete characters",
|
||||
"Delete entire words"
|
||||
),
|
||||
setting = useSharedPrefsInt(
|
||||
key = Settings.PREF_BACKSPACE_MODE,
|
||||
default = Settings.BACKSPACE_MODE_CHARACTERS
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
item {
|
||||
SettingRadio(
|
||||
title = "Spacebar Behavior",
|
||||
options = listOf(
|
||||
Settings.SPACEBAR_MODE_SWIPE_CURSOR,
|
||||
Settings.SPACEBAR_MODE_SWIPE_LANGUAGE,
|
||||
Settings.SPACEBAR_MODE_SWIPE_CURSOR_ONLY
|
||||
),
|
||||
optionNames = listOf(
|
||||
"Swiping moves cursor, long-pressing switches language",
|
||||
"Swiping changes language, long-pressing moves cursor",
|
||||
"Swiping and long-pressing only moves cursor"
|
||||
),
|
||||
setting = useSharedPrefsInt(
|
||||
key = Settings.PREF_SPACEBAR_MODE,
|
||||
default = Settings.SPACEBAR_MODE_SWIPE_CURSOR
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user