aboutsummaryrefslogtreecommitdiffstats
path: root/java/src/com/android/inputmethod/latin/LatinKeyboardView.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/src/com/android/inputmethod/latin/LatinKeyboardView.java')
-rw-r--r--java/src/com/android/inputmethod/latin/LatinKeyboardView.java166
1 files changed, 160 insertions, 6 deletions
diff --git a/java/src/com/android/inputmethod/latin/LatinKeyboardView.java b/java/src/com/android/inputmethod/latin/LatinKeyboardView.java
index 2686a93c6..6ba2095c0 100644
--- a/java/src/com/android/inputmethod/latin/LatinKeyboardView.java
+++ b/java/src/com/android/inputmethod/latin/LatinKeyboardView.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008-2009 Google Inc.
+ * Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
@@ -23,6 +23,7 @@ import android.graphics.Canvas;
import android.graphics.Paint;
import android.inputmethodservice.Keyboard;
import android.inputmethodservice.KeyboardView;
+import android.inputmethodservice.KeyboardView.OnKeyboardActionListener;
import android.inputmethodservice.Keyboard.Key;
import android.os.Handler;
import android.os.Message;
@@ -43,10 +44,27 @@ public class LatinKeyboardView extends KeyboardView {
private Keyboard mPhoneKeyboard;
+ /** Whether the extension of this keyboard is visible */
private boolean mExtensionVisible;
+ /** The view that is shown as an extension of this keyboard view */
private LatinKeyboardView mExtension;
+ /** The popup window that contains the extension of this keyboard */
private PopupWindow mExtensionPopup;
+ /** Whether this view is an extension of another keyboard */
+ private boolean mIsExtensionType;
private boolean mFirstEvent;
+ /** Whether we've started dropping move events because we found a big jump */
+ private boolean mDroppingEvents;
+ /**
+ * Whether multi-touch disambiguation needs to be disabled for any reason. There are 2 reasons
+ * for this to happen - (1) if a real multi-touch event has occured and (2) we've opened an
+ * extension keyboard.
+ */
+ private boolean mDisableDisambiguation;
+ /** The distance threshold at which we start treating the touch session as a multi-touch */
+ private int mJumpThresholdSquare = Integer.MAX_VALUE;
+ /** The y coordinate of the last row */
+ private int mLastRowY;
public LatinKeyboardView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -61,6 +79,17 @@ public class LatinKeyboardView extends KeyboardView {
}
@Override
+ public void setKeyboard(Keyboard k) {
+ super.setKeyboard(k);
+ // One-seventh of the keyboard width seems like a reasonable threshold
+ mJumpThresholdSquare = k.getMinWidth() / 7;
+ mJumpThresholdSquare *= mJumpThresholdSquare;
+ // Assuming there are 4 rows, this is the coordinate of the last row
+ mLastRowY = (k.getHeight() * 3) / 4;
+ setKeyboardLocal(k);
+ }
+
+ @Override
protected boolean onLongPress(Key key) {
if (key.codes[0] == Keyboard.KEYCODE_MODE_CHANGE) {
getOnKeyboardActionListener().onKey(KEYCODE_OPTIONS, null);
@@ -78,6 +107,83 @@ public class LatinKeyboardView extends KeyboardView {
}
}
+ /**
+ * This function checks to see if we need to handle any sudden jumps in the pointer location
+ * that could be due to a multi-touch being treated as a move by the firmware or hardware.
+ * Once a sudden jump is detected, all subsequent move events are discarded
+ * until an UP is received.<P>
+ * When a sudden jump is detected, an UP event is simulated at the last position and when
+ * the sudden moves subside, a DOWN event is simulated for the second key.
+ * @param me the motion event
+ * @return true if the event was consumed, so that it doesn't continue to be handled by
+ * KeyboardView.
+ */
+ private boolean handleSuddenJump(MotionEvent me) {
+ final int action = me.getAction();
+ final int x = (int) me.getX();
+ final int y = (int) me.getY();
+ boolean result = false;
+
+ // Real multi-touch event? Stop looking for sudden jumps
+ if (me.getPointerCount() > 1) {
+ mDisableDisambiguation = true;
+ }
+ if (mDisableDisambiguation) {
+ // If UP, reset the multi-touch flag
+ if (action == MotionEvent.ACTION_UP) mDisableDisambiguation = false;
+ return false;
+ }
+
+ switch (action) {
+ case MotionEvent.ACTION_DOWN:
+ // Reset the "session"
+ mDroppingEvents = false;
+ mDisableDisambiguation = false;
+ break;
+ case MotionEvent.ACTION_MOVE:
+ // Is this a big jump?
+ final int distanceSquare = (mLastX - x) * (mLastX - x) + (mLastY - y) * (mLastY - y);
+ // Check the distance and also if the move is not entirely within the bottom row
+ // If it's only in the bottom row, it might be an intentional slide gesture
+ // for language switching
+ if (distanceSquare > mJumpThresholdSquare
+ && (mLastY < mLastRowY || y < mLastRowY)) {
+ // If we're not yet dropping events, start dropping and send an UP event
+ if (!mDroppingEvents) {
+ mDroppingEvents = true;
+ // Send an up event
+ MotionEvent translated = MotionEvent.obtain(me.getEventTime(), me.getEventTime(),
+ MotionEvent.ACTION_UP,
+ mLastX, mLastY, me.getMetaState());
+ super.onTouchEvent(translated);
+ translated.recycle();
+ }
+ result = true;
+ } else if (mDroppingEvents) {
+ // If moves are small and we're already dropping events, continue dropping
+ result = true;
+ }
+ break;
+ case MotionEvent.ACTION_UP:
+ if (mDroppingEvents) {
+ // Send a down event first, as we dropped a bunch of sudden jumps and assume that
+ // the user is releasing the touch on the second key.
+ MotionEvent translated = MotionEvent.obtain(me.getEventTime(), me.getEventTime(),
+ MotionEvent.ACTION_DOWN,
+ x, y, me.getMetaState());
+ super.onTouchEvent(translated);
+ translated.recycle();
+ mDroppingEvents = false;
+ // Let the up event get processed as well, result = false
+ }
+ break;
+ }
+ // Track the previous coordinate
+ mLastX = x;
+ mLastY = y;
+ return result;
+ }
+
@Override
public boolean onTouchEvent(MotionEvent me) {
LatinKeyboard keyboard = (LatinKeyboard) getKeyboard();
@@ -86,6 +192,12 @@ public class LatinKeyboardView extends KeyboardView {
mLastY = (int) me.getY();
invalidate();
}
+ // If an extension keyboard is visible or this is an extension keyboard, don't look
+ // for sudden jumps. Otherwise, if there was a sudden jump, return without processing the
+ // actual motion event.
+ if (!mExtensionVisible && !mIsExtensionType
+ && handleSuddenJump(me)) return true;
+
// Reset any bounding box controls in the keyboard
if (me.getAction() == MotionEvent.ACTION_DOWN) {
keyboard.keyReleased();
@@ -139,6 +251,8 @@ public class LatinKeyboardView extends KeyboardView {
} else {
mFirstEvent = true;
}
+ // Stop processing multi-touch errors
+ mDisableDisambiguation = true;
}
return true;
}
@@ -157,7 +271,15 @@ public class LatinKeyboardView extends KeyboardView {
}
}
+ private void setExtensionType(boolean isExtensionType) {
+ mIsExtensionType = isExtensionType;
+ }
+
private boolean openExtension() {
+ // If the current keyboard is not visible, don't show the popup
+ if (!isShown()) {
+ return false;
+ }
if (((LatinKeyboard) getKeyboard()).getExtension() == 0) return false;
makePopupWindow();
mExtensionVisible = true;
@@ -172,7 +294,9 @@ public class LatinKeyboardView extends KeyboardView {
LayoutInflater li = (LayoutInflater) getContext().getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
mExtension = (LatinKeyboardView) li.inflate(R.layout.input_trans, null);
- mExtension.setOnKeyboardActionListener((LatinIME) getContext());
+ mExtension.setExtensionType(true);
+ mExtension.setOnKeyboardActionListener(
+ new ExtensionKeyboardListener(getOnKeyboardActionListener()));
mExtension.setPopupParent(this);
mExtension.setPopupOffset(0, -windowLocation[1]);
Keyboard keyboard;
@@ -181,6 +305,7 @@ public class LatinKeyboardView extends KeyboardView {
mExtensionPopup.setContentView(mExtension);
mExtensionPopup.setWidth(getWidth());
mExtensionPopup.setHeight(keyboard.getHeight());
+ mExtensionPopup.setAnimationStyle(-1);
getLocationInWindow(windowLocation);
// TODO: Fix the "- 30".
mExtension.setPopupOffset(0, -windowLocation[1] - 30);
@@ -201,11 +326,42 @@ public class LatinKeyboardView extends KeyboardView {
}
private void closeExtension() {
- mExtension.setVisibility(INVISIBLE);
mExtension.closing();
+ mExtension.setVisibility(INVISIBLE);
mExtensionVisible = false;
}
+ private static class ExtensionKeyboardListener implements OnKeyboardActionListener {
+ private OnKeyboardActionListener mTarget;
+ ExtensionKeyboardListener(OnKeyboardActionListener target) {
+ mTarget = target;
+ }
+ public void onKey(int primaryCode, int[] keyCodes) {
+ mTarget.onKey(primaryCode, keyCodes);
+ }
+ public void onPress(int primaryCode) {
+ mTarget.onPress(primaryCode);
+ }
+ public void onRelease(int primaryCode) {
+ mTarget.onRelease(primaryCode);
+ }
+ public void onText(CharSequence text) {
+ mTarget.onText(text);
+ }
+ public void swipeDown() {
+ // Don't pass through
+ }
+ public void swipeLeft() {
+ // Don't pass through
+ }
+ public void swipeRight() {
+ // Don't pass through
+ }
+ public void swipeUp() {
+ // Don't pass through
+ }
+ }
+
/**************************** INSTRUMENTATION *******************************/
static final boolean DEBUG_AUTO_PLAY = false;
@@ -224,9 +380,7 @@ public class LatinKeyboardView extends KeyboardView {
private int mLastY;
private Paint mPaint;
- @Override
- public void setKeyboard(Keyboard k) {
- super.setKeyboard(k);
+ private void setKeyboardLocal(Keyboard k) {
if (DEBUG_AUTO_PLAY) {
findKeys();
if (mHandler2 == null) {