From 53b6d627e7fe66ce47ee6ae01254abc070558e77 Mon Sep 17 00:00:00 2001 From: "Tadashi G. Takaoka" Date: Thu, 30 Oct 2014 13:10:59 +0900 Subject: [PATCH] Refactor PointerTracker and MainKeyboardView This CL reorganize the key press/release state visual drawing code. Change-Id: I4aa10f57309ae2f81333a1e2bd863c23a7a41d82 --- .../MainKeyboardAccessibilityDelegate.java | 8 +- .../keyboard/MainKeyboardView.java | 90 ++++++----------- .../inputmethod/keyboard/PointerTracker.java | 98 +++++++++++-------- .../keyboard/internal/DrawingProxy.java | 33 ++++--- .../keyboard/internal/TimerHandler.java | 5 +- 5 files changed, 112 insertions(+), 122 deletions(-) diff --git a/java/src/com/android/inputmethod/accessibility/MainKeyboardAccessibilityDelegate.java b/java/src/com/android/inputmethod/accessibility/MainKeyboardAccessibilityDelegate.java index 94a1ee6eb..e80982fc7 100644 --- a/java/src/com/android/inputmethod/accessibility/MainKeyboardAccessibilityDelegate.java +++ b/java/src/com/android/inputmethod/accessibility/MainKeyboardAccessibilityDelegate.java @@ -269,13 +269,9 @@ public final class MainKeyboardAccessibilityDelegate eventTime, eventTime, MotionEvent.ACTION_DOWN, x, y, 0 /* metaState */); // Inject a fake down event to {@link PointerTracker} to handle a long press correctly. tracker.processMotionEvent(downEvent, mKeyDetector); - // The above fake down event triggers an unnecessary long press timer that should be - // canceled. - tracker.cancelLongPressTimer(); downEvent.recycle(); - // Invoke {@link MainKeyboardView#onLongPress(PointerTracker)} as if a long press timeout - // has passed. - mKeyboardView.onLongPress(tracker); + // Invoke {@link PointerTracker#onLongPressed()} as if a long press timeout has passed. + tracker.onLongPressed(); // If {@link Key#hasNoPanelAutoMoreKeys()} is true (such as "0 +" key on the phone layout) // or a key invokes IME switcher dialog, we should just ignore the next // {@link #onRegisterHoverKey(Key,MotionEvent)}. It can be determined by whether diff --git a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java index 06b87bd9a..ad15fa223 100644 --- a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java @@ -461,12 +461,17 @@ public final class MainKeyboardView extends KeyboardView implements DrawingProxy windowContentView.addView(mDrawingPreviewPlacerView); } + // Implements {@link DrawingProxy#onKeyPressed(Key,boolean)}. @Override - public void showKeyPreview(@Nonnull final Key key) { - // If the key is invalid or has no key preview, we must not show key preview. - if (key.noKeyPreview()) { - return; + public void onKeyPressed(@Nonnull final Key key, final boolean withPreview) { + key.onPressed(); + invalidateKey(key); + if (withPreview && !key.noKeyPreview()) { + showKeyPreview(key); } + } + + private void showKeyPreview(@Nonnull final Key key) { final Keyboard keyboard = getKeyboard(); if (keyboard == null) { return; @@ -483,15 +488,26 @@ public final class MainKeyboardView extends KeyboardView implements DrawingProxy getWidth(), mOriginCoords, mDrawingPreviewPlacerView, isHardwareAccelerated()); } - // Implements {@link DrawingProxy#dismissKeyPreviewWithoutDelay(Key)}. - @Override - public void dismissKeyPreviewWithoutDelay(@Nonnull final Key key) { + private void dismissKeyPreviewWithoutDelay(@Nonnull final Key key) { mKeyPreviewChoreographer.dismissKeyPreview(key, false /* withAnimation */); invalidateKey(key); } + // Implements {@link DrawingProxy#onKeyReleased(Key,boolean)}. @Override - public void dismissKeyPreview(@Nonnull final Key key) { + public void onKeyReleased(@Nonnull final Key key, final boolean withAnimation) { + key.onReleased(); + invalidateKey(key); + if (!key.noKeyPreview()) { + if (withAnimation) { + dismissKeyPreview(key); + } else { + dismissKeyPreviewWithoutDelay(key); + } + } + } + + private void dismissKeyPreview(@Nonnull final Key key) { if (isHardwareAccelerated()) { mKeyPreviewChoreographer.dismissKeyPreview(key, true /* withAnimation */); return; @@ -574,7 +590,11 @@ public final class MainKeyboardView extends KeyboardView implements DrawingProxy mDrawingPreviewPlacerView.removeAllViews(); } - private MoreKeysPanel onCreateMoreKeysPanel(final Key key, final Context context) { + // Implements {@link DrawingProxy@showMoreKeysKeyboard(Key,PointerTracker)}. + @Override + @Nullable + public MoreKeysPanel showMoreKeysKeyboard(@Nonnull final Key key, + @Nonnull final PointerTracker tracker) { final MoreKeySpec[] moreKeys = key.getMoreKeys(); if (moreKeys == null) { return null; @@ -590,7 +610,7 @@ public final class MainKeyboardView extends KeyboardView implements DrawingProxy && !key.noKeyPreview() && moreKeys.length == 1 && mKeyPreviewDrawParams.getVisibleWidth() > 0; final MoreKeysKeyboard.Builder builder = new MoreKeysKeyboard.Builder( - context, key, getKeyboard(), isSingleMoreKeyWithPreview, + getContext(), key, getKeyboard(), isSingleMoreKeyWithPreview, mKeyPreviewDrawParams.getVisibleWidth(), mKeyPreviewDrawParams.getVisibleHeight(), newLabelPaint(key)); moreKeysKeyboard = builder.build(); @@ -603,50 +623,6 @@ public final class MainKeyboardView extends KeyboardView implements DrawingProxy (MoreKeysKeyboardView)container.findViewById(R.id.more_keys_keyboard_view); moreKeysKeyboardView.setKeyboard(moreKeysKeyboard); container.measure(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); - return moreKeysKeyboardView; - } - - // Implements {@link DrawingProxy@onLongPress(PointerTracker)}. - /** - * Called when a key is long pressed. - * @param tracker the pointer tracker which pressed the parent key - */ - @Override - public void onLongPress(@Nonnull final PointerTracker tracker) { - if (isShowingMoreKeysPanel()) { - return; - } - final Key key = tracker.getKey(); - if (key == null) { - return; - } - final KeyboardActionListener listener = mKeyboardActionListener; - if (key.hasNoPanelAutoMoreKey()) { - final int moreKeyCode = key.getMoreKeys()[0].mCode; - tracker.onLongPressed(); - listener.onPressKey(moreKeyCode, 0 /* repeatCount */, true /* isSinglePointer */); - listener.onCodeInput(moreKeyCode, Constants.NOT_A_COORDINATE, - Constants.NOT_A_COORDINATE, false /* isKeyRepeat */); - listener.onReleaseKey(moreKeyCode, false /* withSliding */); - return; - } - final int code = key.getCode(); - if (code == Constants.CODE_SPACE || code == Constants.CODE_LANGUAGE_SWITCH) { - // Long pressing the space key invokes IME switcher dialog. - if (listener.onCustomRequest(Constants.CUSTOM_CODE_SHOW_INPUT_METHOD_PICKER)) { - tracker.onLongPressed(); - listener.onReleaseKey(code, false /* withSliding */); - return; - } - } - openMoreKeysPanel(key, tracker); - } - - private void openMoreKeysPanel(final Key key, final PointerTracker tracker) { - final MoreKeysPanel moreKeysPanel = onCreateMoreKeysPanel(key, getContext()); - if (moreKeysPanel == null) { - return; - } final int[] lastCoords = CoordinateUtils.newInstance(); tracker.getLastCoordinates(lastCoords); @@ -664,10 +640,8 @@ public final class MainKeyboardView extends KeyboardView implements DrawingProxy // {@code mPreviewVisibleOffset} has been set appropriately in // {@link KeyboardView#showKeyPreview(PointerTracker)}. final int pointY = key.getY() + mKeyPreviewDrawParams.getVisibleOffset(); - moreKeysPanel.showMoreKeysPanel(this, this, pointX, pointY, mKeyboardActionListener); - tracker.onShowMoreKeysPanel(moreKeysPanel); - // TODO: Implement zoom in animation of more keys panel. - mKeyPreviewChoreographer.dismissKeyPreview(key, false /* withAnimation */); + moreKeysKeyboardView.showMoreKeysPanel(this, this, pointX, pointY, mKeyboardActionListener); + return moreKeysKeyboardView; } public boolean isInDraggingFinger() { diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java index 7902ce852..7b7dd7b72 100644 --- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java +++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java @@ -222,7 +222,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element, final int trackersSize = sTrackers.size(); for (int i = 0; i < trackersSize; ++i) { final PointerTracker tracker = sTrackers.get(i); - tracker.setReleasedKeyGraphics(tracker.getKey()); + tracker.setReleasedKeyGraphics(tracker.getKey(), true /* withAnimation */); } } @@ -382,19 +382,18 @@ public final class PointerTracker implements PointerTrackerQueue.Element, return mKeyDetector.detectHitKey(x, y); } - private void setReleasedKeyGraphics(@Nullable final Key key) { + private void setReleasedKeyGraphics(@Nullable final Key key, final boolean withAnimation) { if (key == null) { return; } - sDrawingProxy.dismissKeyPreview(key); // Even if the key is disabled, update the key release graphics just in case. - updateReleaseKeyGraphics(key); + sDrawingProxy.onKeyReleased(key, withAnimation); if (key.isShift()) { for (final Key shiftKey : mKeyboard.mShiftKeys) { if (shiftKey != key) { - updateReleaseKeyGraphics(shiftKey); + sDrawingProxy.onKeyReleased(shiftKey, false /* withAnimation */); } } } @@ -403,11 +402,11 @@ public final class PointerTracker implements PointerTrackerQueue.Element, final int altCode = key.getAltCode(); final Key altKey = mKeyboard.getKey(altCode); if (altKey != null) { - updateReleaseKeyGraphics(altKey); + sDrawingProxy.onKeyReleased(altKey, false /* withAnimation */); } for (final Key k : mKeyboard.mAltCodeKeysWhileTyping) { if (k != key && k.getAltCode() == altCode) { - updateReleaseKeyGraphics(k); + sDrawingProxy.onKeyReleased(k, false /* withAnimation */); } } } @@ -418,7 +417,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element, return sTypingTimeRecorder.needsToSuppressKeyPreviewPopup(eventTime); } - private void setPressedKeyGraphics(final Key key, final long eventTime) { + private void setPressedKeyGraphics(@Nullable final Key key, final long eventTime) { if (key == null) { return; } @@ -430,15 +429,13 @@ public final class PointerTracker implements PointerTrackerQueue.Element, return; } - if (!key.noKeyPreview() && !sInGesture && !needsToSuppressKeyPreviewPopup(eventTime)) { - sDrawingProxy.showKeyPreview(key); - } - updatePressKeyGraphics(key); + final boolean noKeyPreview = sInGesture || needsToSuppressKeyPreviewPopup(eventTime); + sDrawingProxy.onKeyPressed(key, !noKeyPreview); if (key.isShift()) { for (final Key shiftKey : mKeyboard.mShiftKeys) { if (shiftKey != key) { - updatePressKeyGraphics(shiftKey); + sDrawingProxy.onKeyPressed(shiftKey, false /* withPreview */); } } } @@ -447,26 +444,16 @@ public final class PointerTracker implements PointerTrackerQueue.Element, final int altCode = key.getAltCode(); final Key altKey = mKeyboard.getKey(altCode); if (altKey != null) { - updatePressKeyGraphics(altKey); + sDrawingProxy.onKeyPressed(altKey, false /* withPreview */); } for (final Key k : mKeyboard.mAltCodeKeysWhileTyping) { if (k != key && k.getAltCode() == altCode) { - updatePressKeyGraphics(k); + sDrawingProxy.onKeyPressed(k, false /* withPreview */); } } } } - private static void updateReleaseKeyGraphics(final Key key) { - key.onReleased(); - sDrawingProxy.invalidateKey(key); - } - - private static void updatePressKeyGraphics(final Key key) { - key.onPressed(); - sDrawingProxy.invalidateKey(key); - } - public GestureStrokeDrawingPoints getGestureStrokeDrawingPoints() { return mGestureStrokeDrawingPoints; } @@ -837,7 +824,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element, } private void processDraggingFingerOutFromOldKey(final Key oldKey) { - setReleasedKeyGraphics(oldKey); + setReleasedKeyGraphics(oldKey, true /* withAnimation */); callListenerOnRelease(oldKey, oldKey.getCode(), true /* withSliding */); startKeySelectionByDraggingFinger(oldKey); sTimerProxy.cancelKeyTimersOf(this); @@ -880,12 +867,12 @@ public final class PointerTracker implements PointerTrackerQueue.Element, } onUpEvent(x, y, eventTime); cancelTrackingForAction(); - setReleasedKeyGraphics(oldKey); + setReleasedKeyGraphics(oldKey, true /* withAnimation */); } else { if (!mIsDetectingGesture) { cancelTrackingForAction(); } - setReleasedKeyGraphics(oldKey); + setReleasedKeyGraphics(oldKey, true /* withAnimation */); } } @@ -913,7 +900,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element, onGestureMoveEvent(x, y, eventTime, true /* isMajorEvent */, newKey); if (sInGesture) { mCurrentKey = null; - setReleasedKeyGraphics(oldKey); + setReleasedKeyGraphics(oldKey, true /* withAnimation */); return; } } @@ -978,7 +965,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element, final int currentRepeatingKeyCode = mCurrentRepeatingKeyCode; mCurrentRepeatingKeyCode = Constants.NOT_A_CODE; // Release the last pressed key. - setReleasedKeyGraphics(currentKey); + setReleasedKeyGraphics(currentKey, true /* withAnimation */); if (isShowingMoreKeysPanel()) { if (!mIsTrackingForActionDisabled) { @@ -1015,14 +1002,6 @@ public final class PointerTracker implements PointerTrackerQueue.Element, } } - public void onShowMoreKeysPanel(final MoreKeysPanel panel) { - setReleasedKeyGraphics(mCurrentKey); - final int translatedX = panel.translateX(mLastX); - final int translatedY = panel.translateY(mLastY); - panel.onDownEvent(translatedX, translatedY, mPointerId, SystemClock.uptimeMillis()); - mMoreKeysPanel = panel; - } - @Override public void cancelTrackingForAction() { if (isShowingMoreKeysPanel()) { @@ -1035,14 +1014,49 @@ public final class PointerTracker implements PointerTrackerQueue.Element, return !mIsTrackingForActionDisabled; } - public void cancelLongPressTimer() { + public void onLongPressed() { sTimerProxy.cancelLongPressTimersOf(this); + if (isShowingMoreKeysPanel()) { + return; + } + final Key key = getKey(); + if (key == null) { + return; + } + if (key.hasNoPanelAutoMoreKey()) { + cancelKeyTracking(); + final int moreKeyCode = key.getMoreKeys()[0].mCode; + sListener.onPressKey(moreKeyCode, 0 /* repeatCont */, true /* isSinglePointer */); + sListener.onCodeInput(moreKeyCode, Constants.NOT_A_COORDINATE, + Constants.NOT_A_COORDINATE, false /* isKeyRepeat */); + sListener.onReleaseKey(moreKeyCode, false /* withSliding */); + return; + } + final int code = key.getCode(); + if (code == Constants.CODE_SPACE || code == Constants.CODE_LANGUAGE_SWITCH) { + // Long pressing the space key invokes IME switcher dialog. + if (sListener.onCustomRequest(Constants.CUSTOM_CODE_SHOW_INPUT_METHOD_PICKER)) { + cancelKeyTracking(); + sListener.onReleaseKey(code, false /* withSliding */); + return; + } + } + + setReleasedKeyGraphics(key, false /* withAnimation */); + final MoreKeysPanel moreKeysPanel = sDrawingProxy.showMoreKeysKeyboard(key, this); + if (moreKeysPanel == null) { + return; + } + final int translatedX = moreKeysPanel.translateX(mLastX); + final int translatedY = moreKeysPanel.translateY(mLastY); + moreKeysPanel.onDownEvent(translatedX, translatedY, mPointerId, SystemClock.uptimeMillis()); + mMoreKeysPanel = moreKeysPanel; } - public void onLongPressed() { + private void cancelKeyTracking() { resetKeySelectionByDraggingFinger(); cancelTrackingForAction(); - setReleasedKeyGraphics(mCurrentKey); + setReleasedKeyGraphics(mCurrentKey, true /* withAnimation */); sPointerTrackerQueue.remove(this); } @@ -1059,7 +1073,7 @@ public final class PointerTracker implements PointerTrackerQueue.Element, private void onCancelEventInternal() { sTimerProxy.cancelKeyTimersOf(this); - setReleasedKeyGraphics(mCurrentKey); + setReleasedKeyGraphics(mCurrentKey, true /* withAnimation */); resetKeySelectionByDraggingFinger(); dismissMoreKeysPanel(); } diff --git a/java/src/com/android/inputmethod/keyboard/internal/DrawingProxy.java b/java/src/com/android/inputmethod/keyboard/internal/DrawingProxy.java index 7fc586a0f..06bdfc41b 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/DrawingProxy.java +++ b/java/src/com/android/inputmethod/keyboard/internal/DrawingProxy.java @@ -17,29 +17,36 @@ package com.android.inputmethod.keyboard.internal; import com.android.inputmethod.keyboard.Key; +import com.android.inputmethod.keyboard.MoreKeysPanel; import com.android.inputmethod.keyboard.PointerTracker; import javax.annotation.Nonnull; import javax.annotation.Nullable; public interface DrawingProxy { - // TODO: Remove this method. - public void invalidateKey(@Nullable Key key); - - // TODO: Rename this method to onKeyPressed. - public void showKeyPreview(@Nonnull Key key); - - // TODO: Rename this method to onKeyReleased. - public void dismissKeyPreview(@Nonnull Key key); + /** + * Called when a key is being pressed. + * @param key the {@link Key} that is being pressed. + * @param withPreview true if key popup preview should be displayed. + */ + public void onKeyPressed(@Nonnull Key key, boolean withPreview); /** - * Dismiss a key preview visual without delay. - * @param key the key whose preview visual should be dismissed. + * Called when a key is being released. + * @param key the {@link Key} that is being released. + * @param withAnimation when true, key popup preview should be dismissed with animation. */ - public void dismissKeyPreviewWithoutDelay(@Nonnull Key key); + public void onKeyReleased(@Nonnull Key key, boolean withAnimation); - // TODO: Rename this method to onKeyLongPressed. - public void onLongPress(@Nonnull PointerTracker tracker); + /** + * Start showing more keys keyboard of a key that is being long pressed. + * @param key the {@link Key} that is being long pressed and showing more keys keyboard. + * @param tracker the {@link PointerTracker} that detects this long pressing. + * @return {@link MoreKeysPanel} that is being shown. null if there is no need to show more keys + * keyboard. + */ + @Nullable + public MoreKeysPanel showMoreKeysKeyboard(@Nonnull Key key, @Nonnull PointerTracker tracker); /** * Start a while-typing-animation. diff --git a/java/src/com/android/inputmethod/keyboard/internal/TimerHandler.java b/java/src/com/android/inputmethod/keyboard/internal/TimerHandler.java index 8068427bc..91f3558eb 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/TimerHandler.java +++ b/java/src/com/android/inputmethod/keyboard/internal/TimerHandler.java @@ -66,7 +66,7 @@ public final class TimerHandler extends LeakGuardHandlerWrapper case MSG_LONGPRESS_SHIFT_KEY: cancelLongPressTimers(); final PointerTracker tracker2 = (PointerTracker) msg.obj; - drawingProxy.onLongPress(tracker2); + tracker2.onLongPressed(); break; case MSG_UPDATE_BATCH_INPUT: final PointerTracker tracker3 = (PointerTracker) msg.obj; @@ -74,8 +74,7 @@ public final class TimerHandler extends LeakGuardHandlerWrapper startUpdateBatchInputTimer(tracker3); break; case MSG_DISMISS_KEY_PREVIEW: - final Key key = (Key) msg.obj; - drawingProxy.dismissKeyPreviewWithoutDelay(key); + drawingProxy.onKeyReleased((Key) msg.obj, false /* withAnimation */); break; case MSG_DISMISS_GESTURE_FLOATING_PREVIEW_TEXT: drawingProxy.dismissGestureFloatingPreviewTextWithoutDelay();