mirror of
https://github.com/Helium314/HeliBoard.git
synced 2025-05-14 05:52:47 +00:00
Add support for delete swipe and spacebar navigation.
This is taken from simplekeyboard; the spacebar logic is the old one, to avoid a bug in some applications when moving the cursor at the beginning of the text.
This commit is contained in:
parent
3263ae00cc
commit
ec4c6ea2b9
10 changed files with 130 additions and 13 deletions
|
@ -100,6 +100,9 @@ public interface KeyboardActionListener {
|
|||
* @return true if the request has been consumed, false otherwise.
|
||||
*/
|
||||
public boolean onCustomRequest(int requestCode);
|
||||
public void onMovePointer(int steps);
|
||||
public void onMoveDeletePointer(int steps);
|
||||
public void onUpWithDeletePointerActive();
|
||||
|
||||
public static final KeyboardActionListener EMPTY_LISTENER = new Adapter();
|
||||
|
||||
|
@ -128,5 +131,11 @@ public interface KeyboardActionListener {
|
|||
public boolean onCustomRequest(int requestCode) {
|
||||
return false;
|
||||
}
|
||||
@Override
|
||||
public void onMovePointer(int steps) {}
|
||||
@Override
|
||||
public void onMoveDeletePointer(int steps) {}
|
||||
@Override
|
||||
public void onUpWithDeletePointerActive() {}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -85,6 +85,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element,
|
|||
|
||||
// Parameters for pointer handling.
|
||||
private static PointerTrackerParams sParams;
|
||||
private static int sPointerStep = (int)(10.0 * Resources.getSystem().getDisplayMetrics().density);
|
||||
private static GestureStrokeRecognitionParams sGestureStrokeRecognitionParams;
|
||||
private static GestureStrokeDrawingParams sGestureStrokeDrawingParams;
|
||||
private static boolean sNeedsPhantomSuddenMoveEventHack;
|
||||
|
@ -127,6 +128,10 @@ public final class PointerTracker implements PointerTrackerQueue.Element,
|
|||
// Last pointer position.
|
||||
private int mLastX;
|
||||
private int mLastY;
|
||||
private int mStartX;
|
||||
private int mStartY;
|
||||
private long mStartTime;
|
||||
private boolean mCursorMoved = false;
|
||||
|
||||
// true if keyboard layout has been changed.
|
||||
private boolean mKeyboardLayoutHasBeenChanged;
|
||||
|
@ -696,6 +701,9 @@ public final class PointerTracker implements PointerTrackerQueue.Element,
|
|||
startRepeatKey(key);
|
||||
startLongPressTimer(key);
|
||||
setPressedKeyGraphics(key, eventTime);
|
||||
mStartX = x;
|
||||
mStartY = y;
|
||||
mStartTime = System.currentTimeMillis();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -894,10 +902,35 @@ public final class PointerTracker implements PointerTrackerQueue.Element,
|
|||
}
|
||||
|
||||
private void onMoveEventInternal(final int x, final int y, final long eventTime) {
|
||||
final Key oldKey = mCurrentKey;
|
||||
|
||||
if (oldKey != null && oldKey.getCode() == Constants.CODE_SPACE && Settings.getInstance().getCurrent().mSpaceTrackpadEnabled) {
|
||||
//Pointer slider
|
||||
int steps = (x - mStartX) / sPointerStep;
|
||||
final int longpressTimeout = Settings.getInstance().getCurrent().mKeyLongpressTimeout / MULTIPLIER_FOR_LONG_PRESS_TIMEOUT_IN_SLIDING_INPUT;
|
||||
if (steps != 0 && mStartTime + longpressTimeout < System.currentTimeMillis()) {
|
||||
mCursorMoved = true;
|
||||
mStartX += steps * sPointerStep;
|
||||
sListener.onMovePointer(steps);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (oldKey != null && oldKey.getCode() == Constants.CODE_DELETE && Settings.getInstance().getCurrent().mDeleteSwipeEnabled) {
|
||||
//Delete slider
|
||||
int steps = (x - mStartX) / sPointerStep;
|
||||
if (steps != 0) {
|
||||
sTimerProxy.cancelKeyTimersOf(this);
|
||||
mCursorMoved = true;
|
||||
mStartX += steps * sPointerStep;
|
||||
sListener.onMoveDeletePointer(steps);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
final Key newKey = onMoveKey(x, y);
|
||||
final int lastX = mLastX;
|
||||
final int lastY = mLastY;
|
||||
final Key oldKey = mCurrentKey;
|
||||
final Key newKey = onMoveKey(x, y);
|
||||
|
||||
if (sGestureEnabler.shouldHandleGesture()) {
|
||||
// Register move event on gesture tracker.
|
||||
|
@ -971,6 +1004,10 @@ public final class PointerTracker implements PointerTrackerQueue.Element,
|
|||
// Release the last pressed key.
|
||||
setReleasedKeyGraphics(currentKey, true /* withAnimation */);
|
||||
|
||||
if(mCursorMoved && currentKey.getCode() == Constants.CODE_DELETE) {
|
||||
sListener.onUpWithDeletePointerActive();
|
||||
}
|
||||
|
||||
if (isShowingMoreKeysPanel()) {
|
||||
if (!mIsTrackingForActionDisabled) {
|
||||
final int translatedX = mMoreKeysPanel.translateX(x);
|
||||
|
@ -981,6 +1018,11 @@ public final class PointerTracker implements PointerTrackerQueue.Element,
|
|||
return;
|
||||
}
|
||||
|
||||
if (mCursorMoved) {
|
||||
mCursorMoved = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (sInGesture) {
|
||||
if (currentKey != null) {
|
||||
callListenerOnRelease(currentKey, currentKey.getCode(), true /* withSliding */);
|
||||
|
@ -1023,6 +1065,9 @@ public final class PointerTracker implements PointerTrackerQueue.Element,
|
|||
if (isShowingMoreKeysPanel()) {
|
||||
return;
|
||||
}
|
||||
if(mCursorMoved) {
|
||||
return;
|
||||
}
|
||||
final Key key = getKey();
|
||||
if (key == null) {
|
||||
return;
|
||||
|
@ -1148,6 +1193,10 @@ public final class PointerTracker implements PointerTrackerQueue.Element,
|
|||
// We use longer timeout for sliding finger input started from the modifier key.
|
||||
return longpressTimeout * MULTIPLIER_FOR_LONG_PRESS_TIMEOUT_IN_SLIDING_INPUT;
|
||||
}
|
||||
if (code == Constants.CODE_SPACE) {
|
||||
// Cursor can be moved in space
|
||||
return longpressTimeout * MULTIPLIER_FOR_LONG_PRESS_TIMEOUT_IN_SLIDING_INPUT;
|
||||
}
|
||||
return longpressTimeout;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ import android.os.IBinder;
|
|||
import android.os.Message;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.text.InputType;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.util.PrintWriterPrinter;
|
||||
import android.util.Printer;
|
||||
|
@ -1347,16 +1348,48 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
|||
public boolean onCustomRequest(final int requestCode) {
|
||||
if (isShowingOptionDialog()) return false;
|
||||
switch (requestCode) {
|
||||
case Constants.CUSTOM_CODE_SHOW_INPUT_METHOD_PICKER:
|
||||
if (mRichImm.hasMultipleEnabledIMEsOrSubtypes(true /* include aux subtypes */)) {
|
||||
mRichImm.getInputMethodManager().showInputMethodPicker();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
case Constants.CUSTOM_CODE_SHOW_INPUT_METHOD_PICKER:
|
||||
if (mRichImm.hasMultipleEnabledIMEsOrSubtypes(true /* include aux subtypes */)) {
|
||||
mRichImm.getInputMethodManager().showInputMethodPicker();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMovePointer(int steps) {
|
||||
if (steps < 0) {
|
||||
int availableCharacters = getCurrentInputConnection().getTextBeforeCursor(64, 0).length();
|
||||
steps = availableCharacters < -steps ? -availableCharacters : steps;
|
||||
}
|
||||
else if (steps > 0) {
|
||||
int availableCharacters = getCurrentInputConnection().getTextAfterCursor(64, 0).length();
|
||||
steps = availableCharacters < steps ? availableCharacters : steps;
|
||||
} else return;
|
||||
|
||||
int newPosition = mInputLogic.mConnection.mExpectedSelStart + steps;
|
||||
getCurrentInputConnection().setSelection(newPosition, newPosition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMoveDeletePointer(int steps) {
|
||||
int end = mInputLogic.mConnection.getExpectedSelectionEnd();
|
||||
int start = mInputLogic.mConnection.getExpectedSelectionStart() + steps;
|
||||
if (start > end)
|
||||
return;
|
||||
mInputLogic.mConnection.setSelection(start, end);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpWithDeletePointerActive() {
|
||||
if (mInputLogic.mConnection.hasSelection()) {
|
||||
mInputLogic.sendDownUpKeyEvent(KeyEvent.KEYCODE_DEL);
|
||||
mInputLogic.finishInput();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isShowingOptionDialog() {
|
||||
return mOptionsDialog != null && mOptionsDialog.isShowing();
|
||||
}
|
||||
|
|
|
@ -103,12 +103,12 @@ public final class RichInputConnection implements PrivateCommandPerformer {
|
|||
* It's not really the selection start position: the selection start may not be there yet, and
|
||||
* in some cases, it may never arrive there.
|
||||
*/
|
||||
private int mExpectedSelStart = INVALID_CURSOR_POSITION; // in chars, not code points
|
||||
public int mExpectedSelStart = INVALID_CURSOR_POSITION; // in chars, not code points
|
||||
/**
|
||||
* The expected selection end. Only differs from mExpectedSelStart if a non-empty selection is
|
||||
* expected. The same caveats as mExpectedSelStart apply.
|
||||
*/
|
||||
private int mExpectedSelEnd = INVALID_CURSOR_POSITION; // in chars, not code points
|
||||
public int mExpectedSelEnd = INVALID_CURSOR_POSITION; // in chars, not code points
|
||||
/**
|
||||
* This contains the committed text immediately preceding the cursor and the composing
|
||||
* text, if any. It is refreshed when the cursor moves by calling upon the TextView.
|
||||
|
|
|
@ -1969,7 +1969,7 @@ public final class InputLogic {
|
|||
*
|
||||
* @param keyCode the key code to send inside the key event.
|
||||
*/
|
||||
private void sendDownUpKeyEvent(final int keyCode) {
|
||||
public void sendDownUpKeyEvent(final int keyCode) {
|
||||
final long eventTime = SystemClock.uptimeMillis();
|
||||
mConnection.sendKeyEvent(new KeyEvent(eventTime, eventTime,
|
||||
KeyEvent.ACTION_DOWN, keyCode, 0, 0, KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
|
||||
|
|
|
@ -83,6 +83,8 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
|
|||
public static final String PREF_CUSTOM_INPUT_STYLES = "custom_input_styles";
|
||||
public static final String PREF_ENABLE_SPLIT_KEYBOARD = "pref_split_keyboard";
|
||||
public static final String PREF_KEYBOARD_HEIGHT_SCALE = "pref_keyboard_height_scale";
|
||||
public static final String PREF_SPACE_TRACKPAD = "pref_space_trackpad";
|
||||
public static final String PREF_DELETE_SWIPE = "pref_delete_swipe";
|
||||
// TODO: consolidate key preview dismiss delay with the key preview animation parameters.
|
||||
public static final String PREF_KEY_PREVIEW_POPUP_DISMISS_DELAY =
|
||||
"pref_key_preview_popup_dismiss_delay";
|
||||
|
@ -354,6 +356,14 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
|
|||
return (percentage != UNDEFINED_PREFERENCE_VALUE_FLOAT) ? percentage : defaultValue;
|
||||
}
|
||||
|
||||
public static boolean readSpaceTrackpadEnabled(final SharedPreferences prefs) {
|
||||
return prefs.getBoolean(PREF_SPACE_TRACKPAD, true);
|
||||
}
|
||||
|
||||
public static boolean readDeleteSwipeEnabled(final SharedPreferences prefs) {
|
||||
return prefs.getBoolean(PREF_DELETE_SWIPE, true);
|
||||
}
|
||||
|
||||
public static boolean readUseFullscreenMode(final Resources res) {
|
||||
return res.getBoolean(R.bool.config_use_fullscreen_mode);
|
||||
}
|
||||
|
|
|
@ -73,6 +73,8 @@ public class SettingsValues {
|
|||
public final boolean mUsePersonalizedDicts;
|
||||
public final boolean mUseDoubleSpacePeriod;
|
||||
public final boolean mBlockPotentiallyOffensive;
|
||||
public final boolean mSpaceTrackpadEnabled;
|
||||
public final boolean mDeleteSwipeEnabled;
|
||||
// Use bigrams to predict the next word when there is no input for it yet
|
||||
public final boolean mBigramPredictionEnabled;
|
||||
public final boolean mGestureInputEnabled;
|
||||
|
@ -223,6 +225,8 @@ public class SettingsValues {
|
|||
new TargetPackageInfoGetterTask(context, mAppWorkarounds)
|
||||
.execute(mInputAttributes.mTargetApplicationPackageName);
|
||||
}
|
||||
mSpaceTrackpadEnabled = Settings.readSpaceTrackpadEnabled(prefs);
|
||||
mDeleteSwipeEnabled = Settings.readDeleteSwipeEnabled(prefs);
|
||||
}
|
||||
|
||||
public boolean isMetricsLoggingEnabled() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue