Refactor move and time de-bouncing codes into separate static class

This is the second one of three changes to fix the bug#2868304.

Bug: 2868304
Change-Id: I11a6d2e501888da98faf0c88c8d861c508d500fc
main
Tadashi G. Takaoka 2010-07-26 21:35:21 -07:00
parent 879b79be27
commit e55a9a170e
1 changed files with 124 additions and 63 deletions

View File

@ -177,8 +177,6 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener
private int mVerticalCorrection;
private int mProximityThreshold;
private int mKeyDebounceThreshold;
private static final int KEY_DEBOUNCE_FACTOR = 6;
private boolean mPreviewCentered = false;
private boolean mShowPreview = true;
@ -187,25 +185,18 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener
private int mPopupPreviewY;
private int mWindowY;
private int mLastX;
private int mLastY;
private int mStartX;
private int mStartY;
private boolean mProximityCorrectOn;
private Paint mPaint;
private Rect mPadding;
private long mDownTime;
private long mLastMoveTime;
private int mLastKey;
private int mLastCodeX;
private int mLastCodeY;
private int mCurrentKey = NOT_A_KEY;
private int mDownKey = NOT_A_KEY;
private long mLastKeyTime;
private long mCurrentKeyTime;
private int mStartX;
private int mStartY;
private KeyDebouncer mDebouncer;
private int[] mKeyIndices = new int[12];
private GestureDetector mGestureDetector;
private int mPopupX;
@ -328,6 +319,98 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener
}
};
static class KeyDebouncer {
// for move de-bouncing
private int mLastCodeX;
private int mLastCodeY;
private int mLastX;
private int mLastY;
// for time de-bouncing
private int mLastKey;
private long mLastKeyTime;
private long mLastMoveTime;
private long mCurrentKeyTime;
private int mKeyDebounceThreshold;
private static final int KEY_DEBOUNCE_FACTOR = 6;
KeyDebouncer(int proximityThreshold) {
// 1/KEY_DEBOUNCE_FACTOR of distance between adjacent keys
mKeyDebounceThreshold = proximityThreshold / KEY_DEBOUNCE_FACTOR;
}
public int getLastCodeX() {
return mLastCodeX;
}
public int getLastCodeY() {
return mLastCodeY;
}
public int getLastX() {
return mLastX;
}
public int getLastY() {
return mLastY;
}
public int getLastKey() {
return mLastKey;
}
public void startMoveDebouncing(int x, int y) {
mLastCodeX = x;
mLastCodeY = y;
}
public void updateMoveDebouncing(int x, int y) {
mLastX = x;
mLastY = y;
}
public void resetMoveDebouncing() {
mLastCodeX = mLastX;
mLastCodeY = mLastY;
}
public boolean isMinorMoveBounce(int x, int y, int keyIndex, int currentKey) {
// TODO: Check the coordinate against each key border. The current
// logic is pretty simple.
if (keyIndex == currentKey)
return true;
int dx = x - mLastCodeX;
int dy = y - mLastCodeY;
int delta = dx * dx + dy * dy;
return delta < mKeyDebounceThreshold;
}
public void startTimeDebouncing(long eventTime) {
mLastKey = NOT_A_KEY;
mLastKeyTime = 0;
mCurrentKeyTime = 0;
mLastMoveTime = eventTime;
}
public void updateTimeDebouncing(long eventTime) {
mCurrentKeyTime += eventTime - mLastMoveTime;
mLastMoveTime = eventTime;
}
public void resetTimeDebouncing(long eventTime, int currentKey) {
mLastKey = currentKey;
mLastKeyTime = mCurrentKeyTime + eventTime - mLastMoveTime;
mCurrentKeyTime = 0;
mLastMoveTime = eventTime;
}
public boolean isMinorTimeBounce() {
return mCurrentKeyTime < mLastKeyTime && mCurrentKeyTime < DEBOUNCE_TIME
&& mLastKey != NOT_A_KEY;
}
}
public LatinKeyboardBaseView(Context context, AttributeSet attrs) {
this(context, attrs, R.attr.keyboardViewStyle);
}
@ -683,8 +766,7 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener
mProximityThreshold = (int) (dimensionSum * 1.4f / length);
mProximityThreshold *= mProximityThreshold; // Square it
// 1/KEY_DEBOUNCE_FACTOR of distance between adjacent keys
mKeyDebounceThreshold = mProximityThreshold / KEY_DEBOUNCE_FACTOR;
mDebouncer = new KeyDebouncer(mProximityThreshold);
}
@Override
@ -804,14 +886,16 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener
if (DEBUG) {
if (mShowTouchPoints) {
int lastX = mDebouncer.getLastX();
int lastY = mDebouncer.getLastY();
paint.setAlpha(128);
paint.setColor(0xFFFF0000);
canvas.drawCircle(mStartX, mStartY, 3, paint);
canvas.drawLine(mStartX, mStartY, mLastX, mLastY, paint);
canvas.drawLine(mStartX, mStartY, lastX, lastY, paint);
paint.setColor(0xFF0000FF);
canvas.drawCircle(mLastX, mLastY, 3, paint);
canvas.drawCircle(lastX, lastY, 3, paint);
paint.setColor(0xFF00FF00);
canvas.drawCircle((mStartX + mLastX) / 2, (mStartY + mLastY) / 2, 2, paint);
canvas.drawCircle((mStartX + lastX) / 2, (mStartY + lastY) / 2, 2, paint);
}
}
@ -1206,13 +1290,6 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener
return result;
}
private boolean isMinorMoveForKeyDebounce(int x, int y) {
// TODO: Check the coordinate against each key border. The current
// logic is pretty simple.
return ((x - mLastCodeX) * (x - mLastCodeX) +
(y - mLastCodeY) * (y - mLastCodeY)) < mKeyDebounceThreshold;
}
private boolean onModifiedTouchEvent(MotionEvent me, boolean possiblePoly) {
int touchX = (int) me.getX() - getPaddingLeft();
int touchY = (int) me.getY() + mVerticalCorrection - getPaddingTop();
@ -1246,17 +1323,12 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener
switch (action) {
case MotionEvent.ACTION_DOWN:
mAbortKey = false;
mStartX = touchX;
mStartY = touchY;
mLastCodeX = touchX;
mLastCodeY = touchY;
mLastKeyTime = 0;
mCurrentKeyTime = 0;
mLastKey = NOT_A_KEY;
mCurrentKey = keyIndex;
mDownKey = keyIndex;
mDownTime = me.getEventTime();
mLastMoveTime = mDownTime;
mStartX = touchX;
mStartY = touchY;
mDebouncer.startMoveDebouncing(touchX, touchY);
mDebouncer.startTimeDebouncing(eventTime);
checkMultiTap(eventTime, keyIndex);
mKeyboardActionListener.onPress(keyIndex != NOT_A_KEY ?
mKeys[keyIndex].codes[0] : 0);
@ -1281,22 +1353,16 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener
if (keyIndex != NOT_A_KEY) {
if (mCurrentKey == NOT_A_KEY) {
mCurrentKey = keyIndex;
mCurrentKeyTime = eventTime - mDownTime;
} else {
if (keyIndex == mCurrentKey
|| isMinorMoveForKeyDebounce(touchX, touchY)) {
mCurrentKeyTime += eventTime - mLastMoveTime;
continueLongPress = true;
} else if (mRepeatKeyIndex == NOT_A_KEY) {
resetMultiTap();
mLastKey = mCurrentKey;
mLastCodeX = mLastX;
mLastCodeY = mLastY;
mLastKeyTime =
mCurrentKeyTime + eventTime - mLastMoveTime;
mCurrentKey = keyIndex;
mCurrentKeyTime = 0;
}
mDebouncer.updateTimeDebouncing(eventTime);
} else if (mDebouncer.isMinorMoveBounce(touchX, touchY,
keyIndex, mCurrentKey)) {
mDebouncer.updateTimeDebouncing(eventTime);
continueLongPress = true;
} else if (mRepeatKeyIndex == NOT_A_KEY) {
resetMultiTap();
mDebouncer.resetTimeDebouncing(eventTime, mCurrentKey);
mDebouncer.resetMoveDebouncing();
mCurrentKey = keyIndex;
}
}
if (!continueLongPress) {
@ -1308,25 +1374,21 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener
}
}
showPreview(mCurrentKey);
mLastMoveTime = eventTime;
break;
case MotionEvent.ACTION_UP:
mHandler.cancelKeyTimersAndPopupPreview();
if (keyIndex == mCurrentKey) {
mCurrentKeyTime += eventTime - mLastMoveTime;
mDebouncer.updateTimeDebouncing(eventTime);
} else {
resetMultiTap();
mLastKey = mCurrentKey;
mLastKeyTime = mCurrentKeyTime + eventTime - mLastMoveTime;
mDebouncer.resetTimeDebouncing(eventTime, mCurrentKey);
mCurrentKey = keyIndex;
mCurrentKeyTime = 0;
}
if (mCurrentKeyTime < mLastKeyTime && mCurrentKeyTime < DEBOUNCE_TIME
&& mLastKey != NOT_A_KEY) {
mCurrentKey = mLastKey;
touchX = mLastCodeX;
touchY = mLastCodeY;
if (mDebouncer.isMinorTimeBounce()) {
mCurrentKey = mDebouncer.getLastKey();
touchX = mDebouncer.getLastCodeX();
touchY = mDebouncer.getLastCodeY();
}
showPreview(NOT_A_KEY);
Arrays.fill(mKeyIndices, NOT_A_KEY);
@ -1345,8 +1407,7 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener
invalidateKey(mCurrentKey);
break;
}
mLastX = touchX;
mLastY = touchY;
mDebouncer.updateMoveDebouncing(touchX, touchY);
return true;
}