12085d43daf44752deae1b6b00a14cb0f517d69cbTadashi G. Takaoka/* 28632bff2d5a8e1160989008dea6eff4b94b065ddTadashi G. Takaoka * Copyright (C) 2010 The Android Open Source Project 32085d43daf44752deae1b6b00a14cb0f517d69cbTadashi G. Takaoka * 42085d43daf44752deae1b6b00a14cb0f517d69cbTadashi G. Takaoka * Licensed under the Apache License, Version 2.0 (the "License"); you may not 52085d43daf44752deae1b6b00a14cb0f517d69cbTadashi G. Takaoka * use this file except in compliance with the License. You may obtain a copy of 62085d43daf44752deae1b6b00a14cb0f517d69cbTadashi G. Takaoka * the License at 72085d43daf44752deae1b6b00a14cb0f517d69cbTadashi G. Takaoka * 82085d43daf44752deae1b6b00a14cb0f517d69cbTadashi G. Takaoka * http://www.apache.org/licenses/LICENSE-2.0 92085d43daf44752deae1b6b00a14cb0f517d69cbTadashi G. Takaoka * 102085d43daf44752deae1b6b00a14cb0f517d69cbTadashi G. Takaoka * Unless required by applicable law or agreed to in writing, software 112085d43daf44752deae1b6b00a14cb0f517d69cbTadashi G. Takaoka * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 122085d43daf44752deae1b6b00a14cb0f517d69cbTadashi G. Takaoka * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 132085d43daf44752deae1b6b00a14cb0f517d69cbTadashi G. Takaoka * License for the specific language governing permissions and limitations under 142085d43daf44752deae1b6b00a14cb0f517d69cbTadashi G. Takaoka * the License. 152085d43daf44752deae1b6b00a14cb0f517d69cbTadashi G. Takaoka */ 162085d43daf44752deae1b6b00a14cb0f517d69cbTadashi G. Takaoka 175a309f57155fb95667c2ccdda730eaf175de8876Tadashi G. Takaokapackage com.android.inputmethod.keyboard; 182085d43daf44752deae1b6b00a14cb0f517d69cbTadashi G. Takaoka 19dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaokaimport android.util.Log; 20dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka 216bfb234f294b6ad95176f987256c85e8607d23f5Tadashi G. Takaokaimport java.util.Arrays; 222085d43daf44752deae1b6b00a14cb0f517d69cbTadashi G. Takaokaimport java.util.List; 232085d43daf44752deae1b6b00a14cb0f517d69cbTadashi G. Takaoka 24dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaokapublic class KeyDetector { 25dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka private static final String TAG = KeyDetector.class.getSimpleName(); 26dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka private static final boolean DEBUG = false; 270529a04b6aece3db34b4e7c895c67ad0858c8bd9Tadashi G. Takaoka 28dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka public static final int NOT_A_CODE = -1; 29dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka public static final int NOT_A_KEY = -1; 300529a04b6aece3db34b4e7c895c67ad0858c8bd9Tadashi G. Takaoka 31a19b84dcf65bd70caa0fc72089cfe043b023a898Tadashi G. Takaoka private final int mKeyHysteresisDistanceSquared; 32a19b84dcf65bd70caa0fc72089cfe043b023a898Tadashi G. Takaoka 33dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka private Keyboard mKeyboard; 34dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka private int mCorrectionX; 35dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka private int mCorrectionY; 36dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka private boolean mProximityCorrectOn; 37dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka private int mProximityThresholdSquare; 380529a04b6aece3db34b4e7c895c67ad0858c8bd9Tadashi G. Takaoka 39dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka // working area 40dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka private static final int MAX_NEARBY_KEYS = 12; 41dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka private final int[] mDistances = new int[MAX_NEARBY_KEYS]; 42dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka private final int[] mIndices = new int[MAX_NEARBY_KEYS]; 432085d43daf44752deae1b6b00a14cb0f517d69cbTadashi G. Takaoka 44a19b84dcf65bd70caa0fc72089cfe043b023a898Tadashi G. Takaoka /** 45a19b84dcf65bd70caa0fc72089cfe043b023a898Tadashi G. Takaoka * This class handles key detection. 46a19b84dcf65bd70caa0fc72089cfe043b023a898Tadashi G. Takaoka * 47a19b84dcf65bd70caa0fc72089cfe043b023a898Tadashi G. Takaoka * @param keyHysteresisDistance if the pointer movement distance is smaller than this, the 48a19b84dcf65bd70caa0fc72089cfe043b023a898Tadashi G. Takaoka * movement will not been handled as meaningful movement. The unit is pixel. 49a19b84dcf65bd70caa0fc72089cfe043b023a898Tadashi G. Takaoka */ 50a19b84dcf65bd70caa0fc72089cfe043b023a898Tadashi G. Takaoka public KeyDetector(float keyHysteresisDistance) { 51a19b84dcf65bd70caa0fc72089cfe043b023a898Tadashi G. Takaoka mKeyHysteresisDistanceSquared = (int)(keyHysteresisDistance * keyHysteresisDistance); 52a19b84dcf65bd70caa0fc72089cfe043b023a898Tadashi G. Takaoka } 53a19b84dcf65bd70caa0fc72089cfe043b023a898Tadashi G. Takaoka 54dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka public void setKeyboard(Keyboard keyboard, float correctionX, float correctionY) { 552085d43daf44752deae1b6b00a14cb0f517d69cbTadashi G. Takaoka if (keyboard == null) 562085d43daf44752deae1b6b00a14cb0f517d69cbTadashi G. Takaoka throw new NullPointerException(); 57400046d62e22899e28efd2a62321c637c7831f81Tadashi G. Takaoka mCorrectionX = (int)correctionX; 58400046d62e22899e28efd2a62321c637c7831f81Tadashi G. Takaoka mCorrectionY = (int)correctionY; 592085d43daf44752deae1b6b00a14cb0f517d69cbTadashi G. Takaoka mKeyboard = keyboard; 608da9a13760896cd78235b60d0ea680ea13620532Tadashi G. Takaoka final int threshold = keyboard.mMostCommonKeyWidth; 61a19b84dcf65bd70caa0fc72089cfe043b023a898Tadashi G. Takaoka mProximityThresholdSquare = threshold * threshold; 62a19b84dcf65bd70caa0fc72089cfe043b023a898Tadashi G. Takaoka } 63a19b84dcf65bd70caa0fc72089cfe043b023a898Tadashi G. Takaoka 64a19b84dcf65bd70caa0fc72089cfe043b023a898Tadashi G. Takaoka public int getKeyHysteresisDistanceSquared() { 65a19b84dcf65bd70caa0fc72089cfe043b023a898Tadashi G. Takaoka return mKeyHysteresisDistanceSquared; 662085d43daf44752deae1b6b00a14cb0f517d69cbTadashi G. Takaoka } 672085d43daf44752deae1b6b00a14cb0f517d69cbTadashi G. Takaoka 68400046d62e22899e28efd2a62321c637c7831f81Tadashi G. Takaoka protected int getTouchX(int x) { 69400046d62e22899e28efd2a62321c637c7831f81Tadashi G. Takaoka return x + mCorrectionX; 70400046d62e22899e28efd2a62321c637c7831f81Tadashi G. Takaoka } 71400046d62e22899e28efd2a62321c637c7831f81Tadashi G. Takaoka 72400046d62e22899e28efd2a62321c637c7831f81Tadashi G. Takaoka protected int getTouchY(int y) { 73400046d62e22899e28efd2a62321c637c7831f81Tadashi G. Takaoka return y + mCorrectionY; 74400046d62e22899e28efd2a62321c637c7831f81Tadashi G. Takaoka } 75400046d62e22899e28efd2a62321c637c7831f81Tadashi G. Takaoka 765a7a696aff6718d4e0250c394a9d01cbf2a16916Tadashi G. Takaoka public Keyboard getKeyboard() { 77dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka if (mKeyboard == null) 786bfb234f294b6ad95176f987256c85e8607d23f5Tadashi G. Takaoka throw new IllegalStateException("keyboard isn't set"); 795a7a696aff6718d4e0250c394a9d01cbf2a16916Tadashi G. Takaoka return mKeyboard; 806bfb234f294b6ad95176f987256c85e8607d23f5Tadashi G. Takaoka } 816bfb234f294b6ad95176f987256c85e8607d23f5Tadashi G. Takaoka 822085d43daf44752deae1b6b00a14cb0f517d69cbTadashi G. Takaoka public void setProximityCorrectionEnabled(boolean enabled) { 832085d43daf44752deae1b6b00a14cb0f517d69cbTadashi G. Takaoka mProximityCorrectOn = enabled; 842085d43daf44752deae1b6b00a14cb0f517d69cbTadashi G. Takaoka } 852085d43daf44752deae1b6b00a14cb0f517d69cbTadashi G. Takaoka 862085d43daf44752deae1b6b00a14cb0f517d69cbTadashi G. Takaoka public boolean isProximityCorrectionEnabled() { 872085d43daf44752deae1b6b00a14cb0f517d69cbTadashi G. Takaoka return mProximityCorrectOn; 882085d43daf44752deae1b6b00a14cb0f517d69cbTadashi G. Takaoka } 892085d43daf44752deae1b6b00a14cb0f517d69cbTadashi G. Takaoka 902085d43daf44752deae1b6b00a14cb0f517d69cbTadashi G. Takaoka public void setProximityThreshold(int threshold) { 912085d43daf44752deae1b6b00a14cb0f517d69cbTadashi G. Takaoka mProximityThresholdSquare = threshold * threshold; 922085d43daf44752deae1b6b00a14cb0f517d69cbTadashi G. Takaoka } 932085d43daf44752deae1b6b00a14cb0f517d69cbTadashi G. Takaoka 9432572948d7e3956efebcbd69d7c7d8403bb659e6Tadashi G. Takaoka public boolean alwaysAllowsSlidingInput() { 9532572948d7e3956efebcbd69d7c7d8403bb659e6Tadashi G. Takaoka return false; 9632572948d7e3956efebcbd69d7c7d8403bb659e6Tadashi G. Takaoka } 9732572948d7e3956efebcbd69d7c7d8403bb659e6Tadashi G. Takaoka 980529a04b6aece3db34b4e7c895c67ad0858c8bd9Tadashi G. Takaoka /** 99dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka * Computes maximum size of the array that can contain all nearby key indices returned by 100dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka * {@link #getKeyIndexAndNearbyCodes}. 101dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka * 102dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka * @return Returns maximum size of the array that can contain all nearby key indices returned 103dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka * by {@link #getKeyIndexAndNearbyCodes}. 104dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka */ 105dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka protected int getMaxNearbyKeys() { 106dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka return MAX_NEARBY_KEYS; 107dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka } 108dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka 109dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka /** 1100529a04b6aece3db34b4e7c895c67ad0858c8bd9Tadashi G. Takaoka * Allocates array that can hold all key indices returned by {@link #getKeyIndexAndNearbyCodes} 1110529a04b6aece3db34b4e7c895c67ad0858c8bd9Tadashi G. Takaoka * method. The maximum size of the array should be computed by {@link #getMaxNearbyKeys}. 1120529a04b6aece3db34b4e7c895c67ad0858c8bd9Tadashi G. Takaoka * 1130529a04b6aece3db34b4e7c895c67ad0858c8bd9Tadashi G. Takaoka * @return Allocates and returns an array that can hold all key indices returned by 1140529a04b6aece3db34b4e7c895c67ad0858c8bd9Tadashi G. Takaoka * {@link #getKeyIndexAndNearbyCodes} method. All elements in the returned array are 11544fe4a0598d831ad33e62cd7742709fd45c60387Tadashi G. Takaoka * initialized by {@link #NOT_A_CODE} value. 1160529a04b6aece3db34b4e7c895c67ad0858c8bd9Tadashi G. Takaoka */ 1176bfb234f294b6ad95176f987256c85e8607d23f5Tadashi G. Takaoka public int[] newCodeArray() { 1186bfb234f294b6ad95176f987256c85e8607d23f5Tadashi G. Takaoka int[] codes = new int[getMaxNearbyKeys()]; 11944fe4a0598d831ad33e62cd7742709fd45c60387Tadashi G. Takaoka Arrays.fill(codes, NOT_A_CODE); 1206bfb234f294b6ad95176f987256c85e8607d23f5Tadashi G. Takaoka return codes; 1216bfb234f294b6ad95176f987256c85e8607d23f5Tadashi G. Takaoka } 1226bfb234f294b6ad95176f987256c85e8607d23f5Tadashi G. Takaoka 123dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka private void initializeNearbyKeys() { 124dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka Arrays.fill(mDistances, Integer.MAX_VALUE); 125dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka Arrays.fill(mIndices, NOT_A_KEY); 126dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka } 127dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka 1280529a04b6aece3db34b4e7c895c67ad0858c8bd9Tadashi G. Takaoka /** 129dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka * Insert the key into nearby keys buffer and sort nearby keys by ascending order of distance. 13044fe4a0598d831ad33e62cd7742709fd45c60387Tadashi G. Takaoka * If the distance of two keys are the same, the key which the point is on should be considered 13144fe4a0598d831ad33e62cd7742709fd45c60387Tadashi G. Takaoka * as a closer one. 1320529a04b6aece3db34b4e7c895c67ad0858c8bd9Tadashi G. Takaoka * 133dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka * @param keyIndex index of the key. 134dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka * @param distance distance between the key's edge and user touched point. 13544fe4a0598d831ad33e62cd7742709fd45c60387Tadashi G. Takaoka * @param isOnKey true if the point is on the key. 136dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka * @return order of the key in the nearby buffer, 0 if it is the nearest key. 1370529a04b6aece3db34b4e7c895c67ad0858c8bd9Tadashi G. Takaoka */ 13844fe4a0598d831ad33e62cd7742709fd45c60387Tadashi G. Takaoka private int sortNearbyKeys(int keyIndex, int distance, boolean isOnKey) { 139dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka final int[] distances = mDistances; 140dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka final int[] indices = mIndices; 141dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka for (int insertPos = 0; insertPos < distances.length; insertPos++) { 14244fe4a0598d831ad33e62cd7742709fd45c60387Tadashi G. Takaoka final int comparingDistance = distances[insertPos]; 14344fe4a0598d831ad33e62cd7742709fd45c60387Tadashi G. Takaoka if (distance < comparingDistance || (distance == comparingDistance && isOnKey)) { 144dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka final int nextPos = insertPos + 1; 145dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka if (nextPos < distances.length) { 146dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka System.arraycopy(distances, insertPos, distances, nextPos, 147dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka distances.length - nextPos); 148dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka System.arraycopy(indices, insertPos, indices, nextPos, 149dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka indices.length - nextPos); 150dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka } 151dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka distances[insertPos] = distance; 152dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka indices[insertPos] = keyIndex; 153dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka return insertPos; 154dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka } 155dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka } 156dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka return distances.length; 157dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka } 158dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka 159dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka private void getNearbyKeyCodes(final int[] allCodes) { 1601be29abab2e112f0253a8a5da3478740bb866d27Tadashi G. Takaoka final List<Key> keys = getKeyboard().mKeys; 161dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka final int[] indices = mIndices; 162dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka 163dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka // allCodes[0] should always have the key code even if it is a non-letter key. 164dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka if (indices[0] == NOT_A_KEY) { 165dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka allCodes[0] = NOT_A_CODE; 166dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka return; 167dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka } 168dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka 169dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka int numCodes = 0; 170dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka for (int j = 0; j < indices.length && numCodes < allCodes.length; j++) { 171dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka final int index = indices[j]; 172dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka if (index == NOT_A_KEY) 173dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka break; 174dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka final int code = keys.get(index).mCode; 175dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka // filter out a non-letter key from nearby keys 176dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka if (code < Keyboard.CODE_SPACE) 177dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka continue; 178dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka allCodes[numCodes++] = code; 179dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka } 180dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka } 1812085d43daf44752deae1b6b00a14cb0f517d69cbTadashi G. Takaoka 1820529a04b6aece3db34b4e7c895c67ad0858c8bd9Tadashi G. Takaoka /** 1830529a04b6aece3db34b4e7c895c67ad0858c8bd9Tadashi G. Takaoka * Finds all possible nearby key indices around a touch event point and returns the nearest key 1840529a04b6aece3db34b4e7c895c67ad0858c8bd9Tadashi G. Takaoka * index. The algorithm to determine the nearby keys depends on the threshold set by 1850529a04b6aece3db34b4e7c895c67ad0858c8bd9Tadashi G. Takaoka * {@link #setProximityThreshold(int)} and the mode set by 1860529a04b6aece3db34b4e7c895c67ad0858c8bd9Tadashi G. Takaoka * {@link #setProximityCorrectionEnabled(boolean)}. 1870529a04b6aece3db34b4e7c895c67ad0858c8bd9Tadashi G. Takaoka * 1880529a04b6aece3db34b4e7c895c67ad0858c8bd9Tadashi G. Takaoka * @param x The x-coordinate of a touch point 1890529a04b6aece3db34b4e7c895c67ad0858c8bd9Tadashi G. Takaoka * @param y The y-coordinate of a touch point 190887f11ee43ad621aa6ad93d535ab7f48dec73fc7Tadashi G. Takaoka * @param allCodes All nearby key code except functional key are returned in this array 1910529a04b6aece3db34b4e7c895c67ad0858c8bd9Tadashi G. Takaoka * @return The nearest key index 1920529a04b6aece3db34b4e7c895c67ad0858c8bd9Tadashi G. Takaoka */ 193dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka public int getKeyIndexAndNearbyCodes(int x, int y, final int[] allCodes) { 1941be29abab2e112f0253a8a5da3478740bb866d27Tadashi G. Takaoka final List<Key> keys = getKeyboard().mKeys; 195dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka final int touchX = getTouchX(x); 196dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka final int touchY = getTouchY(y); 197dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka 198dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka initializeNearbyKeys(); 199dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka int primaryIndex = NOT_A_KEY; 200dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka for (final int index : mKeyboard.getNearestKeys(touchX, touchY)) { 201dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka final Key key = keys.get(index); 20244fe4a0598d831ad33e62cd7742709fd45c60387Tadashi G. Takaoka final boolean isOnKey = key.isOnKey(touchX, touchY); 203dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka final int distance = key.squaredDistanceToEdge(touchX, touchY); 20444fe4a0598d831ad33e62cd7742709fd45c60387Tadashi G. Takaoka if (isOnKey || (mProximityCorrectOn && distance < mProximityThresholdSquare)) { 20544fe4a0598d831ad33e62cd7742709fd45c60387Tadashi G. Takaoka final int insertedPosition = sortNearbyKeys(index, distance, isOnKey); 20644fe4a0598d831ad33e62cd7742709fd45c60387Tadashi G. Takaoka if (insertedPosition == 0 && isOnKey) 207dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka primaryIndex = index; 208dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka } 209dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka } 210dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka 211dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka if (allCodes != null && allCodes.length > 0) { 212dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka getNearbyKeyCodes(allCodes); 213dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka if (DEBUG) { 214dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka Log.d(TAG, "x=" + x + " y=" + y 215dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka + " primary=" 216dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka + (primaryIndex == NOT_A_KEY ? "none" : keys.get(primaryIndex).mCode) 217dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka + " codes=" + Arrays.toString(allCodes)); 218dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka } 219dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka } 220dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka 221dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka return primaryIndex; 222dc90d0a15f662cdece97bc2c0ddbd95e703af730Tadashi G. Takaoka } 2230529a04b6aece3db34b4e7c895c67ad0858c8bd9Tadashi G. Takaoka} 224