aboutsummaryrefslogtreecommitdiffstats
path: root/java/src
diff options
context:
space:
mode:
authorTadashi G. Takaoka <takaoka@google.com>2011-01-05 23:00:54 -0800
committerAndroid Git Automerger <android-git-automerger@android.com>2011-01-05 23:00:54 -0800
commit0b157cc66f6ea9b7a638c425111dc5ae0f6d9709 (patch)
tree1392472f723d912957bd0a9e99b2358b56ecc813 /java/src
parent7b3e2b79dafd135cc2d0605775c03653fe31426d (diff)
parent7aedc8a054aca41e6c80d8faf0ed2dd47f9815c4 (diff)
downloadlatinime-0b157cc66f6ea9b7a638c425111dc5ae0f6d9709.tar.gz
latinime-0b157cc66f6ea9b7a638c425111dc5ae0f6d9709.tar.xz
latinime-0b157cc66f6ea9b7a638c425111dc5ae0f6d9709.zip
am 7aedc8a0: Automaticaly snap back to the previous mode from sliding input (DO NOT MERGE)
* commit '7aedc8a054aca41e6c80d8faf0ed2dd47f9815c4': Automaticaly snap back to the previous mode from sliding input (DO NOT MERGE)
Diffstat (limited to 'java/src')
-rw-r--r--java/src/com/android/inputmethod/latin/KeyboardSwitcher.java128
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java24
-rw-r--r--java/src/com/android/inputmethod/latin/LatinKeyboardBaseView.java31
-rw-r--r--java/src/com/android/inputmethod/latin/PointerTracker.java98
4 files changed, 213 insertions, 68 deletions
diff --git a/java/src/com/android/inputmethod/latin/KeyboardSwitcher.java b/java/src/com/android/inputmethod/latin/KeyboardSwitcher.java
index a7b695eb3..0db204ed8 100644
--- a/java/src/com/android/inputmethod/latin/KeyboardSwitcher.java
+++ b/java/src/com/android/inputmethod/latin/KeyboardSwitcher.java
@@ -82,10 +82,6 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
R.xml.kbd_symbols_shift, R.xml.kbd_symbols_shift_black};
private static final int[] KBD_QWERTY = new int[] {R.xml.kbd_qwerty, R.xml.kbd_qwerty_black};
- private static final int SYMBOLS_MODE_STATE_NONE = 0;
- private static final int SYMBOLS_MODE_STATE_BEGIN = 1;
- private static final int SYMBOLS_MODE_STATE_SYMBOL = 2;
-
private LatinKeyboardView mInputView;
private static final int[] ALPHABET_MODES = {
KEYBOARDMODE_NORMAL,
@@ -99,13 +95,14 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
KEYBOARDMODE_IM_WITH_SETTINGS_KEY,
KEYBOARDMODE_WEB_WITH_SETTINGS_KEY };
- private final LatinIME mInputMethodService;
+ private LatinIME mInputMethodService;
private KeyboardId mSymbolsId;
private KeyboardId mSymbolsShiftedId;
private KeyboardId mCurrentId;
- private final HashMap<KeyboardId, SoftReference<LatinKeyboard>> mKeyboards;
+ private final HashMap<KeyboardId, SoftReference<LatinKeyboard>> mKeyboards =
+ new HashMap<KeyboardId, SoftReference<LatinKeyboard>>();
private int mMode = MODE_NONE; /** One of the MODE_XXX values */
private int mImeOptions;
@@ -116,7 +113,14 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
private boolean mHasVoice;
private boolean mVoiceOnPrimary;
private boolean mPreferSymbols;
- private int mSymbolsModeState = SYMBOLS_MODE_STATE_NONE;
+
+ private static final int AUTO_MODE_SWITCH_STATE_ALPHA = 0;
+ private static final int AUTO_MODE_SWITCH_STATE_SYMBOL_BEGIN = 1;
+ private static final int AUTO_MODE_SWITCH_STATE_SYMBOL = 2;
+ // The following states are used only on the distinct multi-touch panel devices.
+ private static final int AUTO_MODE_SWITCH_STATE_MOMENTARY = 3;
+ private static final int AUTO_MODE_SWITCH_STATE_CHORDING = 4;
+ private int mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_ALPHA;
// Indicates whether or not we have the settings key
private boolean mHasSettingsKey;
@@ -133,17 +137,27 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
private int mLayoutId;
- public KeyboardSwitcher(LatinIME ims) {
- mInputMethodService = ims;
+ private static final KeyboardSwitcher sInstance = new KeyboardSwitcher();
+
+ public static KeyboardSwitcher getInstance() {
+ return sInstance;
+ }
+
+ private KeyboardSwitcher() {
+ // Intentional empty constructor for singleton.
+ }
+
+ public static void init(LatinIME ims) {
+ sInstance.mInputMethodService = ims;
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(ims);
- mLayoutId = Integer.valueOf(prefs.getString(PREF_KEYBOARD_LAYOUT, DEFAULT_LAYOUT_ID));
- updateSettingsKeyState(prefs);
- prefs.registerOnSharedPreferenceChangeListener(this);
+ sInstance.mLayoutId = Integer.valueOf(
+ prefs.getString(PREF_KEYBOARD_LAYOUT, DEFAULT_LAYOUT_ID));
+ sInstance.updateSettingsKeyState(prefs);
+ prefs.registerOnSharedPreferenceChangeListener(sInstance);
- mKeyboards = new HashMap<KeyboardId, SoftReference<LatinKeyboard>>();
- mSymbolsId = makeSymbolsId(false);
- mSymbolsShiftedId = makeSymbolsShiftedId(false);
+ sInstance.mSymbolsId = sInstance.makeSymbolsId(false);
+ sInstance.mSymbolsShiftedId = sInstance.makeSymbolsShiftedId(false);
}
/**
@@ -243,7 +257,7 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
}
public void setKeyboardMode(int mode, int imeOptions, boolean enableVoice) {
- mSymbolsModeState = SYMBOLS_MODE_STATE_NONE;
+ mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_ALPHA;
mPreferSymbols = mode == MODE_SYMBOLS;
if (mode == MODE_SYMBOLS) {
mode = MODE_TEXT;
@@ -410,12 +424,18 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
}
}
+ public void onCancelInput() {
+ // Snap back to the previous keyboard mode if the user cancels sliding input.
+ if (mAutoModeSwitchState == AUTO_MODE_SWITCH_STATE_MOMENTARY && getPointerCount() == 1)
+ mInputMethodService.changeKeyboardMode();
+ }
+
public void toggleSymbols() {
setKeyboardMode(mMode, mImeOptions, mHasVoice, !mIsSymbols);
if (mIsSymbols && !mPreferSymbols) {
- mSymbolsModeState = SYMBOLS_MODE_STATE_BEGIN;
+ mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_SYMBOL_BEGIN;
} else {
- mSymbolsModeState = SYMBOLS_MODE_STATE_NONE;
+ mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_ALPHA;
}
}
@@ -423,24 +443,72 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
return mInputView != null && mInputView.hasDistinctMultitouch();
}
+ public void setAutoModeSwitchStateMomentary() {
+ mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_MOMENTARY;
+ }
+
+ public boolean isInMomentaryAutoModeSwitchState() {
+ return mAutoModeSwitchState == AUTO_MODE_SWITCH_STATE_MOMENTARY;
+ }
+
+ public boolean isInChordingAutoModeSwitchState() {
+ return mAutoModeSwitchState == AUTO_MODE_SWITCH_STATE_CHORDING;
+ }
+
+ public boolean isVibrateAndSoundFeedbackRequired() {
+ return mInputView != null && !mInputView.isInSlidingKeyInput();
+ }
+
+ private int getPointerCount() {
+ return mInputView == null ? 0 : mInputView.getPointerCount();
+ }
+
/**
- * Updates state machine to figure out when to automatically switch back to alpha mode.
- * Returns true if the keyboard needs to switch back
+ * Updates state machine to figure out when to automatically snap back to the previous mode.
*/
- public boolean onKey(int key) {
+ public void onKey(int key) {
// Switch back to alpha mode if user types one or more non-space/enter characters
// followed by a space/enter
- switch (mSymbolsModeState) {
- case SYMBOLS_MODE_STATE_BEGIN:
- if (key != LatinIME.KEYCODE_SPACE && key != LatinIME.KEYCODE_ENTER && key > 0) {
- mSymbolsModeState = SYMBOLS_MODE_STATE_SYMBOL;
+ switch (mAutoModeSwitchState) {
+ case AUTO_MODE_SWITCH_STATE_MOMENTARY:
+ // Only distinct multi touch devices can be in this state.
+ // On non-distinct multi touch devices, mode change key is handled by {@link onKey},
+ // not by {@link onPress} and {@link onRelease}. So, on such devices,
+ // {@link mAutoModeSwitchState} starts from {@link AUTO_MODE_SWITCH_STATE_SYMBOL_BEGIN},
+ // or {@link AUTO_MODE_SWITCH_STATE_ALPHA}, not from
+ // {@link AUTO_MODE_SWITCH_STATE_MOMENTARY}.
+ if (key == LatinKeyboard.KEYCODE_MODE_CHANGE) {
+ // Detected only the mode change key has been pressed, and then released.
+ if (mIsSymbols) {
+ mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_SYMBOL_BEGIN;
+ } else {
+ mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_ALPHA;
}
- break;
- case SYMBOLS_MODE_STATE_SYMBOL:
- if (key == LatinIME.KEYCODE_ENTER || key == LatinIME.KEYCODE_SPACE) return true;
- break;
+ } else if (getPointerCount() == 1) {
+ // Snap back to the previous keyboard mode if the user pressed the mode change key
+ // and slid to other key, then released the finger.
+ // If the user cancels the sliding input, snapping back to the previous keyboard
+ // mode is handled by {@link #onCancelInput}.
+ mInputMethodService.changeKeyboardMode();
+ } else {
+ // Chording input is being started. The keyboard mode will be snapped back to the
+ // previous mode in {@link onReleaseSymbol} when the mode change key is released.
+ mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_CHORDING;
+ }
+ break;
+ case AUTO_MODE_SWITCH_STATE_SYMBOL_BEGIN:
+ if (key != LatinIME.KEYCODE_SPACE && key != LatinIME.KEYCODE_ENTER && key >= 0) {
+ mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_SYMBOL;
+ }
+ break;
+ case AUTO_MODE_SWITCH_STATE_SYMBOL:
+ // Snap back to alpha keyboard mode if user types one or more non-space/enter
+ // characters followed by a space/enter.
+ if (key == LatinIME.KEYCODE_ENTER || key == LatinIME.KEYCODE_SPACE) {
+ mInputMethodService.changeKeyboardMode();
+ }
+ break;
}
- return false;
}
public LatinKeyboardView getInputView() {
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index ffca22e45..b1689f886 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -342,6 +342,7 @@ public class LatinIME extends InputMethodService
@Override
public void onCreate() {
LatinImeLogger.init(this);
+ KeyboardSwitcher.init(this);
super.onCreate();
//setStatusIcon(R.drawable.ime_qwerty);
mResources = getResources();
@@ -349,7 +350,7 @@ public class LatinIME extends InputMethodService
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
mLanguageSwitcher = new LanguageSwitcher(this);
mLanguageSwitcher.loadLocales(prefs);
- mKeyboardSwitcher = new KeyboardSwitcher(this);
+ mKeyboardSwitcher = KeyboardSwitcher.getInstance();
mKeyboardSwitcher.setLanguageSwitcher(mLanguageSwitcher);
mSystemLocale = conf.locale.toString();
mLanguageSwitcher.setSystemLocale(conf.locale);
@@ -1247,9 +1248,7 @@ public class LatinIME extends InputMethodService
// Cancel the just reverted state
mJustRevertedSeparator = null;
}
- if (mKeyboardSwitcher.onKey(primaryCode)) {
- changeKeyboardMode();
- }
+ mKeyboardSwitcher.onKey(primaryCode);
// Reset after any single keystroke
mEnteredText = null;
}
@@ -1269,6 +1268,7 @@ public class LatinIME extends InputMethodService
ic.commitText(text, 1);
ic.endBatchEdit();
updateShiftKeyState(getCurrentInputEditorInfo());
+ mKeyboardSwitcher.onKey(0); // dummy key code.
mJustRevertedSeparator = null;
mJustAddedAutoSpace = false;
mEnteredText = text;
@@ -1276,6 +1276,7 @@ public class LatinIME extends InputMethodService
public void onCancel() {
// User released a finger outside any key
+ mKeyboardSwitcher.onCancelInput();
}
private void handleBackspace() {
@@ -2283,15 +2284,18 @@ public class LatinIME extends InputMethodService
}
public void onPress(int primaryCode) {
- vibrate();
- playKeyClick(primaryCode);
+ if (mKeyboardSwitcher.isVibrateAndSoundFeedbackRequired()) {
+ vibrate();
+ playKeyClick(primaryCode);
+ }
final boolean distinctMultiTouch = mKeyboardSwitcher.hasDistinctMultitouch();
if (distinctMultiTouch && primaryCode == Keyboard.KEYCODE_SHIFT) {
mShiftKeyState.onPress();
handleShift();
} else if (distinctMultiTouch && primaryCode == Keyboard.KEYCODE_MODE_CHANGE) {
- mSymbolKeyState.onPress();
changeKeyboardMode();
+ mSymbolKeyState.onPress();
+ mKeyboardSwitcher.setAutoModeSwitchStateMomentary();
} else {
mShiftKeyState.onOtherKeyPressed();
mSymbolKeyState.onOtherKeyPressed();
@@ -2308,7 +2312,9 @@ public class LatinIME extends InputMethodService
resetShift();
mShiftKeyState.onRelease();
} else if (distinctMultiTouch && primaryCode == Keyboard.KEYCODE_MODE_CHANGE) {
- if (mSymbolKeyState.isMomentary())
+ // Snap back to the previous keyboard mode if the user chords the mode change key and
+ // other key, then released the mode change key.
+ if (mKeyboardSwitcher.isInChordingAutoModeSwitchState())
changeKeyboardMode();
mSymbolKeyState.onRelease();
}
@@ -2562,7 +2568,7 @@ public class LatinIME extends InputMethodService
mOptionsDialog.show();
}
- private void changeKeyboardMode() {
+ public void changeKeyboardMode() {
mKeyboardSwitcher.toggleSymbols();
if (mCapsLock && mKeyboardSwitcher.isAlphabetMode()) {
mKeyboardSwitcher.setShiftLocked(mCapsLock);
diff --git a/java/src/com/android/inputmethod/latin/LatinKeyboardBaseView.java b/java/src/com/android/inputmethod/latin/LatinKeyboardBaseView.java
index b1ef08573..008d37202 100644
--- a/java/src/com/android/inputmethod/latin/LatinKeyboardBaseView.java
+++ b/java/src/com/android/inputmethod/latin/LatinKeyboardBaseView.java
@@ -343,7 +343,7 @@ public class LatinKeyboardBaseView extends View implements PointerTracker.UIProx
cancelPopupPreview();
cancelDismissPreview();
}
- };
+ }
static class PointerQueue {
private LinkedList<PointerTracker> mQueue = new LinkedList<PointerTracker>();
@@ -391,6 +391,14 @@ public class LatinKeyboardBaseView extends View implements PointerTracker.UIProx
public void remove(PointerTracker tracker) {
mQueue.remove(tracker);
}
+
+ public boolean isInSlidingKeyInput() {
+ for (final PointerTracker tracker : mQueue) {
+ if (tracker.isInSlidingKeyInput())
+ return true;
+ }
+ return false;
+ }
}
public LatinKeyboardBaseView(Context context, AttributeSet attrs) {
@@ -1086,6 +1094,7 @@ public class LatinKeyboardBaseView extends View implements PointerTracker.UIProx
}
public void onCancel() {
+ mKeyboardActionListener.onCancel();
dismissPopupKeyboard();
}
@@ -1294,15 +1303,29 @@ public class LatinKeyboardBaseView extends View implements PointerTracker.UIProx
return pointers.get(id);
}
+ public boolean isInSlidingKeyInput() {
+ if (mMiniKeyboard != null) {
+ return mMiniKeyboard.isInSlidingKeyInput();
+ } else {
+ return mPointerQueue.isInSlidingKeyInput();
+ }
+ }
+
+ public int getPointerCount() {
+ return mOldPointerCount;
+ }
+
@Override
public boolean onTouchEvent(MotionEvent me) {
- final int pointerCount = me.getPointerCount();
final int action = me.getActionMasked();
+ final int pointerCount = me.getPointerCount();
+ final int oldPointerCount = mOldPointerCount;
+ mOldPointerCount = pointerCount;
// TODO: cleanup this code into a multi-touch to single-touch event converter class?
// If the device does not have distinct multi-touch support panel, ignore all multi-touch
// events except a transition from/to single-touch.
- if (!mHasDistinctMultitouch && pointerCount > 1 && mOldPointerCount > 1) {
+ if (!mHasDistinctMultitouch && pointerCount > 1 && oldPointerCount > 1) {
return true;
}
@@ -1358,7 +1381,6 @@ public class LatinKeyboardBaseView extends View implements PointerTracker.UIProx
if (!mHasDistinctMultitouch) {
// Use only main (id=0) pointer tracker.
PointerTracker tracker = getPointerTracker(0);
- int oldPointerCount = mOldPointerCount;
if (pointerCount == 1 && oldPointerCount == 2) {
// Multi-touch to single touch transition.
// Send a down event for the latest pointer.
@@ -1373,7 +1395,6 @@ public class LatinKeyboardBaseView extends View implements PointerTracker.UIProx
Log.w(TAG, "Unknown touch panel behavior: pointer count is " + pointerCount
+ " (old " + oldPointerCount + ")");
}
- mOldPointerCount = pointerCount;
return true;
}
diff --git a/java/src/com/android/inputmethod/latin/PointerTracker.java b/java/src/com/android/inputmethod/latin/PointerTracker.java
index 90218e4ab..b23b4d7b8 100644
--- a/java/src/com/android/inputmethod/latin/PointerTracker.java
+++ b/java/src/com/android/inputmethod/latin/PointerTracker.java
@@ -51,6 +51,7 @@ public class PointerTracker {
private final UIHandler mHandler;
private final KeyDetector mKeyDetector;
private OnKeyboardActionListener mListener;
+ private final KeyboardSwitcher mKeyboardSwitcher;
private final boolean mHasDistinctMultitouch;
private Key[] mKeys;
@@ -58,12 +59,18 @@ public class PointerTracker {
private final KeyState mKeyState;
+ // true if keyboard layout has been changed.
+ private boolean mKeyboardLayoutHasBeenChanged;
+
// true if event is already translated to a key action (long press or mini-keyboard)
private boolean mKeyAlreadyProcessed;
// true if this pointer is repeatable key
private boolean mIsRepeatableKey;
+ // true if this pointer is in sliding key input
+ private boolean mIsInSlidingKeyInput;
+
// For multi-tap
private int mLastSentIndex;
private int mTapCount;
@@ -157,10 +164,6 @@ public class PointerTracker {
public int onUpKey(int x, int y) {
return onMoveKeyInternal(x, y);
}
-
- public void onSetKeyboard() {
- mKeyIndex = mKeyDetector.getKeyIndexAndNearbyCodes(mKeyX, mKeyY, null);
- }
}
public PointerTracker(int id, UIHandler handler, KeyDetector keyDetector, UIProxy proxy,
@@ -171,6 +174,7 @@ public class PointerTracker {
mProxy = proxy;
mHandler = handler;
mKeyDetector = keyDetector;
+ mKeyboardSwitcher = KeyboardSwitcher.getInstance();
mKeyState = new KeyState(keyDetector);
mHasDistinctMultitouch = proxy.hasDistinctMultitouch();
mDelayBeforeKeyRepeatStart = res.getInteger(R.integer.config_delay_before_key_repeat_start);
@@ -188,8 +192,12 @@ public class PointerTracker {
throw new IllegalArgumentException();
mKeys = keys;
mKeyHysteresisDistanceSquared = (int)(keyHysteresisDistance * keyHysteresisDistance);
- // Update current key index because keyboard layout has been changed.
- mKeyState.onSetKeyboard();
+ // Mark that keyboard layout has been changed.
+ mKeyboardLayoutHasBeenChanged = true;
+ }
+
+ public boolean isInSlidingKeyInput() {
+ return mIsInSlidingKeyInput;
}
private boolean isValidKeyIndex(int keyIndex) {
@@ -268,15 +276,21 @@ public class PointerTracker {
if (DEBUG)
debugLog("onDownEvent:", x, y);
int keyIndex = mKeyState.onDownKey(x, y, eventTime);
+ mKeyboardLayoutHasBeenChanged = false;
mKeyAlreadyProcessed = false;
mIsRepeatableKey = false;
+ mIsInSlidingKeyInput = false;
checkMultiTap(eventTime, keyIndex);
if (mListener != null) {
if (isValidKeyIndex(keyIndex)) {
mListener.onPress(mKeys[keyIndex].codes[0]);
- // This onPress call may have changed keyboard layout and have updated mKeyIndex.
- // If that's the case, mKeyIndex has been updated in setKeyboard().
- keyIndex = mKeyState.getKeyIndex();
+ // 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 keyboard layout.
+ if (mKeyboardLayoutHasBeenChanged) {
+ mKeyboardLayoutHasBeenChanged = false;
+ keyIndex = mKeyState.onDownKey(x, y, eventTime);
+ }
}
}
if (isValidKeyIndex(keyIndex)) {
@@ -285,7 +299,7 @@ public class PointerTracker {
mHandler.startKeyRepeatTimer(mDelayBeforeKeyRepeatStart, keyIndex, this);
mIsRepeatableKey = true;
}
- mHandler.startLongPressTimer(mLongPressKeyTimeout, keyIndex, this);
+ startLongPressTimer(keyIndex);
}
showKeyPreviewAndUpdateKey(keyIndex);
}
@@ -295,42 +309,70 @@ public class PointerTracker {
debugLog("onMoveEvent:", x, y);
if (mKeyAlreadyProcessed)
return;
- KeyState keyState = mKeyState;
- final int keyIndex = keyState.onMoveKey(x, y);
+ final KeyState keyState = mKeyState;
+ int keyIndex = keyState.onMoveKey(x, y);
final Key oldKey = getKey(keyState.getKeyIndex());
if (isValidKeyIndex(keyIndex)) {
if (oldKey == null) {
+ // 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.
+ if (mListener != null) {
+ mListener.onPress(getKey(keyIndex).codes[0]);
+ // 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 keyboard layout.
+ if (mKeyboardLayoutHasBeenChanged) {
+ mKeyboardLayoutHasBeenChanged = false;
+ keyIndex = keyState.onMoveKey(x, y);
+ }
+ }
keyState.onMoveToNewKey(keyIndex, x, y);
- mHandler.startLongPressTimer(mLongPressKeyTimeout, keyIndex, this);
+ startLongPressTimer(keyIndex);
} else if (!isMinorMoveBounce(x, y, keyIndex)) {
+ // 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
+ // onPress() to notify that the new key is being pressed.
+ mIsInSlidingKeyInput = true;
if (mListener != null)
mListener.onRelease(oldKey.codes[0]);
resetMultiTap();
+ if (mListener != null) {
+ mListener.onPress(getKey(keyIndex).codes[0]);
+ // 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 keyboard layout.
+ if (mKeyboardLayoutHasBeenChanged) {
+ mKeyboardLayoutHasBeenChanged = false;
+ keyIndex = keyState.onMoveKey(x, y);
+ }
+ }
keyState.onMoveToNewKey(keyIndex, x, y);
- mHandler.startLongPressTimer(mLongPressKeyTimeout, keyIndex, this);
+ startLongPressTimer(keyIndex);
}
} else {
- if (oldKey != null) {
+ if (oldKey != null && !isMinorMoveBounce(x, y, keyIndex)) {
+ // The pointer has been slid out from the previous key, we must call onRelease() to
+ // notify that the previous key has been released.
+ mIsInSlidingKeyInput = true;
if (mListener != null)
mListener.onRelease(oldKey.codes[0]);
- keyState.onMoveToNewKey(keyIndex, x ,y);
- mHandler.cancelLongPressTimer();
- } else if (!isMinorMoveBounce(x, y, keyIndex)) {
resetMultiTap();
keyState.onMoveToNewKey(keyIndex, x ,y);
mHandler.cancelLongPressTimer();
}
}
- showKeyPreviewAndUpdateKey(mKeyState.getKeyIndex());
+ showKeyPreviewAndUpdateKey(keyState.getKeyIndex());
}
public void onUpEvent(int x, int y, long eventTime) {
if (DEBUG)
debugLog("onUpEvent :", x, y);
- if (mKeyAlreadyProcessed)
- return;
mHandler.cancelKeyTimers();
mHandler.cancelPopupPreview();
+ showKeyPreviewAndUpdateKey(NOT_A_KEY);
+ mIsInSlidingKeyInput = false;
+ if (mKeyAlreadyProcessed)
+ return;
int keyIndex = mKeyState.onUpKey(x, y);
if (isMinorMoveBounce(x, y, keyIndex)) {
// Use previous fixed key index and coordinates.
@@ -338,7 +380,6 @@ public class PointerTracker {
x = mKeyState.getKeyX();
y = mKeyState.getKeyY();
}
- showKeyPreviewAndUpdateKey(NOT_A_KEY);
if (!mIsRepeatableKey) {
detectAndSendKey(keyIndex, x, y, eventTime);
}
@@ -353,6 +394,7 @@ public class PointerTracker {
mHandler.cancelKeyTimers();
mHandler.cancelPopupPreview();
showKeyPreviewAndUpdateKey(NOT_A_KEY);
+ mIsInSlidingKeyInput = false;
int keyIndex = mKeyState.getKeyIndex();
if (isValidKeyIndex(keyIndex))
mProxy.invalidateKey(mKeys[keyIndex]);
@@ -425,6 +467,15 @@ public class PointerTracker {
}
}
+ private void startLongPressTimer(int keyIndex) {
+ if (mKeyboardSwitcher.isInMomentaryAutoModeSwitchState()) {
+ // We use longer timeout for sliding finger input started from the symbols mode key.
+ mHandler.startLongPressTimer(mLongPressKeyTimeout * 3, keyIndex, this);
+ } else {
+ mHandler.startLongPressTimer(mLongPressKeyTimeout, keyIndex, this);
+ }
+ }
+
private void detectAndSendKey(int index, int x, int y, long eventTime) {
final OnKeyboardActionListener listener = mListener;
final Key key = getKey(index);
@@ -436,11 +487,10 @@ public class PointerTracker {
if (key.text != null) {
if (listener != null) {
listener.onText(key.text);
- listener.onRelease(NOT_A_KEY);
+ listener.onRelease(0); // dummy key code
}
} else {
int code = key.codes[0];
- //TextEntryState.keyPressedAt(key, x, y);
int[] codes = mKeyDetector.newCodeArray();
mKeyDetector.getKeyIndexAndNearbyCodes(x, y, codes);
// Multi-tap