diff options
Diffstat (limited to 'java/src/com/android/inputmethod/latin/PointerTracker.java')
-rw-r--r-- | java/src/com/android/inputmethod/latin/PointerTracker.java | 104 |
1 files changed, 62 insertions, 42 deletions
diff --git a/java/src/com/android/inputmethod/latin/PointerTracker.java b/java/src/com/android/inputmethod/latin/PointerTracker.java index f6fd5bd7a..327fef107 100644 --- a/java/src/com/android/inputmethod/latin/PointerTracker.java +++ b/java/src/com/android/inputmethod/latin/PointerTracker.java @@ -16,12 +16,11 @@ package com.android.inputmethod.latin; -import com.android.inputmethod.latin.LatinKeyboardBaseView.OnKeyboardActionListener; -import com.android.inputmethod.latin.LatinKeyboardBaseView.UIHandler; +import com.android.inputmethod.latin.BaseKeyboard.Key; +import com.android.inputmethod.latin.BaseKeyboardView.OnKeyboardActionListener; +import com.android.inputmethod.latin.BaseKeyboardView.UIHandler; import android.content.res.Resources; -import android.inputmethodservice.Keyboard; -import android.inputmethodservice.Keyboard.Key; import android.util.Log; import android.view.MotionEvent; @@ -41,11 +40,12 @@ public class PointerTracker { // Timing constants private final int mDelayBeforeKeyRepeatStart; private final int mLongPressKeyTimeout; + private final int mLongPressShiftKeyTimeout; private final int mMultiTapKeyTimeout; // Miscellaneous constants - private static final int NOT_A_KEY = LatinKeyboardBaseView.NOT_A_KEY; - private static final int[] KEY_DELETE = { Keyboard.KEYCODE_DELETE }; + private static final int NOT_A_KEY = BaseKeyboardView.NOT_A_KEY; + private static final int[] KEY_DELETE = { BaseKeyboard.KEYCODE_DELETE }; private final UIProxy mProxy; private final UIHandler mHandler; @@ -53,6 +53,7 @@ public class PointerTracker { private OnKeyboardActionListener mListener; private final boolean mHasDistinctMultitouch; + private BaseKeyboard mKeyboard; private Key[] mKeys; private int mKeyHysteresisDistanceSquared = -1; @@ -175,6 +176,7 @@ public class PointerTracker { mHasDistinctMultitouch = proxy.hasDistinctMultitouch(); mDelayBeforeKeyRepeatStart = res.getInteger(R.integer.config_delay_before_key_repeat_start); mLongPressKeyTimeout = res.getInteger(R.integer.config_long_press_key_timeout); + mLongPressShiftKeyTimeout = res.getInteger(R.integer.config_long_press_shift_key_timeout); mMultiTapKeyTimeout = res.getInteger(R.integer.config_multi_tap_key_timeout); resetMultiTap(); } @@ -183,9 +185,10 @@ public class PointerTracker { mListener = listener; } - public void setKeyboard(Key[] keys, float keyHysteresisDistance) { - if (keys == null || keyHysteresisDistance < 0) + public void setKeyboard(BaseKeyboard keyboard, Key[] keys, float keyHysteresisDistance) { + if (keyboard == null || keys == null || keyHysteresisDistance < 0) throw new IllegalArgumentException(); + mKeyboard = keyboard; mKeys = keys; mKeyHysteresisDistanceSquared = (int)(keyHysteresisDistance * keyHysteresisDistance); // Update current key index because keyboard layout has been changed. @@ -205,8 +208,8 @@ public class PointerTracker { if (key == null) return false; int primaryCode = key.codes[0]; - return primaryCode == Keyboard.KEYCODE_SHIFT - || primaryCode == Keyboard.KEYCODE_MODE_CHANGE; + return primaryCode == BaseKeyboard.KEYCODE_SHIFT + || primaryCode == BaseKeyboard.KEYCODE_MODE_CHANGE; } public boolean isModifier() { @@ -222,9 +225,11 @@ public class PointerTracker { return key != null && key.codes[0] == LatinIME.KEYCODE_SPACE; } - public void updateKey(int keyIndex) { - if (mKeyAlreadyProcessed) - return; + public void releaseKey() { + updateKeyGraphics(NOT_A_KEY); + } + + private void updateKeyGraphics(int keyIndex) { int oldKeyIndex = mPreviousKey; mPreviousKey = keyIndex; if (keyIndex != oldKeyIndex) { @@ -285,9 +290,9 @@ public class PointerTracker { mHandler.startKeyRepeatTimer(mDelayBeforeKeyRepeatStart, keyIndex, this); mIsRepeatableKey = true; } - mHandler.startLongPressTimer(mLongPressKeyTimeout, keyIndex, this); + startLongPressTimer(keyIndex); } - showKeyPreviewAndUpdateKey(keyIndex); + showKeyPreviewAndUpdateKeyGraphics(keyIndex); } public void onMoveEvent(int x, int y, long eventTime) { @@ -296,32 +301,38 @@ public class PointerTracker { if (mKeyAlreadyProcessed) return; KeyState keyState = mKeyState; - int keyIndex = keyState.onMoveKey(x, y); + final int keyIndex = keyState.onMoveKey(x, y); + final Key oldKey = getKey(keyState.getKeyIndex()); if (isValidKeyIndex(keyIndex)) { - if (keyState.getKeyIndex() == NOT_A_KEY) { + if (oldKey == null) { keyState.onMoveToNewKey(keyIndex, x, y); - mHandler.startLongPressTimer(mLongPressKeyTimeout, keyIndex, this); + startLongPressTimer(keyIndex); } else if (!isMinorMoveBounce(x, y, keyIndex)) { + if (mListener != null) + mListener.onRelease(oldKey.codes[0]); resetMultiTap(); keyState.onMoveToNewKey(keyIndex, x, y); - mHandler.startLongPressTimer(mLongPressKeyTimeout, keyIndex, this); + startLongPressTimer(keyIndex); } } else { - if (keyState.getKeyIndex() != NOT_A_KEY) { + if (oldKey != null) { + if (mListener != null) + mListener.onRelease(oldKey.codes[0]); keyState.onMoveToNewKey(keyIndex, x ,y); - mHandler.cancelLongPressTimer(); + mHandler.cancelLongPressTimers(); } else if (!isMinorMoveBounce(x, y, keyIndex)) { resetMultiTap(); keyState.onMoveToNewKey(keyIndex, x ,y); - mHandler.cancelLongPressTimer(); + mHandler.cancelLongPressTimers(); } } - showKeyPreviewAndUpdateKey(mKeyState.getKeyIndex()); + showKeyPreviewAndUpdateKeyGraphics(mKeyState.getKeyIndex()); } public void onUpEvent(int x, int y, long eventTime) { if (DEBUG) debugLog("onUpEvent :", x, y); + showKeyPreviewAndUpdateKeyGraphics(NOT_A_KEY); if (mKeyAlreadyProcessed) return; mHandler.cancelKeyTimers(); @@ -333,7 +344,6 @@ public class PointerTracker { x = mKeyState.getKeyX(); y = mKeyState.getKeyY(); } - showKeyPreviewAndUpdateKey(NOT_A_KEY); if (!mIsRepeatableKey) { detectAndSendKey(keyIndex, x, y, eventTime); } @@ -347,7 +357,7 @@ public class PointerTracker { debugLog("onCancelEvt:", x, y); mHandler.cancelKeyTimers(); mHandler.cancelPopupPreview(); - showKeyPreviewAndUpdateKey(NOT_A_KEY); + showKeyPreviewAndUpdateKeyGraphics(NOT_A_KEY); int keyIndex = mKeyState.getKeyIndex(); if (isValidKeyIndex(keyIndex)) mProxy.invalidateKey(mKeys[keyIndex]); @@ -390,28 +400,16 @@ public class PointerTracker { if (newKey == curKey) { return true; } else if (isValidKeyIndex(curKey)) { - return getSquareDistanceToKeyEdge(x, y, mKeys[curKey]) < mKeyHysteresisDistanceSquared; + return mKeys[curKey].squaredDistanceToEdge(x, y) < mKeyHysteresisDistanceSquared; } else { return false; } } - private static int getSquareDistanceToKeyEdge(int x, int y, Key key) { - final int left = key.x; - final int right = key.x + key.width; - final int top = key.y; - final int bottom = key.y + key.height; - final int edgeX = x < left ? left : (x > right ? right : x); - final int edgeY = y < top ? top : (y > bottom ? bottom : y); - final int dx = x - edgeX; - final int dy = y - edgeY; - return dx * dx + dy * dy; - } - - private void showKeyPreviewAndUpdateKey(int keyIndex) { - updateKey(keyIndex); + private void showKeyPreviewAndUpdateKeyGraphics(int keyIndex) { + updateKeyGraphics(keyIndex); // The modifier key, such as shift key, should not be shown as preview when multi-touch is - // supported. On thge other hand, if multi-touch is not supported, the modifier key should + // supported. On the other hand, if multi-touch is not supported, the modifier key should // be shown as preview. if (mHasDistinctMultitouch && isModifier()) { mProxy.showPreview(NOT_A_KEY, this); @@ -420,6 +418,20 @@ public class PointerTracker { } } + private void startLongPressTimer(int keyIndex) { + Key key = getKey(keyIndex); + if (key.codes[0] == BaseKeyboard.KEYCODE_SHIFT) { + mHandler.startLongPressShiftTimer(mLongPressShiftKeyTimeout, keyIndex, this); + } else { + mHandler.startLongPressTimer(mLongPressKeyTimeout, keyIndex, this); + } + } + + private boolean isManualTemporaryUpperCase() { + return mKeyboard instanceof LatinKeyboard + && ((LatinKeyboard)mKeyboard).isManualTemporaryUpperCase(); + } + private void detectAndSendKey(int index, int x, int y, long eventTime) { final OnKeyboardActionListener listener = mListener; final Key key = getKey(index); @@ -441,12 +453,20 @@ public class PointerTracker { // Multi-tap if (mInMultiTap) { if (mTapCount != -1) { - mListener.onKey(Keyboard.KEYCODE_DELETE, KEY_DELETE, x, y); + mListener.onKey(BaseKeyboard.KEYCODE_DELETE, KEY_DELETE, x, y); } else { mTapCount = 0; } code = key.codes[mTapCount]; } + + // If keyboard is in manual temporary upper case state and key has manual temporary + // shift code, alternate character code should be sent. + if (isManualTemporaryUpperCase() && key.manualTemporaryUpperCaseCode != 0) { + code = key.manualTemporaryUpperCaseCode; + codes[0] = code; + } + /* * Swap the first and second values in the codes array if the primary code is not * the first value but the second value in the array. This happens when key |