From c1780c16a7444148dedd5471ffadbdff592df2f4 Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Thu, 6 Sep 2012 12:12:10 +0900 Subject: [PATCH] Revise gesture preview trail design Bug: 7042741 Change-Id: I99e3b3a6fc52afaee3cc5daf371131c3afebb3ae --- java/res/values/attrs.xml | 3 +- java/res/values/dimens.xml | 3 +- java/res/values/styles.xml | 3 +- .../internal/GesturePreviewTrail.java | 59 +++++++++++++------ .../keyboard/internal/PreviewPlacerView.java | 36 ++++++----- 5 files changed, 65 insertions(+), 39 deletions(-) diff --git a/java/res/values/attrs.xml b/java/res/values/attrs.xml index e60139704..7e8c77e13 100644 --- a/java/res/values/attrs.xml +++ b/java/res/values/attrs.xml @@ -90,7 +90,8 @@ - + + diff --git a/java/res/values/dimens.xml b/java/res/values/dimens.xml index 9ccaaaf4e..d92a71560 100644 --- a/java/res/values/dimens.xml +++ b/java/res/values/dimens.xml @@ -100,7 +100,8 @@ 36% - 2.5dp + 18.0dp + 2.5dp 24dp 73dp diff --git a/java/res/values/styles.xml b/java/res/values/styles.xml index 94fdbeb53..ed92440ef 100644 --- a/java/res/values/styles.xml +++ b/java/res/values/styles.xml @@ -77,7 +77,8 @@ @integer/config_gesture_preview_trail_fadeout_duration @integer/config_gesture_preview_trail_update_interval @android:color/holo_blue_light - @dimen/gesture_preview_trail_width + @dimen/gesture_preview_trail_start_width + @dimen/gesture_preview_trail_end_width @dimen/config_key_hysteresis_distance @integer/config_touch_noise_threshold_time diff --git a/java/src/com/android/inputmethod/keyboard/internal/GesturePreviewTrail.java b/java/src/com/android/inputmethod/keyboard/internal/GesturePreviewTrail.java index e814d8009..7442b7fad 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/GesturePreviewTrail.java +++ b/java/src/com/android/inputmethod/keyboard/internal/GesturePreviewTrail.java @@ -17,16 +17,18 @@ package com.android.inputmethod.keyboard.internal; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Paint; +import android.graphics.PorterDuff; +import android.graphics.PorterDuffXfermode; +import android.graphics.Xfermode; import android.os.SystemClock; import com.android.inputmethod.latin.Constants; import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.ResizableIntArray; -class GesturePreviewTrail { +final 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); @@ -34,28 +36,39 @@ class GesturePreviewTrail { private long mCurrentDownTime; private int mTrailStartIndex; + private final static Xfermode PORTER_DUFF_MODE_SRC = + new PorterDuffXfermode(PorterDuff.Mode.SRC); + // Use this value as imaginary zero because x-coordinates may be zero. private static final int DOWN_EVENT_MARKER = -128; - static class GesturePreviewTrailParams { + static final class Params { + public final int mTrailColor; + public final float mTrailStartWidth; + public final float mTrailEndWidth; public final int mFadeoutStartDelay; public final int mFadeoutDuration; public final int mUpdateInterval; - public GesturePreviewTrailParams(final TypedArray keyboardViewAttr) { + public final int mTrailLingerDuration; + + public Params(final TypedArray keyboardViewAttr) { + mTrailColor = keyboardViewAttr.getColor( + R.styleable.KeyboardView_gesturePreviewTrailColor, 0); + mTrailStartWidth = keyboardViewAttr.getDimension( + R.styleable.KeyboardView_gesturePreviewTrailStartWidth, 0.0f); + mTrailEndWidth = keyboardViewAttr.getDimension( + R.styleable.KeyboardView_gesturePreviewTrailEndWidth, 0.0f); mFadeoutStartDelay = keyboardViewAttr.getInt( R.styleable.KeyboardView_gesturePreviewTrailFadeoutStartDelay, 0); mFadeoutDuration = keyboardViewAttr.getInt( R.styleable.KeyboardView_gesturePreviewTrailFadeoutDuration, 0); + mTrailLingerDuration = mFadeoutStartDelay + mFadeoutDuration; 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; } @@ -94,23 +107,30 @@ class GesturePreviewTrail { } } - private int getAlpha(final int elapsedTime) { - if (elapsedTime < mPreviewParams.mFadeoutStartDelay) { + private static int getAlpha(final int elapsedTime, final Params params) { + if (elapsedTime < params.mFadeoutStartDelay) { return Constants.Color.ALPHA_OPAQUE; } final int decreasingAlpha = Constants.Color.ALPHA_OPAQUE - * (elapsedTime - mPreviewParams.mFadeoutStartDelay) - / mPreviewParams.mFadeoutDuration; + * (elapsedTime - params.mFadeoutStartDelay) + / params.mFadeoutDuration; return Constants.Color.ALPHA_OPAQUE - decreasingAlpha; } + private static float getWidth(final int elapsedTime, final Params params) { + return Math.max((params.mTrailLingerDuration - elapsedTime) + * (params.mTrailStartWidth - params.mTrailEndWidth) + / params.mTrailLingerDuration, 0.0f); + } + /** * 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 + * @param params The drawing parameters of gesture preview trail * @return true if some gesture preview trails remain to be drawn */ - public boolean drawGestureTrail(final Canvas canvas, final Paint paint) { + public boolean drawGestureTrail(final Canvas canvas, final Paint paint, final Params params) { final int trailSize = mEventTimes.getLength(); if (trailSize == 0) { return false; @@ -120,13 +140,11 @@ class GesturePreviewTrail { 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 = mTrailStartIndex; startIndex < trailSize; startIndex++) { final int elapsedTime = sinceDown - eventTimes[startIndex]; // Skip too old trail points. - if (elapsedTime < lingeringDuration) { + if (elapsedTime < params.mTrailLingerDuration) { break; } } @@ -135,13 +153,20 @@ class GesturePreviewTrail { if (startIndex < trailSize) { int lastX = getXCoordValue(xCoords[startIndex]); int lastY = yCoords[startIndex]; + paint.setColor(params.mTrailColor); + paint.setStyle(Paint.Style.STROKE); + paint.setStrokeCap(Paint.Cap.ROUND); + paint.setXfermode(PORTER_DUFF_MODE_SRC); 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)); + final int alpha = getAlpha(elapsedTime, params); + paint.setAlpha(alpha); + final float width = getWidth(elapsedTime, params); + paint.setStrokeWidth(width); canvas.drawLine(lastX, lastY, x, y, paint); } lastX = getXCoordValue(x); diff --git a/java/src/com/android/inputmethod/keyboard/internal/PreviewPlacerView.java b/java/src/com/android/inputmethod/keyboard/internal/PreviewPlacerView.java index 641fadf6d..8dde4d671 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/PreviewPlacerView.java +++ b/java/src/com/android/inputmethod/keyboard/internal/PreviewPlacerView.java @@ -21,6 +21,8 @@ import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Paint.Align; +import android.graphics.PorterDuff; +import android.graphics.PorterDuffXfermode; import android.graphics.Rect; import android.graphics.RectF; import android.os.Message; @@ -30,14 +32,12 @@ import android.util.SparseArray; import android.widget.RelativeLayout; import com.android.inputmethod.keyboard.PointerTracker; -import com.android.inputmethod.keyboard.internal.GesturePreviewTrail.GesturePreviewTrailParams; +import com.android.inputmethod.keyboard.internal.GesturePreviewTrail.Params; import com.android.inputmethod.latin.CollectionUtils; import com.android.inputmethod.latin.R; import com.android.inputmethod.latin.StaticInnerHandlerWrapper; public class PreviewPlacerView extends RelativeLayout { - private final Paint mGesturePaint; - private final Paint mTextPaint; private final int mGestureFloatingPreviewTextColor; private final int mGestureFloatingPreviewTextOffset; private final int mGestureFloatingPreviewColor; @@ -51,8 +51,11 @@ public class PreviewPlacerView extends RelativeLayout { private final SparseArray mGesturePreviewTrails = CollectionUtils.newSparseArray(); - private final GesturePreviewTrailParams mGesturePreviewTrailParams; + private final Params mGesturePreviewTrailParams; + private final Paint mGesturePaint; + private boolean mDrawsGesturePreviewTrail; + private final Paint mTextPaint; private String mGestureFloatingPreviewText; private final int mGestureFloatingPreviewTextHeight; // {@link RectF} is needed for {@link Canvas#drawRoundRect(RectF, float, float, Paint)}. @@ -60,8 +63,6 @@ public class PreviewPlacerView extends RelativeLayout { private int mLastPointerX; private int mLastPointerY; private static final char[] TEXT_HEIGHT_REFERENCE_CHAR = { 'M' }; - - private boolean mDrawsGesturePreviewTrail; private boolean mDrawsGestureFloatingPreviewText; private final DrawingHandler mDrawingHandler; @@ -70,10 +71,10 @@ public class PreviewPlacerView extends RelativeLayout { private static final int MSG_DISMISS_GESTURE_FLOATING_PREVIEW_TEXT = 0; private static final int MSG_UPDATE_GESTURE_PREVIEW_TRAIL = 1; - private final GesturePreviewTrailParams mGesturePreviewTrailParams; + private final Params mGesturePreviewTrailParams; public DrawingHandler(final PreviewPlacerView outerInstance, - final GesturePreviewTrailParams gesturePreviewTrailParams) { + final Params gesturePreviewTrailParams) { super(outerInstance); mGesturePreviewTrailParams = gesturePreviewTrailParams; } @@ -146,21 +147,13 @@ public class PreviewPlacerView extends RelativeLayout { R.styleable.KeyboardView_gestureFloatingPreviewRoundRadius, 0.0f); mGestureFloatingPreviewTextLingerTimeout = keyboardViewAttr.getInt( R.styleable.KeyboardView_gestureFloatingPreviewTextLingerTimeout, 0); - final int gesturePreviewTrailColor = keyboardViewAttr.getColor( - R.styleable.KeyboardView_gesturePreviewTrailColor, 0); - final int gesturePreviewTrailWidth = keyboardViewAttr.getDimensionPixelSize( - R.styleable.KeyboardView_gesturePreviewTrailWidth, 0); - mGesturePreviewTrailParams = new GesturePreviewTrailParams(keyboardViewAttr); + mGesturePreviewTrailParams = new Params(keyboardViewAttr); keyboardViewAttr.recycle(); mDrawingHandler = new DrawingHandler(this, mGesturePreviewTrailParams); final Paint gesturePaint = new Paint(); gesturePaint.setAntiAlias(true); - gesturePaint.setStyle(Paint.Style.STROKE); - gesturePaint.setStrokeJoin(Paint.Join.ROUND); - gesturePaint.setColor(gesturePreviewTrailColor); - gesturePaint.setStrokeWidth(gesturePreviewTrailWidth); mGesturePaint = gesturePaint; final Paint textPaint = new Paint(); @@ -172,6 +165,10 @@ public class PreviewPlacerView extends RelativeLayout { final Rect textRect = new Rect(); textPaint.getTextBounds(TEXT_HEIGHT_REFERENCE_CHAR, 0, 1, textRect); mGestureFloatingPreviewTextHeight = textRect.height(); + + final Paint layerPaint = new Paint(); + layerPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER)); + setLayerType(LAYER_TYPE_HARDWARE, layerPaint); } public void setOrigin(final int x, final int y) { @@ -190,7 +187,7 @@ public class PreviewPlacerView extends RelativeLayout { synchronized (mGesturePreviewTrails) { trail = mGesturePreviewTrails.get(tracker.mPointerId); if (trail == null) { - trail = new GesturePreviewTrail(mGesturePreviewTrailParams); + trail = new GesturePreviewTrail(); mGesturePreviewTrails.put(tracker.mPointerId, trail); } } @@ -214,7 +211,8 @@ public class PreviewPlacerView extends RelativeLayout { for (int index = 0; index < trailsCount; index++) { final GesturePreviewTrail trail = mGesturePreviewTrails.valueAt(index); needsUpdatingGesturePreviewTrail |= - trail.drawGestureTrail(canvas, mGesturePaint); + trail.drawGestureTrail(canvas, mGesturePaint, + mGesturePreviewTrailParams); } } if (needsUpdatingGesturePreviewTrail) {