MoreKeysKeyboardView.java revision adba09b54ed1b30bf9b24d632165229a0752b144
1ff082d081f3ea18ff0b9b22126ee4a86504cf83cTadashi G. Takaoka/* 2ff082d081f3ea18ff0b9b22126ee4a86504cf83cTadashi G. Takaoka * Copyright (C) 2011 The Android Open Source Project 3ff082d081f3ea18ff0b9b22126ee4a86504cf83cTadashi G. Takaoka * 4ff082d081f3ea18ff0b9b22126ee4a86504cf83cTadashi G. Takaoka * Licensed under the Apache License, Version 2.0 (the "License"); 5ff082d081f3ea18ff0b9b22126ee4a86504cf83cTadashi G. Takaoka * you may not use this file except in compliance with the License. 6ff082d081f3ea18ff0b9b22126ee4a86504cf83cTadashi G. Takaoka * You may obtain a copy of the License at 7ff082d081f3ea18ff0b9b22126ee4a86504cf83cTadashi G. Takaoka * 8ff082d081f3ea18ff0b9b22126ee4a86504cf83cTadashi G. Takaoka * http://www.apache.org/licenses/LICENSE-2.0 9ff082d081f3ea18ff0b9b22126ee4a86504cf83cTadashi G. Takaoka * 10ff082d081f3ea18ff0b9b22126ee4a86504cf83cTadashi G. Takaoka * Unless required by applicable law or agreed to in writing, software 11ff082d081f3ea18ff0b9b22126ee4a86504cf83cTadashi G. Takaoka * distributed under the License is distributed on an "AS IS" BASIS, 12ff082d081f3ea18ff0b9b22126ee4a86504cf83cTadashi G. Takaoka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ff082d081f3ea18ff0b9b22126ee4a86504cf83cTadashi G. Takaoka * See the License for the specific language governing permissions and 14ff082d081f3ea18ff0b9b22126ee4a86504cf83cTadashi G. Takaoka * limitations under the License. 15ff082d081f3ea18ff0b9b22126ee4a86504cf83cTadashi G. Takaoka */ 16ff082d081f3ea18ff0b9b22126ee4a86504cf83cTadashi G. Takaoka 17ff082d081f3ea18ff0b9b22126ee4a86504cf83cTadashi G. Takaokapackage com.android.inputmethod.keyboard; 18ff082d081f3ea18ff0b9b22126ee4a86504cf83cTadashi G. Takaoka 19ff082d081f3ea18ff0b9b22126ee4a86504cf83cTadashi G. Takaokaimport android.content.Context; 20ff082d081f3ea18ff0b9b22126ee4a86504cf83cTadashi G. Takaokaimport android.util.AttributeSet; 2135580bad6f3da3b204653825bbb6871563e70728Tom Ouyangimport android.view.MotionEvent; 22ff082d081f3ea18ff0b9b22126ee4a86504cf83cTadashi G. Takaokaimport android.view.View; 237f8345d59a82a9b1d458b8e55ffd12c2a0d466a7Tadashi G. Takaokaimport android.view.ViewGroup; 24ff082d081f3ea18ff0b9b22126ee4a86504cf83cTadashi G. Takaoka 2562316d7e821fa3a1ed052eb1ac2e8c0d08931d3eTadashi G. Takaokaimport com.android.inputmethod.accessibility.AccessibilityUtils; 2662316d7e821fa3a1ed052eb1ac2e8c0d08931d3eTadashi G. Takaokaimport com.android.inputmethod.accessibility.MoreKeysKeyboardAccessibilityDelegate; 27ac78633be28e8990fc3b3a8de192c80966e746e3Tadashi G. Takaokaimport com.android.inputmethod.latin.Constants; 28e07b51e7c65220ac183546103010dd617d164f60Tadashi G. Takaokaimport com.android.inputmethod.latin.R; 29e28eba5074664d5716b8e58b8d0a235746b261ebKen Wakasaimport com.android.inputmethod.latin.utils.CoordinateUtils; 30e07b51e7c65220ac183546103010dd617d164f60Tadashi G. Takaoka 31ff082d081f3ea18ff0b9b22126ee4a86504cf83cTadashi G. Takaoka/** 322affaf91a04d63e0994102299816014a8bbe11e1Tadashi G. Takaoka * A view that renders a virtual {@link MoreKeysKeyboard}. It handles rendering of keys and 332affaf91a04d63e0994102299816014a8bbe11e1Tadashi G. Takaoka * detecting key presses and touch movements. 34ff082d081f3ea18ff0b9b22126ee4a86504cf83cTadashi G. Takaoka */ 3535580bad6f3da3b204653825bbb6871563e70728Tom Ouyangpublic class MoreKeysKeyboardView extends KeyboardView implements MoreKeysPanel { 36359c35e0f6e534d096efc1d9f2ff585139e3b3acTadashi G. Takaoka private final int[] mCoordinates = CoordinateUtils.newInstance(); 37ff082d081f3ea18ff0b9b22126ee4a86504cf83cTadashi G. Takaoka 381dbeb251b2570dd3025dcd7134090de0fc860d04Tadashi G. Takaoka protected final KeyDetector mKeyDetector; 3909e4530ca75d4664eb72708face83b466839c522Tadashi G. Takaoka private Controller mController = EMPTY_CONTROLLER; 4035580bad6f3da3b204653825bbb6871563e70728Tom Ouyang protected KeyboardActionListener mListener; 41ff082d081f3ea18ff0b9b22126ee4a86504cf83cTadashi G. Takaoka private int mOriginX; 42ff082d081f3ea18ff0b9b22126ee4a86504cf83cTadashi G. Takaoka private int mOriginY; 4335580bad6f3da3b204653825bbb6871563e70728Tom Ouyang private Key mCurrentKey; 4463c233ab9f50d844be6e52e382c6664475606760Tadashi G. Takaoka 4535580bad6f3da3b204653825bbb6871563e70728Tom Ouyang private int mActivePointerId; 46ff082d081f3ea18ff0b9b22126ee4a86504cf83cTadashi G. Takaoka 47aea429200e997762cd92744a2b1f3f586fc00b35Tadashi G. Takaoka protected MoreKeysKeyboardAccessibilityDelegate mAccessibilityDelegate; 4862316d7e821fa3a1ed052eb1ac2e8c0d08931d3eTadashi G. Takaoka 49bc464e2952e102219f0b977fc1e9140ad5bd03e4Tadashi G. Takaoka public MoreKeysKeyboardView(final Context context, final AttributeSet attrs) { 502affaf91a04d63e0994102299816014a8bbe11e1Tadashi G. Takaoka this(context, attrs, R.attr.moreKeysKeyboardViewStyle); 51ff082d081f3ea18ff0b9b22126ee4a86504cf83cTadashi G. Takaoka } 52ff082d081f3ea18ff0b9b22126ee4a86504cf83cTadashi G. Takaoka 53bc464e2952e102219f0b977fc1e9140ad5bd03e4Tadashi G. Takaoka public MoreKeysKeyboardView(final Context context, final AttributeSet attrs, 54bc464e2952e102219f0b977fc1e9140ad5bd03e4Tadashi G. Takaoka final int defStyle) { 55ff082d081f3ea18ff0b9b22126ee4a86504cf83cTadashi G. Takaoka super(context, attrs, defStyle); 5662316d7e821fa3a1ed052eb1ac2e8c0d08931d3eTadashi G. Takaoka mKeyDetector = new MoreKeysDetector(getResources().getDimension( 5762316d7e821fa3a1ed052eb1ac2e8c0d08931d3eTadashi G. Takaoka R.dimen.config_more_keys_keyboard_slide_allowance)); 58ff082d081f3ea18ff0b9b22126ee4a86504cf83cTadashi G. Takaoka } 59ff082d081f3ea18ff0b9b22126ee4a86504cf83cTadashi G. Takaoka 60ff082d081f3ea18ff0b9b22126ee4a86504cf83cTadashi G. Takaoka @Override 61bc464e2952e102219f0b977fc1e9140ad5bd03e4Tadashi G. Takaoka protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) { 6238f55b36c3992a580cf7e20668b1eb72a4eb2431Tadashi G. Takaoka final Keyboard keyboard = getKeyboard(); 6338f55b36c3992a580cf7e20668b1eb72a4eb2431Tadashi G. Takaoka if (keyboard != null) { 648da9a13760896cd78235b60d0ea680ea13620532Tadashi G. Takaoka final int width = keyboard.mOccupiedWidth + getPaddingLeft() + getPaddingRight(); 658da9a13760896cd78235b60d0ea680ea13620532Tadashi G. Takaoka final int height = keyboard.mOccupiedHeight + getPaddingTop() + getPaddingBottom(); 6638f55b36c3992a580cf7e20668b1eb72a4eb2431Tadashi G. Takaoka setMeasuredDimension(width, height); 6738f55b36c3992a580cf7e20668b1eb72a4eb2431Tadashi G. Takaoka } else { 6838f55b36c3992a580cf7e20668b1eb72a4eb2431Tadashi G. Takaoka super.onMeasure(widthMeasureSpec, heightMeasureSpec); 6938f55b36c3992a580cf7e20668b1eb72a4eb2431Tadashi G. Takaoka } 7038f55b36c3992a580cf7e20668b1eb72a4eb2431Tadashi G. Takaoka } 7138f55b36c3992a580cf7e20668b1eb72a4eb2431Tadashi G. Takaoka 7238f55b36c3992a580cf7e20668b1eb72a4eb2431Tadashi G. Takaoka @Override 73bc464e2952e102219f0b977fc1e9140ad5bd03e4Tadashi G. Takaoka public void setKeyboard(final Keyboard keyboard) { 7463c233ab9f50d844be6e52e382c6664475606760Tadashi G. Takaoka super.setKeyboard(keyboard); 751dbeb251b2570dd3025dcd7134090de0fc860d04Tadashi G. Takaoka mKeyDetector.setKeyboard( 761dbeb251b2570dd3025dcd7134090de0fc860d04Tadashi G. Takaoka keyboard, -getPaddingLeft(), -getPaddingTop() + getVerticalCorrection()); 7762316d7e821fa3a1ed052eb1ac2e8c0d08931d3eTadashi G. Takaoka if (AccessibilityUtils.getInstance().isTouchExplorationEnabled()) { 78dec599d1723f4ff52f066bd2dd1a4457d30cd33cTadashi G. Takaoka if (mAccessibilityDelegate == null) { 79dec599d1723f4ff52f066bd2dd1a4457d30cd33cTadashi G. Takaoka mAccessibilityDelegate = new MoreKeysKeyboardAccessibilityDelegate( 80dec599d1723f4ff52f066bd2dd1a4457d30cd33cTadashi G. Takaoka this, mKeyDetector); 81dec599d1723f4ff52f066bd2dd1a4457d30cd33cTadashi G. Takaoka mAccessibilityDelegate.setOpenAnnounce(R.string.spoken_open_more_keys_keyboard); 82dec599d1723f4ff52f066bd2dd1a4457d30cd33cTadashi G. Takaoka mAccessibilityDelegate.setCloseAnnounce(R.string.spoken_close_more_keys_keyboard); 83dec599d1723f4ff52f066bd2dd1a4457d30cd33cTadashi G. Takaoka } 8462316d7e821fa3a1ed052eb1ac2e8c0d08931d3eTadashi G. Takaoka mAccessibilityDelegate.setKeyboard(keyboard); 8562316d7e821fa3a1ed052eb1ac2e8c0d08931d3eTadashi G. Takaoka } else { 8662316d7e821fa3a1ed052eb1ac2e8c0d08931d3eTadashi G. Takaoka mAccessibilityDelegate = null; 8762316d7e821fa3a1ed052eb1ac2e8c0d08931d3eTadashi G. Takaoka } 8863c233ab9f50d844be6e52e382c6664475606760Tadashi G. Takaoka } 8963c233ab9f50d844be6e52e382c6664475606760Tadashi G. Takaoka 9063c233ab9f50d844be6e52e382c6664475606760Tadashi G. Takaoka @Override 91bc464e2952e102219f0b977fc1e9140ad5bd03e4Tadashi G. Takaoka public void showMoreKeysPanel(final View parentView, final Controller controller, 92fa2d543785c52f639ad3157c57420f58a199c550Tom Ouyang final int pointX, final int pointY, final KeyboardActionListener listener) { 93f44a01b40852dde2363a061cdc7df2ef4cb59aadTadashi G. Takaoka mController = controller; 94f44a01b40852dde2363a061cdc7df2ef4cb59aadTadashi G. Takaoka mListener = listener; 95fa2d543785c52f639ad3157c57420f58a199c550Tom Ouyang final View container = getContainerView(); 96bcbaffd9dd950c6b82c682a742c93f9319d908f5Tadashi G. Takaoka // The coordinates of panel's left-top corner in parentView's coordinate system. 972fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa // We need to consider background drawable paddings. 982fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa final int x = pointX - getDefaultCoordX() - container.getPaddingLeft() - getPaddingLeft(); 992fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa final int y = pointY - container.getMeasuredHeight() + container.getPaddingBottom() 1002fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa + getPaddingBottom(); 101ff082d081f3ea18ff0b9b22126ee4a86504cf83cTadashi G. Takaoka 102bcbaffd9dd950c6b82c682a742c93f9319d908f5Tadashi G. Takaoka parentView.getLocationInWindow(mCoordinates); 1032fa3693c264a4c150ac307d9bb7f6f8f18cc4ffcKen Wakasa // Ensure the horizontal position of the panel does not extend past the parentView edges. 104fa2d543785c52f639ad3157c57420f58a199c550Tom Ouyang final int maxX = parentView.getMeasuredWidth() - container.getMeasuredWidth(); 105be68b41ccb1a16201c3b91f1576a731f7715aaf6Tom Ouyang final int panelX = Math.max(0, Math.min(maxX, x)) + CoordinateUtils.x(mCoordinates); 106fa2d543785c52f639ad3157c57420f58a199c550Tom Ouyang final int panelY = y + CoordinateUtils.y(mCoordinates); 107fa2d543785c52f639ad3157c57420f58a199c550Tom Ouyang container.setX(panelX); 108fa2d543785c52f639ad3157c57420f58a199c550Tom Ouyang container.setY(panelY); 109ff082d081f3ea18ff0b9b22126ee4a86504cf83cTadashi G. Takaoka 110bcbaffd9dd950c6b82c682a742c93f9319d908f5Tadashi G. Takaoka mOriginX = x + container.getPaddingLeft(); 111bcbaffd9dd950c6b82c682a742c93f9319d908f5Tadashi G. Takaoka mOriginY = y + container.getPaddingTop(); 112fa2d543785c52f639ad3157c57420f58a199c550Tom Ouyang controller.onShowMoreKeysPanel(this); 11362316d7e821fa3a1ed052eb1ac2e8c0d08931d3eTadashi G. Takaoka final MoreKeysKeyboardAccessibilityDelegate accessibilityDelegate = mAccessibilityDelegate; 11462316d7e821fa3a1ed052eb1ac2e8c0d08931d3eTadashi G. Takaoka if (accessibilityDelegate != null) { 11562316d7e821fa3a1ed052eb1ac2e8c0d08931d3eTadashi G. Takaoka accessibilityDelegate.onShowMoreKeysKeyboard(); 11662316d7e821fa3a1ed052eb1ac2e8c0d08931d3eTadashi G. Takaoka } 117f3f3189adbce15d609d5e06632f8e0630db890d1Tadashi G. Takaoka } 118f3f3189adbce15d609d5e06632f8e0630db890d1Tadashi G. Takaoka 11935580bad6f3da3b204653825bbb6871563e70728Tom Ouyang /** 12035580bad6f3da3b204653825bbb6871563e70728Tom Ouyang * Returns the default x coordinate for showing this panel. 12135580bad6f3da3b204653825bbb6871563e70728Tom Ouyang */ 12235580bad6f3da3b204653825bbb6871563e70728Tom Ouyang protected int getDefaultCoordX() { 12335580bad6f3da3b204653825bbb6871563e70728Tom Ouyang return ((MoreKeysKeyboard)getKeyboard()).getDefaultCoordX(); 12435580bad6f3da3b204653825bbb6871563e70728Tom Ouyang } 12535580bad6f3da3b204653825bbb6871563e70728Tom Ouyang 12635580bad6f3da3b204653825bbb6871563e70728Tom Ouyang @Override 12735580bad6f3da3b204653825bbb6871563e70728Tom Ouyang public void onDownEvent(final int x, final int y, final int pointerId, final long eventTime) { 12835580bad6f3da3b204653825bbb6871563e70728Tom Ouyang mActivePointerId = pointerId; 129adba09b54ed1b30bf9b24d632165229a0752b144Tadashi G. Takaoka mCurrentKey = detectKey(x, y); 13035580bad6f3da3b204653825bbb6871563e70728Tom Ouyang } 13135580bad6f3da3b204653825bbb6871563e70728Tom Ouyang 13235580bad6f3da3b204653825bbb6871563e70728Tom Ouyang @Override 133fa9b9578d44748de512c947651010e703c663936Tadashi G. Takaoka public void onMoveEvent(final int x, final int y, final int pointerId, final long eventTime) { 134ac69ab400d1ea4f90b4ca24486d62212decf1069Tom Ouyang if (mActivePointerId != pointerId) { 135ac69ab400d1ea4f90b4ca24486d62212decf1069Tom Ouyang return; 136ac69ab400d1ea4f90b4ca24486d62212decf1069Tom Ouyang } 137ac69ab400d1ea4f90b4ca24486d62212decf1069Tom Ouyang final boolean hasOldKey = (mCurrentKey != null); 138adba09b54ed1b30bf9b24d632165229a0752b144Tadashi G. Takaoka mCurrentKey = detectKey(x, y); 139ac69ab400d1ea4f90b4ca24486d62212decf1069Tom Ouyang if (hasOldKey && mCurrentKey == null) { 140fa9b9578d44748de512c947651010e703c663936Tadashi G. Takaoka // A more keys keyboard is canceled when detecting no key. 1411f215a58c99f0eb2f536e9cccd51371f2883e201Tadashi G. Takaoka mController.onCancelMoreKeysPanel(); 142ac69ab400d1ea4f90b4ca24486d62212decf1069Tom Ouyang } 14335580bad6f3da3b204653825bbb6871563e70728Tom Ouyang } 14435580bad6f3da3b204653825bbb6871563e70728Tom Ouyang 14535580bad6f3da3b204653825bbb6871563e70728Tom Ouyang @Override 14635580bad6f3da3b204653825bbb6871563e70728Tom Ouyang public void onUpEvent(final int x, final int y, final int pointerId, final long eventTime) { 147fa9b9578d44748de512c947651010e703c663936Tadashi G. Takaoka if (mActivePointerId != pointerId) { 148fa9b9578d44748de512c947651010e703c663936Tadashi G. Takaoka return; 149fa9b9578d44748de512c947651010e703c663936Tadashi G. Takaoka } 150fa9b9578d44748de512c947651010e703c663936Tadashi G. Takaoka // Calling {@link #detectKey(int,int,int)} here is harmless because the last move event and 151fa9b9578d44748de512c947651010e703c663936Tadashi G. Takaoka // the following up event share the same coordinates. 152adba09b54ed1b30bf9b24d632165229a0752b144Tadashi G. Takaoka mCurrentKey = detectKey(x, y); 153fa9b9578d44748de512c947651010e703c663936Tadashi G. Takaoka if (mCurrentKey != null) { 15435580bad6f3da3b204653825bbb6871563e70728Tom Ouyang updateReleaseKeyGraphics(mCurrentKey); 1555fc1510bc1cbe9bcd1105a403e07b5400470ae96Tadashi G. Takaoka onKeyInput(mCurrentKey, x, y); 15635580bad6f3da3b204653825bbb6871563e70728Tom Ouyang mCurrentKey = null; 15735580bad6f3da3b204653825bbb6871563e70728Tom Ouyang } 15835580bad6f3da3b204653825bbb6871563e70728Tom Ouyang } 15935580bad6f3da3b204653825bbb6871563e70728Tom Ouyang 16035580bad6f3da3b204653825bbb6871563e70728Tom Ouyang /** 16135580bad6f3da3b204653825bbb6871563e70728Tom Ouyang * Performs the specific action for this panel when the user presses a key on the panel. 16235580bad6f3da3b204653825bbb6871563e70728Tom Ouyang */ 1635fc1510bc1cbe9bcd1105a403e07b5400470ae96Tadashi G. Takaoka protected void onKeyInput(final Key key, final int x, final int y) { 1645fc1510bc1cbe9bcd1105a403e07b5400470ae96Tadashi G. Takaoka final int code = key.getCode(); 16535580bad6f3da3b204653825bbb6871563e70728Tom Ouyang if (code == Constants.CODE_OUTPUT_TEXT) { 16635580bad6f3da3b204653825bbb6871563e70728Tom Ouyang mListener.onTextInput(mCurrentKey.getOutputText()); 16735580bad6f3da3b204653825bbb6871563e70728Tom Ouyang } else if (code != Constants.CODE_UNSPECIFIED) { 168a91dfff5e54f68c4003327eeca47286084c35a2fJean Chalard if (getKeyboard().hasProximityCharsCorrection(code)) { 1692282e8520a2c1984989a14fb09896536f5033b26Jean Chalard mListener.onCodeInput(code, x, y, false /* isKeyRepeat */); 170a91dfff5e54f68c4003327eeca47286084c35a2fJean Chalard } else { 1712282e8520a2c1984989a14fb09896536f5033b26Jean Chalard mListener.onCodeInput(code, Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE, 1722282e8520a2c1984989a14fb09896536f5033b26Jean Chalard false /* isKeyRepeat */); 173a91dfff5e54f68c4003327eeca47286084c35a2fJean Chalard } 17435580bad6f3da3b204653825bbb6871563e70728Tom Ouyang } 17535580bad6f3da3b204653825bbb6871563e70728Tom Ouyang } 17635580bad6f3da3b204653825bbb6871563e70728Tom Ouyang 177adba09b54ed1b30bf9b24d632165229a0752b144Tadashi G. Takaoka private Key detectKey(int x, int y) { 17835580bad6f3da3b204653825bbb6871563e70728Tom Ouyang final Key oldKey = mCurrentKey; 17935580bad6f3da3b204653825bbb6871563e70728Tom Ouyang final Key newKey = mKeyDetector.detectHitKey(x, y); 180fa9b9578d44748de512c947651010e703c663936Tadashi G. Takaoka if (newKey == oldKey) { 181fa9b9578d44748de512c947651010e703c663936Tadashi G. Takaoka return newKey; 182fa9b9578d44748de512c947651010e703c663936Tadashi G. Takaoka } 183fa9b9578d44748de512c947651010e703c663936Tadashi G. Takaoka // A new key is detected. 184fa9b9578d44748de512c947651010e703c663936Tadashi G. Takaoka if (oldKey != null) { 185fa9b9578d44748de512c947651010e703c663936Tadashi G. Takaoka updateReleaseKeyGraphics(oldKey); 186fa9b9578d44748de512c947651010e703c663936Tadashi G. Takaoka invalidateKey(oldKey); 187fa9b9578d44748de512c947651010e703c663936Tadashi G. Takaoka } 188fa9b9578d44748de512c947651010e703c663936Tadashi G. Takaoka if (newKey != null) { 189fa9b9578d44748de512c947651010e703c663936Tadashi G. Takaoka updatePressKeyGraphics(newKey); 190fa9b9578d44748de512c947651010e703c663936Tadashi G. Takaoka invalidateKey(newKey); 19135580bad6f3da3b204653825bbb6871563e70728Tom Ouyang } 192fa9b9578d44748de512c947651010e703c663936Tadashi G. Takaoka return newKey; 19335580bad6f3da3b204653825bbb6871563e70728Tom Ouyang } 19435580bad6f3da3b204653825bbb6871563e70728Tom Ouyang 19535580bad6f3da3b204653825bbb6871563e70728Tom Ouyang private void updateReleaseKeyGraphics(final Key key) { 19635580bad6f3da3b204653825bbb6871563e70728Tom Ouyang key.onReleased(); 19735580bad6f3da3b204653825bbb6871563e70728Tom Ouyang invalidateKey(key); 19835580bad6f3da3b204653825bbb6871563e70728Tom Ouyang } 19935580bad6f3da3b204653825bbb6871563e70728Tom Ouyang 20035580bad6f3da3b204653825bbb6871563e70728Tom Ouyang private void updatePressKeyGraphics(final Key key) { 20135580bad6f3da3b204653825bbb6871563e70728Tom Ouyang key.onPressed(); 20235580bad6f3da3b204653825bbb6871563e70728Tom Ouyang invalidateKey(key); 20335580bad6f3da3b204653825bbb6871563e70728Tom Ouyang } 20435580bad6f3da3b204653825bbb6871563e70728Tom Ouyang 205ff082d081f3ea18ff0b9b22126ee4a86504cf83cTadashi G. Takaoka @Override 20609e4530ca75d4664eb72708face83b466839c522Tadashi G. Takaoka public void dismissMoreKeysPanel() { 20709e4530ca75d4664eb72708face83b466839c522Tadashi G. Takaoka if (!isShowingInParent()) { 20809e4530ca75d4664eb72708face83b466839c522Tadashi G. Takaoka return; 20909e4530ca75d4664eb72708face83b466839c522Tadashi G. Takaoka } 210a2e365da0acf80c1bcd8413d72f697a0da374779Tadashi G. Takaoka final MoreKeysKeyboardAccessibilityDelegate accessibilityDelegate = mAccessibilityDelegate; 211a2e365da0acf80c1bcd8413d72f697a0da374779Tadashi G. Takaoka if (accessibilityDelegate != null) { 212a2e365da0acf80c1bcd8413d72f697a0da374779Tadashi G. Takaoka accessibilityDelegate.onDismissMoreKeysKeyboard(); 213a2e365da0acf80c1bcd8413d72f697a0da374779Tadashi G. Takaoka } 2141f215a58c99f0eb2f536e9cccd51371f2883e201Tadashi G. Takaoka mController.onDismissMoreKeysPanel(); 2159ec80d9d89eb599329c354451acdc482cc3de836Tadashi G. Takaoka } 2169ec80d9d89eb599329c354451acdc482cc3de836Tadashi G. Takaoka 2179ec80d9d89eb599329c354451acdc482cc3de836Tadashi G. Takaoka @Override 218bc464e2952e102219f0b977fc1e9140ad5bd03e4Tadashi G. Takaoka public int translateX(final int x) { 21963c233ab9f50d844be6e52e382c6664475606760Tadashi G. Takaoka return x - mOriginX; 22063c233ab9f50d844be6e52e382c6664475606760Tadashi G. Takaoka } 22163c233ab9f50d844be6e52e382c6664475606760Tadashi G. Takaoka 22263c233ab9f50d844be6e52e382c6664475606760Tadashi G. Takaoka @Override 223bc464e2952e102219f0b977fc1e9140ad5bd03e4Tadashi G. Takaoka public int translateY(final int y) { 22463c233ab9f50d844be6e52e382c6664475606760Tadashi G. Takaoka return y - mOriginY; 225ff082d081f3ea18ff0b9b22126ee4a86504cf83cTadashi G. Takaoka } 226fa2d543785c52f639ad3157c57420f58a199c550Tom Ouyang 227fa2d543785c52f639ad3157c57420f58a199c550Tom Ouyang @Override 22835580bad6f3da3b204653825bbb6871563e70728Tom Ouyang public boolean onTouchEvent(final MotionEvent me) { 22935580bad6f3da3b204653825bbb6871563e70728Tom Ouyang final int action = me.getActionMasked(); 23035580bad6f3da3b204653825bbb6871563e70728Tom Ouyang final long eventTime = me.getEventTime(); 23135580bad6f3da3b204653825bbb6871563e70728Tom Ouyang final int index = me.getActionIndex(); 23235580bad6f3da3b204653825bbb6871563e70728Tom Ouyang final int x = (int)me.getX(index); 23335580bad6f3da3b204653825bbb6871563e70728Tom Ouyang final int y = (int)me.getY(index); 23435580bad6f3da3b204653825bbb6871563e70728Tom Ouyang final int pointerId = me.getPointerId(index); 23535580bad6f3da3b204653825bbb6871563e70728Tom Ouyang switch (action) { 23635580bad6f3da3b204653825bbb6871563e70728Tom Ouyang case MotionEvent.ACTION_DOWN: 23735580bad6f3da3b204653825bbb6871563e70728Tom Ouyang case MotionEvent.ACTION_POINTER_DOWN: 23835580bad6f3da3b204653825bbb6871563e70728Tom Ouyang onDownEvent(x, y, pointerId, eventTime); 23935580bad6f3da3b204653825bbb6871563e70728Tom Ouyang break; 24035580bad6f3da3b204653825bbb6871563e70728Tom Ouyang case MotionEvent.ACTION_UP: 24135580bad6f3da3b204653825bbb6871563e70728Tom Ouyang case MotionEvent.ACTION_POINTER_UP: 24235580bad6f3da3b204653825bbb6871563e70728Tom Ouyang onUpEvent(x, y, pointerId, eventTime); 24335580bad6f3da3b204653825bbb6871563e70728Tom Ouyang break; 24435580bad6f3da3b204653825bbb6871563e70728Tom Ouyang case MotionEvent.ACTION_MOVE: 24535580bad6f3da3b204653825bbb6871563e70728Tom Ouyang onMoveEvent(x, y, pointerId, eventTime); 24635580bad6f3da3b204653825bbb6871563e70728Tom Ouyang break; 24735580bad6f3da3b204653825bbb6871563e70728Tom Ouyang } 24833482a9b9ccf605c63fab7c9b8273a240bbc2035Tadashi G. Takaoka return true; 24935580bad6f3da3b204653825bbb6871563e70728Tom Ouyang } 25035580bad6f3da3b204653825bbb6871563e70728Tom Ouyang 25162316d7e821fa3a1ed052eb1ac2e8c0d08931d3eTadashi G. Takaoka /** 25262316d7e821fa3a1ed052eb1ac2e8c0d08931d3eTadashi G. Takaoka * {@inheritDoc} 25362316d7e821fa3a1ed052eb1ac2e8c0d08931d3eTadashi G. Takaoka */ 25462316d7e821fa3a1ed052eb1ac2e8c0d08931d3eTadashi G. Takaoka @Override 25562316d7e821fa3a1ed052eb1ac2e8c0d08931d3eTadashi G. Takaoka public boolean onHoverEvent(final MotionEvent event) { 25662316d7e821fa3a1ed052eb1ac2e8c0d08931d3eTadashi G. Takaoka final MoreKeysKeyboardAccessibilityDelegate accessibilityDelegate = mAccessibilityDelegate; 25762316d7e821fa3a1ed052eb1ac2e8c0d08931d3eTadashi G. Takaoka if (accessibilityDelegate != null) { 25862316d7e821fa3a1ed052eb1ac2e8c0d08931d3eTadashi G. Takaoka return accessibilityDelegate.onHoverEvent(event); 25962316d7e821fa3a1ed052eb1ac2e8c0d08931d3eTadashi G. Takaoka } 26062316d7e821fa3a1ed052eb1ac2e8c0d08931d3eTadashi G. Takaoka return super.onHoverEvent(event); 26162316d7e821fa3a1ed052eb1ac2e8c0d08931d3eTadashi G. Takaoka } 26262316d7e821fa3a1ed052eb1ac2e8c0d08931d3eTadashi G. Takaoka 2637f8345d59a82a9b1d458b8e55ffd12c2a0d466a7Tadashi G. Takaoka private View getContainerView() { 264fa2d543785c52f639ad3157c57420f58a199c550Tom Ouyang return (View)getParent(); 265fa2d543785c52f639ad3157c57420f58a199c550Tom Ouyang } 266fa2d543785c52f639ad3157c57420f58a199c550Tom Ouyang 267fa2d543785c52f639ad3157c57420f58a199c550Tom Ouyang @Override 2687f8345d59a82a9b1d458b8e55ffd12c2a0d466a7Tadashi G. Takaoka public void showInParent(final ViewGroup parentView) { 2697f8345d59a82a9b1d458b8e55ffd12c2a0d466a7Tadashi G. Takaoka removeFromParent(); 2707f8345d59a82a9b1d458b8e55ffd12c2a0d466a7Tadashi G. Takaoka parentView.addView(getContainerView()); 2717f8345d59a82a9b1d458b8e55ffd12c2a0d466a7Tadashi G. Takaoka } 2727f8345d59a82a9b1d458b8e55ffd12c2a0d466a7Tadashi G. Takaoka 2737f8345d59a82a9b1d458b8e55ffd12c2a0d466a7Tadashi G. Takaoka @Override 2747f8345d59a82a9b1d458b8e55ffd12c2a0d466a7Tadashi G. Takaoka public void removeFromParent() { 2757f8345d59a82a9b1d458b8e55ffd12c2a0d466a7Tadashi G. Takaoka final View containerView = getContainerView(); 2767f8345d59a82a9b1d458b8e55ffd12c2a0d466a7Tadashi G. Takaoka final ViewGroup currentParent = (ViewGroup)containerView.getParent(); 2777f8345d59a82a9b1d458b8e55ffd12c2a0d466a7Tadashi G. Takaoka if (currentParent != null) { 2787f8345d59a82a9b1d458b8e55ffd12c2a0d466a7Tadashi G. Takaoka currentParent.removeView(containerView); 2797f8345d59a82a9b1d458b8e55ffd12c2a0d466a7Tadashi G. Takaoka } 2807f8345d59a82a9b1d458b8e55ffd12c2a0d466a7Tadashi G. Takaoka } 2817f8345d59a82a9b1d458b8e55ffd12c2a0d466a7Tadashi G. Takaoka 2827f8345d59a82a9b1d458b8e55ffd12c2a0d466a7Tadashi G. Takaoka @Override 283fa2d543785c52f639ad3157c57420f58a199c550Tom Ouyang public boolean isShowingInParent() { 284fa2d543785c52f639ad3157c57420f58a199c550Tom Ouyang return (getContainerView().getParent() != null); 285fa2d543785c52f639ad3157c57420f58a199c550Tom Ouyang } 286ff082d081f3ea18ff0b9b22126ee4a86504cf83cTadashi G. Takaoka} 287