KeyDetector.java revision 5c641a9f59735f0eaa772bde027993275b1bdfd7
1/* 2 * Copyright (C) 2010 The Android Open Source Project 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.keyboard; 18 19 20public class KeyDetector { 21 public static final int NOT_A_CODE = -1; 22 23 private final int mKeyHysteresisDistanceSquared; 24 25 private Keyboard mKeyboard; 26 private int mCorrectionX; 27 private int mCorrectionY; 28 private boolean mProximityCorrectOn; 29 30 /** 31 * This class handles key detection. 32 * 33 * @param keyHysteresisDistance if the pointer movement distance is smaller than this, the 34 * movement will not been handled as meaningful movement. The unit is pixel. 35 */ 36 public KeyDetector(float keyHysteresisDistance) { 37 mKeyHysteresisDistanceSquared = (int)(keyHysteresisDistance * keyHysteresisDistance); 38 } 39 40 public void setKeyboard(Keyboard keyboard, float correctionX, float correctionY) { 41 if (keyboard == null) 42 throw new NullPointerException(); 43 mCorrectionX = (int)correctionX; 44 mCorrectionY = (int)correctionY; 45 mKeyboard = keyboard; 46 } 47 48 public int getKeyHysteresisDistanceSquared() { 49 return mKeyHysteresisDistanceSquared; 50 } 51 52 public int getTouchX(int x) { 53 return x + mCorrectionX; 54 } 55 56 // TODO: Remove vertical correction. 57 public int getTouchY(int y) { 58 return y + mCorrectionY; 59 } 60 61 public Keyboard getKeyboard() { 62 if (mKeyboard == null) 63 throw new IllegalStateException("keyboard isn't set"); 64 return mKeyboard; 65 } 66 67 public void setProximityCorrectionEnabled(boolean enabled) { 68 mProximityCorrectOn = enabled; 69 } 70 71 public boolean isProximityCorrectionEnabled() { 72 return mProximityCorrectOn; 73 } 74 75 public boolean alwaysAllowsSlidingInput() { 76 return false; 77 } 78 79 /** 80 * Detect the key whose hitbox the touch point is in. 81 * 82 * @param x The x-coordinate of a touch point 83 * @param y The y-coordinate of a touch point 84 * @return the key that the touch point hits. 85 */ 86 public Key detectHitKey(int x, int y) { 87 final int touchX = getTouchX(x); 88 final int touchY = getTouchY(y); 89 90 int minDistance = Integer.MAX_VALUE; 91 Key primaryKey = null; 92 for (final Key key: mKeyboard.getNearestKeys(touchX, touchY)) { 93 final boolean isOnKey = key.isOnKey(touchX, touchY); 94 final int distance = key.squaredDistanceToEdge(touchX, touchY); 95 // To take care of hitbox overlaps, we compare mCode here too. 96 if (primaryKey == null || distance < minDistance 97 || (distance == minDistance && isOnKey && key.mCode > primaryKey.mCode)) { 98 minDistance = distance; 99 primaryKey = key; 100 } 101 } 102 return primaryKey; 103 } 104 105 public static String printableCode(Key key) { 106 return key != null ? Keyboard.printableCode(key.mCode) : "none"; 107 } 108 109 public static String printableCodes(int[] codes) { 110 final StringBuilder sb = new StringBuilder(); 111 boolean addDelimiter = false; 112 for (final int code : codes) { 113 if (code == NOT_A_CODE) break; 114 if (addDelimiter) sb.append(", "); 115 sb.append(Keyboard.printableCode(code)); 116 addDelimiter = true; 117 } 118 return "[" + sb + "]"; 119 } 120} 121