Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a47a17a2 authored by Tadashi G. Takaoka's avatar Tadashi G. Takaoka Committed by Android (Google) Code Review
Browse files

Merge "Revise gesture preview trail design" into jb-mr1-dev

parents fc9ea5be c1780c16
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -90,7 +90,8 @@
        <!-- Interval of updating gesture preview trail in millisecond. -->
        <attr name="gesturePreviewTrailUpdateInterval" format="integer" />
        <attr name="gesturePreviewTrailColor" format="color" />
        <attr name="gesturePreviewTrailWidth" format="dimension" />
        <attr name="gesturePreviewTrailStartWidth" format="dimension" />
        <attr name="gesturePreviewTrailEndWidth" format="dimension" />
    </declare-styleable>

    <declare-styleable name="MainKeyboardView">
+2 −1
Original line number Diff line number Diff line
@@ -100,7 +100,8 @@
    <fraction name="center_suggestion_percentile">36%</fraction>

    <!-- Gesture preview trail parameters -->
    <dimen name="gesture_preview_trail_width">2.5dp</dimen>
    <dimen name="gesture_preview_trail_start_width">18.0dp</dimen>
    <dimen name="gesture_preview_trail_end_width">2.5dp</dimen>
    <!-- Gesture floating preview text parameters -->
    <dimen name="gesture_floating_preview_text_size">24dp</dimen>
    <dimen name="gesture_floating_preview_text_offset">73dp</dimen>
+2 −1
Original line number Diff line number Diff line
@@ -77,7 +77,8 @@
        <item name="gesturePreviewTrailFadeoutDuration">@integer/config_gesture_preview_trail_fadeout_duration</item>
        <item name="gesturePreviewTrailUpdateInterval">@integer/config_gesture_preview_trail_update_interval</item>
        <item name="gesturePreviewTrailColor">@android:color/holo_blue_light</item>
        <item name="gesturePreviewTrailWidth">@dimen/gesture_preview_trail_width</item>
        <item name="gesturePreviewTrailStartWidth">@dimen/gesture_preview_trail_start_width</item>
        <item name="gesturePreviewTrailEndWidth">@dimen/gesture_preview_trail_end_width</item>
        <!-- Common attributes of MainKeyboardView -->
        <item name="keyHysteresisDistance">@dimen/config_key_hysteresis_distance</item>
        <item name="touchNoiseThresholdTime">@integer/config_touch_noise_threshold_time</item>
+42 −17
Original line number Diff line number Diff line
@@ -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);
+17 −19
Original line number Diff line number Diff line
@@ -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<GesturePreviewTrail> 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) {