Merge "Update assets for LatinIME" into gingerbread
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index ddfcaa9..f85206e 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -229,8 +229,9 @@
     private int mDeleteCount;
     private long mLastKeyTime;
 
-    // Shift modifier key state
+    // Modifier keys state
     private ModifierKeyState mShiftKeyState = new ModifierKeyState();
+    private ModifierKeyState mSymbolKeyState = new ModifierKeyState();
 
     private Tutorial mTutorial;
 
@@ -1133,6 +1134,7 @@
             mDeleteCount = 0;
         }
         mLastKeyTime = when;
+        final boolean distinctMultiTouch = mKeyboardSwitcher.hasDistinctMultitouch();
         switch (primaryCode) {
             case Keyboard.KEYCODE_DELETE:
                 handleBackspace();
@@ -1141,9 +1143,14 @@
                 break;
             case Keyboard.KEYCODE_SHIFT:
                 // Shift key is handled in onPress() when device has distinct multi-touch panel.
-                if (!mKeyboardSwitcher.hasDistinctMultitouch())
+                if (!distinctMultiTouch)
                     handleShift();
                 break;
+            case Keyboard.KEYCODE_MODE_CHANGE:
+                // Symbol key is handled in onPress() when device has distinct multi-touch panel.
+                if (!distinctMultiTouch)
+                    changeKeyboardMode();
+                break;
             case Keyboard.KEYCODE_CANCEL:
                 if (!isShowingOptionDialog()) {
                     handleClose();
@@ -1161,10 +1168,6 @@
             case LatinKeyboardView.KEYCODE_PREV_LANGUAGE:
                 toggleLanguage(false, false);
                 break;
-            case Keyboard.KEYCODE_MODE_CHANGE:
-                // TODO: Mode change (symbol key) should be handled in onPress().
-                changeKeyboardMode();
-                break;
             case LatinKeyboardView.KEYCODE_VOICE:
                 if (VOICE_INSTALLED) {
                     startListening(false /* was a button press, was not a swipe */);
@@ -2210,13 +2213,16 @@
     public void onPress(int primaryCode) {
         vibrate();
         playKeyClick(primaryCode);
-        if (mKeyboardSwitcher.hasDistinctMultitouch() && primaryCode == Keyboard.KEYCODE_SHIFT) {
+        final boolean distinctMultiTouch = mKeyboardSwitcher.hasDistinctMultitouch();
+        if (distinctMultiTouch && primaryCode == Keyboard.KEYCODE_SHIFT) {
             mShiftKeyState.onPress();
             handleShift();
-        } else if (primaryCode == Keyboard.KEYCODE_MODE_CHANGE) {
-            // TODO: We should handle KEYCODE_MODE_CHANGE (symbol) here as well.
+        } else if (distinctMultiTouch && primaryCode == Keyboard.KEYCODE_MODE_CHANGE) {
+            mSymbolKeyState.onPress();
+            changeKeyboardMode();
         } else {
             mShiftKeyState.onOtherKeyPressed();
+            mSymbolKeyState.onOtherKeyPressed();
         }
     }
 
@@ -2224,12 +2230,15 @@
         // Reset any drag flags in the keyboard
         ((LatinKeyboard) mKeyboardSwitcher.getInputView().getKeyboard()).keyReleased();
         //vibrate();
-        if (mKeyboardSwitcher.hasDistinctMultitouch() && primaryCode == Keyboard.KEYCODE_SHIFT) {
+        final boolean distinctMultiTouch = mKeyboardSwitcher.hasDistinctMultitouch();
+        if (distinctMultiTouch && primaryCode == Keyboard.KEYCODE_SHIFT) {
             if (mShiftKeyState.isMomentary())
                 resetShift();
             mShiftKeyState.onRelease();
-        } else if (primaryCode == Keyboard.KEYCODE_MODE_CHANGE) {
-            // TODO: We should handle KEYCODE_MODE_CHANGE (symbol) here as well.
+        } else if (distinctMultiTouch && primaryCode == Keyboard.KEYCODE_MODE_CHANGE) {
+            if (mSymbolKeyState.isMomentary())
+                changeKeyboardMode();
+            mSymbolKeyState.onRelease();
         }
     }
 
diff --git a/java/src/com/android/inputmethod/latin/LatinKeyboardBaseView.java b/java/src/com/android/inputmethod/latin/LatinKeyboardBaseView.java
index 8f1ec65..45ecca3 100644
--- a/java/src/com/android/inputmethod/latin/LatinKeyboardBaseView.java
+++ b/java/src/com/android/inputmethod/latin/LatinKeyboardBaseView.java
@@ -180,7 +180,6 @@
     private Key[] mKeys;
 
     // Key preview popup
-    private final static boolean PREVIEW_CENTERED = false;
     private TextView mPreviewText;
     private PopupWindow mPreviewPopup;
     private int mPreviewTextSizeLarge;
@@ -188,8 +187,6 @@
     private int mOldPreviewKeyIndex = NOT_A_KEY;
     private boolean mShowPreview = true;
     private boolean mShowTouchPoints = true;
-    private int mPopupPreviewX;
-    private int mPopupPreviewY;
     private int mPopupPreviewOffsetX;
     private int mPopupPreviewOffsetY;
     private int mWindowY;
@@ -869,7 +866,6 @@
         Key key = tracker.getKey(keyIndex);
         if (key == null)
             return;
-        final PopupWindow previewPopup = mPreviewPopup;
         if (key.icon != null) {
             mPreviewText.setCompoundDrawables(null, null, null,
                     key.iconPreview != null ? key.iconPreview : key.icon);
@@ -895,14 +891,10 @@
             lp.width = popupWidth;
             lp.height = popupHeight;
         }
-        if (PREVIEW_CENTERED) {
-            // TODO: Fix this if centering is brought back
-            mPopupPreviewX = 160 - mPreviewText.getMeasuredWidth() / 2;
-            mPopupPreviewY = - mPreviewText.getMeasuredHeight();
-        } else {
-            mPopupPreviewX = key.x - mPreviewText.getPaddingLeft() + getPaddingLeft();
-            mPopupPreviewY = key.y - popupHeight + mPreviewOffset;
-        }
+
+        int popupPreviewX = key.x - mPreviewText.getPaddingLeft() + getPaddingLeft();
+        int popupPreviewY = key.y - popupHeight + mPreviewOffset;
+
         mHandler.cancelDismissPreview();
         if (mOffsetInWindow == null) {
             mOffsetInWindow = new int[2];
@@ -916,29 +908,28 @@
         // Set the preview background state
         mPreviewText.getBackground().setState(
                 key.popupResId != 0 ? LONG_PRESSABLE_STATE_SET : EMPTY_STATE_SET);
-        mPopupPreviewX += mOffsetInWindow[0];
-        mPopupPreviewY += mOffsetInWindow[1];
+        popupPreviewX += mOffsetInWindow[0];
+        popupPreviewY += mOffsetInWindow[1];
 
         // If the popup cannot be shown above the key, put it on the side
-        if (mPopupPreviewY + mWindowY < 0) {
+        if (popupPreviewY + mWindowY < 0) {
             // If the key you're pressing is on the left side of the keyboard, show the popup on
             // the right, offset by enough to see at least one key to the left/right.
             if (key.x + key.width <= getWidth() / 2) {
-                mPopupPreviewX += (int) (key.width * 2.5);
+                popupPreviewX += (int) (key.width * 2.5);
             } else {
-                mPopupPreviewX -= (int) (key.width * 2.5);
+                popupPreviewX -= (int) (key.width * 2.5);
             }
-            mPopupPreviewY += popupHeight;
+            popupPreviewY += popupHeight;
         }
 
-        if (previewPopup.isShowing()) {
-            previewPopup.update(mPopupPreviewX, mPopupPreviewY,
-                    popupWidth, popupHeight);
+        if (mPreviewPopup.isShowing()) {
+            mPreviewPopup.update(popupPreviewX, popupPreviewY, popupWidth, popupHeight);
         } else {
-            previewPopup.setWidth(popupWidth);
-            previewPopup.setHeight(popupHeight);
-            previewPopup.showAtLocation(mMiniKeyboardParent, Gravity.NO_GRAVITY,
-                    mPopupPreviewX, mPopupPreviewY);
+            mPreviewPopup.setWidth(popupWidth);
+            mPreviewPopup.setHeight(popupHeight);
+            mPreviewPopup.showAtLocation(mMiniKeyboardParent, Gravity.NO_GRAVITY,
+                    popupPreviewX, popupPreviewY);
         }
         mPreviewText.setVisibility(VISIBLE);
     }
diff --git a/java/src/com/android/inputmethod/latin/LatinKeyboardView.java b/java/src/com/android/inputmethod/latin/LatinKeyboardView.java
index 8f20a22..c17d7c5 100644
--- a/java/src/com/android/inputmethod/latin/LatinKeyboardView.java
+++ b/java/src/com/android/inputmethod/latin/LatinKeyboardView.java
@@ -52,9 +52,6 @@
     /** The y coordinate of the last row */
     private int mLastRowY;
 
-    // This is local working variable for onLongPress().
-    private int[] mKeyCodes = new int[1];
-
     public LatinKeyboardView(Context context, AttributeSet attrs) {
         super(context, attrs);
     }
diff --git a/java/src/com/android/inputmethod/latin/PointerTracker.java b/java/src/com/android/inputmethod/latin/PointerTracker.java
index 8b1f019..e10c9b8 100644
--- a/java/src/com/android/inputmethod/latin/PointerTracker.java
+++ b/java/src/com/android/inputmethod/latin/PointerTracker.java
@@ -111,6 +111,8 @@
             throw new IllegalArgumentException();
         mKeys = keys;
         mKeyDebounceThresholdSquared = (int)(hysteresisPixel * hysteresisPixel);
+        // Update current key index because keyboard layout has been changed.
+        mCurrentKey = mKeyDetector.getKeyIndexAndNearbyCodes(mStartX, mStartY, null);
     }
 
     private boolean isValidKeyIndex(int keyIndex) {
@@ -126,8 +128,8 @@
         if (key == null)
             return false;
         int primaryCode = key.codes[0];
-        // TODO: KEYCODE_MODE_CHANGE (symbol) will be also a modifier key
-        return primaryCode == Keyboard.KEYCODE_SHIFT;
+        return primaryCode == Keyboard.KEYCODE_SHIFT
+                || primaryCode == Keyboard.KEYCODE_MODE_CHANGE;
     }
 
     public void updateKey(int keyIndex) {
@@ -173,6 +175,8 @@
     }
 
     public void onDownEvent(int x, int y, long eventTime) {
+        if (DEBUG)
+            debugLog("onDownEvent:", x, y);
         int keyIndex = mKeyDetector.getKeyIndexAndNearbyCodes(x, y, null);
         mCurrentKey = keyIndex;
         mStartX = x;
@@ -186,6 +190,8 @@
         if (mListener != null) {
             int primaryCode = isValidKeyIndex(keyIndex) ? mKeys[keyIndex].codes[0] : 0;
             mListener.onPress(primaryCode);
+            // This onPress call may have changed keyboard layout and have updated mCurrentKey
+            keyIndex = mCurrentKey;
         }
         if (isValidKeyIndex(keyIndex)) {
             if (mKeys[keyIndex].repeatable) {
@@ -197,11 +203,11 @@
         }
         showKeyPreviewAndUpdateKey(keyIndex);
         updateMoveDebouncing(x, y);
-        if (DEBUG)
-            debugLog("onDownEvent:", x, y);
     }
 
     public void onMoveEvent(int x, int y, long eventTime) {
+        if (DEBUG_MOVE)
+            debugLog("onMoveEvent:", x, y);
         if (mKeyAlreadyProcessed)
             return;
         int keyIndex = mKeyDetector.getKeyIndexAndNearbyCodes(x, y, null);
@@ -242,15 +248,13 @@
          */
         showKeyPreviewAndUpdateKey(isMinorTimeBounce() ? mLastKey : mCurrentKey);
         updateMoveDebouncing(x, y);
-        if (DEBUG_MOVE)
-            debugLog("onMoveEvent:", x, y);
     }
 
     public void onUpEvent(int x, int y, long eventTime) {
-        if (mKeyAlreadyProcessed)
-            return;
         if (DEBUG)
             debugLog("onUpEvent  :", x, y);
+        if (mKeyAlreadyProcessed)
+            return;
         mHandler.cancelKeyTimers();
         mHandler.cancelPopupPreview();
         int keyIndex = mKeyDetector.getKeyIndexAndNearbyCodes(x, y, null);
@@ -384,8 +388,11 @@
         // 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
         // be shown as preview.
-        if (!isModifier() || !mHasDistinctMultitouch)
+        if (mHasDistinctMultitouch && isModifier()) {
+            mProxy.showPreview(NOT_A_KEY, this);
+        } else {
             mProxy.showPreview(keyIndex, this);
+        }
     }
 
     private void detectAndSendKey(int index, int x, int y, long eventTime) {
@@ -478,7 +485,7 @@
     }
 
     private void debugLog(String title, int x, int y) {
-        Key key = getKey(mCurrentKey);
+        Key key = getKey(mKeyDetector.getKeyIndexAndNearbyCodes(x, y, null));
         final String code;
         if (key == null) {
             code = "----";