15f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka/* 25f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka * Copyright (C) 2011 The Android Open Source Project 35f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka * 45f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka * Licensed under the Apache License, Version 2.0 (the "License"); 55f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka * you may not use this file except in compliance with the License. 65f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka * You may obtain a copy of the License at 75f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka * 85f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka * http://www.apache.org/licenses/LICENSE-2.0 95f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka * 105f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka * Unless required by applicable law or agreed to in writing, software 115f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka * distributed under the License is distributed on an "AS IS" BASIS, 125f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka * See the License for the specific language governing permissions and 145f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka * limitations under the License. 155f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka */ 165f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka 175f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaokapackage com.android.inputmethod.keyboard; 185f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka 19d7c4ba170982ddce5ac12ea92c3c3d8b53d524baTadashi G. Takaokaimport android.animation.AnimatorInflater; 2031c94cea82f1788e3a04f2a1e012945f35497f0aTadashi G. Takaokaimport android.animation.ObjectAnimator; 215f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaokaimport android.content.Context; 2213ae76d7a342581160c172cd21706b3d57d32dadTadashi G. Takaokaimport android.content.SharedPreferences; 235f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaokaimport android.content.pm.PackageManager; 244112dc05002d7a880e558418639cf25c4bd02a5aTadashi G. Takaokaimport android.content.res.TypedArray; 256dde878d515f7bf5268d16a8fe4921d8821c5ae7Tadashi G. Takaokaimport android.graphics.Canvas; 26f3c4cd45a5df6f90b922ea44db259e53117bb25aTadashi G. Takaokaimport android.graphics.Color; 2722b48de11ce6f31a0edf90e1308073e67a7a2adbTadashi G. Takaokaimport android.graphics.Paint; 284112dc05002d7a880e558418639cf25c4bd02a5aTadashi G. Takaokaimport android.graphics.Paint.Align; 29bd93eddb52816acedd5242864e467781d4adfd71Tadashi G. Takaokaimport android.graphics.Typeface; 3013ae76d7a342581160c172cd21706b3d57d32dadTadashi G. Takaokaimport android.preference.PreferenceManager; 315d2d852eb0caaf7416c159f83d51e07b1ca87e30Jean Chalardimport android.text.TextUtils; 325f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaokaimport android.util.AttributeSet; 335f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaokaimport android.util.Log; 345f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaokaimport android.view.LayoutInflater; 355f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaokaimport android.view.MotionEvent; 365f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaokaimport android.view.View; 37b8dc67466339dc14653ad634c86851025373326bTadashi G. Takaokaimport android.view.ViewGroup; 385f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka 395f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaokaimport com.android.inputmethod.accessibility.AccessibilityUtils; 404d146d5e3e00cab1cca7d0d29fe00c0d629b5eacTadashi G. Takaokaimport com.android.inputmethod.accessibility.MainKeyboardAccessibilityDelegate; 4115f6d4ae34664ea3d92827a2c3003198c0bac70bTadashi G. Takaokaimport com.android.inputmethod.annotations.ExternallyReferenced; 42cf915ddc878699909365dd599a0e154552e244e2Tadashi G. Takaokaimport com.android.inputmethod.keyboard.internal.DrawingPreviewPlacerView; 4334a9e2ae87c6718d439b294d9536b6587a4f89f8Tadashi G. Takaokaimport com.android.inputmethod.keyboard.internal.DrawingProxy; 44cf915ddc878699909365dd599a0e154552e244e2Tadashi G. Takaokaimport com.android.inputmethod.keyboard.internal.GestureFloatingTextDrawingPreview; 45cf915ddc878699909365dd599a0e154552e244e2Tadashi G. Takaokaimport com.android.inputmethod.keyboard.internal.GestureTrailsDrawingPreview; 4649d8af8a4e900f3c68c333aba7fde0a11fd368b1Tadashi G. Takaokaimport com.android.inputmethod.keyboard.internal.KeyDrawParams; 47bb476be4e62b3bed7848d37df42f8fa7363b58d1Tadashi G. Takaokaimport com.android.inputmethod.keyboard.internal.KeyPreviewChoreographer; 480e4f0da449d0fc4f0c4c6b49b4c24961da36a5d1Tadashi G. Takaokaimport com.android.inputmethod.keyboard.internal.KeyPreviewDrawParams; 49016d6c424cf004c282db5a57e64f3d1eee672a22Tadashi G. Takaokaimport com.android.inputmethod.keyboard.internal.KeyPreviewView; 5003288ef47fd93758b5665e19fe9b892ece6e586fTadashi G. Takaokaimport com.android.inputmethod.keyboard.internal.MoreKeySpec; 51b6cc3a85ab68cff2fae4c3858b48d9c5d7b45690Tadashi G. Takaokaimport com.android.inputmethod.keyboard.internal.NonDistinctMultitouchHelper; 52cf915ddc878699909365dd599a0e154552e244e2Tadashi G. Takaokaimport com.android.inputmethod.keyboard.internal.SlidingKeyInputDrawingPreview; 532fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasaimport com.android.inputmethod.keyboard.internal.TimerHandler; 545f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaokaimport com.android.inputmethod.latin.R; 5585ddfe1317a4475269e53f62c2338c335e02e839Jean Chalardimport com.android.inputmethod.latin.RichInputMethodSubtype; 56375982106bf073971fccd14b2c65ec8e089bb2aeTadashi G. Takaokaimport com.android.inputmethod.latin.SuggestedWords; 579342484e8d573a40f470b6a593df31c602fa4076Ken Wakasaimport com.android.inputmethod.latin.common.Constants; 585b91b551e5ffaf2c2e691dfbd434f21c82293986Jean Chalardimport com.android.inputmethod.latin.common.CoordinateUtils; 59a7d2fc6befa1b16883200a653fc01deb4d94944dKen Wakasaimport com.android.inputmethod.latin.settings.DebugSettings; 604934a88b618f06600e2d725a43bdd2511715b4caTadashi G. Takaokaimport com.android.inputmethod.latin.utils.LanguageOnSpacebarUtils; 61ccf4a310279b13bbf0b6aac76a0878178c1dfb7dTadashi G. Takaokaimport com.android.inputmethod.latin.utils.TypefaceUtils; 625f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka 635d2d852eb0caaf7416c159f83d51e07b1ca87e30Jean Chalardimport java.util.Locale; 645f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaokaimport java.util.WeakHashMap; 655f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka 662ad6d9cda33825fa265cd17372f115bb48f49d19Tadashi G. Takaokaimport javax.annotation.Nonnull; 67051f8b144232f724386960cf6781a6d4665e4f02Tadashi G. Takaokaimport javax.annotation.Nullable; 682ad6d9cda33825fa265cd17372f115bb48f49d19Tadashi G. Takaoka 695f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka/** 705f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka * A view that is responsible for detecting key presses and touch movements. 715f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka * 722fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa * @attr ref R.styleable#MainKeyboardView_languageOnSpacebarTextRatio 732fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa * @attr ref R.styleable#MainKeyboardView_languageOnSpacebarTextColor 7441f9f1ef703ca4d63f1ef08b51d1365a17b4065aTadashi G. Takaoka * @attr ref R.styleable#MainKeyboardView_languageOnSpacebarTextShadowRadius 752fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa * @attr ref R.styleable#MainKeyboardView_languageOnSpacebarTextShadowColor 76dc34da218a22489d92d1015e9e5dac8d951b89f4Tadashi G. Takaoka * @attr ref R.styleable#MainKeyboardView_languageOnSpacebarFinalAlpha 77dc34da218a22489d92d1015e9e5dac8d951b89f4Tadashi G. Takaoka * @attr ref R.styleable#MainKeyboardView_languageOnSpacebarFadeoutAnimator 78dc34da218a22489d92d1015e9e5dac8d951b89f4Tadashi G. Takaoka * @attr ref R.styleable#MainKeyboardView_altCodeKeyWhileTypingFadeoutAnimator 79dc34da218a22489d92d1015e9e5dac8d951b89f4Tadashi G. Takaoka * @attr ref R.styleable#MainKeyboardView_altCodeKeyWhileTypingFadeinAnimator 80dc34da218a22489d92d1015e9e5dac8d951b89f4Tadashi G. Takaoka * @attr ref R.styleable#MainKeyboardView_keyHysteresisDistance 81dc34da218a22489d92d1015e9e5dac8d951b89f4Tadashi G. Takaoka * @attr ref R.styleable#MainKeyboardView_touchNoiseThresholdTime 82dc34da218a22489d92d1015e9e5dac8d951b89f4Tadashi G. Takaoka * @attr ref R.styleable#MainKeyboardView_touchNoiseThresholdDistance 832fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa * @attr ref R.styleable#MainKeyboardView_keySelectionByDraggingFinger 84dc34da218a22489d92d1015e9e5dac8d951b89f4Tadashi G. Takaoka * @attr ref R.styleable#MainKeyboardView_keyRepeatStartTimeout 85dc34da218a22489d92d1015e9e5dac8d951b89f4Tadashi G. Takaoka * @attr ref R.styleable#MainKeyboardView_keyRepeatInterval 86dc34da218a22489d92d1015e9e5dac8d951b89f4Tadashi G. Takaoka * @attr ref R.styleable#MainKeyboardView_longPressKeyTimeout 87dc34da218a22489d92d1015e9e5dac8d951b89f4Tadashi G. Takaoka * @attr ref R.styleable#MainKeyboardView_longPressShiftKeyTimeout 88dc34da218a22489d92d1015e9e5dac8d951b89f4Tadashi G. Takaoka * @attr ref R.styleable#MainKeyboardView_ignoreAltCodeKeyTimeout 89375982106bf073971fccd14b2c65ec8e089bb2aeTadashi G. Takaoka * @attr ref R.styleable#MainKeyboardView_keyPreviewLayout 900e4f0da449d0fc4f0c4c6b49b4c24961da36a5d1Tadashi G. Takaoka * @attr ref R.styleable#MainKeyboardView_keyPreviewOffset 910e4f0da449d0fc4f0c4c6b49b4c24961da36a5d1Tadashi G. Takaoka * @attr ref R.styleable#MainKeyboardView_keyPreviewHeight 920e4f0da449d0fc4f0c4c6b49b4c24961da36a5d1Tadashi G. Takaoka * @attr ref R.styleable#MainKeyboardView_keyPreviewLingerTimeout 93ac88f3d8459e17236654aa38debea749ecb631d1Tadashi G. Takaoka * @attr ref R.styleable#MainKeyboardView_keyPreviewShowUpAnimator 94ac88f3d8459e17236654aa38debea749ecb631d1Tadashi G. Takaoka * @attr ref R.styleable#MainKeyboardView_keyPreviewDismissAnimator 95d9449ccf3ce9e5eabb022aed6a45bba680bce115Tadashi G. Takaoka * @attr ref R.styleable#MainKeyboardView_moreKeysKeyboardLayout 960f33e614c0799fa3a14a2c32db4bf0654df039daTadashi G. Takaoka * @attr ref R.styleable#MainKeyboardView_moreKeysKeyboardForActionLayout 97f3c4cd45a5df6f90b922ea44db259e53117bb25aTadashi G. Takaoka * @attr ref R.styleable#MainKeyboardView_backgroundDimAlpha 98dc34da218a22489d92d1015e9e5dac8d951b89f4Tadashi G. Takaoka * @attr ref R.styleable#MainKeyboardView_showMoreKeysKeyboardAtTouchPoint 99375982106bf073971fccd14b2c65ec8e089bb2aeTadashi G. Takaoka * @attr ref R.styleable#MainKeyboardView_gestureFloatingPreviewTextLingerTimeout 1003623b9767b3d5f122f574d4c4d14aa79ed305752Tadashi G. Takaoka * @attr ref R.styleable#MainKeyboardView_gestureStaticTimeThresholdAfterFastTyping 1013623b9767b3d5f122f574d4c4d14aa79ed305752Tadashi G. Takaoka * @attr ref R.styleable#MainKeyboardView_gestureDetectFastMoveSpeedThreshold 1023623b9767b3d5f122f574d4c4d14aa79ed305752Tadashi G. Takaoka * @attr ref R.styleable#MainKeyboardView_gestureDynamicThresholdDecayDuration 1033623b9767b3d5f122f574d4c4d14aa79ed305752Tadashi G. Takaoka * @attr ref R.styleable#MainKeyboardView_gestureDynamicTimeThresholdFrom 1043623b9767b3d5f122f574d4c4d14aa79ed305752Tadashi G. Takaoka * @attr ref R.styleable#MainKeyboardView_gestureDynamicTimeThresholdTo 1053623b9767b3d5f122f574d4c4d14aa79ed305752Tadashi G. Takaoka * @attr ref R.styleable#MainKeyboardView_gestureDynamicDistanceThresholdFrom 1063623b9767b3d5f122f574d4c4d14aa79ed305752Tadashi G. Takaoka * @attr ref R.styleable#MainKeyboardView_gestureDynamicDistanceThresholdTo 1073623b9767b3d5f122f574d4c4d14aa79ed305752Tadashi G. Takaoka * @attr ref R.styleable#MainKeyboardView_gestureSamplingMinimumDistance 1083623b9767b3d5f122f574d4c4d14aa79ed305752Tadashi G. Takaoka * @attr ref R.styleable#MainKeyboardView_gestureRecognitionMinimumTime 1093623b9767b3d5f122f574d4c4d14aa79ed305752Tadashi G. Takaoka * @attr ref R.styleable#MainKeyboardView_gestureRecognitionSpeedThreshold 1103623b9767b3d5f122f574d4c4d14aa79ed305752Tadashi G. Takaoka * @attr ref R.styleable#MainKeyboardView_suppressKeyPreviewAfterBatchInputDuration 1115f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka */ 11234a9e2ae87c6718d439b294d9536b6587a4f89f8Tadashi G. Takaokapublic final class MainKeyboardView extends KeyboardView implements DrawingProxy, 113be708c4e59ba16cf735440b99aa682baa3319ec5Tadashi G. Takaoka MoreKeysPanel.Controller { 114c8e45ddb032554f4e9d4411d8ef47d98db62d77bTadashi G. Takaoka private static final String TAG = MainKeyboardView.class.getSimpleName(); 1155f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka 116bd93eddb52816acedd5242864e467781d4adfd71Tadashi G. Takaoka /** Listener for {@link KeyboardActionListener}. */ 117bd93eddb52816acedd5242864e467781d4adfd71Tadashi G. Takaoka private KeyboardActionListener mKeyboardActionListener; 118bd93eddb52816acedd5242864e467781d4adfd71Tadashi G. Takaoka 1192fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa /* Space key and its icon and background. */ 1204112dc05002d7a880e558418639cf25c4bd02a5aTadashi G. Takaoka private Key mSpaceKey; 121bd93eddb52816acedd5242864e467781d4adfd71Tadashi G. Takaoka // Stuff to draw language name on spacebar. 12231c94cea82f1788e3a04f2a1e012945f35497f0aTadashi G. Takaoka private final int mLanguageOnSpacebarFinalAlpha; 12331c94cea82f1788e3a04f2a1e012945f35497f0aTadashi G. Takaoka private ObjectAnimator mLanguageOnSpacebarFadeoutAnimator; 1247dd32dfc065c13e946c0d42a0e000f4ce7298ed7Tadashi G. Takaoka private int mLanguageOnSpacebarFormatType; 125fd60b2f97035382b14dce207b3613711982a613eTadashi G. Takaoka private boolean mHasMultipleEnabledIMEsOrSubtypes; 1264daf32b6c0358f0273a99b622a259ecdf6b44fa4Tom Ouyang private int mLanguageOnSpacebarAnimAlpha = Constants.Color.ALPHA_OPAQUE; 1272fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa private final float mLanguageOnSpacebarTextRatio; 1282fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa private float mLanguageOnSpacebarTextSize; 1292fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa private final int mLanguageOnSpacebarTextColor; 13041f9f1ef703ca4d63f1ef08b51d1365a17b4065aTadashi G. Takaoka private final float mLanguageOnSpacebarTextShadowRadius; 1312fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa private final int mLanguageOnSpacebarTextShadowColor; 13241f9f1ef703ca4d63f1ef08b51d1365a17b4065aTadashi G. Takaoka private static final float LANGUAGE_ON_SPACEBAR_TEXT_SHADOW_RADIUS_DISABLED = -1.0f; 133bd2ca9c0214ea80fa860f4a9d118f866e16b03caTadashi G. Takaoka // The minimum x-scale to fit the language name on spacebar. 134bd2ca9c0214ea80fa860f4a9d118f866e16b03caTadashi G. Takaoka private static final float MINIMUM_XSCALE_OF_LANGUAGE_NAME = 0.8f; 13515d4793911fa305e0a58aced925961e948582979satok 13673a46bfeb7a109b49be196e5d679e44c9e66a2e8Tadashi G. Takaoka // Stuff to draw altCodeWhileTyping keys. 1372fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa private final ObjectAnimator mAltCodeKeyWhileTypingFadeoutAnimator; 1382fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa private final ObjectAnimator mAltCodeKeyWhileTypingFadeinAnimator; 1394daf32b6c0358f0273a99b622a259ecdf6b44fa4Tom Ouyang private int mAltCodeKeyWhileTypingAnimAlpha = Constants.Color.ALPHA_OPAQUE; 14073a46bfeb7a109b49be196e5d679e44c9e66a2e8Tadashi G. Takaoka 141cf915ddc878699909365dd599a0e154552e244e2Tadashi G. Takaoka // Drawing preview placer view 142cf915ddc878699909365dd599a0e154552e244e2Tadashi G. Takaoka private final DrawingPreviewPlacerView mDrawingPreviewPlacerView; 143375982106bf073971fccd14b2c65ec8e089bb2aeTadashi G. Takaoka private final int[] mOriginCoords = CoordinateUtils.newInstance(); 144cf915ddc878699909365dd599a0e154552e244e2Tadashi G. Takaoka private final GestureFloatingTextDrawingPreview mGestureFloatingTextDrawingPreview; 145cf915ddc878699909365dd599a0e154552e244e2Tadashi G. Takaoka private final GestureTrailsDrawingPreview mGestureTrailsDrawingPreview; 146cf915ddc878699909365dd599a0e154552e244e2Tadashi G. Takaoka private final SlidingKeyInputDrawingPreview mSlidingKeyInputDrawingPreview; 147375982106bf073971fccd14b2c65ec8e089bb2aeTadashi G. Takaoka 1480e4f0da449d0fc4f0c4c6b49b4c24961da36a5d1Tadashi G. Takaoka // Key preview 149992c5219092ccafe66363451fbf4ca7c5a43fb20Tadashi G. Takaoka private final KeyPreviewDrawParams mKeyPreviewDrawParams; 150bb476be4e62b3bed7848d37df42f8fa7363b58d1Tadashi G. Takaoka private final KeyPreviewChoreographer mKeyPreviewChoreographer; 1510e4f0da449d0fc4f0c4c6b49b4c24961da36a5d1Tadashi G. Takaoka 1522affaf91a04d63e0994102299816014a8bbe11e1Tadashi G. Takaoka // More keys keyboard 153f3c4cd45a5df6f90b922ea44db259e53117bb25aTadashi G. Takaoka private final Paint mBackgroundDimAlphaPaint = new Paint(); 154a729377395967f7652d93992cbcf50cd2ff522d1Tadashi G. Takaoka private final View mMoreKeysKeyboardContainer; 1550f33e614c0799fa3a14a2c32db4bf0654df039daTadashi G. Takaoka private final View mMoreKeysKeyboardForActionContainer; 156a91561aa58db1c43092c1caecc051a11fa5391c7Tadashi G. Takaoka private final WeakHashMap<Key, Keyboard> mMoreKeysKeyboardCache = new WeakHashMap<>(); 1572affaf91a04d63e0994102299816014a8bbe11e1Tadashi G. Takaoka private final boolean mConfigShowMoreKeysKeyboardAtTouchedPoint; 158d9449ccf3ce9e5eabb022aed6a45bba680bce115Tadashi G. Takaoka // More keys panel (used by both more keys keyboard and more suggestions view) 159d9449ccf3ce9e5eabb022aed6a45bba680bce115Tadashi G. Takaoka // TODO: Consider extending to support multiple more keys panels 160d9449ccf3ce9e5eabb022aed6a45bba680bce115Tadashi G. Takaoka private MoreKeysPanel mMoreKeysPanel; 1615f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka 162375982106bf073971fccd14b2c65ec8e089bb2aeTadashi G. Takaoka // Gesture floating preview text 163375982106bf073971fccd14b2c65ec8e089bb2aeTadashi G. Takaoka // TODO: Make this parameter customizable by user via settings. 164375982106bf073971fccd14b2c65ec8e089bb2aeTadashi G. Takaoka private int mGestureFloatingPreviewTextLingerTimeout; 165375982106bf073971fccd14b2c65ec8e089bb2aeTadashi G. Takaoka 1662fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa private final KeyDetector mKeyDetector; 167b6cc3a85ab68cff2fae4c3858b48d9c5d7b45690Tadashi G. Takaoka private final NonDistinctMultitouchHelper mNonDistinctMultitouchHelper; 1685f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka 1692ad6d9cda33825fa265cd17372f115bb48f49d19Tadashi G. Takaoka private final TimerHandler mTimerHandler; 170741831d32295acfb7675d7e0781a634d78868c63Satoshi Kataoka private final int mLanguageOnSpacebarHorizontalMargin; 1715f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka 172d78b586976af9b6b8f6e00c04747facfac313abcTadashi G. Takaoka private MainKeyboardAccessibilityDelegate mAccessibilityDelegate; 173bca7e4e9a2ed07d5d87f4dce9f793e40edb09691Tadashi G. Takaoka 174dc34da218a22489d92d1015e9e5dac8d951b89f4Tadashi G. Takaoka public MainKeyboardView(final Context context, final AttributeSet attrs) { 175c8e45ddb032554f4e9d4411d8ef47d98db62d77bTadashi G. Takaoka this(context, attrs, R.attr.mainKeyboardViewStyle); 1765f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka } 1775f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka 178dc34da218a22489d92d1015e9e5dac8d951b89f4Tadashi G. Takaoka public MainKeyboardView(final Context context, final AttributeSet attrs, final int defStyle) { 1795f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka super(context, attrs, defStyle); 1805f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka 181be708c4e59ba16cf735440b99aa682baa3319ec5Tadashi G. Takaoka final DrawingPreviewPlacerView drawingPreviewPlacerView = 182be708c4e59ba16cf735440b99aa682baa3319ec5Tadashi G. Takaoka new DrawingPreviewPlacerView(context, attrs); 1832fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa 1842fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa final TypedArray mainKeyboardViewAttr = context.obtainStyledAttributes( 1852fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa attrs, R.styleable.MainKeyboardView, defStyle, R.style.MainKeyboardView); 1862fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa final int ignoreAltCodeKeyTimeout = mainKeyboardViewAttr.getInt( 1872fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa R.styleable.MainKeyboardView_ignoreAltCodeKeyTimeout, 0); 1882fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa final int gestureRecognitionUpdateTime = mainKeyboardViewAttr.getInt( 1892fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa R.styleable.MainKeyboardView_gestureRecognitionUpdateTime, 0); 1902ad6d9cda33825fa265cd17372f115bb48f49d19Tadashi G. Takaoka mTimerHandler = new TimerHandler( 1912fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa this, ignoreAltCodeKeyTimeout, gestureRecognitionUpdateTime); 1922fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa 1932fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa final float keyHysteresisDistance = mainKeyboardViewAttr.getDimension( 1942fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa R.styleable.MainKeyboardView_keyHysteresisDistance, 0.0f); 1952fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa final float keyHysteresisDistanceForSlidingModifier = mainKeyboardViewAttr.getDimension( 1962fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa R.styleable.MainKeyboardView_keyHysteresisDistanceForSlidingModifier, 0.0f); 1972fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa mKeyDetector = new KeyDetector( 1982fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa keyHysteresisDistance, keyHysteresisDistanceForSlidingModifier); 1992fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa 2002ad6d9cda33825fa265cd17372f115bb48f49d19Tadashi G. Takaoka PointerTracker.init(mainKeyboardViewAttr, mTimerHandler, this /* DrawingProxy */); 2012fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa 20213ae76d7a342581160c172cd21706b3d57d32dadTadashi G. Takaoka final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); 20313ae76d7a342581160c172cd21706b3d57d32dadTadashi G. Takaoka final boolean forceNonDistinctMultitouch = prefs.getBoolean( 204a5ff9f0c77005769f92ca1131882bb4e3ca18980Tadashi G. Takaoka DebugSettings.PREF_FORCE_NON_DISTINCT_MULTITOUCH, false); 20513ae76d7a342581160c172cd21706b3d57d32dadTadashi G. Takaoka final boolean hasDistinctMultitouch = context.getPackageManager() 206b6cc3a85ab68cff2fae4c3858b48d9c5d7b45690Tadashi G. Takaoka .hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN_MULTITOUCH_DISTINCT) 207b6cc3a85ab68cff2fae4c3858b48d9c5d7b45690Tadashi G. Takaoka && !forceNonDistinctMultitouch; 208b6cc3a85ab68cff2fae4c3858b48d9c5d7b45690Tadashi G. Takaoka mNonDistinctMultitouchHelper = hasDistinctMultitouch ? null 209921a32f0a923ca00c4818d3869f0abd9a63dcf0eTadashi G. Takaoka : new NonDistinctMultitouchHelper(); 21022b48de11ce6f31a0edf90e1308073e67a7a2adbTadashi G. Takaoka 211f3c4cd45a5df6f90b922ea44db259e53117bb25aTadashi G. Takaoka final int backgroundDimAlpha = mainKeyboardViewAttr.getInt( 212f3c4cd45a5df6f90b922ea44db259e53117bb25aTadashi G. Takaoka R.styleable.MainKeyboardView_backgroundDimAlpha, 0); 213f3c4cd45a5df6f90b922ea44db259e53117bb25aTadashi G. Takaoka mBackgroundDimAlphaPaint.setColor(Color.BLACK); 214f3c4cd45a5df6f90b922ea44db259e53117bb25aTadashi G. Takaoka mBackgroundDimAlphaPaint.setAlpha(backgroundDimAlpha); 2152fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa mLanguageOnSpacebarTextRatio = mainKeyboardViewAttr.getFraction( 2162fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa R.styleable.MainKeyboardView_languageOnSpacebarTextRatio, 1, 1, 1.0f); 2172fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa mLanguageOnSpacebarTextColor = mainKeyboardViewAttr.getColor( 2182fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa R.styleable.MainKeyboardView_languageOnSpacebarTextColor, 0); 21941f9f1ef703ca4d63f1ef08b51d1365a17b4065aTadashi G. Takaoka mLanguageOnSpacebarTextShadowRadius = mainKeyboardViewAttr.getFloat( 22041f9f1ef703ca4d63f1ef08b51d1365a17b4065aTadashi G. Takaoka R.styleable.MainKeyboardView_languageOnSpacebarTextShadowRadius, 22141f9f1ef703ca4d63f1ef08b51d1365a17b4065aTadashi G. Takaoka LANGUAGE_ON_SPACEBAR_TEXT_SHADOW_RADIUS_DISABLED); 2222fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa mLanguageOnSpacebarTextShadowColor = mainKeyboardViewAttr.getColor( 2232fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa R.styleable.MainKeyboardView_languageOnSpacebarTextShadowColor, 0); 224d9449ccf3ce9e5eabb022aed6a45bba680bce115Tadashi G. Takaoka mLanguageOnSpacebarFinalAlpha = mainKeyboardViewAttr.getInt( 225c8e45ddb032554f4e9d4411d8ef47d98db62d77bTadashi G. Takaoka R.styleable.MainKeyboardView_languageOnSpacebarFinalAlpha, 2264daf32b6c0358f0273a99b622a259ecdf6b44fa4Tom Ouyang Constants.Color.ALPHA_OPAQUE); 227d9449ccf3ce9e5eabb022aed6a45bba680bce115Tadashi G. Takaoka final int languageOnSpacebarFadeoutAnimatorResId = mainKeyboardViewAttr.getResourceId( 228c8e45ddb032554f4e9d4411d8ef47d98db62d77bTadashi G. Takaoka R.styleable.MainKeyboardView_languageOnSpacebarFadeoutAnimator, 0); 229d9449ccf3ce9e5eabb022aed6a45bba680bce115Tadashi G. Takaoka final int altCodeKeyWhileTypingFadeoutAnimatorResId = mainKeyboardViewAttr.getResourceId( 230c8e45ddb032554f4e9d4411d8ef47d98db62d77bTadashi G. Takaoka R.styleable.MainKeyboardView_altCodeKeyWhileTypingFadeoutAnimator, 0); 231d9449ccf3ce9e5eabb022aed6a45bba680bce115Tadashi G. Takaoka final int altCodeKeyWhileTypingFadeinAnimatorResId = mainKeyboardViewAttr.getResourceId( 232c8e45ddb032554f4e9d4411d8ef47d98db62d77bTadashi G. Takaoka R.styleable.MainKeyboardView_altCodeKeyWhileTypingFadeinAnimator, 0); 233160f01211d169d64102205e80e9ac8d46c7d674bTadashi G. Takaoka 234992c5219092ccafe66363451fbf4ca7c5a43fb20Tadashi G. Takaoka mKeyPreviewDrawParams = new KeyPreviewDrawParams(mainKeyboardViewAttr); 235bb476be4e62b3bed7848d37df42f8fa7363b58d1Tadashi G. Takaoka mKeyPreviewChoreographer = new KeyPreviewChoreographer(mKeyPreviewDrawParams); 236bb476be4e62b3bed7848d37df42f8fa7363b58d1Tadashi G. Takaoka 237a729377395967f7652d93992cbcf50cd2ff522d1Tadashi G. Takaoka final int moreKeysKeyboardLayoutId = mainKeyboardViewAttr.getResourceId( 238d9449ccf3ce9e5eabb022aed6a45bba680bce115Tadashi G. Takaoka R.styleable.MainKeyboardView_moreKeysKeyboardLayout, 0); 2390f33e614c0799fa3a14a2c32db4bf0654df039daTadashi G. Takaoka final int moreKeysKeyboardForActionLayoutId = mainKeyboardViewAttr.getResourceId( 2400f33e614c0799fa3a14a2c32db4bf0654df039daTadashi G. Takaoka R.styleable.MainKeyboardView_moreKeysKeyboardForActionLayout, 2410f33e614c0799fa3a14a2c32db4bf0654df039daTadashi G. Takaoka moreKeysKeyboardLayoutId); 242d9449ccf3ce9e5eabb022aed6a45bba680bce115Tadashi G. Takaoka mConfigShowMoreKeysKeyboardAtTouchedPoint = mainKeyboardViewAttr.getBoolean( 243c8e45ddb032554f4e9d4411d8ef47d98db62d77bTadashi G. Takaoka R.styleable.MainKeyboardView_showMoreKeysKeyboardAtTouchedPoint, false); 244375982106bf073971fccd14b2c65ec8e089bb2aeTadashi G. Takaoka 245375982106bf073971fccd14b2c65ec8e089bb2aeTadashi G. Takaoka mGestureFloatingPreviewTextLingerTimeout = mainKeyboardViewAttr.getInt( 246375982106bf073971fccd14b2c65ec8e089bb2aeTadashi G. Takaoka R.styleable.MainKeyboardView_gestureFloatingPreviewTextLingerTimeout, 0); 247fb523d7f5d40123a49a9128c455815db320c90fcTadashi G. Takaoka 248cf915ddc878699909365dd599a0e154552e244e2Tadashi G. Takaoka mGestureFloatingTextDrawingPreview = new GestureFloatingTextDrawingPreview( 2497fb630b2a83983ea42108969b82ca85886e19241Tadashi G. Takaoka mainKeyboardViewAttr); 250be708c4e59ba16cf735440b99aa682baa3319ec5Tadashi G. Takaoka mGestureFloatingTextDrawingPreview.setDrawingView(drawingPreviewPlacerView); 251fb523d7f5d40123a49a9128c455815db320c90fcTadashi G. Takaoka 2527fb630b2a83983ea42108969b82ca85886e19241Tadashi G. Takaoka mGestureTrailsDrawingPreview = new GestureTrailsDrawingPreview(mainKeyboardViewAttr); 253be708c4e59ba16cf735440b99aa682baa3319ec5Tadashi G. Takaoka mGestureTrailsDrawingPreview.setDrawingView(drawingPreviewPlacerView); 254fb523d7f5d40123a49a9128c455815db320c90fcTadashi G. Takaoka 2557fb630b2a83983ea42108969b82ca85886e19241Tadashi G. Takaoka mSlidingKeyInputDrawingPreview = new SlidingKeyInputDrawingPreview(mainKeyboardViewAttr); 256be708c4e59ba16cf735440b99aa682baa3319ec5Tadashi G. Takaoka mSlidingKeyInputDrawingPreview.setDrawingView(drawingPreviewPlacerView); 257d9449ccf3ce9e5eabb022aed6a45bba680bce115Tadashi G. Takaoka mainKeyboardViewAttr.recycle(); 258160f01211d169d64102205e80e9ac8d46c7d674bTadashi G. Takaoka 259be708c4e59ba16cf735440b99aa682baa3319ec5Tadashi G. Takaoka mDrawingPreviewPlacerView = drawingPreviewPlacerView; 260be708c4e59ba16cf735440b99aa682baa3319ec5Tadashi G. Takaoka 2610f33e614c0799fa3a14a2c32db4bf0654df039daTadashi G. Takaoka final LayoutInflater inflater = LayoutInflater.from(getContext()); 2620f33e614c0799fa3a14a2c32db4bf0654df039daTadashi G. Takaoka mMoreKeysKeyboardContainer = inflater.inflate(moreKeysKeyboardLayoutId, null); 2630f33e614c0799fa3a14a2c32db4bf0654df039daTadashi G. Takaoka mMoreKeysKeyboardForActionContainer = inflater.inflate( 2640f33e614c0799fa3a14a2c32db4bf0654df039daTadashi G. Takaoka moreKeysKeyboardForActionLayoutId, null); 26531c94cea82f1788e3a04f2a1e012945f35497f0aTadashi G. Takaoka mLanguageOnSpacebarFadeoutAnimator = loadObjectAnimator( 26631c94cea82f1788e3a04f2a1e012945f35497f0aTadashi G. Takaoka languageOnSpacebarFadeoutAnimatorResId, this); 26731c94cea82f1788e3a04f2a1e012945f35497f0aTadashi G. Takaoka mAltCodeKeyWhileTypingFadeoutAnimator = loadObjectAnimator( 26831c94cea82f1788e3a04f2a1e012945f35497f0aTadashi G. Takaoka altCodeKeyWhileTypingFadeoutAnimatorResId, this); 26931c94cea82f1788e3a04f2a1e012945f35497f0aTadashi G. Takaoka mAltCodeKeyWhileTypingFadeinAnimator = loadObjectAnimator( 27031c94cea82f1788e3a04f2a1e012945f35497f0aTadashi G. Takaoka altCodeKeyWhileTypingFadeinAnimatorResId, this); 271f87e8f7ec1efb93398d909c67468d716b0248fe7Tadashi G. Takaoka 272f87e8f7ec1efb93398d909c67468d716b0248fe7Tadashi G. Takaoka mKeyboardActionListener = KeyboardActionListener.EMPTY_LISTENER; 273741831d32295acfb7675d7e0781a634d78868c63Satoshi Kataoka 2742fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa mLanguageOnSpacebarHorizontalMargin = (int)getResources().getDimension( 2752fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa R.dimen.config_language_on_spacebar_horizontal_margin); 27631c94cea82f1788e3a04f2a1e012945f35497f0aTadashi G. Takaoka } 27731c94cea82f1788e3a04f2a1e012945f35497f0aTadashi G. Takaoka 27852876bbefd774e8647910f73a2e4c17ac4e6bf5cKen Wakasa @Override 27952876bbefd774e8647910f73a2e4c17ac4e6bf5cKen Wakasa public void setHardwareAcceleratedDrawingEnabled(final boolean enabled) { 28052876bbefd774e8647910f73a2e4c17ac4e6bf5cKen Wakasa super.setHardwareAcceleratedDrawingEnabled(enabled); 281cf915ddc878699909365dd599a0e154552e244e2Tadashi G. Takaoka mDrawingPreviewPlacerView.setHardwareAcceleratedDrawingEnabled(enabled); 28252876bbefd774e8647910f73a2e4c17ac4e6bf5cKen Wakasa } 28352876bbefd774e8647910f73a2e4c17ac4e6bf5cKen Wakasa 284dc34da218a22489d92d1015e9e5dac8d951b89f4Tadashi G. Takaoka private ObjectAnimator loadObjectAnimator(final int resId, final Object target) { 28520dd1bc090abdd3e88855fe54b1865949aa1168dTadashi G. Takaoka if (resId == 0) { 28657372fd3da2e879f190e4ccd41a00813774c9019Tadashi G. Takaoka // TODO: Stop returning null. 28720dd1bc090abdd3e88855fe54b1865949aa1168dTadashi G. Takaoka return null; 28820dd1bc090abdd3e88855fe54b1865949aa1168dTadashi G. Takaoka } 28931c94cea82f1788e3a04f2a1e012945f35497f0aTadashi G. Takaoka final ObjectAnimator animator = (ObjectAnimator)AnimatorInflater.loadAnimator( 29031c94cea82f1788e3a04f2a1e012945f35497f0aTadashi G. Takaoka getContext(), resId); 291d7c4ba170982ddce5ac12ea92c3c3d8b53d524baTadashi G. Takaoka if (animator != null) { 29231c94cea82f1788e3a04f2a1e012945f35497f0aTadashi G. Takaoka animator.setTarget(target); 29373a46bfeb7a109b49be196e5d679e44c9e66a2e8Tadashi G. Takaoka } 29431c94cea82f1788e3a04f2a1e012945f35497f0aTadashi G. Takaoka return animator; 29531c94cea82f1788e3a04f2a1e012945f35497f0aTadashi G. Takaoka } 29673a46bfeb7a109b49be196e5d679e44c9e66a2e8Tadashi G. Takaoka 2972fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa private static void cancelAndStartAnimators(final ObjectAnimator animatorToCancel, 2982fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa final ObjectAnimator animatorToStart) { 2992fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa if (animatorToCancel == null || animatorToStart == null) { 3002fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa // TODO: Stop using null as a no-operation animator. 3012fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa return; 3022fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa } 3032fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa float startFraction = 0.0f; 3042fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa if (animatorToCancel.isStarted()) { 3052fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa animatorToCancel.cancel(); 3062fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa startFraction = 1.0f - animatorToCancel.getAnimatedFraction(); 3072fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa } 3082fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa final long startTime = (long)(animatorToStart.getDuration() * startFraction); 3092fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa animatorToStart.start(); 3102fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa animatorToStart.setCurrentPlayTime(startTime); 3112fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa } 3122fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa 313be708c4e59ba16cf735440b99aa682baa3319ec5Tadashi G. Takaoka // Implements {@link DrawingProxy#startWhileTypingAnimation(int)}. 314051f8b144232f724386960cf6781a6d4665e4f02Tadashi G. Takaoka /** 315051f8b144232f724386960cf6781a6d4665e4f02Tadashi G. Takaoka * Called when a while-typing-animation should be started. 316be708c4e59ba16cf735440b99aa682baa3319ec5Tadashi G. Takaoka * @param fadeInOrOut {@link DrawingProxy#FADE_IN} starts while-typing-fade-in animation. 317be708c4e59ba16cf735440b99aa682baa3319ec5Tadashi G. Takaoka * {@link DrawingProxy#FADE_OUT} starts while-typing-fade-out animation. 318051f8b144232f724386960cf6781a6d4665e4f02Tadashi G. Takaoka */ 3192fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa @Override 320051f8b144232f724386960cf6781a6d4665e4f02Tadashi G. Takaoka public void startWhileTypingAnimation(final int fadeInOrOut) { 321051f8b144232f724386960cf6781a6d4665e4f02Tadashi G. Takaoka switch (fadeInOrOut) { 322be708c4e59ba16cf735440b99aa682baa3319ec5Tadashi G. Takaoka case DrawingProxy.FADE_IN: 323051f8b144232f724386960cf6781a6d4665e4f02Tadashi G. Takaoka cancelAndStartAnimators( 324051f8b144232f724386960cf6781a6d4665e4f02Tadashi G. Takaoka mAltCodeKeyWhileTypingFadeoutAnimator, mAltCodeKeyWhileTypingFadeinAnimator); 325051f8b144232f724386960cf6781a6d4665e4f02Tadashi G. Takaoka break; 326be708c4e59ba16cf735440b99aa682baa3319ec5Tadashi G. Takaoka case DrawingProxy.FADE_OUT: 327051f8b144232f724386960cf6781a6d4665e4f02Tadashi G. Takaoka cancelAndStartAnimators( 328051f8b144232f724386960cf6781a6d4665e4f02Tadashi G. Takaoka mAltCodeKeyWhileTypingFadeinAnimator, mAltCodeKeyWhileTypingFadeoutAnimator); 329051f8b144232f724386960cf6781a6d4665e4f02Tadashi G. Takaoka break; 330051f8b144232f724386960cf6781a6d4665e4f02Tadashi G. Takaoka } 3312fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa } 3322fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa 33315f6d4ae34664ea3d92827a2c3003198c0bac70bTadashi G. Takaoka @ExternallyReferenced 33431c94cea82f1788e3a04f2a1e012945f35497f0aTadashi G. Takaoka public int getLanguageOnSpacebarAnimAlpha() { 33531c94cea82f1788e3a04f2a1e012945f35497f0aTadashi G. Takaoka return mLanguageOnSpacebarAnimAlpha; 336d7c4ba170982ddce5ac12ea92c3c3d8b53d524baTadashi G. Takaoka } 337d7c4ba170982ddce5ac12ea92c3c3d8b53d524baTadashi G. Takaoka 33815f6d4ae34664ea3d92827a2c3003198c0bac70bTadashi G. Takaoka @ExternallyReferenced 339dc34da218a22489d92d1015e9e5dac8d951b89f4Tadashi G. Takaoka public void setLanguageOnSpacebarAnimAlpha(final int alpha) { 34031c94cea82f1788e3a04f2a1e012945f35497f0aTadashi G. Takaoka mLanguageOnSpacebarAnimAlpha = alpha; 34131c94cea82f1788e3a04f2a1e012945f35497f0aTadashi G. Takaoka invalidateKey(mSpaceKey); 34231c94cea82f1788e3a04f2a1e012945f35497f0aTadashi G. Takaoka } 34331c94cea82f1788e3a04f2a1e012945f35497f0aTadashi G. Takaoka 34415f6d4ae34664ea3d92827a2c3003198c0bac70bTadashi G. Takaoka @ExternallyReferenced 34531c94cea82f1788e3a04f2a1e012945f35497f0aTadashi G. Takaoka public int getAltCodeKeyWhileTypingAnimAlpha() { 34631c94cea82f1788e3a04f2a1e012945f35497f0aTadashi G. Takaoka return mAltCodeKeyWhileTypingAnimAlpha; 34731c94cea82f1788e3a04f2a1e012945f35497f0aTadashi G. Takaoka } 34831c94cea82f1788e3a04f2a1e012945f35497f0aTadashi G. Takaoka 34915f6d4ae34664ea3d92827a2c3003198c0bac70bTadashi G. Takaoka @ExternallyReferenced 350dc34da218a22489d92d1015e9e5dac8d951b89f4Tadashi G. Takaoka public void setAltCodeKeyWhileTypingAnimAlpha(final int alpha) { 3515141f04ef3b213fbe4816168d1c42f30449fc446Tadashi G. Takaoka if (mAltCodeKeyWhileTypingAnimAlpha == alpha) { 3525141f04ef3b213fbe4816168d1c42f30449fc446Tadashi G. Takaoka return; 3535141f04ef3b213fbe4816168d1c42f30449fc446Tadashi G. Takaoka } 3545141f04ef3b213fbe4816168d1c42f30449fc446Tadashi G. Takaoka // Update the visual of alt-code-key-while-typing. 35531c94cea82f1788e3a04f2a1e012945f35497f0aTadashi G. Takaoka mAltCodeKeyWhileTypingAnimAlpha = alpha; 3565141f04ef3b213fbe4816168d1c42f30449fc446Tadashi G. Takaoka final Keyboard keyboard = getKeyboard(); 3575141f04ef3b213fbe4816168d1c42f30449fc446Tadashi G. Takaoka if (keyboard == null) { 3585141f04ef3b213fbe4816168d1c42f30449fc446Tadashi G. Takaoka return; 3595141f04ef3b213fbe4816168d1c42f30449fc446Tadashi G. Takaoka } 3605141f04ef3b213fbe4816168d1c42f30449fc446Tadashi G. Takaoka for (final Key key : keyboard.mAltCodeKeysWhileTyping) { 3615141f04ef3b213fbe4816168d1c42f30449fc446Tadashi G. Takaoka invalidateKey(key); 3625141f04ef3b213fbe4816168d1c42f30449fc446Tadashi G. Takaoka } 3635f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka } 3645f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka 365dc34da218a22489d92d1015e9e5dac8d951b89f4Tadashi G. Takaoka public void setKeyboardActionListener(final KeyboardActionListener listener) { 3665f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka mKeyboardActionListener = listener; 3675c73ed628b22fdfa59585803ee86e383c579a7d4Tadashi G. Takaoka PointerTracker.setKeyboardActionListener(listener); 3685f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka } 3695f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka 3702fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa // TODO: We should reconsider which coordinate system should be used to represent keyboard 3712fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa // event. 3722fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa public int getKeyX(final int x) { 3732fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa return Constants.isValidCoordinate(x) ? mKeyDetector.getTouchX(x) : x; 3745f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka } 3755f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka 3762fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa // TODO: We should reconsider which coordinate system should be used to represent keyboard 3772fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa // event. 3782fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa public int getKeyY(final int y) { 3792fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa return Constants.isValidCoordinate(y) ? mKeyDetector.getTouchY(y) : y; 3800efe174ea43fe576683102effbaef5be27575706Tadashi G. Takaoka } 3810efe174ea43fe576683102effbaef5be27575706Tadashi G. Takaoka 3825f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka /** 3835f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka * Attaches a keyboard to this view. The keyboard can be switched at any time and the 3845f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka * view will re-layout itself to accommodate the keyboard. 3855f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka * @see Keyboard 3865f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka * @see #getKeyboard() 3875f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka * @param keyboard the keyboard to display in this view 3885f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka */ 3895f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka @Override 390dc34da218a22489d92d1015e9e5dac8d951b89f4Tadashi G. Takaoka public void setKeyboard(final Keyboard keyboard) { 3915cbda70956af14453fca7395d892c59aabbd8fd3Jean Chalard // Remove any pending messages, except dismissing preview and key repeat. 3922ad6d9cda33825fa265cd17372f115bb48f49d19Tadashi G. Takaoka mTimerHandler.cancelLongPressTimers(); 3935f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka super.setKeyboard(keyboard); 3945a7a696aff6718d4e0250c394a9d01cbf2a16916Tadashi G. Takaoka mKeyDetector.setKeyboard( 39508ae0d5ca03ed455827e82222df249d1cafb5d71Tadashi G. Takaoka keyboard, -getPaddingLeft(), -getPaddingTop() + getVerticalCorrection()); 3968335c59ea7715f3dbc6625f128a7a038f314a89fTadashi G. Takaoka PointerTracker.setKeyDetector(mKeyDetector); 397a729377395967f7652d93992cbcf50cd2ff522d1Tadashi G. Takaoka mMoreKeysKeyboardCache.clear(); 3984112dc05002d7a880e558418639cf25c4bd02a5aTadashi G. Takaoka 399240871ecafde7834ebb4270cd7758fc904a5f3a7Tadashi G. Takaoka mSpaceKey = keyboard.getKey(Constants.CODE_SPACE); 4004112dc05002d7a880e558418639cf25c4bd02a5aTadashi G. Takaoka final int keyHeight = keyboard.mMostCommonKeyHeight - keyboard.mVerticalGap; 4012fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa mLanguageOnSpacebarTextSize = keyHeight * mLanguageOnSpacebarTextRatio; 402f147794fd41491a3383e6aca6d49007f58124068alanv 403d78b586976af9b6b8f6e00c04747facfac313abcTadashi G. Takaoka if (AccessibilityUtils.getInstance().isAccessibilityEnabled()) { 404dec599d1723f4ff52f066bd2dd1a4457d30cd33cTadashi G. Takaoka if (mAccessibilityDelegate == null) { 405dec599d1723f4ff52f066bd2dd1a4457d30cd33cTadashi G. Takaoka mAccessibilityDelegate = new MainKeyboardAccessibilityDelegate(this, mKeyDetector); 406dec599d1723f4ff52f066bd2dd1a4457d30cd33cTadashi G. Takaoka } 407ae0fab9550f1d9159d819dbb0b7cc86c2bf2937cTadashi G. Takaoka mAccessibilityDelegate.setKeyboard(keyboard); 408d78b586976af9b6b8f6e00c04747facfac313abcTadashi G. Takaoka } else { 409ae0fab9550f1d9159d819dbb0b7cc86c2bf2937cTadashi G. Takaoka mAccessibilityDelegate = null; 410d78b586976af9b6b8f6e00c04747facfac313abcTadashi G. Takaoka } 4115f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka } 4125f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka 4130e4f0da449d0fc4f0c4c6b49b4c24961da36a5d1Tadashi G. Takaoka /** 414ac88f3d8459e17236654aa38debea749ecb631d1Tadashi G. Takaoka * Enables or disables the key preview popup. This is a popup that shows a magnified 4150e4f0da449d0fc4f0c4c6b49b4c24961da36a5d1Tadashi G. Takaoka * version of the depressed key. By default the preview is enabled. 4160e4f0da449d0fc4f0c4c6b49b4c24961da36a5d1Tadashi G. Takaoka * @param previewEnabled whether or not to enable the key feedback preview 4170e4f0da449d0fc4f0c4c6b49b4c24961da36a5d1Tadashi G. Takaoka * @param delay the delay after which the preview is dismissed 4180e4f0da449d0fc4f0c4c6b49b4c24961da36a5d1Tadashi G. Takaoka */ 4190e4f0da449d0fc4f0c4c6b49b4c24961da36a5d1Tadashi G. Takaoka public void setKeyPreviewPopupEnabled(final boolean previewEnabled, final int delay) { 4207d09b5681202d3df9df1d5634071091f3f45fbe5Tadashi G. Takaoka mKeyPreviewDrawParams.setPopupEnabled(previewEnabled, delay); 4210e4f0da449d0fc4f0c4c6b49b4c24961da36a5d1Tadashi G. Takaoka } 4220e4f0da449d0fc4f0c4c6b49b4c24961da36a5d1Tadashi G. Takaoka 423ac88f3d8459e17236654aa38debea749ecb631d1Tadashi G. Takaoka /** 424ac88f3d8459e17236654aa38debea749ecb631d1Tadashi G. Takaoka * Enables or disables the key preview popup animations and set animations' parameters. 425ac88f3d8459e17236654aa38debea749ecb631d1Tadashi G. Takaoka * 426ac88f3d8459e17236654aa38debea749ecb631d1Tadashi G. Takaoka * @param hasCustomAnimationParams false to use the default key preview popup animations 427ac88f3d8459e17236654aa38debea749ecb631d1Tadashi G. Takaoka * specified by keyPreviewShowUpAnimator and keyPreviewDismissAnimator attributes. 428ac88f3d8459e17236654aa38debea749ecb631d1Tadashi G. Takaoka * true to override the default animations with the specified parameters. 429ac88f3d8459e17236654aa38debea749ecb631d1Tadashi G. Takaoka * @param showUpStartXScale from this x-scale the show up animation will start. 430ac88f3d8459e17236654aa38debea749ecb631d1Tadashi G. Takaoka * @param showUpStartYScale from this y-scale the show up animation will start. 431ac88f3d8459e17236654aa38debea749ecb631d1Tadashi G. Takaoka * @param showUpDuration the duration of the show up animation in milliseconds. 432ac88f3d8459e17236654aa38debea749ecb631d1Tadashi G. Takaoka * @param dismissEndXScale to this x-scale the dismiss animation will end. 433ac88f3d8459e17236654aa38debea749ecb631d1Tadashi G. Takaoka * @param dismissEndYScale to this y-scale the dismiss animation will end. 434ac88f3d8459e17236654aa38debea749ecb631d1Tadashi G. Takaoka * @param dismissDuration the duration of the dismiss animation in milliseconds. 435ac88f3d8459e17236654aa38debea749ecb631d1Tadashi G. Takaoka */ 436ac88f3d8459e17236654aa38debea749ecb631d1Tadashi G. Takaoka public void setKeyPreviewAnimationParams(final boolean hasCustomAnimationParams, 437ac88f3d8459e17236654aa38debea749ecb631d1Tadashi G. Takaoka final float showUpStartXScale, final float showUpStartYScale, final int showUpDuration, 438ac88f3d8459e17236654aa38debea749ecb631d1Tadashi G. Takaoka final float dismissEndXScale, final float dismissEndYScale, final int dismissDuration) { 439ac88f3d8459e17236654aa38debea749ecb631d1Tadashi G. Takaoka mKeyPreviewDrawParams.setAnimationParams(hasCustomAnimationParams, 440ac88f3d8459e17236654aa38debea749ecb631d1Tadashi G. Takaoka showUpStartXScale, showUpStartYScale, showUpDuration, 441ac88f3d8459e17236654aa38debea749ecb631d1Tadashi G. Takaoka dismissEndXScale, dismissEndYScale, dismissDuration); 442276b1a2ebc6d5ea3fa36fa9271cdc6310db34021Tadashi G. Takaoka } 443276b1a2ebc6d5ea3fa36fa9271cdc6310db34021Tadashi G. Takaoka 444375982106bf073971fccd14b2c65ec8e089bb2aeTadashi G. Takaoka private void locatePreviewPlacerView() { 445375982106bf073971fccd14b2c65ec8e089bb2aeTadashi G. Takaoka getLocationInWindow(mOriginCoords); 4460c01fc6f1c01a2009546a2982818e68c08012ab3Tadashi G. Takaoka mDrawingPreviewPlacerView.setKeyboardViewGeometry(mOriginCoords, getWidth(), getHeight()); 4470c01fc6f1c01a2009546a2982818e68c08012ab3Tadashi G. Takaoka } 4480c01fc6f1c01a2009546a2982818e68c08012ab3Tadashi G. Takaoka 4490c01fc6f1c01a2009546a2982818e68c08012ab3Tadashi G. Takaoka private void installPreviewPlacerView() { 450375982106bf073971fccd14b2c65ec8e089bb2aeTadashi G. Takaoka final View rootView = getRootView(); 451375982106bf073971fccd14b2c65ec8e089bb2aeTadashi G. Takaoka if (rootView == null) { 452375982106bf073971fccd14b2c65ec8e089bb2aeTadashi G. Takaoka Log.w(TAG, "Cannot find root view"); 453375982106bf073971fccd14b2c65ec8e089bb2aeTadashi G. Takaoka return; 454375982106bf073971fccd14b2c65ec8e089bb2aeTadashi G. Takaoka } 455375982106bf073971fccd14b2c65ec8e089bb2aeTadashi G. Takaoka final ViewGroup windowContentView = (ViewGroup)rootView.findViewById(android.R.id.content); 456375982106bf073971fccd14b2c65ec8e089bb2aeTadashi G. Takaoka // Note: It'd be very weird if we get null by android.R.id.content. 457375982106bf073971fccd14b2c65ec8e089bb2aeTadashi G. Takaoka if (windowContentView == null) { 458cf915ddc878699909365dd599a0e154552e244e2Tadashi G. Takaoka Log.w(TAG, "Cannot find android.R.id.content view to add DrawingPreviewPlacerView"); 4590c01fc6f1c01a2009546a2982818e68c08012ab3Tadashi G. Takaoka return; 460375982106bf073971fccd14b2c65ec8e089bb2aeTadashi G. Takaoka } 4610c01fc6f1c01a2009546a2982818e68c08012ab3Tadashi G. Takaoka windowContentView.addView(mDrawingPreviewPlacerView); 462375982106bf073971fccd14b2c65ec8e089bb2aeTadashi G. Takaoka } 463375982106bf073971fccd14b2c65ec8e089bb2aeTadashi G. Takaoka 46453b6d627e7fe66ce47ee6ae01254abc070558e77Tadashi G. Takaoka // Implements {@link DrawingProxy#onKeyPressed(Key,boolean)}. 4650e4f0da449d0fc4f0c4c6b49b4c24961da36a5d1Tadashi G. Takaoka @Override 46653b6d627e7fe66ce47ee6ae01254abc070558e77Tadashi G. Takaoka public void onKeyPressed(@Nonnull final Key key, final boolean withPreview) { 46753b6d627e7fe66ce47ee6ae01254abc070558e77Tadashi G. Takaoka key.onPressed(); 46853b6d627e7fe66ce47ee6ae01254abc070558e77Tadashi G. Takaoka invalidateKey(key); 46953b6d627e7fe66ce47ee6ae01254abc070558e77Tadashi G. Takaoka if (withPreview && !key.noKeyPreview()) { 47053b6d627e7fe66ce47ee6ae01254abc070558e77Tadashi G. Takaoka showKeyPreview(key); 4710e4f0da449d0fc4f0c4c6b49b4c24961da36a5d1Tadashi G. Takaoka } 47253b6d627e7fe66ce47ee6ae01254abc070558e77Tadashi G. Takaoka } 47353b6d627e7fe66ce47ee6ae01254abc070558e77Tadashi G. Takaoka 47453b6d627e7fe66ce47ee6ae01254abc070558e77Tadashi G. Takaoka private void showKeyPreview(@Nonnull final Key key) { 4752fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa final Keyboard keyboard = getKeyboard(); 476a68e0dd437daa1387edc65082f96a00ca258a7b0Tadashi G. Takaoka if (keyboard == null) { 477a68e0dd437daa1387edc65082f96a00ca258a7b0Tadashi G. Takaoka return; 478a68e0dd437daa1387edc65082f96a00ca258a7b0Tadashi G. Takaoka } 479a68e0dd437daa1387edc65082f96a00ca258a7b0Tadashi G. Takaoka final KeyPreviewDrawParams previewParams = mKeyPreviewDrawParams; 4807d09b5681202d3df9df1d5634071091f3f45fbe5Tadashi G. Takaoka if (!previewParams.isPopupEnabled()) { 481992c5219092ccafe66363451fbf4ca7c5a43fb20Tadashi G. Takaoka previewParams.setVisibleOffset(-keyboard.mVerticalGap); 4822fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa return; 4832fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa } 4842fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa 485bb476be4e62b3bed7848d37df42f8fa7363b58d1Tadashi G. Takaoka locatePreviewPlacerView(); 4860e4f0da449d0fc4f0c4c6b49b4c24961da36a5d1Tadashi G. Takaoka getLocationInWindow(mOriginCoords); 4879d5d01a54319797db17fa8ac4b612f8836c83b9aTadashi G. Takaoka mKeyPreviewChoreographer.placeAndShowKeyPreview(key, keyboard.mIconsSet, getKeyDrawParams(), 4883ff72dd0daa9baaeb4d6b8ade59d65c1f0e8b34fTadashi G. Takaoka getWidth(), mOriginCoords, mDrawingPreviewPlacerView, isHardwareAccelerated()); 4892fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa } 4902fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa 49153b6d627e7fe66ce47ee6ae01254abc070558e77Tadashi G. Takaoka private void dismissKeyPreviewWithoutDelay(@Nonnull final Key key) { 492bb476be4e62b3bed7848d37df42f8fa7363b58d1Tadashi G. Takaoka mKeyPreviewChoreographer.dismissKeyPreview(key, false /* withAnimation */); 4932fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa invalidateKey(key); 4942fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa } 4952fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa 49653b6d627e7fe66ce47ee6ae01254abc070558e77Tadashi G. Takaoka // Implements {@link DrawingProxy#onKeyReleased(Key,boolean)}. 4972fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa @Override 49853b6d627e7fe66ce47ee6ae01254abc070558e77Tadashi G. Takaoka public void onKeyReleased(@Nonnull final Key key, final boolean withAnimation) { 49953b6d627e7fe66ce47ee6ae01254abc070558e77Tadashi G. Takaoka key.onReleased(); 50053b6d627e7fe66ce47ee6ae01254abc070558e77Tadashi G. Takaoka invalidateKey(key); 50153b6d627e7fe66ce47ee6ae01254abc070558e77Tadashi G. Takaoka if (!key.noKeyPreview()) { 50253b6d627e7fe66ce47ee6ae01254abc070558e77Tadashi G. Takaoka if (withAnimation) { 50353b6d627e7fe66ce47ee6ae01254abc070558e77Tadashi G. Takaoka dismissKeyPreview(key); 50453b6d627e7fe66ce47ee6ae01254abc070558e77Tadashi G. Takaoka } else { 50553b6d627e7fe66ce47ee6ae01254abc070558e77Tadashi G. Takaoka dismissKeyPreviewWithoutDelay(key); 50653b6d627e7fe66ce47ee6ae01254abc070558e77Tadashi G. Takaoka } 50753b6d627e7fe66ce47ee6ae01254abc070558e77Tadashi G. Takaoka } 50853b6d627e7fe66ce47ee6ae01254abc070558e77Tadashi G. Takaoka } 50953b6d627e7fe66ce47ee6ae01254abc070558e77Tadashi G. Takaoka 51053b6d627e7fe66ce47ee6ae01254abc070558e77Tadashi G. Takaoka private void dismissKeyPreview(@Nonnull final Key key) { 5112ad6d9cda33825fa265cd17372f115bb48f49d19Tadashi G. Takaoka if (isHardwareAccelerated()) { 512d2c00f550d6b4f2452fe38cee7c1d2222a4b4b3dTadashi G. Takaoka mKeyPreviewChoreographer.dismissKeyPreview(key, true /* withAnimation */); 513d2c00f550d6b4f2452fe38cee7c1d2222a4b4b3dTadashi G. Takaoka return; 5142fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa } 5152ad6d9cda33825fa265cd17372f115bb48f49d19Tadashi G. Takaoka // TODO: Implement preference option to control key preview method and duration. 5162ad6d9cda33825fa265cd17372f115bb48f49d19Tadashi G. Takaoka mTimerHandler.postDismissKeyPreview(key, mKeyPreviewDrawParams.getLingerTimeout()); 5170e4f0da449d0fc4f0c4c6b49b4c24961da36a5d1Tadashi G. Takaoka } 5180e4f0da449d0fc4f0c4c6b49b4c24961da36a5d1Tadashi G. Takaoka 519ff961ddf8c58df569c97684bfd83a01b2a9470aaTadashi G. Takaoka public void setSlidingKeyInputPreviewEnabled(final boolean enabled) { 520cf915ddc878699909365dd599a0e154552e244e2Tadashi G. Takaoka mSlidingKeyInputDrawingPreview.setPreviewEnabled(enabled); 521ff961ddf8c58df569c97684bfd83a01b2a9470aaTadashi G. Takaoka } 522ff961ddf8c58df569c97684bfd83a01b2a9470aaTadashi G. Takaoka 5230e4f0da449d0fc4f0c4c6b49b4c24961da36a5d1Tadashi G. Takaoka @Override 524be708c4e59ba16cf735440b99aa682baa3319ec5Tadashi G. Takaoka public void showSlidingKeyInputPreview(@Nullable final PointerTracker tracker) { 5250e4f0da449d0fc4f0c4c6b49b4c24961da36a5d1Tadashi G. Takaoka locatePreviewPlacerView(); 526051f8b144232f724386960cf6781a6d4665e4f02Tadashi G. Takaoka if (tracker != null) { 527051f8b144232f724386960cf6781a6d4665e4f02Tadashi G. Takaoka mSlidingKeyInputDrawingPreview.setPreviewPosition(tracker); 528051f8b144232f724386960cf6781a6d4665e4f02Tadashi G. Takaoka } else { 529051f8b144232f724386960cf6781a6d4665e4f02Tadashi G. Takaoka mSlidingKeyInputDrawingPreview.dismissSlidingKeyInputPreview(); 530051f8b144232f724386960cf6781a6d4665e4f02Tadashi G. Takaoka } 5310e4f0da449d0fc4f0c4c6b49b4c24961da36a5d1Tadashi G. Takaoka } 5320e4f0da449d0fc4f0c4c6b49b4c24961da36a5d1Tadashi G. Takaoka 533724db044957eb3544323c9814cbb4f20e81b8594Ken Wakasa private void setGesturePreviewMode(final boolean isGestureTrailEnabled, 534724db044957eb3544323c9814cbb4f20e81b8594Ken Wakasa final boolean isGestureFloatingPreviewTextEnabled) { 535cf915ddc878699909365dd599a0e154552e244e2Tadashi G. Takaoka mGestureFloatingTextDrawingPreview.setPreviewEnabled(isGestureFloatingPreviewTextEnabled); 536cf915ddc878699909365dd599a0e154552e244e2Tadashi G. Takaoka mGestureTrailsDrawingPreview.setPreviewEnabled(isGestureTrailEnabled); 537375982106bf073971fccd14b2c65ec8e089bb2aeTadashi G. Takaoka } 538375982106bf073971fccd14b2c65ec8e089bb2aeTadashi G. Takaoka 5392ad6d9cda33825fa265cd17372f115bb48f49d19Tadashi G. Takaoka public void showGestureFloatingPreviewText(@Nonnull final SuggestedWords suggestedWords, 5402ad6d9cda33825fa265cd17372f115bb48f49d19Tadashi G. Takaoka final boolean dismissDelayed) { 541375982106bf073971fccd14b2c65ec8e089bb2aeTadashi G. Takaoka locatePreviewPlacerView(); 5422ad6d9cda33825fa265cd17372f115bb48f49d19Tadashi G. Takaoka final GestureFloatingTextDrawingPreview gestureFloatingTextDrawingPreview = 5432ad6d9cda33825fa265cd17372f115bb48f49d19Tadashi G. Takaoka mGestureFloatingTextDrawingPreview; 5442ad6d9cda33825fa265cd17372f115bb48f49d19Tadashi G. Takaoka gestureFloatingTextDrawingPreview.setSuggetedWords(suggestedWords); 5452ad6d9cda33825fa265cd17372f115bb48f49d19Tadashi G. Takaoka if (dismissDelayed) { 5462ad6d9cda33825fa265cd17372f115bb48f49d19Tadashi G. Takaoka mTimerHandler.postDismissGestureFloatingPreviewText( 5472ad6d9cda33825fa265cd17372f115bb48f49d19Tadashi G. Takaoka mGestureFloatingPreviewTextLingerTimeout); 5482ad6d9cda33825fa265cd17372f115bb48f49d19Tadashi G. Takaoka } 549375982106bf073971fccd14b2c65ec8e089bb2aeTadashi G. Takaoka } 550375982106bf073971fccd14b2c65ec8e089bb2aeTadashi G. Takaoka 551be708c4e59ba16cf735440b99aa682baa3319ec5Tadashi G. Takaoka // Implements {@link DrawingProxy#dismissGestureFloatingPreviewTextWithoutDelay()}. 5522ad6d9cda33825fa265cd17372f115bb48f49d19Tadashi G. Takaoka @Override 5532ad6d9cda33825fa265cd17372f115bb48f49d19Tadashi G. Takaoka public void dismissGestureFloatingPreviewTextWithoutDelay() { 5542ad6d9cda33825fa265cd17372f115bb48f49d19Tadashi G. Takaoka mGestureFloatingTextDrawingPreview.dismissGestureFloatingPreviewText(); 555375982106bf073971fccd14b2c65ec8e089bb2aeTadashi G. Takaoka } 556375982106bf073971fccd14b2c65ec8e089bb2aeTadashi G. Takaoka 557fb523d7f5d40123a49a9128c455815db320c90fcTadashi G. Takaoka @Override 558be708c4e59ba16cf735440b99aa682baa3319ec5Tadashi G. Takaoka public void showGestureTrail(@Nonnull final PointerTracker tracker, 559212165b0b8308802a461a6a526d367ba67b5567aTadashi G. Takaoka final boolean showsFloatingPreviewText) { 560375982106bf073971fccd14b2c65ec8e089bb2aeTadashi G. Takaoka locatePreviewPlacerView(); 561212165b0b8308802a461a6a526d367ba67b5567aTadashi G. Takaoka if (showsFloatingPreviewText) { 562cf915ddc878699909365dd599a0e154552e244e2Tadashi G. Takaoka mGestureFloatingTextDrawingPreview.setPreviewPosition(tracker); 563212165b0b8308802a461a6a526d367ba67b5567aTadashi G. Takaoka } 564cf915ddc878699909365dd599a0e154552e244e2Tadashi G. Takaoka mGestureTrailsDrawingPreview.setPreviewPosition(tracker); 565375982106bf073971fccd14b2c65ec8e089bb2aeTadashi G. Takaoka } 566375982106bf073971fccd14b2c65ec8e089bb2aeTadashi G. Takaoka 5678335c59ea7715f3dbc6625f128a7a038f314a89fTadashi G. Takaoka // Note that this method is called from a non-UI thread. 568c1e6100bdea95872cb66a64b7ee14ab0ae46476fTadashi G. Takaoka @SuppressWarnings("static-method") 569dc34da218a22489d92d1015e9e5dac8d951b89f4Tadashi G. Takaoka public void setMainDictionaryAvailability(final boolean mainDictionaryAvailable) { 5708335c59ea7715f3dbc6625f128a7a038f314a89fTadashi G. Takaoka PointerTracker.setMainDictionaryAvailability(mainDictionaryAvailable); 5718335c59ea7715f3dbc6625f128a7a038f314a89fTadashi G. Takaoka } 5728335c59ea7715f3dbc6625f128a7a038f314a89fTadashi G. Takaoka 573724db044957eb3544323c9814cbb4f20e81b8594Ken Wakasa public void setGestureHandlingEnabledByUser(final boolean isGestureHandlingEnabledByUser, 574724db044957eb3544323c9814cbb4f20e81b8594Ken Wakasa final boolean isGestureTrailEnabled, 575724db044957eb3544323c9814cbb4f20e81b8594Ken Wakasa final boolean isGestureFloatingPreviewTextEnabled) { 576724db044957eb3544323c9814cbb4f20e81b8594Ken Wakasa PointerTracker.setGestureHandlingEnabledByUser(isGestureHandlingEnabledByUser); 577724db044957eb3544323c9814cbb4f20e81b8594Ken Wakasa setGesturePreviewMode(isGestureHandlingEnabledByUser && isGestureTrailEnabled, 578724db044957eb3544323c9814cbb4f20e81b8594Ken Wakasa isGestureHandlingEnabledByUser && isGestureFloatingPreviewTextEnabled); 5790657b9698a110f8e895448d829478982ce37b6d1Tadashi G. Takaoka } 5800657b9698a110f8e895448d829478982ce37b6d1Tadashi G. Takaoka 5815f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka @Override 5824331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge protected void onAttachedToWindow() { 5834331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge super.onAttachedToWindow(); 5840c01fc6f1c01a2009546a2982818e68c08012ab3Tadashi G. Takaoka installPreviewPlacerView(); 585c3f78c9057a5710898feaf8027659484477e5821Tadashi G. Takaoka } 586c3f78c9057a5710898feaf8027659484477e5821Tadashi G. Takaoka 587c3f78c9057a5710898feaf8027659484477e5821Tadashi G. Takaoka @Override 588c3f78c9057a5710898feaf8027659484477e5821Tadashi G. Takaoka protected void onDetachedFromWindow() { 589c3f78c9057a5710898feaf8027659484477e5821Tadashi G. Takaoka super.onDetachedFromWindow(); 590cf915ddc878699909365dd599a0e154552e244e2Tadashi G. Takaoka mDrawingPreviewPlacerView.removeAllViews(); 5914331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge } 5924331012a9e7779ff7c8359a443dc5815ee6ea8d9Kurt Partridge 59353b6d627e7fe66ce47ee6ae01254abc070558e77Tadashi G. Takaoka // Implements {@link DrawingProxy@showMoreKeysKeyboard(Key,PointerTracker)}. 59453b6d627e7fe66ce47ee6ae01254abc070558e77Tadashi G. Takaoka @Override 59553b6d627e7fe66ce47ee6ae01254abc070558e77Tadashi G. Takaoka @Nullable 59653b6d627e7fe66ce47ee6ae01254abc070558e77Tadashi G. Takaoka public MoreKeysPanel showMoreKeysKeyboard(@Nonnull final Key key, 59753b6d627e7fe66ce47ee6ae01254abc070558e77Tadashi G. Takaoka @Nonnull final PointerTracker tracker) { 59803288ef47fd93758b5665e19fe9b892ece6e586fTadashi G. Takaoka final MoreKeySpec[] moreKeys = key.getMoreKeys(); 59903288ef47fd93758b5665e19fe9b892ece6e586fTadashi G. Takaoka if (moreKeys == null) { 6005f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka return null; 60120dd1bc090abdd3e88855fe54b1865949aa1168dTadashi G. Takaoka } 602a729377395967f7652d93992cbcf50cd2ff522d1Tadashi G. Takaoka Keyboard moreKeysKeyboard = mMoreKeysKeyboardCache.get(key); 603a729377395967f7652d93992cbcf50cd2ff522d1Tadashi G. Takaoka if (moreKeysKeyboard == null) { 60403288ef47fd93758b5665e19fe9b892ece6e586fTadashi G. Takaoka // {@link KeyPreviewDrawParams#mPreviewVisibleWidth} should have been set at 60503288ef47fd93758b5665e19fe9b892ece6e586fTadashi G. Takaoka // {@link KeyPreviewChoreographer#placeKeyPreview(Key,TextView,KeyboardIconsSet,KeyDrawParams,int,int[]}, 60603288ef47fd93758b5665e19fe9b892ece6e586fTadashi G. Takaoka // though there may be some chances that the value is zero. <code>width == 0</code> 60703288ef47fd93758b5665e19fe9b892ece6e586fTadashi G. Takaoka // will cause zero-division error at 60803288ef47fd93758b5665e19fe9b892ece6e586fTadashi G. Takaoka // {@link MoreKeysKeyboardParams#setParameters(int,int,int,int,int,int,boolean,int)}. 60984405d2a6815a99992849e821e073835f2d892e3Tadashi G. Takaoka final boolean isSingleMoreKeyWithPreview = mKeyPreviewDrawParams.isPopupEnabled() 61003288ef47fd93758b5665e19fe9b892ece6e586fTadashi G. Takaoka && !key.noKeyPreview() && moreKeys.length == 1 61103288ef47fd93758b5665e19fe9b892ece6e586fTadashi G. Takaoka && mKeyPreviewDrawParams.getVisibleWidth() > 0; 61203288ef47fd93758b5665e19fe9b892ece6e586fTadashi G. Takaoka final MoreKeysKeyboard.Builder builder = new MoreKeysKeyboard.Builder( 61353b6d627e7fe66ce47ee6ae01254abc070558e77Tadashi G. Takaoka getContext(), key, getKeyboard(), isSingleMoreKeyWithPreview, 61403288ef47fd93758b5665e19fe9b892ece6e586fTadashi G. Takaoka mKeyPreviewDrawParams.getVisibleWidth(), 61503288ef47fd93758b5665e19fe9b892ece6e586fTadashi G. Takaoka mKeyPreviewDrawParams.getVisibleHeight(), newLabelPaint(key)); 61603288ef47fd93758b5665e19fe9b892ece6e586fTadashi G. Takaoka moreKeysKeyboard = builder.build(); 617a729377395967f7652d93992cbcf50cd2ff522d1Tadashi G. Takaoka mMoreKeysKeyboardCache.put(key, moreKeysKeyboard); 61820dd1bc090abdd3e88855fe54b1865949aa1168dTadashi G. Takaoka } 6195f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka 6200f33e614c0799fa3a14a2c32db4bf0654df039daTadashi G. Takaoka final View container = key.isActionKey() ? mMoreKeysKeyboardForActionContainer 6210f33e614c0799fa3a14a2c32db4bf0654df039daTadashi G. Takaoka : mMoreKeysKeyboardContainer; 6222affaf91a04d63e0994102299816014a8bbe11e1Tadashi G. Takaoka final MoreKeysKeyboardView moreKeysKeyboardView = 6232affaf91a04d63e0994102299816014a8bbe11e1Tadashi G. Takaoka (MoreKeysKeyboardView)container.findViewById(R.id.more_keys_keyboard_view); 6242affaf91a04d63e0994102299816014a8bbe11e1Tadashi G. Takaoka moreKeysKeyboardView.setKeyboard(moreKeysKeyboard); 625b8dc67466339dc14653ad634c86851025373326bTadashi G. Takaoka container.measure(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); 62663c233ab9f50d844be6e52e382c6664475606760Tadashi G. Takaoka 627547b638194c05f971003edb06c3c6c489a76da5fTadashi G. Takaoka final int[] lastCoords = CoordinateUtils.newInstance(); 628547b638194c05f971003edb06c3c6c489a76da5fTadashi G. Takaoka tracker.getLastCoordinates(lastCoords); 62903288ef47fd93758b5665e19fe9b892ece6e586fTadashi G. Takaoka final boolean keyPreviewEnabled = mKeyPreviewDrawParams.isPopupEnabled() 63003288ef47fd93758b5665e19fe9b892ece6e586fTadashi G. Takaoka && !key.noKeyPreview(); 6317ecc1081ab9b4e41e4b2aec7877aaaf8df29e611Tadashi G. Takaoka // The more keys keyboard is usually horizontally aligned with the center of the parent key. 6327ecc1081ab9b4e41e4b2aec7877aaaf8df29e611Tadashi G. Takaoka // If showMoreKeysKeyboardAtTouchedPoint is true and the key preview is disabled, the more 6337ecc1081ab9b4e41e4b2aec7877aaaf8df29e611Tadashi G. Takaoka // keys keyboard is placed at the touch point of the parent key. 6347ecc1081ab9b4e41e4b2aec7877aaaf8df29e611Tadashi G. Takaoka final int pointX = (mConfigShowMoreKeysKeyboardAtTouchedPoint && !keyPreviewEnabled) 635547b638194c05f971003edb06c3c6c489a76da5fTadashi G. Takaoka ? CoordinateUtils.x(lastCoords) 6367dc60f9db729e93cb591492574a436418c553ebfTadashi G. Takaoka : key.getX() + key.getWidth() / 2; 6377ecc1081ab9b4e41e4b2aec7877aaaf8df29e611Tadashi G. Takaoka // The more keys keyboard is usually vertically aligned with the top edge of the parent key 6387ecc1081ab9b4e41e4b2aec7877aaaf8df29e611Tadashi G. Takaoka // (plus vertical gap). If the key preview is enabled, the more keys keyboard is vertically 6397ecc1081ab9b4e41e4b2aec7877aaaf8df29e611Tadashi G. Takaoka // aligned with the bottom edge of the visible part of the key preview. 64029d5973fd35438a83acf7f44b5d55d5620278ee3Tadashi G. Takaoka // {@code mPreviewVisibleOffset} has been set appropriately in 64129d5973fd35438a83acf7f44b5d55d5620278ee3Tadashi G. Takaoka // {@link KeyboardView#showKeyPreview(PointerTracker)}. 642992c5219092ccafe66363451fbf4ca7c5a43fb20Tadashi G. Takaoka final int pointY = key.getY() + mKeyPreviewDrawParams.getVisibleOffset(); 64353b6d627e7fe66ce47ee6ae01254abc070558e77Tadashi G. Takaoka moreKeysKeyboardView.showMoreKeysPanel(this, this, pointX, pointY, mKeyboardActionListener); 64453b6d627e7fe66ce47ee6ae01254abc070558e77Tadashi G. Takaoka return moreKeysKeyboardView; 6455f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka } 6465f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka 6472fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa public boolean isInDraggingFinger() { 648a729377395967f7652d93992cbcf50cd2ff522d1Tadashi G. Takaoka if (isShowingMoreKeysPanel()) { 64963c233ab9f50d844be6e52e382c6664475606760Tadashi G. Takaoka return true; 6505f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka } 6512fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa return PointerTracker.isAnyInDraggingFinger(); 6525f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka } 6535f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka 654d9449ccf3ce9e5eabb022aed6a45bba680bce115Tadashi G. Takaoka @Override 655d9449ccf3ce9e5eabb022aed6a45bba680bce115Tadashi G. Takaoka public void onShowMoreKeysPanel(final MoreKeysPanel panel) { 6561b6eea89037158a1e271730eacdacb8b6e550d3aTadashi G. Takaoka locatePreviewPlacerView(); 657ca6e5dfedbb57f6ec31880f2799b40a6b2adadbcTadashi G. Takaoka // Dismiss another {@link MoreKeysPanel} that may be being showed. 658ca6e5dfedbb57f6ec31880f2799b40a6b2adadbcTadashi G. Takaoka onDismissMoreKeysPanel(); 659ca6e5dfedbb57f6ec31880f2799b40a6b2adadbcTadashi G. Takaoka // Dismiss all key previews that may be being showed. 660ca6e5dfedbb57f6ec31880f2799b40a6b2adadbcTadashi G. Takaoka PointerTracker.setReleasedKeyGraphicsToAllKeys(); 661051f8b144232f724386960cf6781a6d4665e4f02Tadashi G. Takaoka // Dismiss sliding key input preview that may be being showed. 662051f8b144232f724386960cf6781a6d4665e4f02Tadashi G. Takaoka mSlidingKeyInputDrawingPreview.dismissSlidingKeyInputPreview(); 663cf915ddc878699909365dd599a0e154552e244e2Tadashi G. Takaoka panel.showInParent(mDrawingPreviewPlacerView); 664d9449ccf3ce9e5eabb022aed6a45bba680bce115Tadashi G. Takaoka mMoreKeysPanel = panel; 665d9449ccf3ce9e5eabb022aed6a45bba680bce115Tadashi G. Takaoka } 666d9449ccf3ce9e5eabb022aed6a45bba680bce115Tadashi G. Takaoka 667d9449ccf3ce9e5eabb022aed6a45bba680bce115Tadashi G. Takaoka public boolean isShowingMoreKeysPanel() { 668a729377395967f7652d93992cbcf50cd2ff522d1Tadashi G. Takaoka return mMoreKeysPanel != null && mMoreKeysPanel.isShowingInParent(); 669d9449ccf3ce9e5eabb022aed6a45bba680bce115Tadashi G. Takaoka } 670d9449ccf3ce9e5eabb022aed6a45bba680bce115Tadashi G. Takaoka 671d9449ccf3ce9e5eabb022aed6a45bba680bce115Tadashi G. Takaoka @Override 6721f215a58c99f0eb2f536e9cccd51371f2883e201Tadashi G. Takaoka public void onCancelMoreKeysPanel() { 673d9449ccf3ce9e5eabb022aed6a45bba680bce115Tadashi G. Takaoka PointerTracker.dismissAllMoreKeysPanels(); 674d9449ccf3ce9e5eabb022aed6a45bba680bce115Tadashi G. Takaoka } 675d9449ccf3ce9e5eabb022aed6a45bba680bce115Tadashi G. Takaoka 676d9449ccf3ce9e5eabb022aed6a45bba680bce115Tadashi G. Takaoka @Override 6771f215a58c99f0eb2f536e9cccd51371f2883e201Tadashi G. Takaoka public void onDismissMoreKeysPanel() { 678d9449ccf3ce9e5eabb022aed6a45bba680bce115Tadashi G. Takaoka if (isShowingMoreKeysPanel()) { 6797f8345d59a82a9b1d458b8e55ffd12c2a0d466a7Tadashi G. Takaoka mMoreKeysPanel.removeFromParent(); 680d9449ccf3ce9e5eabb022aed6a45bba680bce115Tadashi G. Takaoka mMoreKeysPanel = null; 681d9449ccf3ce9e5eabb022aed6a45bba680bce115Tadashi G. Takaoka } 682d9449ccf3ce9e5eabb022aed6a45bba680bce115Tadashi G. Takaoka } 683d9449ccf3ce9e5eabb022aed6a45bba680bce115Tadashi G. Takaoka 6845433ce64c0f141bc4ee82912844f47f575654af5Tadashi G. Takaoka public void startDoubleTapShiftKeyTimer() { 6852ad6d9cda33825fa265cd17372f115bb48f49d19Tadashi G. Takaoka mTimerHandler.startDoubleTapShiftKeyTimer(); 6865433ce64c0f141bc4ee82912844f47f575654af5Tadashi G. Takaoka } 6875433ce64c0f141bc4ee82912844f47f575654af5Tadashi G. Takaoka 6885433ce64c0f141bc4ee82912844f47f575654af5Tadashi G. Takaoka public void cancelDoubleTapShiftKeyTimer() { 6892ad6d9cda33825fa265cd17372f115bb48f49d19Tadashi G. Takaoka mTimerHandler.cancelDoubleTapShiftKeyTimer(); 6905433ce64c0f141bc4ee82912844f47f575654af5Tadashi G. Takaoka } 6915433ce64c0f141bc4ee82912844f47f575654af5Tadashi G. Takaoka 6925433ce64c0f141bc4ee82912844f47f575654af5Tadashi G. Takaoka public boolean isInDoubleTapShiftKeyTimeout() { 6932ad6d9cda33825fa265cd17372f115bb48f49d19Tadashi G. Takaoka return mTimerHandler.isInDoubleTapShiftKeyTimeout(); 6945433ce64c0f141bc4ee82912844f47f575654af5Tadashi G. Takaoka } 6955433ce64c0f141bc4ee82912844f47f575654af5Tadashi G. Takaoka 6965f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka @Override 69712d80ebead6a1d7f704a5a3af3b6fe3313ceab05Dan Zivkovic public boolean onTouchEvent(final MotionEvent event) { 69846286874f30c4a6ef44646c4e4adf36fe55c74b9Tadashi G. Takaoka if (getKeyboard() == null) { 69946286874f30c4a6ef44646c4e4adf36fe55c74b9Tadashi G. Takaoka return false; 70046286874f30c4a6ef44646c4e4adf36fe55c74b9Tadashi G. Takaoka } 701b6cc3a85ab68cff2fae4c3858b48d9c5d7b45690Tadashi G. Takaoka if (mNonDistinctMultitouchHelper != null) { 70212d80ebead6a1d7f704a5a3af3b6fe3313ceab05Dan Zivkovic if (event.getPointerCount() > 1 && mTimerHandler.isInKeyRepeat()) { 703b6cc3a85ab68cff2fae4c3858b48d9c5d7b45690Tadashi G. Takaoka // Key repeating timer will be canceled if 2 or more keys are in action. 7042ad6d9cda33825fa265cd17372f115bb48f49d19Tadashi G. Takaoka mTimerHandler.cancelKeyRepeatTimers(); 705b6cc3a85ab68cff2fae4c3858b48d9c5d7b45690Tadashi G. Takaoka } 706b6cc3a85ab68cff2fae4c3858b48d9c5d7b45690Tadashi G. Takaoka // Non distinct multitouch screen support 70712d80ebead6a1d7f704a5a3af3b6fe3313ceab05Dan Zivkovic mNonDistinctMultitouchHelper.processMotionEvent(event, mKeyDetector); 708b6cc3a85ab68cff2fae4c3858b48d9c5d7b45690Tadashi G. Takaoka return true; 709b6cc3a85ab68cff2fae4c3858b48d9c5d7b45690Tadashi G. Takaoka } 71012d80ebead6a1d7f704a5a3af3b6fe3313ceab05Dan Zivkovic return processMotionEvent(event); 711c403a46f6d787b79768895272d53d296100677ddTadashi G. Takaoka } 712c403a46f6d787b79768895272d53d296100677ddTadashi G. Takaoka 71312d80ebead6a1d7f704a5a3af3b6fe3313ceab05Dan Zivkovic public boolean processMotionEvent(final MotionEvent event) { 71412d80ebead6a1d7f704a5a3af3b6fe3313ceab05Dan Zivkovic final int index = event.getActionIndex(); 71512d80ebead6a1d7f704a5a3af3b6fe3313ceab05Dan Zivkovic final int id = event.getPointerId(index); 7162fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa final PointerTracker tracker = PointerTracker.getPointerTracker(id); 7172fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa // When a more keys panel is showing, we should ignore other fingers' single touch events 7182fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa // other than the finger that is showing the more keys panel. 7192fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa if (isShowingMoreKeysPanel() && !tracker.isShowingMoreKeysPanel() 7202fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa && PointerTracker.getActivePointerTrackerCount() == 1) { 7212fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa return true; 7222fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa } 72312d80ebead6a1d7f704a5a3af3b6fe3313ceab05Dan Zivkovic tracker.processMotionEvent(event, mKeyDetector); 7245f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka return true; 7255f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka } 7265f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka 7275c095e59f679f726df1b6655fbbd73e310ac0decTadashi G. Takaoka public void cancelAllOngoingEvents() { 7282ad6d9cda33825fa265cd17372f115bb48f49d19Tadashi G. Takaoka mTimerHandler.cancelAllMessages(); 729ca6e5dfedbb57f6ec31880f2799b40a6b2adadbcTadashi G. Takaoka PointerTracker.setReleasedKeyGraphicsToAllKeys(); 7302ad6d9cda33825fa265cd17372f115bb48f49d19Tadashi G. Takaoka mGestureFloatingTextDrawingPreview.dismissGestureFloatingPreviewText(); 731051f8b144232f724386960cf6781a6d4665e4f02Tadashi G. Takaoka mSlidingKeyInputDrawingPreview.dismissSlidingKeyInputPreview(); 7325c095e59f679f726df1b6655fbbd73e310ac0decTadashi G. Takaoka PointerTracker.dismissAllMoreKeysPanels(); 7335c095e59f679f726df1b6655fbbd73e310ac0decTadashi G. Takaoka PointerTracker.cancelAllPointerTrackers(); 734375982106bf073971fccd14b2c65ec8e089bb2aeTadashi G. Takaoka } 735375982106bf073971fccd14b2c65ec8e089bb2aeTadashi G. Takaoka 7365f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka public void closing() { 7375c095e59f679f726df1b6655fbbd73e310ac0decTadashi G. Takaoka cancelAllOngoingEvents(); 738a729377395967f7652d93992cbcf50cd2ff522d1Tadashi G. Takaoka mMoreKeysKeyboardCache.clear(); 7395f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka } 7405f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka 741bca7e4e9a2ed07d5d87f4dce9f793e40edb09691Tadashi G. Takaoka public void onHideWindow() { 742a74719c934ceb30d2afb7ae999c909f5c6fd5325Tadashi G. Takaoka onDismissMoreKeysPanel(); 743d78b586976af9b6b8f6e00c04747facfac313abcTadashi G. Takaoka final MainKeyboardAccessibilityDelegate accessibilityDelegate = mAccessibilityDelegate; 74404cd8794e04b14c2b7e7eed036b83075792134a1Tadashi G. Takaoka if (accessibilityDelegate != null 74504cd8794e04b14c2b7e7eed036b83075792134a1Tadashi G. Takaoka && AccessibilityUtils.getInstance().isAccessibilityEnabled()) { 746d78b586976af9b6b8f6e00c04747facfac313abcTadashi G. Takaoka accessibilityDelegate.onHideWindow(); 7471ead609e6fd64fd5ac2979ac3802d8bada7d7f49Tadashi G. Takaoka } 748bca7e4e9a2ed07d5d87f4dce9f793e40edb09691Tadashi G. Takaoka } 749bca7e4e9a2ed07d5d87f4dce9f793e40edb09691Tadashi G. Takaoka 750586a15c3f0d44590a5162e0ab4c3c52511f13f26Alan Viverette /** 7519647d7fbee4cbd72876e949e6544dc43fadbd148Tadashi G. Takaoka * {@inheritDoc} 752586a15c3f0d44590a5162e0ab4c3c52511f13f26Alan Viverette */ 753c6435f92a80c6664870f9d1a4bb2a1c5153ef2c3Tadashi G. Takaoka @Override 7549647d7fbee4cbd72876e949e6544dc43fadbd148Tadashi G. Takaoka public boolean onHoverEvent(final MotionEvent event) { 755d78b586976af9b6b8f6e00c04747facfac313abcTadashi G. Takaoka final MainKeyboardAccessibilityDelegate accessibilityDelegate = mAccessibilityDelegate; 75604cd8794e04b14c2b7e7eed036b83075792134a1Tadashi G. Takaoka if (accessibilityDelegate != null 75704cd8794e04b14c2b7e7eed036b83075792134a1Tadashi G. Takaoka && AccessibilityUtils.getInstance().isTouchExplorationEnabled()) { 758d78b586976af9b6b8f6e00c04747facfac313abcTadashi G. Takaoka return accessibilityDelegate.onHoverEvent(event); 7595f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka } 7609647d7fbee4cbd72876e949e6544dc43fadbd148Tadashi G. Takaoka return super.onHoverEvent(event); 7615f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka } 76222b48de11ce6f31a0edf90e1308073e67a7a2adbTadashi G. Takaoka 763dc34da218a22489d92d1015e9e5dac8d951b89f4Tadashi G. Takaoka public void updateShortcutKey(final boolean available) { 7647bd714c086a78e2058543b0971ac92f5a30b2362Tadashi G. Takaoka final Keyboard keyboard = getKeyboard(); 76520dd1bc090abdd3e88855fe54b1865949aa1168dTadashi G. Takaoka if (keyboard == null) { 76620dd1bc090abdd3e88855fe54b1865949aa1168dTadashi G. Takaoka return; 76720dd1bc090abdd3e88855fe54b1865949aa1168dTadashi G. Takaoka } 768240871ecafde7834ebb4270cd7758fc904a5f3a7Tadashi G. Takaoka final Key shortcutKey = keyboard.getKey(Constants.CODE_SHORTCUT); 76920dd1bc090abdd3e88855fe54b1865949aa1168dTadashi G. Takaoka if (shortcutKey == null) { 77020dd1bc090abdd3e88855fe54b1865949aa1168dTadashi G. Takaoka return; 77120dd1bc090abdd3e88855fe54b1865949aa1168dTadashi G. Takaoka } 7727bd714c086a78e2058543b0971ac92f5a30b2362Tadashi G. Takaoka shortcutKey.setEnabled(available); 7737bd714c086a78e2058543b0971ac92f5a30b2362Tadashi G. Takaoka invalidateKey(shortcutKey); 7745afc3ae2d9df0c2c93f2c66af13b128889ac3b5dTadashi G. Takaoka } 7755afc3ae2d9df0c2c93f2c66af13b128889ac3b5dTadashi G. Takaoka 776dc34da218a22489d92d1015e9e5dac8d951b89f4Tadashi G. Takaoka public void startDisplayLanguageOnSpacebar(final boolean subtypeChanged, 7777dd32dfc065c13e946c0d42a0e000f4ce7298ed7Tadashi G. Takaoka final int languageOnSpacebarFormatType, 7787dd32dfc065c13e946c0d42a0e000f4ce7298ed7Tadashi G. Takaoka final boolean hasMultipleEnabledIMEsOrSubtypes) { 779016d6c424cf004c282db5a57e64f3d1eee672a22Tadashi G. Takaoka if (subtypeChanged) { 780016d6c424cf004c282db5a57e64f3d1eee672a22Tadashi G. Takaoka KeyPreviewView.clearTextCache(); 781016d6c424cf004c282db5a57e64f3d1eee672a22Tadashi G. Takaoka } 7827dd32dfc065c13e946c0d42a0e000f4ce7298ed7Tadashi G. Takaoka mLanguageOnSpacebarFormatType = languageOnSpacebarFormatType; 783fd60b2f97035382b14dce207b3613711982a613eTadashi G. Takaoka mHasMultipleEnabledIMEsOrSubtypes = hasMultipleEnabledIMEsOrSubtypes; 784fd60b2f97035382b14dce207b3613711982a613eTadashi G. Takaoka final ObjectAnimator animator = mLanguageOnSpacebarFadeoutAnimator; 785d7c4ba170982ddce5ac12ea92c3c3d8b53d524baTadashi G. Takaoka if (animator == null) { 7864934a88b618f06600e2d725a43bdd2511715b4caTadashi G. Takaoka mLanguageOnSpacebarFormatType = LanguageOnSpacebarUtils.FORMAT_TYPE_NONE; 7874c0c638a189c1073b1fb6e43fe5fddb6f9932038Tadashi G. Takaoka } else { 7887dd32dfc065c13e946c0d42a0e000f4ce7298ed7Tadashi G. Takaoka if (subtypeChanged 7894934a88b618f06600e2d725a43bdd2511715b4caTadashi G. Takaoka && languageOnSpacebarFormatType != LanguageOnSpacebarUtils.FORMAT_TYPE_NONE) { 7904daf32b6c0358f0273a99b622a259ecdf6b44fa4Tom Ouyang setLanguageOnSpacebarAnimAlpha(Constants.Color.ALPHA_OPAQUE); 79131c94cea82f1788e3a04f2a1e012945f35497f0aTadashi G. Takaoka if (animator.isStarted()) { 79231c94cea82f1788e3a04f2a1e012945f35497f0aTadashi G. Takaoka animator.cancel(); 79331c94cea82f1788e3a04f2a1e012945f35497f0aTadashi G. Takaoka } 794d7c4ba170982ddce5ac12ea92c3c3d8b53d524baTadashi G. Takaoka animator.start(); 795dabf96896ef4c304c6dad36b307a2a458a58209dTadashi G. Takaoka } else { 79631c94cea82f1788e3a04f2a1e012945f35497f0aTadashi G. Takaoka if (!animator.isStarted()) { 79731c94cea82f1788e3a04f2a1e012945f35497f0aTadashi G. Takaoka mLanguageOnSpacebarAnimAlpha = mLanguageOnSpacebarFinalAlpha; 79831c94cea82f1788e3a04f2a1e012945f35497f0aTadashi G. Takaoka } 799dabf96896ef4c304c6dad36b307a2a458a58209dTadashi G. Takaoka } 8004c0c638a189c1073b1fb6e43fe5fddb6f9932038Tadashi G. Takaoka } 8014112dc05002d7a880e558418639cf25c4bd02a5aTadashi G. Takaoka invalidateKey(mSpaceKey); 8024112dc05002d7a880e558418639cf25c4bd02a5aTadashi G. Takaoka } 8034112dc05002d7a880e558418639cf25c4bd02a5aTadashi G. Takaoka 80422b48de11ce6f31a0edf90e1308073e67a7a2adbTadashi G. Takaoka @Override 805dc34da218a22489d92d1015e9e5dac8d951b89f4Tadashi G. Takaoka protected void onDrawKeyTopVisuals(final Key key, final Canvas canvas, final Paint paint, 806dc34da218a22489d92d1015e9e5dac8d951b89f4Tadashi G. Takaoka final KeyDrawParams params) { 8076bc9186457219daeb3734531a01271b0e4fa37fbTadashi G. Takaoka if (key.altCodeWhileTyping() && key.isEnabled()) { 80873a46bfeb7a109b49be196e5d679e44c9e66a2e8Tadashi G. Takaoka params.mAnimAlpha = mAltCodeKeyWhileTypingAnimAlpha; 80973a46bfeb7a109b49be196e5d679e44c9e66a2e8Tadashi G. Takaoka } 81041808192d3a64d3e823e13ace27e3ce80b1c5bdaTadashi G. Takaoka super.onDrawKeyTopVisuals(key, canvas, paint, params); 8117dc60f9db729e93cb591492574a436418c553ebfTadashi G. Takaoka final int code = key.getCode(); 8127dc60f9db729e93cb591492574a436418c553ebfTadashi G. Takaoka if (code == Constants.CODE_SPACE) { 81341808192d3a64d3e823e13ace27e3ce80b1c5bdaTadashi G. Takaoka // If input language are explicitly selected. 8144934a88b618f06600e2d725a43bdd2511715b4caTadashi G. Takaoka if (mLanguageOnSpacebarFormatType != LanguageOnSpacebarUtils.FORMAT_TYPE_NONE) { 81541808192d3a64d3e823e13ace27e3ce80b1c5bdaTadashi G. Takaoka drawLanguageOnSpacebar(key, canvas, paint); 81641808192d3a64d3e823e13ace27e3ce80b1c5bdaTadashi G. Takaoka } 8174112dc05002d7a880e558418639cf25c4bd02a5aTadashi G. Takaoka // Whether space key needs to show the "..." popup hint for special purposes 818fd60b2f97035382b14dce207b3613711982a613eTadashi G. Takaoka if (key.isLongPressEnabled() && mHasMultipleEnabledIMEsOrSubtypes) { 819bd93eddb52816acedd5242864e467781d4adfd71Tadashi G. Takaoka drawKeyPopupHint(key, canvas, paint, params); 8204112dc05002d7a880e558418639cf25c4bd02a5aTadashi G. Takaoka } 8217dc60f9db729e93cb591492574a436418c553ebfTadashi G. Takaoka } else if (code == Constants.CODE_LANGUAGE_SWITCH) { 822fd60b2f97035382b14dce207b3613711982a613eTadashi G. Takaoka drawKeyPopupHint(key, canvas, paint, params); 82322b48de11ce6f31a0edf90e1308073e67a7a2adbTadashi G. Takaoka } 82422b48de11ce6f31a0edf90e1308073e67a7a2adbTadashi G. Takaoka } 8254112dc05002d7a880e558418639cf25c4bd02a5aTadashi G. Takaoka 826741831d32295acfb7675d7e0781a634d78868c63Satoshi Kataoka private boolean fitsTextIntoWidth(final int width, final String text, final Paint paint) { 827741831d32295acfb7675d7e0781a634d78868c63Satoshi Kataoka final int maxTextWidth = width - mLanguageOnSpacebarHorizontalMargin * 2; 828bd2ca9c0214ea80fa860f4a9d118f866e16b03caTadashi G. Takaoka paint.setTextScaleX(1.0f); 8292fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa final float textWidth = TypefaceUtils.getStringWidth(text, paint); 83020dd1bc090abdd3e88855fe54b1865949aa1168dTadashi G. Takaoka if (textWidth < width) { 83120dd1bc090abdd3e88855fe54b1865949aa1168dTadashi G. Takaoka return true; 83220dd1bc090abdd3e88855fe54b1865949aa1168dTadashi G. Takaoka } 833bd2ca9c0214ea80fa860f4a9d118f866e16b03caTadashi G. Takaoka 834741831d32295acfb7675d7e0781a634d78868c63Satoshi Kataoka final float scaleX = maxTextWidth / textWidth; 83520dd1bc090abdd3e88855fe54b1865949aa1168dTadashi G. Takaoka if (scaleX < MINIMUM_XSCALE_OF_LANGUAGE_NAME) { 83620dd1bc090abdd3e88855fe54b1865949aa1168dTadashi G. Takaoka return false; 83720dd1bc090abdd3e88855fe54b1865949aa1168dTadashi G. Takaoka } 838bd2ca9c0214ea80fa860f4a9d118f866e16b03caTadashi G. Takaoka 839bd2ca9c0214ea80fa860f4a9d118f866e16b03caTadashi G. Takaoka paint.setTextScaleX(scaleX); 8402fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa return TypefaceUtils.getStringWidth(text, paint) < maxTextWidth; 841bd2ca9c0214ea80fa860f4a9d118f866e16b03caTadashi G. Takaoka } 842bd2ca9c0214ea80fa860f4a9d118f866e16b03caTadashi G. Takaoka 843bd2ca9c0214ea80fa860f4a9d118f866e16b03caTadashi G. Takaoka // Layout language name on spacebar. 844741831d32295acfb7675d7e0781a634d78868c63Satoshi Kataoka private String layoutLanguageOnSpacebar(final Paint paint, 84585ddfe1317a4475269e53f62c2338c335e02e839Jean Chalard final RichInputMethodSubtype subtype, final int width) { 846bd2ca9c0214ea80fa860f4a9d118f866e16b03caTadashi G. Takaoka // Choose appropriate language name to fit into the width. 8474934a88b618f06600e2d725a43bdd2511715b4caTadashi G. Takaoka if (mLanguageOnSpacebarFormatType == LanguageOnSpacebarUtils.FORMAT_TYPE_FULL_LOCALE) { 84885ddfe1317a4475269e53f62c2338c335e02e839Jean Chalard final String fullText = subtype.getFullDisplayName(); 8497dd32dfc065c13e946c0d42a0e000f4ce7298ed7Tadashi G. Takaoka if (fitsTextIntoWidth(width, fullText, paint)) { 8507dd32dfc065c13e946c0d42a0e000f4ce7298ed7Tadashi G. Takaoka return fullText; 8517dd32dfc065c13e946c0d42a0e000f4ce7298ed7Tadashi G. Takaoka } 852bd2ca9c0214ea80fa860f4a9d118f866e16b03caTadashi G. Takaoka } 853bd2ca9c0214ea80fa860f4a9d118f866e16b03caTadashi G. Takaoka 85485ddfe1317a4475269e53f62c2338c335e02e839Jean Chalard final String middleText = subtype.getMiddleDisplayName(); 85520dd1bc090abdd3e88855fe54b1865949aa1168dTadashi G. Takaoka if (fitsTextIntoWidth(width, middleText, paint)) { 85620dd1bc090abdd3e88855fe54b1865949aa1168dTadashi G. Takaoka return middleText; 8574112dc05002d7a880e558418639cf25c4bd02a5aTadashi G. Takaoka } 8584112dc05002d7a880e558418639cf25c4bd02a5aTadashi G. Takaoka 859bd2ca9c0214ea80fa860f4a9d118f866e16b03caTadashi G. Takaoka return ""; 8604112dc05002d7a880e558418639cf25c4bd02a5aTadashi G. Takaoka } 8614112dc05002d7a880e558418639cf25c4bd02a5aTadashi G. Takaoka 86241808192d3a64d3e823e13ace27e3ce80b1c5bdaTadashi G. Takaoka private void drawLanguageOnSpacebar(final Key key, final Canvas canvas, final Paint paint) { 863a66069abd83900b5f6b5333756d67e93b6edb3c1Tadashi G. Takaoka final Keyboard keyboard = getKeyboard(); 864a66069abd83900b5f6b5333756d67e93b6edb3c1Tadashi G. Takaoka if (keyboard == null) { 865a66069abd83900b5f6b5333756d67e93b6edb3c1Tadashi G. Takaoka return; 866a66069abd83900b5f6b5333756d67e93b6edb3c1Tadashi G. Takaoka } 8677dc60f9db729e93cb591492574a436418c553ebfTadashi G. Takaoka final int width = key.getWidth(); 8687dc60f9db729e93cb591492574a436418c553ebfTadashi G. Takaoka final int height = key.getHeight(); 86941808192d3a64d3e823e13ace27e3ce80b1c5bdaTadashi G. Takaoka paint.setTextAlign(Align.CENTER); 87041808192d3a64d3e823e13ace27e3ce80b1c5bdaTadashi G. Takaoka paint.setTypeface(Typeface.DEFAULT); 87141808192d3a64d3e823e13ace27e3ce80b1c5bdaTadashi G. Takaoka paint.setTextSize(mLanguageOnSpacebarTextSize); 872a66069abd83900b5f6b5333756d67e93b6edb3c1Tadashi G. Takaoka final String language = layoutLanguageOnSpacebar(paint, keyboard.mId.mSubtype, width); 87341808192d3a64d3e823e13ace27e3ce80b1c5bdaTadashi G. Takaoka // Draw language text with shadow 87441808192d3a64d3e823e13ace27e3ce80b1c5bdaTadashi G. Takaoka final float descent = paint.descent(); 87541808192d3a64d3e823e13ace27e3ce80b1c5bdaTadashi G. Takaoka final float textHeight = -paint.ascent() + descent; 87641808192d3a64d3e823e13ace27e3ce80b1c5bdaTadashi G. Takaoka final float baseline = height / 2 + textHeight / 2; 87741808192d3a64d3e823e13ace27e3ce80b1c5bdaTadashi G. Takaoka if (mLanguageOnSpacebarTextShadowRadius > 0.0f) { 87841808192d3a64d3e823e13ace27e3ce80b1c5bdaTadashi G. Takaoka paint.setShadowLayer(mLanguageOnSpacebarTextShadowRadius, 0, 0, 87941808192d3a64d3e823e13ace27e3ce80b1c5bdaTadashi G. Takaoka mLanguageOnSpacebarTextShadowColor); 88041808192d3a64d3e823e13ace27e3ce80b1c5bdaTadashi G. Takaoka } else { 88141f9f1ef703ca4d63f1ef08b51d1365a17b4065aTadashi G. Takaoka paint.clearShadowLayer(); 8824112dc05002d7a880e558418639cf25c4bd02a5aTadashi G. Takaoka } 88341808192d3a64d3e823e13ace27e3ce80b1c5bdaTadashi G. Takaoka paint.setColor(mLanguageOnSpacebarTextColor); 88441808192d3a64d3e823e13ace27e3ce80b1c5bdaTadashi G. Takaoka paint.setAlpha(mLanguageOnSpacebarAnimAlpha); 88541808192d3a64d3e823e13ace27e3ce80b1c5bdaTadashi G. Takaoka canvas.drawText(language, width / 2, baseline - descent, paint); 88641808192d3a64d3e823e13ace27e3ce80b1c5bdaTadashi G. Takaoka paint.clearShadowLayer(); 88741808192d3a64d3e823e13ace27e3ce80b1c5bdaTadashi G. Takaoka paint.setTextScaleX(1.0f); 8884112dc05002d7a880e558418639cf25c4bd02a5aTadashi G. Takaoka } 889c8814e20b7b0ed5f7e11292480e89152618dd862Ken Wakasa 890e68d565d0f9704145adbf781105f1ac9a90f0a98Ken Wakasa @Override 891c8814e20b7b0ed5f7e11292480e89152618dd862Ken Wakasa public void deallocateMemory() { 892e68d565d0f9704145adbf781105f1ac9a90f0a98Ken Wakasa super.deallocateMemory(); 893afca1ddd233c03d79433931a0b6ba97ed22663edTadashi G. Takaoka mDrawingPreviewPlacerView.deallocateMemory(); 894c8814e20b7b0ed5f7e11292480e89152618dd862Ken Wakasa } 8955f6816fa8bf259f0340a3d12c551d1532f647d66Tadashi G. Takaoka} 896