am c0a1dc0e: Merge "Draw gesture trail that is above the keyboard" into jb-mr1-dev
* commit 'c0a1dc0e070fd47745a644d60b1178a2a577c3d3': Draw gesture trail that is above the keyboardmain
commit
2f8207855c
|
@ -826,7 +826,8 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
|
||||||
}
|
}
|
||||||
final int[] viewOrigin = new int[2];
|
final int[] viewOrigin = new int[2];
|
||||||
getLocationInWindow(viewOrigin);
|
getLocationInWindow(viewOrigin);
|
||||||
mPreviewPlacerView.setOrigin(viewOrigin[0], viewOrigin[1]);
|
mPreviewPlacerView.setKeyboardViewGeometry(
|
||||||
|
viewOrigin[0], viewOrigin[1], getWidth(), getHeight());
|
||||||
final View rootView = getRootView();
|
final View rootView = getRootView();
|
||||||
if (rootView == null) {
|
if (rootView == null) {
|
||||||
Log.w(TAG, "Cannot find root view");
|
Log.w(TAG, "Cannot find root view");
|
||||||
|
|
|
@ -576,7 +576,8 @@ public class PointerTracker implements PointerTrackerQueue.Element {
|
||||||
mDrawingProxy.showGesturePreviewTrail(this, isOldestTracker);
|
mDrawingProxy.showGesturePreviewTrail(this, isOldestTracker);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateBatchInput(final long eventTime) {
|
private void mayUpdateBatchInput(final long eventTime, final Key key) {
|
||||||
|
if (key != null) {
|
||||||
synchronized (sAggregratedPointers) {
|
synchronized (sAggregratedPointers) {
|
||||||
mGestureStrokeWithPreviewPoints.appendIncrementalBatchPoints(sAggregratedPointers);
|
mGestureStrokeWithPreviewPoints.appendIncrementalBatchPoints(sAggregratedPointers);
|
||||||
final int size = sAggregratedPointers.getPointerSize();
|
final int size = sAggregratedPointers.getPointerSize();
|
||||||
|
@ -590,6 +591,7 @@ public class PointerTracker implements PointerTrackerQueue.Element {
|
||||||
mListener.onUpdateBatchInput(sAggregratedPointers);
|
mListener.onUpdateBatchInput(sAggregratedPointers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
final boolean isOldestTracker = sPointerTrackerQueue.getOldestElement() == this;
|
final boolean isOldestTracker = sPointerTrackerQueue.getOldestElement() == this;
|
||||||
mDrawingProxy.showGesturePreviewTrail(this, isOldestTracker);
|
mDrawingProxy.showGesturePreviewTrail(this, isOldestTracker);
|
||||||
}
|
}
|
||||||
|
@ -746,8 +748,8 @@ public class PointerTracker implements PointerTrackerQueue.Element {
|
||||||
if (mIsDetectingGesture) {
|
if (mIsDetectingGesture) {
|
||||||
mGestureStrokeWithPreviewPoints.addPoint(x, y, gestureTime, isMajorEvent);
|
mGestureStrokeWithPreviewPoints.addPoint(x, y, gestureTime, isMajorEvent);
|
||||||
mayStartBatchInput(key);
|
mayStartBatchInput(key);
|
||||||
if (sInGesture && key != null) {
|
if (sInGesture) {
|
||||||
updateBatchInput(eventTime);
|
mayUpdateBatchInput(eventTime, key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,10 @@ import com.android.inputmethod.latin.R;
|
||||||
import com.android.inputmethod.latin.StaticInnerHandlerWrapper;
|
import com.android.inputmethod.latin.StaticInnerHandlerWrapper;
|
||||||
|
|
||||||
public class PreviewPlacerView extends RelativeLayout {
|
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 mGestureFloatingPreviewTextColor;
|
||||||
private final int mGestureFloatingPreviewTextOffset;
|
private final int mGestureFloatingPreviewTextOffset;
|
||||||
private final int mGestureFloatingPreviewColor;
|
private final int mGestureFloatingPreviewColor;
|
||||||
|
@ -47,14 +51,17 @@ public class PreviewPlacerView extends RelativeLayout {
|
||||||
private final float mGestureFloatingPreviewVerticalPadding;
|
private final float mGestureFloatingPreviewVerticalPadding;
|
||||||
private final float mGestureFloatingPreviewRoundRadius;
|
private final float mGestureFloatingPreviewRoundRadius;
|
||||||
|
|
||||||
private int mXOrigin;
|
private int mKeyboardViewOriginX;
|
||||||
private int mYOrigin;
|
private int mKeyboardViewOriginY;
|
||||||
|
|
||||||
private final SparseArray<GesturePreviewTrail> mGesturePreviewTrails =
|
private final SparseArray<GesturePreviewTrail> mGesturePreviewTrails =
|
||||||
CollectionUtils.newSparseArray();
|
CollectionUtils.newSparseArray();
|
||||||
private final Params mGesturePreviewTrailParams;
|
private final Params mGesturePreviewTrailParams;
|
||||||
private final Paint mGesturePaint;
|
private final Paint mGesturePaint;
|
||||||
private boolean mDrawsGesturePreviewTrail;
|
private boolean mDrawsGesturePreviewTrail;
|
||||||
|
private int mOffscreenWidth;
|
||||||
|
private int mOffscreenHeight;
|
||||||
|
private int mOffscreenOffsetY;
|
||||||
private Bitmap mOffscreenBuffer;
|
private Bitmap mOffscreenBuffer;
|
||||||
private final Canvas mOffscreenCanvas = new Canvas();
|
private final Canvas mOffscreenCanvas = new Canvas();
|
||||||
private final Rect mOffscreenDirtyRect = new Rect();
|
private final Rect mOffscreenDirtyRect = new Rect();
|
||||||
|
@ -165,9 +172,12 @@ public class PreviewPlacerView extends RelativeLayout {
|
||||||
setLayerType(LAYER_TYPE_HARDWARE, layerPaint);
|
setLayerType(LAYER_TYPE_HARDWARE, layerPaint);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOrigin(final int x, final int y) {
|
public void setKeyboardViewGeometry(final int x, final int y, final int w, final int h) {
|
||||||
mXOrigin = x;
|
mKeyboardViewOriginX = x;
|
||||||
mYOrigin = y;
|
mKeyboardViewOriginY = y;
|
||||||
|
mOffscreenOffsetY = (int)(h * EXTRA_GESTURE_TRAIL_AREA_ABOVE_KEYBOARD_RATIO);
|
||||||
|
mOffscreenWidth = w;
|
||||||
|
mOffscreenHeight = mOffscreenOffsetY + h;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setGesturePreviewMode(final boolean drawsGesturePreviewTrail,
|
public void setGesturePreviewMode(final boolean drawsGesturePreviewTrail,
|
||||||
|
@ -204,45 +214,42 @@ public class PreviewPlacerView extends RelativeLayout {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onDetachedFromWindow() {
|
protected void onDetachedFromWindow() {
|
||||||
|
freeOffscreenBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void freeOffscreenBuffer() {
|
||||||
if (mOffscreenBuffer != null) {
|
if (mOffscreenBuffer != null) {
|
||||||
mOffscreenBuffer.recycle();
|
mOffscreenBuffer.recycle();
|
||||||
mOffscreenBuffer = null;
|
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
|
@Override
|
||||||
public void onDraw(final Canvas canvas) {
|
public void onDraw(final Canvas canvas) {
|
||||||
super.onDraw(canvas);
|
super.onDraw(canvas);
|
||||||
canvas.translate(mXOrigin, mYOrigin);
|
|
||||||
if (mDrawsGesturePreviewTrail) {
|
if (mDrawsGesturePreviewTrail) {
|
||||||
if (mOffscreenBuffer == null) {
|
mayAllocateOffscreenBuffer();
|
||||||
mOffscreenBuffer = Bitmap.createBitmap(
|
// Draw gesture trails to offscreen buffer.
|
||||||
getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
|
final boolean needsUpdatingGesturePreviewTrail = drawGestureTrails(
|
||||||
mOffscreenCanvas.setBitmap(mOffscreenBuffer);
|
mOffscreenCanvas, mGesturePaint, mOffscreenDirtyRect);
|
||||||
}
|
// Transfer offscreen buffer to screen.
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!mOffscreenDirtyRect.isEmpty()) {
|
if (!mOffscreenDirtyRect.isEmpty()) {
|
||||||
|
final int offsetY = mKeyboardViewOriginY - mOffscreenOffsetY;
|
||||||
|
canvas.translate(mKeyboardViewOriginX, offsetY);
|
||||||
canvas.drawBitmap(mOffscreenBuffer, mOffscreenDirtyRect, mOffscreenDirtyRect,
|
canvas.drawBitmap(mOffscreenBuffer, mOffscreenDirtyRect, mOffscreenDirtyRect,
|
||||||
mGesturePaint);
|
mGesturePaint);
|
||||||
|
canvas.translate(-mKeyboardViewOriginX, -offsetY);
|
||||||
// Note: Defer clearing the dirty rectangle here because we will get cleared
|
// Note: Defer clearing the dirty rectangle here because we will get cleared
|
||||||
// rectangle on the canvas.
|
// rectangle on the canvas.
|
||||||
}
|
}
|
||||||
|
@ -251,9 +258,49 @@ public class PreviewPlacerView extends RelativeLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (mDrawsGestureFloatingPreviewText) {
|
if (mDrawsGestureFloatingPreviewText) {
|
||||||
|
canvas.translate(mKeyboardViewOriginX, mKeyboardViewOriginY);
|
||||||
drawGestureFloatingPreviewText(canvas, mGestureFloatingPreviewText);
|
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) {
|
public void setGestureFloatingPreviewText(final String gestureFloatingPreviewText) {
|
||||||
|
|
Loading…
Reference in New Issue