am 263caae3
: Merge "Support bimanual gesture input" into jb-mr1-dev
* commit '263caae3c91314883b37c2db314342fab5c7903f': Support bimanual gesture input
This commit is contained in:
commit
5d309b35d2
3 changed files with 127 additions and 134 deletions
|
@ -992,7 +992,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void showGestureTrail(PointerTracker tracker) {
|
public void showGesturePreviewTrail(PointerTracker tracker) {
|
||||||
locatePreviewPlacerView();
|
locatePreviewPlacerView();
|
||||||
mPreviewPlacerView.invalidatePointer(tracker);
|
mPreviewPlacerView.invalidatePointer(tracker);
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,7 +80,7 @@ public class PointerTracker implements PointerTrackerQueue.Element {
|
||||||
public void invalidateKey(Key key);
|
public void invalidateKey(Key key);
|
||||||
public void showKeyPreview(PointerTracker tracker);
|
public void showKeyPreview(PointerTracker tracker);
|
||||||
public void dismissKeyPreview(PointerTracker tracker);
|
public void dismissKeyPreview(PointerTracker tracker);
|
||||||
public void showGestureTrail(PointerTracker tracker);
|
public void showGesturePreviewTrail(PointerTracker tracker);
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface TimerProxy {
|
public interface TimerProxy {
|
||||||
|
@ -152,8 +152,6 @@ public class PointerTracker implements PointerTrackerQueue.Element {
|
||||||
private static boolean sNeedsPhantomSuddenMoveEventHack;
|
private static boolean sNeedsPhantomSuddenMoveEventHack;
|
||||||
|
|
||||||
private static final ArrayList<PointerTracker> sTrackers = CollectionUtils.newArrayList();
|
private static final ArrayList<PointerTracker> sTrackers = CollectionUtils.newArrayList();
|
||||||
private static final InputPointers sAggregratedPointers = new InputPointers(
|
|
||||||
GestureStroke.DEFAULT_CAPACITY);
|
|
||||||
private static PointerTrackerQueue sPointerTrackerQueue;
|
private static PointerTrackerQueue sPointerTrackerQueue;
|
||||||
|
|
||||||
public final int mPointerId;
|
public final int mPointerId;
|
||||||
|
@ -166,13 +164,13 @@ public class PointerTracker implements PointerTrackerQueue.Element {
|
||||||
private Keyboard mKeyboard;
|
private Keyboard mKeyboard;
|
||||||
private int mKeyQuarterWidthSquared;
|
private int mKeyQuarterWidthSquared;
|
||||||
|
|
||||||
private boolean mIsAlphabetKeyboard;
|
private boolean mIsDetectingGesture = false; // per PointerTracker.
|
||||||
private boolean mIsPossibleGesture = false;
|
private static boolean sInGesture = false;
|
||||||
private boolean mInGesture = false;
|
private static long sGestureFirstDownTime;
|
||||||
|
private static final InputPointers sAggregratedPointers = new InputPointers(
|
||||||
// TODO: Remove these variables
|
GestureStroke.DEFAULT_CAPACITY);
|
||||||
private int mLastRecognitionPointSize = 0;
|
private static int sLastRecognitionPointSize = 0;
|
||||||
private long mLastRecognitionTime = 0;
|
private static long sLastRecognitionTime = 0;
|
||||||
|
|
||||||
// The position and time at which first down event occurred.
|
// The position and time at which first down event occurred.
|
||||||
private long mDownTime;
|
private long mDownTime;
|
||||||
|
@ -290,40 +288,6 @@ public class PointerTracker implements PointerTrackerQueue.Element {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: To handle multi-touch gestures we may want to move this method to
|
|
||||||
// {@link PointerTrackerQueue}.
|
|
||||||
private static InputPointers getIncrementalBatchPoints() {
|
|
||||||
final int trackersSize = sTrackers.size();
|
|
||||||
for (int i = 0; i < trackersSize; ++i) {
|
|
||||||
final PointerTracker tracker = sTrackers.get(i);
|
|
||||||
tracker.mGestureStrokeWithPreviewTrail.appendIncrementalBatchPoints(
|
|
||||||
sAggregratedPointers);
|
|
||||||
}
|
|
||||||
return sAggregratedPointers;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: To handle multi-touch gestures we may want to move this method to
|
|
||||||
// {@link PointerTrackerQueue}.
|
|
||||||
private static InputPointers getAllBatchPoints() {
|
|
||||||
final int trackersSize = sTrackers.size();
|
|
||||||
for (int i = 0; i < trackersSize; ++i) {
|
|
||||||
final PointerTracker tracker = sTrackers.get(i);
|
|
||||||
tracker.mGestureStrokeWithPreviewTrail.appendAllBatchPoints(sAggregratedPointers);
|
|
||||||
}
|
|
||||||
return sAggregratedPointers;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: To handle multi-touch gestures we may want to move this method to
|
|
||||||
// {@link PointerTrackerQueue}.
|
|
||||||
public static void clearBatchInputPointsOfAllPointerTrackers() {
|
|
||||||
final int trackersSize = sTrackers.size();
|
|
||||||
for (int i = 0; i < trackersSize; ++i) {
|
|
||||||
final PointerTracker tracker = sTrackers.get(i);
|
|
||||||
tracker.mGestureStrokeWithPreviewTrail.reset();
|
|
||||||
}
|
|
||||||
sAggregratedPointers.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
private PointerTracker(final int id, final KeyEventHandler handler) {
|
private PointerTracker(final int id, final KeyEventHandler handler) {
|
||||||
if (handler == null) {
|
if (handler == null) {
|
||||||
throw new NullPointerException();
|
throw new NullPointerException();
|
||||||
|
@ -338,7 +302,7 @@ public class PointerTracker implements PointerTrackerQueue.Element {
|
||||||
|
|
||||||
// Returns true if keyboard has been changed by this callback.
|
// Returns true if keyboard has been changed by this callback.
|
||||||
private boolean callListenerOnPressAndCheckKeyboardLayoutChange(final Key key) {
|
private boolean callListenerOnPressAndCheckKeyboardLayoutChange(final Key key) {
|
||||||
if (mInGesture) {
|
if (sInGesture) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final boolean ignoreModifierKey = mIgnoreModifierKey && key.isModifier();
|
final boolean ignoreModifierKey = mIgnoreModifierKey && key.isModifier();
|
||||||
|
@ -394,7 +358,7 @@ public class PointerTracker implements PointerTrackerQueue.Element {
|
||||||
// primaryCode is different from {@link Key#mCode}.
|
// primaryCode is different from {@link Key#mCode}.
|
||||||
private void callListenerOnRelease(final Key key, final int primaryCode,
|
private void callListenerOnRelease(final Key key, final int primaryCode,
|
||||||
final boolean withSliding) {
|
final boolean withSliding) {
|
||||||
if (mInGesture) {
|
if (sInGesture) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final boolean ignoreModifierKey = mIgnoreModifierKey && key.isModifier();
|
final boolean ignoreModifierKey = mIgnoreModifierKey && key.isModifier();
|
||||||
|
@ -428,7 +392,6 @@ public class PointerTracker implements PointerTrackerQueue.Element {
|
||||||
private void setKeyDetectorInner(final KeyDetector keyDetector) {
|
private void setKeyDetectorInner(final KeyDetector keyDetector) {
|
||||||
mKeyDetector = keyDetector;
|
mKeyDetector = keyDetector;
|
||||||
mKeyboard = keyDetector.getKeyboard();
|
mKeyboard = keyDetector.getKeyboard();
|
||||||
mIsAlphabetKeyboard = mKeyboard.mId.isAlphabetKeyboard();
|
|
||||||
mGestureStrokeWithPreviewTrail.setGestureSampleLength(mKeyboard.mMostCommonKeyWidth);
|
mGestureStrokeWithPreviewTrail.setGestureSampleLength(mKeyboard.mMostCommonKeyWidth);
|
||||||
final Key newKey = mKeyDetector.detectHitKey(mKeyX, mKeyY);
|
final Key newKey = mKeyDetector.detectHitKey(mKeyX, mKeyY);
|
||||||
if (newKey != mCurrentKey) {
|
if (newKey != mCurrentKey) {
|
||||||
|
@ -502,7 +465,7 @@ public class PointerTracker implements PointerTrackerQueue.Element {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!key.noKeyPreview() && !mInGesture) {
|
if (!key.noKeyPreview() && !sInGesture) {
|
||||||
mDrawingProxy.showKeyPreview(this);
|
mDrawingProxy.showKeyPreview(this);
|
||||||
}
|
}
|
||||||
updatePressKeyGraphics(key);
|
updatePressKeyGraphics(key);
|
||||||
|
@ -577,50 +540,65 @@ public class PointerTracker implements PointerTrackerQueue.Element {
|
||||||
return newKey;
|
return newKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static int getActivePointerTrackerCount() {
|
||||||
|
return (sPointerTrackerQueue == null) ? 1 : sPointerTrackerQueue.size();
|
||||||
|
}
|
||||||
|
|
||||||
private void startBatchInput() {
|
private void startBatchInput() {
|
||||||
if (DEBUG_LISTENER) {
|
if (DEBUG_LISTENER) {
|
||||||
Log.d(TAG, "onStartBatchInput");
|
Log.d(TAG, "onStartBatchInput");
|
||||||
}
|
}
|
||||||
mInGesture = true;
|
sInGesture = true;
|
||||||
mListener.onStartBatchInput();
|
mListener.onStartBatchInput();
|
||||||
|
mDrawingProxy.showGesturePreviewTrail(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateBatchInput(final InputPointers batchPoints) {
|
private void updateBatchInput(final long eventTime) {
|
||||||
|
synchronized (sAggregratedPointers) {
|
||||||
|
mGestureStrokeWithPreviewTrail.appendIncrementalBatchPoints(sAggregratedPointers);
|
||||||
|
final int size = sAggregratedPointers.getPointerSize();
|
||||||
|
if (size > sLastRecognitionPointSize
|
||||||
|
&& eventTime > sLastRecognitionTime + MIN_GESTURE_RECOGNITION_TIME) {
|
||||||
|
sLastRecognitionPointSize = size;
|
||||||
|
sLastRecognitionTime = eventTime;
|
||||||
if (DEBUG_LISTENER) {
|
if (DEBUG_LISTENER) {
|
||||||
Log.d(TAG, "onUpdateBatchInput: batchPoints=" + batchPoints.getPointerSize());
|
Log.d(TAG, "onUpdateBatchInput: batchPoints=" + size);
|
||||||
}
|
}
|
||||||
mListener.onUpdateBatchInput(batchPoints);
|
mListener.onUpdateBatchInput(sAggregratedPointers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mDrawingProxy.showGesturePreviewTrail(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void endBatchInput(final InputPointers batchPoints) {
|
private void endBatchInput() {
|
||||||
|
synchronized (sAggregratedPointers) {
|
||||||
|
mGestureStrokeWithPreviewTrail.appendAllBatchPoints(sAggregratedPointers);
|
||||||
|
if (getActivePointerTrackerCount() == 1) {
|
||||||
if (DEBUG_LISTENER) {
|
if (DEBUG_LISTENER) {
|
||||||
Log.d(TAG, "onEndBatchInput: batchPoints=" + batchPoints.getPointerSize());
|
Log.d(TAG, "onEndBatchInput: batchPoints="
|
||||||
|
+ sAggregratedPointers.getPointerSize());
|
||||||
}
|
}
|
||||||
mListener.onEndBatchInput(batchPoints);
|
sInGesture = false;
|
||||||
clearBatchInputRecognitionStateOfThisPointerTracker();
|
mListener.onEndBatchInput(sAggregratedPointers);
|
||||||
|
clearBatchInputPointsOfAllPointerTrackers();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mDrawingProxy.showGesturePreviewTrail(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void abortBatchInput() {
|
||||||
clearBatchInputPointsOfAllPointerTrackers();
|
clearBatchInputPointsOfAllPointerTrackers();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void abortBatchInput() {
|
private static void clearBatchInputPointsOfAllPointerTrackers() {
|
||||||
clearBatchInputRecognitionStateOfThisPointerTracker();
|
final int trackersSize = sTrackers.size();
|
||||||
clearBatchInputPointsOfAllPointerTrackers();
|
for (int i = 0; i < trackersSize; ++i) {
|
||||||
|
final PointerTracker tracker = sTrackers.get(i);
|
||||||
|
tracker.mGestureStrokeWithPreviewTrail.reset();
|
||||||
}
|
}
|
||||||
|
sAggregratedPointers.reset();
|
||||||
private void clearBatchInputRecognitionStateOfThisPointerTracker() {
|
sLastRecognitionPointSize = 0;
|
||||||
mIsPossibleGesture = false;
|
sLastRecognitionTime = 0;
|
||||||
mInGesture = false;
|
|
||||||
mLastRecognitionPointSize = 0;
|
|
||||||
mLastRecognitionTime = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean updateBatchInputRecognitionState(final long eventTime, final int size) {
|
|
||||||
if (size > mLastRecognitionPointSize
|
|
||||||
&& eventTime > mLastRecognitionTime + MIN_GESTURE_RECOGNITION_TIME) {
|
|
||||||
mLastRecognitionPointSize = size;
|
|
||||||
mLastRecognitionTime = eventTime;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void processMotionEvent(final int action, final int x, final int y, final long eventTime,
|
public void processMotionEvent(final int action, final int x, final int y, final long eventTime,
|
||||||
|
@ -671,8 +649,8 @@ public class PointerTracker implements PointerTrackerQueue.Element {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final PointerTrackerQueue queue = sPointerTrackerQueue;
|
|
||||||
final Key key = getKeyOn(x, y);
|
final Key key = getKeyOn(x, y);
|
||||||
|
final PointerTrackerQueue queue = sPointerTrackerQueue;
|
||||||
if (queue != null) {
|
if (queue != null) {
|
||||||
if (key != null && key.isModifier()) {
|
if (key != null && key.isModifier()) {
|
||||||
// Before processing a down event of modifier key, all pointers already being
|
// Before processing a down event of modifier key, all pointers already being
|
||||||
|
@ -682,16 +660,26 @@ public class PointerTracker implements PointerTrackerQueue.Element {
|
||||||
queue.add(this);
|
queue.add(this);
|
||||||
}
|
}
|
||||||
onDownEventInternal(x, y, eventTime);
|
onDownEventInternal(x, y, eventTime);
|
||||||
if (queue != null && queue.size() == 1) {
|
if (!sShouldHandleGesture) {
|
||||||
mIsPossibleGesture = false;
|
return;
|
||||||
// A gesture should start only from the letter key.
|
|
||||||
if (sShouldHandleGesture && mIsAlphabetKeyboard && !mIsShowingMoreKeysPanel
|
|
||||||
&& key != null && Keyboard.isLetterCode(key.mCode)) {
|
|
||||||
mIsPossibleGesture = true;
|
|
||||||
// TODO: pointer times should be relative to first down even in entire batch input
|
|
||||||
// instead of resetting to 0 for each new down event.
|
|
||||||
mGestureStrokeWithPreviewTrail.addPoint(x, y, 0, false);
|
|
||||||
}
|
}
|
||||||
|
final int activePointerTrackerCount = getActivePointerTrackerCount();
|
||||||
|
if (activePointerTrackerCount == 1) {
|
||||||
|
mIsDetectingGesture = false;
|
||||||
|
// A gesture should start only from the letter key.
|
||||||
|
final boolean isAlphabetKeyboard = (mKeyboard != null)
|
||||||
|
&& mKeyboard.mId.isAlphabetKeyboard();
|
||||||
|
if (isAlphabetKeyboard && !mIsShowingMoreKeysPanel && key != null
|
||||||
|
&& Keyboard.isLetterCode(key.mCode)) {
|
||||||
|
mIsDetectingGesture = true;
|
||||||
|
sGestureFirstDownTime = eventTime;
|
||||||
|
mGestureStrokeWithPreviewTrail.addPoint(x, y, 0, false /* isHistorical */);
|
||||||
|
}
|
||||||
|
} else if (sInGesture && activePointerTrackerCount > 1) {
|
||||||
|
mIsDetectingGesture = true;
|
||||||
|
final int elapsedTimeFromFirstDown = (int)(eventTime - sGestureFirstDownTime);
|
||||||
|
mGestureStrokeWithPreviewTrail.addPoint(x, y, elapsedTimeFromFirstDown,
|
||||||
|
false /* isHistorical */);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -727,22 +715,18 @@ public class PointerTracker implements PointerTrackerQueue.Element {
|
||||||
mIsInSlidingKeyInput = true;
|
mIsInSlidingKeyInput = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onGestureMoveEvent(final PointerTracker tracker, final int x, final int y,
|
private void onGestureMoveEvent(final int x, final int y, final long eventTime,
|
||||||
final long eventTime, final boolean isHistorical, final Key key) {
|
final boolean isHistorical, final Key key) {
|
||||||
final int gestureTime = (int)(eventTime - tracker.getDownTime());
|
final int gestureTime = (int)(eventTime - sGestureFirstDownTime);
|
||||||
if (sShouldHandleGesture && mIsPossibleGesture) {
|
if (mIsDetectingGesture) {
|
||||||
final GestureStroke stroke = mGestureStrokeWithPreviewTrail;
|
final GestureStroke stroke = mGestureStrokeWithPreviewTrail;
|
||||||
stroke.addPoint(x, y, gestureTime, isHistorical);
|
stroke.addPoint(x, y, gestureTime, isHistorical);
|
||||||
if (!mInGesture && stroke.isStartOfAGesture()) {
|
if (!sInGesture && stroke.isStartOfAGesture()) {
|
||||||
startBatchInput();
|
startBatchInput();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (key != null && mInGesture) {
|
if (sInGesture && key != null) {
|
||||||
final InputPointers batchPoints = getIncrementalBatchPoints();
|
updateBatchInput(eventTime);
|
||||||
mDrawingProxy.showGestureTrail(this);
|
|
||||||
if (updateBatchInputRecognitionState(eventTime, batchPoints.getPointerSize())) {
|
|
||||||
updateBatchInput(batchPoints);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -755,7 +739,7 @@ public class PointerTracker implements PointerTrackerQueue.Element {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (me != null) {
|
if (sShouldHandleGesture && me != null) {
|
||||||
// Add historical points to gesture path.
|
// Add historical points to gesture path.
|
||||||
final int pointerIndex = me.findPointerIndex(mPointerId);
|
final int pointerIndex = me.findPointerIndex(mPointerId);
|
||||||
final int historicalSize = me.getHistorySize();
|
final int historicalSize = me.getHistorySize();
|
||||||
|
@ -763,24 +747,31 @@ public class PointerTracker implements PointerTrackerQueue.Element {
|
||||||
final int historicalX = (int)me.getHistoricalX(pointerIndex, h);
|
final int historicalX = (int)me.getHistoricalX(pointerIndex, h);
|
||||||
final int historicalY = (int)me.getHistoricalY(pointerIndex, h);
|
final int historicalY = (int)me.getHistoricalY(pointerIndex, h);
|
||||||
final long historicalTime = me.getHistoricalEventTime(h);
|
final long historicalTime = me.getHistoricalEventTime(h);
|
||||||
onGestureMoveEvent(this, historicalX, historicalY, historicalTime,
|
onGestureMoveEvent(historicalX, historicalY, historicalTime,
|
||||||
true /* isHistorical */, null);
|
true /* isHistorical */, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onMoveEventInternal(x, y, eventTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onMoveEventInternal(final int x, final int y, final long eventTime) {
|
||||||
final int lastX = mLastX;
|
final int lastX = mLastX;
|
||||||
final int lastY = mLastY;
|
final int lastY = mLastY;
|
||||||
final Key oldKey = mCurrentKey;
|
final Key oldKey = mCurrentKey;
|
||||||
Key key = onMoveKey(x, y);
|
Key key = onMoveKey(x, y);
|
||||||
|
|
||||||
|
if (sShouldHandleGesture) {
|
||||||
// Register move event on gesture tracker.
|
// Register move event on gesture tracker.
|
||||||
onGestureMoveEvent(this, x, y, eventTime, false /* isHistorical */, key);
|
onGestureMoveEvent(x, y, eventTime, false /* isHistorical */, key);
|
||||||
if (mInGesture) {
|
if (sInGesture) {
|
||||||
mIgnoreModifierKey = true;
|
mIgnoreModifierKey = true;
|
||||||
mTimerProxy.cancelLongPressTimer();
|
mTimerProxy.cancelLongPressTimer();
|
||||||
mIsInSlidingKeyInput = true;
|
mIsInSlidingKeyInput = true;
|
||||||
mCurrentKey = null;
|
mCurrentKey = null;
|
||||||
setReleasedKeyGraphics(oldKey);
|
setReleasedKeyGraphics(oldKey);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key != null) {
|
if (key != null) {
|
||||||
|
@ -825,7 +816,7 @@ public class PointerTracker implements PointerTrackerQueue.Element {
|
||||||
// TODO: Should find a way to balance gesture detection and this hack.
|
// TODO: Should find a way to balance gesture detection and this hack.
|
||||||
if (sNeedsPhantomSuddenMoveEventHack
|
if (sNeedsPhantomSuddenMoveEventHack
|
||||||
&& lastMoveSquared >= mKeyQuarterWidthSquared
|
&& lastMoveSquared >= mKeyQuarterWidthSquared
|
||||||
&& !mIsPossibleGesture) {
|
&& !mIsDetectingGesture) {
|
||||||
if (DEBUG_MODE) {
|
if (DEBUG_MODE) {
|
||||||
Log.w(TAG, String.format("onMoveEvent:"
|
Log.w(TAG, String.format("onMoveEvent:"
|
||||||
+ " phantom sudden move event is translated to "
|
+ " phantom sudden move event is translated to "
|
||||||
|
@ -843,12 +834,11 @@ public class PointerTracker implements PointerTrackerQueue.Element {
|
||||||
// touch panels when there are close multiple touches.
|
// touch panels when there are close multiple touches.
|
||||||
// Caveat: When in chording input mode with a modifier key, we don't use
|
// Caveat: When in chording input mode with a modifier key, we don't use
|
||||||
// this hack.
|
// this hack.
|
||||||
final PointerTrackerQueue queue = sPointerTrackerQueue;
|
if (getActivePointerTrackerCount() > 1 && sPointerTrackerQueue != null
|
||||||
if (queue != null && queue.size() > 1
|
&& !sPointerTrackerQueue.hasModifierKeyOlderThan(this)) {
|
||||||
&& !queue.hasModifierKeyOlderThan(this)) {
|
|
||||||
onUpEventInternal();
|
onUpEventInternal();
|
||||||
}
|
}
|
||||||
if (!mIsPossibleGesture) {
|
if (!mIsDetectingGesture) {
|
||||||
mKeyAlreadyProcessed = true;
|
mKeyAlreadyProcessed = true;
|
||||||
}
|
}
|
||||||
setReleasedKeyGraphics(oldKey);
|
setReleasedKeyGraphics(oldKey);
|
||||||
|
@ -866,7 +856,7 @@ public class PointerTracker implements PointerTrackerQueue.Element {
|
||||||
if (mIsAllowedSlidingKeyInput) {
|
if (mIsAllowedSlidingKeyInput) {
|
||||||
onMoveToNewKey(key, x, y);
|
onMoveToNewKey(key, x, y);
|
||||||
} else {
|
} else {
|
||||||
if (!mIsPossibleGesture) {
|
if (!mIsDetectingGesture) {
|
||||||
mKeyAlreadyProcessed = true;
|
mKeyAlreadyProcessed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -881,7 +871,7 @@ public class PointerTracker implements PointerTrackerQueue.Element {
|
||||||
|
|
||||||
final PointerTrackerQueue queue = sPointerTrackerQueue;
|
final PointerTrackerQueue queue = sPointerTrackerQueue;
|
||||||
if (queue != null) {
|
if (queue != null) {
|
||||||
if (!mInGesture) {
|
if (!sInGesture) {
|
||||||
if (mCurrentKey != null && mCurrentKey.isModifier()) {
|
if (mCurrentKey != null && mCurrentKey.isModifier()) {
|
||||||
// Before processing an up event of modifier key, all pointers already being
|
// Before processing an up event of modifier key, all pointers already being
|
||||||
// tracked should be released.
|
// tracked should be released.
|
||||||
|
@ -890,9 +880,11 @@ public class PointerTracker implements PointerTrackerQueue.Element {
|
||||||
queue.releaseAllPointersOlderThan(this, eventTime);
|
queue.releaseAllPointersOlderThan(this, eventTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
queue.remove(this);
|
|
||||||
}
|
}
|
||||||
onUpEventInternal();
|
onUpEventInternal();
|
||||||
|
if (queue != null) {
|
||||||
|
queue.remove(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Let this pointer tracker know that one of newer-than-this pointer trackers got an up event.
|
// Let this pointer tracker know that one of newer-than-this pointer trackers got an up event.
|
||||||
|
@ -910,34 +902,31 @@ public class PointerTracker implements PointerTrackerQueue.Element {
|
||||||
private void onUpEventInternal() {
|
private void onUpEventInternal() {
|
||||||
mTimerProxy.cancelKeyTimers();
|
mTimerProxy.cancelKeyTimers();
|
||||||
mIsInSlidingKeyInput = false;
|
mIsInSlidingKeyInput = false;
|
||||||
mIsPossibleGesture = false;
|
mIsDetectingGesture = false;
|
||||||
|
final Key currentKey = mCurrentKey;
|
||||||
|
mCurrentKey = null;
|
||||||
// Release the last pressed key.
|
// Release the last pressed key.
|
||||||
setReleasedKeyGraphics(mCurrentKey);
|
setReleasedKeyGraphics(currentKey);
|
||||||
if (mIsShowingMoreKeysPanel) {
|
if (mIsShowingMoreKeysPanel) {
|
||||||
mDrawingProxy.dismissMoreKeysPanel();
|
mDrawingProxy.dismissMoreKeysPanel();
|
||||||
mIsShowingMoreKeysPanel = false;
|
mIsShowingMoreKeysPanel = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mInGesture) {
|
if (sInGesture) {
|
||||||
// Register up event on gesture tracker.
|
if (currentKey != null) {
|
||||||
// TODO: Figure out how to deal with multiple fingers that are in gesture, sliding,
|
callListenerOnRelease(currentKey, currentKey.mCode, true);
|
||||||
// and/or tapping mode?
|
|
||||||
endBatchInput(getAllBatchPoints());
|
|
||||||
if (mCurrentKey != null) {
|
|
||||||
callListenerOnRelease(mCurrentKey, mCurrentKey.mCode, true);
|
|
||||||
mCurrentKey = null;
|
|
||||||
}
|
}
|
||||||
mDrawingProxy.showGestureTrail(this);
|
endBatchInput();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// This event will be recognized as a regular code input. Clear unused batch points so they
|
// This event will be recognized as a regular code input. Clear unused possible batch points
|
||||||
// are not mistakenly included in the next batch event.
|
// so they are not mistakenly displayed as preview.
|
||||||
clearBatchInputPointsOfAllPointerTrackers();
|
clearBatchInputPointsOfAllPointerTrackers();
|
||||||
if (mKeyAlreadyProcessed) {
|
if (mKeyAlreadyProcessed) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (mCurrentKey != null && !mCurrentKey.isRepeatable()) {
|
if (currentKey != null && !currentKey.isRepeatable()) {
|
||||||
detectAndSendKey(mCurrentKey, mKeyX, mKeyY);
|
detectAndSendKey(currentKey, mKeyX, mKeyY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -981,7 +970,7 @@ public class PointerTracker implements PointerTrackerQueue.Element {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startRepeatKey(final Key key) {
|
private void startRepeatKey(final Key key) {
|
||||||
if (key != null && key.isRepeatable() && !mInGesture) {
|
if (key != null && key.isRepeatable() && !sInGesture) {
|
||||||
onRegisterKey(key);
|
onRegisterKey(key);
|
||||||
mTimerProxy.startKeyRepeatTimer(this);
|
mTimerProxy.startKeyRepeatTimer(this);
|
||||||
}
|
}
|
||||||
|
@ -1010,7 +999,7 @@ public class PointerTracker implements PointerTrackerQueue.Element {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startLongPressTimer(final Key key) {
|
private void startLongPressTimer(final Key key) {
|
||||||
if (key != null && key.isLongPressEnabled() && !mInGesture) {
|
if (key != null && key.isLongPressEnabled() && !sInGesture) {
|
||||||
mTimerProxy.startLongPressTimer(this);
|
mTimerProxy.startLongPressTimer(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -130,8 +130,12 @@ public class GestureStroke {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void appendBatchPoints(final InputPointers out, final int size) {
|
private void appendBatchPoints(final InputPointers out, final int size) {
|
||||||
|
final int length = size - mLastIncrementalBatchSize;
|
||||||
|
if (length <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
out.append(mPointerId, mEventTimes, mXCoordinates, mYCoordinates,
|
out.append(mPointerId, mEventTimes, mXCoordinates, mYCoordinates,
|
||||||
mLastIncrementalBatchSize, size - mLastIncrementalBatchSize);
|
mLastIncrementalBatchSize, length);
|
||||||
mLastIncrementalBatchSize = size;
|
mLastIncrementalBatchSize = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue