aboutsummaryrefslogtreecommitdiffstats
path: root/java/src/com
diff options
context:
space:
mode:
Diffstat (limited to 'java/src/com')
-rw-r--r--java/src/com/android/inputmethod/keyboard/LatinKeyboardBaseView.java137
-rw-r--r--java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java2
-rw-r--r--java/src/com/android/inputmethod/keyboard/PointerTracker.java151
-rw-r--r--java/src/com/android/inputmethod/keyboard/PopupMiniKeyboardView.java110
-rw-r--r--java/src/com/android/inputmethod/keyboard/PopupPanel.java18
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java27
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/PointerTrackerQueue.java2
-rw-r--r--java/src/com/android/inputmethod/latin/LatinIME.java15
-rw-r--r--java/src/com/android/inputmethod/latin/UserDictionary.java40
9 files changed, 290 insertions, 212 deletions
diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboardBaseView.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboardBaseView.java
index b512f5ac7..b807dd325 100644
--- a/java/src/com/android/inputmethod/keyboard/LatinKeyboardBaseView.java
+++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboardBaseView.java
@@ -21,6 +21,7 @@ import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.os.Message;
+import android.os.SystemClock;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
@@ -36,11 +37,9 @@ import com.android.inputmethod.accessibility.AccessibleKeyboardViewProxy;
import com.android.inputmethod.keyboard.PointerTracker.DrawingProxy;
import com.android.inputmethod.keyboard.PointerTracker.TimerProxy;
import com.android.inputmethod.keyboard.internal.MiniKeyboardBuilder;
-import com.android.inputmethod.keyboard.internal.PointerTrackerQueue;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.StaticInnerHandlerWrapper;
-import java.util.ArrayList;
import java.util.WeakHashMap;
/**
@@ -65,18 +64,14 @@ public class LatinKeyboardBaseView extends KeyboardView implements PointerTracke
// Mini keyboard
private PopupWindow mPopupWindow;
- private PopupPanel mPopupMiniKeyboardPanel;
+ private PopupPanel mPopupPanel;
+ private int mPopupPanelPointerTrackerId;
private final WeakHashMap<Key, PopupPanel> mPopupPanelCache =
new WeakHashMap<Key, PopupPanel>();
/** Listener for {@link KeyboardActionListener}. */
private KeyboardActionListener mKeyboardActionListener;
- private final ArrayList<PointerTracker> mPointerTrackers = new ArrayList<PointerTracker>();
-
- // TODO: Let the PointerTracker class manage this pointer queue
- private final PointerTrackerQueue mPointerQueue;
-
private final boolean mHasDistinctMultitouch;
private int mOldPointerCount = 1;
private int mOldKeyIndex;
@@ -249,7 +244,7 @@ public class LatinKeyboardBaseView extends KeyboardView implements PointerTracke
.hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN_MULTITOUCH_DISTINCT);
mKeyRepeatInterval = res.getInteger(R.integer.config_key_repeat_interval);
- mPointerQueue = mHasDistinctMultitouch ? new PointerTrackerQueue() : null;
+ PointerTracker.init(mHasDistinctMultitouch, getContext());
}
public void startIgnoringDoubleTap() {
@@ -259,9 +254,7 @@ public class LatinKeyboardBaseView extends KeyboardView implements PointerTracke
public void setKeyboardActionListener(KeyboardActionListener listener) {
mKeyboardActionListener = listener;
- for (PointerTracker tracker : mPointerTrackers) {
- tracker.setKeyboardActionListener(listener);
- }
+ PointerTracker.setKeyboardActionListener(listener);
}
/**
@@ -304,17 +297,15 @@ public class LatinKeyboardBaseView extends KeyboardView implements PointerTracke
@Override
public void setKeyboard(Keyboard keyboard) {
if (getKeyboard() != null) {
- dismissAllKeyPreviews();
+ PointerTracker.dismissAllKeyPreviews();
}
// Remove any pending messages, except dismissing preview
mKeyTimerHandler.cancelKeyTimers();
super.setKeyboard(keyboard);
mKeyDetector.setKeyboard(
keyboard, -getPaddingLeft(), -getPaddingTop() + mVerticalCorrection);
- for (PointerTracker tracker : mPointerTrackers) {
- tracker.setKeyDetector(mKeyDetector);
- }
mKeyDetector.setProximityThreshold(keyboard.getMostCommonKeyWidth());
+ PointerTracker.setKeyDetector(mKeyDetector);
mPopupPanelCache.clear();
}
@@ -343,14 +334,6 @@ public class LatinKeyboardBaseView extends KeyboardView implements PointerTracke
return mKeyDetector.isProximityCorrectionEnabled();
}
- // TODO: clean up this method.
- private void dismissAllKeyPreviews() {
- for (PointerTracker tracker : mPointerTrackers) {
- tracker.setReleasedKeyGraphics();
- dismissKeyPreview(tracker);
- }
- }
-
@Override
public void cancelAllMessages() {
mKeyTimerHandler.cancelAllMessages();
@@ -363,15 +346,13 @@ public class LatinKeyboardBaseView extends KeyboardView implements PointerTracke
return false;
}
+ // Check if we are already displaying popup panel.
+ if (mPopupPanel != null)
+ return false;
final Key parentKey = tracker.getKey(keyIndex);
if (parentKey == null)
return false;
- boolean result = onLongPress(parentKey, tracker);
- if (result) {
- dismissAllKeyPreviews();
- tracker.onLongPressed();
- }
- return result;
+ return onLongPress(parentKey, tracker);
}
private void onLongPressShiftKey(PointerTracker tracker) {
@@ -398,35 +379,6 @@ public class LatinKeyboardBaseView extends KeyboardView implements PointerTracke
final PopupMiniKeyboardView miniKeyboardView =
(PopupMiniKeyboardView)container.findViewById(R.id.mini_keyboard_view);
- miniKeyboardView.setKeyboardActionListener(new KeyboardActionListener() {
- @Override
- public void onCodeInput(int primaryCode, int[] keyCodes, int x, int y) {
- mKeyboardActionListener.onCodeInput(primaryCode, keyCodes, x, y);
- dismissMiniKeyboard();
- }
-
- @Override
- public void onTextInput(CharSequence text) {
- mKeyboardActionListener.onTextInput(text);
- dismissMiniKeyboard();
- }
-
- @Override
- public void onCancelInput() {
- mKeyboardActionListener.onCancelInput();
- dismissMiniKeyboard();
- }
-
- @Override
- public void onPress(int primaryCode, boolean withSliding) {
- mKeyboardActionListener.onPress(primaryCode, withSliding);
- }
- @Override
- public void onRelease(int primaryCode, boolean withSliding) {
- mKeyboardActionListener.onRelease(primaryCode, withSliding);
- }
- });
-
final Keyboard parentKeyboard = getKeyboard();
final Keyboard miniKeyboard = new MiniKeyboardBuilder(
this, parentKeyboard.getPopupKeyboardResId(), parentKey, parentKeyboard).build();
@@ -440,7 +392,7 @@ public class LatinKeyboardBaseView extends KeyboardView implements PointerTracke
@Override
protected boolean needsToDimKeyboard() {
- return mPopupMiniKeyboardPanel != null;
+ return mPopupPanel != null;
}
/**
@@ -466,38 +418,28 @@ public class LatinKeyboardBaseView extends KeyboardView implements PointerTracke
// Allow popup window to be drawn off the screen.
mPopupWindow.setClippingEnabled(false);
}
- mPopupMiniKeyboardPanel = popupPanel;
+ mPopupPanel = popupPanel;
+ mPopupPanelPointerTrackerId = tracker.mPointerId;
+
+ tracker.onLongPressed();
popupPanel.showPanel(this, parentKey, tracker, mPopupWindow);
+ final int translatedX = popupPanel.translateX(tracker.getLastX());
+ final int translatedY = popupPanel.translateY(tracker.getLastY());
+ tracker.onDownEvent(translatedX, translatedY, SystemClock.uptimeMillis(), popupPanel);
invalidateAllKeys();
return true;
}
private PointerTracker getPointerTracker(final int id) {
- final ArrayList<PointerTracker> pointers = mPointerTrackers;
- final KeyboardActionListener listener = mKeyboardActionListener;
- final Keyboard keyboard = getKeyboard();
-
- // Create pointer trackers until we can get 'id+1'-th tracker, if needed.
- for (int i = pointers.size(); i <= id; i++) {
- final PointerTracker tracker =
- new PointerTracker(i, getContext(), mKeyTimerHandler, mKeyDetector, this,
- mPointerQueue);
- if (keyboard != null)
- tracker.setKeyDetector(mKeyDetector);
- if (listener != null)
- tracker.setKeyboardActionListener(listener);
- pointers.add(tracker);
- }
-
- return pointers.get(id);
+ return PointerTracker.getPointerTracker(id, this);
}
public boolean isInSlidingKeyInput() {
- if (mPopupMiniKeyboardPanel != null) {
- return mPopupMiniKeyboardPanel.isInSlidingKeyInput();
+ if (mPopupPanel != null) {
+ return true;
} else {
- return mPointerQueue.isInSlidingKeyInput();
+ return PointerTracker.isAnyInSlidingKeyInput();
}
}
@@ -521,9 +463,9 @@ public class LatinKeyboardBaseView extends KeyboardView implements PointerTracke
}
// Gesture detector must be enabled only when mini-keyboard is not on the screen.
- if (mPopupMiniKeyboardPanel == null && mGestureDetector != null
+ if (mPopupPanel == null && mGestureDetector != null
&& mGestureDetector.onTouchEvent(me)) {
- dismissAllKeyPreviews();
+ PointerTracker.dismissAllKeyPreviews();
mKeyTimerHandler.cancelKeyTimers();
return true;
}
@@ -531,13 +473,13 @@ public class LatinKeyboardBaseView extends KeyboardView implements PointerTracke
final long eventTime = me.getEventTime();
final int index = me.getActionIndex();
final int id = me.getPointerId(index);
- final int x = (int)me.getX(index);
- final int y = (int)me.getY(index);
-
- // Needs to be called after the gesture detector gets a turn, as it may have displayed the
- // mini keyboard
- if (mPopupMiniKeyboardPanel != null) {
- return mPopupMiniKeyboardPanel.onTouchEvent(me);
+ final int x, y;
+ if (mPopupPanel != null && id == mPopupPanelPointerTrackerId) {
+ x = mPopupPanel.translateX((int)me.getX(index));
+ y = mPopupPanel.translateY((int)me.getY(index));
+ } else {
+ x = (int)me.getX(index);
+ y = (int)me.getY(index);
}
if (mKeyTimerHandler.isInKeyRepeat()) {
@@ -585,7 +527,15 @@ public class LatinKeyboardBaseView extends KeyboardView implements PointerTracke
if (action == MotionEvent.ACTION_MOVE) {
for (int i = 0; i < pointerCount; i++) {
final PointerTracker tracker = getPointerTracker(me.getPointerId(i));
- tracker.onMoveEvent((int)me.getX(i), (int)me.getY(i), eventTime);
+ final int px, py;
+ if (mPopupPanel != null && tracker.mPointerId == mPopupPanelPointerTrackerId) {
+ px = mPopupPanel.translateX((int)me.getX(i));
+ py = mPopupPanel.translateY((int)me.getY(i));
+ } else {
+ px = (int)me.getX(i);
+ py = (int)me.getY(i);
+ }
+ tracker.onMoveEvent(px, py, eventTime);
}
} else {
processMotionEvent(getPointerTracker(id), action, x, y, eventTime, this);
@@ -621,10 +571,11 @@ public class LatinKeyboardBaseView extends KeyboardView implements PointerTracke
mPopupPanelCache.clear();
}
- private boolean dismissMiniKeyboard() {
+ public boolean dismissMiniKeyboard() {
if (mPopupWindow != null && mPopupWindow.isShowing()) {
mPopupWindow.dismiss();
- mPopupMiniKeyboardPanel = null;
+ mPopupPanel = null;
+ mPopupPanelPointerTrackerId = -1;
invalidateAllKeys();
return true;
}
diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
index 39d607d95..5f5475ce8 100644
--- a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java
@@ -96,8 +96,10 @@ public class LatinKeyboardView extends LatinKeyboardBaseView {
protected boolean onLongPress(Key key, PointerTracker tracker) {
int primaryCode = key.mCode;
if (primaryCode == Keyboard.CODE_SETTINGS) {
+ tracker.onLongPressed();
return invokeOnKey(Keyboard.CODE_SETTINGS_LONGPRESS);
} else if (primaryCode == '0' && getLatinKeyboard().isPhoneKeyboard()) {
+ tracker.onLongPressed();
// Long pressing on 0 in phone number keypad gives you a '+'.
return invokeOnKey('+');
} else {
diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
index 29a575ad0..aa2f3af48 100644
--- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java
+++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
@@ -18,7 +18,6 @@ package com.android.inputmethod.keyboard;
import android.content.Context;
import android.content.res.Resources;
-import android.os.SystemClock;
import android.util.Log;
import com.android.inputmethod.keyboard.internal.PointerTrackerQueue;
@@ -26,6 +25,7 @@ import com.android.inputmethod.latin.LatinImeLogger;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.SubtypeSwitcher;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -78,23 +78,24 @@ public class PointerTracker {
public void cancelKeyTimers();
}
- public final int mPointerId;
-
+ private static KeyboardSwitcher sKeyboardSwitcher;
+ private static boolean sConfigSlidingKeyInputEnabled;
// Timing constants
- private final int mDelayBeforeKeyRepeatStart;
- private final int mLongPressKeyTimeout;
- private final int mLongPressShiftKeyTimeout;
+ private static int sDelayBeforeKeyRepeatStart;
+ private static int sLongPressKeyTimeout;
+ private static int sLongPressShiftKeyTimeout;
+ private static int sTouchNoiseThresholdMillis;
+ private static int sTouchNoiseThresholdDistanceSquared;
+
+ private static final List<PointerTracker> sTrackers = new ArrayList<PointerTracker>();
+ private static PointerTrackerQueue sPointerTrackerQueue;
+
+ public final int mPointerId;
private DrawingProxy mDrawingProxy;
private TimerProxy mTimerProxy;
- private final PointerTrackerQueue mPointerTrackerQueue;
private KeyDetector mKeyDetector;
private KeyboardActionListener mListener = EMPTY_LISTENER;
- private final KeyboardSwitcher mKeyboardSwitcher;
- private final boolean mConfigSlidingKeyInputEnabled;
-
- private final int mTouchNoiseThresholdMillis;
- private final int mTouchNoiseThresholdDistanceSquared;
private Keyboard mKeyboard;
private List<Key> mKeys;
@@ -124,7 +125,7 @@ public class PointerTracker {
private boolean mIsRepeatableKey;
// true if this pointer is in sliding key input
- private boolean mIsInSlidingKeyInput;
+ boolean mIsInSlidingKeyInput;
// true if sliding key is allowed.
private boolean mIsAllowedSlidingKeyInput;
@@ -136,7 +137,7 @@ public class PointerTracker {
// true if this pointer is in sliding language switch
private boolean mIsInSlidingLanguageSwitch;
private int mSpaceKeyIndex;
- private final SubtypeSwitcher mSubtypeSwitcher;
+ private static SubtypeSwitcher sSubtypeSwitcher;
// Empty {@link KeyboardActionListener}
private static final KeyboardActionListener EMPTY_LISTENER = new KeyboardActionListener() {
@@ -152,31 +153,72 @@ public class PointerTracker {
public void onCancelInput() {}
};
- public PointerTracker(int id, Context context, TimerProxy timerProxy, KeyDetector keyDetector,
- DrawingProxy drawingProxy, PointerTrackerQueue queue) {
- if (drawingProxy == null || timerProxy == null || keyDetector == null)
- throw new NullPointerException();
- mPointerId = id;
- mDrawingProxy = drawingProxy;
- mTimerProxy = timerProxy;
- mPointerTrackerQueue = queue; // This is null for non-distinct multi-touch device.
- setKeyDetectorInner(keyDetector);
- mKeyboardSwitcher = KeyboardSwitcher.getInstance();
+ public static void init(boolean hasDistinctMultitouch, Context context) {
+ if (hasDistinctMultitouch) {
+ sPointerTrackerQueue = new PointerTrackerQueue();
+ } else {
+ sPointerTrackerQueue = null;
+ }
+
final Resources res = context.getResources();
- mConfigSlidingKeyInputEnabled = res.getBoolean(R.bool.config_sliding_key_input_enabled);
- mDelayBeforeKeyRepeatStart = res.getInteger(R.integer.config_delay_before_key_repeat_start);
- mLongPressKeyTimeout = res.getInteger(R.integer.config_long_press_key_timeout);
- mLongPressShiftKeyTimeout = res.getInteger(R.integer.config_long_press_shift_key_timeout);
- mTouchNoiseThresholdMillis = res.getInteger(R.integer.config_touch_noise_threshold_millis);
+ sConfigSlidingKeyInputEnabled = res.getBoolean(R.bool.config_sliding_key_input_enabled);
+ sDelayBeforeKeyRepeatStart = res.getInteger(R.integer.config_delay_before_key_repeat_start);
+ sLongPressKeyTimeout = res.getInteger(R.integer.config_long_press_key_timeout);
+ sLongPressShiftKeyTimeout = res.getInteger(R.integer.config_long_press_shift_key_timeout);
+ sTouchNoiseThresholdMillis = res.getInteger(R.integer.config_touch_noise_threshold_millis);
final float touchNoiseThresholdDistance = res.getDimension(
R.dimen.config_touch_noise_threshold_distance);
- mTouchNoiseThresholdDistanceSquared = (int)(
+ sTouchNoiseThresholdDistanceSquared = (int)(
touchNoiseThresholdDistance * touchNoiseThresholdDistance);
- mSubtypeSwitcher = SubtypeSwitcher.getInstance();
+ sKeyboardSwitcher = KeyboardSwitcher.getInstance();
+ sSubtypeSwitcher = SubtypeSwitcher.getInstance();
}
- public void setKeyboardActionListener(KeyboardActionListener listener) {
- mListener = listener;
+ public static PointerTracker getPointerTracker(final int id, KeyEventHandler handler) {
+ final List<PointerTracker> trackers = sTrackers;
+
+ // Create pointer trackers until we can get 'id+1'-th tracker, if needed.
+ for (int i = trackers.size(); i <= id; i++) {
+ final PointerTracker tracker = new PointerTracker(i, handler);
+ trackers.add(tracker);
+ }
+
+ return trackers.get(id);
+ }
+
+ public static boolean isAnyInSlidingKeyInput() {
+ return sPointerTrackerQueue != null ? sPointerTrackerQueue.isAnyInSlidingKeyInput() : false;
+ }
+
+ public static void setKeyboardActionListener(KeyboardActionListener listener) {
+ for (final PointerTracker tracker : sTrackers) {
+ tracker.mListener = listener;
+ }
+ }
+
+ public static void setKeyDetector(KeyDetector keyDetector) {
+ for (final PointerTracker tracker : sTrackers) {
+ tracker.setKeyDetectorInner(keyDetector);
+ // Mark that keyboard layout has been changed.
+ tracker.mKeyboardLayoutHasBeenChanged = true;
+ }
+ }
+
+ public static void dismissAllKeyPreviews() {
+ for (final PointerTracker tracker : sTrackers) {
+ tracker.setReleasedKeyGraphics();
+ tracker.dismissKeyPreview();
+ }
+ }
+
+ public PointerTracker(int id, KeyEventHandler handler) {
+ if (handler == null)
+ throw new NullPointerException();
+ mPointerId = id;
+ setKeyDetectorInner(handler.getKeyDetector());
+ mListener = handler.getKeyboardActionListener();
+ mDrawingProxy = handler.getDrawingProxy();
+ mTimerProxy = handler.getTimerProxy();
}
// Returns true if keyboard has been changed by this callback.
@@ -244,14 +286,6 @@ public class PointerTracker {
mKeyQuarterWidthSquared = keyQuarterWidth * keyQuarterWidth;
}
- public void setKeyDetector(KeyDetector keyDetector) {
- if (keyDetector == null)
- throw new NullPointerException();
- setKeyDetectorInner(keyDetector);
- // Mark that keyboard layout has been changed.
- mKeyboardLayoutHasBeenChanged = true;
- }
-
public boolean isInSlidingKeyInput() {
return mIsInSlidingKeyInput;
}
@@ -361,15 +395,16 @@ public class PointerTracker {
printTouchEvent("onDownEvent:", x, y, eventTime);
mDrawingProxy = handler.getDrawingProxy();
+ mTimerProxy = handler.getTimerProxy();
setKeyboardActionListener(handler.getKeyboardActionListener());
setKeyDetectorInner(handler.getKeyDetector());
// Naive up-to-down noise filter.
final long deltaT = eventTime - mUpTime;
- if (deltaT < mTouchNoiseThresholdMillis) {
+ if (deltaT < sTouchNoiseThresholdMillis) {
final int dx = x - mLastX;
final int dy = y - mLastY;
final int distanceSquared = (dx * dx + dy * dy);
- if (distanceSquared < mTouchNoiseThresholdDistanceSquared) {
+ if (distanceSquared < sTouchNoiseThresholdDistanceSquared) {
if (DEBUG_MODE)
Log.w(TAG, "onDownEvent: ignore potential noise: time=" + deltaT
+ " distance=" + distanceSquared);
@@ -378,7 +413,7 @@ public class PointerTracker {
}
}
- final PointerTrackerQueue queue = mPointerTrackerQueue;
+ final PointerTrackerQueue queue = sPointerTrackerQueue;
if (queue != null) {
if (isOnModifierKey(x, y)) {
// Before processing a down event of modifier key, all pointers already being
@@ -394,7 +429,7 @@ public class PointerTracker {
int keyIndex = onDownKey(x, y, eventTime);
// Sliding key is allowed when 1) enabled by configuration, 2) this pointer starts sliding
// from modifier key, or 3) this pointer is on mini-keyboard.
- mIsAllowedSlidingKeyInput = mConfigSlidingKeyInputEnabled || isModifierInternal(keyIndex)
+ mIsAllowedSlidingKeyInput = sConfigSlidingKeyInputEnabled || isModifierInternal(keyIndex)
|| mKeyDetector instanceof MiniKeyboardKeyDetector;
mKeyboardLayoutHasBeenChanged = false;
mKeyAlreadyProcessed = false;
@@ -495,8 +530,8 @@ public class PointerTracker {
else if (isSpaceKey(keyIndex) && !mIsInSlidingLanguageSwitch
&& mKeyboard instanceof LatinKeyboard) {
final LatinKeyboard keyboard = ((LatinKeyboard)mKeyboard);
- if (mSubtypeSwitcher.useSpacebarLanguageSwitcher()
- && mSubtypeSwitcher.getEnabledKeyboardLocaleCount() > 1) {
+ if (sSubtypeSwitcher.useSpacebarLanguageSwitcher()
+ && sSubtypeSwitcher.getEnabledKeyboardLocaleCount() > 1) {
final int diff = x - mKeyX;
if (keyboard.shouldTriggerSpacebarSlidingLanguageSwitch(diff)) {
// Detect start sliding language switch.
@@ -505,7 +540,7 @@ public class PointerTracker {
keyboard.updateSpacebarPreviewIcon(diff);
// Display spacebar slide language switcher.
showKeyPreview(keyIndex);
- final PointerTrackerQueue queue = mPointerTrackerQueue;
+ final PointerTrackerQueue queue = sPointerTrackerQueue;
if (queue != null)
queue.releaseAllPointersExcept(this, eventTime, true);
}
@@ -533,7 +568,7 @@ public class PointerTracker {
if (DEBUG_EVENT)
printTouchEvent("onUpEvent :", x, y, eventTime);
- final PointerTrackerQueue queue = mPointerTrackerQueue;
+ final PointerTrackerQueue queue = sPointerTrackerQueue;
if (queue != null) {
if (isModifier()) {
// Before processing an up event of modifier key, all pointers already being
@@ -598,10 +633,10 @@ public class PointerTracker {
public void onLongPressed() {
mKeyAlreadyProcessed = true;
- final PointerTrackerQueue queue = mPointerTrackerQueue;
+ setReleasedKeyGraphics();
+ dismissKeyPreview();
+ final PointerTrackerQueue queue = sPointerTrackerQueue;
if (queue != null) {
- // TODO: Support chording + long-press input.
- queue.releaseAllPointersExcept(this, SystemClock.uptimeMillis(), true);
queue.remove(this);
}
}
@@ -610,7 +645,7 @@ public class PointerTracker {
if (DEBUG_EVENT)
printTouchEvent("onCancelEvt:", x, y, eventTime);
- final PointerTrackerQueue queue = mPointerTrackerQueue;
+ final PointerTrackerQueue queue = sPointerTrackerQueue;
if (queue != null) {
queue.releaseAllPointersExcept(this, eventTime, true);
queue.remove(this);
@@ -631,7 +666,7 @@ public class PointerTracker {
if (key != null && key.mRepeatable) {
dismissKeyPreview();
onRepeatKey(keyIndex);
- mTimerProxy.startKeyRepeatTimer(mDelayBeforeKeyRepeatStart, keyIndex, this);
+ mTimerProxy.startKeyRepeatTimer(sDelayBeforeKeyRepeatStart, keyIndex, this);
mIsRepeatableKey = true;
} else {
mIsRepeatableKey = false;
@@ -685,16 +720,16 @@ public class PointerTracker {
private void startLongPressTimer(int keyIndex) {
Key key = getKey(keyIndex);
if (key.mCode == Keyboard.CODE_SHIFT) {
- mTimerProxy.startLongPressShiftTimer(mLongPressShiftKeyTimeout, keyIndex, this);
+ mTimerProxy.startLongPressShiftTimer(sLongPressShiftKeyTimeout, keyIndex, this);
} else if (key.hasUppercaseLetter() && mKeyboard.isManualTemporaryUpperCase()) {
// We need not start long press timer on the key which has manual temporary upper case
// code defined and the keyboard is in manual temporary upper case mode.
return;
- } else if (mKeyboardSwitcher.isInMomentarySwitchState()) {
+ } else if (sKeyboardSwitcher.isInMomentarySwitchState()) {
// We use longer timeout for sliding finger input started from the symbols mode key.
- mTimerProxy.startLongPressTimer(mLongPressKeyTimeout * 3, keyIndex, this);
+ mTimerProxy.startLongPressTimer(sLongPressKeyTimeout * 3, keyIndex, this);
} else {
- mTimerProxy.startLongPressTimer(mLongPressKeyTimeout, keyIndex, this);
+ mTimerProxy.startLongPressTimer(sLongPressKeyTimeout, keyIndex, this);
}
}
diff --git a/java/src/com/android/inputmethod/keyboard/PopupMiniKeyboardView.java b/java/src/com/android/inputmethod/keyboard/PopupMiniKeyboardView.java
index a3d9c0465..af8e59568 100644
--- a/java/src/com/android/inputmethod/keyboard/PopupMiniKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/PopupMiniKeyboardView.java
@@ -18,26 +18,73 @@ package com.android.inputmethod.keyboard;
import android.content.Context;
import android.content.res.Resources;
-import android.os.SystemClock;
+import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.Gravity;
-import android.view.MotionEvent;
import android.view.View;
import android.widget.PopupWindow;
+import com.android.inputmethod.keyboard.PointerTracker.DrawingProxy;
+import com.android.inputmethod.keyboard.PointerTracker.TimerProxy;
import com.android.inputmethod.latin.R;
/**
* A view that renders a virtual {@link MiniKeyboard}. It handles rendering of keys and detecting
* key presses and touch movements.
*/
-public class PopupMiniKeyboardView extends LatinKeyboardBaseView implements PopupPanel {
+public class PopupMiniKeyboardView extends KeyboardView implements PopupPanel {
private final int[] mCoordinates = new int[2];
private final boolean mConfigShowMiniKeyboardAtTouchedPoint;
+ private final KeyDetector mKeyDetector;
+ private final int mVerticalCorrection;
+
+ private LatinKeyboardBaseView mParentKeyboardView;
private int mOriginX;
private int mOriginY;
- private long mDownTime;
+
+ private static final TimerProxy EMPTY_TIMER_PROXY = new TimerProxy() {
+ @Override
+ public void startKeyRepeatTimer(long delay, int keyIndex, PointerTracker tracker) {}
+ @Override
+ public void startLongPressTimer(long delay, int keyIndex, PointerTracker tracker) {}
+ @Override
+ public void startLongPressShiftTimer(long delay, int keyIndex, PointerTracker tracker) {}
+ @Override
+ public void cancelLongPressTimers() {}
+ @Override
+ public void cancelKeyTimers() {}
+ };
+
+ private final KeyboardActionListener mListner = new KeyboardActionListener() {
+ @Override
+ public void onCodeInput(int primaryCode, int[] keyCodes, int x, int y) {
+ mParentKeyboardView.getKeyboardActionListener()
+ .onCodeInput(primaryCode, keyCodes, x, y);
+ mParentKeyboardView.dismissMiniKeyboard();
+ }
+
+ @Override
+ public void onTextInput(CharSequence text) {
+ mParentKeyboardView.getKeyboardActionListener().onTextInput(text);
+ mParentKeyboardView.dismissMiniKeyboard();
+ }
+
+ @Override
+ public void onCancelInput() {
+ mParentKeyboardView.getKeyboardActionListener().onCancelInput();
+ mParentKeyboardView.dismissMiniKeyboard();
+ }
+
+ @Override
+ public void onPress(int primaryCode, boolean withSliding) {
+ mParentKeyboardView.getKeyboardActionListener().onPress(primaryCode, withSliding);
+ }
+ @Override
+ public void onRelease(int primaryCode, boolean withSliding) {
+ mParentKeyboardView.getKeyboardActionListener().onRelease(primaryCode, withSliding);
+ }
+ };
public PopupMiniKeyboardView(Context context, AttributeSet attrs) {
this(context, attrs, R.attr.popupMiniKeyboardViewStyle);
@@ -46,6 +93,12 @@ public class PopupMiniKeyboardView extends LatinKeyboardBaseView implements Popu
public PopupMiniKeyboardView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
+ final TypedArray a = context.obtainStyledAttributes(
+ attrs, R.styleable.KeyboardView, defStyle, R.style.KeyboardView);
+ mVerticalCorrection = a.getDimensionPixelOffset(
+ R.styleable.KeyboardView_verticalCorrection, 0);
+ a.recycle();
+
final Resources res = context.getResources();
mConfigShowMiniKeyboardAtTouchedPoint = res.getBoolean(
R.bool.config_show_mini_keyboard_at_touched_point);
@@ -53,11 +106,37 @@ public class PopupMiniKeyboardView extends LatinKeyboardBaseView implements Popu
mKeyDetector = new MiniKeyboardKeyDetector(res.getDimension(
R.dimen.mini_keyboard_slide_allowance));
// Remove gesture detector on mini-keyboard
- mGestureDetector = null;
setKeyPreviewPopupEnabled(false, 0);
}
@Override
+ public void setKeyboard(Keyboard keyboard) {
+ super.setKeyboard(keyboard);
+ mKeyDetector.setKeyboard(keyboard, -getPaddingLeft(),
+ -getPaddingTop() + mVerticalCorrection);
+ }
+
+ @Override
+ public KeyDetector getKeyDetector() {
+ return mKeyDetector;
+ }
+
+ @Override
+ public KeyboardActionListener getKeyboardActionListener() {
+ return mListner;
+ }
+
+ @Override
+ public DrawingProxy getDrawingProxy() {
+ return this;
+ }
+
+ @Override
+ public TimerProxy getTimerProxy() {
+ return EMPTY_TIMER_PROXY;
+ }
+
+ @Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
// Do nothing for the mini keyboard.
}
@@ -70,8 +149,9 @@ public class PopupMiniKeyboardView extends LatinKeyboardBaseView implements Popu
}
@Override
- public void showPanel(KeyboardView parentKeyboardView, Key parentKey,
+ public void showPanel(LatinKeyboardBaseView parentKeyboardView, Key parentKey,
PointerTracker tracker, PopupWindow window) {
+ mParentKeyboardView = parentKeyboardView;
final View container = (View)getParent();
final MiniKeyboard miniKeyboard = (MiniKeyboard)getKeyboard();
final Keyboard parentKeyboard = parentKeyboardView.getKeyboard();
@@ -99,19 +179,15 @@ public class PopupMiniKeyboardView extends LatinKeyboardBaseView implements Popu
mOriginX = x + container.getPaddingLeft() - mCoordinates[0];
mOriginY = y + container.getPaddingTop() - mCoordinates[1];
- mDownTime = SystemClock.uptimeMillis();
-
- // Inject down event on the key to mini keyboard.
- final MotionEvent downEvent = MotionEvent.obtain(mDownTime, mDownTime,
- MotionEvent.ACTION_DOWN, pointX - mOriginX,
- pointY + parentKey.mHeight / 2 - mOriginY, 0);
- onTouchEvent(downEvent);
- downEvent.recycle();
}
@Override
- public boolean onTouchEvent(MotionEvent me) {
- me.offsetLocation(-mOriginX, -mOriginY);
- return super.onTouchEvent(me);
+ public int translateX(int x) {
+ return x - mOriginX;
+ }
+
+ @Override
+ public int translateY(int y) {
+ return y - mOriginY;
}
}
diff --git a/java/src/com/android/inputmethod/keyboard/PopupPanel.java b/java/src/com/android/inputmethod/keyboard/PopupPanel.java
index 2d9130fcb..f94d1c562 100644
--- a/java/src/com/android/inputmethod/keyboard/PopupPanel.java
+++ b/java/src/com/android/inputmethod/keyboard/PopupPanel.java
@@ -16,7 +16,6 @@
package com.android.inputmethod.keyboard;
-import android.view.MotionEvent;
import android.widget.PopupWindow;
public interface PopupPanel extends PointerTracker.KeyEventHandler {
@@ -27,19 +26,20 @@ public interface PopupPanel extends PointerTracker.KeyEventHandler {
* @param tracker the pointer tracker that pressesd the parent key
* @param window PopupWindow to be used to show this popup panel
*/
- public void showPanel(KeyboardView parentKeyboardView, Key parentKey,
+ public void showPanel(LatinKeyboardBaseView parentKeyboardView, Key parentKey,
PointerTracker tracker, PopupWindow window);
/**
- * Check if the pointer is in siding key input mode.
- * @return true if the pointer is sliding key input mode.
+ * Translate X-coordinate of touch event to the local X-coordinate of this PopupPanel.
+ * @param x the global X-coordinate
+ * @return the local X-coordinate to this PopupPanel
*/
- public boolean isInSlidingKeyInput();
+ public int translateX(int x);
/**
- * The motion event handler.
- * @param me the MotionEvent to be processed.
- * @return true if the motion event is processed and should be consumed.
+ * Translate Y-coordinate of touch event to the local Y-coordinate of this PopupPanel.
+ * @param y the global Y-coordinate
+ * @return the local Y-coordinate to this PopupPanel
*/
- public boolean onTouchEvent(MotionEvent me);
+ public int translateY(int y);
}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java b/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java
index 1530fed6f..535a6954c 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyboardIconsSet.java
@@ -34,21 +34,22 @@ public class KeyboardIconsSet {
private static final int ICON_TO_SYMBOL_KEY = 2;
private static final int ICON_TO_SYMBOL_KEY_WITH_SHORTCUT = 3;
private static final int ICON_DELETE_KEY = 4;
- private static final int ICON_SETTINGS_KEY = 5;
- private static final int ICON_SHORTCUT_KEY = 6;
- private static final int ICON_SPACE_KEY = 7;
- private static final int ICON_RETURN_KEY = 8;
- private static final int ICON_SEARCH_KEY = 9;
- private static final int ICON_TAB_KEY = 10;
+ private static final int ICON_DELETE_RTL_KEY = 5;
+ private static final int ICON_SETTINGS_KEY = 6;
+ private static final int ICON_SHORTCUT_KEY = 7;
+ private static final int ICON_SPACE_KEY = 8;
+ private static final int ICON_RETURN_KEY = 9;
+ private static final int ICON_SEARCH_KEY = 10;
+ private static final int ICON_TAB_KEY = 11;
// This should be aligned with Keyboard.keyIconShifted enum.
- private static final int ICON_SHIFTED_SHIFT_KEY = 11;
+ private static final int ICON_SHIFTED_SHIFT_KEY = 12;
// This should be aligned with Keyboard.keyIconPreview enum.
- private static final int ICON_PREVIEW_SPACE_KEY = 12;
- private static final int ICON_PREVIEW_TAB_KEY = 13;
- private static final int ICON_PREVIEW_SETTINGS_KEY = 14;
- private static final int ICON_PREVIEW_SHORTCUT_KEY = 15;
+ private static final int ICON_PREVIEW_SPACE_KEY = 13;
+ private static final int ICON_PREVIEW_TAB_KEY = 14;
+ private static final int ICON_PREVIEW_SETTINGS_KEY = 15;
+ private static final int ICON_PREVIEW_SHORTCUT_KEY = 16;
- private static final int ICON_LAST = 15;
+ private static final int ICON_LAST = 16;
private final Drawable mIcons[] = new Drawable[ICON_LAST + 1];
@@ -62,6 +63,8 @@ public class KeyboardIconsSet {
return ICON_TO_SYMBOL_KEY_WITH_SHORTCUT;
case R.styleable.Keyboard_iconDeleteKey:
return ICON_DELETE_KEY;
+ case R.styleable.Keyboard_iconDeleteRtlKey:
+ return ICON_DELETE_RTL_KEY;
case R.styleable.Keyboard_iconSettingsKey:
return ICON_SETTINGS_KEY;
case R.styleable.Keyboard_iconShortcutKey:
diff --git a/java/src/com/android/inputmethod/keyboard/internal/PointerTrackerQueue.java b/java/src/com/android/inputmethod/keyboard/internal/PointerTrackerQueue.java
index f87cd869e..545b27fdc 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/PointerTrackerQueue.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/PointerTrackerQueue.java
@@ -63,7 +63,7 @@ public class PointerTrackerQueue {
mQueue.remove(tracker);
}
- public boolean isInSlidingKeyInput() {
+ public boolean isAnyInSlidingKeyInput() {
for (final PointerTracker tracker : mQueue) {
if (tracker.isInSlidingKeyInput())
return true;
diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java
index cec30eaab..5304d830d 100644
--- a/java/src/com/android/inputmethod/latin/LatinIME.java
+++ b/java/src/com/android/inputmethod/latin/LatinIME.java
@@ -1803,19 +1803,18 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar
final InputConnection ic = getCurrentInputConnection();
final CharSequence punctuation = ic.getTextBeforeCursor(1, 0);
if (deleteChar) ic.deleteSurroundingText(1, 0);
- int toDelete = mCommittedLength;
- final CharSequence toTheLeft = ic.getTextBeforeCursor(mCommittedLength, 0);
- if (!TextUtils.isEmpty(toTheLeft)
- && mSettingsValues.isWordSeparator(toTheLeft.charAt(0))) {
- toDelete--;
- }
- ic.deleteSurroundingText(toDelete, 0);
+ final CharSequence textToTheLeft = ic.getTextBeforeCursor(mCommittedLength, 0);
+ final int toDeleteLength = (!TextUtils.isEmpty(textToTheLeft)
+ && mSettingsValues.isWordSeparator(textToTheLeft.charAt(0)))
+ ? mCommittedLength - 1 : mCommittedLength;
+ ic.deleteSurroundingText(toDeleteLength, 0);
+
// Re-insert punctuation only when the deleted character was word separator and the
// composing text wasn't equal to the auto-corrected text.
if (deleteChar
&& !TextUtils.isEmpty(punctuation)
&& mSettingsValues.isWordSeparator(punctuation.charAt(0))
- && !TextUtils.equals(mComposingStringBuilder, toTheLeft)) {
+ && !TextUtils.equals(mComposingStringBuilder, textToTheLeft)) {
ic.commitText(mComposingStringBuilder, 1);
TextEntryState.acceptedTyped(mComposingStringBuilder);
ic.commitText(punctuation, 1);
diff --git a/java/src/com/android/inputmethod/latin/UserDictionary.java b/java/src/com/android/inputmethod/latin/UserDictionary.java
index c06bd736e..2aaa26c8d 100644
--- a/java/src/com/android/inputmethod/latin/UserDictionary.java
+++ b/java/src/com/android/inputmethod/latin/UserDictionary.java
@@ -16,12 +16,14 @@
package com.android.inputmethod.latin;
+import android.content.ContentProviderClient;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
+import android.os.RemoteException;
import android.provider.UserDictionary.Words;
public class UserDictionary extends ExpandableDictionary {
@@ -99,24 +101,34 @@ public class UserDictionary extends ExpandableDictionary {
values.put(Words.APP_ID, 0);
final ContentResolver contentResolver = getContext().getContentResolver();
+ final ContentProviderClient client =
+ contentResolver.acquireContentProviderClient(Words.CONTENT_URI);
+ if (null == client) return;
new Thread("addWord") {
@Override
public void run() {
- Cursor cursor = contentResolver.query(Words.CONTENT_URI, PROJECTION_ADD,
- "word=? and ((locale IS NULL) or (locale=?))",
- new String[] { word, mLocale }, null);
- if (cursor != null && cursor.moveToFirst()) {
- String locale = cursor.getString(cursor.getColumnIndex(Words.LOCALE));
- // If locale is null, we will not override the entry.
- if (locale != null && locale.equals(mLocale.toString())) {
- long id = cursor.getLong(cursor.getColumnIndex(Words._ID));
- Uri uri = Uri.withAppendedPath(Words.CONTENT_URI, Long.toString(id));
- // Update the entry with new frequency value.
- contentResolver.update(uri, values, null, null);
+ try {
+ final Cursor cursor = client.query(Words.CONTENT_URI, PROJECTION_ADD,
+ "word=? and ((locale IS NULL) or (locale=?))",
+ new String[] { word, mLocale }, null);
+ if (cursor != null && cursor.moveToFirst()) {
+ final String locale = cursor.getString(cursor.getColumnIndex(Words.LOCALE));
+ // If locale is null, we will not override the entry.
+ if (locale != null && locale.equals(mLocale.toString())) {
+ final long id = cursor.getLong(cursor.getColumnIndex(Words._ID));
+ final Uri uri =
+ Uri.withAppendedPath(Words.CONTENT_URI, Long.toString(id));
+ // Update the entry with new frequency value.
+ client.update(uri, values, null, null);
+ }
+ } else {
+ // Insert new entry.
+ client.insert(Words.CONTENT_URI, values);
}
- } else {
- // Insert new entry.
- contentResolver.insert(Words.CONTENT_URI, values);
+ } catch (RemoteException e) {
+ // If we come here, the activity is already about to be killed, and we
+ // have no means of contacting the content provider any more.
+ // See ContentResolver#insert, inside the catch(){}
}
}
}.start();