Rename gesture related classes

Change-Id: I5cb03576bb7221f1864e157857d872880a0a58f8
This commit is contained in:
Tadashi G. Takaoka 2013-12-24 18:31:49 +09:00
parent afca1ddd23
commit e2a6253cb5
8 changed files with 228 additions and 155 deletions

View file

@ -24,10 +24,10 @@ import android.view.MotionEvent;
import com.android.inputmethod.keyboard.internal.BogusMoveEventDetector;
import com.android.inputmethod.keyboard.internal.GestureEnabler;
import com.android.inputmethod.keyboard.internal.GestureStroke;
import com.android.inputmethod.keyboard.internal.GestureStrokeParams;
import com.android.inputmethod.keyboard.internal.GestureStrokePreviewParams;
import com.android.inputmethod.keyboard.internal.GestureStrokeWithPreviewPoints;
import com.android.inputmethod.keyboard.internal.GestureStrokeDrawingParams;
import com.android.inputmethod.keyboard.internal.GestureStrokeDrawingPoints;
import com.android.inputmethod.keyboard.internal.GestureStrokeRecognitionParams;
import com.android.inputmethod.keyboard.internal.GestureStrokeRecognitionPoints;
import com.android.inputmethod.keyboard.internal.PointerTrackerQueue;
import com.android.inputmethod.keyboard.internal.TypingTimeRecorder;
import com.android.inputmethod.latin.Constants;
@ -135,8 +135,8 @@ 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 GestureStrokeRecognitionParams sGestureStrokeRecognitionParams;
private static GestureStrokeDrawingParams sGestureStrokeDrawingParams;
private static boolean sNeedsPhantomSuddenMoveEventHack;
// Move this threshold to resource.
// TODO: Device specific parameter would be better for device specific hack?
@ -163,7 +163,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
private static long sGestureFirstDownTime;
private static TypingTimeRecorder sTypingTimeRecorder;
private static final InputPointers sAggregatedPointers = new InputPointers(
GestureStroke.DEFAULT_CAPACITY);
GestureStrokeRecognitionPoints.DEFAULT_CAPACITY);
private static int sLastRecognitionPointSize = 0; // synchronized using sAggregatedPointers
private static long sLastRecognitionTime = 0; // synchronized using sAggregatedPointers
@ -203,16 +203,16 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
// true if dragging finger is allowed.
private boolean mIsAllowedDraggingFinger;
private final GestureStrokeWithPreviewPoints mGestureStrokeWithPreviewPoints;
private final GestureStrokeDrawingPoints mGestureStrokeDrawingPoints;
// TODO: Add PointerTrackerFactory singleton and move some class static methods into it.
public static void init(final TypedArray mainKeyboardViewAttr, final TimerProxy timerProxy,
final DrawingProxy drawingProxy) {
sParams = new PointerTrackerParams(mainKeyboardViewAttr);
sGestureStrokeParams = new GestureStrokeParams(mainKeyboardViewAttr);
sGesturePreviewParams = new GestureStrokePreviewParams(mainKeyboardViewAttr);
sGestureStrokeRecognitionParams = new GestureStrokeRecognitionParams(mainKeyboardViewAttr);
sGestureStrokeDrawingParams = new GestureStrokeDrawingParams(mainKeyboardViewAttr);
sTypingTimeRecorder = new TypingTimeRecorder(
sGestureStrokeParams.mStaticTimeThresholdAfterFastTyping,
sGestureStrokeRecognitionParams.mStaticTimeThresholdAfterFastTyping,
sParams.mSuppressKeyPreviewAfterBatchInputDuration);
final Resources res = mainKeyboardViewAttr.getResources();
@ -286,8 +286,8 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
private PointerTracker(final int id) {
mPointerId = id;
mGestureStrokeWithPreviewPoints = new GestureStrokeWithPreviewPoints(
id, sGestureStrokeParams, sGesturePreviewParams);
mGestureStrokeDrawingPoints = new GestureStrokeDrawingPoints(
id, sGestureStrokeRecognitionParams, sGestureStrokeDrawingParams);
}
// Returns true if keyboard has been changed by this callback.
@ -408,7 +408,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
mKeyboardLayoutHasBeenChanged = true;
final int keyWidth = mKeyboard.mMostCommonKeyWidth;
final int keyHeight = mKeyboard.mMostCommonKeyHeight;
mGestureStrokeWithPreviewPoints.setKeyboardGeometry(keyWidth, mKeyboard.mOccupiedHeight);
mGestureStrokeDrawingPoints.setKeyboardGeometry(keyWidth, mKeyboard.mOccupiedHeight);
final Key newKey = mKeyDetector.detectHitKey(mKeyX, mKeyY);
if (newKey != mCurrentKey) {
if (sDrawingProxy != null) {
@ -523,8 +523,8 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
sDrawingProxy.invalidateKey(key);
}
public GestureStrokeWithPreviewPoints getGestureStrokeWithPreviewPoints() {
return mGestureStrokeWithPreviewPoints;
public GestureStrokeDrawingPoints getGestureStrokeDrawingPoints() {
return mGestureStrokeDrawingPoints;
}
public void getLastCoordinates(final int[] outCoords) {
@ -581,7 +581,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
* @return true if the batch input has started successfully.
*/
private boolean mayStartBatchInput() {
if (!mGestureStrokeWithPreviewPoints.isStartOfAGesture()) {
if (!mGestureStrokeDrawingPoints.isStartOfAGesture()) {
return false;
}
if (DEBUG_LISTENER) {
@ -609,13 +609,13 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
public void updateBatchInputByTimer(final long syntheticMoveEventTime) {
final int gestureTime = (int)(syntheticMoveEventTime - sGestureFirstDownTime);
mGestureStrokeWithPreviewPoints.duplicateLastPointWith(gestureTime);
mGestureStrokeDrawingPoints.duplicateLastPointWith(gestureTime);
updateBatchInput(syntheticMoveEventTime);
}
private void updateBatchInput(final long moveEventTime) {
synchronized (sAggregatedPointers) {
final GestureStroke stroke = mGestureStrokeWithPreviewPoints;
final GestureStrokeRecognitionPoints stroke = mGestureStrokeDrawingPoints;
stroke.appendIncrementalBatchPoints(sAggregatedPointers);
final int size = sAggregatedPointers.getPointerSize();
if (size > sLastRecognitionPointSize
@ -642,7 +642,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
private boolean mayEndBatchInput(final long upEventTime) {
boolean hasEndBatchInputSuccessfully = false;
synchronized (sAggregatedPointers) {
mGestureStrokeWithPreviewPoints.appendAllBatchPoints(sAggregatedPointers);
mGestureStrokeDrawingPoints.appendAllBatchPoints(sAggregatedPointers);
if (getActivePointerTrackerCount() == 1) {
hasEndBatchInputSuccessfully = true;
sTypingTimeRecorder.onEndBatchInput(upEventTime);
@ -754,7 +754,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
if (getActivePointerTrackerCount() == 1) {
sGestureFirstDownTime = eventTime;
}
mGestureStrokeWithPreviewPoints.onDownEvent(x, y, eventTime, sGestureFirstDownTime,
mGestureStrokeDrawingPoints.onDownEvent(x, y, eventTime, sGestureFirstDownTime,
sTypingTimeRecorder.getLastLetterTypingTime());
}
}
@ -814,11 +814,11 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
if (!mIsDetectingGesture) {
return;
}
final int beforeLength = mGestureStrokeWithPreviewPoints.getLength();
final int beforeLength = mGestureStrokeDrawingPoints.getLength();
final int gestureTime = (int)(eventTime - sGestureFirstDownTime);
final boolean onValidArea = mGestureStrokeWithPreviewPoints.addPointOnKeyboard(
final boolean onValidArea = mGestureStrokeDrawingPoints.addPointOnKeyboard(
x, y, gestureTime, isMajorEvent);
if (mGestureStrokeWithPreviewPoints.getLength() > beforeLength) {
if (mGestureStrokeDrawingPoints.getLength() > beforeLength) {
sTimerProxy.startUpdateBatchInputTimer(this);
}
// If the move event goes out from valid batch input area, cancel batch input.

View file

@ -20,7 +20,15 @@ import android.content.res.TypedArray;
import com.android.inputmethod.latin.R;
public final class GestureStrokePreviewParams {
/**
* This class holds parameters to control how a gesture stroke is sampled and drawn on the screen.
*
* @attr ref R.styleable#MainKeyboardView_gestureTrailMinSamplingDistance
* @attr ref R.styleable#MainKeyboardView_gestureTrailMaxInterpolationAngularThreshold
* @attr ref R.styleable#MainKeyboardView_gestureTrailMaxInterpolationDistanceThreshold
* @attr ref R.styleable#MainKeyboardView_gestureTrailMaxInterpolationSegments
*/
public final class GestureStrokeDrawingParams {
public final double mMinSamplingDistance; // in pixel
public final double mMaxInterpolationAngularThreshold; // in radian
public final double mMaxInterpolationDistanceThreshold; // in pixel
@ -31,7 +39,7 @@ public final class GestureStrokePreviewParams {
private static final float DEFAULT_MAX_INTERPOLATION_DISTANCE_THRESHOLD = 0.0f; // dp
private static final int DEFAULT_MAX_INTERPOLATION_SEGMENTS = 4;
public GestureStrokePreviewParams(final TypedArray mainKeyboardViewAttr) {
public GestureStrokeDrawingParams(final TypedArray mainKeyboardViewAttr) {
mMinSamplingDistance = mainKeyboardViewAttr.getDimension(
R.styleable.MainKeyboardView_gestureTrailMinSamplingDistance,
DEFAULT_MIN_SAMPLING_DISTANCE);

View file

@ -18,14 +18,20 @@ package com.android.inputmethod.keyboard.internal;
import com.android.inputmethod.latin.utils.ResizableIntArray;
public final class GestureStrokeWithPreviewPoints extends GestureStroke {
/**
* This class holds drawing points to represent a gesture stroke on the screen.
* TODO: Currently this class extends {@link GestureStrokeRecognitionPoints} that holds recognition
* points of a gesture stroke. This class should be independent from
* {@link GestureStrokeRecognitionPoints}.
*/
public final class GestureStrokeDrawingPoints extends GestureStrokeRecognitionPoints {
public static final int PREVIEW_CAPACITY = 256;
private final ResizableIntArray mPreviewEventTimes = new ResizableIntArray(PREVIEW_CAPACITY);
private final ResizableIntArray mPreviewXCoordinates = new ResizableIntArray(PREVIEW_CAPACITY);
private final ResizableIntArray mPreviewYCoordinates = new ResizableIntArray(PREVIEW_CAPACITY);
private final GestureStrokePreviewParams mPreviewParams;
private final GestureStrokeDrawingParams mDrawingParams;
private int mStrokeId;
private int mLastPreviewSize;
@ -36,11 +42,11 @@ public final class GestureStrokeWithPreviewPoints extends GestureStroke {
private int mLastY;
private double mDistanceFromLastSample;
public GestureStrokeWithPreviewPoints(final int pointerId,
final GestureStrokeParams strokeParams,
final GestureStrokePreviewParams previewParams) {
super(pointerId, strokeParams);
mPreviewParams = previewParams;
public GestureStrokeDrawingPoints(final int pointerId,
final GestureStrokeRecognitionParams recognitionParams,
final GestureStrokeDrawingParams drawingParams) {
super(pointerId, recognitionParams);
mDrawingParams = drawingParams;
}
@Override
@ -63,7 +69,7 @@ public final class GestureStrokeWithPreviewPoints extends GestureStroke {
mLastX = x;
mLastY = y;
final boolean isDownEvent = (mPreviewEventTimes.getLength() == 0);
if (mDistanceFromLastSample >= mPreviewParams.mMinSamplingDistance || isDownEvent) {
if (mDistanceFromLastSample >= mDrawingParams.mMinSamplingDistance || isDownEvent) {
mDistanceFromLastSample = 0.0d;
return true;
}
@ -89,7 +95,7 @@ public final class GestureStrokeWithPreviewPoints extends GestureStroke {
* @param xCoords the x-coordinates array of gesture trail to be drawn.
* @param yCoords the y-coordinates array of gesture trail to be drawn.
* @param types the point types array of gesture trail. This is valid only when
* {@link GestureTrail#DEBUG_SHOW_POINTS} is true.
* {@link GestureTrailDrawingPoints#DEBUG_SHOW_POINTS} is true.
*/
public void appendPreviewStroke(final ResizableIntArray eventTimes,
final ResizableIntArray xCoords, final ResizableIntArray yCoords,
@ -101,8 +107,8 @@ public final class GestureStrokeWithPreviewPoints extends GestureStroke {
eventTimes.append(mPreviewEventTimes, mLastPreviewSize, length);
xCoords.append(mPreviewXCoordinates, mLastPreviewSize, length);
yCoords.append(mPreviewYCoordinates, mLastPreviewSize, length);
if (GestureTrail.DEBUG_SHOW_POINTS) {
types.fill(GestureTrail.POINT_TYPE_SAMPLED, types.getLength(), length);
if (GestureTrailDrawingPoints.DEBUG_SHOW_POINTS) {
types.fill(GestureTrailDrawingPoints.POINT_TYPE_SAMPLED, types.getLength(), length);
}
mLastPreviewSize = mPreviewEventTimes.getLength();
}
@ -119,7 +125,7 @@ public final class GestureStrokeWithPreviewPoints extends GestureStroke {
* @param xCoords the x-coordinates array of gesture trail to be drawn.
* @param yCoords the y-coordinates array of gesture trail to be drawn.
* @param types the point types array of gesture trail. This is valid only when
* {@link GestureTrail#DEBUG_SHOW_POINTS} is true.
* {@link GestureTrailDrawingPoints#DEBUG_SHOW_POINTS} is true.
* @return the start index of the last interpolated segment of input arrays.
*/
public int interpolateStrokeAndReturnStartIndexOfLastSegment(final int lastInterpolatedIndex,
@ -145,12 +151,12 @@ public final class GestureStrokeWithPreviewPoints extends GestureStroke {
final double m2 = Math.atan2(mInterpolator.mSlope2Y, mInterpolator.mSlope2X);
final double deltaAngle = Math.abs(angularDiff(m2, m1));
final int segmentsByAngle = (int)Math.ceil(
deltaAngle / mPreviewParams.mMaxInterpolationAngularThreshold);
deltaAngle / mDrawingParams.mMaxInterpolationAngularThreshold);
final double deltaDistance = Math.hypot(mInterpolator.mP1X - mInterpolator.mP2X,
mInterpolator.mP1Y - mInterpolator.mP2Y);
final int segmentsByDistance = (int)Math.ceil(deltaDistance
/ mPreviewParams.mMaxInterpolationDistanceThreshold);
final int segments = Math.min(mPreviewParams.mMaxInterpolationSegments,
/ mDrawingParams.mMaxInterpolationDistanceThreshold);
final int segments = Math.min(mDrawingParams.mMaxInterpolationSegments,
Math.max(segmentsByAngle, segmentsByDistance));
final int t1 = eventTimes.get(d1);
final int dt = pt[p2] - pt[p1];
@ -161,16 +167,16 @@ public final class GestureStrokeWithPreviewPoints extends GestureStroke {
eventTimes.add(d1, (int)(dt * t) + t1);
xCoords.add(d1, (int)mInterpolator.mInterpolatedX);
yCoords.add(d1, (int)mInterpolator.mInterpolatedY);
if (GestureTrail.DEBUG_SHOW_POINTS) {
types.add(d1, GestureTrail.POINT_TYPE_INTERPOLATED);
if (GestureTrailDrawingPoints.DEBUG_SHOW_POINTS) {
types.add(d1, GestureTrailDrawingPoints.POINT_TYPE_INTERPOLATED);
}
d1++;
}
eventTimes.add(d1, pt[p2]);
xCoords.add(d1, px[p2]);
yCoords.add(d1, py[p2]);
if (GestureTrail.DEBUG_SHOW_POINTS) {
types.add(d1, GestureTrail.POINT_TYPE_SAMPLED);
if (GestureTrailDrawingPoints.DEBUG_SHOW_POINTS) {
types.add(d1, GestureTrailDrawingPoints.POINT_TYPE_SAMPLED);
}
}
return lastInterpolatedDrawIndex;

View file

@ -21,7 +21,22 @@ import android.content.res.TypedArray;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.utils.ResourceUtils;
public final class GestureStrokeParams {
/**
* This class holds parameters to control how a gesture stroke is sampled and recognized.
* This class also has parameters to distinguish gesture input events from fast typing events.
*
* @attr ref R.styleable#MainKeyboardView_gestureStaticTimeThresholdAfterFastTyping
* @attr ref R.styleable#MainKeyboardView_gestureDetectFastMoveSpeedThreshold
* @attr ref R.styleable#MainKeyboardView_gestureDynamicThresholdDecayDuration
* @attr ref R.styleable#MainKeyboardView_gestureDynamicTimeThresholdFrom
* @attr ref R.styleable#MainKeyboardView_gestureDynamicTimeThresholdTo
* @attr ref R.styleable#MainKeyboardView_gestureDynamicDistanceThresholdFrom
* @attr ref R.styleable#MainKeyboardView_gestureDynamicDistanceThresholdTo
* @attr ref R.styleable#MainKeyboardView_gestureSamplingMinimumDistance
* @attr ref R.styleable#MainKeyboardView_gestureRecognitionMinimumTime
* @attr ref R.styleable#MainKeyboardView_gestureRecognitionSpeedThreshold
*/
public final class GestureStrokeRecognitionParams {
// Static threshold for gesture after fast typing
public final int mStaticTimeThresholdAfterFastTyping; // msec
// Static threshold for starting gesture detection
@ -40,10 +55,11 @@ public final class GestureStrokeParams {
public final int mRecognitionMinimumTime; // msec
public final float mRecognitionSpeedThreshold; // keyWidth/sec
// Default GestureStroke parameters.
public static final GestureStrokeParams DEFAULT = new GestureStrokeParams();
// Default GestureStrokeRecognitionPoints parameters.
public static final GestureStrokeRecognitionParams DEFAULT =
new GestureStrokeRecognitionParams();
private GestureStrokeParams() {
private GestureStrokeRecognitionParams() {
// These parameter values are default and intended for testing.
mStaticTimeThresholdAfterFastTyping = 350; // msec
mDetectFastMoveSpeedThreshold = 1.5f; // keyWidth/sec
@ -58,7 +74,7 @@ public final class GestureStrokeParams {
mRecognitionSpeedThreshold = 5.5f; // keyWidth/sec
}
public GestureStrokeParams(final TypedArray mainKeyboardViewAttr) {
public GestureStrokeRecognitionParams(final TypedArray mainKeyboardViewAttr) {
mStaticTimeThresholdAfterFastTyping = mainKeyboardViewAttr.getInt(
R.styleable.MainKeyboardView_gestureStaticTimeThresholdAfterFastTyping,
DEFAULT.mStaticTimeThresholdAfterFastTyping);

View file

@ -21,8 +21,12 @@ import android.util.Log;
import com.android.inputmethod.latin.InputPointers;
import com.android.inputmethod.latin.utils.ResizableIntArray;
public class GestureStroke {
private static final String TAG = GestureStroke.class.getSimpleName();
/**
* This class holds event points to recognize a gesture stroke.
* TODO: Should be final and package private class.
*/
public class GestureStrokeRecognitionPoints {
private static final String TAG = GestureStrokeRecognitionPoints.class.getSimpleName();
private static final boolean DEBUG = false;
private static final boolean DEBUG_SPEED = false;
@ -37,7 +41,7 @@ public class GestureStroke {
private final ResizableIntArray mXCoordinates = new ResizableIntArray(DEFAULT_CAPACITY);
private final ResizableIntArray mYCoordinates = new ResizableIntArray(DEFAULT_CAPACITY);
private final GestureStrokeParams mParams;
private final GestureStrokeRecognitionParams mRecognitionParams;
private int mKeyWidth; // pixel
private int mMinYCoordinate; // pixel
@ -63,9 +67,10 @@ public class GestureStroke {
private static final int MSEC_PER_SEC = 1000;
public GestureStroke(final int pointerId, final GestureStrokeParams params) {
public GestureStrokeRecognitionPoints(final int pointerId,
final GestureStrokeRecognitionParams recognitionParams) {
mPointerId = pointerId;
mParams = params;
mRecognitionParams = recognitionParams;
}
public void setKeyboardGeometry(final int keyWidth, final int keyboardHeight) {
@ -73,18 +78,22 @@ public class GestureStroke {
mMinYCoordinate = -(int)(keyboardHeight * EXTRA_GESTURE_TRAIL_AREA_ABOVE_KEYBOARD_RATIO);
mMaxYCoordinate = keyboardHeight;
// TODO: Find an appropriate base metric for these length. Maybe diagonal length of the key?
mDetectFastMoveSpeedThreshold = (int)(keyWidth * mParams.mDetectFastMoveSpeedThreshold);
mGestureDynamicDistanceThresholdFrom =
(int)(keyWidth * mParams.mDynamicDistanceThresholdFrom);
mGestureDynamicDistanceThresholdTo = (int)(keyWidth * mParams.mDynamicDistanceThresholdTo);
mGestureSamplingMinimumDistance = (int)(keyWidth * mParams.mSamplingMinimumDistance);
mGestureRecognitionSpeedThreshold = (int)(keyWidth * mParams.mRecognitionSpeedThreshold);
mDetectFastMoveSpeedThreshold = (int)(
keyWidth * mRecognitionParams.mDetectFastMoveSpeedThreshold);
mGestureDynamicDistanceThresholdFrom = (int)(
keyWidth * mRecognitionParams.mDynamicDistanceThresholdFrom);
mGestureDynamicDistanceThresholdTo = (int)(
keyWidth * mRecognitionParams.mDynamicDistanceThresholdTo);
mGestureSamplingMinimumDistance = (int)(
keyWidth * mRecognitionParams.mSamplingMinimumDistance);
mGestureRecognitionSpeedThreshold = (int)(
keyWidth * mRecognitionParams.mRecognitionSpeedThreshold);
if (DEBUG) {
Log.d(TAG, String.format(
"[%d] setKeyboardGeometry: keyWidth=%3d tT=%3d >> %3d tD=%3d >> %3d",
mPointerId, keyWidth,
mParams.mDynamicTimeThresholdFrom,
mParams.mDynamicTimeThresholdTo,
mRecognitionParams.mDynamicTimeThresholdFrom,
mRecognitionParams.mDynamicTimeThresholdTo,
mGestureDynamicDistanceThresholdFrom,
mGestureDynamicDistanceThresholdTo));
}
@ -98,7 +107,7 @@ public class GestureStroke {
final long gestureFirstDownTime, final long lastTypingTime) {
reset();
final long elapsedTimeAfterTyping = downTime - lastTypingTime;
if (elapsedTimeAfterTyping < mParams.mStaticTimeThresholdAfterFastTyping) {
if (elapsedTimeAfterTyping < mRecognitionParams.mStaticTimeThresholdAfterFastTyping) {
mAfterFastTyping = true;
}
if (DEBUG) {
@ -110,23 +119,24 @@ public class GestureStroke {
}
private int getGestureDynamicDistanceThreshold(final int deltaTime) {
if (!mAfterFastTyping || deltaTime >= mParams.mDynamicThresholdDecayDuration) {
if (!mAfterFastTyping || deltaTime >= mRecognitionParams.mDynamicThresholdDecayDuration) {
return mGestureDynamicDistanceThresholdTo;
}
final int decayedThreshold =
(mGestureDynamicDistanceThresholdFrom - mGestureDynamicDistanceThresholdTo)
* deltaTime / mParams.mDynamicThresholdDecayDuration;
* deltaTime / mRecognitionParams.mDynamicThresholdDecayDuration;
return mGestureDynamicDistanceThresholdFrom - decayedThreshold;
}
private int getGestureDynamicTimeThreshold(final int deltaTime) {
if (!mAfterFastTyping || deltaTime >= mParams.mDynamicThresholdDecayDuration) {
return mParams.mDynamicTimeThresholdTo;
if (!mAfterFastTyping || deltaTime >= mRecognitionParams.mDynamicThresholdDecayDuration) {
return mRecognitionParams.mDynamicTimeThresholdTo;
}
final int decayedThreshold =
(mParams.mDynamicTimeThresholdFrom - mParams.mDynamicTimeThresholdTo)
* deltaTime / mParams.mDynamicThresholdDecayDuration;
return mParams.mDynamicTimeThresholdFrom - decayedThreshold;
(mRecognitionParams.mDynamicTimeThresholdFrom
- mRecognitionParams.mDynamicTimeThresholdTo)
* deltaTime / mRecognitionParams.mDynamicThresholdDecayDuration;
return mRecognitionParams.mDynamicTimeThresholdFrom - decayedThreshold;
}
public final boolean isStartOfAGesture() {
@ -285,7 +295,7 @@ public class GestureStroke {
public final boolean hasRecognitionTimePast(
final long currentTime, final long lastRecognitionTime) {
return currentTime > lastRecognitionTime + mParams.mRecognitionMinimumTime;
return currentTime > lastRecognitionTime + mRecognitionParams.mRecognitionMinimumTime;
}
public final void appendAllBatchPoints(final InputPointers out) {
@ -307,10 +317,6 @@ public class GestureStroke {
}
private static int getDistance(final int x1, final int y1, final int x2, final int y2) {
final int dx = x1 - x2;
final int dy = y1 - y2;
// Note that, in recent versions of Android, FloatMath is actually slower than
// java.lang.Math due to the way the JIT optimizes java.lang.Math.
return (int)Math.sqrt(dx * dx + dy * dy);
return (int)Math.hypot(x1 - x2, y1 - y2);
}
}

View file

@ -0,0 +1,79 @@
/*
* Copyright (C) 2013 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.content.res.TypedArray;
import com.android.inputmethod.latin.R;
/**
* This class holds parameters to control how a gesture trail is drawn and animated on the screen.
*
* On the other hand, {@link GestureStrokeDrawingParams} class controls how each gesture stroke is
* sampled and interpolated. This class controls how those gesture strokes are displayed as a
* gesture trail and animated on the screen.
*
* @attr ref R.styleable#MainKeyboardView_gestureTrailFadeoutStartDelay
* @attr ref R.styleable#MainKeyboardView_gestureTrailFadeoutDuration
* @attr ref R.styleable#MainKeyboardView_gestureTrailUpdateInterval
* @attr ref R.styleable#MainKeyboardView_gestureTrailColor
* @attr ref R.styleable#MainKeyboardView_gestureTrailWidth
*/
final class GestureTrailDrawingParams {
private static final int FADEOUT_START_DELAY_FOR_DEBUG = 2000; // millisecond
private static final int FADEOUT_DURATION_FOR_DEBUG = 200; // millisecond
public final int mTrailColor;
public final float mTrailStartWidth;
public final float mTrailEndWidth;
public final float mTrailBodyRatio;
public boolean mTrailShadowEnabled;
public final float mTrailShadowRatio;
public final int mFadeoutStartDelay;
public final int mFadeoutDuration;
public final int mUpdateInterval;
public final int mTrailLingerDuration;
public GestureTrailDrawingParams(final TypedArray mainKeyboardViewAttr) {
mTrailColor = mainKeyboardViewAttr.getColor(
R.styleable.MainKeyboardView_gestureTrailColor, 0);
mTrailStartWidth = mainKeyboardViewAttr.getDimension(
R.styleable.MainKeyboardView_gestureTrailStartWidth, 0.0f);
mTrailEndWidth = mainKeyboardViewAttr.getDimension(
R.styleable.MainKeyboardView_gestureTrailEndWidth, 0.0f);
final int PERCENTAGE_INT = 100;
mTrailBodyRatio = (float)mainKeyboardViewAttr.getInt(
R.styleable.MainKeyboardView_gestureTrailBodyRatio, PERCENTAGE_INT)
/ (float)PERCENTAGE_INT;
final int trailShadowRatioInt = mainKeyboardViewAttr.getInt(
R.styleable.MainKeyboardView_gestureTrailShadowRatio, 0);
mTrailShadowEnabled = (trailShadowRatioInt > 0);
mTrailShadowRatio = (float)trailShadowRatioInt / (float)PERCENTAGE_INT;
mFadeoutStartDelay = GestureTrailDrawingPoints.DEBUG_SHOW_POINTS
? FADEOUT_START_DELAY_FOR_DEBUG
: mainKeyboardViewAttr.getInt(
R.styleable.MainKeyboardView_gestureTrailFadeoutStartDelay, 0);
mFadeoutDuration = GestureTrailDrawingPoints.DEBUG_SHOW_POINTS
? FADEOUT_DURATION_FOR_DEBUG
: mainKeyboardViewAttr.getInt(
R.styleable.MainKeyboardView_gestureTrailFadeoutDuration, 0);
mTrailLingerDuration = mFadeoutStartDelay + mFadeoutDuration;
mUpdateInterval = mainKeyboardViewAttr.getInt(
R.styleable.MainKeyboardView_gestureTrailUpdateInterval, 0);
}
}

View file

@ -16,7 +16,6 @@
package com.android.inputmethod.keyboard.internal;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
@ -25,24 +24,22 @@ import android.graphics.Rect;
import android.os.SystemClock;
import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.utils.ResizableIntArray;
/*
* @attr ref R.styleable#MainKeyboardView_gestureTrailFadeoutStartDelay
* @attr ref R.styleable#MainKeyboardView_gestureTrailFadeoutDuration
* @attr ref R.styleable#MainKeyboardView_gestureTrailUpdateInterval
* @attr ref R.styleable#MainKeyboardView_gestureTrailColor
* @attr ref R.styleable#MainKeyboardView_gestureTrailWidth
/**
* This class holds drawing points to represent a gesture trail. The gesture trail may contain
* multiple non-contiguous gesture strokes and will be animated asynchronously from gesture input.
*
* On the other hand, {@link GestureStrokeDrawingPoints} class holds drawing points of each gesture
* stroke. This class holds drawing points of those gesture strokes to draw as a gesture trail.
* Drawing points in this class will be asynchronously removed when fading out animation goes.
*/
final class GestureTrail {
final class GestureTrailDrawingPoints {
public static final boolean DEBUG_SHOW_POINTS = false;
public static final int POINT_TYPE_SAMPLED = 1;
public static final int POINT_TYPE_INTERPOLATED = 2;
private static final int FADEOUT_START_DELAY_FOR_DEBUG = 2000; // millisecond
private static final int FADEOUT_DURATION_FOR_DEBUG = 200; // millisecond
private static final int DEFAULT_CAPACITY = GestureStrokeWithPreviewPoints.PREVIEW_CAPACITY;
private static final int DEFAULT_CAPACITY = GestureStrokeDrawingPoints.PREVIEW_CAPACITY;
// These three {@link ResizableIntArray}s should be synchronized by {@link #mEventTimes}.
private final ResizableIntArray mXCoordinates = new ResizableIntArray(DEFAULT_CAPACITY);
@ -56,46 +53,6 @@ final class GestureTrail {
private int mTrailStartIndex;
private int mLastInterpolatedDrawIndex;
static final class Params {
public final int mTrailColor;
public final float mTrailStartWidth;
public final float mTrailEndWidth;
public final float mTrailBodyRatio;
public boolean mTrailShadowEnabled;
public final float mTrailShadowRatio;
public final int mFadeoutStartDelay;
public final int mFadeoutDuration;
public final int mUpdateInterval;
public final int mTrailLingerDuration;
public Params(final TypedArray mainKeyboardViewAttr) {
mTrailColor = mainKeyboardViewAttr.getColor(
R.styleable.MainKeyboardView_gestureTrailColor, 0);
mTrailStartWidth = mainKeyboardViewAttr.getDimension(
R.styleable.MainKeyboardView_gestureTrailStartWidth, 0.0f);
mTrailEndWidth = mainKeyboardViewAttr.getDimension(
R.styleable.MainKeyboardView_gestureTrailEndWidth, 0.0f);
final int PERCENTAGE_INT = 100;
mTrailBodyRatio = (float)mainKeyboardViewAttr.getInt(
R.styleable.MainKeyboardView_gestureTrailBodyRatio, PERCENTAGE_INT)
/ (float)PERCENTAGE_INT;
final int trailShadowRatioInt = mainKeyboardViewAttr.getInt(
R.styleable.MainKeyboardView_gestureTrailShadowRatio, 0);
mTrailShadowEnabled = (trailShadowRatioInt > 0);
mTrailShadowRatio = (float)trailShadowRatioInt / (float)PERCENTAGE_INT;
mFadeoutStartDelay = DEBUG_SHOW_POINTS ? FADEOUT_START_DELAY_FOR_DEBUG
: mainKeyboardViewAttr.getInt(
R.styleable.MainKeyboardView_gestureTrailFadeoutStartDelay, 0);
mFadeoutDuration = DEBUG_SHOW_POINTS ? FADEOUT_DURATION_FOR_DEBUG
: mainKeyboardViewAttr.getInt(
R.styleable.MainKeyboardView_gestureTrailFadeoutDuration, 0);
mTrailLingerDuration = mFadeoutStartDelay + mFadeoutDuration;
mUpdateInterval = mainKeyboardViewAttr.getInt(
R.styleable.MainKeyboardView_gestureTrailUpdateInterval, 0);
}
}
// Use this value as imaginary zero because x-coordinates may be zero.
private static final int DOWN_EVENT_MARKER = -128;
@ -112,13 +69,13 @@ final class GestureTrail {
? DOWN_EVENT_MARKER - xCoordOrMark : xCoordOrMark;
}
public void addStroke(final GestureStrokeWithPreviewPoints stroke, final long downTime) {
public void addStroke(final GestureStrokeDrawingPoints stroke, final long downTime) {
synchronized (mEventTimes) {
addStrokeLocked(stroke, downTime);
}
}
private void addStrokeLocked(final GestureStrokeWithPreviewPoints stroke, final long downTime) {
private void addStrokeLocked(final GestureStrokeDrawingPoints stroke, final long downTime) {
final int trailSize = mEventTimes.getLength();
stroke.appendPreviewStroke(mEventTimes, mXCoordinates, mYCoordinates, mPointTypes);
if (mEventTimes.getLength() == trailSize) {
@ -126,13 +83,14 @@ final class GestureTrail {
}
final int[] eventTimes = mEventTimes.getPrimitiveArray();
final int strokeId = stroke.getGestureStrokeId();
// Because interpolation algorithm in {@link GestureStrokeWithPreviewPoints} can't determine
// Because interpolation algorithm in {@link GestureStrokeDrawingPoints} can't determine
// the interpolated points in the last segment of gesture stroke, it may need recalculation
// of interpolation when new segments are added to the stroke.
// {@link #mLastInterpolatedDrawIndex} holds the start index of the last segment. It may
// be updated by the interpolation
// {@link GestureStrokeWithPreviewPoints#interpolatePreviewStroke}
// or by animation {@link #drawGestureTrail(Canvas,Paint,Rect,Params)} below.
// {@link GestureStrokeDrawingPoints#interpolatePreviewStroke}
// or by animation {@link #drawGestureTrail(Canvas,Paint,Rect,GestureTrailDrawingParams)}
// below.
final int lastInterpolatedIndex = (strokeId == mCurrentStrokeId)
? mLastInterpolatedDrawIndex : trailSize;
mLastInterpolatedDrawIndex = stroke.interpolateStrokeAndReturnStartIndexOfLastSegment(
@ -161,7 +119,7 @@ final class GestureTrail {
* @param params gesture trail display parameters
* @return the width of a gesture trail
*/
private static int getAlpha(final int elapsedTime, final Params params) {
private static int getAlpha(final int elapsedTime, final GestureTrailDrawingParams params) {
if (elapsedTime < params.mFadeoutStartDelay) {
return Constants.Color.ALPHA_OPAQUE;
}
@ -180,7 +138,7 @@ final class GestureTrail {
* @param params gesture trail display parameters
* @return the width of a gesture trail
*/
private static float getWidth(final int elapsedTime, final Params params) {
private static float getWidth(final int elapsedTime, final GestureTrailDrawingParams params) {
final float deltaWidth = params.mTrailStartWidth - params.mTrailEndWidth;
return params.mTrailStartWidth - (deltaWidth * elapsedTime) / params.mTrailLingerDuration;
}
@ -197,14 +155,14 @@ final class GestureTrail {
* @return true if some gesture trails remain to be drawn
*/
public boolean drawGestureTrail(final Canvas canvas, final Paint paint,
final Rect outBoundsRect, final Params params) {
final Rect outBoundsRect, final GestureTrailDrawingParams params) {
synchronized (mEventTimes) {
return drawGestureTrailLocked(canvas, paint, outBoundsRect, params);
}
}
private boolean drawGestureTrailLocked(final Canvas canvas, final Paint paint,
final Rect outBoundsRect, final Params params) {
final Rect outBoundsRect, final GestureTrailDrawingParams params) {
// Initialize bounds rectangle.
outBoundsRect.setEmpty();
final int trailSize = mEventTimes.getLength();

View file

@ -29,16 +29,16 @@ import android.util.SparseArray;
import android.view.View;
import com.android.inputmethod.keyboard.PointerTracker;
import com.android.inputmethod.keyboard.internal.GestureTrail.Params;
import com.android.inputmethod.latin.utils.CollectionUtils;
import com.android.inputmethod.latin.utils.LeakGuardHandlerWrapper;
/**
* Draw gesture trail preview graphics during gesture.
* Draw preview graphics of multiple gesture trails during gesture input.
*/
public final class GestureTrailsDrawingPreview extends AbstractDrawingPreview {
private final SparseArray<GestureTrail> mGestureTrails = CollectionUtils.newSparseArray();
private final Params mGestureTrailParams;
private final SparseArray<GestureTrailDrawingPoints> mGestureTrails =
CollectionUtils.newSparseArray();
private final GestureTrailDrawingParams mDrawingParams;
private final Paint mGesturePaint;
private int mOffscreenWidth;
private int mOffscreenHeight;
@ -55,12 +55,12 @@ public final class GestureTrailsDrawingPreview extends AbstractDrawingPreview {
extends LeakGuardHandlerWrapper<GestureTrailsDrawingPreview> {
private static final int MSG_UPDATE_GESTURE_TRAIL = 0;
private final Params mGestureTrailParams;
private final GestureTrailDrawingParams mDrawingParams;
public DrawingHandler(final GestureTrailsDrawingPreview ownerInstance,
final Params gestureTrailParams) {
final GestureTrailDrawingParams drawingParams) {
super(ownerInstance);
mGestureTrailParams = gestureTrailParams;
mDrawingParams = drawingParams;
}
@Override
@ -79,15 +79,15 @@ public final class GestureTrailsDrawingPreview extends AbstractDrawingPreview {
public void postUpdateGestureTrailPreview() {
removeMessages(MSG_UPDATE_GESTURE_TRAIL);
sendMessageDelayed(obtainMessage(MSG_UPDATE_GESTURE_TRAIL),
mGestureTrailParams.mUpdateInterval);
mDrawingParams.mUpdateInterval);
}
}
public GestureTrailsDrawingPreview(final View drawingView,
final TypedArray mainKeyboardViewAttr) {
super(drawingView);
mGestureTrailParams = new Params(mainKeyboardViewAttr);
mDrawingHandler = new DrawingHandler(this, mGestureTrailParams);
mDrawingParams = new GestureTrailDrawingParams(mainKeyboardViewAttr);
mDrawingHandler = new DrawingHandler(this, mDrawingParams);
final Paint gesturePaint = new Paint();
gesturePaint.setAntiAlias(true);
gesturePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));
@ -96,8 +96,8 @@ public final class GestureTrailsDrawingPreview extends AbstractDrawingPreview {
@Override
public void setKeyboardGeometry(final int[] originCoords, final int width, final int height) {
mOffscreenOffsetY = (int)(
height * GestureStroke.EXTRA_GESTURE_TRAIL_AREA_ABOVE_KEYBOARD_RATIO);
mOffscreenOffsetY = (int)(height
* GestureStrokeRecognitionPoints.EXTRA_GESTURE_TRAIL_AREA_ABOVE_KEYBOARD_RATIO);
mOffscreenWidth = width;
mOffscreenHeight = mOffscreenOffsetY + height;
}
@ -143,9 +143,9 @@ public final class GestureTrailsDrawingPreview extends AbstractDrawingPreview {
// Trails count == fingers count that have ever been active.
final int trailsCount = mGestureTrails.size();
for (int index = 0; index < trailsCount; index++) {
final GestureTrail trail = mGestureTrails.valueAt(index);
final GestureTrailDrawingPoints trail = mGestureTrails.valueAt(index);
needsUpdatingGestureTrail |= trail.drawGestureTrail(offscreenCanvas, paint,
mGestureTrailBoundsRect, mGestureTrailParams);
mGestureTrailBoundsRect, mDrawingParams);
// {@link #mGestureTrailBoundsRect} has bounding box of the trail.
dirtyRect.union(mGestureTrailBoundsRect);
}
@ -188,15 +188,15 @@ public final class GestureTrailsDrawingPreview extends AbstractDrawingPreview {
if (!isPreviewEnabled()) {
return;
}
GestureTrail trail;
GestureTrailDrawingPoints trail;
synchronized (mGestureTrails) {
trail = mGestureTrails.get(tracker.mPointerId);
if (trail == null) {
trail = new GestureTrail();
trail = new GestureTrailDrawingPoints();
mGestureTrails.put(tracker.mPointerId, trail);
}
}
trail.addStroke(tracker.getGestureStrokeWithPreviewPoints(), tracker.getDownTime());
trail.addStroke(tracker.getGestureStrokeDrawingPoints(), tracker.getDownTime());
// TODO: Should narrow the invalidate region.
getDrawingView().invalidate();