diff options
author | 2011-04-13 03:12:06 -0700 | |
---|---|---|
committer | 2011-04-13 03:12:06 -0700 | |
commit | dc3d4e8c06c099c3170a9503cf3a73c7f5569ed6 (patch) | |
tree | 6464a849e284cce6f1cc98797726987d9783f6e4 /java/src | |
parent | a6abb1f87c0061d7a409066586ba99d8fdbd86e2 (diff) | |
parent | 7a3d3ae17f7a8ca0b44e9c92328a7de7cbc80f92 (diff) | |
download | latinime-dc3d4e8c06c099c3170a9503cf3a73c7f5569ed6.tar.gz latinime-dc3d4e8c06c099c3170a9503cf3a73c7f5569ed6.tar.xz latinime-dc3d4e8c06c099c3170a9503cf3a73c7f5569ed6.zip |
Merge "Fast key preview"
Diffstat (limited to 'java/src')
5 files changed, 60 insertions, 117 deletions
diff --git a/java/src/com/android/inputmethod/compat/InputMethodServiceCompatWrapper.java b/java/src/com/android/inputmethod/compat/InputMethodServiceCompatWrapper.java index e02aac704..1ea7236f9 100644 --- a/java/src/com/android/inputmethod/compat/InputMethodServiceCompatWrapper.java +++ b/java/src/com/android/inputmethod/compat/InputMethodServiceCompatWrapper.java @@ -19,20 +19,9 @@ package com.android.inputmethod.compat; import com.android.inputmethod.latin.SubtypeSwitcher; import android.inputmethodservice.InputMethodService; -import android.view.View; import android.view.inputmethod.InputMethodSubtype; -import android.widget.HorizontalScrollView; - -import java.lang.reflect.Field; -import java.lang.reflect.Method; public class InputMethodServiceCompatWrapper extends InputMethodService { - private static final Method METHOD_HorizontalScrollView_setOverScrollMode = - CompatUtils.getMethod(HorizontalScrollView.class, "setOverScrollMode", int.class); - private static final Field FIELD_View_OVER_SCROLL_NEVER = - CompatUtils.getField(View.class, "OVER_SCROLL_NEVER"); - private static final Integer View_OVER_SCROLL_NEVER = - (Integer)CompatUtils.getFieldValue(null, null, FIELD_View_OVER_SCROLL_NEVER); // CAN_HANDLE_ON_CURRENT_INPUT_METHOD_SUBTYPE_CHANGED needs to be false if the API level is 10 // or previous. Note that InputMethodSubtype was added in the API level 11. // For the API level 11 or later, LatinIME should override onCurrentInputMethodSubtypeChanged(). @@ -66,13 +55,6 @@ public class InputMethodServiceCompatWrapper extends InputMethodService { } } - protected static void setOverScrollModeNever(HorizontalScrollView scrollView) { - if (View_OVER_SCROLL_NEVER != null) { - CompatUtils.invoke(scrollView, null, METHOD_HorizontalScrollView_setOverScrollMode, - View_OVER_SCROLL_NEVER); - } - } - ////////////////////////////////////// // Functions using API v11 or later // ////////////////////////////////////// diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java index 7b570d7ed..71863803b 100644 --- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java +++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java @@ -45,8 +45,8 @@ import android.view.Gravity; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; -import android.view.ViewGroup.LayoutParams; -import android.view.WindowManager; +import android.view.ViewGroup; +import android.widget.FrameLayout; import android.widget.PopupWindow; import android.widget.TextView; @@ -110,14 +110,12 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { // Key preview popup private boolean mInForeground; private TextView mPreviewText; - private PopupWindow mPreviewPopup; private int mPreviewTextSizeLarge; - private int[] mOffsetInWindow; + private final int[] mOffsetInWindow = new int[2]; private int mOldPreviewKeyIndex = KeyDetector.NOT_A_KEY; private boolean mShowPreview = true; private int mPopupPreviewOffsetX; private int mPopupPreviewOffsetY; - private int mWindowY; private int mPopupPreviewDisplayedY; private final int mDelayBeforePreview; private final int mDelayAfterPreview; @@ -125,7 +123,6 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { // Popup mini keyboard private PopupWindow mMiniKeyboardPopup; private KeyboardView mMiniKeyboardView; - private View mMiniKeyboardParent; private final WeakHashMap<Key, View> mMiniKeyboardCache = new WeakHashMap<Key, View>(); private int mMiniKeyboardOriginX; private int mMiniKeyboardOriginY; @@ -204,7 +201,7 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { showKey(msg.arg1, (PointerTracker)msg.obj); break; case MSG_DISMISS_PREVIEW: - mPreviewPopup.dismiss(); + mPreviewText.setVisibility(View.INVISIBLE); break; case MSG_REPEAT_KEY: { final PointerTracker tracker = (PointerTracker)msg.obj; @@ -227,12 +224,11 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { public void popupPreview(long delay, int keyIndex, PointerTracker tracker) { removeMessages(MSG_POPUP_PREVIEW); - if (mPreviewPopup.isShowing() && mPreviewText.getVisibility() == VISIBLE) { + if (mPreviewText.getVisibility() == VISIBLE) { // Show right away, if it's already visible and finger is moving around showKey(keyIndex, tracker); } else { - sendMessageDelayed(obtainMessage(MSG_POPUP_PREVIEW, keyIndex, 0, tracker), - delay); + sendMessageDelayed(obtainMessage(MSG_POPUP_PREVIEW, keyIndex, 0, tracker), delay); } } @@ -241,9 +237,7 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { } public void dismissPreview(long delay) { - if (mPreviewPopup.isShowing()) { - sendMessageDelayed(obtainMessage(MSG_DISMISS_PREVIEW), delay); - } + sendMessageDelayed(obtainMessage(MSG_DISMISS_PREVIEW), delay); } public void cancelDismissPreview() { @@ -366,24 +360,17 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { final Resources res = getResources(); - mPreviewPopup = new PopupWindow(context); if (previewLayout != 0) { mPreviewText = (TextView) LayoutInflater.from(context).inflate(previewLayout, null); mPreviewTextSizeLarge = (int) res.getDimension(R.dimen.key_preview_text_size_large); - mPreviewPopup.setContentView(mPreviewText); - mPreviewPopup.setBackgroundDrawable(null); } else { mShowPreview = false; } - mPreviewPopup.setTouchable(false); - mPreviewPopup.setAnimationStyle(R.style.KeyPreviewAnimation); - mPreviewPopup.setClippingEnabled(false); mDelayBeforePreview = res.getInteger(R.integer.config_delay_before_preview); mDelayAfterPreview = res.getInteger(R.integer.config_delay_after_preview); mKeyLabelHorizontalPadding = (int)res.getDimension( R.dimen.key_label_horizontal_alignment_padding); - mMiniKeyboardParent = this; mMiniKeyboardPopup = new PopupWindow(context); mMiniKeyboardPopup.setBackgroundDrawable(null); mMiniKeyboardPopup.setAnimationStyle(R.style.MiniKeyboardAnimation); @@ -583,7 +570,6 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { public void setPopupOffset(int x, int y) { mPopupPreviewOffsetX = x; mPopupPreviewOffsetY = y; - mPreviewPopup.dismiss(); } /** @@ -915,8 +901,16 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { } } - // TODO Must fix popup preview on xlarge layout + // TODO: Introduce minimum duration for displaying key previews + // TODO: Display up to two key previews when the user presses two keys at the same time private void showKey(final int keyIndex, PointerTracker tracker) { + // If the preview popup has no parent view yet, add it to the screen FrameLayout. + if (mPreviewText.getParent() == null) { + final FrameLayout screenContent = (FrameLayout) getRootView() + .findViewById(android.R.id.content); + screenContent.addView(mPreviewText, new FrameLayout.LayoutParams(0, 0)); + } + Key key = tracker.getKey(keyIndex); // If keyIndex is invalid or IME is already closed, we must not show key preview. // Trying to show preview PopupWindow while root window is closed causes @@ -948,7 +942,7 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { int popupWidth = Math.max(mPreviewText.getMeasuredWidth(), keyDrawWidth + mPreviewText.getPaddingLeft() + mPreviewText.getPaddingRight()); final int popupHeight = mPreviewHeight; - LayoutParams lp = mPreviewText.getLayoutParams(); + final ViewGroup.LayoutParams lp = mPreviewText.getLayoutParams(); if (lp != null) { lp.width = popupWidth; lp.height = popupHeight; @@ -958,47 +952,23 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { int popupPreviewY = key.mY - popupHeight + mPreviewOffset; mHandler.cancelDismissPreview(); - if (mOffsetInWindow == null) { - mOffsetInWindow = new int[2]; - getLocationInWindow(mOffsetInWindow); - mOffsetInWindow[0] += mPopupPreviewOffsetX; // Offset may be zero - mOffsetInWindow[1] += mPopupPreviewOffsetY; // Offset may be zero - int[] windowLocation = new int[2]; - getLocationOnScreen(windowLocation); - mWindowY = windowLocation[1]; - } + getLocationInWindow(mOffsetInWindow); + mOffsetInWindow[0] += mPopupPreviewOffsetX; // Offset may be zero + mOffsetInWindow[1] += mPopupPreviewOffsetY; // Offset may be zero + // Set the preview background state mPreviewText.getBackground().setState( key.mPopupCharacters != null ? LONG_PRESSABLE_STATE_SET : EMPTY_STATE_SET); popupPreviewX += mOffsetInWindow[0]; popupPreviewY += mOffsetInWindow[1]; - // If the popup cannot be shown above the key, put it on the side - if (popupPreviewY + mWindowY < 0) { - // If the key you're pressing is on the left side of the keyboard, show the popup on - // the right, offset by enough to see at least one key to the left/right. - if (keyDrawX + keyDrawWidth <= getWidth() / 2) { - popupPreviewX += (int) (keyDrawWidth * 2.5); - } else { - popupPreviewX -= (int) (keyDrawWidth * 2.5); - } - popupPreviewY += popupHeight; - } - - try { - if (mPreviewPopup.isShowing()) { - mPreviewPopup.update(popupPreviewX, popupPreviewY, popupWidth, popupHeight); - } else { - mPreviewPopup.setWidth(popupWidth); - mPreviewPopup.setHeight(popupHeight); - mPreviewPopup.showAtLocation(mMiniKeyboardParent, Gravity.NO_GRAVITY, - popupPreviewX, popupPreviewY); - } - } catch (WindowManager.BadTokenException e) { - // Swallow the exception which will be happened when IME is already closed. - Log.w(TAG, "LatinIME is already closed when tried showing key preview."); + // Place the key preview. + // TODO: Adjust position of key previews which touch screen edges + if (lp instanceof ViewGroup.MarginLayoutParams) { + ViewGroup.MarginLayoutParams mlp = (ViewGroup.MarginLayoutParams)lp; + mlp.setMargins(popupPreviewX, popupPreviewY, 0, 0); } - // Record popup preview position to display mini-keyboard later at the same positon + // Record popup preview position to display mini-keyboard later at the same position mPopupPreviewDisplayedY = popupPreviewY; mPreviewText.setVisibility(VISIBLE); } @@ -1114,7 +1084,6 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { 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)); @@ -1349,7 +1318,7 @@ public class KeyboardView extends View implements PointerTracker.UIProxy { } public void closing() { - mPreviewPopup.dismiss(); + mPreviewText.setVisibility(View.GONE); mHandler.cancelAllMessages(); dismissPopupKeyboard(); diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java index eb5335ffd..add38cf45 100644 --- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java +++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java @@ -549,7 +549,6 @@ public class PointerTracker { final Key key = getKey(keyIndex); if (key != null && !key.mEnabled) return; - updateKeyGraphics(keyIndex); // The modifier key, such as shift key, should not be shown as preview when multi-touch is // supported. On the other hand, if multi-touch is not supported, the modifier key should // be shown as preview. If accessibility is turned on, the modifier key should be shown as @@ -559,6 +558,7 @@ public class PointerTracker { } else { mProxy.showPreview(keyIndex, this); } + updateKeyGraphics(keyIndex); } private void startLongPressTimer(int keyIndex) { diff --git a/java/src/com/android/inputmethod/latin/CandidateView.java b/java/src/com/android/inputmethod/latin/CandidateView.java index 5719b9012..6fb80adf0 100644 --- a/java/src/com/android/inputmethod/latin/CandidateView.java +++ b/java/src/com/android/inputmethod/latin/CandidateView.java @@ -133,7 +133,6 @@ public class CandidateView extends LinearLayout implements OnClickListener, OnLo ViewGroup.LayoutParams.WRAP_CONTENT); mPreviewPopup.setContentView(mPreviewText); mPreviewPopup.setBackgroundDrawable(null); - mPreviewPopup.setAnimationStyle(R.style.KeyPreviewAnimation); mConfigCandidateHighlightFontColorEnabled = res.getBoolean(R.bool.config_candidate_highlight_font_color_enabled); mColorNormal = res.getColor(R.color.candidate_normal); diff --git a/java/src/com/android/inputmethod/latin/LatinIME.java b/java/src/com/android/inputmethod/latin/LatinIME.java index 3905a4c7a..d87de09c6 100644 --- a/java/src/com/android/inputmethod/latin/LatinIME.java +++ b/java/src/com/android/inputmethod/latin/LatinIME.java @@ -57,7 +57,6 @@ import android.util.DisplayMetrics; import android.util.Log; import android.util.PrintWriterPrinter; import android.util.Printer; -import android.view.Gravity; import android.view.HapticFeedbackConstants; import android.view.KeyEvent; import android.view.LayoutInflater; @@ -71,8 +70,6 @@ import android.view.inputmethod.EditorInfo; import android.view.inputmethod.ExtractedText; import android.view.inputmethod.ExtractedTextRequest; import android.view.inputmethod.InputConnection; -import android.widget.FrameLayout; -import android.widget.HorizontalScrollView; import android.widget.LinearLayout; import java.io.FileDescriptor; @@ -144,6 +141,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar }; private View mCandidateViewContainer; + private int mCandidateStripHeight; private CandidateView mCandidateView; private Suggest mSuggest; private CompletionInfo[] mApplicationSpecifiedCompletions; @@ -533,12 +531,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar LayoutInflater inflater = getLayoutInflater(); LinearLayout container = (LinearLayout)inflater.inflate(R.layout.candidates, null); mCandidateViewContainer = container; - if (container.getPaddingRight() != 0) { - HorizontalScrollView scrollView = - (HorizontalScrollView) container.findViewById(R.id.candidates_scroll_view); - setOverScrollModeNever(scrollView); - container.setGravity(Gravity.CENTER_HORIZONTAL); - } + mCandidateStripHeight = (int)mResources.getDimension(R.dimen.candidate_strip_height); mCandidateView = (CandidateView) container.findViewById(R.id.candidates); mCandidateView.setService(this); setCandidatesViewShown(true); @@ -586,8 +579,7 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar switcher.updateShiftState(); } - setCandidatesViewShownInternal(isCandidateStripVisible(), - false /* needsInputViewShown */ ); + setCandidatesViewShownInternal(isCandidateStripVisible(), false /* needsInputViewShown */ ); // Delay updating suggestions because keyboard input view may not be shown at this point. mHandler.postUpdateSuggestions(); @@ -877,10 +869,21 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar } private void setCandidatesViewShownInternal(boolean shown, boolean needsInputViewShown) { - // TODO: Remove this if we support candidates with hard keyboard + // TODO: Modify this if we support candidates with hard keyboard if (onEvaluateInputViewShown()) { - super.setCandidatesViewShown(shown - && (needsInputViewShown ? mKeyboardSwitcher.isInputViewShown() : true)); + final boolean shouldShowCandidates = shown + && (needsInputViewShown ? mKeyboardSwitcher.isInputViewShown() : true); + if (isExtractViewShown()) { + // No need to have extra space to show the key preview. + mCandidateViewContainer.setMinimumHeight(0); + super.setCandidatesViewShown(shown); + } else { + // We must control the visibility of the suggestion strip in order to avoid clipped + // key previews, even when we don't show the suggestion strip. + mCandidateViewContainer.setVisibility( + shouldShowCandidates ? View.VISIBLE : View.INVISIBLE); + super.setCandidatesViewShown(true); + } } } @@ -892,35 +895,25 @@ public class LatinIME extends InputMethodServiceCompatWrapper implements Keyboar @Override public void onComputeInsets(InputMethodService.Insets outInsets) { super.onComputeInsets(outInsets); - if (!isFullscreenMode()) { - outInsets.contentTopInsets = outInsets.visibleTopInsets; - } - KeyboardView inputView = mKeyboardSwitcher.getInputView(); + final KeyboardView inputView = mKeyboardSwitcher.getInputView(); // Need to set touchable region only if input view is being shown if (inputView != null && mKeyboardSwitcher.isInputViewShown()) { - final int x = 0; - int y = 0; - final int width = inputView.getWidth(); - int height = inputView.getHeight() + EXTENDED_TOUCHABLE_REGION_HEIGHT; - if (mCandidateViewContainer != null) { - ViewParent candidateParent = mCandidateViewContainer.getParent(); - if (candidateParent instanceof FrameLayout) { - FrameLayout fl = (FrameLayout) candidateParent; - if (fl != null) { - // Check frame layout's visibility - if (fl.getVisibility() == View.INVISIBLE) { - y = fl.getHeight(); - height += y; - } else if (fl.getVisibility() == View.VISIBLE) { - height += fl.getHeight(); - } - } - } + final int containerHeight = mCandidateViewContainer.getHeight(); + int touchY = containerHeight; + if (mCandidateViewContainer.getVisibility() == View.VISIBLE) { + touchY -= mCandidateStripHeight; } + outInsets.contentTopInsets = touchY; + outInsets.visibleTopInsets = touchY; + final int touchWidth = inputView.getWidth(); + final int touchHeight = inputView.getHeight() + containerHeight + // Extend touchable region below the keyboard. + + EXTENDED_TOUCHABLE_REGION_HEIGHT; if (DEBUG) { - Log.d(TAG, "Touchable region " + x + ", " + y + ", " + width + ", " + height); + Log.d(TAG, "Touchable region: y=" + touchY + " width=" + touchWidth + + " height=" + touchHeight); } - setTouchableRegionCompat(outInsets, x, y, width, height); + setTouchableRegionCompat(outInsets, 0, touchY, touchWidth, touchHeight); } } |