Get rid of usage of key index
Change-Id: I7596ce3ae52fde436d06c2dd95ae873c7aa5ef7fmain
parent
55042ff977
commit
e22baaadd3
|
@ -29,7 +29,6 @@ import android.view.inputmethod.EditorInfo;
|
||||||
import com.android.inputmethod.compat.AccessibilityEventCompatUtils;
|
import com.android.inputmethod.compat.AccessibilityEventCompatUtils;
|
||||||
import com.android.inputmethod.compat.MotionEventCompatUtils;
|
import com.android.inputmethod.compat.MotionEventCompatUtils;
|
||||||
import com.android.inputmethod.keyboard.Key;
|
import com.android.inputmethod.keyboard.Key;
|
||||||
import com.android.inputmethod.keyboard.KeyDetector;
|
|
||||||
import com.android.inputmethod.keyboard.LatinKeyboardView;
|
import com.android.inputmethod.keyboard.LatinKeyboardView;
|
||||||
import com.android.inputmethod.keyboard.PointerTracker;
|
import com.android.inputmethod.keyboard.PointerTracker;
|
||||||
|
|
||||||
|
@ -42,7 +41,7 @@ public class AccessibleKeyboardViewProxy {
|
||||||
private LatinKeyboardView mView;
|
private LatinKeyboardView mView;
|
||||||
private AccessibleKeyboardActionListener mListener;
|
private AccessibleKeyboardActionListener mListener;
|
||||||
|
|
||||||
private int mLastHoverKeyIndex = KeyDetector.NOT_A_KEY;
|
private Key mLastHoverKey = null;
|
||||||
|
|
||||||
public static void init(InputMethodService inputMethod, SharedPreferences prefs) {
|
public static void init(InputMethodService inputMethod, SharedPreferences prefs) {
|
||||||
sInstance.initInternal(inputMethod, prefs);
|
sInstance.initInternal(inputMethod, prefs);
|
||||||
|
@ -81,7 +80,7 @@ public class AccessibleKeyboardViewProxy {
|
||||||
|
|
||||||
switch (event.getEventType()) {
|
switch (event.getEventType()) {
|
||||||
case AccessibilityEventCompatUtils.TYPE_VIEW_HOVER_ENTER:
|
case AccessibilityEventCompatUtils.TYPE_VIEW_HOVER_ENTER:
|
||||||
final Key key = tracker.getKey(mLastHoverKeyIndex);
|
final Key key = mLastHoverKey;
|
||||||
|
|
||||||
if (key == null)
|
if (key == null)
|
||||||
break;
|
break;
|
||||||
|
@ -130,12 +129,12 @@ public class AccessibleKeyboardViewProxy {
|
||||||
switch (event.getAction()) {
|
switch (event.getAction()) {
|
||||||
case MotionEventCompatUtils.ACTION_HOVER_ENTER:
|
case MotionEventCompatUtils.ACTION_HOVER_ENTER:
|
||||||
case MotionEventCompatUtils.ACTION_HOVER_MOVE:
|
case MotionEventCompatUtils.ACTION_HOVER_MOVE:
|
||||||
final int keyIndex = tracker.getKeyIndexOn(x, y);
|
final Key key = tracker.getKeyOn(x, y);
|
||||||
|
|
||||||
if (keyIndex != mLastHoverKeyIndex) {
|
if (key != mLastHoverKey) {
|
||||||
fireKeyHoverEvent(tracker, mLastHoverKeyIndex, false);
|
fireKeyHoverEvent(tracker, mLastHoverKey, false);
|
||||||
mLastHoverKeyIndex = keyIndex;
|
mLastHoverKey = key;
|
||||||
fireKeyHoverEvent(tracker, mLastHoverKeyIndex, true);
|
fireKeyHoverEvent(tracker, mLastHoverKey, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -144,7 +143,7 @@ public class AccessibleKeyboardViewProxy {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fireKeyHoverEvent(PointerTracker tracker, int keyIndex, boolean entering) {
|
private void fireKeyHoverEvent(PointerTracker tracker, Key key, boolean entering) {
|
||||||
if (mListener == null) {
|
if (mListener == null) {
|
||||||
Log.e(TAG, "No accessible keyboard action listener set!");
|
Log.e(TAG, "No accessible keyboard action listener set!");
|
||||||
return;
|
return;
|
||||||
|
@ -155,11 +154,6 @@ public class AccessibleKeyboardViewProxy {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (keyIndex == KeyDetector.NOT_A_KEY)
|
|
||||||
return;
|
|
||||||
|
|
||||||
final Key key = tracker.getKey(keyIndex);
|
|
||||||
|
|
||||||
if (key == null)
|
if (key == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -318,6 +318,14 @@ public class Key {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isShift() {
|
||||||
|
return mCode == Keyboard.CODE_SHIFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isModifier() {
|
||||||
|
return mCode == Keyboard.CODE_SHIFT || mCode == Keyboard.CODE_SWITCH_ALPHA_SYMBOL;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isRepeatable() {
|
public boolean isRepeatable() {
|
||||||
return (mActionFlags & ACTION_FLAGS_IS_REPEATABLE) != 0;
|
return (mActionFlags & ACTION_FLAGS_IS_REPEATABLE) != 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ public class KeyDetector {
|
||||||
private static final boolean DEBUG = false;
|
private static final boolean DEBUG = false;
|
||||||
|
|
||||||
public static final int NOT_A_CODE = -1;
|
public static final int NOT_A_CODE = -1;
|
||||||
public static final int NOT_A_KEY = -1;
|
private static final int NOT_A_KEY = -1;
|
||||||
|
|
||||||
private final int mKeyHysteresisDistanceSquared;
|
private final int mKeyHysteresisDistanceSquared;
|
||||||
|
|
||||||
|
@ -96,22 +96,22 @@ public class KeyDetector {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes maximum size of the array that can contain all nearby key indices returned by
|
* Computes maximum size of the array that can contain all nearby key codes returned by
|
||||||
* {@link #getKeyIndexAndNearbyCodes}.
|
* {@link #getKeyAndNearbyCodes}.
|
||||||
*
|
*
|
||||||
* @return Returns maximum size of the array that can contain all nearby key indices returned
|
* @return Returns maximum size of the array that can contain all nearby key codes returned
|
||||||
* by {@link #getKeyIndexAndNearbyCodes}.
|
* by {@link #getKeyAndNearbyCodes}.
|
||||||
*/
|
*/
|
||||||
protected int getMaxNearbyKeys() {
|
protected int getMaxNearbyKeys() {
|
||||||
return MAX_NEARBY_KEYS;
|
return MAX_NEARBY_KEYS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocates array that can hold all key indices returned by {@link #getKeyIndexAndNearbyCodes}
|
* Allocates array that can hold all key codes returned by {@link #getKeyAndNearbyCodes}
|
||||||
* method. The maximum size of the array should be computed by {@link #getMaxNearbyKeys}.
|
* method. The maximum size of the array should be computed by {@link #getMaxNearbyKeys}.
|
||||||
*
|
*
|
||||||
* @return Allocates and returns an array that can hold all key indices returned by
|
* @return Allocates and returns an array that can hold all key codes returned by
|
||||||
* {@link #getKeyIndexAndNearbyCodes} method. All elements in the returned array are
|
* {@link #getKeyAndNearbyCodes} method. All elements in the returned array are
|
||||||
* initialized by {@link #NOT_A_CODE} value.
|
* initialized by {@link #NOT_A_CODE} value.
|
||||||
*/
|
*/
|
||||||
public int[] newCodeArray() {
|
public int[] newCodeArray() {
|
||||||
|
@ -180,31 +180,32 @@ public class KeyDetector {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds all possible nearby key indices around a touch event point and returns the nearest key
|
* Finds all possible nearby key codes around a touch event point and returns the nearest key.
|
||||||
* index. The algorithm to determine the nearby keys depends on the threshold set by
|
* The algorithm to determine the nearby keys depends on the threshold set by
|
||||||
* {@link #setProximityThreshold(int)} and the mode set by
|
* {@link #setProximityThreshold(int)} and the mode set by
|
||||||
* {@link #setProximityCorrectionEnabled(boolean)}.
|
* {@link #setProximityCorrectionEnabled(boolean)}.
|
||||||
*
|
*
|
||||||
* @param x The x-coordinate of a touch point
|
* @param x The x-coordinate of a touch point
|
||||||
* @param y The y-coordinate of a touch point
|
* @param y The y-coordinate of a touch point
|
||||||
* @param allCodes All nearby key code except functional key are returned in this array
|
* @param allCodes All nearby key codes except functional key are returned in this array
|
||||||
* @return The nearest key index
|
* @return The nearest key
|
||||||
*/
|
*/
|
||||||
public int getKeyIndexAndNearbyCodes(int x, int y, final int[] allCodes) {
|
public Key getKeyAndNearbyCodes(int x, int y, final int[] allCodes) {
|
||||||
final List<Key> keys = getKeyboard().mKeys;
|
final List<Key> keys = getKeyboard().mKeys;
|
||||||
final int touchX = getTouchX(x);
|
final int touchX = getTouchX(x);
|
||||||
final int touchY = getTouchY(y);
|
final int touchY = getTouchY(y);
|
||||||
|
|
||||||
initializeNearbyKeys();
|
initializeNearbyKeys();
|
||||||
int primaryIndex = NOT_A_KEY;
|
Key primaryKey = null;
|
||||||
for (final int index : mKeyboard.getNearestKeys(touchX, touchY)) {
|
for (final int index : mKeyboard.getNearestKeys(touchX, touchY)) {
|
||||||
final Key key = keys.get(index);
|
final Key key = keys.get(index);
|
||||||
final boolean isOnKey = key.isOnKey(touchX, touchY);
|
final boolean isOnKey = key.isOnKey(touchX, touchY);
|
||||||
final int distance = key.squaredDistanceToEdge(touchX, touchY);
|
final int distance = key.squaredDistanceToEdge(touchX, touchY);
|
||||||
if (isOnKey || (mProximityCorrectOn && distance < mProximityThresholdSquare)) {
|
if (isOnKey || (mProximityCorrectOn && distance < mProximityThresholdSquare)) {
|
||||||
final int insertedPosition = sortNearbyKeys(index, distance, isOnKey);
|
final int insertedPosition = sortNearbyKeys(index, distance, isOnKey);
|
||||||
if (insertedPosition == 0 && isOnKey)
|
if (insertedPosition == 0 && isOnKey) {
|
||||||
primaryIndex = index;
|
primaryKey = key;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,11 +214,11 @@ public class KeyDetector {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, "x=" + x + " y=" + y
|
Log.d(TAG, "x=" + x + " y=" + y
|
||||||
+ " primary="
|
+ " primary="
|
||||||
+ (primaryIndex == NOT_A_KEY ? "none" : keys.get(primaryIndex).mCode)
|
+ (primaryKey == null ? "none" : primaryKey.mCode)
|
||||||
+ " codes=" + Arrays.toString(allCodes));
|
+ " codes=" + Arrays.toString(allCodes));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return primaryIndex;
|
return primaryKey;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -148,7 +148,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
|
||||||
final PointerTracker tracker = (PointerTracker) msg.obj;
|
final PointerTracker tracker = (PointerTracker) msg.obj;
|
||||||
switch (msg.what) {
|
switch (msg.what) {
|
||||||
case MSG_SHOW_KEY_PREVIEW:
|
case MSG_SHOW_KEY_PREVIEW:
|
||||||
keyboardView.showKey(msg.arg1, tracker);
|
keyboardView.showKey(tracker);
|
||||||
break;
|
break;
|
||||||
case MSG_DISMISS_KEY_PREVIEW:
|
case MSG_DISMISS_KEY_PREVIEW:
|
||||||
tracker.getKeyPreviewText().setVisibility(View.INVISIBLE);
|
tracker.getKeyPreviewText().setVisibility(View.INVISIBLE);
|
||||||
|
@ -156,16 +156,15 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void showKeyPreview(long delay, int keyIndex, PointerTracker tracker) {
|
public void showKeyPreview(long delay, PointerTracker tracker) {
|
||||||
removeMessages(MSG_SHOW_KEY_PREVIEW);
|
removeMessages(MSG_SHOW_KEY_PREVIEW);
|
||||||
final KeyboardView keyboardView = getOuterInstance();
|
final KeyboardView keyboardView = getOuterInstance();
|
||||||
if (keyboardView == null) return;
|
if (keyboardView == null) return;
|
||||||
if (tracker.getKeyPreviewText().getVisibility() == VISIBLE || delay == 0) {
|
if (tracker.getKeyPreviewText().getVisibility() == VISIBLE || delay == 0) {
|
||||||
// Show right away, if it's already visible and finger is moving around
|
// Show right away, if it's already visible and finger is moving around
|
||||||
keyboardView.showKey(keyIndex, tracker);
|
keyboardView.showKey(tracker);
|
||||||
} else {
|
} else {
|
||||||
sendMessageDelayed(
|
sendMessageDelayed(obtainMessage(MSG_SHOW_KEY_PREVIEW, tracker), delay);
|
||||||
obtainMessage(MSG_SHOW_KEY_PREVIEW, keyIndex, 0, tracker), delay);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -830,9 +829,9 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void showKeyPreview(int keyIndex, PointerTracker tracker) {
|
public void showKeyPreview(PointerTracker tracker) {
|
||||||
if (mShowKeyPreviewPopup) {
|
if (mShowKeyPreviewPopup) {
|
||||||
mDrawingHandler.showKeyPreview(mDelayBeforePreview, keyIndex, tracker);
|
mDrawingHandler.showKeyPreview(mDelayBeforePreview, tracker);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -858,7 +857,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
|
||||||
keyPreview, FrameLayoutCompatUtils.newLayoutParam(mPreviewPlacer, 0, 0));
|
keyPreview, FrameLayoutCompatUtils.newLayoutParam(mPreviewPlacer, 0, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showKey(final int keyIndex, PointerTracker tracker) {
|
private void showKey(PointerTracker tracker) {
|
||||||
final TextView previewText = tracker.getKeyPreviewText();
|
final TextView previewText = tracker.getKeyPreviewText();
|
||||||
// If the key preview has no parent view yet, add it to the ViewGroup which can place
|
// If the key preview has no parent view yet, add it to the ViewGroup which can place
|
||||||
// key preview absolutely in SoftInputWindow.
|
// key preview absolutely in SoftInputWindow.
|
||||||
|
@ -867,8 +866,8 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
|
||||||
}
|
}
|
||||||
|
|
||||||
mDrawingHandler.cancelDismissKeyPreview(tracker);
|
mDrawingHandler.cancelDismissKeyPreview(tracker);
|
||||||
final Key key = tracker.getKey(keyIndex);
|
final Key key = tracker.getKey();
|
||||||
// If keyIndex is invalid or IME is already closed, we must not show key preview.
|
// If key is invalid or IME is already closed, we must not show key preview.
|
||||||
// Trying to show key preview while root window is closed causes
|
// Trying to show key preview while root window is closed causes
|
||||||
// WindowManager.BadTokenException.
|
// WindowManager.BadTokenException.
|
||||||
if (key == null)
|
if (key == null)
|
||||||
|
|
|
@ -74,7 +74,7 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
|
||||||
|
|
||||||
private final boolean mHasDistinctMultitouch;
|
private final boolean mHasDistinctMultitouch;
|
||||||
private int mOldPointerCount = 1;
|
private int mOldPointerCount = 1;
|
||||||
private int mOldKeyIndex;
|
private Key mOldKey;
|
||||||
|
|
||||||
private final boolean mConfigShowMiniKeyboardAtTouchedPoint;
|
private final boolean mConfigShowMiniKeyboardAtTouchedPoint;
|
||||||
protected KeyDetector mKeyDetector;
|
protected KeyDetector mKeyDetector;
|
||||||
|
@ -103,19 +103,19 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
|
||||||
final PointerTracker tracker = (PointerTracker) msg.obj;
|
final PointerTracker tracker = (PointerTracker) msg.obj;
|
||||||
switch (msg.what) {
|
switch (msg.what) {
|
||||||
case MSG_REPEAT_KEY:
|
case MSG_REPEAT_KEY:
|
||||||
tracker.onRepeatKey(msg.arg1);
|
tracker.onRepeatKey(tracker.getKey());
|
||||||
startKeyRepeatTimer(keyboardView.mKeyRepeatInterval, msg.arg1, tracker);
|
startKeyRepeatTimer(keyboardView.mKeyRepeatInterval, tracker);
|
||||||
break;
|
break;
|
||||||
case MSG_LONGPRESS_KEY:
|
case MSG_LONGPRESS_KEY:
|
||||||
keyboardView.openMiniKeyboardIfRequired(msg.arg1, tracker);
|
keyboardView.openMiniKeyboardIfRequired(tracker.getKey(), tracker);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void startKeyRepeatTimer(long delay, int keyIndex, PointerTracker tracker) {
|
public void startKeyRepeatTimer(long delay, PointerTracker tracker) {
|
||||||
mInKeyRepeat = true;
|
mInKeyRepeat = true;
|
||||||
sendMessageDelayed(obtainMessage(MSG_REPEAT_KEY, keyIndex, 0, tracker), delay);
|
sendMessageDelayed(obtainMessage(MSG_REPEAT_KEY, tracker), delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void cancelKeyRepeatTimer() {
|
public void cancelKeyRepeatTimer() {
|
||||||
|
@ -128,9 +128,9 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void startLongPressTimer(long delay, int keyIndex, PointerTracker tracker) {
|
public void startLongPressTimer(long delay, PointerTracker tracker) {
|
||||||
cancelLongPressTimer();
|
cancelLongPressTimer();
|
||||||
sendMessageDelayed(obtainMessage(MSG_LONGPRESS_KEY, keyIndex, 0, tracker), delay);
|
sendMessageDelayed(obtainMessage(MSG_LONGPRESS_KEY, tracker), delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -181,8 +181,9 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
|
||||||
final int pointerIndex = firstDown.getActionIndex();
|
final int pointerIndex = firstDown.getActionIndex();
|
||||||
final int id = firstDown.getPointerId(pointerIndex);
|
final int id = firstDown.getPointerId(pointerIndex);
|
||||||
final PointerTracker tracker = getPointerTracker(id);
|
final PointerTracker tracker = getPointerTracker(id);
|
||||||
|
final Key key = tracker.getKeyOn((int)firstDown.getX(), (int)firstDown.getY());
|
||||||
// If the first down event is on shift key.
|
// If the first down event is on shift key.
|
||||||
if (tracker.isOnShiftKey((int) firstDown.getX(), (int) firstDown.getY())) {
|
if (key != null && key.isShift()) {
|
||||||
mProcessingShiftDoubleTapEvent = true;
|
mProcessingShiftDoubleTapEvent = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -199,8 +200,9 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
|
||||||
final int pointerIndex = secondDown.getActionIndex();
|
final int pointerIndex = secondDown.getActionIndex();
|
||||||
final int id = secondDown.getPointerId(pointerIndex);
|
final int id = secondDown.getPointerId(pointerIndex);
|
||||||
final PointerTracker tracker = getPointerTracker(id);
|
final PointerTracker tracker = getPointerTracker(id);
|
||||||
|
final Key key = tracker.getKeyOn((int)secondDown.getX(), (int)secondDown.getY());
|
||||||
// If the second down event is also on shift key.
|
// If the second down event is also on shift key.
|
||||||
if (tracker.isOnShiftKey((int) secondDown.getX(), (int) secondDown.getY())) {
|
if (key != null && key.isShift()) {
|
||||||
// Detected a double tap on shift key. If we are in the ignoring double tap
|
// Detected a double tap on shift key. If we are in the ignoring double tap
|
||||||
// mode, it means we have already turned off caps lock in
|
// mode, it means we have already turned off caps lock in
|
||||||
// {@link KeyboardSwitcher#onReleaseShift} .
|
// {@link KeyboardSwitcher#onReleaseShift} .
|
||||||
|
@ -326,7 +328,7 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
|
||||||
super.cancelAllMessages();
|
super.cancelAllMessages();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean openMiniKeyboardIfRequired(int keyIndex, PointerTracker tracker) {
|
private boolean openMiniKeyboardIfRequired(Key parentKey, PointerTracker tracker) {
|
||||||
// Check if we have a popup layout specified first.
|
// Check if we have a popup layout specified first.
|
||||||
if (mMoreKeysLayout == 0) {
|
if (mMoreKeysLayout == 0) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -335,7 +337,6 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
|
||||||
// Check if we are already displaying popup panel.
|
// Check if we are already displaying popup panel.
|
||||||
if (mMoreKeysPanel != null)
|
if (mMoreKeysPanel != null)
|
||||||
return false;
|
return false;
|
||||||
final Key parentKey = tracker.getKey(keyIndex);
|
|
||||||
if (parentKey == null)
|
if (parentKey == null)
|
||||||
return false;
|
return false;
|
||||||
return onLongPress(parentKey, tracker);
|
return onLongPress(parentKey, tracker);
|
||||||
|
@ -546,8 +547,8 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
|
||||||
// Multi-touch to single touch transition.
|
// Multi-touch to single touch transition.
|
||||||
// Send a down event for the latest pointer if the key is different from the
|
// Send a down event for the latest pointer if the key is different from the
|
||||||
// previous key.
|
// previous key.
|
||||||
final int newKeyIndex = tracker.getKeyIndexOn(x, y);
|
final Key newKey = tracker.getKeyOn(x, y);
|
||||||
if (mOldKeyIndex != newKeyIndex) {
|
if (mOldKey != newKey) {
|
||||||
tracker.onDownEvent(x, y, eventTime, this);
|
tracker.onDownEvent(x, y, eventTime, this);
|
||||||
if (action == MotionEvent.ACTION_UP)
|
if (action == MotionEvent.ACTION_UP)
|
||||||
tracker.onUpEvent(x, y, eventTime);
|
tracker.onUpEvent(x, y, eventTime);
|
||||||
|
@ -557,7 +558,7 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
|
||||||
// Send an up event for the last pointer.
|
// Send an up event for the last pointer.
|
||||||
final int lastX = tracker.getLastX();
|
final int lastX = tracker.getLastX();
|
||||||
final int lastY = tracker.getLastY();
|
final int lastY = tracker.getLastY();
|
||||||
mOldKeyIndex = tracker.getKeyIndexOn(lastX, lastY);
|
mOldKey = tracker.getKeyOn(lastX, lastY);
|
||||||
tracker.onUpEvent(lastX, lastY, eventTime);
|
tracker.onUpEvent(lastX, lastY, eventTime);
|
||||||
} else if (pointerCount == 1 && oldPointerCount == 1) {
|
} else if (pointerCount == 1 && oldPointerCount == 1) {
|
||||||
tracker.processMotionEvent(action, x, y, eventTime, this);
|
tracker.processMotionEvent(action, x, y, eventTime, this);
|
||||||
|
|
|
@ -16,8 +16,6 @@
|
||||||
|
|
||||||
package com.android.inputmethod.keyboard;
|
package com.android.inputmethod.keyboard;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class MoreKeysDetector extends KeyDetector {
|
public class MoreKeysDetector extends KeyDetector {
|
||||||
private final int mSlideAllowanceSquare;
|
private final int mSlideAllowanceSquare;
|
||||||
private final int mSlideAllowanceSquareTop;
|
private final int mSlideAllowanceSquareTop;
|
||||||
|
@ -41,24 +39,23 @@ public class MoreKeysDetector extends KeyDetector {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getKeyIndexAndNearbyCodes(int x, int y, final int[] allCodes) {
|
public Key getKeyAndNearbyCodes(int x, int y, final int[] allCodes) {
|
||||||
final List<Key> keys = getKeyboard().mKeys;
|
|
||||||
final int touchX = getTouchX(x);
|
final int touchX = getTouchX(x);
|
||||||
final int touchY = getTouchY(y);
|
final int touchY = getTouchY(y);
|
||||||
|
|
||||||
int nearestIndex = NOT_A_KEY;
|
Key nearestKey = null;
|
||||||
int nearestDist = (y < 0) ? mSlideAllowanceSquareTop : mSlideAllowanceSquare;
|
int nearestDist = (y < 0) ? mSlideAllowanceSquareTop : mSlideAllowanceSquare;
|
||||||
final int keyCount = keys.size();
|
for (final Key key : getKeyboard().mKeys) {
|
||||||
for (int index = 0; index < keyCount; index++) {
|
final int dist = key.squaredDistanceToEdge(touchX, touchY);
|
||||||
final int dist = keys.get(index).squaredDistanceToEdge(touchX, touchY);
|
|
||||||
if (dist < nearestDist) {
|
if (dist < nearestDist) {
|
||||||
nearestIndex = index;
|
nearestKey = key;
|
||||||
nearestDist = dist;
|
nearestDist = dist;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (allCodes != null && nearestIndex != NOT_A_KEY)
|
if (allCodes != null && nearestKey != null) {
|
||||||
allCodes[0] = keys.get(nearestIndex).mCode;
|
allCodes[0] = nearestKey.mCode;
|
||||||
return nearestIndex;
|
}
|
||||||
|
return nearestKey;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -68,7 +68,7 @@ public class PointerTracker {
|
||||||
public interface DrawingProxy extends MoreKeysPanel.Controller {
|
public interface DrawingProxy extends MoreKeysPanel.Controller {
|
||||||
public void invalidateKey(Key key);
|
public void invalidateKey(Key key);
|
||||||
public TextView inflateKeyPreviewText();
|
public TextView inflateKeyPreviewText();
|
||||||
public void showKeyPreview(int keyIndex, PointerTracker tracker);
|
public void showKeyPreview(PointerTracker tracker);
|
||||||
public void cancelShowKeyPreview(PointerTracker tracker);
|
public void cancelShowKeyPreview(PointerTracker tracker);
|
||||||
public void dismissKeyPreview(PointerTracker tracker);
|
public void dismissKeyPreview(PointerTracker tracker);
|
||||||
}
|
}
|
||||||
|
@ -76,8 +76,8 @@ public class PointerTracker {
|
||||||
public interface TimerProxy {
|
public interface TimerProxy {
|
||||||
public void startKeyTypedTimer(long delay);
|
public void startKeyTypedTimer(long delay);
|
||||||
public boolean isTyping();
|
public boolean isTyping();
|
||||||
public void startKeyRepeatTimer(long delay, int keyIndex, PointerTracker tracker);
|
public void startKeyRepeatTimer(long delay, PointerTracker tracker);
|
||||||
public void startLongPressTimer(long delay, int keyIndex, PointerTracker tracker);
|
public void startLongPressTimer(long delay, PointerTracker tracker);
|
||||||
public void cancelLongPressTimer();
|
public void cancelLongPressTimer();
|
||||||
public void cancelKeyTimers();
|
public void cancelKeyTimers();
|
||||||
|
|
||||||
|
@ -87,9 +87,9 @@ public class PointerTracker {
|
||||||
@Override
|
@Override
|
||||||
public boolean isTyping() { return false; }
|
public boolean isTyping() { return false; }
|
||||||
@Override
|
@Override
|
||||||
public void startKeyRepeatTimer(long delay, int keyIndex, PointerTracker tracker) {}
|
public void startKeyRepeatTimer(long delay, PointerTracker tracker) {}
|
||||||
@Override
|
@Override
|
||||||
public void startLongPressTimer(long delay, int keyIndex, PointerTracker tracker) {}
|
public void startLongPressTimer(long delay, PointerTracker tracker) {}
|
||||||
@Override
|
@Override
|
||||||
public void cancelLongPressTimer() {}
|
public void cancelLongPressTimer() {}
|
||||||
@Override
|
@Override
|
||||||
|
@ -127,9 +127,9 @@ public class PointerTracker {
|
||||||
private long mDownTime;
|
private long mDownTime;
|
||||||
private long mUpTime;
|
private long mUpTime;
|
||||||
|
|
||||||
// The current key index where this pointer is.
|
// The current key where this pointer is.
|
||||||
private int mKeyIndex = KeyDetector.NOT_A_KEY;
|
private Key mCurrentKey = null;
|
||||||
// The position where mKeyIndex was recognized for the first time.
|
// The position where the current key was recognized for the first time.
|
||||||
private int mKeyX;
|
private int mKeyX;
|
||||||
private int mKeyY;
|
private int mKeyY;
|
||||||
|
|
||||||
|
@ -217,7 +217,7 @@ public class PointerTracker {
|
||||||
|
|
||||||
public static void dismissAllKeyPreviews() {
|
public static void dismissAllKeyPreviews() {
|
||||||
for (final PointerTracker tracker : sTrackers) {
|
for (final PointerTracker tracker : sTrackers) {
|
||||||
tracker.setReleasedKeyGraphics(tracker.mKeyIndex);
|
tracker.setReleasedKeyGraphics(tracker.mCurrentKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -238,7 +238,7 @@ public class PointerTracker {
|
||||||
|
|
||||||
// Returns true if keyboard has been changed by this callback.
|
// Returns true if keyboard has been changed by this callback.
|
||||||
private boolean callListenerOnPressAndCheckKeyboardLayoutChange(Key key, boolean withSliding) {
|
private boolean callListenerOnPressAndCheckKeyboardLayoutChange(Key key, boolean withSliding) {
|
||||||
final boolean ignoreModifierKey = mIgnoreModifierKey && isModifierCode(key.mCode);
|
final boolean ignoreModifierKey = mIgnoreModifierKey && key.isModifier();
|
||||||
if (DEBUG_LISTENER)
|
if (DEBUG_LISTENER)
|
||||||
Log.d(TAG, "onPress : " + keyCodePrintable(key.mCode) + " sliding=" + withSliding
|
Log.d(TAG, "onPress : " + keyCodePrintable(key.mCode) + " sliding=" + withSliding
|
||||||
+ " ignoreModifier=" + ignoreModifierKey);
|
+ " ignoreModifier=" + ignoreModifierKey);
|
||||||
|
@ -257,13 +257,14 @@ public class PointerTracker {
|
||||||
// Note that we need primaryCode argument because the keyboard may in shifted state and the
|
// Note that we need primaryCode argument because the keyboard may in shifted state and the
|
||||||
// primaryCode is different from {@link Key#mCode}.
|
// primaryCode is different from {@link Key#mCode}.
|
||||||
private void callListenerOnCodeInput(Key key, int primaryCode, int[] keyCodes, int x, int y) {
|
private void callListenerOnCodeInput(Key key, int primaryCode, int[] keyCodes, int x, int y) {
|
||||||
final boolean ignoreModifierKey = mIgnoreModifierKey && isModifierCode(key.mCode);
|
final boolean ignoreModifierKey = mIgnoreModifierKey && key.isModifier();
|
||||||
if (DEBUG_LISTENER)
|
if (DEBUG_LISTENER)
|
||||||
Log.d(TAG, "onCodeInput: " + keyCodePrintable(primaryCode)
|
Log.d(TAG, "onCodeInput: " + keyCodePrintable(primaryCode)
|
||||||
+ " codes="+ Arrays.toString(keyCodes) + " x=" + x + " y=" + y
|
+ " codes="+ Arrays.toString(keyCodes) + " x=" + x + " y=" + y
|
||||||
+ " ignoreModifier=" + ignoreModifierKey);
|
+ " ignoreModifier=" + ignoreModifierKey);
|
||||||
if (ignoreModifierKey)
|
if (ignoreModifierKey) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
if (key.isEnabled()) {
|
if (key.isEnabled()) {
|
||||||
mListener.onCodeInput(primaryCode, keyCodes, x, y);
|
mListener.onCodeInput(primaryCode, keyCodes, x, y);
|
||||||
}
|
}
|
||||||
|
@ -280,12 +281,13 @@ public class PointerTracker {
|
||||||
// Note that we need primaryCode argument because the keyboard may in shifted state and the
|
// Note that we need primaryCode argument because the keyboard may in shifted state and the
|
||||||
// primaryCode is different from {@link Key#mCode}.
|
// primaryCode is different from {@link Key#mCode}.
|
||||||
private void callListenerOnRelease(Key key, int primaryCode, boolean withSliding) {
|
private void callListenerOnRelease(Key key, int primaryCode, boolean withSliding) {
|
||||||
final boolean ignoreModifierKey = mIgnoreModifierKey && isModifierCode(key.mCode);
|
final boolean ignoreModifierKey = mIgnoreModifierKey && key.isModifier();
|
||||||
if (DEBUG_LISTENER)
|
if (DEBUG_LISTENER)
|
||||||
Log.d(TAG, "onRelease : " + keyCodePrintable(primaryCode) + " sliding="
|
Log.d(TAG, "onRelease : " + keyCodePrintable(primaryCode) + " sliding="
|
||||||
+ withSliding + " ignoreModifier=" + ignoreModifierKey);
|
+ withSliding + " ignoreModifier=" + ignoreModifierKey);
|
||||||
if (ignoreModifierKey)
|
if (ignoreModifierKey) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
if (key.isEnabled()) {
|
if (key.isEnabled()) {
|
||||||
mListener.onRelease(primaryCode, withSliding);
|
mListener.onRelease(primaryCode, withSliding);
|
||||||
}
|
}
|
||||||
|
@ -309,55 +311,30 @@ public class PointerTracker {
|
||||||
return mIsInSlidingKeyInput;
|
return mIsInSlidingKeyInput;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isValidKeyIndex(int keyIndex) {
|
public Key getKey() {
|
||||||
return keyIndex >= 0 && keyIndex < mKeys.size();
|
return mCurrentKey;
|
||||||
}
|
|
||||||
|
|
||||||
public Key getKey(int keyIndex) {
|
|
||||||
return isValidKeyIndex(keyIndex) ? mKeys.get(keyIndex) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean isModifierCode(int primaryCode) {
|
|
||||||
return primaryCode == Keyboard.CODE_SHIFT
|
|
||||||
|| primaryCode == Keyboard.CODE_SWITCH_ALPHA_SYMBOL;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isModifierInternal(int keyIndex) {
|
|
||||||
final Key key = getKey(keyIndex);
|
|
||||||
return key == null ? false : isModifierCode(key.mCode);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isModifier() {
|
public boolean isModifier() {
|
||||||
return isModifierInternal(mKeyIndex);
|
return mCurrentKey != null && mCurrentKey.isModifier();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isOnModifierKey(int x, int y) {
|
public Key getKeyOn(int x, int y) {
|
||||||
return isModifierInternal(mKeyDetector.getKeyIndexAndNearbyCodes(x, y, null));
|
return mKeyDetector.getKeyAndNearbyCodes(x, y, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isOnShiftKey(int x, int y) {
|
private void setReleasedKeyGraphics(Key key) {
|
||||||
final Key key = getKey(mKeyDetector.getKeyIndexAndNearbyCodes(x, y, null));
|
|
||||||
return key != null && key.mCode == Keyboard.CODE_SHIFT;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getKeyIndexOn(int x, int y) {
|
|
||||||
return mKeyDetector.getKeyIndexAndNearbyCodes(x, y, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setReleasedKeyGraphics(int keyIndex) {
|
|
||||||
mDrawingProxy.dismissKeyPreview(this);
|
mDrawingProxy.dismissKeyPreview(this);
|
||||||
final Key key = getKey(keyIndex);
|
|
||||||
if (key != null && key.isEnabled()) {
|
if (key != null && key.isEnabled()) {
|
||||||
key.onReleased();
|
key.onReleased();
|
||||||
mDrawingProxy.invalidateKey(key);
|
mDrawingProxy.invalidateKey(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setPressedKeyGraphics(int keyIndex) {
|
private void setPressedKeyGraphics(Key key) {
|
||||||
final Key key = getKey(keyIndex);
|
|
||||||
if (key != null && key.isEnabled()) {
|
if (key != null && key.isEnabled()) {
|
||||||
if (!key.noKeyPreview()) {
|
if (!key.noKeyPreview()) {
|
||||||
mDrawingProxy.showKeyPreview(keyIndex, this);
|
mDrawingProxy.showKeyPreview(this);
|
||||||
}
|
}
|
||||||
key.onPressed();
|
key.onPressed();
|
||||||
mDrawingProxy.invalidateKey(key);
|
mDrawingProxy.invalidateKey(key);
|
||||||
|
@ -376,31 +353,31 @@ public class PointerTracker {
|
||||||
return mDownTime;
|
return mDownTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int onDownKey(int x, int y, long eventTime) {
|
private Key onDownKey(int x, int y, long eventTime) {
|
||||||
mDownTime = eventTime;
|
mDownTime = eventTime;
|
||||||
return onMoveToNewKey(onMoveKeyInternal(x, y), x, y);
|
return onMoveToNewKey(onMoveKeyInternal(x, y), x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int onMoveKeyInternal(int x, int y) {
|
private Key onMoveKeyInternal(int x, int y) {
|
||||||
mLastX = x;
|
mLastX = x;
|
||||||
mLastY = y;
|
mLastY = y;
|
||||||
return mKeyDetector.getKeyIndexAndNearbyCodes(x, y, null);
|
return mKeyDetector.getKeyAndNearbyCodes(x, y, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int onMoveKey(int x, int y) {
|
private Key onMoveKey(int x, int y) {
|
||||||
return onMoveKeyInternal(x, y);
|
return onMoveKeyInternal(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int onMoveToNewKey(int keyIndex, int x, int y) {
|
private Key onMoveToNewKey(Key newKey, int x, int y) {
|
||||||
mKeyIndex = keyIndex;
|
mCurrentKey = newKey;
|
||||||
mKeyX = x;
|
mKeyX = x;
|
||||||
mKeyY = y;
|
mKeyY = y;
|
||||||
return keyIndex;
|
return newKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int onUpKey(int x, int y, long eventTime) {
|
private Key onUpKey(int x, int y, long eventTime) {
|
||||||
mUpTime = eventTime;
|
mUpTime = eventTime;
|
||||||
mKeyIndex = KeyDetector.NOT_A_KEY;
|
mCurrentKey = null;
|
||||||
return onMoveKeyInternal(x, y);
|
return onMoveKeyInternal(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -449,7 +426,8 @@ public class PointerTracker {
|
||||||
|
|
||||||
final PointerTrackerQueue queue = sPointerTrackerQueue;
|
final PointerTrackerQueue queue = sPointerTrackerQueue;
|
||||||
if (queue != null) {
|
if (queue != null) {
|
||||||
if (isOnModifierKey(x, y)) {
|
final Key key = getKeyOn(x, y);
|
||||||
|
if (key != null && key.isModifier()) {
|
||||||
// Before processing a down event of modifier key, all pointers already being
|
// Before processing a down event of modifier key, all pointers already being
|
||||||
// tracked should be released.
|
// tracked should be released.
|
||||||
queue.releaseAllPointers(eventTime);
|
queue.releaseAllPointers(eventTime);
|
||||||
|
@ -460,32 +438,34 @@ public class PointerTracker {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onDownEventInternal(int x, int y, long eventTime) {
|
private void onDownEventInternal(int x, int y, long eventTime) {
|
||||||
int keyIndex = onDownKey(x, y, eventTime);
|
Key key = onDownKey(x, y, eventTime);
|
||||||
// Sliding key is allowed when 1) enabled by configuration, 2) this pointer starts sliding
|
// Sliding key is allowed when 1) enabled by configuration, 2) this pointer starts sliding
|
||||||
// from modifier key, or 3) this pointer's KeyDetector always allows sliding input.
|
// from modifier key, or 3) this pointer's KeyDetector always allows sliding input.
|
||||||
mIsAllowedSlidingKeyInput = sConfigSlidingKeyInputEnabled || isModifierInternal(keyIndex)
|
mIsAllowedSlidingKeyInput = sConfigSlidingKeyInputEnabled || key.isModifier()
|
||||||
|| mKeyDetector.alwaysAllowsSlidingInput();
|
|| mKeyDetector.alwaysAllowsSlidingInput();
|
||||||
mKeyboardLayoutHasBeenChanged = false;
|
mKeyboardLayoutHasBeenChanged = false;
|
||||||
mKeyAlreadyProcessed = false;
|
mKeyAlreadyProcessed = false;
|
||||||
mIsRepeatableKey = false;
|
mIsRepeatableKey = false;
|
||||||
mIsInSlidingKeyInput = false;
|
mIsInSlidingKeyInput = false;
|
||||||
mIgnoreModifierKey = false;
|
mIgnoreModifierKey = false;
|
||||||
if (isValidKeyIndex(keyIndex)) {
|
if (key != null) {
|
||||||
// This onPress call may have changed keyboard layout. Those cases are detected at
|
// This onPress call may have changed keyboard layout. Those cases are detected at
|
||||||
// {@link #setKeyboard}. In those cases, we should update keyIndex according to the new
|
// {@link #setKeyboard}. In those cases, we should update key according to the new
|
||||||
// keyboard layout.
|
// keyboard layout.
|
||||||
if (callListenerOnPressAndCheckKeyboardLayoutChange(getKey(keyIndex), false))
|
if (callListenerOnPressAndCheckKeyboardLayoutChange(key, false)) {
|
||||||
keyIndex = onDownKey(x, y, eventTime);
|
key = onDownKey(x, y, eventTime);
|
||||||
|
}
|
||||||
|
|
||||||
startRepeatKey(keyIndex);
|
startRepeatKey(key);
|
||||||
startLongPressTimer(keyIndex);
|
startLongPressTimer(key);
|
||||||
setPressedKeyGraphics(keyIndex);
|
setPressedKeyGraphics(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startSlidingKeyInput(Key key) {
|
private void startSlidingKeyInput(Key key) {
|
||||||
if (!mIsInSlidingKeyInput)
|
if (!mIsInSlidingKeyInput) {
|
||||||
mIgnoreModifierKey = isModifierCode(key.mCode);
|
mIgnoreModifierKey = key.isModifier();
|
||||||
|
}
|
||||||
mIsInSlidingKeyInput = true;
|
mIsInSlidingKeyInput = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -497,39 +477,40 @@ public class PointerTracker {
|
||||||
|
|
||||||
final int lastX = mLastX;
|
final int lastX = mLastX;
|
||||||
final int lastY = mLastY;
|
final int lastY = mLastY;
|
||||||
final int oldKeyIndex = mKeyIndex;
|
final Key oldKey = mCurrentKey;
|
||||||
final Key oldKey = getKey(oldKeyIndex);
|
Key key = onMoveKey(x, y);
|
||||||
int keyIndex = onMoveKey(x, y);
|
if (key != null) {
|
||||||
if (isValidKeyIndex(keyIndex)) {
|
|
||||||
if (oldKey == null) {
|
if (oldKey == null) {
|
||||||
// The pointer has been slid in to the new key, but the finger was not on any keys.
|
// The pointer has been slid in to the new key, but the finger was not on any keys.
|
||||||
// In this case, we must call onPress() to notify that the new key is being pressed.
|
// In this case, we must call onPress() to notify that the new key is being pressed.
|
||||||
// This onPress call may have changed keyboard layout. Those cases are detected at
|
// This onPress call may have changed keyboard layout. Those cases are detected at
|
||||||
// {@link #setKeyboard}. In those cases, we should update keyIndex according to the
|
// {@link #setKeyboard}. In those cases, we should update key according to the
|
||||||
// new keyboard layout.
|
// new keyboard layout.
|
||||||
if (callListenerOnPressAndCheckKeyboardLayoutChange(getKey(keyIndex), true))
|
if (callListenerOnPressAndCheckKeyboardLayoutChange(key, true)) {
|
||||||
keyIndex = onMoveKey(x, y);
|
key = onMoveKey(x, y);
|
||||||
onMoveToNewKey(keyIndex, x, y);
|
}
|
||||||
startLongPressTimer(keyIndex);
|
onMoveToNewKey(key, x, y);
|
||||||
setPressedKeyGraphics(keyIndex);
|
startLongPressTimer(key);
|
||||||
} else if (isMajorEnoughMoveToBeOnNewKey(x, y, keyIndex)) {
|
setPressedKeyGraphics(key);
|
||||||
|
} else if (isMajorEnoughMoveToBeOnNewKey(x, y, key)) {
|
||||||
// The pointer has been slid in to the new key from the previous key, we must call
|
// The pointer has been slid in to the new key from the previous key, we must call
|
||||||
// onRelease() first to notify that the previous key has been released, then call
|
// onRelease() first to notify that the previous key has been released, then call
|
||||||
// onPress() to notify that the new key is being pressed.
|
// onPress() to notify that the new key is being pressed.
|
||||||
setReleasedKeyGraphics(oldKeyIndex);
|
setReleasedKeyGraphics(oldKey);
|
||||||
callListenerOnRelease(oldKey, oldKey.mCode, true);
|
callListenerOnRelease(oldKey, oldKey.mCode, true);
|
||||||
startSlidingKeyInput(oldKey);
|
startSlidingKeyInput(oldKey);
|
||||||
mTimerProxy.cancelKeyTimers();
|
mTimerProxy.cancelKeyTimers();
|
||||||
startRepeatKey(keyIndex);
|
startRepeatKey(key);
|
||||||
if (mIsAllowedSlidingKeyInput) {
|
if (mIsAllowedSlidingKeyInput) {
|
||||||
// This onPress call may have changed keyboard layout. Those cases are detected
|
// This onPress call may have changed keyboard layout. Those cases are detected
|
||||||
// at {@link #setKeyboard}. In those cases, we should update keyIndex according
|
// at {@link #setKeyboard}. In those cases, we should update key according
|
||||||
// to the new keyboard layout.
|
// to the new keyboard layout.
|
||||||
if (callListenerOnPressAndCheckKeyboardLayoutChange(getKey(keyIndex), true))
|
if (callListenerOnPressAndCheckKeyboardLayoutChange(key, true)) {
|
||||||
keyIndex = onMoveKey(x, y);
|
key = onMoveKey(x, y);
|
||||||
onMoveToNewKey(keyIndex, x, y);
|
}
|
||||||
startLongPressTimer(keyIndex);
|
onMoveToNewKey(key, x, y);
|
||||||
setPressedKeyGraphics(keyIndex);
|
startLongPressTimer(key);
|
||||||
|
setPressedKeyGraphics(key);
|
||||||
} else {
|
} else {
|
||||||
// HACK: On some devices, quick successive touches may be translated to sudden
|
// HACK: On some devices, quick successive touches may be translated to sudden
|
||||||
// move by touch panel firmware. This hack detects the case and translates the
|
// move by touch panel firmware. This hack detects the case and translates the
|
||||||
|
@ -545,20 +526,20 @@ public class PointerTracker {
|
||||||
onDownEventInternal(x, y, eventTime);
|
onDownEventInternal(x, y, eventTime);
|
||||||
} else {
|
} else {
|
||||||
mKeyAlreadyProcessed = true;
|
mKeyAlreadyProcessed = true;
|
||||||
setReleasedKeyGraphics(oldKeyIndex);
|
setReleasedKeyGraphics(oldKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (oldKey != null && isMajorEnoughMoveToBeOnNewKey(x, y, keyIndex)) {
|
if (oldKey != null && isMajorEnoughMoveToBeOnNewKey(x, y, key)) {
|
||||||
// The pointer has been slid out from the previous key, we must call onRelease() to
|
// The pointer has been slid out from the previous key, we must call onRelease() to
|
||||||
// notify that the previous key has been released.
|
// notify that the previous key has been released.
|
||||||
setReleasedKeyGraphics(oldKeyIndex);
|
setReleasedKeyGraphics(oldKey);
|
||||||
callListenerOnRelease(oldKey, oldKey.mCode, true);
|
callListenerOnRelease(oldKey, oldKey.mCode, true);
|
||||||
startSlidingKeyInput(oldKey);
|
startSlidingKeyInput(oldKey);
|
||||||
mTimerProxy.cancelLongPressTimer();
|
mTimerProxy.cancelLongPressTimer();
|
||||||
if (mIsAllowedSlidingKeyInput) {
|
if (mIsAllowedSlidingKeyInput) {
|
||||||
onMoveToNewKey(keyIndex, x, y);
|
onMoveToNewKey(key, x, y);
|
||||||
} else {
|
} else {
|
||||||
mKeyAlreadyProcessed = true;
|
mKeyAlreadyProcessed = true;
|
||||||
}
|
}
|
||||||
|
@ -572,7 +553,7 @@ public class PointerTracker {
|
||||||
|
|
||||||
final PointerTrackerQueue queue = sPointerTrackerQueue;
|
final PointerTrackerQueue queue = sPointerTrackerQueue;
|
||||||
if (queue != null) {
|
if (queue != null) {
|
||||||
if (isModifier()) {
|
if (mCurrentKey != null && mCurrentKey.isModifier()) {
|
||||||
// Before processing an up event of modifier key, all pointers already being
|
// Before processing an up event of modifier key, all pointers already being
|
||||||
// tracked should be released.
|
// tracked should be released.
|
||||||
queue.releaseAllPointersExcept(this, eventTime);
|
queue.releaseAllPointersExcept(this, eventTime);
|
||||||
|
@ -607,8 +588,8 @@ public class PointerTracker {
|
||||||
keyX = mKeyX;
|
keyX = mKeyX;
|
||||||
keyY = mKeyY;
|
keyY = mKeyY;
|
||||||
}
|
}
|
||||||
final int keyIndex = onUpKey(keyX, keyY, eventTime);
|
final Key key = onUpKey(keyX, keyY, eventTime);
|
||||||
setReleasedKeyGraphics(keyIndex);
|
setReleasedKeyGraphics(key);
|
||||||
if (mIsShowingMoreKeysPanel) {
|
if (mIsShowingMoreKeysPanel) {
|
||||||
mDrawingProxy.dismissMoreKeysPanel();
|
mDrawingProxy.dismissMoreKeysPanel();
|
||||||
mIsShowingMoreKeysPanel = false;
|
mIsShowingMoreKeysPanel = false;
|
||||||
|
@ -616,7 +597,7 @@ public class PointerTracker {
|
||||||
if (mKeyAlreadyProcessed)
|
if (mKeyAlreadyProcessed)
|
||||||
return;
|
return;
|
||||||
if (!mIsRepeatableKey) {
|
if (!mIsRepeatableKey) {
|
||||||
detectAndSendKey(keyIndex, keyX, keyY);
|
detectAndSendKey(key, keyX, keyY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -628,7 +609,7 @@ public class PointerTracker {
|
||||||
|
|
||||||
public void onLongPressed() {
|
public void onLongPressed() {
|
||||||
mKeyAlreadyProcessed = true;
|
mKeyAlreadyProcessed = true;
|
||||||
setReleasedKeyGraphics(mKeyIndex);
|
setReleasedKeyGraphics(mCurrentKey);
|
||||||
final PointerTrackerQueue queue = sPointerTrackerQueue;
|
final PointerTrackerQueue queue = sPointerTrackerQueue;
|
||||||
if (queue != null) {
|
if (queue != null) {
|
||||||
queue.remove(this);
|
queue.remove(this);
|
||||||
|
@ -650,7 +631,7 @@ public class PointerTracker {
|
||||||
private void onCancelEventInternal() {
|
private void onCancelEventInternal() {
|
||||||
mTimerProxy.cancelKeyTimers();
|
mTimerProxy.cancelKeyTimers();
|
||||||
mDrawingProxy.cancelShowKeyPreview(this);
|
mDrawingProxy.cancelShowKeyPreview(this);
|
||||||
setReleasedKeyGraphics(mKeyIndex);
|
setReleasedKeyGraphics(mCurrentKey);
|
||||||
mIsInSlidingKeyInput = false;
|
mIsInSlidingKeyInput = false;
|
||||||
if (mIsShowingMoreKeysPanel) {
|
if (mIsShowingMoreKeysPanel) {
|
||||||
mDrawingProxy.dismissMoreKeysPanel();
|
mDrawingProxy.dismissMoreKeysPanel();
|
||||||
|
@ -658,48 +639,45 @@ public class PointerTracker {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startRepeatKey(int keyIndex) {
|
private void startRepeatKey(Key key) {
|
||||||
final Key key = getKey(keyIndex);
|
|
||||||
if (key != null && key.isRepeatable()) {
|
if (key != null && key.isRepeatable()) {
|
||||||
onRepeatKey(keyIndex);
|
onRepeatKey(key);
|
||||||
mTimerProxy.startKeyRepeatTimer(sDelayBeforeKeyRepeatStart, keyIndex, this);
|
mTimerProxy.startKeyRepeatTimer(sDelayBeforeKeyRepeatStart, this);
|
||||||
mIsRepeatableKey = true;
|
mIsRepeatableKey = true;
|
||||||
} else {
|
} else {
|
||||||
mIsRepeatableKey = false;
|
mIsRepeatableKey = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onRepeatKey(int keyIndex) {
|
public void onRepeatKey(Key key) {
|
||||||
Key key = getKey(keyIndex);
|
|
||||||
if (key != null) {
|
if (key != null) {
|
||||||
detectAndSendKey(keyIndex, key.mX, key.mY);
|
detectAndSendKey(key, key.mX, key.mY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isMajorEnoughMoveToBeOnNewKey(int x, int y, int newKey) {
|
private boolean isMajorEnoughMoveToBeOnNewKey(int x, int y, Key newKey) {
|
||||||
if (mKeys == null || mKeyDetector == null)
|
if (mKeys == null || mKeyDetector == null)
|
||||||
throw new NullPointerException("keyboard and/or key detector not set");
|
throw new NullPointerException("keyboard and/or key detector not set");
|
||||||
int curKey = mKeyIndex;
|
Key curKey = mCurrentKey;
|
||||||
if (newKey == curKey) {
|
if (newKey == curKey) {
|
||||||
return false;
|
return false;
|
||||||
} else if (isValidKeyIndex(curKey)) {
|
} else if (curKey != null) {
|
||||||
return mKeys.get(curKey).squaredDistanceToEdge(x, y)
|
return curKey.squaredDistanceToEdge(x, y)
|
||||||
>= mKeyDetector.getKeyHysteresisDistanceSquared();
|
>= mKeyDetector.getKeyHysteresisDistanceSquared();
|
||||||
} else {
|
} else {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startLongPressTimer(int keyIndex) {
|
private void startLongPressTimer(Key key) {
|
||||||
Key key = getKey(keyIndex);
|
|
||||||
if (key == null) return;
|
if (key == null) return;
|
||||||
if (key.mCode == Keyboard.CODE_SHIFT) {
|
if (key.mCode == Keyboard.CODE_SHIFT) {
|
||||||
if (sLongPressShiftKeyTimeout > 0) {
|
if (sLongPressShiftKeyTimeout > 0) {
|
||||||
mTimerProxy.startLongPressTimer(sLongPressShiftKeyTimeout, keyIndex, this);
|
mTimerProxy.startLongPressTimer(sLongPressShiftKeyTimeout, this);
|
||||||
}
|
}
|
||||||
} else if (key.mCode == Keyboard.CODE_SPACE) {
|
} else if (key.mCode == Keyboard.CODE_SPACE) {
|
||||||
if (sLongPressSpaceKeyTimeout > 0) {
|
if (sLongPressSpaceKeyTimeout > 0) {
|
||||||
mTimerProxy.startLongPressTimer(sLongPressSpaceKeyTimeout, keyIndex, this);
|
mTimerProxy.startLongPressTimer(sLongPressSpaceKeyTimeout, this);
|
||||||
}
|
}
|
||||||
} else if (key.hasUppercaseLetter() && mKeyboard.isManualTemporaryUpperCase()) {
|
} else if (key.hasUppercaseLetter() && mKeyboard.isManualTemporaryUpperCase()) {
|
||||||
// We need not start long press timer on the key which has manual temporary upper case
|
// We need not start long press timer on the key which has manual temporary upper case
|
||||||
|
@ -707,14 +685,13 @@ public class PointerTracker {
|
||||||
return;
|
return;
|
||||||
} else if (sKeyboardSwitcher.isInMomentarySwitchState()) {
|
} else if (sKeyboardSwitcher.isInMomentarySwitchState()) {
|
||||||
// We use longer timeout for sliding finger input started from the symbols mode key.
|
// We use longer timeout for sliding finger input started from the symbols mode key.
|
||||||
mTimerProxy.startLongPressTimer(sLongPressKeyTimeout * 3, keyIndex, this);
|
mTimerProxy.startLongPressTimer(sLongPressKeyTimeout * 3, this);
|
||||||
} else {
|
} else {
|
||||||
mTimerProxy.startLongPressTimer(sLongPressKeyTimeout, keyIndex, this);
|
mTimerProxy.startLongPressTimer(sLongPressKeyTimeout, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void detectAndSendKey(int keyIndex, int x, int y) {
|
private void detectAndSendKey(Key key, int x, int y) {
|
||||||
final Key key = getKey(keyIndex);
|
|
||||||
if (key == null) {
|
if (key == null) {
|
||||||
callListenerOnCancelInput();
|
callListenerOnCancelInput();
|
||||||
return;
|
return;
|
||||||
|
@ -731,7 +708,7 @@ public class PointerTracker {
|
||||||
} else {
|
} else {
|
||||||
int code = key.mCode;
|
int code = key.mCode;
|
||||||
final int[] codes = mKeyDetector.newCodeArray();
|
final int[] codes = mKeyDetector.newCodeArray();
|
||||||
mKeyDetector.getKeyIndexAndNearbyCodes(x, y, codes);
|
mKeyDetector.getKeyAndNearbyCodes(x, y, codes);
|
||||||
|
|
||||||
// If keyboard is in manual temporary upper case state and key has manual temporary
|
// If keyboard is in manual temporary upper case state and key has manual temporary
|
||||||
// uppercase letter as key hint letter, alternate character code should be sent.
|
// uppercase letter as key hint letter, alternate character code should be sent.
|
||||||
|
@ -754,7 +731,7 @@ public class PointerTracker {
|
||||||
callListenerOnCodeInput(key, code, codes, x, y);
|
callListenerOnCodeInput(key, code, codes, x, y);
|
||||||
}
|
}
|
||||||
callListenerOnRelease(key, code, false);
|
callListenerOnRelease(key, code, false);
|
||||||
if (!key.ignoreWhileTyping() && !isModifierCode(code)) {
|
if (!key.ignoreWhileTyping() && !key.isModifier()) {
|
||||||
mTimerProxy.startKeyTypedTimer(sIgnoreSpecialKeyTimeout);
|
mTimerProxy.startKeyTypedTimer(sIgnoreSpecialKeyTimeout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -763,17 +740,17 @@ public class PointerTracker {
|
||||||
private long mPreviousEventTime;
|
private long mPreviousEventTime;
|
||||||
|
|
||||||
private void printTouchEvent(String title, int x, int y, long eventTime) {
|
private void printTouchEvent(String title, int x, int y, long eventTime) {
|
||||||
final int keyIndex = mKeyDetector.getKeyIndexAndNearbyCodes(x, y, null);
|
final Key key = mKeyDetector.getKeyAndNearbyCodes(x, y, null);
|
||||||
final Key key = getKey(keyIndex);
|
|
||||||
final String code = (key == null) ? "----" : keyCodePrintable(key.mCode);
|
final String code = (key == null) ? "----" : keyCodePrintable(key.mCode);
|
||||||
final long delta = eventTime - mPreviousEventTime;
|
final long delta = eventTime - mPreviousEventTime;
|
||||||
Log.d(TAG, String.format("%s%s[%d] %4d %4d %5d %3d(%s)", title,
|
Log.d(TAG, String.format("%s%s[%d] %4d %4d %5d %s", title,
|
||||||
(mKeyAlreadyProcessed ? "-" : " "), mPointerId, x, y, delta, keyIndex, code));
|
(mKeyAlreadyProcessed ? "-" : " "), mPointerId, x, y, delta, code));
|
||||||
mPreviousEventTime = eventTime;
|
mPreviousEventTime = eventTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String keyCodePrintable(int primaryCode) {
|
private static String keyCodePrintable(int primaryCode) {
|
||||||
final String modifier = isModifierCode(primaryCode) ? " modifier" : "";
|
if (primaryCode < 0) return String.format("%4d", primaryCode);
|
||||||
return String.format((primaryCode < 0) ? "%4d" : "0x%02x", primaryCode) + modifier;
|
if (primaryCode < 0x100) return String.format("\\u%02x", primaryCode);
|
||||||
|
return String.format("\\u04x", primaryCode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -152,7 +152,7 @@ public class WordComposer {
|
||||||
final int x = key.mX + key.mWidth / 2;
|
final int x = key.mX + key.mWidth / 2;
|
||||||
final int y = key.mY + key.mHeight / 2;
|
final int y = key.mY + key.mHeight / 2;
|
||||||
final int[] codes = keyDetector.newCodeArray();
|
final int[] codes = keyDetector.newCodeArray();
|
||||||
keyDetector.getKeyIndexAndNearbyCodes(x, y, codes);
|
keyDetector.getKeyAndNearbyCodes(x, y, codes);
|
||||||
add(codePoint, codes, x, y);
|
add(codePoint, codes, x, y);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,6 @@ package com.android.inputmethod.latin;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
|
||||||
import com.android.inputmethod.keyboard.Key;
|
|
||||||
import com.android.inputmethod.keyboard.KeyDetector;
|
import com.android.inputmethod.keyboard.KeyDetector;
|
||||||
import com.android.inputmethod.keyboard.KeyboardId;
|
import com.android.inputmethod.keyboard.KeyboardId;
|
||||||
import com.android.inputmethod.keyboard.LatinKeyboard;
|
import com.android.inputmethod.keyboard.LatinKeyboard;
|
||||||
|
|
Loading…
Reference in New Issue