diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java index a58ad2310..f97d1283a 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java @@ -146,11 +146,6 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha // Update the settings key state because number of enabled IMEs could have been changed mSettingsKeyEnabledInSettings = getSettingsKeyMode(mPrefs, mInputMethodService); final KeyboardId id = getKeyboardId(attribute, isSymbols); - - final Keyboard oldKeyboard = mInputView.getKeyboard(); - if (oldKeyboard != null && oldKeyboard.mId.equals(id)) - return; - makeSymbolsKeyboardIds(id.mMode, attribute); mCurrentId = id; mInputView.setKeyPreviewEnabled(mInputMethodService.getPopupOn()); @@ -296,12 +291,6 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha return null; } - public void keyReleased() { - LatinKeyboard latinKeyboard = getLatinKeyboard(); - if (latinKeyboard != null) - latinKeyboard.keyReleased(); - } - public boolean isShiftedOrShiftLocked() { LatinKeyboard latinKeyboard = getLatinKeyboard(); if (latinKeyboard != null) diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java index b8bcee687..5854db656 100644 --- a/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java +++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboard.java @@ -56,17 +56,15 @@ public class LatinKeyboard extends Keyboard { private final Key mSpaceKey; private final Drawable mSpaceIcon; private final Drawable mSpacePreviewIcon; - private final int[] mSpaceKeyIndexArray; + private final int mSpaceKeyIndex; private final Drawable mSpaceAutoCorrectionIndicator; private final Drawable mButtonArrowLeftIcon; private final Drawable mButtonArrowRightIcon; private final int mSpacebarTextColor; private final int mSpacebarTextShadowColor; - private final int mSpacebarVerticalCorrection; private float mSpacebarTextFadeFactor = 0.0f; - private int mSpaceDragStartX; - private int mSpaceDragLastDiff; - private boolean mCurrentlyInSpace; + private final int mSpacebarLanguageSwitchThreshold; + private int mSpacebarLanguageSwitchDiff; private SlidingLocaleDrawable mSlidingLocaleIcon; private final HashMap> mSpaceDrawableCache = new HashMap>(); @@ -115,7 +113,7 @@ public class LatinKeyboard extends Keyboard { mSpaceKey = (spaceKeyIndex >= 0) ? keys.get(spaceKeyIndex) : null; mSpaceIcon = (mSpaceKey != null) ? mSpaceKey.getIcon() : null; mSpacePreviewIcon = (mSpaceKey != null) ? mSpaceKey.getPreviewIcon() : null; - mSpaceKeyIndexArray = new int[] { spaceKeyIndex }; + mSpaceKeyIndex = spaceKeyIndex; mShortcutKey = (shortcutKeyIndex >= 0) ? keys.get(shortcutKeyIndex) : null; mEnabledShortcutIcon = (mShortcutKey != null) ? mShortcutKey.getIcon() : null; @@ -133,8 +131,8 @@ public class LatinKeyboard extends Keyboard { mSpaceAutoCorrectionIndicator = res.getDrawable(R.drawable.sym_keyboard_space_led); mButtonArrowLeftIcon = res.getDrawable(R.drawable.sym_keyboard_language_arrows_left); mButtonArrowRightIcon = res.getDrawable(R.drawable.sym_keyboard_language_arrows_right); - mSpacebarVerticalCorrection = res.getDimensionPixelOffset( - R.dimen.spacebar_vertical_correction); + // The threshold is "key width" x 1.5 + mSpacebarLanguageSwitchThreshold = (getMostCommonKeyWidth() * 3) / 2; } public void setSpacebarTextFadeFactor(float fadeFactor, LatinKeyboardView view) { @@ -325,7 +323,10 @@ public class LatinKeyboard extends Keyboard { return buffer; } - private void updateLocaleDrag(int diff) { + public void updateSpacebarPreviewIcon(int diff) { + if (mSpacebarLanguageSwitchDiff == diff) + return; + mSpacebarLanguageSwitchDiff = diff; if (mSlidingLocaleIcon == null) { final int width = Math.max(mSpaceKey.mWidth, (int)(getMinWidth() * SPACEBAR_POPUP_MIN_RATIO)); @@ -333,7 +334,6 @@ public class LatinKeyboard extends Keyboard { mSlidingLocaleIcon = new SlidingLocaleDrawable(mContext, mSpacePreviewIcon, width, height); mSlidingLocaleIcon.setBounds(0, 0, width, height); - mSpaceKey.setPreviewIcon(mSlidingLocaleIcon); } mSlidingLocaleIcon.setDiff(diff); if (Math.abs(diff) == Integer.MAX_VALUE) { @@ -344,85 +344,44 @@ public class LatinKeyboard extends Keyboard { mSpaceKey.getPreviewIcon().invalidateSelf(); } - // This method is called when "popup on keypress" is off. + public boolean shouldTriggerSpacebarSlidingLanguageSwitch(int diff) { + return Math.abs(diff) > mSpacebarLanguageSwitchThreshold; + } + + /** + * Return true if spacebar needs showing preview even when "popup on keypress" is off. + * @param keyIndex index of the pressing key + * @return true if spacebar needs showing preview + */ @Override public boolean needSpacebarPreview(int keyIndex) { + // This method is called when "popup on keypress" is off. if (!mSubtypeSwitcher.useSpacebarLanguageSwitcher()) return false; // Dismiss key preview. if (keyIndex == KeyDetector.NOT_A_KEY) return true; // Key is not a spacebar. - if (keyIndex != mSpaceKeyIndexArray[0]) + if (keyIndex != mSpaceKeyIndex) return false; // The language switcher will be displayed only when the dragging distance is greater - // than average key width of this keyboard. - return Math.abs(mSpaceDragLastDiff) > getMostCommonKeyWidth(); + // than the threshold. + return shouldTriggerSpacebarSlidingLanguageSwitch(mSpacebarLanguageSwitchDiff); } public int getLanguageChangeDirection() { - if (mSpaceKey == null || SubtypeSwitcher.getInstance().getEnabledKeyboardLocaleCount() <= 1 - || Math.abs(mSpaceDragLastDiff) < getMostCommonKeyWidth() * SPACEBAR_DRAG_WIDTH) { + if (mSpaceKey == null || mSubtypeSwitcher.getEnabledKeyboardLocaleCount() <= 1 || Math.abs( + mSpacebarLanguageSwitchDiff) < getMostCommonKeyWidth() * SPACEBAR_DRAG_WIDTH) { return 0; // No change } - return mSpaceDragLastDiff > 0 ? 1 : -1; - } - - public void keyReleased() { - mCurrentlyInSpace = false; - mSpaceDragLastDiff = 0; - if (mSpaceKey != null) { - updateLocaleDrag(Integer.MAX_VALUE); - } - } - - /** - * Does the magic of locking the touch gesture into the spacebar when - * switching input languages. - */ - @Override - public boolean isInside(Key key, int pointX, int pointY) { - int x = pointX; - int y = pointY; - final int code = key.mCode; - if (code == CODE_SPACE) { - y += mSpacebarVerticalCorrection; - if (SubtypeSwitcher.getInstance().useSpacebarLanguageSwitcher() - && SubtypeSwitcher.getInstance().getEnabledKeyboardLocaleCount() > 1) { - if (mCurrentlyInSpace) { - int diff = x - mSpaceDragStartX; - if (Math.abs(diff - mSpaceDragLastDiff) > 0) { - updateLocaleDrag(diff); - } - mSpaceDragLastDiff = diff; - return true; - } else { - boolean isOnSpace = key.isOnKey(x, y); - if (isOnSpace) { - mCurrentlyInSpace = true; - mSpaceDragStartX = x; - updateLocaleDrag(0); - } - return isOnSpace; - } - } - } - - // Lock into the spacebar - if (mCurrentlyInSpace) return false; - - return key.isOnKey(x, y); + return mSpacebarLanguageSwitchDiff > 0 ? 1 : -1; } @Override public int[] getNearestKeys(int x, int y) { - if (mCurrentlyInSpace) { - return mSpaceKeyIndexArray; - } else { - // Avoid dead pixels at edges of the keyboard - return super.getNearestKeys(Math.max(0, Math.min(x, getMinWidth() - 1)), - Math.max(0, Math.min(y, getHeight() - 1))); - } + // Avoid dead pixels at edges of the keyboard + return super.getNearestKeys(Math.max(0, Math.min(x, getMinWidth() - 1)), + Math.max(0, Math.min(y, getHeight() - 1))); } private static int getTextSizeFromTheme(Theme theme, int style, int defValue) { diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java index a64a9e609..efc446a0d 100644 --- a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java @@ -68,11 +68,6 @@ public class LatinKeyboardView extends KeyboardView { @Override public void setKeyboard(Keyboard newKeyboard) { - final LatinKeyboard oldKeyboard = getLatinKeyboard(); - if (oldKeyboard != null) { - // Reset old keyboard state before switching to new keyboard. - oldKeyboard.keyReleased(); - } super.setKeyboard(newKeyboard); // One-seventh of the keyboard width seems like a reasonable threshold mJumpThresholdSquare = newKeyboard.getMinWidth() / 7; @@ -216,8 +211,7 @@ public class LatinKeyboardView extends KeyboardView { @Override public boolean onTouchEvent(MotionEvent me) { - LatinKeyboard keyboard = getLatinKeyboard(); - if (keyboard == null) return true; + if (getLatinKeyboard() == null) return true; // If there was a sudden jump, return without processing the actual motion event. if (handleSuddenJump(me)) { @@ -226,24 +220,6 @@ public class LatinKeyboardView extends KeyboardView { return true; } - // Reset any bounding box controls in the keyboard - if (me.getAction() == MotionEvent.ACTION_DOWN) { - keyboard.keyReleased(); - } - - if (me.getAction() == MotionEvent.ACTION_UP) { - int languageDirection = keyboard.getLanguageChangeDirection(); - if (languageDirection != 0) { - getOnKeyboardActionListener().onCodeInput( - languageDirection == 1 - ? LatinKeyboard.CODE_NEXT_LANGUAGE : LatinKeyboard.CODE_PREV_LANGUAGE, - null, mLastX, mLastY); - me.setAction(MotionEvent.ACTION_CANCEL); - keyboard.keyReleased(); - return super.onTouchEvent(me); - } - } - return super.onTouchEvent(me); } diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java index 1b1aa492c..29867c381 100644 --- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java +++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java @@ -19,6 +19,7 @@ package com.android.inputmethod.keyboard; import com.android.inputmethod.keyboard.KeyboardView.UIHandler; import com.android.inputmethod.latin.LatinImeLogger; import com.android.inputmethod.latin.R; +import com.android.inputmethod.latin.SubtypeSwitcher; import android.content.res.Resources; import android.util.Log; @@ -90,6 +91,12 @@ public class PointerTracker { // ignore modifier key if true private boolean mIgnoreModifierKey; + // TODO: Remove these hacking variables + // true if this pointer is in sliding language switch + private boolean mIsInSlidingLanguageSwitch; + private int mSpaceKeyIndex; + private final SubtypeSwitcher mSubtypeSwitcher; + // Empty {@link KeyboardActionListener} private static final KeyboardActionListener EMPTY_LISTENER = new KeyboardActionListener() { @Override @@ -129,6 +136,7 @@ public class PointerTracker { R.dimen.config_touch_noise_threshold_distance); mTouchNoiseThresholdDistanceSquared = (int)( touchNoiseThresholdDistance * touchNoiseThresholdDistance); + mSubtypeSwitcher = SubtypeSwitcher.getInstance(); } public void setOnKeyboardActionListener(KeyboardActionListener listener) { @@ -338,6 +346,7 @@ public class PointerTracker { mKeyAlreadyProcessed = false; mIsRepeatableKey = false; mIsInSlidingKeyInput = false; + mIsInSlidingLanguageSwitch = false; mIgnoreModifierKey = false; if (isValidKeyIndex(keyIndex)) { // This onPress call may have changed keyboard layout. Those cases are detected at @@ -374,6 +383,12 @@ public class PointerTracker { return; final PointerTrackerKeyState keyState = mKeyState; + // TODO: Remove this hacking code + if (mIsInSlidingLanguageSwitch) { + ((LatinKeyboard)mKeyboard).updateSpacebarPreviewIcon(x - keyState.getKeyX()); + showKeyPreview(mSpaceKeyIndex); + return; + } final int lastX = keyState.getLastX(); final int lastY = keyState.getLastY(); final int oldKeyIndex = keyState.getKeyIndex(); @@ -428,11 +443,25 @@ public class PointerTracker { dismissKeyPreview(); setReleasedKeyGraphics(oldKeyIndex); } - return; } - } else if (mKeyboard.needSpacebarPreview(keyIndex)) { - // Display spacebar slide language switcher. - showKeyPreview(keyIndex); + } + // TODO: Remove this hack code + else if (isSpaceKey(keyIndex) && !mIsInSlidingLanguageSwitch + && mKeyboard instanceof LatinKeyboard) { + final LatinKeyboard keyboard = ((LatinKeyboard)mKeyboard); + if (mSubtypeSwitcher.useSpacebarLanguageSwitcher() + && mSubtypeSwitcher.getEnabledKeyboardLocaleCount() > 1) { + final int diff = x - keyState.getKeyX(); + if (keyboard.shouldTriggerSpacebarSlidingLanguageSwitch(diff)) { + // Detect start sliding language switch. + mIsInSlidingLanguageSwitch = true; + mSpaceKeyIndex = keyIndex; + keyboard.updateSpacebarPreviewIcon(diff); + // Display spacebar slide language switcher. + showKeyPreview(keyIndex); + queue.releaseAllPointersExcept(this, eventTime, true); + } + } } } else { if (oldKey != null && isMajorEnoughMoveToBeOnNewKey(x, y, keyIndex)) { @@ -447,7 +476,6 @@ public class PointerTracker { } else { mKeyAlreadyProcessed = true; dismissKeyPreview(); - return; } } } @@ -462,7 +490,7 @@ public class PointerTracker { if (isModifier()) { // Before processing an up event of modifier key, all pointers already being // tracked should be released. - queue.releaseAllPointersExcept(this, eventTime); + queue.releaseAllPointersExcept(this, eventTime, true); } else { queue.releaseAllPointersOlderThan(this, eventTime); } @@ -474,8 +502,10 @@ public class PointerTracker { // Let this pointer tracker know that one of newer-than-this pointer trackers got an up event. // This pointer tracker needs to keep the key top graphics "pressed", but needs to get a // "virtual" up event. - public void onPhantomUpEvent(int x, int y, long eventTime) { - onUpEventInternal(x, y, eventTime, false); + public void onPhantomUpEvent(int x, int y, long eventTime, boolean updateReleasedKeyGraphics) { + if (DEBUG_EVENT) + printTouchEvent("onPhntEvent:", x, y, eventTime); + onUpEventInternal(x, y, eventTime, updateReleasedKeyGraphics); mKeyAlreadyProcessed = true; } @@ -500,6 +530,20 @@ public class PointerTracker { setReleasedKeyGraphics(keyIndex); if (mKeyAlreadyProcessed) return; + // TODO: Remove this hacking code + if (mIsInSlidingLanguageSwitch) { + setReleasedKeyGraphics(mSpaceKeyIndex); + final int languageDir = ((LatinKeyboard)mKeyboard).getLanguageChangeDirection(); + if (languageDir != 0) { + final int code = (languageDir == 1) + ? LatinKeyboard.CODE_NEXT_LANGUAGE : LatinKeyboard.CODE_PREV_LANGUAGE; + // This will change keyboard layout. + mListener.onCodeInput(code, new int[] {code}, keyX, keyY); + } + ((LatinKeyboard)mKeyboard).updateSpacebarPreviewIcon(0); + mIsInSlidingLanguageSwitch = false; + return; + } if (!mIsRepeatableKey) { detectAndSendKey(keyIndex, keyX, keyY); } @@ -515,8 +559,10 @@ public class PointerTracker { if (DEBUG_EVENT) printTouchEvent("onCancelEvt:", x, y, eventTime); - if (queue != null) + if (queue != null) { + queue.releaseAllPointersExcept(this, eventTime, true); queue.remove(this); + } onCancelEventInternal(); } diff --git a/java/src/com/android/inputmethod/keyboard/PointerTrackerQueue.java b/java/src/com/android/inputmethod/keyboard/PointerTrackerQueue.java index 0a9410042..42089d5ea 100644 --- a/java/src/com/android/inputmethod/keyboard/PointerTrackerQueue.java +++ b/java/src/com/android/inputmethod/keyboard/PointerTrackerQueue.java @@ -35,21 +35,22 @@ public class PointerTrackerQueue { if (t.isModifier()) { oldestPos++; } else { - t.onPhantomUpEvent(t.getLastX(), t.getLastY(), eventTime); + t.onPhantomUpEvent(t.getLastX(), t.getLastY(), eventTime, false); queue.remove(oldestPos); } } } public void releaseAllPointers(long eventTime) { - releaseAllPointersExcept(null, eventTime); + releaseAllPointersExcept(null, eventTime, true); } - public void releaseAllPointersExcept(PointerTracker tracker, long eventTime) { + public void releaseAllPointersExcept(PointerTracker tracker, long eventTime, + boolean updateReleasedKeyGraphics) { for (PointerTracker t : mQueue) { if (t == tracker) continue; - t.onPhantomUpEvent(t.getLastX(), t.getLastY(), eventTime); + t.onPhantomUpEvent(t.getLastX(), t.getLastY(), eventTime, updateReleasedKeyGraphics); } mQueue.clear(); if (tracker != null) diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index f9bcfc655..28fd6aad7 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -359,11 +359,14 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar final LatinKeyboardView inputView = mKeyboardSwitcher.getInputView(); if (inputView != null) { final LatinKeyboard keyboard = mKeyboardSwitcher.getLatinKeyboard(); + // The language is always displayed when the delay is negative. + final boolean needsToDisplayLanguage = localeChanged + || mConfigDelayBeforeFadeoutLanguageOnSpacebar < 0; // The language is never displayed when the delay is zero. if (mConfigDelayBeforeFadeoutLanguageOnSpacebar != 0) - inputView.setSpacebarTextFadeFactor(localeChanged ? 1.0f + inputView.setSpacebarTextFadeFactor(needsToDisplayLanguage ? 1.0f : mConfigFinalFadeoutFactorOfLanguageOnSpacebar, keyboard); - // The language is always displayed when the delay is negative. + // The fadeout animation will start when the delay is positive. if (localeChanged && mConfigDelayBeforeFadeoutLanguageOnSpacebar > 0) { sendMessageDelayed(obtainMessage(MSG_FADEOUT_LANGUAGE_ON_SPACEBAR, keyboard), mConfigDelayBeforeFadeoutLanguageOnSpacebar); @@ -2058,7 +2061,6 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar public void onRelease(int primaryCode, boolean withSliding) { KeyboardSwitcher switcher = mKeyboardSwitcher; // Reset any drag flags in the keyboard - switcher.keyReleased(); final boolean distinctMultiTouch = switcher.hasDistinctMultitouch(); if (distinctMultiTouch && primaryCode == Keyboard.CODE_SHIFT) { switcher.onReleaseShift(withSliding);