Merge "Rename gesture related classes"
This commit is contained in:
commit
a801c8fd9b
8 changed files with 228 additions and 155 deletions
|
@ -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.
|
||||||
|
|
|
@ -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);
|
|
@ -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;
|
|
@ -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);
|
|
@ -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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
|
@ -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();
|
||||||
|
|
Loading…
Reference in a new issue