diff options
| author | Tadashi G. Takaoka <takaoka@google.com> | 2012-07-23 10:27:14 +0900 |
|---|---|---|
| committer | Tadashi G. Takaoka <takaoka@google.com> | 2012-07-23 12:11:43 +0900 |
| commit | c8e45ddb032554f4e9d4411d8ef47d98db62d77b (patch) | |
| tree | be6274a3d7bfcbb8e3a83558a4fa1619c338bebc /java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java | |
| parent | a4f762ff98a5024cf265b6f45880eed29b10dcbd (diff) | |
Rename LatinKeyboardView to MainKeyboardView
Change-Id: I8f3123b8d727c7beb72e226f80c17794f89c8b60
Diffstat (limited to 'java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java')
| -rw-r--r-- | java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java | 1036 |
1 files changed, 0 insertions, 1036 deletions
diff --git a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java b/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java deleted file mode 100644 index 0a7e7a2e3..000000000 --- a/java/src/com/android/inputmethod/keyboard/LatinKeyboardView.java +++ /dev/null @@ -1,1036 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * 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.keyboard; - -import android.animation.AnimatorInflater; -import android.animation.ObjectAnimator; -import android.content.Context; -import android.content.pm.PackageManager; -import android.content.res.Resources; -import android.content.res.TypedArray; -import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.Paint.Align; -import android.graphics.Typeface; -import android.graphics.drawable.Drawable; -import android.os.Message; -import android.text.TextUtils; -import android.util.AttributeSet; -import android.util.Log; -import android.view.LayoutInflater; -import android.view.MotionEvent; -import android.view.View; -import android.view.ViewConfiguration; -import android.view.ViewGroup; -import android.view.inputmethod.InputMethodSubtype; -import android.widget.PopupWindow; - -import com.android.inputmethod.accessibility.AccessibilityUtils; -import com.android.inputmethod.accessibility.AccessibleKeyboardViewProxy; -import com.android.inputmethod.keyboard.PointerTracker.DrawingProxy; -import com.android.inputmethod.keyboard.PointerTracker.TimerProxy; -import com.android.inputmethod.latin.Constants; -import com.android.inputmethod.latin.LatinIME; -import com.android.inputmethod.latin.LatinImeLogger; -import com.android.inputmethod.latin.R; -import com.android.inputmethod.latin.StaticInnerHandlerWrapper; -import com.android.inputmethod.latin.StringUtils; -import com.android.inputmethod.latin.SubtypeLocale; -import com.android.inputmethod.latin.Utils; -import com.android.inputmethod.latin.Utils.UsabilityStudyLogUtils; -import com.android.inputmethod.latin.define.ProductionFlag; -import com.android.inputmethod.research.ResearchLogger; - -import java.util.Locale; -import java.util.WeakHashMap; - -/** - * A view that is responsible for detecting key presses and touch movements. - * - * @attr ref R.styleable#KeyboardView_keyHysteresisDistance - * @attr ref R.styleable#KeyboardView_verticalCorrection - * @attr ref R.styleable#KeyboardView_popupLayout - */ -public class LatinKeyboardView extends KeyboardView implements PointerTracker.KeyEventHandler, - SuddenJumpingTouchEventHandler.ProcessMotionEvent { - private static final String TAG = LatinKeyboardView.class.getSimpleName(); - - // TODO: Kill process when the usability study mode was changed. - private static final boolean ENABLE_USABILITY_STUDY_LOG = LatinImeLogger.sUsabilityStudy; - - /** Listener for {@link KeyboardActionListener}. */ - private KeyboardActionListener mKeyboardActionListener; - - /* Space key and its icons */ - private Key mSpaceKey; - private Drawable mSpaceIcon; - // Stuff to draw language name on spacebar. - private final int mLanguageOnSpacebarFinalAlpha; - private ObjectAnimator mLanguageOnSpacebarFadeoutAnimator; - private boolean mNeedsToDisplayLanguage; - private boolean mHasMultipleEnabledIMEsOrSubtypes; - private int mLanguageOnSpacebarAnimAlpha = Constants.Color.ALPHA_OPAQUE; - private final float mSpacebarTextRatio; - private float mSpacebarTextSize; - private final int mSpacebarTextColor; - private final int mSpacebarTextShadowColor; - // The minimum x-scale to fit the language name on spacebar. - private static final float MINIMUM_XSCALE_OF_LANGUAGE_NAME = 0.8f; - // Stuff to draw auto correction LED on spacebar. - private boolean mAutoCorrectionSpacebarLedOn; - private final boolean mAutoCorrectionSpacebarLedEnabled; - private final Drawable mAutoCorrectionSpacebarLedIcon; - private static final int SPACE_LED_LENGTH_PERCENT = 80; - - // Stuff to draw altCodeWhileTyping keys. - private ObjectAnimator mAltCodeKeyWhileTypingFadeoutAnimator; - private ObjectAnimator mAltCodeKeyWhileTypingFadeinAnimator; - private int mAltCodeKeyWhileTypingAnimAlpha = Constants.Color.ALPHA_OPAQUE; - - // More keys keyboard - private PopupWindow mMoreKeysWindow; - private MoreKeysPanel mMoreKeysPanel; - private int mMoreKeysPanelPointerTrackerId; - private final WeakHashMap<Key, MoreKeysPanel> mMoreKeysPanelCache = - new WeakHashMap<Key, MoreKeysPanel>(); - private final boolean mConfigShowMoreKeysKeyboardAtTouchedPoint; - - private final PointerTrackerParams mPointerTrackerParams; - private final SuddenJumpingTouchEventHandler mTouchScreenRegulator; - - protected KeyDetector mKeyDetector; - private boolean mHasDistinctMultitouch; - private int mOldPointerCount = 1; - private Key mOldKey; - - private final KeyTimerHandler mKeyTimerHandler; - - private static class KeyTimerHandler extends StaticInnerHandlerWrapper<LatinKeyboardView> - implements TimerProxy { - private static final int MSG_REPEAT_KEY = 1; - private static final int MSG_LONGPRESS_KEY = 2; - private static final int MSG_DOUBLE_TAP = 3; - private static final int MSG_TYPING_STATE_EXPIRED = 4; - - private final KeyTimerParams mParams; - - public KeyTimerHandler(LatinKeyboardView outerInstance, KeyTimerParams params) { - super(outerInstance); - mParams = params; - } - - @Override - public void handleMessage(Message msg) { - final LatinKeyboardView keyboardView = getOuterInstance(); - final PointerTracker tracker = (PointerTracker) msg.obj; - switch (msg.what) { - case MSG_REPEAT_KEY: - final Key currentKey = tracker.getKey(); - if (currentKey != null && currentKey.mCode == msg.arg1) { - tracker.onRegisterKey(currentKey); - startKeyRepeatTimer(tracker, mParams.mKeyRepeatInterval); - } - break; - case MSG_LONGPRESS_KEY: - if (tracker != null) { - keyboardView.openMoreKeysKeyboardIfRequired(tracker.getKey(), tracker); - } else { - KeyboardSwitcher.getInstance().onLongPressTimeout(msg.arg1); - } - break; - case MSG_TYPING_STATE_EXPIRED: - cancelAndStartAnimators(keyboardView.mAltCodeKeyWhileTypingFadeoutAnimator, - keyboardView.mAltCodeKeyWhileTypingFadeinAnimator); - break; - } - } - - private void startKeyRepeatTimer(PointerTracker tracker, long delay) { - final Key key = tracker.getKey(); - if (key == null) return; - sendMessageDelayed(obtainMessage(MSG_REPEAT_KEY, key.mCode, 0, tracker), delay); - } - - @Override - public void startKeyRepeatTimer(PointerTracker tracker) { - startKeyRepeatTimer(tracker, mParams.mKeyRepeatStartTimeout); - } - - public void cancelKeyRepeatTimer() { - removeMessages(MSG_REPEAT_KEY); - } - - // TODO: Suppress layout changes in key repeat mode - public boolean isInKeyRepeat() { - return hasMessages(MSG_REPEAT_KEY); - } - - @Override - public void startLongPressTimer(int code) { - cancelLongPressTimer(); - final int delay; - switch (code) { - case Keyboard.CODE_SHIFT: - delay = mParams.mLongPressShiftKeyTimeout; - break; - default: - delay = 0; - break; - } - if (delay > 0) { - sendMessageDelayed(obtainMessage(MSG_LONGPRESS_KEY, code, 0), delay); - } - } - - @Override - public void startLongPressTimer(PointerTracker tracker) { - cancelLongPressTimer(); - if (tracker == null) { - return; - } - final Key key = tracker.getKey(); - final int delay; - switch (key.mCode) { - case Keyboard.CODE_SHIFT: - delay = mParams.mLongPressShiftKeyTimeout; - break; - default: - if (KeyboardSwitcher.getInstance().isInMomentarySwitchState()) { - // We use longer timeout for sliding finger input started from the symbols - // mode key. - delay = mParams.mLongPressKeyTimeout * 3; - } else { - delay = mParams.mLongPressKeyTimeout; - } - break; - } - if (delay > 0) { - sendMessageDelayed(obtainMessage(MSG_LONGPRESS_KEY, tracker), delay); - } - } - - @Override - public void cancelLongPressTimer() { - removeMessages(MSG_LONGPRESS_KEY); - } - - public static void cancelAndStartAnimators(final ObjectAnimator animatorToCancel, - final ObjectAnimator animatorToStart) { - float startFraction = 0.0f; - if (animatorToCancel.isStarted()) { - animatorToCancel.cancel(); - startFraction = 1.0f - animatorToCancel.getAnimatedFraction(); - } - final long startTime = (long)(animatorToStart.getDuration() * startFraction); - animatorToStart.start(); - animatorToStart.setCurrentPlayTime(startTime); - } - - @Override - public void startTypingStateTimer() { - final boolean isTyping = isTypingState(); - removeMessages(MSG_TYPING_STATE_EXPIRED); - sendMessageDelayed( - obtainMessage(MSG_TYPING_STATE_EXPIRED), mParams.mIgnoreAltCodeKeyTimeout); - if (isTyping) { - return; - } - final LatinKeyboardView keyboardView = getOuterInstance(); - cancelAndStartAnimators(keyboardView.mAltCodeKeyWhileTypingFadeinAnimator, - keyboardView.mAltCodeKeyWhileTypingFadeoutAnimator); - } - - @Override - public boolean isTypingState() { - return hasMessages(MSG_TYPING_STATE_EXPIRED); - } - - @Override - public void startDoubleTapTimer() { - sendMessageDelayed(obtainMessage(MSG_DOUBLE_TAP), - ViewConfiguration.getDoubleTapTimeout()); - } - - @Override - public void cancelDoubleTapTimer() { - removeMessages(MSG_DOUBLE_TAP); - } - - @Override - public boolean isInDoubleTapTimeout() { - return hasMessages(MSG_DOUBLE_TAP); - } - - @Override - public void cancelKeyTimers() { - cancelKeyRepeatTimer(); - cancelLongPressTimer(); - } - - public void cancelAllMessages() { - cancelKeyTimers(); - } - } - - public static class PointerTrackerParams { - public final boolean mSlidingKeyInputEnabled; - public final int mTouchNoiseThresholdTime; - public final float mTouchNoiseThresholdDistance; - - public static final PointerTrackerParams DEFAULT = new PointerTrackerParams(); - - private PointerTrackerParams() { - mSlidingKeyInputEnabled = false; - mTouchNoiseThresholdTime =0; - mTouchNoiseThresholdDistance = 0; - } - - public PointerTrackerParams(TypedArray latinKeyboardViewAttr) { - mSlidingKeyInputEnabled = latinKeyboardViewAttr.getBoolean( - R.styleable.LatinKeyboardView_slidingKeyInputEnable, false); - mTouchNoiseThresholdTime = latinKeyboardViewAttr.getInt( - R.styleable.LatinKeyboardView_touchNoiseThresholdTime, 0); - mTouchNoiseThresholdDistance = latinKeyboardViewAttr.getDimension( - R.styleable.LatinKeyboardView_touchNoiseThresholdDistance, 0); - } - } - - static class KeyTimerParams { - public final int mKeyRepeatStartTimeout; - public final int mKeyRepeatInterval; - public final int mLongPressKeyTimeout; - public final int mLongPressShiftKeyTimeout; - public final int mIgnoreAltCodeKeyTimeout; - - public KeyTimerParams(TypedArray latinKeyboardViewAttr) { - mKeyRepeatStartTimeout = latinKeyboardViewAttr.getInt( - R.styleable.LatinKeyboardView_keyRepeatStartTimeout, 0); - mKeyRepeatInterval = latinKeyboardViewAttr.getInt( - R.styleable.LatinKeyboardView_keyRepeatInterval, 0); - mLongPressKeyTimeout = latinKeyboardViewAttr.getInt( - R.styleable.LatinKeyboardView_longPressKeyTimeout, 0); - mLongPressShiftKeyTimeout = latinKeyboardViewAttr.getInt( - R.styleable.LatinKeyboardView_longPressShiftKeyTimeout, 0); - mIgnoreAltCodeKeyTimeout = latinKeyboardViewAttr.getInt( - R.styleable.LatinKeyboardView_ignoreAltCodeKeyTimeout, 0); - } - } - - public LatinKeyboardView(Context context, AttributeSet attrs) { - this(context, attrs, R.attr.latinKeyboardViewStyle); - } - - public LatinKeyboardView(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - - mTouchScreenRegulator = new SuddenJumpingTouchEventHandler(getContext(), this); - - mHasDistinctMultitouch = context.getPackageManager() - .hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN_MULTITOUCH_DISTINCT); - final Resources res = getResources(); - final boolean needsPhantomSuddenMoveEventHack = Boolean.parseBoolean( - Utils.getDeviceOverrideValue(res, - R.array.phantom_sudden_move_event_device_list, "false")); - PointerTracker.init(mHasDistinctMultitouch, needsPhantomSuddenMoveEventHack); - - final TypedArray a = context.obtainStyledAttributes( - attrs, R.styleable.LatinKeyboardView, defStyle, R.style.LatinKeyboardView); - mAutoCorrectionSpacebarLedEnabled = a.getBoolean( - R.styleable.LatinKeyboardView_autoCorrectionSpacebarLedEnabled, false); - mAutoCorrectionSpacebarLedIcon = a.getDrawable( - R.styleable.LatinKeyboardView_autoCorrectionSpacebarLedIcon); - mSpacebarTextRatio = a.getFraction(R.styleable.LatinKeyboardView_spacebarTextRatio, - 1000, 1000, 1) / 1000.0f; - mSpacebarTextColor = a.getColor(R.styleable.LatinKeyboardView_spacebarTextColor, 0); - mSpacebarTextShadowColor = a.getColor( - R.styleable.LatinKeyboardView_spacebarTextShadowColor, 0); - mLanguageOnSpacebarFinalAlpha = a.getInt( - R.styleable.LatinKeyboardView_languageOnSpacebarFinalAlpha, - Constants.Color.ALPHA_OPAQUE); - final int languageOnSpacebarFadeoutAnimatorResId = a.getResourceId( - R.styleable.LatinKeyboardView_languageOnSpacebarFadeoutAnimator, 0); - final int altCodeKeyWhileTypingFadeoutAnimatorResId = a.getResourceId( - R.styleable.LatinKeyboardView_altCodeKeyWhileTypingFadeoutAnimator, 0); - final int altCodeKeyWhileTypingFadeinAnimatorResId = a.getResourceId( - R.styleable.LatinKeyboardView_altCodeKeyWhileTypingFadeinAnimator, 0); - - final KeyTimerParams keyTimerParams = new KeyTimerParams(a); - mPointerTrackerParams = new PointerTrackerParams(a); - - final float keyHysteresisDistance = a.getDimension( - R.styleable.LatinKeyboardView_keyHysteresisDistance, 0); - mKeyDetector = new KeyDetector(keyHysteresisDistance); - mKeyTimerHandler = new KeyTimerHandler(this, keyTimerParams); - mConfigShowMoreKeysKeyboardAtTouchedPoint = a.getBoolean( - R.styleable.LatinKeyboardView_showMoreKeysKeyboardAtTouchedPoint, false); - a.recycle(); - - PointerTracker.setParameters(mPointerTrackerParams); - - mLanguageOnSpacebarFadeoutAnimator = loadObjectAnimator( - languageOnSpacebarFadeoutAnimatorResId, this); - mAltCodeKeyWhileTypingFadeoutAnimator = loadObjectAnimator( - altCodeKeyWhileTypingFadeoutAnimatorResId, this); - mAltCodeKeyWhileTypingFadeinAnimator = loadObjectAnimator( - altCodeKeyWhileTypingFadeinAnimatorResId, this); - } - - private ObjectAnimator loadObjectAnimator(int resId, Object target) { - if (resId == 0) return null; - final ObjectAnimator animator = (ObjectAnimator)AnimatorInflater.loadAnimator( - getContext(), resId); - if (animator != null) { - animator.setTarget(target); - } - return animator; - } - - // Getter/setter methods for {@link ObjectAnimator}. - public int getLanguageOnSpacebarAnimAlpha() { - return mLanguageOnSpacebarAnimAlpha; - } - - public void setLanguageOnSpacebarAnimAlpha(int alpha) { - mLanguageOnSpacebarAnimAlpha = alpha; - invalidateKey(mSpaceKey); - } - - public int getAltCodeKeyWhileTypingAnimAlpha() { - return mAltCodeKeyWhileTypingAnimAlpha; - } - - public void setAltCodeKeyWhileTypingAnimAlpha(int alpha) { - mAltCodeKeyWhileTypingAnimAlpha = alpha; - updateAltCodeKeyWhileTyping(); - } - - public void setKeyboardActionListener(KeyboardActionListener listener) { - mKeyboardActionListener = listener; - PointerTracker.setKeyboardActionListener(listener); - } - - /** - * Returns the {@link KeyboardActionListener} object. - * @return the listener attached to this keyboard - */ - @Override - public KeyboardActionListener getKeyboardActionListener() { - return mKeyboardActionListener; - } - - @Override - public KeyDetector getKeyDetector() { - return mKeyDetector; - } - - @Override - public DrawingProxy getDrawingProxy() { - return this; - } - - @Override - public TimerProxy getTimerProxy() { - return mKeyTimerHandler; - } - - /** - * Attaches a keyboard to this view. The keyboard can be switched at any time and the - * view will re-layout itself to accommodate the keyboard. - * @see Keyboard - * @see #getKeyboard() - * @param keyboard the keyboard to display in this view - */ - @Override - public void setKeyboard(Keyboard keyboard) { - // Remove any pending messages, except dismissing preview and key repeat. - mKeyTimerHandler.cancelLongPressTimer(); - super.setKeyboard(keyboard); - mKeyDetector.setKeyboard( - keyboard, -getPaddingLeft(), -getPaddingTop() + mVerticalCorrection); - PointerTracker.setKeyDetector(mKeyDetector, mGestureInputEnabled); - mTouchScreenRegulator.setKeyboard(keyboard); - mMoreKeysPanelCache.clear(); - - mSpaceKey = keyboard.getKey(Keyboard.CODE_SPACE); - mSpaceIcon = (mSpaceKey != null) - ? mSpaceKey.getIcon(keyboard.mIconsSet, Constants.Color.ALPHA_OPAQUE) : null; - final int keyHeight = keyboard.mMostCommonKeyHeight - keyboard.mVerticalGap; - mSpacebarTextSize = keyHeight * mSpacebarTextRatio; - if (ProductionFlag.IS_EXPERIMENTAL) { - ResearchLogger.latinKeyboardView_setKeyboard(keyboard); - } - - // This always needs to be set since the accessibility state can - // potentially change without the keyboard being set again. - AccessibleKeyboardViewProxy.getInstance().setKeyboard(keyboard); - } - - /** - * Returns whether the device has distinct multi-touch panel. - * @return true if the device has distinct multi-touch panel. - */ - public boolean hasDistinctMultitouch() { - return mHasDistinctMultitouch; - } - - public void setDistinctMultitouch(boolean hasDistinctMultitouch) { - mHasDistinctMultitouch = hasDistinctMultitouch; - } - - /** - * When enabled, calls to {@link KeyboardActionListener#onCodeInput} will include key - * codes for adjacent keys. When disabled, only the primary key code will be - * reported. - * @param enabled whether or not the proximity correction is enabled - */ - public void setProximityCorrectionEnabled(boolean enabled) { - mKeyDetector.setProximityCorrectionEnabled(enabled); - } - - /** - * Returns true if proximity correction is enabled. - */ - public boolean isProximityCorrectionEnabled() { - return mKeyDetector.isProximityCorrectionEnabled(); - } - - @Override - protected void onAttachedToWindow() { - super.onAttachedToWindow(); - // Notify the research logger that the keyboard view has been attached. This is needed - // to properly show the splash screen, which requires that the window token of the - // KeyboardView be non-null. - if (ProductionFlag.IS_EXPERIMENTAL) { - ResearchLogger.getInstance().latinKeyboardView_onAttachedToWindow(); - } - } - - @Override - public void cancelAllMessages() { - mKeyTimerHandler.cancelAllMessages(); - super.cancelAllMessages(); - } - - private boolean openMoreKeysKeyboardIfRequired(Key parentKey, PointerTracker tracker) { - // Check if we have a popup layout specified first. - if (mMoreKeysLayout == 0) { - return false; - } - - // Check if we are already displaying popup panel. - if (mMoreKeysPanel != null) - return false; - if (parentKey == null) - return false; - return onLongPress(parentKey, tracker); - } - - // This default implementation returns a more keys panel. - protected MoreKeysPanel onCreateMoreKeysPanel(Key parentKey) { - if (parentKey.mMoreKeys == null) - return null; - - final View container = LayoutInflater.from(getContext()).inflate(mMoreKeysLayout, null); - if (container == null) - throw new NullPointerException(); - - final MoreKeysKeyboardView moreKeysKeyboardView = - (MoreKeysKeyboardView)container.findViewById(R.id.more_keys_keyboard_view); - final Keyboard moreKeysKeyboard = new MoreKeysKeyboard.Builder(container, parentKey, this) - .build(); - moreKeysKeyboardView.setKeyboard(moreKeysKeyboard); - container.measure(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); - - return moreKeysKeyboardView; - } - - /** - * Called when a key is long pressed. By default this will open more keys keyboard associated - * with this key. - * @param parentKey the key that was long pressed - * @param tracker the pointer tracker which pressed the parent key - * @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 parentKey, PointerTracker tracker) { - if (ProductionFlag.IS_EXPERIMENTAL) { - ResearchLogger.latinKeyboardView_onLongPress(); - } - final int primaryCode = parentKey.mCode; - if (parentKey.hasEmbeddedMoreKey()) { - final int embeddedCode = parentKey.mMoreKeys[0].mCode; - tracker.onLongPressed(); - invokeCodeInput(embeddedCode); - invokeReleaseKey(primaryCode); - KeyboardSwitcher.getInstance().hapticAndAudioFeedback(primaryCode); - return true; - } - if (primaryCode == Keyboard.CODE_SPACE || primaryCode == Keyboard.CODE_LANGUAGE_SWITCH) { - // Long pressing the space key invokes IME switcher dialog. - if (invokeCustomRequest(LatinIME.CODE_SHOW_INPUT_METHOD_PICKER)) { - tracker.onLongPressed(); - invokeReleaseKey(primaryCode); - return true; - } - } - return openMoreKeysPanel(parentKey, tracker); - } - - private boolean invokeCustomRequest(int code) { - return mKeyboardActionListener.onCustomRequest(code); - } - - private void invokeCodeInput(int primaryCode) { - mKeyboardActionListener.onCodeInput(primaryCode, - KeyboardActionListener.NOT_A_TOUCH_COORDINATE, - KeyboardActionListener.NOT_A_TOUCH_COORDINATE); - } - - private void invokeReleaseKey(int primaryCode) { - mKeyboardActionListener.onReleaseKey(primaryCode, false); - } - - private boolean openMoreKeysPanel(Key parentKey, PointerTracker tracker) { - MoreKeysPanel moreKeysPanel = mMoreKeysPanelCache.get(parentKey); - if (moreKeysPanel == null) { - moreKeysPanel = onCreateMoreKeysPanel(parentKey); - if (moreKeysPanel == null) - return false; - mMoreKeysPanelCache.put(parentKey, moreKeysPanel); - } - if (mMoreKeysWindow == null) { - mMoreKeysWindow = new PopupWindow(getContext()); - mMoreKeysWindow.setBackgroundDrawable(null); - mMoreKeysWindow.setAnimationStyle(R.style.MoreKeysKeyboardAnimation); - } - mMoreKeysPanel = moreKeysPanel; - mMoreKeysPanelPointerTrackerId = tracker.mPointerId; - - final boolean keyPreviewEnabled = isKeyPreviewPopupEnabled() && !parentKey.noKeyPreview(); - // The more keys keyboard is usually horizontally aligned with the center of the parent key. - // If showMoreKeysKeyboardAtTouchedPoint is true and the key preview is disabled, the more - // keys keyboard is placed at the touch point of the parent key. - final int pointX = (mConfigShowMoreKeysKeyboardAtTouchedPoint && !keyPreviewEnabled) - ? tracker.getLastX() - : parentKey.mX + parentKey.mWidth / 2; - // The more keys keyboard is usually vertically aligned with the top edge of the parent key - // (plus vertical gap). If the key preview is enabled, the more keys keyboard is vertically - // aligned with the bottom edge of the visible part of the key preview. - final int pointY = parentKey.mY + (keyPreviewEnabled - ? mKeyPreviewDrawParams.mPreviewVisibleOffset - : -parentKey.mVerticalGap); - moreKeysPanel.showMoreKeysPanel( - this, this, pointX, pointY, mMoreKeysWindow, mKeyboardActionListener); - final int translatedX = moreKeysPanel.translateX(tracker.getLastX()); - final int translatedY = moreKeysPanel.translateY(tracker.getLastY()); - tracker.onShowMoreKeysPanel(translatedX, translatedY, moreKeysPanel); - dimEntireKeyboard(true); - return true; - } - - public boolean isInSlidingKeyInput() { - if (mMoreKeysPanel != null) { - return true; - } else { - return PointerTracker.isAnyInSlidingKeyInput(); - } - } - - public int getPointerCount() { - return mOldPointerCount; - } - - @Override - public boolean onTouchEvent(MotionEvent me) { - if (getKeyboard() == null) { - return false; - } - return mTouchScreenRegulator.onTouchEvent(me); - } - - @Override - public boolean processMotionEvent(MotionEvent me) { - final boolean nonDistinctMultitouch = !mHasDistinctMultitouch; - final int action = me.getActionMasked(); - final int pointerCount = me.getPointerCount(); - final int oldPointerCount = mOldPointerCount; - mOldPointerCount = pointerCount; - - // TODO: cleanup this code into a multi-touch to single-touch event converter class? - // If the device does not have distinct multi-touch support panel, ignore all multi-touch - // events except a transition from/to single-touch. - if (nonDistinctMultitouch && pointerCount > 1 && oldPointerCount > 1) { - return true; - } - - final long eventTime = me.getEventTime(); - final int index = me.getActionIndex(); - final int id = me.getPointerId(index); - final int x, y; - if (mMoreKeysPanel != null && id == mMoreKeysPanelPointerTrackerId) { - x = mMoreKeysPanel.translateX((int)me.getX(index)); - y = mMoreKeysPanel.translateY((int)me.getY(index)); - } else { - x = (int)me.getX(index); - y = (int)me.getY(index); - } - if (ENABLE_USABILITY_STUDY_LOG) { - final String eventTag; - switch (action) { - case MotionEvent.ACTION_UP: - eventTag = "[Up]"; - break; - case MotionEvent.ACTION_DOWN: - eventTag = "[Down]"; - break; - case MotionEvent.ACTION_POINTER_UP: - eventTag = "[PointerUp]"; - break; - case MotionEvent.ACTION_POINTER_DOWN: - eventTag = "[PointerDown]"; - break; - case MotionEvent.ACTION_MOVE: // Skip this as being logged below - eventTag = ""; - break; - default: - eventTag = "[Action" + action + "]"; - break; - } - if (!TextUtils.isEmpty(eventTag)) { - final float size = me.getSize(index); - final float pressure = me.getPressure(index); - UsabilityStudyLogUtils.getInstance().write( - eventTag + eventTime + "," + id + "," + x + "," + y + "," - + size + "," + pressure); - } - } - if (ProductionFlag.IS_EXPERIMENTAL) { - ResearchLogger.latinKeyboardView_processMotionEvent(me, action, eventTime, index, id, - x, y); - } - - if (mKeyTimerHandler.isInKeyRepeat()) { - final PointerTracker tracker = PointerTracker.getPointerTracker(id, this); - // Key repeating timer will be canceled if 2 or more keys are in action, and current - // event (UP or DOWN) is non-modifier key. - if (pointerCount > 1 && !tracker.isModifier()) { - mKeyTimerHandler.cancelKeyRepeatTimer(); - } - // Up event will pass through. - } - - // TODO: cleanup this code into a multi-touch to single-touch event converter class? - // Translate mutli-touch event to single-touch events on the device that has no distinct - // multi-touch panel. - if (nonDistinctMultitouch) { - // Use only main (id=0) pointer tracker. - final PointerTracker tracker = PointerTracker.getPointerTracker(0, this); - if (pointerCount == 1 && oldPointerCount == 2) { - // Multi-touch to single touch transition. - // Send a down event for the latest pointer if the key is different from the - // previous key. - final Key newKey = tracker.getKeyOn(x, y); - if (mOldKey != newKey) { - tracker.onDownEvent(x, y, eventTime, this); - if (action == MotionEvent.ACTION_UP) - tracker.onUpEvent(x, y, eventTime); - } - } else if (pointerCount == 2 && oldPointerCount == 1) { - // Single-touch to multi-touch transition. - // Send an up event for the last pointer. - final int lastX = tracker.getLastX(); - final int lastY = tracker.getLastY(); - mOldKey = tracker.getKeyOn(lastX, lastY); - tracker.onUpEvent(lastX, lastY, eventTime); - } else if (pointerCount == 1 && oldPointerCount == 1) { - tracker.processMotionEvent(action, x, y, eventTime, this); - } else { - Log.w(TAG, "Unknown touch panel behavior: pointer count is " + pointerCount - + " (old " + oldPointerCount + ")"); - } - return true; - } - - if (action == MotionEvent.ACTION_MOVE) { - for (int i = 0; i < pointerCount; i++) { - final int pointerId = me.getPointerId(i); - final PointerTracker tracker = PointerTracker.getPointerTracker( - pointerId, this); - final int px, py; - final MotionEvent motionEvent; - if (mMoreKeysPanel != null - && tracker.mPointerId == mMoreKeysPanelPointerTrackerId) { - px = mMoreKeysPanel.translateX((int)me.getX(i)); - py = mMoreKeysPanel.translateY((int)me.getY(i)); - motionEvent = null; - } else { - px = (int)me.getX(i); - py = (int)me.getY(i); - motionEvent = me; - } - tracker.onMoveEvent(px, py, eventTime, motionEvent); - if (ENABLE_USABILITY_STUDY_LOG) { - final float pointerSize = me.getSize(i); - final float pointerPressure = me.getPressure(i); - UsabilityStudyLogUtils.getInstance().write("[Move]" + eventTime + "," - + pointerId + "," + px + "," + py + "," - + pointerSize + "," + pointerPressure); - } - if (ProductionFlag.IS_EXPERIMENTAL) { - ResearchLogger.latinKeyboardView_processMotionEvent(me, action, eventTime, - i, pointerId, px, py); - } - } - } else { - final PointerTracker tracker = PointerTracker.getPointerTracker(id, this); - tracker.processMotionEvent(action, x, y, eventTime, this); - } - - return true; - } - - @Override - public void closing() { - super.closing(); - dismissMoreKeysPanel(); - mMoreKeysPanelCache.clear(); - } - - @Override - public boolean dismissMoreKeysPanel() { - if (mMoreKeysWindow != null && mMoreKeysWindow.isShowing()) { - mMoreKeysWindow.dismiss(); - mMoreKeysPanel = null; - mMoreKeysPanelPointerTrackerId = -1; - dimEntireKeyboard(false); - return true; - } - return false; - } - - @Override - public void draw(Canvas c) { - Utils.GCUtils.getInstance().reset(); - boolean tryGC = true; - for (int i = 0; i < Utils.GCUtils.GC_TRY_LOOP_MAX && tryGC; ++i) { - try { - super.draw(c); - tryGC = false; - } catch (OutOfMemoryError e) { - tryGC = Utils.GCUtils.getInstance().tryGCOrWait(TAG, e); - } - } - } - - /** - * Receives hover events from the input framework. - * - * @param event The motion event to be dispatched. - * @return {@code true} if the event was handled by the view, {@code false} - * otherwise - */ - @Override - public boolean dispatchHoverEvent(MotionEvent event) { - if (AccessibilityUtils.getInstance().isTouchExplorationEnabled()) { - final PointerTracker tracker = PointerTracker.getPointerTracker(0, this); - return AccessibleKeyboardViewProxy.getInstance().dispatchHoverEvent(event, tracker); - } - - // Reflection doesn't support calling superclass methods. - return false; - } - - public void updateShortcutKey(boolean available) { - final Keyboard keyboard = getKeyboard(); - if (keyboard == null) return; - final Key shortcutKey = keyboard.getKey(Keyboard.CODE_SHORTCUT); - if (shortcutKey == null) return; - shortcutKey.setEnabled(available); - invalidateKey(shortcutKey); - } - - private void updateAltCodeKeyWhileTyping() { - final Keyboard keyboard = getKeyboard(); - if (keyboard == null) return; - for (final Key key : keyboard.mAltCodeKeysWhileTyping) { - invalidateKey(key); - } - } - - public void startDisplayLanguageOnSpacebar(boolean subtypeChanged, - boolean needsToDisplayLanguage, boolean hasMultipleEnabledIMEsOrSubtypes) { - mNeedsToDisplayLanguage = needsToDisplayLanguage; - mHasMultipleEnabledIMEsOrSubtypes = hasMultipleEnabledIMEsOrSubtypes; - final ObjectAnimator animator = mLanguageOnSpacebarFadeoutAnimator; - if (animator == null) { - mNeedsToDisplayLanguage = false; - } else { - if (subtypeChanged && needsToDisplayLanguage) { - setLanguageOnSpacebarAnimAlpha(Constants.Color.ALPHA_OPAQUE); - if (animator.isStarted()) { - animator.cancel(); - } - animator.start(); - } else { - if (!animator.isStarted()) { - mLanguageOnSpacebarAnimAlpha = mLanguageOnSpacebarFinalAlpha; - } - } - } - invalidateKey(mSpaceKey); - } - - public void updateAutoCorrectionState(boolean isAutoCorrection) { - if (!mAutoCorrectionSpacebarLedEnabled) return; - mAutoCorrectionSpacebarLedOn = isAutoCorrection; - invalidateKey(mSpaceKey); - } - - @Override - protected void onDrawKeyTopVisuals(Key key, Canvas canvas, Paint paint, KeyDrawParams params) { - if (key.altCodeWhileTyping() && key.isEnabled()) { - params.mAnimAlpha = mAltCodeKeyWhileTypingAnimAlpha; - } - if (key.mCode == Keyboard.CODE_SPACE) { - drawSpacebar(key, canvas, paint); - // Whether space key needs to show the "..." popup hint for special purposes - if (key.isLongPressEnabled() && mHasMultipleEnabledIMEsOrSubtypes) { - drawKeyPopupHint(key, canvas, paint, params); - } - } else if (key.mCode == Keyboard.CODE_LANGUAGE_SWITCH) { - super.onDrawKeyTopVisuals(key, canvas, paint, params); - drawKeyPopupHint(key, canvas, paint, params); - } else { - super.onDrawKeyTopVisuals(key, canvas, paint, params); - } - } - - private boolean fitsTextIntoWidth(final int width, String text, Paint paint) { - paint.setTextScaleX(1.0f); - final float textWidth = getLabelWidth(text, paint); - if (textWidth < width) return true; - - final float scaleX = width / textWidth; - if (scaleX < MINIMUM_XSCALE_OF_LANGUAGE_NAME) return false; - - paint.setTextScaleX(scaleX); - return getLabelWidth(text, paint) < width; - } - - // Layout language name on spacebar. - private String layoutLanguageOnSpacebar(Paint paint, InputMethodSubtype subtype, - final int width) { - // Choose appropriate language name to fit into the width. - String text = getFullDisplayName(subtype, getResources()); - if (fitsTextIntoWidth(width, text, paint)) { - return text; - } - - text = getMiddleDisplayName(subtype); - if (fitsTextIntoWidth(width, text, paint)) { - return text; - } - - text = getShortDisplayName(subtype); - if (fitsTextIntoWidth(width, text, paint)) { - return text; - } - - return ""; - } - - private void drawSpacebar(Key key, Canvas canvas, Paint paint) { - final int width = key.mWidth; - final int height = key.mHeight; - - // If input language are explicitly selected. - if (mNeedsToDisplayLanguage) { - paint.setTextAlign(Align.CENTER); - paint.setTypeface(Typeface.DEFAULT); - paint.setTextSize(mSpacebarTextSize); - final InputMethodSubtype subtype = getKeyboard().mId.mSubtype; - final String language = layoutLanguageOnSpacebar(paint, subtype, width); - // Draw language text with shadow - final float descent = paint.descent(); - final float textHeight = -paint.ascent() + descent; - final float baseline = height / 2 + textHeight / 2; - paint.setColor(mSpacebarTextShadowColor); - paint.setAlpha(mLanguageOnSpacebarAnimAlpha); - canvas.drawText(language, width / 2, baseline - descent - 1, paint); - paint.setColor(mSpacebarTextColor); - paint.setAlpha(mLanguageOnSpacebarAnimAlpha); - canvas.drawText(language, width / 2, baseline - descent, paint); - } - - // Draw the spacebar icon at the bottom - if (mAutoCorrectionSpacebarLedOn) { - final int iconWidth = width * SPACE_LED_LENGTH_PERCENT / 100; - final int iconHeight = mAutoCorrectionSpacebarLedIcon.getIntrinsicHeight(); - int x = (width - iconWidth) / 2; - int y = height - iconHeight; - drawIcon(canvas, mAutoCorrectionSpacebarLedIcon, x, y, iconWidth, iconHeight); - } else if (mSpaceIcon != null) { - final int iconWidth = mSpaceIcon.getIntrinsicWidth(); - final int iconHeight = mSpaceIcon.getIntrinsicHeight(); - int x = (width - iconWidth) / 2; - int y = height - iconHeight; - drawIcon(canvas, mSpaceIcon, x, y, iconWidth, iconHeight); - } - } - - // InputMethodSubtype's display name for spacebar text in its locale. - // isAdditionalSubtype (T=true, F=false) - // locale layout | Short Middle Full - // ------ ------ - ---- --------- ---------------------- - // en_US qwerty F En English English (US) exception - // en_GB qwerty F En English English (UK) exception - // fr azerty F Fr Français Français - // fr_CA qwerty F Fr Français Français (Canada) - // de qwertz F De Deutsch Deutsch - // zz qwerty F QWERTY QWERTY - // fr qwertz T Fr Français Français (QWERTZ) - // de qwerty T De Deutsch Deutsch (QWERTY) - // en_US azerty T En English English (US) (AZERTY) - // zz azerty T AZERTY AZERTY - - // Get InputMethodSubtype's full display name in its locale. - static String getFullDisplayName(InputMethodSubtype subtype, Resources res) { - if (SubtypeLocale.isNoLanguage(subtype)) { - return SubtypeLocale.getKeyboardLayoutSetDisplayName(subtype); - } - - return SubtypeLocale.getSubtypeDisplayName(subtype, res); - } - - // Get InputMethodSubtype's short display name in its locale. - static String getShortDisplayName(InputMethodSubtype subtype) { - if (SubtypeLocale.isNoLanguage(subtype)) { - return ""; - } - final Locale locale = SubtypeLocale.getSubtypeLocale(subtype); - return StringUtils.toTitleCase(locale.getLanguage(), locale); - } - - // Get InputMethodSubtype's middle display name in its locale. - static String getMiddleDisplayName(InputMethodSubtype subtype) { - if (SubtypeLocale.isNoLanguage(subtype)) { - return SubtypeLocale.getKeyboardLayoutSetDisplayName(subtype); - } - final Locale locale = SubtypeLocale.getSubtypeLocale(subtype); - return StringUtils.toTitleCase(locale.getDisplayLanguage(locale), locale); - } -} |
