Encapsulate vertical and horizontal correction values into KeyDetector.
Bug: 2959169 Change-Id: Id2b0b974fffdf6f09ee1828e957b973d2ce1c315main
parent
6b4d521fb4
commit
400046d62e
|
@ -25,12 +25,16 @@ abstract class KeyDetector {
|
||||||
protected Keyboard mKeyboard;
|
protected Keyboard mKeyboard;
|
||||||
protected Key[] mKeys;
|
protected Key[] mKeys;
|
||||||
|
|
||||||
|
protected int mCorrectionX;
|
||||||
|
protected int mCorrectionY;
|
||||||
protected boolean mProximityCorrectOn;
|
protected boolean mProximityCorrectOn;
|
||||||
protected int mProximityThresholdSquare;
|
protected int mProximityThresholdSquare;
|
||||||
|
|
||||||
public Key[] setKeyboard(Keyboard keyboard) {
|
public Key[] setKeyboard(Keyboard keyboard, float correctionX, float correctionY) {
|
||||||
if (keyboard == null)
|
if (keyboard == null)
|
||||||
throw new NullPointerException();
|
throw new NullPointerException();
|
||||||
|
mCorrectionX = (int)correctionX;
|
||||||
|
mCorrectionY = (int)correctionY;
|
||||||
mKeyboard = keyboard;
|
mKeyboard = keyboard;
|
||||||
List<Key> keys = mKeyboard.getKeys();
|
List<Key> keys = mKeyboard.getKeys();
|
||||||
Key[] array = keys.toArray(new Key[keys.size()]);
|
Key[] array = keys.toArray(new Key[keys.size()]);
|
||||||
|
@ -38,6 +42,14 @@ abstract class KeyDetector {
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected int getTouchX(int x) {
|
||||||
|
return x + mCorrectionX;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int getTouchY(int y) {
|
||||||
|
return y + mCorrectionY;
|
||||||
|
}
|
||||||
|
|
||||||
public void setProximityCorrectionEnabled(boolean enabled) {
|
public void setProximityCorrectionEnabled(boolean enabled) {
|
||||||
mProximityCorrectOn = enabled;
|
mProximityCorrectOn = enabled;
|
||||||
}
|
}
|
||||||
|
|
|
@ -165,7 +165,7 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener,
|
||||||
private float mShadowRadius;
|
private float mShadowRadius;
|
||||||
private Drawable mKeyBackground;
|
private Drawable mKeyBackground;
|
||||||
private float mBackgroundDimAmount;
|
private float mBackgroundDimAmount;
|
||||||
private int mVerticalCorrection;
|
private float mVerticalCorrection;
|
||||||
private int mPreviewOffset;
|
private int mPreviewOffset;
|
||||||
private int mPreviewHeight;
|
private int mPreviewHeight;
|
||||||
private int mPopupLayout;
|
private int mPopupLayout;
|
||||||
|
@ -541,7 +541,8 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener,
|
||||||
mHandler.cancelPopupPreview();
|
mHandler.cancelPopupPreview();
|
||||||
mKeyboard = keyboard;
|
mKeyboard = keyboard;
|
||||||
LatinImeLogger.onSetKeyboard(keyboard);
|
LatinImeLogger.onSetKeyboard(keyboard);
|
||||||
mKeys = mKeyDetector.setKeyboard(keyboard);
|
mKeys = mKeyDetector.setKeyboard(keyboard, -getPaddingLeft(),
|
||||||
|
-getPaddingTop() + mVerticalCorrection);
|
||||||
for (PointerTracker tracker : mPointerTrackers) {
|
for (PointerTracker tracker : mPointerTrackers) {
|
||||||
tracker.setKeyboard(mKeys, mDebounceHysteresis);
|
tracker.setKeyboard(mKeys, mDebounceHysteresis);
|
||||||
}
|
}
|
||||||
|
@ -613,9 +614,6 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener,
|
||||||
return mSymbolColorScheme;
|
return mSymbolColorScheme;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setVerticalCorrection(int verticalOffset) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPopupParent(View v) {
|
public void setPopupParent(View v) {
|
||||||
mPopupParent = v;
|
mPopupParent = v;
|
||||||
}
|
}
|
||||||
|
@ -1070,14 +1068,6 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener,
|
||||||
return mMiniKeyboardOnScreen;
|
return mMiniKeyboardOnScreen;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getTouchX(float x) {
|
|
||||||
return (int)x - getPaddingLeft();
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getTouchY(float y) {
|
|
||||||
return (int)y + mVerticalCorrection - getPaddingTop();
|
|
||||||
}
|
|
||||||
|
|
||||||
private PointerTracker getPointerTracker(final int id) {
|
private PointerTracker getPointerTracker(final int id) {
|
||||||
final ArrayList<PointerTracker> pointers = mPointerTrackers;
|
final ArrayList<PointerTracker> pointers = mPointerTrackers;
|
||||||
final Key[] keys = mKeys;
|
final Key[] keys = mKeys;
|
||||||
|
@ -1132,29 +1122,29 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener,
|
||||||
|
|
||||||
if (action == MotionEvent.ACTION_MOVE) {
|
if (action == MotionEvent.ACTION_MOVE) {
|
||||||
for (int index = 0; index < pointerCount; index++) {
|
for (int index = 0; index < pointerCount; index++) {
|
||||||
int touchX = getTouchX(me.getX(index));
|
int x = (int)me.getX(index);
|
||||||
int touchY = getTouchY(me.getY(index));
|
int y = (int)me.getY(index);
|
||||||
int id = me.getPointerId(index);
|
int id = me.getPointerId(index);
|
||||||
PointerTracker tracker = getPointerTracker(id);
|
PointerTracker tracker = getPointerTracker(id);
|
||||||
tracker.onMoveEvent(touchX, touchY, eventTime);
|
tracker.onMoveEvent(x, y, eventTime);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int index = me.getActionIndex();
|
int index = me.getActionIndex();
|
||||||
int touchX = getTouchX(me.getX(index));
|
int x = (int)me.getX(index);
|
||||||
int touchY = getTouchY(me.getY(index));
|
int y = (int)me.getY(index);
|
||||||
int id = me.getPointerId(index);
|
int id = me.getPointerId(index);
|
||||||
PointerTracker tracker = getPointerTracker(id);
|
PointerTracker tracker = getPointerTracker(id);
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case MotionEvent.ACTION_DOWN:
|
case MotionEvent.ACTION_DOWN:
|
||||||
case MotionEvent.ACTION_POINTER_DOWN:
|
case MotionEvent.ACTION_POINTER_DOWN:
|
||||||
onDownEvent(tracker, touchX, touchY, eventTime);
|
onDownEvent(tracker, x, y, eventTime);
|
||||||
break;
|
break;
|
||||||
case MotionEvent.ACTION_UP:
|
case MotionEvent.ACTION_UP:
|
||||||
case MotionEvent.ACTION_POINTER_UP:
|
case MotionEvent.ACTION_POINTER_UP:
|
||||||
onUpEvent(tracker, touchX, touchY, eventTime);
|
onUpEvent(tracker, x, y, eventTime);
|
||||||
break;
|
break;
|
||||||
case MotionEvent.ACTION_CANCEL:
|
case MotionEvent.ACTION_CANCEL:
|
||||||
onCancelEvent(tracker, touchX, touchY, eventTime);
|
onCancelEvent(tracker, x, y, eventTime);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1162,12 +1152,12 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onDownEvent(PointerTracker tracker, int touchX, int touchY, long eventTime) {
|
private void onDownEvent(PointerTracker tracker, int x, int y, long eventTime) {
|
||||||
tracker.onDownEvent(touchX, touchY, eventTime);
|
tracker.onDownEvent(x, y, eventTime);
|
||||||
mPointerQueue.add(tracker);
|
mPointerQueue.add(tracker);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onUpEvent(PointerTracker tracker, int touchX, int touchY, long eventTime) {
|
private void onUpEvent(PointerTracker tracker, int x, int y, long eventTime) {
|
||||||
int index = mPointerQueue.lastIndexOf(tracker);
|
int index = mPointerQueue.lastIndexOf(tracker);
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
mPointerQueue.releasePointersOlderThan(tracker, eventTime);
|
mPointerQueue.releasePointersOlderThan(tracker, eventTime);
|
||||||
|
@ -1175,12 +1165,12 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener,
|
||||||
Log.w(TAG, "onUpEvent: corresponding down event not found for pointer "
|
Log.w(TAG, "onUpEvent: corresponding down event not found for pointer "
|
||||||
+ tracker.mPointerId);
|
+ tracker.mPointerId);
|
||||||
}
|
}
|
||||||
tracker.onUpEvent(touchX, touchY, eventTime);
|
tracker.onUpEvent(x, y, eventTime);
|
||||||
mPointerQueue.remove(tracker);
|
mPointerQueue.remove(tracker);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onCancelEvent(PointerTracker tracker, int touchX, int touchY, long eventTime) {
|
private void onCancelEvent(PointerTracker tracker, int x, int y, long eventTime) {
|
||||||
tracker.onCancelEvent(touchX, touchY, eventTime);
|
tracker.onCancelEvent(x, y, eventTime);
|
||||||
mPointerQueue.remove(tracker);
|
mPointerQueue.remove(tracker);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -139,12 +139,12 @@ public class PointerTracker {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onDownEvent(int touchX, int touchY, long eventTime) {
|
public void onDownEvent(int x, int y, long eventTime) {
|
||||||
int keyIndex = mKeyDetector.getKeyIndexAndNearbyCodes(touchX, touchY, null);
|
int keyIndex = mKeyDetector.getKeyIndexAndNearbyCodes(x, y, null);
|
||||||
mCurrentKey = keyIndex;
|
mCurrentKey = keyIndex;
|
||||||
mStartX = touchX;
|
mStartX = x;
|
||||||
mStartY = touchY;
|
mStartY = y;
|
||||||
startMoveDebouncing(touchX, touchY);
|
startMoveDebouncing(x, y);
|
||||||
startTimeDebouncing(eventTime);
|
startTimeDebouncing(eventTime);
|
||||||
checkMultiTap(eventTime, keyIndex);
|
checkMultiTap(eventTime, keyIndex);
|
||||||
if (mListener != null) {
|
if (mListener != null) {
|
||||||
|
@ -159,19 +159,19 @@ public class PointerTracker {
|
||||||
mHandler.startLongPressTimer(LONGPRESS_TIMEOUT, keyIndex, this);
|
mHandler.startLongPressTimer(LONGPRESS_TIMEOUT, keyIndex, this);
|
||||||
}
|
}
|
||||||
showKeyPreviewAndUpdateKey(keyIndex);
|
showKeyPreviewAndUpdateKey(keyIndex);
|
||||||
updateMoveDebouncing(touchX, touchY);
|
updateMoveDebouncing(x, y);
|
||||||
if (DEBUG)
|
if (DEBUG)
|
||||||
debugLog("onDownEvent:", touchX, touchY);
|
debugLog("onDownEvent:", x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onMoveEvent(int touchX, int touchY, long eventTime) {
|
public void onMoveEvent(int x, int y, long eventTime) {
|
||||||
int keyIndex = mKeyDetector.getKeyIndexAndNearbyCodes(touchX, touchY, null);
|
int keyIndex = mKeyDetector.getKeyIndexAndNearbyCodes(x, y, null);
|
||||||
if (isValidKeyIndex(keyIndex)) {
|
if (isValidKeyIndex(keyIndex)) {
|
||||||
if (mCurrentKey == NOT_A_KEY) {
|
if (mCurrentKey == NOT_A_KEY) {
|
||||||
updateTimeDebouncing(eventTime);
|
updateTimeDebouncing(eventTime);
|
||||||
mCurrentKey = keyIndex;
|
mCurrentKey = keyIndex;
|
||||||
mHandler.startLongPressTimer(LONGPRESS_TIMEOUT, keyIndex, this);
|
mHandler.startLongPressTimer(LONGPRESS_TIMEOUT, keyIndex, this);
|
||||||
} else if (isMinorMoveBounce(touchX, touchY, keyIndex, mCurrentKey)) {
|
} else if (isMinorMoveBounce(x, y, keyIndex, mCurrentKey)) {
|
||||||
updateTimeDebouncing(eventTime);
|
updateTimeDebouncing(eventTime);
|
||||||
} else {
|
} else {
|
||||||
resetMultiTap();
|
resetMultiTap();
|
||||||
|
@ -190,19 +190,19 @@ public class PointerTracker {
|
||||||
* should not be showed as popup preview.
|
* should not be showed as popup preview.
|
||||||
*/
|
*/
|
||||||
showKeyPreviewAndUpdateKey(isMinorTimeBounce() ? mLastKey : mCurrentKey);
|
showKeyPreviewAndUpdateKey(isMinorTimeBounce() ? mLastKey : mCurrentKey);
|
||||||
updateMoveDebouncing(touchX, touchY);
|
updateMoveDebouncing(x, y);
|
||||||
if (DEBUG_MOVE)
|
if (DEBUG_MOVE)
|
||||||
debugLog("onMoveEvent:", touchX, touchY);
|
debugLog("onMoveEvent:", x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onUpEvent(int touchX, int touchY, long eventTime) {
|
public void onUpEvent(int x, int y, long eventTime) {
|
||||||
if (DEBUG)
|
if (DEBUG)
|
||||||
debugLog("onUpEvent :", touchX, touchY);
|
debugLog("onUpEvent :", x, y);
|
||||||
int keyIndex = mKeyDetector.getKeyIndexAndNearbyCodes(touchX, touchY, null);
|
int keyIndex = mKeyDetector.getKeyIndexAndNearbyCodes(x, y, null);
|
||||||
boolean wasInKeyRepeat = mHandler.isInKeyRepeat();
|
boolean wasInKeyRepeat = mHandler.isInKeyRepeat();
|
||||||
mHandler.cancelKeyTimers();
|
mHandler.cancelKeyTimers();
|
||||||
mHandler.cancelPopupPreview();
|
mHandler.cancelPopupPreview();
|
||||||
if (isMinorMoveBounce(touchX, touchY, keyIndex, mCurrentKey)) {
|
if (isMinorMoveBounce(x, y, keyIndex, mCurrentKey)) {
|
||||||
updateTimeDebouncing(eventTime);
|
updateTimeDebouncing(eventTime);
|
||||||
} else {
|
} else {
|
||||||
resetMultiTap();
|
resetMultiTap();
|
||||||
|
@ -211,21 +211,21 @@ public class PointerTracker {
|
||||||
}
|
}
|
||||||
if (isMinorTimeBounce()) {
|
if (isMinorTimeBounce()) {
|
||||||
mCurrentKey = mLastKey;
|
mCurrentKey = mLastKey;
|
||||||
touchX = mLastCodeX;
|
x = mLastCodeX;
|
||||||
touchY = mLastCodeY;
|
y = mLastCodeY;
|
||||||
}
|
}
|
||||||
showKeyPreviewAndUpdateKey(NOT_A_KEY);
|
showKeyPreviewAndUpdateKey(NOT_A_KEY);
|
||||||
// If we're not on a repeating key (which sends on a DOWN event)
|
// If we're not on a repeating key (which sends on a DOWN event)
|
||||||
if (!wasInKeyRepeat && !mProxy.isMiniKeyboardOnScreen()) {
|
if (!wasInKeyRepeat && !mProxy.isMiniKeyboardOnScreen()) {
|
||||||
detectAndSendKey(mCurrentKey, touchX, touchY, eventTime);
|
detectAndSendKey(mCurrentKey, (int)x, (int)y, eventTime);
|
||||||
}
|
}
|
||||||
if (isValidKeyIndex(keyIndex))
|
if (isValidKeyIndex(keyIndex))
|
||||||
mProxy.invalidateKey(mKeys[keyIndex]);
|
mProxy.invalidateKey(mKeys[keyIndex]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onCancelEvent(int touchX, int touchY, long eventTime) {
|
public void onCancelEvent(int x, int y, long eventTime) {
|
||||||
if (DEBUG)
|
if (DEBUG)
|
||||||
debugLog("onCancelEvt:", touchX, touchY);
|
debugLog("onCancelEvt:", x, y);
|
||||||
mHandler.cancelKeyTimers();
|
mHandler.cancelKeyTimers();
|
||||||
mHandler.cancelPopupPreview();
|
mHandler.cancelPopupPreview();
|
||||||
mProxy.dismissPopupKeyboard();
|
mProxy.dismissPopupKeyboard();
|
||||||
|
@ -244,6 +244,14 @@ public class PointerTracker {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getLastX() {
|
||||||
|
return mLastX;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLastY() {
|
||||||
|
return mLastY;
|
||||||
|
}
|
||||||
|
|
||||||
// These package scope methods are only for debugging purpose.
|
// These package scope methods are only for debugging purpose.
|
||||||
/* package */ int getStartX() {
|
/* package */ int getStartX() {
|
||||||
return mStartX;
|
return mStartX;
|
||||||
|
@ -253,14 +261,6 @@ public class PointerTracker {
|
||||||
return mStartY;
|
return mStartY;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* package */ int getLastX() {
|
|
||||||
return mLastX;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* package */ int getLastY() {
|
|
||||||
return mLastY;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void startMoveDebouncing(int x, int y) {
|
private void startMoveDebouncing(int x, int y) {
|
||||||
mLastCodeX = x;
|
mLastCodeX = x;
|
||||||
mLastCodeY = y;
|
mLastCodeY = y;
|
||||||
|
@ -426,7 +426,7 @@ public class PointerTracker {
|
||||||
code = String.format((primaryCode < 0) ? "%4d" : "0x%02x", primaryCode);
|
code = String.format((primaryCode < 0) ? "%4d" : "0x%02x", primaryCode);
|
||||||
}
|
}
|
||||||
Log.d(TAG,
|
Log.d(TAG,
|
||||||
String.format("%s [%d] %d,%d %s %s", title, mPointerId, x, y, code,
|
String.format("%s [%d] %3d,%3d %s %s", title, mPointerId, x, y, code,
|
||||||
isModifier() ? "modifier" : ""));
|
isModifier() ? "modifier" : ""));
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -35,6 +35,8 @@ class ProximityKeyDetector extends KeyDetector {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getKeyIndexAndNearbyCodes(int x, int y, int[] allKeys) {
|
public int getKeyIndexAndNearbyCodes(int x, int y, int[] allKeys) {
|
||||||
|
int touchX = getTouchX(x);
|
||||||
|
int touchY = getTouchY(y);
|
||||||
final Key[] keys = mKeys;
|
final Key[] keys = mKeys;
|
||||||
if (keys == null)
|
if (keys == null)
|
||||||
throw new IllegalStateException("keyboard isn't set");
|
throw new IllegalStateException("keyboard isn't set");
|
||||||
|
@ -44,18 +46,18 @@ class ProximityKeyDetector extends KeyDetector {
|
||||||
int closestKeyDist = mProximityThresholdSquare + 1;
|
int closestKeyDist = mProximityThresholdSquare + 1;
|
||||||
int[] distances = mDistances;
|
int[] distances = mDistances;
|
||||||
Arrays.fill(distances, Integer.MAX_VALUE);
|
Arrays.fill(distances, Integer.MAX_VALUE);
|
||||||
int [] nearestKeyIndices = mKeyboard.getNearestKeys(x, y);
|
int [] nearestKeyIndices = mKeyboard.getNearestKeys(touchX, touchY);
|
||||||
final int keyCount = nearestKeyIndices.length;
|
final int keyCount = nearestKeyIndices.length;
|
||||||
for (int i = 0; i < keyCount; i++) {
|
for (int i = 0; i < keyCount; i++) {
|
||||||
final Key key = keys[nearestKeyIndices[i]];
|
final Key key = keys[nearestKeyIndices[i]];
|
||||||
int dist = 0;
|
int dist = 0;
|
||||||
boolean isInside = key.isInside(x,y);
|
boolean isInside = key.isInside(touchX, touchY);
|
||||||
if (isInside) {
|
if (isInside) {
|
||||||
primaryIndex = nearestKeyIndices[i];
|
primaryIndex = nearestKeyIndices[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (((mProximityCorrectOn
|
if (((mProximityCorrectOn
|
||||||
&& (dist = key.squaredDistanceFrom(x, y)) < mProximityThresholdSquare)
|
&& (dist = key.squaredDistanceFrom(touchX, touchY)) < mProximityThresholdSquare)
|
||||||
|| isInside)
|
|| isInside)
|
||||||
&& key.codes[0] > 32) {
|
&& key.codes[0] > 32) {
|
||||||
// Find insertion point
|
// Find insertion point
|
||||||
|
|
Loading…
Reference in New Issue