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

Commit 547b6381 authored by Tadashi G. Takaoka's avatar Tadashi G. Takaoka
Browse files

Groundwork for sliding key input preview

Bug: 7548583
Change-Id: Id807af31f581c08ff8074ed1f6766337bea9469f
parent b5fc0e02
Loading
Loading
Loading
Loading
+13 −9
Original line number Diff line number Diff line
@@ -135,7 +135,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {

    // Preview placer view
    private final PreviewPlacerView mPreviewPlacerView;
    private final int[] mCoordinates = CoordinateUtils.newInstance();
    private final int[] mOriginCoords = CoordinateUtils.newInstance();

    // Key preview
    private static final int PREVIEW_ALPHA = 240;
@@ -833,10 +833,9 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
            // In transient state.
            return;
        }
        final int[] viewOrigin = CoordinateUtils.newInstance();
        getLocationInWindow(viewOrigin);
        getLocationInWindow(mOriginCoords);
        final DisplayMetrics dm = getResources().getDisplayMetrics();
        if (CoordinateUtils.y(viewOrigin) < dm.heightPixels / 4) {
        if (CoordinateUtils.y(mOriginCoords) < dm.heightPixels / 4) {
            // In transient state.
            return;
        }
@@ -851,11 +850,16 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
            Log.w(TAG, "Cannot find android.R.id.content view to add PreviewPlacerView");
        } else {
            windowContentView.addView(mPreviewPlacerView);
            mPreviewPlacerView.setKeyboardViewGeometry(
                    CoordinateUtils.x(viewOrigin), CoordinateUtils.y(viewOrigin), width, height);
            mPreviewPlacerView.setKeyboardViewGeometry(mOriginCoords, width, height);
        }
    }

    @Override
    public void showSlidingKeyInputPreview(final PointerTracker tracker) {
        locatePreviewPlacerView();
        mPreviewPlacerView.showSlidingKeyInputPreview(tracker);
    }

    public void showGestureFloatingPreviewText(final String gestureFloatingPreviewText) {
        locatePreviewPlacerView();
        mPreviewPlacerView.setGestureFloatingPreviewText(gestureFloatingPreviewText);
@@ -937,13 +941,13 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
        // The distance between the top edge of the parent key and the bottom of the visible part
        // of the key preview background.
        previewParams.mPreviewVisibleOffset = mPreviewOffset - previewText.getPaddingBottom();
        getLocationInWindow(mCoordinates);
        getLocationInWindow(mOriginCoords);
        // The key preview is horizontally aligned with the center of the visible part of the
        // parent key. If it doesn't fit in this {@link KeyboardView}, it is moved inward to fit and
        // the left/right background is used if such background is specified.
        final int statePosition;
        int previewX = key.getDrawX() - (previewWidth - keyDrawWidth) / 2
                + CoordinateUtils.x(mCoordinates);
                + CoordinateUtils.x(mOriginCoords);
        if (previewX < 0) {
            previewX = 0;
            statePosition = STATE_LEFT;
@@ -956,7 +960,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
        // The key preview is placed vertically above the top edge of the parent key with an
        // arbitrary offset.
        final int previewY = key.mY - previewHeight + mPreviewOffset
                + CoordinateUtils.y(mCoordinates);
                + CoordinateUtils.y(mOriginCoords);

        if (background != null) {
            final int hasMoreKeys = (key.mMoreKeys != null) ? STATE_HAS_MOREKEYS : STATE_NORMAL;
+11 −7
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@ import com.android.inputmethod.keyboard.PointerTracker.TimerProxy;
import com.android.inputmethod.keyboard.internal.KeyDrawParams;
import com.android.inputmethod.keyboard.internal.TouchScreenRegulator;
import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.CoordinateUtils;
import com.android.inputmethod.latin.DebugSettings;
import com.android.inputmethod.latin.LatinIME;
import com.android.inputmethod.latin.LatinImeLogger;
@@ -672,12 +673,14 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
        mMoreKeysPanel = moreKeysPanel;
        mMoreKeysPanelPointerTrackerId = tracker.mPointerId;

        final int[] lastCoords = CoordinateUtils.newInstance();
        tracker.getLastCoordinates(lastCoords);
        final boolean keyPreviewEnabled = isKeyPreviewPopupEnabled() && !parentKey.noKeyPreview();
        // The more keys keyboard is usually horizontally aligned with the center of the parent key.
        // If showMoreKeysKeyboardAtTouchedPoint is true and the key preview is disabled, the more
        // keys keyboard is placed at the touch point of the parent key.
        final int pointX = (mConfigShowMoreKeysKeyboardAtTouchedPoint && !keyPreviewEnabled)
                ? tracker.getLastX()
                ? CoordinateUtils.x(lastCoords)
                : parentKey.mX + parentKey.mWidth / 2;
        // The more keys keyboard is usually vertically aligned with the top edge of the parent key
        // (plus vertical gap). If the key preview is enabled, the more keys keyboard is vertically
@@ -687,8 +690,8 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
        final int pointY = parentKey.mY + mKeyPreviewDrawParams.mPreviewVisibleOffset;
        moreKeysPanel.showMoreKeysPanel(
                this, this, pointX, pointY, mMoreKeysWindow, mKeyboardActionListener);
        final int translatedX = moreKeysPanel.translateX(tracker.getLastX());
        final int translatedY = moreKeysPanel.translateY(tracker.getLastY());
        final int translatedX = moreKeysPanel.translateX(CoordinateUtils.x(lastCoords));
        final int translatedY = moreKeysPanel.translateY(CoordinateUtils.y(lastCoords));
        tracker.onShowMoreKeysPanel(translatedX, translatedY, moreKeysPanel);
        dimEntireKeyboard(true);
        return true;
@@ -788,10 +791,11 @@ public final class MainKeyboardView extends KeyboardView implements PointerTrack
            } else if (pointerCount == 2 && oldPointerCount == 1) {
                // Single-touch to multi-touch transition.
                // Send an up event for the last pointer.
                final int lastX = tracker.getLastX();
                final int lastY = tracker.getLastY();
                mOldKey = tracker.getKeyOn(lastX, lastY);
                tracker.onUpEvent(lastX, lastY, eventTime);
                final int[] lastCoords = CoordinateUtils.newInstance();
                mOldKey = tracker.getKeyOn(
                        CoordinateUtils.x(lastCoords), CoordinateUtils.y(lastCoords));
                tracker.onUpEvent(
                        CoordinateUtils.x(lastCoords), CoordinateUtils.y(lastCoords), eventTime);
            } else if (pointerCount == 1 && oldPointerCount == 1) {
                tracker.processMotionEvent(action, x, y, eventTime, this);
            } else {
+18 −7
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import com.android.inputmethod.keyboard.internal.GestureStrokeWithPreviewPoints;
import com.android.inputmethod.keyboard.internal.PointerTrackerQueue;
import com.android.inputmethod.latin.CollectionUtils;
import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.CoordinateUtils;
import com.android.inputmethod.latin.InputPointers;
import com.android.inputmethod.latin.LatinImeLogger;
import com.android.inputmethod.latin.R;
@@ -80,6 +81,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
        public void invalidateKey(Key key);
        public void showKeyPreview(PointerTracker tracker);
        public void dismissKeyPreview(PointerTracker tracker);
        public void showSlidingKeyInputPreview(PointerTracker tracker);
        public void showGesturePreviewTrail(PointerTracker tracker, boolean isOldestTracker);
    }

@@ -296,6 +298,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {

    // The position and time at which first down event occurred.
    private long mDownTime;
    private int[] mDownCoordinates = CoordinateUtils.newInstance();
    private long mUpTime;

    // The current key where this pointer is.
@@ -540,6 +543,10 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
        return mIsInSlidingKeyInput;
    }

    public boolean isInSlidingKeyInputFromModifier() {
        return mIsInSlidingKeyInputFromModifier;
    }

    public Key getKey() {
        return mCurrentKey;
    }
@@ -642,20 +649,21 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
        return mGestureStrokeWithPreviewPoints;
    }

    public int getLastX() {
        return mLastX;
    }

    public int getLastY() {
        return mLastY;
    public void getLastCoordinates(final int[] outCoords) {
        CoordinateUtils.set(outCoords, mLastX, mLastY);
    }

    public long getDownTime() {
        return mDownTime;
    }

    public void getDownCoordinates(final int[] outCoords) {
        CoordinateUtils.copy(outCoords, mDownCoordinates);
    }

    private Key onDownKey(final int x, final int y, final long eventTime) {
        mDownTime = eventTime;
        CoordinateUtils.set(mDownCoordinates, x, y);
        mBogusMoveEventDetector.onDownKey();
        return onMoveToNewKey(onMoveKeyInternal(x, y), x, y);
    }
@@ -867,6 +875,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
    private void resetSlidingKeyInput() {
        mIsInSlidingKeyInput = false;
        mIsInSlidingKeyInputFromModifier = false;
        mDrawingProxy.showSlidingKeyInputPreview(this);
    }

    private void onGestureMoveEvent(final int x, final int y, final long eventTime,
@@ -1061,6 +1070,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
                slideOutFromOldKey(oldKey, x, y);
            }
        }
        mDrawingProxy.showSlidingKeyInputPreview(this);
    }

    public void onUpEvent(final int x, final int y, final long eventTime) {
@@ -1087,7 +1097,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
    @Override
    public void onPhantomUpEvent(final long eventTime) {
        if (DEBUG_EVENT) {
            printTouchEvent("onPhntEvent:", getLastX(), getLastY(), eventTime);
            printTouchEvent("onPhntEvent:", mLastX, mLastY, eventTime);
        }
        onUpEventInternal(eventTime);
        cancelTracking();
@@ -1134,6 +1144,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element {
    }

    public void onLongPressed() {
        resetSlidingKeyInput();
        cancelTracking();
        setReleasedKeyGraphics(mCurrentKey);
        sPointerTrackerQueue.remove(this);
+41 −18
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ import android.widget.RelativeLayout;
import com.android.inputmethod.keyboard.PointerTracker;
import com.android.inputmethod.keyboard.internal.GesturePreviewTrail.Params;
import com.android.inputmethod.latin.CollectionUtils;
import com.android.inputmethod.latin.CoordinateUtils;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.StaticInnerHandlerWrapper;

@@ -47,8 +48,7 @@ public final class PreviewPlacerView extends RelativeLayout {
    private final float mGestureFloatingPreviewVerticalPadding;
    private final float mGestureFloatingPreviewRoundRadius;

    private int mKeyboardViewOriginX;
    private int mKeyboardViewOriginY;
    private final int[] mKeyboardViewOrigin = CoordinateUtils.newInstance();

    private final SparseArray<GesturePreviewTrail> mGesturePreviewTrails =
            CollectionUtils.newSparseArray();
@@ -68,11 +68,14 @@ public final class PreviewPlacerView extends RelativeLayout {
    private final int mGestureFloatingPreviewTextHeight;
    // {@link RectF} is needed for {@link Canvas#drawRoundRect(RectF, float, float, Paint)}.
    private final RectF mGestureFloatingPreviewRectangle = new RectF();
    private int mLastPointerX;
    private int mLastPointerY;
    private final int[] mLastPointerCoords = CoordinateUtils.newInstance();
    private static final char[] TEXT_HEIGHT_REFERENCE_CHAR = { 'M' };
    private boolean mDrawsGestureFloatingPreviewText;

    private boolean mShowSlidingKeyInputPreview;
    private final int[] mRubberBandFrom = CoordinateUtils.newInstance();
    private final int[] mRubberBandTo = CoordinateUtils.newInstance();

    private final DrawingHandler mDrawingHandler;

    private static final class DrawingHandler extends StaticInnerHandlerWrapper<PreviewPlacerView> {
@@ -168,9 +171,8 @@ public final class PreviewPlacerView extends RelativeLayout {
        setLayerType(LAYER_TYPE_HARDWARE, layerPaint);
    }

    public void setKeyboardViewGeometry(final int x, final int y, final int w, final int h) {
        mKeyboardViewOriginX = x;
        mKeyboardViewOriginY = y;
    public void setKeyboardViewGeometry(final int[] originCoords, final int w, final int h) {
        CoordinateUtils.copy(mKeyboardViewOrigin, originCoords);
        mOffscreenOffsetY = (int)(h * GestureStroke.EXTRA_GESTURE_TRAIL_AREA_ABOVE_KEYBOARD_RATIO);
        mOffscreenWidth = w;
        mOffscreenHeight = mOffscreenOffsetY + h;
@@ -186,8 +188,7 @@ public final class PreviewPlacerView extends RelativeLayout {
        final boolean needsToUpdateLastPointer =
                isOldestTracker && mDrawsGestureFloatingPreviewText;
        if (needsToUpdateLastPointer) {
            mLastPointerX = tracker.getLastX();
            mLastPointerY = tracker.getLastY();
            tracker.getLastCoordinates(mLastPointerCoords);
        }

        if (mDrawsGesturePreviewTrail) {
@@ -208,6 +209,17 @@ public final class PreviewPlacerView extends RelativeLayout {
        }
    }

    public void showSlidingKeyInputPreview(final PointerTracker tracker) {
        if (!tracker.isInSlidingKeyInputFromModifier()) {
            mShowSlidingKeyInputPreview = false;
            return;
        }
        tracker.getDownCoordinates(mRubberBandFrom);
        tracker.getLastCoordinates(mRubberBandTo);
        mShowSlidingKeyInputPreview = true;
        invalidate();
    }

    @Override
    protected void onDetachedFromWindow() {
        freeOffscreenBuffer();
@@ -234,6 +246,8 @@ public final class PreviewPlacerView extends RelativeLayout {
    @Override
    public void onDraw(final Canvas canvas) {
        super.onDraw(canvas);
        final int originX = CoordinateUtils.x(mKeyboardViewOrigin);
        final int originY = CoordinateUtils.y(mKeyboardViewOrigin);
        if (mDrawsGesturePreviewTrail) {
            mayAllocateOffscreenBuffer();
            // Draw gesture trails to offscreen buffer.
@@ -241,11 +255,11 @@ public final class PreviewPlacerView extends RelativeLayout {
                    mOffscreenCanvas, mGesturePaint, mOffscreenDirtyRect);
            // Transfer offscreen buffer to screen.
            if (!mOffscreenDirtyRect.isEmpty()) {
                final int offsetY = mKeyboardViewOriginY - mOffscreenOffsetY;
                canvas.translate(mKeyboardViewOriginX, offsetY);
                final int offsetY = originY - mOffscreenOffsetY;
                canvas.translate(originX, offsetY);
                canvas.drawBitmap(mOffscreenBuffer, mOffscreenDirtyRect, mOffscreenDirtyRect,
                        mGesturePaint);
                canvas.translate(-mKeyboardViewOriginX, -offsetY);
                canvas.translate(-originX, -offsetY);
                // Note: Defer clearing the dirty rectangle here because we will get cleared
                // rectangle on the canvas.
            }
@@ -254,9 +268,14 @@ public final class PreviewPlacerView extends RelativeLayout {
            }
        }
        if (mDrawsGestureFloatingPreviewText) {
            canvas.translate(mKeyboardViewOriginX, mKeyboardViewOriginY);
            canvas.translate(originX, originY);
            drawGestureFloatingPreviewText(canvas, mGestureFloatingPreviewText);
            canvas.translate(-mKeyboardViewOriginX, -mKeyboardViewOriginY);
            canvas.translate(-originX, -originY);
        }
        if (mShowSlidingKeyInputPreview) {
            canvas.translate(originX, originY);
            drawSlidingKeyInputPreview(canvas);
            canvas.translate(-originX, -originY);
        }
    }

@@ -317,8 +336,6 @@ public final class PreviewPlacerView extends RelativeLayout {

        final Paint paint = mTextPaint;
        final RectF rectangle = mGestureFloatingPreviewRectangle;
        // TODO: Figure out how we should deal with the floating preview text with multiple moving
        // fingers.

        // Paint the round rectangle background.
        final int textHeight = mGestureFloatingPreviewTextHeight;
@@ -328,9 +345,11 @@ public final class PreviewPlacerView extends RelativeLayout {
        final float rectWidth = textWidth + hPad * 2.0f;
        final float rectHeight = textHeight + vPad * 2.0f;
        final int canvasWidth = canvas.getWidth();
        final float rectX = Math.min(Math.max(mLastPointerX - rectWidth / 2.0f, 0.0f),
        final float rectX = Math.min(
                Math.max(CoordinateUtils.x(mLastPointerCoords) - rectWidth / 2.0f, 0.0f),
                canvasWidth - rectWidth);
        final float rectY = mLastPointerY - mGestureFloatingPreviewTextOffset - rectHeight;
        final float rectY = CoordinateUtils.y(mLastPointerCoords)
                - mGestureFloatingPreviewTextOffset - rectHeight;
        rectangle.set(rectX, rectY, rectX + rectWidth, rectY + rectHeight);
        final float round = mGestureFloatingPreviewRoundRadius;
        paint.setColor(mGestureFloatingPreviewColor);
@@ -341,4 +360,8 @@ public final class PreviewPlacerView extends RelativeLayout {
        final float textY = rectY + vPad + textHeight;
        canvas.drawText(gestureFloatingPreviewText, textX, textY, paint);
    }

    private void drawSlidingKeyInputPreview(final Canvas canvas) {
        // TODO: Implement rubber band preview
    }
}
+10 −0
Original line number Diff line number Diff line
@@ -36,4 +36,14 @@ public final class CoordinateUtils {
    public static int y(final int[] coords) {
        return coords[INDEX_Y];
    }

    public static void set(final int[] coords, final int x, final int y) {
        coords[INDEX_X] = x;
        coords[INDEX_Y] = y;
    }

    public static void copy(final int[] destination, final int[] source) {
        destination[INDEX_X] = source[INDEX_X];
        destination[INDEX_Y] = source[INDEX_Y];
    }
}