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

View file

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

View file

@ -21,7 +21,22 @@ import android.content.res.TypedArray;
import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.utils.ResourceUtils; 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 // Static threshold for gesture after fast typing
public final int mStaticTimeThresholdAfterFastTyping; // msec public final int mStaticTimeThresholdAfterFastTyping; // msec
// Static threshold for starting gesture detection // Static threshold for starting gesture detection
@ -40,10 +55,11 @@ public final class GestureStrokeParams {
public final int mRecognitionMinimumTime; // msec public final int mRecognitionMinimumTime; // msec
public final float mRecognitionSpeedThreshold; // keyWidth/sec public final float mRecognitionSpeedThreshold; // keyWidth/sec
// Default GestureStroke parameters. // Default GestureStrokeRecognitionPoints parameters.
public static final GestureStrokeParams DEFAULT = new GestureStrokeParams(); public static final GestureStrokeRecognitionParams DEFAULT =
new GestureStrokeRecognitionParams();
private GestureStrokeParams() { private GestureStrokeRecognitionParams() {
// These parameter values are default and intended for testing. // These parameter values are default and intended for testing.
mStaticTimeThresholdAfterFastTyping = 350; // msec mStaticTimeThresholdAfterFastTyping = 350; // msec
mDetectFastMoveSpeedThreshold = 1.5f; // keyWidth/sec mDetectFastMoveSpeedThreshold = 1.5f; // keyWidth/sec
@ -58,7 +74,7 @@ public final class GestureStrokeParams {
mRecognitionSpeedThreshold = 5.5f; // keyWidth/sec mRecognitionSpeedThreshold = 5.5f; // keyWidth/sec
} }
public GestureStrokeParams(final TypedArray mainKeyboardViewAttr) { public GestureStrokeRecognitionParams(final TypedArray mainKeyboardViewAttr) {
mStaticTimeThresholdAfterFastTyping = mainKeyboardViewAttr.getInt( mStaticTimeThresholdAfterFastTyping = mainKeyboardViewAttr.getInt(
R.styleable.MainKeyboardView_gestureStaticTimeThresholdAfterFastTyping, R.styleable.MainKeyboardView_gestureStaticTimeThresholdAfterFastTyping,
DEFAULT.mStaticTimeThresholdAfterFastTyping); DEFAULT.mStaticTimeThresholdAfterFastTyping);

View file

@ -21,8 +21,12 @@ import android.util.Log;
import com.android.inputmethod.latin.InputPointers; import com.android.inputmethod.latin.InputPointers;
import com.android.inputmethod.latin.utils.ResizableIntArray; 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 = false;
private static final boolean DEBUG_SPEED = 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 mXCoordinates = new ResizableIntArray(DEFAULT_CAPACITY);
private final ResizableIntArray mYCoordinates = 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 mKeyWidth; // pixel
private int mMinYCoordinate; // pixel private int mMinYCoordinate; // pixel
@ -63,9 +67,10 @@ public class GestureStroke {
private static final int MSEC_PER_SEC = 1000; 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; mPointerId = pointerId;
mParams = params; mRecognitionParams = recognitionParams;
} }
public void setKeyboardGeometry(final int keyWidth, final int keyboardHeight) { 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); mMinYCoordinate = -(int)(keyboardHeight * EXTRA_GESTURE_TRAIL_AREA_ABOVE_KEYBOARD_RATIO);
mMaxYCoordinate = keyboardHeight; mMaxYCoordinate = keyboardHeight;
// TODO: Find an appropriate base metric for these length. Maybe diagonal length of the key? // TODO: Find an appropriate base metric for these length. Maybe diagonal length of the key?
mDetectFastMoveSpeedThreshold = (int)(keyWidth * mParams.mDetectFastMoveSpeedThreshold); mDetectFastMoveSpeedThreshold = (int)(
mGestureDynamicDistanceThresholdFrom = keyWidth * mRecognitionParams.mDetectFastMoveSpeedThreshold);
(int)(keyWidth * mParams.mDynamicDistanceThresholdFrom); mGestureDynamicDistanceThresholdFrom = (int)(
mGestureDynamicDistanceThresholdTo = (int)(keyWidth * mParams.mDynamicDistanceThresholdTo); keyWidth * mRecognitionParams.mDynamicDistanceThresholdFrom);
mGestureSamplingMinimumDistance = (int)(keyWidth * mParams.mSamplingMinimumDistance); mGestureDynamicDistanceThresholdTo = (int)(
mGestureRecognitionSpeedThreshold = (int)(keyWidth * mParams.mRecognitionSpeedThreshold); keyWidth * mRecognitionParams.mDynamicDistanceThresholdTo);
mGestureSamplingMinimumDistance = (int)(
keyWidth * mRecognitionParams.mSamplingMinimumDistance);
mGestureRecognitionSpeedThreshold = (int)(
keyWidth * mRecognitionParams.mRecognitionSpeedThreshold);
if (DEBUG) { if (DEBUG) {
Log.d(TAG, String.format( Log.d(TAG, String.format(
"[%d] setKeyboardGeometry: keyWidth=%3d tT=%3d >> %3d tD=%3d >> %3d", "[%d] setKeyboardGeometry: keyWidth=%3d tT=%3d >> %3d tD=%3d >> %3d",
mPointerId, keyWidth, mPointerId, keyWidth,
mParams.mDynamicTimeThresholdFrom, mRecognitionParams.mDynamicTimeThresholdFrom,
mParams.mDynamicTimeThresholdTo, mRecognitionParams.mDynamicTimeThresholdTo,
mGestureDynamicDistanceThresholdFrom, mGestureDynamicDistanceThresholdFrom,
mGestureDynamicDistanceThresholdTo)); mGestureDynamicDistanceThresholdTo));
} }
@ -98,7 +107,7 @@ public class GestureStroke {
final long gestureFirstDownTime, final long lastTypingTime) { final long gestureFirstDownTime, final long lastTypingTime) {
reset(); reset();
final long elapsedTimeAfterTyping = downTime - lastTypingTime; final long elapsedTimeAfterTyping = downTime - lastTypingTime;
if (elapsedTimeAfterTyping < mParams.mStaticTimeThresholdAfterFastTyping) { if (elapsedTimeAfterTyping < mRecognitionParams.mStaticTimeThresholdAfterFastTyping) {
mAfterFastTyping = true; mAfterFastTyping = true;
} }
if (DEBUG) { if (DEBUG) {
@ -110,23 +119,24 @@ public class GestureStroke {
} }
private int getGestureDynamicDistanceThreshold(final int deltaTime) { private int getGestureDynamicDistanceThreshold(final int deltaTime) {
if (!mAfterFastTyping || deltaTime >= mParams.mDynamicThresholdDecayDuration) { if (!mAfterFastTyping || deltaTime >= mRecognitionParams.mDynamicThresholdDecayDuration) {
return mGestureDynamicDistanceThresholdTo; return mGestureDynamicDistanceThresholdTo;
} }
final int decayedThreshold = final int decayedThreshold =
(mGestureDynamicDistanceThresholdFrom - mGestureDynamicDistanceThresholdTo) (mGestureDynamicDistanceThresholdFrom - mGestureDynamicDistanceThresholdTo)
* deltaTime / mParams.mDynamicThresholdDecayDuration; * deltaTime / mRecognitionParams.mDynamicThresholdDecayDuration;
return mGestureDynamicDistanceThresholdFrom - decayedThreshold; return mGestureDynamicDistanceThresholdFrom - decayedThreshold;
} }
private int getGestureDynamicTimeThreshold(final int deltaTime) { private int getGestureDynamicTimeThreshold(final int deltaTime) {
if (!mAfterFastTyping || deltaTime >= mParams.mDynamicThresholdDecayDuration) { if (!mAfterFastTyping || deltaTime >= mRecognitionParams.mDynamicThresholdDecayDuration) {
return mParams.mDynamicTimeThresholdTo; return mRecognitionParams.mDynamicTimeThresholdTo;
} }
final int decayedThreshold = final int decayedThreshold =
(mParams.mDynamicTimeThresholdFrom - mParams.mDynamicTimeThresholdTo) (mRecognitionParams.mDynamicTimeThresholdFrom
* deltaTime / mParams.mDynamicThresholdDecayDuration; - mRecognitionParams.mDynamicTimeThresholdTo)
return mParams.mDynamicTimeThresholdFrom - decayedThreshold; * deltaTime / mRecognitionParams.mDynamicThresholdDecayDuration;
return mRecognitionParams.mDynamicTimeThresholdFrom - decayedThreshold;
} }
public final boolean isStartOfAGesture() { public final boolean isStartOfAGesture() {
@ -285,7 +295,7 @@ public class GestureStroke {
public final boolean hasRecognitionTimePast( public final boolean hasRecognitionTimePast(
final long currentTime, final long lastRecognitionTime) { final long currentTime, final long lastRecognitionTime) {
return currentTime > lastRecognitionTime + mParams.mRecognitionMinimumTime; return currentTime > lastRecognitionTime + mRecognitionParams.mRecognitionMinimumTime;
} }
public final void appendAllBatchPoints(final InputPointers out) { 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) { private static int getDistance(final int x1, final int y1, final int x2, final int y2) {
final int dx = x1 - x2; return (int)Math.hypot(x1 - x2, y1 - y2);
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);
} }
} }

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

View file

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