From 06123e56912b5dcd7aca3d0c18c7ceb1f1cde573 Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Fri, 27 Aug 2010 21:23:51 +0900 Subject: [PATCH] Don't re-allocate KeyDebouncer when keyboard is switched. This change also re-orders instance variables and eliminates unnecessary ones. Bug: 2910379 Change-Id: I6b2217f75738fada32a33f59f0f7adba5e99dd6e --- .../latin/LatinKeyboardBaseView.java | 188 +++++++++--------- 1 file changed, 94 insertions(+), 94 deletions(-) diff --git a/java/src/com/android/inputmethod/latin/LatinKeyboardBaseView.java b/java/src/com/android/inputmethod/latin/LatinKeyboardBaseView.java index 4007c2b55..95794f7cc 100644 --- a/java/src/com/android/inputmethod/latin/LatinKeyboardBaseView.java +++ b/java/src/com/android/inputmethod/latin/LatinKeyboardBaseView.java @@ -17,6 +17,7 @@ package com.android.inputmethod.latin; import android.content.Context; +import android.content.res.Resources; import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.Canvas; @@ -61,6 +62,9 @@ import java.util.Map; * @attr ref R.styleable#LatinKeyboardBaseView_popupLayout */ public class LatinKeyboardBaseView extends View implements View.OnClickListener { + private static final boolean DEBUG = false; + + public static final int NOT_A_TOUCH_COORDINATE = -1; public interface OnKeyboardActionListener { @@ -139,29 +143,54 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener void swipeUp(); } - public static final int NOT_A_TOUCH_COORDINATE = -1; + // Timing constants + private static final int DELAY_BEFORE_PREVIEW = 0; + private static final int DELAY_AFTER_PREVIEW = 70; + private static final int REPEAT_INTERVAL = 50; // ~20 keys per second + private static final int REPEAT_START_DELAY = 400; + private static final int LONGPRESS_TIMEOUT = ViewConfiguration.getLongPressTimeout(); + private static final int MULTITAP_INTERVAL = 800; // milliseconds + private static final int KEY_DEBOUNCE_TIME = 70; - private static final boolean DEBUG = false; + // Miscellaneous constants static final int NOT_A_KEY = -1; private static final int[] KEY_DELETE = { Keyboard.KEYCODE_DELETE }; private static final int[] LONG_PRESSABLE_STATE_SET = { android.R.attr.state_long_pressable }; - private Keyboard mKeyboard; - private int mCurrentKeyIndex = NOT_A_KEY; - private int mLabelTextSize; + // XML attribute private int mKeyTextSize; private int mKeyTextColor; - private float mShadowRadius; + private Typeface mKeyTextStyle = Typeface.DEFAULT; + private int mLabelTextSize; + private int mSymbolColorScheme = 0; private int mShadowColor; + private float mShadowRadius; + private Drawable mKeyBackground; private float mBackgroundDimAmount; + private int mVerticalCorrection; + private int mPreviewOffset; + private int mPreviewHeight; + private int mPopupLayout; + // Main keyboard + private Keyboard mKeyboard; + private Key[] mKeys; + + // Key preview popup + private final static boolean PREVIEW_CENTERED = false; private TextView mPreviewText; private PopupWindow mPreviewPopup; private int mPreviewTextSizeLarge; - private int mPreviewOffset; - private int mPreviewHeight; private int[] mOffsetInWindow; + private int mOldPreviewKeyIndex = NOT_A_KEY; + private boolean mShowPreview = true; + private boolean mShowTouchPoints = true; + private int mPopupPreviewX; + private int mPopupPreviewY; + private int mWindowY; + private final StringBuilder mPreviewLabel = new StringBuilder(1); + // Popup mini keyboard private PopupWindow mPopupKeyboard; private View mMiniKeyboardContainer; private LatinKeyboardBaseView mMiniKeyboard; @@ -171,78 +200,54 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener private int mMiniKeyboardOffsetY; private Map mMiniKeyboardCache; private int[] mWindowOffset; - private Key[] mKeys; - private Typeface mKeyTextStyle = Typeface.DEFAULT; - private int mSymbolColorScheme = 0; /** Listener for {@link OnKeyboardActionListener}. */ private OnKeyboardActionListener mKeyboardActionListener; - private static final int DELAY_BEFORE_PREVIEW = 0; - private static final int DELAY_AFTER_PREVIEW = 70; - private static final int DEBOUNCE_TIME = 70; - - private int mVerticalCorrection; - private ProximityKeyDetector mProximityKeyDetector = new ProximityKeyDetector(); - - private boolean mPreviewCentered = false; - private boolean mShowPreview = true; - private boolean mShowTouchPoints = true; - private int mPopupPreviewX; - private int mPopupPreviewY; - private int mWindowY; - - private Paint mPaint; - private Rect mPadding; - + private final KeyDebouncer mDebouncer = new KeyDebouncer(); + private final float mDebounceHysteresis; private int mCurrentKey = NOT_A_KEY; private int mStartX; private int mStartY; - private KeyDebouncer mDebouncer; + private final ProximityKeyDetector mProximityKeyDetector = new ProximityKeyDetector(); - private GestureDetector mGestureDetector; - private int mPopupX; - private int mPopupY; - private int mPopupLayout; private boolean mAbortKey; - private Key mInvalidatedKey; - private Rect mClipRegion = new Rect(0, 0, 0, 0); - private SwipeTracker mSwipeTracker = new SwipeTracker(); - private int mSwipeThreshold; - private boolean mDisambiguateSwipe; - - // Variables for dealing with multiple pointers - private int mOldPointerCount = 1; - private int mOldPointerX; - private int mOldPointerY; - - private Drawable mKeyBackground; - - private static final int REPEAT_INTERVAL = 50; // ~20 keys per second - private static final int REPEAT_START_DELAY = 400; - private static final int LONGPRESS_TIMEOUT = ViewConfiguration.getLongPressTimeout(); // For multi-tap private int mLastSentIndex; private int mTapCount; private long mLastTapTime; private boolean mInMultiTap; - private static final int MULTITAP_INTERVAL = 800; // milliseconds - private StringBuilder mPreviewLabel = new StringBuilder(1); + // Variables for dealing with multiple pointers + private int mOldPointerCount = 1; + private int mOldPointerX; + private int mOldPointerY; + + // Swipe gesture detector + private final GestureDetector mGestureDetector; + private final SwipeTracker mSwipeTracker = new SwipeTracker(); + private final int mSwipeThreshold; + private final boolean mDisambiguateSwipe; + + // Drawing /** Whether the keyboard bitmap needs to be redrawn before it's blitted. **/ private boolean mDrawPending; /** The dirty region in the keyboard bitmap */ - private Rect mDirtyRect = new Rect(); + private final Rect mDirtyRect = new Rect(); /** The keyboard bitmap for faster updates */ private Bitmap mBuffer; /** Notes if the keyboard just changed, so that we could possibly reallocate the mBuffer. */ private boolean mKeyboardChanged; + private Key mInvalidatedKey; /** The canvas for the above mutable keyboard bitmap */ private Canvas mCanvas; + private final Paint mPaint; + private final Rect mPadding; + private final Rect mClipRegion = new Rect(0, 0, 0, 0); - UIHandler mHandler = new UIHandler(); + private final UIHandler mHandler = new UIHandler(); class UIHandler extends Handler { private static final int MSG_POPUP_PREVIEW = 1; @@ -324,8 +329,8 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener }; static class KeyDebouncer { - private final Key[] mKeys; - private final int mKeyDebounceThresholdSquared; + private Key[] mKeys; + private int mKeyDebounceThresholdSquared = -1; // for move de-bouncing private int mLastCodeX; @@ -339,7 +344,7 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener private long mLastMoveTime; private long mCurrentKeyTime; - KeyDebouncer(Key[] keys, float hysteresisPixel) { + public void setKeyboard(Key[] keys, float hysteresisPixel) { if (keys == null || hysteresisPixel < 1.0f) throw new IllegalArgumentException(); mKeys = keys; @@ -382,6 +387,8 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener } public boolean isMinorMoveBounce(int x, int y, int newKey, int curKey) { + if (mKeys == null || mKeyDebounceThresholdSquared < 0) + throw new IllegalStateException("keyboard and/or hysteresis not set"); if (newKey == curKey) { return true; } else if (curKey >= 0 && curKey < mKeys.length) { @@ -424,7 +431,7 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener } public boolean isMinorTimeBounce() { - return mCurrentKeyTime < mLastKeyTime && mCurrentKeyTime < DEBOUNCE_TIME + return mCurrentKeyTime < mLastKeyTime && mCurrentKeyTime < KEY_DEBOUNCE_TIME && mLastKey != NOT_A_KEY; } } @@ -516,15 +523,11 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener } else { mShowPreview = false; } - mPreviewPopup.setTouchable(false); + mPopupParent = this; mPopupKeyboard = new PopupWindow(context); mPopupKeyboard.setBackgroundDrawable(null); - //mPopupKeyboard.setClippingEnabled(false); - - mPopupParent = this; - //mPredicting = true; mPaint = new Paint(); mPaint.setAntiAlias(true); @@ -536,19 +539,18 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener mMiniKeyboardCache = new HashMap(); mKeyBackground.getPadding(mPadding); - mSwipeThreshold = (int) (500 * getResources().getDisplayMetrics().density); + final Resources res = getResources(); + mSwipeThreshold = (int) (500 * res.getDisplayMetrics().density); // TODO: Refer frameworks/base/core/res/res/values/config.xml - mDisambiguateSwipe = getResources().getBoolean(R.bool.config_swipeDisambiguation); + mDisambiguateSwipe = res.getBoolean(R.bool.config_swipeDisambiguation); + mDebounceHysteresis = res.getDimension(R.dimen.key_debounce_hysteresis_distance); resetMultiTap(); - initGestureDetector(); - } - private void initGestureDetector() { GestureDetector.SimpleOnGestureListener listener = new GestureDetector.SimpleOnGestureListener() { @Override - public boolean onFling(MotionEvent me1, MotionEvent me2, - float velocityX, float velocityY) { + public boolean onFling(MotionEvent me1, MotionEvent me2, float velocityX, + float velocityY) { final float absX = Math.abs(velocityX); final float absY = Math.abs(velocityY); float deltaX = me2.getX() - me1.getX(); @@ -619,6 +621,7 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener List keys = mKeyboard.getKeys(); mKeys = keys.toArray(new Key[keys.size()]); mProximityKeyDetector.setKeyboard(keyboard, mKeys); + mDebouncer.setKeyboard(mKeys, mDebounceHysteresis); requestLayout(); // Hint to reallocate the buffer if the size changed mKeyboardChanged = true; @@ -773,10 +776,6 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener } if (dimensionSum < 0 || length == 0) return; mProximityKeyDetector.setProximityThreshold((int) (dimensionSum * 1.4f / length)); - - final float hysteresisPixel = getContext().getResources() - .getDimension(R.dimen.key_debounce_hysteresis_distance); - mDebouncer = new KeyDebouncer(keys, hysteresisPixel); } @Override @@ -966,24 +965,26 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener } private void showPreview(int keyIndex) { - int oldKeyIndex = mCurrentKeyIndex; - final PopupWindow previewPopup = mPreviewPopup; + int oldKeyIndex = mOldPreviewKeyIndex; + mOldPreviewKeyIndex = keyIndex; - mCurrentKeyIndex = keyIndex; // Release the old key and press the new key final Key[] keys = mKeys; - if (oldKeyIndex != mCurrentKeyIndex) { + if (oldKeyIndex != keyIndex) { if (oldKeyIndex != NOT_A_KEY && keys.length > oldKeyIndex) { - keys[oldKeyIndex].onReleased(mCurrentKeyIndex == NOT_A_KEY); + // if new key index is not a key, old key was just released inside of the key. + final boolean inside = (keyIndex == NOT_A_KEY); + keys[oldKeyIndex].onReleased(inside); invalidateKey(oldKeyIndex); } - if (mCurrentKeyIndex != NOT_A_KEY && keys.length > mCurrentKeyIndex) { - keys[mCurrentKeyIndex].onPressed(); - invalidateKey(mCurrentKeyIndex); + if (keyIndex != NOT_A_KEY && keys.length > keyIndex) { + keys[keyIndex].onPressed(); + invalidateKey(keyIndex); } } // If key changed and preview is on ... - if (oldKeyIndex != mCurrentKeyIndex && mShowPreview) { + if (oldKeyIndex != keyIndex && mShowPreview) { + final PopupWindow previewPopup = mPreviewPopup; if (keyIndex == NOT_A_KEY) { mHandler.cancelPopupPreview(); if (previewPopup.isShowing()) { @@ -1030,13 +1031,13 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener lp.width = popupWidth; lp.height = popupHeight; } - if (!mPreviewCentered) { - mPopupPreviewX = key.x - mPreviewText.getPaddingLeft() + getPaddingLeft(); - mPopupPreviewY = key.y - popupHeight + mPreviewOffset; - } else { + if (PREVIEW_CENTERED) { // TODO: Fix this if centering is brought back mPopupPreviewX = 160 - mPreviewText.getMeasuredWidth() / 2; mPopupPreviewY = - mPreviewText.getMeasuredHeight(); + } else { + mPopupPreviewX = key.x - mPreviewText.getPaddingLeft() + getPaddingLeft(); + mPopupPreviewY = key.y - popupHeight + mPreviewOffset; } mHandler.cancelDismissPreview(); if (mOffsetInWindow == null) { @@ -1147,8 +1148,7 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener mMiniKeyboardContainer = inflater.inflate(mPopupLayout, null); mMiniKeyboard = (LatinKeyboardBaseView) mMiniKeyboardContainer.findViewById( R.id.LatinKeyboardBaseView); - View closeButton = mMiniKeyboardContainer.findViewById( - R.id.closeButton); + View closeButton = mMiniKeyboardContainer.findViewById(R.id.closeButton); if (closeButton != null) closeButton.setOnClickListener(this); mMiniKeyboard.setOnKeyboardActionListener(new OnKeyboardActionListener() { public void onKey(int primaryCode, int[] keyCodes, int x, int y) { @@ -1195,12 +1195,12 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener mWindowOffset = new int[2]; getLocationInWindow(mWindowOffset); } - mPopupX = popupKey.x + getPaddingLeft(); - mPopupY = popupKey.y + getPaddingTop(); - mPopupX = mPopupX + popupKey.width - mMiniKeyboardContainer.getMeasuredWidth(); - mPopupY = mPopupY - mMiniKeyboardContainer.getMeasuredHeight(); - final int x = mPopupX + mMiniKeyboardContainer.getPaddingRight() + mWindowOffset[0]; - final int y = mPopupY + mMiniKeyboardContainer.getPaddingBottom() + mWindowOffset[1]; + int popupX = popupKey.x + 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); mMiniKeyboard.setShifted(isShifted()); mPopupKeyboard.setContentView(mMiniKeyboardContainer);