diff options
Diffstat (limited to 'java/src/com/android/inputmethod/keyboard/KeyboardView.java')
| -rw-r--r-- | java/src/com/android/inputmethod/keyboard/KeyboardView.java | 138 |
1 files changed, 48 insertions, 90 deletions
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java index 766fdf0e6..6d7bfb8d5 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java @@ -125,7 +125,7 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { // Popup mini keyboard private PopupWindow mMiniKeyboardPopup; - private KeyboardView mMiniKeyboard; + private KeyboardView mMiniKeyboardView; private View mMiniKeyboardParent; private final WeakHashMap<Key, View> mMiniKeyboardCache = new WeakHashMap<Key, View>(); private int mMiniKeyboardOriginX; @@ -134,6 +134,7 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { private int[] mWindowOffset; private final float mMiniKeyboardSlideAllowance; private int mMiniKeyboardTrackerId; + private final boolean mConfigShowMiniKeyboardAtTouchedPoint; /** Listener for {@link KeyboardActionListener}. */ private KeyboardActionListener mKeyboardActionListener; @@ -296,7 +297,7 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { public KeyboardView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); - TypedArray a = context.obtainStyledAttributes( + final TypedArray a = context.obtainStyledAttributes( attrs, R.styleable.KeyboardView, defStyle, R.style.KeyboardView); int previewLayout = 0; int keyTextSize = 0; @@ -381,6 +382,8 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { mMiniKeyboardPopup = new PopupWindow(context); mMiniKeyboardPopup.setBackgroundDrawable(null); mMiniKeyboardPopup.setAnimationStyle(R.style.MiniKeyboardAnimation); + // Allow popup window to be drawn off the screen. + mMiniKeyboardPopup.setClippingEnabled(false); mPaint = new Paint(); mPaint.setAntiAlias(true); @@ -395,6 +398,8 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { // TODO: Refer frameworks/base/core/res/res/values/config.xml mDisambiguateSwipe = res.getBoolean(R.bool.config_swipeDisambiguation); mMiniKeyboardSlideAllowance = res.getDimension(R.dimen.mini_keyboard_slide_allowance); + mConfigShowMiniKeyboardAtTouchedPoint = res.getBoolean( + R.bool.config_show_mini_keyboard_at_touched_point); GestureDetector.SimpleOnGestureListener listener = new GestureDetector.SimpleOnGestureListener() { @@ -535,10 +540,6 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { return mColorScheme; } - public void setPopupParent(View v) { - mMiniKeyboardParent = v; - } - public void setPopupOffset(int x, int y) { mPopupPreviewOffsetX = x; mPopupPreviewOffsetY = y; @@ -798,7 +799,7 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { mInvalidatedKey = null; // Overlay a dark rectangle to dim the keyboard - if (mMiniKeyboard != null) { + if (mMiniKeyboardView != null) { paint.setColor((int) (mBackgroundDimAmount * 0xFF) << 24); canvas.drawRect(0, 0, getWidth(), getHeight(), paint); } @@ -1052,7 +1053,7 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { Key popupKey = tracker.getKey(keyIndex); if (popupKey == null) return false; - boolean result = onLongPress(popupKey); + boolean result = onLongPress(popupKey, tracker); if (result) { dismissKeyPreview(); mMiniKeyboardTrackerId = tracker.mPointerId; @@ -1077,14 +1078,13 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { } private View inflateMiniKeyboardContainer(Key popupKey) { - int popupKeyboardResId = mKeyboard.getPopupKeyboardResId(); - View container = LayoutInflater.from(getContext()).inflate(mPopupLayout, null); + final View container = LayoutInflater.from(getContext()).inflate(mPopupLayout, null); if (container == null) throw new NullPointerException(); - KeyboardView miniKeyboard = + final KeyboardView miniKeyboardView = (KeyboardView)container.findViewById(R.id.KeyboardView); - miniKeyboard.setOnKeyboardActionListener(new KeyboardActionListener() { + miniKeyboardView.setOnKeyboardActionListener(new KeyboardActionListener() { @Override public void onCodeInput(int primaryCode, int[] keyCodes, int x, int y) { mKeyboardActionListener.onCodeInput(primaryCode, keyCodes, x, y); @@ -1117,14 +1117,14 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { } }); // Override default ProximityKeyDetector. - miniKeyboard.mKeyDetector = new MiniKeyboardKeyDetector(mMiniKeyboardSlideAllowance); + miniKeyboardView.mKeyDetector = new MiniKeyboardKeyDetector(mMiniKeyboardSlideAllowance); // Remove gesture detector on mini-keyboard - miniKeyboard.mGestureDetector = null; + miniKeyboardView.mGestureDetector = null; - Keyboard keyboard = new MiniKeyboardBuilder(this, popupKeyboardResId, popupKey) - .build(); - miniKeyboard.setKeyboard(keyboard); - miniKeyboard.setPopupParent(this); + final Keyboard keyboard = new MiniKeyboardBuilder(this, mKeyboard.getPopupKeyboardResId(), + popupKey).build(); + miniKeyboardView.setKeyboard(keyboard); + miniKeyboardView.mMiniKeyboardParent = this; container.measure(MeasureSpec.makeMeasureSpec(getWidth(), MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(getHeight(), MeasureSpec.AT_MOST)); @@ -1152,7 +1152,7 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { * @return true if the long press is handled, false otherwise. Subclasses should call the * method on the base class if the subclass doesn't wish to handle the call. */ - protected boolean onLongPress(Key popupKey) { + protected boolean onLongPress(Key popupKey, PointerTracker tracker) { if (popupKey.mPopupCharacters == null) return false; @@ -1161,93 +1161,51 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { container = inflateMiniKeyboardContainer(popupKey); mMiniKeyboardCache.put(popupKey, container); } - mMiniKeyboard = (KeyboardView)container.findViewById(R.id.KeyboardView); + mMiniKeyboardView = (KeyboardView)container.findViewById(R.id.KeyboardView); + final MiniKeyboard miniKeyboard = (MiniKeyboard)mMiniKeyboardView.getKeyboard(); + if (mWindowOffset == null) { mWindowOffset = new int[2]; getLocationInWindow(mWindowOffset); } - - // Get width of a key in the mini popup keyboard = "miniKeyWidth". - // On the other hand, "popupKey.width" is width of the pressed key on the main keyboard. - // We adjust the position of mini popup keyboard with the edge key in it: - // a) When we have the leftmost key in popup keyboard directly above the pressed key - // Right edges of both keys should be aligned for consistent default selection - // b) When we have the rightmost key in popup keyboard directly above the pressed key - // Left edges of both keys should be aligned for consistent default selection - final List<Key> miniKeys = mMiniKeyboard.getKeyboard().getKeys(); - final int miniKeyWidth = miniKeys.size() > 0 ? miniKeys.get(0).mWidth : 0; - - // HACK: Have the leftmost number in the popup characters right above the key - boolean isNumberAtLeftmost = - hasMultiplePopupChars(popupKey) && isNumberAtLeftmostPopupChar(popupKey); - int popupX = popupKey.mX + mWindowOffset[0]; - popupX += getPaddingLeft(); - if (isNumberAtLeftmost) { - popupX += popupKey.mWidth - miniKeyWidth; // adjustment for a) described above - popupX -= container.getPaddingLeft(); - } else { - popupX += miniKeyWidth; // adjustment for b) described above - popupX -= container.getMeasuredWidth(); - popupX += container.getPaddingRight(); - } - int popupY = popupKey.mY + mWindowOffset[1]; - popupY += getPaddingTop(); - popupY -= container.getMeasuredHeight(); - popupY += container.getPaddingBottom(); + final int pointX = (mConfigShowMiniKeyboardAtTouchedPoint) ? tracker.getLastX() + : popupKey.mX + popupKey.mWidth / 2; + final int popupX = pointX - miniKeyboard.getDefaultCoordX() + - container.getPaddingLeft() + + getPaddingLeft() + mWindowOffset[0]; + final int popupY = popupKey.mY - mKeyboard.getVerticalGap() + - (container.getMeasuredHeight() - container.getPaddingBottom()) + + getPaddingTop() + mWindowOffset[1]; final int x = popupX; - final int y = mShowPreview && isOneRowKeys(miniKeys) ? mPopupPreviewDisplayedY : popupY; + final int y = mShowPreview && isOneRowKeys(miniKeyboard.getKeys()) + ? mPopupPreviewDisplayedY : popupY; - int adjustedX = x; - if (x < 0) { - adjustedX = 0; - } else if (x > (getMeasuredWidth() - container.getMeasuredWidth())) { - adjustedX = getMeasuredWidth() - container.getMeasuredWidth(); - } - mMiniKeyboardOriginX = adjustedX + container.getPaddingLeft() - mWindowOffset[0]; + mMiniKeyboardOriginX = x + container.getPaddingLeft() - mWindowOffset[0]; mMiniKeyboardOriginY = y + container.getPaddingTop() - mWindowOffset[1]; - mMiniKeyboard.setPopupOffset(adjustedX, y); - Keyboard baseMiniKeyboard = mMiniKeyboard.getKeyboard(); - if (baseMiniKeyboard != null && baseMiniKeyboard.setShifted(mKeyboard == null - ? false : mKeyboard.isShiftedOrShiftLocked())) { - mMiniKeyboard.invalidateAllKeys(); + mMiniKeyboardView.setPopupOffset(x, y); + if (miniKeyboard.setShifted( + mKeyboard == null ? false : mKeyboard.isShiftedOrShiftLocked())) { + mMiniKeyboardView.invalidateAllKeys(); } // Mini keyboard needs no pop-up key preview displayed. - mMiniKeyboard.setPreviewEnabled(false); + mMiniKeyboardView.setPreviewEnabled(false); mMiniKeyboardPopup.setContentView(container); mMiniKeyboardPopup.setWidth(container.getMeasuredWidth()); mMiniKeyboardPopup.setHeight(container.getMeasuredHeight()); mMiniKeyboardPopup.showAtLocation(this, Gravity.NO_GRAVITY, x, y); // Inject down event on the key to mini keyboard. - long eventTime = SystemClock.uptimeMillis(); + final long eventTime = SystemClock.uptimeMillis(); mMiniKeyboardPopupTime = eventTime; - MotionEvent downEvent = generateMiniKeyboardMotionEvent(MotionEvent.ACTION_DOWN, popupKey.mX - + popupKey.mWidth / 2, popupKey.mY + popupKey.mHeight / 2, eventTime); - mMiniKeyboard.onTouchEvent(downEvent); + final MotionEvent downEvent = generateMiniKeyboardMotionEvent(MotionEvent.ACTION_DOWN, + pointX, popupKey.mY + popupKey.mHeight / 2, eventTime); + mMiniKeyboardView.onTouchEvent(downEvent); downEvent.recycle(); invalidateAllKeys(); return true; } - private static boolean hasMultiplePopupChars(Key key) { - if (key.mPopupCharacters != null && key.mPopupCharacters.length > 1) { - return true; - } - return false; - } - - private static boolean isNumberAtLeftmostPopupChar(Key key) { - if (key.mPopupCharacters != null && isAsciiDigit(key.mPopupCharacters[0].charAt(0))) { - return true; - } - return false; - } - - private static boolean isAsciiDigit(char c) { - return (c < 0x80) && Character.isDigit(c); - } - private MotionEvent generateMiniKeyboardMotionEvent(int action, int x, int y, long eventTime) { return MotionEvent.obtain(mMiniKeyboardPopupTime, eventTime, action, x - mMiniKeyboardOriginX, y - mMiniKeyboardOriginY, 0); @@ -1273,8 +1231,8 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { } public boolean isInSlidingKeyInput() { - if (mMiniKeyboard != null) { - return mMiniKeyboard.isInSlidingKeyInput(); + if (mMiniKeyboardView != null) { + return mMiniKeyboardView.isInSlidingKeyInput(); } else { return mPointerQueue.isInSlidingKeyInput(); } @@ -1302,7 +1260,7 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { mSwipeTracker.addMovement(me); // Gesture detector must be enabled only when mini-keyboard is not on the screen. - if (mMiniKeyboard == null + if (mMiniKeyboardView == null && mGestureDetector != null && mGestureDetector.onTouchEvent(me)) { dismissKeyPreview(); mHandler.cancelKeyTimers(); @@ -1317,14 +1275,14 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { // Needs to be called after the gesture detector gets a turn, as it may have // displayed the mini keyboard - if (mMiniKeyboard != null) { + if (mMiniKeyboardView != null) { final int miniKeyboardPointerIndex = me.findPointerIndex(mMiniKeyboardTrackerId); if (miniKeyboardPointerIndex >= 0 && miniKeyboardPointerIndex < pointerCount) { final int miniKeyboardX = (int)me.getX(miniKeyboardPointerIndex); final int miniKeyboardY = (int)me.getY(miniKeyboardPointerIndex); MotionEvent translated = generateMiniKeyboardMotionEvent(action, miniKeyboardX, miniKeyboardY, eventTime); - mMiniKeyboard.onTouchEvent(translated); + mMiniKeyboardView.onTouchEvent(translated); translated.recycle(); } return true; @@ -1422,7 +1380,7 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { private void dismissPopupKeyboard() { if (mMiniKeyboardPopup.isShowing()) { mMiniKeyboardPopup.dismiss(); - mMiniKeyboard = null; + mMiniKeyboardView = null; mMiniKeyboardOriginX = 0; mMiniKeyboardOriginY = 0; invalidateAllKeys(); |
