aboutsummaryrefslogtreecommitdiffstats
path: root/java/src
diff options
context:
space:
mode:
authorTadashi G. Takaoka <takaoka@google.com>2010-12-17 16:56:15 +0900
committerTadashi G. Takaoka <takaoka@google.com>2010-12-19 18:48:49 +0900
commit9e91472285a1b903631f1e3c998f5aa1efd3e98e (patch)
tree8c1b23eb297e1f8d821271881b79b538a2fdd58d /java/src
parent67a4ecacc7525c9343cded13fc93e9a2381ea2d8 (diff)
downloadlatinime-9e91472285a1b903631f1e3c998f5aa1efd3e98e.tar.gz
latinime-9e91472285a1b903631f1e3c998f5aa1efd3e98e.tar.xz
latinime-9e91472285a1b903631f1e3c998f5aa1efd3e98e.zip
Automaticaly snap back to the previous mode from sliding symbol input
Bug: 3280151 Change-Id: I48ea134639465d0cc178e524af8d7885d185957d
Diffstat (limited to 'java/src')
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardId.java4
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java80
-rw-r--r--java/src/com/android/inputmethod/keyboard/KeyboardView.java12
-rw-r--r--java/src/com/android/inputmethod/keyboard/ModifierKeyState.java4
-rw-r--r--java/src/com/android/inputmethod/keyboard/PointerTracker.java17
5 files changed, 93 insertions, 24 deletions
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardId.java b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
index f6577e747..db86740c3 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardId.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardId.java
@@ -89,6 +89,10 @@ public class KeyboardId {
return mXmlId == R.xml.kbd_qwerty;
}
+ public boolean isSymbolsKeyboard() {
+ return mXmlId == R.xml.kbd_symbols;
+ }
+
public boolean isPhoneKeyboard() {
return mMode == MODE_PHONE;
}
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
index 17d01f89f..31d98a676 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardSwitcher.java
@@ -51,10 +51,6 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
R.layout.input_honeycomb, // DEFAULT_LAYOUT_ID
};
- 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 SubtypeSwitcher mSubtypeSwitcher;
private SharedPreferences mPrefs;
@@ -79,7 +75,14 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
private boolean mIsAutoCorrectionActive;
private boolean mVoiceKeyEnabled;
private boolean mVoiceButtonOnPrimary;
- 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;
@@ -146,10 +149,9 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
public void loadKeyboard(int mode, int imeOptions, boolean voiceKeyEnabled,
boolean voiceButtonOnPrimary) {
- mSymbolsModeState = SYMBOLS_MODE_STATE_NONE;
+ mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_ALPHA;
try {
- loadKeyboardInternal(mode, imeOptions, voiceKeyEnabled, voiceButtonOnPrimary,
- false);
+ loadKeyboardInternal(mode, imeOptions, voiceKeyEnabled, voiceButtonOnPrimary, false);
} catch (RuntimeException e) {
Log.w(TAG, e);
LatinImeLogger.logOnException(mode + "," + imeOptions, e);
@@ -467,19 +469,22 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
public void onPressSymbol() {
if (DEBUG_STATE)
- Log.d(TAG, "onReleaseShift:"
+ Log.d(TAG, "onPressSymbol:"
+ " keyboard=" + getLatinKeyboard().getKeyboardShiftState()
+ " symbolKeyState=" + mSymbolKeyState);
changeKeyboardMode();
mSymbolKeyState.onPress();
+ mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_MOMENTARY;
}
public void onReleaseSymbol() {
if (DEBUG_STATE)
- Log.d(TAG, "onReleaseShift:"
+ Log.d(TAG, "onReleaseSymbol:"
+ " keyboard=" + getLatinKeyboard().getKeyboardShiftState()
+ " symbolKeyState=" + mSymbolKeyState);
- 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 (mAutoModeSwitchState == AUTO_MODE_SWITCH_STATE_CHORDING)
changeKeyboardMode();
mSymbolKeyState.onRelease();
}
@@ -516,13 +521,21 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
mInputView.setKeyboard(keyboard);
}
+ public boolean isInMomentaryAutoModeSwitchState() {
+ return mAutoModeSwitchState == AUTO_MODE_SWITCH_STATE_MOMENTARY;
+ }
+
+ private int getPointerCount() {
+ return mInputView == null ? 0 : mInputView.getPointerCount();
+ }
+
private void toggleKeyboardMode() {
loadKeyboardInternal(mMode, mImeOptions, mVoiceKeyEnabled, mVoiceButtonOnPrimary,
!mIsSymbols);
if (mIsSymbols) {
- mSymbolsModeState = SYMBOLS_MODE_STATE_BEGIN;
+ mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_SYMBOL_BEGIN;
} else {
- mSymbolsModeState = SYMBOLS_MODE_STATE_NONE;
+ mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_ALPHA;
}
}
@@ -531,18 +544,45 @@ public class KeyboardSwitcher implements SharedPreferences.OnSharedPreferenceCha
}
/**
- * Updates state machine to figure out when to automatically switch back to alpha mode.
+ * Updates state machine to figure out when to automatically snap back to the previous mode.
*/
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 (DEBUG_STATE)
+ Log.d(TAG, "onKey: code=" + key + " autoModeSwitchState=" + mAutoModeSwitchState
+ + " pointers=" + getPointerCount());
+ 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 == Keyboard.CODE_SWITCH_ALPHA_SYMBOL) {
+ // 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;
+ }
+ } 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.
+ 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 != Keyboard.CODE_SPACE && key != Keyboard.CODE_ENTER && key > 0) {
- mSymbolsModeState = SYMBOLS_MODE_STATE_SYMBOL;
+ mAutoModeSwitchState = AUTO_MODE_SWITCH_STATE_SYMBOL;
}
break;
- case SYMBOLS_MODE_STATE_SYMBOL:
+ 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 == Keyboard.CODE_ENTER || key == Keyboard.CODE_SPACE) {
changeKeyboardMode();
}
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
index 2ad414c90..47d4d1ade 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
@@ -1308,15 +1308,21 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
return pointers.get(id);
}
+ 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;
}
@@ -1372,7 +1378,6 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
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.
@@ -1387,7 +1392,6 @@ public class KeyboardView extends View implements PointerTracker.UIProxy {
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/keyboard/ModifierKeyState.java b/java/src/com/android/inputmethod/keyboard/ModifierKeyState.java
index 1bd3d8040..f215db876 100644
--- a/java/src/com/android/inputmethod/keyboard/ModifierKeyState.java
+++ b/java/src/com/android/inputmethod/keyboard/ModifierKeyState.java
@@ -55,6 +55,10 @@ public class ModifierKeyState {
Log.d(TAG, mName + ".onOtherKeyPressed: " + toString(oldState) + " > " + this);
}
+ public boolean isPressing() {
+ return mState == PRESSING;
+ }
+
public boolean isReleasing() {
return mState == RELEASING;
}
diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
index c96cefd2b..395783e86 100644
--- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java
+++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
@@ -50,6 +50,7 @@ public class PointerTracker {
private final UIHandler mHandler;
private final KeyDetector mKeyDetector;
private KeyboardActionListener mListener;
+ private final KeyboardSwitcher mKeyboardSwitcher;
private final boolean mHasDistinctMultitouch;
private final boolean mConfigSlidingKeyInputEnabled;
@@ -175,6 +176,7 @@ public class PointerTracker {
mProxy = proxy;
mHandler = handler;
mKeyDetector = keyDetector;
+ mKeyboardSwitcher = KeyboardSwitcher.getInstance();
mKeyState = new KeyState(keyDetector);
mHasDistinctMultitouch = proxy.hasDistinctMultitouch();
mConfigSlidingKeyInputEnabled = res.getBoolean(R.bool.config_sliding_key_input_enabled);
@@ -318,13 +320,22 @@ public class PointerTracker {
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).mCodes[0]);
keyState.onMoveToNewKey(keyIndex, x, y);
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.
if (mListener != null)
mListener.onRelease(oldKey.mCodes[0]);
if (mIsAllowedSlidingKeyInput) {
resetMultiTap();
+ if (mListener != null)
+ mListener.onPress(getKey(keyIndex).mCodes[0]);
keyState.onMoveToNewKey(keyIndex, x, y);
startLongPressTimer(keyIndex);
} else {
@@ -334,7 +345,10 @@ public class PointerTracker {
}
}
} else {
+ // TODO: we should check isMinorMoveDebounce() first.
if (oldKey != null) {
+ // The pointer has been slid out from the previous key, we must call onRelease() to
+ // notify that the previous key has been released.
if (mListener != null)
mListener.onRelease(oldKey.mCodes[0]);
if (mIsAllowedSlidingKeyInput) {
@@ -449,6 +463,9 @@ public class PointerTracker {
Key key = getKey(keyIndex);
if (key.mCodes[0] == Keyboard.CODE_SHIFT) {
mHandler.startLongPressShiftTimer(mLongPressShiftKeyTimeout, keyIndex, this);
+ } else if (mKeyboardSwitcher.isInMomentaryAutoModeSwitchState()) {
+ // We use longer timeout for sliding finger input started from the symbols mode key.
+ mHandler.startLongPressTimer(mLongPressKeyTimeout * 2, keyIndex, this);
} else {
mHandler.startLongPressTimer(mLongPressKeyTimeout, keyIndex, this);
}