1/* 2 * Copyright (C) 2010 Google Inc. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 * use this file except in compliance with the License. You may obtain a copy of 6 * the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 * License for the specific language governing permissions and limitations under 14 * the License. 15 */ 16 17package com.android.inputmethod.latin; 18 19import android.inputmethodservice.Keyboard.Key; 20 21import java.util.Arrays; 22 23class ProximityKeyDetector extends KeyDetector { 24 private static final int MAX_NEARBY_KEYS = 12; 25 26 // working area 27 private int[] mDistances = new int[MAX_NEARBY_KEYS]; 28 29 @Override 30 protected int getMaxNearbyKeys() { 31 return MAX_NEARBY_KEYS; 32 } 33 34 @Override 35 public int getKeyIndexAndNearbyCodes(int x, int y, int[] allKeys) { 36 final Key[] keys = getKeys(); 37 final int touchX = getTouchX(x); 38 final int touchY = getTouchY(y); 39 int primaryIndex = LatinKeyboardBaseView.NOT_A_KEY; 40 int closestKey = LatinKeyboardBaseView.NOT_A_KEY; 41 int closestKeyDist = mProximityThresholdSquare + 1; 42 int[] distances = mDistances; 43 Arrays.fill(distances, Integer.MAX_VALUE); 44 int [] nearestKeyIndices = mKeyboard.getNearestKeys(touchX, touchY); 45 final int keyCount = nearestKeyIndices.length; 46 for (int i = 0; i < keyCount; i++) { 47 final Key key = keys[nearestKeyIndices[i]]; 48 int dist = 0; 49 boolean isInside = key.isInside(touchX, touchY); 50 if (isInside) { 51 primaryIndex = nearestKeyIndices[i]; 52 } 53 54 if (((mProximityCorrectOn 55 && (dist = key.squaredDistanceFrom(touchX, touchY)) < mProximityThresholdSquare) 56 || isInside) 57 && key.codes[0] > 32) { 58 // Find insertion point 59 final int nCodes = key.codes.length; 60 if (dist < closestKeyDist) { 61 closestKeyDist = dist; 62 closestKey = nearestKeyIndices[i]; 63 } 64 65 if (allKeys == null) continue; 66 67 for (int j = 0; j < distances.length; j++) { 68 if (distances[j] > dist) { 69 // Make space for nCodes codes 70 System.arraycopy(distances, j, distances, j + nCodes, 71 distances.length - j - nCodes); 72 System.arraycopy(allKeys, j, allKeys, j + nCodes, 73 allKeys.length - j - nCodes); 74 System.arraycopy(key.codes, 0, allKeys, j, nCodes); 75 Arrays.fill(distances, j, j + nCodes, dist); 76 break; 77 } 78 } 79 } 80 } 81 if (primaryIndex == LatinKeyboardBaseView.NOT_A_KEY) { 82 primaryIndex = closestKey; 83 } 84 return primaryIndex; 85 } 86} 87