diff options
Diffstat (limited to 'java/src/com/android/inputmethod/keyboard/PointerTracker.java')
-rw-r--r-- | java/src/com/android/inputmethod/keyboard/PointerTracker.java | 117 |
1 files changed, 74 insertions, 43 deletions
diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java index 91c4319e7..174239325 100644 --- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java +++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java @@ -25,6 +25,7 @@ import com.android.inputmethod.accessibility.AccessibilityUtils; import com.android.inputmethod.keyboard.internal.GestureStroke; import com.android.inputmethod.keyboard.internal.GestureStroke.GestureStrokeParams; import com.android.inputmethod.keyboard.internal.GestureStrokeWithPreviewPoints; +import com.android.inputmethod.keyboard.internal.GestureStrokeWithPreviewPoints.GestureStrokePreviewParams; import com.android.inputmethod.keyboard.internal.PointerTrackerQueue; import com.android.inputmethod.latin.CollectionUtils; import com.android.inputmethod.latin.Constants; @@ -83,7 +84,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element { public void dismissKeyPreview(PointerTracker tracker); public void showSlidingKeyInputPreview(PointerTracker tracker); public void dismissSlidingKeyInputPreview(); - public void showGesturePreviewTrail(PointerTracker tracker); + public void showGestureTrail(PointerTracker tracker); } public interface TimerProxy { @@ -161,6 +162,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element { // Parameters for pointer handling. private static PointerTrackerParams sParams; private static GestureStrokeParams sGestureStrokeParams; + private static GestureStrokePreviewParams sGesturePreviewParams; private static boolean sNeedsPhantomSuddenMoveEventHack; // Move this threshold to resource. // TODO: Device specific parameter would be better for device specific hack? @@ -176,7 +178,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element { private DrawingProxy mDrawingProxy; private TimerProxy mTimerProxy; private KeyDetector mKeyDetector; - private KeyboardActionListener mListener = EMPTY_LISTENER; + private KeyboardActionListener mListener = KeyboardActionListener.Adapter.EMPTY_LISTENER; private Keyboard mKeyboard; private int mPhantonSuddenMoveThreshold; @@ -318,8 +320,8 @@ public final class PointerTracker implements PointerTrackerQueue.Element { // true if keyboard layout has been changed. private boolean mKeyboardLayoutHasBeenChanged; - // true if this pointer is no longer tracking touch event. - private boolean mIsTrackingCanceled; + // true if this pointer is no longer triggering any action because it has been canceled. + private boolean mIsTrackingForActionDisabled; // the more keys panel currently being shown. equals null if no panel is active. private MoreKeysPanel mMoreKeysPanel; @@ -333,22 +335,20 @@ public final class PointerTracker implements PointerTrackerQueue.Element { // true if a sliding key input is allowed. private boolean mIsAllowedSlidingKeyInput; - // Empty {@link KeyboardActionListener} - private static final KeyboardActionListener EMPTY_LISTENER = - new KeyboardActionListener.Adapter(); - private final GestureStrokeWithPreviewPoints mGestureStrokeWithPreviewPoints; public static void init(final boolean needsPhantomSuddenMoveEventHack) { sNeedsPhantomSuddenMoveEventHack = needsPhantomSuddenMoveEventHack; sParams = PointerTrackerParams.DEFAULT; sGestureStrokeParams = GestureStrokeParams.DEFAULT; + sGesturePreviewParams = GestureStrokePreviewParams.DEFAULT; sTimeRecorder = new TimeRecorder(sParams, sGestureStrokeParams); } public static void setParameters(final TypedArray mainKeyboardViewAttr) { sParams = new PointerTrackerParams(mainKeyboardViewAttr); sGestureStrokeParams = new GestureStrokeParams(mainKeyboardViewAttr); + sGesturePreviewParams = new GestureStrokePreviewParams(mainKeyboardViewAttr); sTimeRecorder = new TimeRecorder(sParams, sGestureStrokeParams); } @@ -432,7 +432,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element { } mPointerId = id; mGestureStrokeWithPreviewPoints = new GestureStrokeWithPreviewPoints( - id, sGestureStrokeParams); + id, sGestureStrokeParams, sGesturePreviewParams); setKeyDetectorInner(handler.getKeyDetector()); mListener = handler.getKeyboardActionListener(); mDrawingProxy = handler.getDrawingProxy(); @@ -441,7 +441,11 @@ public final class PointerTracker implements PointerTrackerQueue.Element { // Returns true if keyboard has been changed by this callback. private boolean callListenerOnPressAndCheckKeyboardLayoutChange(final Key key) { - if (sInGesture || mIsDetectingGesture) { + // While gesture input is going on, this method should be a no-operation. But when gesture + // input has been canceled, <code>sInGesture</code> and <code>mIsDetectingGesture</code> + // are set to false. To keep this method is a no-operation, + // <code>mIsTrackingForActionDisabled</code> should also be taken account of. + if (sInGesture || mIsDetectingGesture || mIsTrackingForActionDisabled) { return false; } final boolean ignoreModifierKey = mIsInSlidingKeyInput && key.isModifier(); @@ -455,7 +459,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element { return false; } if (key.isEnabled()) { - mListener.onPressKey(key.mCode); + mListener.onPressKey(key.mCode, getActivePointerTrackerCount() == 1); final boolean keyboardLayoutHasBeenChanged = mKeyboardLayoutHasBeenChanged; mKeyboardLayoutHasBeenChanged = false; mTimerProxy.startTypingStateTimer(key); @@ -500,7 +504,8 @@ public final class PointerTracker implements PointerTrackerQueue.Element { // primaryCode is different from {@link Key#mCode}. private void callListenerOnRelease(final Key key, final int primaryCode, final boolean withSliding) { - if (sInGesture || mIsDetectingGesture) { + // See the comment at {@link #callListenerOnPressAndCheckKeyboardLayoutChange(Key}}. + if (sInGesture || mIsDetectingGesture || mIsTrackingForActionDisabled) { return; } final boolean ignoreModifierKey = mIsInSlidingKeyInput && key.isModifier(); @@ -522,6 +527,13 @@ public final class PointerTracker implements PointerTrackerQueue.Element { } } + private void callListenerOnFinishSlidingInput() { + if (DEBUG_LISTENER) { + Log.d(TAG, String.format("[%d] onFinishSlidingInput", mPointerId)); + } + mListener.onFinishSlidingInput(); + } + private void callListenerOnCancelInput() { if (DEBUG_LISTENER) { Log.d(TAG, String.format("[%d] onCancelInput", mPointerId)); @@ -732,7 +744,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element { dismissAllMoreKeysPanels(); } mTimerProxy.cancelLongPressTimer(); - mDrawingProxy.showGesturePreviewTrail(this); + mDrawingProxy.showGestureTrail(this); } public void updateBatchInputByTimer(final long eventTime) { @@ -745,10 +757,10 @@ public final class PointerTracker implements PointerTrackerQueue.Element { if (key != null) { updateBatchInput(eventTime); } - if (mIsTrackingCanceled) { + if (mIsTrackingForActionDisabled) { return; } - mDrawingProxy.showGesturePreviewTrail(this); + mDrawingProxy.showGestureTrail(this); } private void updateBatchInput(final long eventTime) { @@ -777,7 +789,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element { sInGesture = false; sTimeRecorder.onEndBatchInput(eventTime); mTimerProxy.cancelAllUpdateBatchInputTimers(); - if (!mIsTrackingCanceled) { + if (!mIsTrackingForActionDisabled) { if (DEBUG_LISTENER) { Log.d(TAG, String.format("[%d] onEndBatchInput : batchPoints=%d", mPointerId, sAggregratedPointers.getPointerSize())); @@ -786,10 +798,10 @@ public final class PointerTracker implements PointerTrackerQueue.Element { } } } - if (mIsTrackingCanceled) { + if (mIsTrackingForActionDisabled) { return; } - mDrawingProxy.showGesturePreviewTrail(this); + mDrawingProxy.showGestureTrail(this); } private void cancelBatchInput() { @@ -846,7 +858,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element { if (ProductionFlag.USES_DEVELOPMENT_ONLY_DIAGNOSTICS) { ResearchLogger.pointerTracker_onDownEvent(deltaT, distance * distance); } - cancelTracking(); + cancelTrackingForAction(); return; } } @@ -887,7 +899,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element { || (key != null && key.isModifier()) || mKeyDetector.alwaysAllowsSlidingInput(); mKeyboardLayoutHasBeenChanged = false; - mIsTrackingCanceled = false; + mIsTrackingForActionDisabled = false; resetSlidingKeyInput(); if (key != null) { // This onPress call may have changed keyboard layout. Those cases are detected at @@ -947,7 +959,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element { if (DEBUG_MOVE_EVENT) { printTouchEvent("onMoveEvent:", x, y, eventTime); } - if (mIsTrackingCanceled) { + if (mIsTrackingForActionDisabled) { return; } @@ -985,6 +997,9 @@ public final class PointerTracker implements PointerTrackerQueue.Element { key = onMoveKey(x, y); } onMoveToNewKey(key, x, y); + if (mIsTrackingForActionDisabled) { + return; + } startLongPressTimer(key); setPressedKeyGraphics(key, eventTime); } @@ -1028,7 +1043,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element { private void processSildeOutFromOldKey(final Key oldKey) { setReleasedKeyGraphics(oldKey); - callListenerOnRelease(oldKey, oldKey.mCode, true); + callListenerOnRelease(oldKey, oldKey.mCode, true /* withSliding */); startSlidingKeyInput(oldKey); mTimerProxy.cancelKeyTimers(); } @@ -1069,11 +1084,11 @@ public final class PointerTracker implements PointerTrackerQueue.Element { + " detected sliding finger while multi touching", mPointerId)); } onUpEvent(x, y, eventTime); - cancelTracking(); + cancelTrackingForAction(); setReleasedKeyGraphics(oldKey); } else { if (!mIsDetectingGesture) { - cancelTracking(); + cancelTrackingForAction(); } setReleasedKeyGraphics(oldKey); } @@ -1087,7 +1102,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element { onMoveToNewKey(null, x, y); } else { if (!mIsDetectingGesture) { - cancelTracking(); + cancelTrackingForAction(); } } } @@ -1155,11 +1170,13 @@ public final class PointerTracker implements PointerTrackerQueue.Element { return; } onUpEventInternal(mLastX, mLastY, eventTime); - cancelTracking(); + cancelTrackingForAction(); } private void onUpEventInternal(final int x, final int y, final long eventTime) { mTimerProxy.cancelKeyTimers(); + final boolean isInSlidingKeyInput = mIsInSlidingKeyInput; + final boolean isInSlidingKeyInputFromModifier = mIsInSlidingKeyInputFromModifier; resetSlidingKeyInput(); mIsDetectingGesture = false; final Key currentKey = mCurrentKey; @@ -1168,7 +1185,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element { setReleasedKeyGraphics(currentKey); if (isShowingMoreKeysPanel()) { - if (!mIsTrackingCanceled) { + if (!mIsTrackingForActionDisabled) { final int translatedX = mMoreKeysPanel.translateX(x); final int translatedY = mMoreKeysPanel.translateY(y); mMoreKeysPanel.onUpEvent(translatedX, translatedY, mPointerId, eventTime); @@ -1180,17 +1197,22 @@ public final class PointerTracker implements PointerTrackerQueue.Element { if (sInGesture) { if (currentKey != null) { - callListenerOnRelease(currentKey, currentKey.mCode, true); + callListenerOnRelease(currentKey, currentKey.mCode, true /* withSliding */); } mayEndBatchInput(eventTime); return; } - if (mIsTrackingCanceled) { + if (mIsTrackingForActionDisabled) { + return; + } + if (currentKey != null && currentKey.isRepeatable() && !isInSlidingKeyInput) { + // Repeatable key has been registered in {@link #onDownEventInternal(int,int,long)}. return; } - if (currentKey != null && !currentKey.isRepeatable()) { - detectAndSendKey(currentKey, mKeyX, mKeyY, eventTime); + detectAndSendKey(currentKey, mKeyX, mKeyY, eventTime); + if (isInSlidingKeyInputFromModifier) { + callListenerOnFinishSlidingInput(); } } @@ -1203,16 +1225,16 @@ public final class PointerTracker implements PointerTrackerQueue.Element { } @Override - public void cancelTracking() { + public void cancelTrackingForAction() { if (isShowingMoreKeysPanel()) { return; } - mIsTrackingCanceled = true; + mIsTrackingForActionDisabled = true; } public void onLongPressed() { resetSlidingKeyInput(); - cancelTracking(); + cancelTrackingForAction(); setReleasedKeyGraphics(mCurrentKey); sPointerTrackerQueue.remove(this); } @@ -1239,10 +1261,13 @@ public final class PointerTracker implements PointerTrackerQueue.Element { } private void startRepeatKey(final Key key) { - if (key != null && key.isRepeatable() && !sInGesture) { - onRegisterKey(key); - mTimerProxy.startKeyRepeatTimer(this); - } + if (sInGesture) return; + if (key == null) return; + if (!key.isRepeatable()) return; + // Don't start key repeat when we are in sliding input mode. + if (mIsInSlidingKeyInput) return; + onRegisterKey(key); + mTimerProxy.startKeyRepeatTimer(this); } public void onRegisterKey(final Key key) { @@ -1295,9 +1320,15 @@ public final class PointerTracker implements PointerTrackerQueue.Element { } private void startLongPressTimer(final Key key) { - if (key != null && key.isLongPressEnabled() && !sInGesture) { - mTimerProxy.startLongPressTimer(this); - } + if (sInGesture) return; + if (key == null) return; + if (!key.isLongPressEnabled()) return; + // Caveat: Please note that isLongPressEnabled() can be true even if the current key + // doesn't have its more keys. (e.g. spacebar, globe key) + // We always need to start the long press timer if the key has its more keys regardless of + // whether or not we are in the sliding input mode. + if (mIsInSlidingKeyInput && key.mMoreKeys == null) return; + mTimerProxy.startLongPressTimer(this); } private void detectAndSendKey(final Key key, final int x, final int y, final long eventTime) { @@ -1308,7 +1339,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element { final int code = key.mCode; callListenerOnCodeInput(key, code, x, y, eventTime); - callListenerOnRelease(key, code, false); + callListenerOnRelease(key, code, false /* withSliding */); } private void printTouchEvent(final String title, final int x, final int y, @@ -1316,6 +1347,6 @@ public final class PointerTracker implements PointerTrackerQueue.Element { final Key key = mKeyDetector.detectHitKey(x, y); final String code = KeyDetector.printableCode(key); Log.d(TAG, String.format("[%d]%s%s %4d %4d %5d %s", mPointerId, - (mIsTrackingCanceled ? "-" : " "), title, x, y, eventTime, code)); + (mIsTrackingForActionDisabled ? "-" : " "), title, x, y, eventTime, code)); } } |