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

Commit 07221a4a authored by Tadashi G. Takaoka's avatar Tadashi G. Takaoka
Browse files

Support sliding pop-up mini-keyboard input

TODO:
- Remove close button on mini-keyboard
- Dismiss mini-keyboard when finger leave the screen while no key is selected

This change also renames some instance variables to have more meaningful name.

Bug: 2959169
Change-Id: I9fd79116a647d7be82415c6e9e7cdaf6edcb2bf6
parent f0fd5065
Loading
Loading
Loading
Loading
+55 −29
Original line number Diff line number Diff line
@@ -185,17 +185,20 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener,
    private boolean mShowTouchPoints = true;
    private int mPopupPreviewX;
    private int mPopupPreviewY;
    private int mPopupPreviewOffsetX;
    private int mPopupPreviewOffsetY;
    private int mWindowY;

    // Popup mini keyboard
    private PopupWindow mPopupKeyboard;
    private PopupWindow mMiniKeyboardPopup;
    private View mMiniKeyboardContainer;
    private LatinKeyboardBaseView mMiniKeyboard;
    private boolean mMiniKeyboardOnScreen;
    private View mPopupParent;
    private int mMiniKeyboardOffsetX;
    private int mMiniKeyboardOffsetY;
    private View mMiniKeyboardParent;
    private Map<Key,View> mMiniKeyboardCache;
    private int mMiniKeyboardOriginX;
    private int mMiniKeyboardOriginY;
    private long mMiniKeyboardPopupTime;
    private int[] mWindowOffset;

    /** Listener for {@link OnKeyboardActionListener}. */
@@ -445,10 +448,10 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener,
            mShowPreview = false;
        }
        mPreviewPopup.setTouchable(false);
        mPopupParent = this;
        mMiniKeyboardParent = this;

        mPopupKeyboard = new PopupWindow(context);
        mPopupKeyboard.setBackgroundDrawable(null);
        mMiniKeyboardPopup = new PopupWindow(context);
        mMiniKeyboardPopup.setBackgroundDrawable(null);

        mPaint = new Paint();
        mPaint.setAntiAlias(true);
@@ -615,12 +618,12 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener,
    }

    public void setPopupParent(View v) {
        mPopupParent = v;
        mMiniKeyboardParent = v;
    }

    public void setPopupOffset(int x, int y) {
        mMiniKeyboardOffsetX = x;
        mMiniKeyboardOffsetY = y;
        mPopupPreviewOffsetX = x;
        mPopupPreviewOffsetY = y;
        if (mPreviewPopup.isShowing()) {
            mPreviewPopup.dismiss();
        }
@@ -896,8 +899,8 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener,
        if (mOffsetInWindow == null) {
            mOffsetInWindow = new int[2];
            getLocationInWindow(mOffsetInWindow);
            mOffsetInWindow[0] += mMiniKeyboardOffsetX; // Offset may be zero
            mOffsetInWindow[1] += mMiniKeyboardOffsetY; // Offset may be zero
            mOffsetInWindow[0] += mPopupPreviewOffsetX; // Offset may be zero
            mOffsetInWindow[1] += mPopupPreviewOffsetY; // Offset may be zero
            int[] mWindowLocation = new int[2];
            getLocationOnScreen(mWindowLocation);
            mWindowY = mWindowLocation[1];
@@ -926,7 +929,7 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener,
        } else {
            previewPopup.setWidth(popupWidth);
            previewPopup.setHeight(popupHeight);
            previewPopup.showAtLocation(mPopupParent, Gravity.NO_GRAVITY,
            previewPopup.showAtLocation(mMiniKeyboardParent, Gravity.NO_GRAVITY,
                    mPopupPreviewX, mPopupPreviewY);
        }
        mPreviewText.setVisibility(VISIBLE);
@@ -974,6 +977,13 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener,
        boolean result = onLongPress(popupKey);
        if (result) {
            dismissKeyPreview();

            long eventTime = tracker.getDownTime();
            mMiniKeyboardPopupTime = eventTime;
            MotionEvent downEvent = generateMiniKeyboardMotionEvent(MotionEvent.ACTION_DOWN,
                    tracker.getLastX(), tracker.getLastY(), eventTime);
            mMiniKeyboard.onTouchEvent(downEvent);
            downEvent.recycle();
        }
        return result;
    }
@@ -1020,7 +1030,7 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener,
                        mKeyboardActionListener.onRelease(primaryCode);
                    }
                });
                //mInputView.setSuggest(mSuggest);

                Keyboard keyboard;
                if (popupKey.popupCharacters != null) {
                    keyboard = new Keyboard(getContext(), popupKeyboardId,
@@ -1043,20 +1053,25 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener,
                mWindowOffset = new int[2];
                getLocationInWindow(mWindowOffset);
            }
            int popupX = popupKey.x + getPaddingLeft();
            int popupX = popupKey.x + popupKey.width + getPaddingLeft();
            int popupY = popupKey.y + getPaddingTop();
            popupX = popupX + popupKey.width - mMiniKeyboardContainer.getMeasuredWidth();
            popupY = popupY - mMiniKeyboardContainer.getMeasuredHeight();
            final int x = popupX + mMiniKeyboardContainer.getPaddingRight() + mWindowOffset[0];
            final int y = popupY + mMiniKeyboardContainer.getPaddingBottom() + mWindowOffset[1];
            mMiniKeyboard.setPopupOffset(x < 0 ? 0 : x, y);
            popupX -= mMiniKeyboardContainer.getMeasuredWidth();
            popupY -= mMiniKeyboardContainer.getMeasuredHeight();
            popupX += mWindowOffset[0];
            popupY += mWindowOffset[1];
            final int x = popupX + mMiniKeyboardContainer.getPaddingRight();
            final int y = popupY + mMiniKeyboardContainer.getPaddingBottom();
            mMiniKeyboardOriginX = (x < 0 ? 0 : x) + mMiniKeyboardContainer.getPaddingLeft();
            mMiniKeyboardOriginY = y + mMiniKeyboardContainer.getPaddingTop();
            mMiniKeyboard.setPopupOffset((x < 0) ? 0 : x, y);
            mMiniKeyboard.setShifted(isShifted());
            mPopupKeyboard.setContentView(mMiniKeyboardContainer);
            mPopupKeyboard.setWidth(mMiniKeyboardContainer.getMeasuredWidth());
            mPopupKeyboard.setHeight(mMiniKeyboardContainer.getMeasuredHeight());
            mPopupKeyboard.showAtLocation(this, Gravity.NO_GRAVITY, x, y);
            mMiniKeyboardPopup.setContentView(mMiniKeyboardContainer);
            mMiniKeyboardPopup.setWidth(mMiniKeyboardContainer.getMeasuredWidth());
            mMiniKeyboardPopup.setHeight(mMiniKeyboardContainer.getMeasuredHeight());
            mMiniKeyboardPopup.showAtLocation(this, Gravity.NO_GRAVITY, x, y);
            mMiniKeyboardOnScreen = true;
            //mMiniKeyboard.onTouchEvent(getTranslatedEvent(me));

            // TODO: down event?
            invalidateAllKeys();
            return true;
        }
@@ -1068,6 +1083,11 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener,
        return mMiniKeyboardOnScreen;
    }

    private MotionEvent generateMiniKeyboardMotionEvent(int action, int x, int y, long eventTime) {
        return MotionEvent.obtain(mMiniKeyboardPopupTime, eventTime, action,
                x - mMiniKeyboardOriginX, y - mMiniKeyboardOriginY, 0);
    }

    private PointerTracker getPointerTracker(final int id) {
        final ArrayList<PointerTracker> pointers = mPointerTrackers;
        final Key[] keys = mKeys;
@@ -1105,7 +1125,11 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener,

        // Needs to be called after the gesture detector gets a turn, as it may have
        // displayed the mini keyboard
        if (mMiniKeyboardOnScreen && action != MotionEvent.ACTION_CANCEL) {
        if (mMiniKeyboardOnScreen) {
            MotionEvent translated = generateMiniKeyboardMotionEvent(action, (int)me.getX(),
                    (int)me.getY(), eventTime);
            mMiniKeyboard.onTouchEvent(translated);
            translated.recycle();
            return true;
        }

@@ -1209,15 +1233,17 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener,
    }

    public void dismissPopupKeyboard() {
        if (mPopupKeyboard.isShowing()) {
            mPopupKeyboard.dismiss();
        if (mMiniKeyboardPopup.isShowing()) {
            mMiniKeyboardPopup.dismiss();
            mMiniKeyboardOnScreen = false;
            mMiniKeyboardOriginX = 0;
            mMiniKeyboardOriginY = 0;
            invalidateAllKeys();
        }
    }

    public boolean handleBack() {
        if (mPopupKeyboard.isShowing()) {
        if (mMiniKeyboardPopup.isShowing()) {
            dismissPopupKeyboard();
            return true;
        }
+19 −1
Original line number Diff line number Diff line
@@ -61,6 +61,7 @@ public class PointerTracker {
    private int mCurrentKey = NOT_A_KEY;
    private int mStartX;
    private int mStartY;
    private long mDownTime;

    // for move de-bouncing
    private int mLastCodeX;
@@ -144,6 +145,7 @@ public class PointerTracker {
        mCurrentKey = keyIndex;
        mStartX = x;
        mStartY = y;
        mDownTime = eventTime;
        startMoveDebouncing(x, y);
        startTimeDebouncing(eventTime);
        checkMultiTap(eventTime, keyIndex);
@@ -181,8 +183,20 @@ public class PointerTracker {
                mHandler.startLongPressTimer(LONGPRESS_TIMEOUT, keyIndex, this);
            }
        } else {
            if (mCurrentKey != NOT_A_KEY) {
                updateTimeDebouncing(eventTime);
                mCurrentKey = keyIndex;
                mHandler.cancelLongPressTimer();
            } else if (isMinorMoveBounce(x, y, keyIndex, mCurrentKey)) {
                updateTimeDebouncing(eventTime);
            } else {
                resetMultiTap();
                resetTimeDebouncing(eventTime, mCurrentKey);
                resetMoveDebouncing();
                mCurrentKey = keyIndex;
                mHandler.cancelLongPressTimer();
            }
        }
        /*
         * While time debouncing is in effect, mCurrentKey holds the new key and this tracker
         * holds the last key.  At ACTION_UP event if time debouncing will be in effect
@@ -252,6 +266,10 @@ public class PointerTracker {
        return mLastY;
    }

    public long getDownTime() {
        return mDownTime;
    }

    // These package scope methods are only for debugging purpose.
    /* package */ int getStartX() {
        return mStartX;