diff options
author | 2012-08-24 01:05:20 -0700 | |
---|---|---|
committer | 2012-08-24 01:05:21 -0700 | |
commit | a1a669a1212d630e9c04d9ddfc1588169359c790 (patch) | |
tree | f608cfbb42f37e5dc1686dcc7c2533171af47dd8 /java/src/com/android/inputmethod/keyboard/internal/GesturePreviewTrail.java | |
parent | 48f0460d4c91d83209d226cb12d81a1174eaa438 (diff) | |
parent | 333a300586c3bedb3d51524642b542cefaa1a22d (diff) | |
download | latinime-a1a669a1212d630e9c04d9ddfc1588169359c790.tar.gz latinime-a1a669a1212d630e9c04d9ddfc1588169359c790.tar.xz latinime-a1a669a1212d630e9c04d9ddfc1588169359c790.zip |
Merge "Add multiple gesture preview trails animation" into jb-mr1-dev
Diffstat (limited to 'java/src/com/android/inputmethod/keyboard/internal/GesturePreviewTrail.java')
-rw-r--r-- | java/src/com/android/inputmethod/keyboard/internal/GesturePreviewTrail.java | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/java/src/com/android/inputmethod/keyboard/internal/GesturePreviewTrail.java b/java/src/com/android/inputmethod/keyboard/internal/GesturePreviewTrail.java new file mode 100644 index 000000000..edc20998f --- /dev/null +++ b/java/src/com/android/inputmethod/keyboard/internal/GesturePreviewTrail.java @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ + +package com.android.inputmethod.keyboard.internal; + +import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.os.SystemClock; + +import com.android.inputmethod.latin.Constants; +import com.android.inputmethod.latin.R; +import com.android.inputmethod.latin.ResizableIntArray; + +class GesturePreviewTrail { + private static final int DEFAULT_CAPACITY = GestureStrokeWithPreviewTrail.PREVIEW_CAPACITY; + + private final GesturePreviewTrailParams mPreviewParams; + private final ResizableIntArray mXCoordinates = new ResizableIntArray(DEFAULT_CAPACITY); + private final ResizableIntArray mYCoordinates = new ResizableIntArray(DEFAULT_CAPACITY); + private final ResizableIntArray mEventTimes = new ResizableIntArray(DEFAULT_CAPACITY); + private int mCurrentStrokeId; + private long mCurrentDownTime; + + // Use this value as imaginary zero because x-coordinates may be zero. + private static final int DOWN_EVENT_MARKER = -128; + + static class GesturePreviewTrailParams { + public final int mFadeoutStartDelay; + public final int mFadeoutDuration; + public final int mUpdateInterval; + + public GesturePreviewTrailParams(final TypedArray keyboardViewAttr) { + mFadeoutStartDelay = keyboardViewAttr.getInt( + R.styleable.KeyboardView_gesturePreviewTrailFadeoutStartDelay, 0); + mFadeoutDuration = keyboardViewAttr.getInt( + R.styleable.KeyboardView_gesturePreviewTrailFadeoutDuration, 0); + mUpdateInterval = keyboardViewAttr.getInt( + R.styleable.KeyboardView_gesturePreviewTrailUpdateInterval, 0); + } + } + + public GesturePreviewTrail(final GesturePreviewTrailParams params) { + mPreviewParams = params; + } + + private static int markAsDownEvent(final int xCoord) { + return DOWN_EVENT_MARKER - xCoord; + } + + private static boolean isDownEventXCoord(final int xCoordOrMark) { + return xCoordOrMark <= DOWN_EVENT_MARKER; + } + + private static int getXCoordValue(final int xCoordOrMark) { + return isDownEventXCoord(xCoordOrMark) + ? DOWN_EVENT_MARKER - xCoordOrMark : xCoordOrMark; + } + + public void addStroke(final GestureStrokeWithPreviewTrail stroke, final long downTime) { + final int strokeId = stroke.getGestureStrokeId(); + final boolean isNewStroke = strokeId != mCurrentStrokeId; + final int trailSize = mEventTimes.getLength(); + stroke.appendPreviewStroke(mEventTimes, mXCoordinates, mYCoordinates); + final int newTrailSize = mEventTimes.getLength(); + if (stroke.getGestureStrokePreviewSize() == 0) { + return; + } + if (isNewStroke) { + final int elapsedTime = (int)(downTime - mCurrentDownTime); + final int[] eventTimes = mEventTimes.getPrimitiveArray(); + for (int i = 0; i < trailSize; i++) { + eventTimes[i] -= elapsedTime; + } + + if (newTrailSize > trailSize) { + final int[] xCoords = mXCoordinates.getPrimitiveArray(); + xCoords[trailSize] = markAsDownEvent(xCoords[trailSize]); + } + mCurrentDownTime = downTime; + mCurrentStrokeId = strokeId; + } + } + + private int getAlpha(final int elapsedTime) { + if (elapsedTime < mPreviewParams.mFadeoutStartDelay) { + return Constants.Color.ALPHA_OPAQUE; + } + final int decreasingAlpha = Constants.Color.ALPHA_OPAQUE + * (elapsedTime - mPreviewParams.mFadeoutStartDelay) + / mPreviewParams.mFadeoutDuration; + return Constants.Color.ALPHA_OPAQUE - decreasingAlpha; + } + + /** + * Draw gesture preview trail + * @param canvas The canvas to draw the gesture preview trail + * @param paint The paint object to be used to draw the gesture preview trail + * @return true if some gesture preview trails remain to be drawn + */ + public boolean drawGestureTrail(final Canvas canvas, final Paint paint) { + final int trailSize = mEventTimes.getLength(); + if (trailSize == 0) { + return false; + } + + final int[] eventTimes = mEventTimes.getPrimitiveArray(); + final int[] xCoords = mXCoordinates.getPrimitiveArray(); + final int[] yCoords = mYCoordinates.getPrimitiveArray(); + final int sinceDown = (int)(SystemClock.uptimeMillis() - mCurrentDownTime); + final int lingeringDuration = mPreviewParams.mFadeoutStartDelay + + mPreviewParams.mFadeoutDuration; + int startIndex; + for (startIndex = 0; startIndex < trailSize; startIndex++) { + final int elapsedTime = sinceDown - eventTimes[startIndex]; + // Skip too old trail points. + if (elapsedTime < lingeringDuration) { + break; + } + } + + if (startIndex < trailSize) { + int lastX = getXCoordValue(xCoords[startIndex]); + int lastY = yCoords[startIndex]; + for (int i = startIndex + 1; i < trailSize - 1; i++) { + final int x = xCoords[i]; + final int y = yCoords[i]; + final int elapsedTime = sinceDown - eventTimes[i]; + // Draw trail line only when the current point isn't a down point. + if (!isDownEventXCoord(x)) { + paint.setAlpha(getAlpha(elapsedTime)); + canvas.drawLine(lastX, lastY, x, y, paint); + } + lastX = getXCoordValue(x); + lastY = y; + } + } + + // TODO: Implement ring buffer to avoid moving points. + // Discard faded out points. + final int newSize = trailSize - startIndex; + System.arraycopy(eventTimes, startIndex, eventTimes, 0, newSize); + System.arraycopy(xCoords, startIndex, xCoords, 0, newSize); + System.arraycopy(yCoords, startIndex, yCoords, 0, newSize); + mEventTimes.setLength(newSize); + mXCoordinates.setLength(newSize); + mYCoordinates.setLength(newSize); + return newSize > 0; + } +} |