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
This commit is contained in:
Tadashi G. Takaoka 2010-07-26 21:35:21 -07:00
parent 879b79be27
commit e55a9a170e

View File

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