Merge "Draw gesture trail that is above the keyboard" into jb-mr1-dev
This commit is contained in:
commit
c0a1dc0e07
3 changed files with 96 additions and 46 deletions
|
@ -826,7 +826,8 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
|
|||
}
|
||||
final int[] viewOrigin = new int[2];
|
||||
getLocationInWindow(viewOrigin);
|
||||
mPreviewPlacerView.setOrigin(viewOrigin[0], viewOrigin[1]);
|
||||
mPreviewPlacerView.setKeyboardViewGeometry(
|
||||
viewOrigin[0], viewOrigin[1], getWidth(), getHeight());
|
||||
final View rootView = getRootView();
|
||||
if (rootView == null) {
|
||||
Log.w(TAG, "Cannot find root view");
|
||||
|
|
|
@ -576,18 +576,20 @@ public class PointerTracker implements PointerTrackerQueue.Element {
|
|||
mDrawingProxy.showGesturePreviewTrail(this, isOldestTracker);
|
||||
}
|
||||
|
||||
private void updateBatchInput(final long eventTime) {
|
||||
synchronized (sAggregratedPointers) {
|
||||
mGestureStrokeWithPreviewPoints.appendIncrementalBatchPoints(sAggregratedPointers);
|
||||
final int size = sAggregratedPointers.getPointerSize();
|
||||
if (size > sLastRecognitionPointSize
|
||||
&& GestureStroke.hasRecognitionTimePast(eventTime, sLastRecognitionTime)) {
|
||||
sLastRecognitionPointSize = size;
|
||||
sLastRecognitionTime = eventTime;
|
||||
if (DEBUG_LISTENER) {
|
||||
Log.d(TAG, "onUpdateBatchInput: batchPoints=" + size);
|
||||
private void mayUpdateBatchInput(final long eventTime, final Key key) {
|
||||
if (key != null) {
|
||||
synchronized (sAggregratedPointers) {
|
||||
mGestureStrokeWithPreviewPoints.appendIncrementalBatchPoints(sAggregratedPointers);
|
||||
final int size = sAggregratedPointers.getPointerSize();
|
||||
if (size > sLastRecognitionPointSize
|
||||
&& GestureStroke.hasRecognitionTimePast(eventTime, sLastRecognitionTime)) {
|
||||
sLastRecognitionPointSize = size;
|
||||
sLastRecognitionTime = eventTime;
|
||||
if (DEBUG_LISTENER) {
|
||||
Log.d(TAG, "onUpdateBatchInput: batchPoints=" + size);
|
||||
}
|
||||
mListener.onUpdateBatchInput(sAggregratedPointers);
|
||||
}
|
||||
mListener.onUpdateBatchInput(sAggregratedPointers);
|
||||
}
|
||||
}
|
||||
final boolean isOldestTracker = sPointerTrackerQueue.getOldestElement() == this;
|
||||
|
@ -746,8 +748,8 @@ public class PointerTracker implements PointerTrackerQueue.Element {
|
|||
if (mIsDetectingGesture) {
|
||||
mGestureStrokeWithPreviewPoints.addPoint(x, y, gestureTime, isMajorEvent);
|
||||
mayStartBatchInput(key);
|
||||
if (sInGesture && key != null) {
|
||||
updateBatchInput(eventTime);
|
||||
if (sInGesture) {
|
||||
mayUpdateBatchInput(eventTime, key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,6 +40,10 @@ import com.android.inputmethod.latin.R;
|
|||
import com.android.inputmethod.latin.StaticInnerHandlerWrapper;
|
||||
|
||||
public class PreviewPlacerView extends RelativeLayout {
|
||||
// The height of extra area above the keyboard to draw gesture trails.
|
||||
// Proportional to the keyboard height.
|
||||
private static final float EXTRA_GESTURE_TRAIL_AREA_ABOVE_KEYBOARD_RATIO = 0.25f;
|
||||
|
||||
private final int mGestureFloatingPreviewTextColor;
|
||||
private final int mGestureFloatingPreviewTextOffset;
|
||||
private final int mGestureFloatingPreviewColor;
|
||||
|
@ -47,14 +51,17 @@ public class PreviewPlacerView extends RelativeLayout {
|
|||
private final float mGestureFloatingPreviewVerticalPadding;
|
||||
private final float mGestureFloatingPreviewRoundRadius;
|
||||
|
||||
private int mXOrigin;
|
||||
private int mYOrigin;
|
||||
private int mKeyboardViewOriginX;
|
||||
private int mKeyboardViewOriginY;
|
||||
|
||||
private final SparseArray<GesturePreviewTrail> mGesturePreviewTrails =
|
||||
CollectionUtils.newSparseArray();
|
||||
private final Params mGesturePreviewTrailParams;
|
||||
private final Paint mGesturePaint;
|
||||
private boolean mDrawsGesturePreviewTrail;
|
||||
private int mOffscreenWidth;
|
||||
private int mOffscreenHeight;
|
||||
private int mOffscreenOffsetY;
|
||||
private Bitmap mOffscreenBuffer;
|
||||
private final Canvas mOffscreenCanvas = new Canvas();
|
||||
private final Rect mOffscreenDirtyRect = new Rect();
|
||||
|
@ -165,9 +172,12 @@ public class PreviewPlacerView extends RelativeLayout {
|
|||
setLayerType(LAYER_TYPE_HARDWARE, layerPaint);
|
||||
}
|
||||
|
||||
public void setOrigin(final int x, final int y) {
|
||||
mXOrigin = x;
|
||||
mYOrigin = y;
|
||||
public void setKeyboardViewGeometry(final int x, final int y, final int w, final int h) {
|
||||
mKeyboardViewOriginX = x;
|
||||
mKeyboardViewOriginY = y;
|
||||
mOffscreenOffsetY = (int)(h * EXTRA_GESTURE_TRAIL_AREA_ABOVE_KEYBOARD_RATIO);
|
||||
mOffscreenWidth = w;
|
||||
mOffscreenHeight = mOffscreenOffsetY + h;
|
||||
}
|
||||
|
||||
public void setGesturePreviewMode(final boolean drawsGesturePreviewTrail,
|
||||
|
@ -204,45 +214,42 @@ public class PreviewPlacerView extends RelativeLayout {
|
|||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
freeOffscreenBuffer();
|
||||
}
|
||||
|
||||
private void freeOffscreenBuffer() {
|
||||
if (mOffscreenBuffer != null) {
|
||||
mOffscreenBuffer.recycle();
|
||||
mOffscreenBuffer = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void mayAllocateOffscreenBuffer() {
|
||||
if (mOffscreenBuffer != null && mOffscreenBuffer.getWidth() == mOffscreenWidth
|
||||
&& mOffscreenBuffer.getHeight() == mOffscreenHeight) {
|
||||
return;
|
||||
}
|
||||
freeOffscreenBuffer();
|
||||
mOffscreenBuffer = Bitmap.createBitmap(
|
||||
mOffscreenWidth, mOffscreenHeight, Bitmap.Config.ARGB_8888);
|
||||
mOffscreenCanvas.setBitmap(mOffscreenBuffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDraw(final Canvas canvas) {
|
||||
super.onDraw(canvas);
|
||||
canvas.translate(mXOrigin, mYOrigin);
|
||||
if (mDrawsGesturePreviewTrail) {
|
||||
if (mOffscreenBuffer == null) {
|
||||
mOffscreenBuffer = Bitmap.createBitmap(
|
||||
getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
|
||||
mOffscreenCanvas.setBitmap(mOffscreenBuffer);
|
||||
}
|
||||
if (!mOffscreenDirtyRect.isEmpty()) {
|
||||
// Clear previous dirty rectangle.
|
||||
mGesturePaint.setColor(Color.TRANSPARENT);
|
||||
mGesturePaint.setStyle(Paint.Style.FILL);
|
||||
mOffscreenCanvas.drawRect(mOffscreenDirtyRect, mGesturePaint);
|
||||
mOffscreenDirtyRect.setEmpty();
|
||||
}
|
||||
boolean needsUpdatingGesturePreviewTrail = false;
|
||||
synchronized (mGesturePreviewTrails) {
|
||||
// Trails count == fingers count that have ever been active.
|
||||
final int trailsCount = mGesturePreviewTrails.size();
|
||||
for (int index = 0; index < trailsCount; index++) {
|
||||
final GesturePreviewTrail trail = mGesturePreviewTrails.valueAt(index);
|
||||
needsUpdatingGesturePreviewTrail |=
|
||||
trail.drawGestureTrail(mOffscreenCanvas, mGesturePaint,
|
||||
mGesturePreviewTrailBoundsRect, mGesturePreviewTrailParams);
|
||||
// {@link #mGesturePreviewTrailBoundsRect} has bounding box of the trail.
|
||||
mOffscreenDirtyRect.union(mGesturePreviewTrailBoundsRect);
|
||||
}
|
||||
}
|
||||
mayAllocateOffscreenBuffer();
|
||||
// Draw gesture trails to offscreen buffer.
|
||||
final boolean needsUpdatingGesturePreviewTrail = drawGestureTrails(
|
||||
mOffscreenCanvas, mGesturePaint, mOffscreenDirtyRect);
|
||||
// Transfer offscreen buffer to screen.
|
||||
if (!mOffscreenDirtyRect.isEmpty()) {
|
||||
final int offsetY = mKeyboardViewOriginY - mOffscreenOffsetY;
|
||||
canvas.translate(mKeyboardViewOriginX, offsetY);
|
||||
canvas.drawBitmap(mOffscreenBuffer, mOffscreenDirtyRect, mOffscreenDirtyRect,
|
||||
mGesturePaint);
|
||||
canvas.translate(-mKeyboardViewOriginX, -offsetY);
|
||||
// Note: Defer clearing the dirty rectangle here because we will get cleared
|
||||
// rectangle on the canvas.
|
||||
}
|
||||
|
@ -251,9 +258,49 @@ public class PreviewPlacerView extends RelativeLayout {
|
|||
}
|
||||
}
|
||||
if (mDrawsGestureFloatingPreviewText) {
|
||||
canvas.translate(mKeyboardViewOriginX, mKeyboardViewOriginY);
|
||||
drawGestureFloatingPreviewText(canvas, mGestureFloatingPreviewText);
|
||||
canvas.translate(-mKeyboardViewOriginX, -mKeyboardViewOriginY);
|
||||
}
|
||||
canvas.translate(-mXOrigin, -mYOrigin);
|
||||
}
|
||||
|
||||
private boolean drawGestureTrails(final Canvas offscreenCanvas, final Paint paint,
|
||||
final Rect dirtyRect) {
|
||||
// Clear previous dirty rectangle.
|
||||
if (!dirtyRect.isEmpty()) {
|
||||
paint.setColor(Color.TRANSPARENT);
|
||||
paint.setStyle(Paint.Style.FILL);
|
||||
offscreenCanvas.drawRect(dirtyRect, paint);
|
||||
}
|
||||
dirtyRect.setEmpty();
|
||||
|
||||
// Draw gesture trails to offscreen buffer.
|
||||
offscreenCanvas.translate(0, mOffscreenOffsetY);
|
||||
boolean needsUpdatingGesturePreviewTrail = false;
|
||||
synchronized (mGesturePreviewTrails) {
|
||||
// Trails count == fingers count that have ever been active.
|
||||
final int trailsCount = mGesturePreviewTrails.size();
|
||||
for (int index = 0; index < trailsCount; index++) {
|
||||
final GesturePreviewTrail trail = mGesturePreviewTrails.valueAt(index);
|
||||
needsUpdatingGesturePreviewTrail |=
|
||||
trail.drawGestureTrail(offscreenCanvas, paint,
|
||||
mGesturePreviewTrailBoundsRect, mGesturePreviewTrailParams);
|
||||
// {@link #mGesturePreviewTrailBoundsRect} has bounding box of the trail.
|
||||
dirtyRect.union(mGesturePreviewTrailBoundsRect);
|
||||
}
|
||||
}
|
||||
offscreenCanvas.translate(0, -mOffscreenOffsetY);
|
||||
|
||||
// Clip dirty rectangle with offscreen buffer width/height.
|
||||
dirtyRect.offset(0, mOffscreenOffsetY);
|
||||
clipRect(dirtyRect, 0, 0, mOffscreenWidth, mOffscreenHeight);
|
||||
return needsUpdatingGesturePreviewTrail;
|
||||
}
|
||||
|
||||
private static void clipRect(final Rect out, final int left, final int top, final int right,
|
||||
final int bottom) {
|
||||
out.set(Math.max(out.left, left), Math.max(out.top, top), Math.min(out.right, right),
|
||||
Math.min(out.bottom, bottom));
|
||||
}
|
||||
|
||||
public void setGestureFloatingPreviewText(final String gestureFloatingPreviewText) {
|
||||
|
|
Loading…
Reference in a new issue