Loading java/src/com/android/inputmethod/keyboard/PointerTracker.java +109 −49 Original line number Diff line number Diff line Loading @@ -23,7 +23,6 @@ import android.view.View; import android.widget.TextView; import com.android.inputmethod.keyboard.internal.GestureStroke; import com.android.inputmethod.keyboard.internal.GestureTracker; import com.android.inputmethod.keyboard.internal.PointerTrackerQueue; import com.android.inputmethod.latin.InputPointers; import com.android.inputmethod.latin.LatinImeLogger; Loading @@ -39,6 +38,10 @@ public class PointerTracker { private static final boolean DEBUG_LISTENER = false; private static boolean DEBUG_MODE = LatinImeLogger.sDBG; // TODO: There should be an option to turn on/off the gesture input. private static final boolean GESTURE_ON = true; private static final int MIN_RECOGNITION_TIME = 100; // msec public interface KeyEventHandler { /** * Get KeyDetector object that is used for this PointerTracker. Loading Loading @@ -128,6 +131,13 @@ public class PointerTracker { private int mKeyQuarterWidthSquared; private final TextView mKeyPreviewText; private boolean mIsAlphabetKeyboard; private boolean mIsPossibleGesture = false; private boolean mInGesture = false; private int mLastRecognitionPointSize = 0; private long mLastRecognitionTime = 0; // The position and time at which first down event occurred. private long mDownTime; private long mUpTime; Loading Loading @@ -164,9 +174,6 @@ public class PointerTracker { private static final KeyboardActionListener EMPTY_LISTENER = new KeyboardActionListener.Adapter(); // Gesture tracker singleton instance private static final GestureTracker sGestureTracker = GestureTracker.getInstance(); private final GestureStroke mGestureStroke; public static void init(boolean hasDistinctMultitouch, Loading Loading @@ -207,7 +214,6 @@ public class PointerTracker { for (final PointerTracker tracker : sTrackers) { tracker.mListener = listener; } GestureTracker.init(listener); } public static void setKeyDetector(KeyDetector keyDetector) { Loading @@ -216,7 +222,6 @@ public class PointerTracker { // Mark that keyboard layout has been changed. tracker.mKeyboardLayoutHasBeenChanged = true; } sGestureTracker.setKeyboard(keyDetector.getKeyboard()); } public static void dismissAllKeyPreviews() { Loading @@ -226,35 +231,35 @@ public class PointerTracker { } } // The working and returning object of the following methods, // {@link #getIncrementalBatchPoints()} and {@link #getAllBatchPoints()}. private static final InputPointers mAggregatedPointers = new InputPointers(); // TODO: This method is called only from GestureTracker and should address the thread-safty // issue soon. public static InputPointers getIncrementalBatchPoints() { final InputPointers pointers = mAggregatedPointers; pointers.reset(); // TODO: To handle multi-touch gestures we may want to move this method to // {@link PointerTrackerQueue}. private static InputPointers getIncrementalBatchPoints() { final InputPointers pointers = new InputPointers(); // TODO: Add a default capacity parameter for the InputPointers' constructor. // TODO: Avoid creating a new instance here? for (final PointerTracker tracker : sTrackers) { tracker.getGestureStroke().appendIncrementalBatchPoints(pointers); tracker.mGestureStroke.appendIncrementalBatchPoints(pointers); } return pointers; } // TODO: This method is called only from GestureTracker and should address the thread-safety // issue soon. public static InputPointers getAllBatchPoints() { final InputPointers pointers = mAggregatedPointers; pointers.reset(); // TODO: To handle multi-touch gestures we may want to move this method to // {@link PointerTrackerQueue}. private static InputPointers getAllBatchPoints() { // TODO: Add a default capacity parameter for the InputPointers' constructor. // TODO: Avoid creating a new instance here? final InputPointers pointers = new InputPointers(); for (final PointerTracker tracker : sTrackers) { tracker.getGestureStroke().appendAllBatchPoints(pointers); tracker.mGestureStroke.appendAllBatchPoints(pointers); } return pointers; } // TODO: To handle multi-touch gestures we may want to move this method to // {@link PointerTrackerQueue}. public static void clearBatchInputPoints() { for (final PointerTracker tracker : sTrackers) { tracker.getGestureStroke().reset(); tracker.mGestureStroke.reset(); } } Loading @@ -274,13 +279,9 @@ public class PointerTracker { return mKeyPreviewText; } public GestureStroke getGestureStroke() { return mGestureStroke; } // Returns true if keyboard has been changed by this callback. private boolean callListenerOnPressAndCheckKeyboardLayoutChange(Key key) { if (sGestureTracker.isInGesture()) { if (mInGesture) { return false; } final boolean ignoreModifierKey = mIgnoreModifierKey && key.isModifier(); Loading Loading @@ -336,7 +337,7 @@ public class PointerTracker { // Note that we need primaryCode argument because the keyboard may in shifted state and the // primaryCode is different from {@link Key#mCode}. private void callListenerOnRelease(Key key, int primaryCode, boolean withSliding) { if (sGestureTracker.isInGesture()) { if (mInGesture) { return; } final boolean ignoreModifierKey = mIgnoreModifierKey && key.isModifier(); Loading Loading @@ -369,6 +370,7 @@ public class PointerTracker { private void setKeyDetectorInner(KeyDetector keyDetector) { mKeyDetector = keyDetector; mKeyboard = keyDetector.getKeyboard(); mIsAlphabetKeyboard = mKeyboard.mId.isAlphabetKeyboard(); mGestureStroke.setGestureSampleLength( mKeyboard.mMostCommonKeyWidth, mKeyboard.mMostCommonKeyHeight); final Key newKey = mKeyDetector.detectHitKey(mKeyX, mKeyY); Loading Loading @@ -441,7 +443,7 @@ public class PointerTracker { return; } if (!key.noKeyPreview() && !sGestureTracker.isInGesture()) { if (!key.noKeyPreview() && !mInGesture) { mDrawingProxy.showKeyPreview(this); } updatePressKeyGraphics(key); Loading Loading @@ -512,6 +514,45 @@ public class PointerTracker { return newKey; } private void startBatchInput() { if (DEBUG_LISTENER) { Log.d(TAG, "onStartBatchInput"); } mInGesture = true; mListener.onStartBatchInput(); } private void updateBatchInput(InputPointers batchPoints) { if (DEBUG_LISTENER) { Log.d(TAG, "onUpdateBatchInput: batchPoints=" + batchPoints.getPointerSize()); } mListener.onUpdateBatchInput(batchPoints); } private void endBatchInput(InputPointers batchPoints) { if (DEBUG_LISTENER) { Log.d(TAG, "onEndBatchInput: batchPoints=" + batchPoints.getPointerSize()); } mListener.onEndBatchInput(batchPoints); mInGesture = false; clearBatchInputPoints(); } private void abortBatchInput() { mIsPossibleGesture = false; mInGesture = false; } private boolean updateBatchInputRecognitionState(long eventTime, int size) { if (size > mLastRecognitionPointSize && eventTime > mLastRecognitionTime + MIN_RECOGNITION_TIME) { mLastRecognitionPointSize = size; mLastRecognitionTime = eventTime; return true; } return false; } public void processMotionEvent(int action, int x, int y, long eventTime, KeyEventHandler handler) { switch (action) { Loading Loading @@ -570,7 +611,13 @@ public class PointerTracker { } onDownEventInternal(x, y, eventTime); if (queue != null && queue.size() == 1) { sGestureTracker.onDownEvent(this, x, y, eventTime, key); mIsPossibleGesture = false; // A gesture should start only from the letter key. if (GESTURE_ON && mIsAlphabetKeyboard && key != null && Keyboard.isLetterCode(key.mCode)) { mIsPossibleGesture = true; mGestureStroke.addPoint(x, y, 0, false); } } } Loading Loading @@ -606,6 +653,25 @@ public class PointerTracker { mIsInSlidingKeyInput = true; } private void onGestureMoveEvent(PointerTracker tracker, int x, int y, long eventTime, boolean isHistorical, Key key) { final int gestureTime = (int)(eventTime - tracker.getDownTime()); if (GESTURE_ON && mIsPossibleGesture) { final GestureStroke stroke = mGestureStroke; stroke.addPoint(x, y, gestureTime, isHistorical); if (!mInGesture && stroke.isStartOfAGesture(gestureTime)) { startBatchInput(); } } if (key != null && mInGesture) { final InputPointers batchPoints = getIncrementalBatchPoints(); if (updateBatchInputRecognitionState(eventTime, batchPoints.getPointerSize())) { updateBatchInput(batchPoints); } } } public void onMoveEvent(int x, int y, long eventTime, MotionEvent me) { if (DEBUG_MOVE_EVENT) printTouchEvent("onMoveEvent:", x, y, eventTime); Loading @@ -620,7 +686,7 @@ public class PointerTracker { final int historicalX = (int)me.getHistoricalX(pointerIndex, h); final int historicalY = (int)me.getHistoricalY(pointerIndex, h); final long historicalTime = me.getHistoricalEventTime(h); sGestureTracker.onMoveEvent(this, historicalX, historicalY, historicalTime, onGestureMoveEvent(this, historicalX, historicalY, historicalTime, true /* isHistorical */, null); } } Loading @@ -631,8 +697,8 @@ public class PointerTracker { Key key = onMoveKey(x, y); // Register move event on gesture tracker. sGestureTracker.onMoveEvent(this, x, y, eventTime, false, key); if (sGestureTracker.isInGesture()) { onGestureMoveEvent(this, x, y, eventTime, false /* isHistorical */, key); if (mInGesture) { mIgnoreModifierKey = true; mTimerProxy.cancelLongPressTimer(); mIsInSlidingKeyInput = true; Loading Loading @@ -729,7 +795,7 @@ public class PointerTracker { final PointerTrackerQueue queue = sPointerTrackerQueue; if (queue != null) { if (!sGestureTracker.isInGesture()) { if (!mInGesture) { if (mCurrentKey != null && mCurrentKey.isModifier()) { // Before processing an up event of modifier key, all pointers already being // tracked should be released. Loading Loading @@ -763,21 +829,16 @@ public class PointerTracker { mIsShowingMoreKeysPanel = false; } if (sGestureTracker.isInGesture()) { if (mInGesture) { // Register up event on gesture tracker. sGestureTracker.onUpEvent(this, x, y, eventTime); if (!sPointerTrackerQueue.isAnyInSlidingKeyInput()) { // TODO: Calls to beginBatchInput() is missing in this class. Reorganize the code. sGestureTracker.endBatchInput(); } // TODO: Figure out how to deal with multiple fingers that are in gesture, sliding, // and/or tapping mode? endBatchInput(getAllBatchPoints()); if (mCurrentKey != null) { callListenerOnRelease(mCurrentKey, mCurrentKey.mCode, true); } mCurrentKey = null; } return; } else { // TODO: Calls to beginBatchInput() is missing in this class. Reorganize the code. sGestureTracker.endBatchInput(); } if (mKeyAlreadyProcessed) Loading @@ -791,8 +852,7 @@ public class PointerTracker { onLongPressed(); onDownEvent(x, y, SystemClock.uptimeMillis(), handler); mIsShowingMoreKeysPanel = true; // TODO: Calls to beginBatchInput() is missing in this class. Reorganize the code. sGestureTracker.abortBatchInput(); abortBatchInput(); } public void onLongPressed() { Loading Loading @@ -827,7 +887,7 @@ public class PointerTracker { } private void startRepeatKey(Key key) { if (key != null && key.isRepeatable() && !sGestureTracker.isInGesture()) { if (key != null && key.isRepeatable() && !mInGesture) { onRegisterKey(key); mTimerProxy.startKeyRepeatTimer(this); } Loading Loading @@ -857,7 +917,7 @@ public class PointerTracker { } private void startLongPressTimer(Key key) { if (key != null && key.isLongPressEnabled() && !sGestureTracker.isInGesture()) { if (key != null && key.isLongPressEnabled() && !mInGesture) { mTimerProxy.startLongPressTimer(this); } } Loading java/src/com/android/inputmethod/keyboard/internal/GestureTracker.javadeleted 100644 → 0 +0 −147 Original line number Diff line number Diff line /* * Copyright (C) 2012 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and limitations under * the License. */ package com.android.inputmethod.keyboard.internal; import android.util.Log; import com.android.inputmethod.keyboard.Key; import com.android.inputmethod.keyboard.Keyboard; import com.android.inputmethod.keyboard.KeyboardActionListener; import com.android.inputmethod.keyboard.PointerTracker; import com.android.inputmethod.latin.InputPointers; // TODO: Remove this class by consolidating with PointerTracker public class GestureTracker { private static final String TAG = GestureTracker.class.getSimpleName(); private static final boolean DEBUG_LISTENER = false; // TODO: There should be an option to turn on/off the gesture input. private static final boolean GESTURE_ON = true; private static final GestureTracker sInstance = new GestureTracker(); private static final int MIN_RECOGNITION_TIME = 100; private boolean mIsAlphabetKeyboard; private boolean mIsPossibleGesture = false; private boolean mInGesture = false; private KeyboardActionListener mListener; private int mLastRecognitionPointSize = 0; private long mLastRecognitionTime = 0; public static void init(KeyboardActionListener listner) { sInstance.mListener = listner; } public static GestureTracker getInstance() { return sInstance; } private GestureTracker() { } public void setKeyboard(Keyboard keyboard) { mIsAlphabetKeyboard = keyboard.mId.isAlphabetKeyboard(); } private void startBatchInput() { if (DEBUG_LISTENER) { Log.d(TAG, "onStartBatchInput"); } mInGesture = true; mListener.onStartBatchInput(); } // TODO: The corresponding startBatchInput() is a private method. Reorganize the code. public void endBatchInput() { if (isInGesture()) { final InputPointers batchPoints = PointerTracker.getAllBatchPoints(); if (DEBUG_LISTENER) { Log.d(TAG, "onEndBatchInput: batchPoints=" + batchPoints.getPointerSize()); } mListener.onEndBatchInput(batchPoints); } mInGesture = false; clearBatchInputPoints(); } public void abortBatchInput() { mIsPossibleGesture = false; mInGesture = false; } public boolean isInGesture() { return mInGesture; } public void onDownEvent(PointerTracker tracker, int x, int y, long eventTime, Key key) { mIsPossibleGesture = false; // A gesture should start only from the letter key. if (GESTURE_ON && mIsAlphabetKeyboard && key != null && Keyboard.isLetterCode(key.mCode)) { mIsPossibleGesture = true; tracker.getGestureStroke().addPoint(x, y, 0, false); } } public void onMoveEvent(PointerTracker tracker, int x, int y, long eventTime, boolean isHistorical, Key key) { final int gestureTime = (int)(eventTime - tracker.getDownTime()); if (GESTURE_ON && mIsPossibleGesture) { final GestureStroke stroke = tracker.getGestureStroke(); stroke.addPoint(x, y, gestureTime, isHistorical); if (!isInGesture() && stroke.isStartOfAGesture(gestureTime)) { startBatchInput(); } } if (key != null && isInGesture()) { final InputPointers batchPoints = PointerTracker.getIncrementalBatchPoints(); if (updateBatchInputRecognitionState(eventTime, batchPoints.getPointerSize())) { if (DEBUG_LISTENER) { Log.d(TAG, "onUpdateBatchInput: batchPoints=" + batchPoints.getPointerSize()); } mListener.onUpdateBatchInput(batchPoints); } } } public void onUpEvent(PointerTracker tracker, int x, int y, long eventTime) { if (isInGesture()) { final InputPointers batchPoints = PointerTracker.getAllBatchPoints(); if (DEBUG_LISTENER) { Log.d(TAG, "onUpdateBatchInput: batchPoints=" + batchPoints.getPointerSize()); } mListener.onUpdateBatchInput(batchPoints); } } private void clearBatchInputPoints() { PointerTracker.clearBatchInputPoints(); mLastRecognitionPointSize = 0; mLastRecognitionTime = 0; } private boolean updateBatchInputRecognitionState(long eventTime, int size) { if (size > mLastRecognitionPointSize && eventTime > mLastRecognitionTime + MIN_RECOGNITION_TIME) { mLastRecognitionPointSize = size; mLastRecognitionTime = eventTime; return true; } return false; } } java/src/com/android/inputmethod/latin/InputPointers.java +3 −0 Original line number Diff line number Diff line Loading @@ -60,6 +60,9 @@ public class InputPointers { * @param length the number of pointers to be appended. */ public void append(InputPointers src, int startPos, int length) { if (length == 0) { return; } mXCoordinates.append(src.mXCoordinates, startPos, length); mYCoordinates.append(src.mYCoordinates, startPos, length); mPointerIds.append(src.mPointerIds, startPos, length); Loading Loading
java/src/com/android/inputmethod/keyboard/PointerTracker.java +109 −49 Original line number Diff line number Diff line Loading @@ -23,7 +23,6 @@ import android.view.View; import android.widget.TextView; import com.android.inputmethod.keyboard.internal.GestureStroke; import com.android.inputmethod.keyboard.internal.GestureTracker; import com.android.inputmethod.keyboard.internal.PointerTrackerQueue; import com.android.inputmethod.latin.InputPointers; import com.android.inputmethod.latin.LatinImeLogger; Loading @@ -39,6 +38,10 @@ public class PointerTracker { private static final boolean DEBUG_LISTENER = false; private static boolean DEBUG_MODE = LatinImeLogger.sDBG; // TODO: There should be an option to turn on/off the gesture input. private static final boolean GESTURE_ON = true; private static final int MIN_RECOGNITION_TIME = 100; // msec public interface KeyEventHandler { /** * Get KeyDetector object that is used for this PointerTracker. Loading Loading @@ -128,6 +131,13 @@ public class PointerTracker { private int mKeyQuarterWidthSquared; private final TextView mKeyPreviewText; private boolean mIsAlphabetKeyboard; private boolean mIsPossibleGesture = false; private boolean mInGesture = false; private int mLastRecognitionPointSize = 0; private long mLastRecognitionTime = 0; // The position and time at which first down event occurred. private long mDownTime; private long mUpTime; Loading Loading @@ -164,9 +174,6 @@ public class PointerTracker { private static final KeyboardActionListener EMPTY_LISTENER = new KeyboardActionListener.Adapter(); // Gesture tracker singleton instance private static final GestureTracker sGestureTracker = GestureTracker.getInstance(); private final GestureStroke mGestureStroke; public static void init(boolean hasDistinctMultitouch, Loading Loading @@ -207,7 +214,6 @@ public class PointerTracker { for (final PointerTracker tracker : sTrackers) { tracker.mListener = listener; } GestureTracker.init(listener); } public static void setKeyDetector(KeyDetector keyDetector) { Loading @@ -216,7 +222,6 @@ public class PointerTracker { // Mark that keyboard layout has been changed. tracker.mKeyboardLayoutHasBeenChanged = true; } sGestureTracker.setKeyboard(keyDetector.getKeyboard()); } public static void dismissAllKeyPreviews() { Loading @@ -226,35 +231,35 @@ public class PointerTracker { } } // The working and returning object of the following methods, // {@link #getIncrementalBatchPoints()} and {@link #getAllBatchPoints()}. private static final InputPointers mAggregatedPointers = new InputPointers(); // TODO: This method is called only from GestureTracker and should address the thread-safty // issue soon. public static InputPointers getIncrementalBatchPoints() { final InputPointers pointers = mAggregatedPointers; pointers.reset(); // TODO: To handle multi-touch gestures we may want to move this method to // {@link PointerTrackerQueue}. private static InputPointers getIncrementalBatchPoints() { final InputPointers pointers = new InputPointers(); // TODO: Add a default capacity parameter for the InputPointers' constructor. // TODO: Avoid creating a new instance here? for (final PointerTracker tracker : sTrackers) { tracker.getGestureStroke().appendIncrementalBatchPoints(pointers); tracker.mGestureStroke.appendIncrementalBatchPoints(pointers); } return pointers; } // TODO: This method is called only from GestureTracker and should address the thread-safety // issue soon. public static InputPointers getAllBatchPoints() { final InputPointers pointers = mAggregatedPointers; pointers.reset(); // TODO: To handle multi-touch gestures we may want to move this method to // {@link PointerTrackerQueue}. private static InputPointers getAllBatchPoints() { // TODO: Add a default capacity parameter for the InputPointers' constructor. // TODO: Avoid creating a new instance here? final InputPointers pointers = new InputPointers(); for (final PointerTracker tracker : sTrackers) { tracker.getGestureStroke().appendAllBatchPoints(pointers); tracker.mGestureStroke.appendAllBatchPoints(pointers); } return pointers; } // TODO: To handle multi-touch gestures we may want to move this method to // {@link PointerTrackerQueue}. public static void clearBatchInputPoints() { for (final PointerTracker tracker : sTrackers) { tracker.getGestureStroke().reset(); tracker.mGestureStroke.reset(); } } Loading @@ -274,13 +279,9 @@ public class PointerTracker { return mKeyPreviewText; } public GestureStroke getGestureStroke() { return mGestureStroke; } // Returns true if keyboard has been changed by this callback. private boolean callListenerOnPressAndCheckKeyboardLayoutChange(Key key) { if (sGestureTracker.isInGesture()) { if (mInGesture) { return false; } final boolean ignoreModifierKey = mIgnoreModifierKey && key.isModifier(); Loading Loading @@ -336,7 +337,7 @@ public class PointerTracker { // Note that we need primaryCode argument because the keyboard may in shifted state and the // primaryCode is different from {@link Key#mCode}. private void callListenerOnRelease(Key key, int primaryCode, boolean withSliding) { if (sGestureTracker.isInGesture()) { if (mInGesture) { return; } final boolean ignoreModifierKey = mIgnoreModifierKey && key.isModifier(); Loading Loading @@ -369,6 +370,7 @@ public class PointerTracker { private void setKeyDetectorInner(KeyDetector keyDetector) { mKeyDetector = keyDetector; mKeyboard = keyDetector.getKeyboard(); mIsAlphabetKeyboard = mKeyboard.mId.isAlphabetKeyboard(); mGestureStroke.setGestureSampleLength( mKeyboard.mMostCommonKeyWidth, mKeyboard.mMostCommonKeyHeight); final Key newKey = mKeyDetector.detectHitKey(mKeyX, mKeyY); Loading Loading @@ -441,7 +443,7 @@ public class PointerTracker { return; } if (!key.noKeyPreview() && !sGestureTracker.isInGesture()) { if (!key.noKeyPreview() && !mInGesture) { mDrawingProxy.showKeyPreview(this); } updatePressKeyGraphics(key); Loading Loading @@ -512,6 +514,45 @@ public class PointerTracker { return newKey; } private void startBatchInput() { if (DEBUG_LISTENER) { Log.d(TAG, "onStartBatchInput"); } mInGesture = true; mListener.onStartBatchInput(); } private void updateBatchInput(InputPointers batchPoints) { if (DEBUG_LISTENER) { Log.d(TAG, "onUpdateBatchInput: batchPoints=" + batchPoints.getPointerSize()); } mListener.onUpdateBatchInput(batchPoints); } private void endBatchInput(InputPointers batchPoints) { if (DEBUG_LISTENER) { Log.d(TAG, "onEndBatchInput: batchPoints=" + batchPoints.getPointerSize()); } mListener.onEndBatchInput(batchPoints); mInGesture = false; clearBatchInputPoints(); } private void abortBatchInput() { mIsPossibleGesture = false; mInGesture = false; } private boolean updateBatchInputRecognitionState(long eventTime, int size) { if (size > mLastRecognitionPointSize && eventTime > mLastRecognitionTime + MIN_RECOGNITION_TIME) { mLastRecognitionPointSize = size; mLastRecognitionTime = eventTime; return true; } return false; } public void processMotionEvent(int action, int x, int y, long eventTime, KeyEventHandler handler) { switch (action) { Loading Loading @@ -570,7 +611,13 @@ public class PointerTracker { } onDownEventInternal(x, y, eventTime); if (queue != null && queue.size() == 1) { sGestureTracker.onDownEvent(this, x, y, eventTime, key); mIsPossibleGesture = false; // A gesture should start only from the letter key. if (GESTURE_ON && mIsAlphabetKeyboard && key != null && Keyboard.isLetterCode(key.mCode)) { mIsPossibleGesture = true; mGestureStroke.addPoint(x, y, 0, false); } } } Loading Loading @@ -606,6 +653,25 @@ public class PointerTracker { mIsInSlidingKeyInput = true; } private void onGestureMoveEvent(PointerTracker tracker, int x, int y, long eventTime, boolean isHistorical, Key key) { final int gestureTime = (int)(eventTime - tracker.getDownTime()); if (GESTURE_ON && mIsPossibleGesture) { final GestureStroke stroke = mGestureStroke; stroke.addPoint(x, y, gestureTime, isHistorical); if (!mInGesture && stroke.isStartOfAGesture(gestureTime)) { startBatchInput(); } } if (key != null && mInGesture) { final InputPointers batchPoints = getIncrementalBatchPoints(); if (updateBatchInputRecognitionState(eventTime, batchPoints.getPointerSize())) { updateBatchInput(batchPoints); } } } public void onMoveEvent(int x, int y, long eventTime, MotionEvent me) { if (DEBUG_MOVE_EVENT) printTouchEvent("onMoveEvent:", x, y, eventTime); Loading @@ -620,7 +686,7 @@ public class PointerTracker { final int historicalX = (int)me.getHistoricalX(pointerIndex, h); final int historicalY = (int)me.getHistoricalY(pointerIndex, h); final long historicalTime = me.getHistoricalEventTime(h); sGestureTracker.onMoveEvent(this, historicalX, historicalY, historicalTime, onGestureMoveEvent(this, historicalX, historicalY, historicalTime, true /* isHistorical */, null); } } Loading @@ -631,8 +697,8 @@ public class PointerTracker { Key key = onMoveKey(x, y); // Register move event on gesture tracker. sGestureTracker.onMoveEvent(this, x, y, eventTime, false, key); if (sGestureTracker.isInGesture()) { onGestureMoveEvent(this, x, y, eventTime, false /* isHistorical */, key); if (mInGesture) { mIgnoreModifierKey = true; mTimerProxy.cancelLongPressTimer(); mIsInSlidingKeyInput = true; Loading Loading @@ -729,7 +795,7 @@ public class PointerTracker { final PointerTrackerQueue queue = sPointerTrackerQueue; if (queue != null) { if (!sGestureTracker.isInGesture()) { if (!mInGesture) { if (mCurrentKey != null && mCurrentKey.isModifier()) { // Before processing an up event of modifier key, all pointers already being // tracked should be released. Loading Loading @@ -763,21 +829,16 @@ public class PointerTracker { mIsShowingMoreKeysPanel = false; } if (sGestureTracker.isInGesture()) { if (mInGesture) { // Register up event on gesture tracker. sGestureTracker.onUpEvent(this, x, y, eventTime); if (!sPointerTrackerQueue.isAnyInSlidingKeyInput()) { // TODO: Calls to beginBatchInput() is missing in this class. Reorganize the code. sGestureTracker.endBatchInput(); } // TODO: Figure out how to deal with multiple fingers that are in gesture, sliding, // and/or tapping mode? endBatchInput(getAllBatchPoints()); if (mCurrentKey != null) { callListenerOnRelease(mCurrentKey, mCurrentKey.mCode, true); } mCurrentKey = null; } return; } else { // TODO: Calls to beginBatchInput() is missing in this class. Reorganize the code. sGestureTracker.endBatchInput(); } if (mKeyAlreadyProcessed) Loading @@ -791,8 +852,7 @@ public class PointerTracker { onLongPressed(); onDownEvent(x, y, SystemClock.uptimeMillis(), handler); mIsShowingMoreKeysPanel = true; // TODO: Calls to beginBatchInput() is missing in this class. Reorganize the code. sGestureTracker.abortBatchInput(); abortBatchInput(); } public void onLongPressed() { Loading Loading @@ -827,7 +887,7 @@ public class PointerTracker { } private void startRepeatKey(Key key) { if (key != null && key.isRepeatable() && !sGestureTracker.isInGesture()) { if (key != null && key.isRepeatable() && !mInGesture) { onRegisterKey(key); mTimerProxy.startKeyRepeatTimer(this); } Loading Loading @@ -857,7 +917,7 @@ public class PointerTracker { } private void startLongPressTimer(Key key) { if (key != null && key.isLongPressEnabled() && !sGestureTracker.isInGesture()) { if (key != null && key.isLongPressEnabled() && !mInGesture) { mTimerProxy.startLongPressTimer(this); } } Loading
java/src/com/android/inputmethod/keyboard/internal/GestureTracker.javadeleted 100644 → 0 +0 −147 Original line number Diff line number Diff line /* * Copyright (C) 2012 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and limitations under * the License. */ package com.android.inputmethod.keyboard.internal; import android.util.Log; import com.android.inputmethod.keyboard.Key; import com.android.inputmethod.keyboard.Keyboard; import com.android.inputmethod.keyboard.KeyboardActionListener; import com.android.inputmethod.keyboard.PointerTracker; import com.android.inputmethod.latin.InputPointers; // TODO: Remove this class by consolidating with PointerTracker public class GestureTracker { private static final String TAG = GestureTracker.class.getSimpleName(); private static final boolean DEBUG_LISTENER = false; // TODO: There should be an option to turn on/off the gesture input. private static final boolean GESTURE_ON = true; private static final GestureTracker sInstance = new GestureTracker(); private static final int MIN_RECOGNITION_TIME = 100; private boolean mIsAlphabetKeyboard; private boolean mIsPossibleGesture = false; private boolean mInGesture = false; private KeyboardActionListener mListener; private int mLastRecognitionPointSize = 0; private long mLastRecognitionTime = 0; public static void init(KeyboardActionListener listner) { sInstance.mListener = listner; } public static GestureTracker getInstance() { return sInstance; } private GestureTracker() { } public void setKeyboard(Keyboard keyboard) { mIsAlphabetKeyboard = keyboard.mId.isAlphabetKeyboard(); } private void startBatchInput() { if (DEBUG_LISTENER) { Log.d(TAG, "onStartBatchInput"); } mInGesture = true; mListener.onStartBatchInput(); } // TODO: The corresponding startBatchInput() is a private method. Reorganize the code. public void endBatchInput() { if (isInGesture()) { final InputPointers batchPoints = PointerTracker.getAllBatchPoints(); if (DEBUG_LISTENER) { Log.d(TAG, "onEndBatchInput: batchPoints=" + batchPoints.getPointerSize()); } mListener.onEndBatchInput(batchPoints); } mInGesture = false; clearBatchInputPoints(); } public void abortBatchInput() { mIsPossibleGesture = false; mInGesture = false; } public boolean isInGesture() { return mInGesture; } public void onDownEvent(PointerTracker tracker, int x, int y, long eventTime, Key key) { mIsPossibleGesture = false; // A gesture should start only from the letter key. if (GESTURE_ON && mIsAlphabetKeyboard && key != null && Keyboard.isLetterCode(key.mCode)) { mIsPossibleGesture = true; tracker.getGestureStroke().addPoint(x, y, 0, false); } } public void onMoveEvent(PointerTracker tracker, int x, int y, long eventTime, boolean isHistorical, Key key) { final int gestureTime = (int)(eventTime - tracker.getDownTime()); if (GESTURE_ON && mIsPossibleGesture) { final GestureStroke stroke = tracker.getGestureStroke(); stroke.addPoint(x, y, gestureTime, isHistorical); if (!isInGesture() && stroke.isStartOfAGesture(gestureTime)) { startBatchInput(); } } if (key != null && isInGesture()) { final InputPointers batchPoints = PointerTracker.getIncrementalBatchPoints(); if (updateBatchInputRecognitionState(eventTime, batchPoints.getPointerSize())) { if (DEBUG_LISTENER) { Log.d(TAG, "onUpdateBatchInput: batchPoints=" + batchPoints.getPointerSize()); } mListener.onUpdateBatchInput(batchPoints); } } } public void onUpEvent(PointerTracker tracker, int x, int y, long eventTime) { if (isInGesture()) { final InputPointers batchPoints = PointerTracker.getAllBatchPoints(); if (DEBUG_LISTENER) { Log.d(TAG, "onUpdateBatchInput: batchPoints=" + batchPoints.getPointerSize()); } mListener.onUpdateBatchInput(batchPoints); } } private void clearBatchInputPoints() { PointerTracker.clearBatchInputPoints(); mLastRecognitionPointSize = 0; mLastRecognitionTime = 0; } private boolean updateBatchInputRecognitionState(long eventTime, int size) { if (size > mLastRecognitionPointSize && eventTime > mLastRecognitionTime + MIN_RECOGNITION_TIME) { mLastRecognitionPointSize = size; mLastRecognitionTime = eventTime; return true; } return false; } }
java/src/com/android/inputmethod/latin/InputPointers.java +3 −0 Original line number Diff line number Diff line Loading @@ -60,6 +60,9 @@ public class InputPointers { * @param length the number of pointers to be appended. */ public void append(InputPointers src, int startPos, int length) { if (length == 0) { return; } mXCoordinates.append(src.mXCoordinates, startPos, length); mYCoordinates.append(src.mYCoordinates, startPos, length); mPointerIds.append(src.mPointerIds, startPos, length); Loading