aboutsummaryrefslogtreecommitdiffstats
path: root/java/src
diff options
context:
space:
mode:
authorTadashi G. Takaoka <takaoka@google.com>2010-09-02 01:17:56 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2010-09-02 01:17:56 -0700
commit3491c877dd25df829e5e6541a72f375cc2842ea5 (patch)
treead55dff9215e202de5d0481c3825bad6984d7651 /java/src
parent8f5b0ccc507ea7569fec0b8fb0260eedc486ed95 (diff)
parent40a05f62edc6cdedb4365a722b48a72826ef2bf6 (diff)
downloadlatinime-3491c877dd25df829e5e6541a72f375cc2842ea5.tar.gz
latinime-3491c877dd25df829e5e6541a72f375cc2842ea5.tar.xz
latinime-3491c877dd25df829e5e6541a72f375cc2842ea5.zip
Merge "Queuing PointerTracker to support n-key roll-over and shift modifier." into gingerbread
Diffstat (limited to 'java/src')
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java29
-rw-r--r--java/src/com/android/inputmethod/latin/LatinKeyboardBaseView.java67
-rw-r--r--java/src/com/android/inputmethod/latin/ModifierKeyState.java42
-rw-r--r--java/src/com/android/inputmethod/latin/PointerTracker.java22
4 files changed, 153 insertions, 7 deletions
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index 76f774c96..7afee3fad 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -227,6 +227,9 @@ public class LatinIME extends InputMethodService
private int mDeleteCount;
private long mLastKeyTime;
+ // Shift modifier key state
+ private ModifierKeyState mShiftKeyState = new ModifierKeyState();
+
private Tutorial mTutorial;
private AudioManager mAudioManager;
@@ -976,7 +979,8 @@ public class LatinIME extends InputMethodService
public void updateShiftKeyState(EditorInfo attr) {
InputConnection ic = getCurrentInputConnection();
if (ic != null && attr != null && mKeyboardSwitcher.isAlphabetMode()) {
- mKeyboardSwitcher.setShifted(mCapsLock || getCursorCapsMode(ic, attr) != 0);
+ mKeyboardSwitcher.setShifted(mShiftKeyState.isMomentary() || mCapsLock
+ || getCursorCapsMode(ic, attr) != 0);
}
}
@@ -1233,12 +1237,20 @@ public class LatinIME extends InputMethodService
ic.endBatchEdit();
}
+ private void resetShift() {
+ handleShiftInternal(true);
+ }
+
private void handleShift() {
+ handleShiftInternal(false);
+ }
+
+ private void handleShiftInternal(boolean forceNormal) {
mHandler.removeMessages(MSG_UPDATE_SHIFT_STATE);
KeyboardSwitcher switcher = mKeyboardSwitcher;
LatinKeyboardView inputView = switcher.getInputView();
if (switcher.isAlphabetMode()) {
- if (mCapsLock) {
+ if (mCapsLock || forceNormal) {
mCapsLock = false;
switcher.setShifted(false);
} else if (inputView != null) {
@@ -2146,15 +2158,26 @@ public class LatinIME extends InputMethodService
vibrate();
playKeyClick(primaryCode);
if (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 {
+ mShiftKeyState.onOtherKeyPressed();
}
- // TODO: We should handle KEYCODE_MODE_CHANGE (symbol) here as well.
}
public void onRelease(int primaryCode) {
// Reset any drag flags in the keyboard
((LatinKeyboard) mKeyboardSwitcher.getInputView().getKeyboard()).keyReleased();
//vibrate();
+ if (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.
+ }
}
private FieldContext makeFieldContext() {
diff --git a/java/src/com/android/inputmethod/latin/LatinKeyboardBaseView.java b/java/src/com/android/inputmethod/latin/LatinKeyboardBaseView.java
index 4daf6515f..30042d8a1 100644
--- a/java/src/com/android/inputmethod/latin/LatinKeyboardBaseView.java
+++ b/java/src/com/android/inputmethod/latin/LatinKeyboardBaseView.java
@@ -33,6 +33,7 @@ import android.inputmethodservice.Keyboard.Key;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
+import android.util.Log;
import android.util.TypedValue;
import android.view.GestureDetector;
import android.view.Gravity;
@@ -45,6 +46,7 @@ import android.widget.TextView;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.LinkedList;
import java.util.Map;
/**
@@ -62,6 +64,7 @@ import java.util.Map;
*/
public class LatinKeyboardBaseView extends View implements View.OnClickListener,
PointerTracker.UIProxy {
+ private static final String TAG = "LatinKeyboardBaseView";
private static final boolean DEBUG = false;
public static final int NOT_A_TOUCH_COORDINATE = -1;
@@ -199,6 +202,7 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener,
private OnKeyboardActionListener mKeyboardActionListener;
private final ArrayList<PointerTracker> mPointerTrackers = new ArrayList<PointerTracker>();
+ private final PointerQueue mPointerQueue = new PointerQueue();
private final float mDebounceHysteresis;
protected KeyDetector mKeyDetector = new ProximityKeyDetector();
@@ -316,6 +320,41 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener,
}
};
+ static class PointerQueue {
+ private LinkedList<PointerTracker> mQueue = new LinkedList<PointerTracker>();
+
+ public void add(PointerTracker tracker) {
+ mQueue.add(tracker);
+ }
+
+ public int lastIndexOf(PointerTracker tracker) {
+ LinkedList<PointerTracker> queue = mQueue;
+ for (int index = queue.size() - 1; index >= 0; index--) {
+ PointerTracker t = queue.get(index);
+ if (t == tracker)
+ return index;
+ }
+ return -1;
+ }
+
+ public void releasePointersOlderThan(PointerTracker tracker, long eventTime) {
+ LinkedList<PointerTracker> queue = mQueue;
+ int oldestPos = 0;
+ for (PointerTracker t = queue.get(oldestPos); t != tracker; t = queue.get(oldestPos)) {
+ if (t.isModifier()) {
+ oldestPos++;
+ } else {
+ t.onUpEvent(t.getLastX(), t.getLastY(), eventTime);
+ queue.remove(oldestPos);
+ }
+ }
+ }
+
+ public void remove(PointerTracker tracker) {
+ mQueue.remove(tracker);
+ }
+ }
+
public LatinKeyboardBaseView(Context context, AttributeSet attrs) {
this(context, attrs, R.attr.keyboardViewStyle);
}
@@ -1107,14 +1146,14 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener,
switch (action) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
- tracker.onDownEvent(touchX, touchY, eventTime);
+ onDownEvent(tracker, touchX, touchY, eventTime);
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
- tracker.onUpEvent(touchX, touchY, eventTime);
+ onUpEvent(tracker, touchX, touchY, eventTime);
break;
case MotionEvent.ACTION_CANCEL:
- tracker.onCancelEvent(touchX, touchY, eventTime);
+ onCancelEvent(tracker, touchX, touchY, eventTime);
break;
}
}
@@ -1122,6 +1161,28 @@ public class LatinKeyboardBaseView extends View implements View.OnClickListener,
return true;
}
+ private void onDownEvent(PointerTracker tracker, int touchX, int touchY, long eventTime) {
+ tracker.onDownEvent(touchX, touchY, eventTime);
+ mPointerQueue.add(tracker);
+ }
+
+ private void onUpEvent(PointerTracker tracker, int touchX, int touchY, long eventTime) {
+ int index = mPointerQueue.lastIndexOf(tracker);
+ if (index >= 0) {
+ mPointerQueue.releasePointersOlderThan(tracker, eventTime);
+ } else {
+ Log.w(TAG, "onUpEvent: corresponding down event not found for pointer "
+ + tracker.mPointerId);
+ }
+ tracker.onUpEvent(touchX, touchY, eventTime);
+ mPointerQueue.remove(tracker);
+ }
+
+ private void onCancelEvent(PointerTracker tracker, int touchX, int touchY, long eventTime) {
+ tracker.onCancelEvent(touchX, touchY, eventTime);
+ mPointerQueue.remove(tracker);
+ }
+
protected void swipeRight() {
mKeyboardActionListener.swipeRight();
}
diff --git a/java/src/com/android/inputmethod/latin/ModifierKeyState.java b/java/src/com/android/inputmethod/latin/ModifierKeyState.java
new file mode 100644
index 000000000..097e87abe
--- /dev/null
+++ b/java/src/com/android/inputmethod/latin/ModifierKeyState.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2010 Google Inc.
+ *
+ * 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
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.android.inputmethod.latin;
+
+class ModifierKeyState {
+ private static final int RELEASING = 0;
+ private static final int PRESSING = 1;
+ private static final int MOMENTARY = 2;
+
+ private int mState = RELEASING;
+
+ public void onPress() {
+ mState = PRESSING;
+ }
+
+ public void onRelease() {
+ mState = RELEASING;
+ }
+
+ public void onOtherKeyPressed() {
+ if (mState == PRESSING)
+ mState = MOMENTARY;
+ }
+
+ public boolean isMomentary() {
+ return mState == MOMENTARY;
+ }
+}
diff --git a/java/src/com/android/inputmethod/latin/PointerTracker.java b/java/src/com/android/inputmethod/latin/PointerTracker.java
index c8976a372..10f51bd48 100644
--- a/java/src/com/android/inputmethod/latin/PointerTracker.java
+++ b/java/src/com/android/inputmethod/latin/PointerTracker.java
@@ -21,9 +21,13 @@ import com.android.inputmethod.latin.LatinKeyboardBaseView.UIHandler;
import android.inputmethodservice.Keyboard;
import android.inputmethodservice.Keyboard.Key;
+import android.util.Log;
import android.view.ViewConfiguration;
public class PointerTracker {
+ private static final String TAG = "PointerTracker";
+ private static final boolean DEBUG = false;
+
public interface UIProxy {
public void invalidateKey(Key key);
public void showPreview(int keyIndex, PointerTracker tracker);
@@ -108,6 +112,15 @@ public class PointerTracker {
return isValidKeyIndex(keyIndex) ? mKeys[keyIndex] : null;
}
+ public boolean isModifier() {
+ Key key = getKey(mCurrentKey);
+ 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;
+ }
+
public void updateKey(int keyIndex) {
int oldKeyIndex = mPreviousKey;
mPreviousKey = keyIndex;
@@ -146,6 +159,8 @@ public class PointerTracker {
}
showKeyPreviewAndUpdateKey(keyIndex);
updateMoveDebouncing(touchX, touchY);
+ if (DEBUG)
+ Log.d(TAG, "onDownEvent: [" + mPointerId + "] modifier=" + isModifier());
}
public void onMoveEvent(int touchX, int touchY, long eventTime) {
@@ -178,6 +193,8 @@ public class PointerTracker {
}
public void onUpEvent(int touchX, int touchY, long eventTime) {
+ if (DEBUG)
+ Log.d(TAG, "onUpEvent: [" + mPointerId + "] modifier=" + isModifier());
int keyIndex = mKeyDetector.getKeyIndexAndNearbyCodes(touchX, touchY, null);
boolean wasInKeyRepeat = mHandler.isInKeyRepeat();
mHandler.cancelKeyTimers();
@@ -204,6 +221,8 @@ public class PointerTracker {
}
public void onCancelEvent(int touchX, int touchY, long eventTime) {
+ if (DEBUG)
+ Log.d(TAG, "onCancelEvent: [" + mPointerId + "]");
mHandler.cancelKeyTimers();
mHandler.cancelPopupPreview();
mProxy.dismissPopupKeyboard();
@@ -305,7 +324,8 @@ public class PointerTracker {
private void showKeyPreviewAndUpdateKey(int keyIndex) {
updateKey(keyIndex);
- mProxy.showPreview(keyIndex, this);
+ if (!isModifier())
+ mProxy.showPreview(keyIndex, this);
}
private void detectAndSendKey(int index, int x, int y, long eventTime) {