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 17 package com.android.inputmethod.keyboard; 18 19 20 public 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 */ KeyDetector(float keyHysteresisDistance)36 public KeyDetector(float keyHysteresisDistance) { 37 mKeyHysteresisDistanceSquared = (int)(keyHysteresisDistance * keyHysteresisDistance); 38 } 39 setKeyboard(Keyboard keyboard, float correctionX, float correctionY)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 getKeyHysteresisDistanceSquared()48 public int getKeyHysteresisDistanceSquared() { 49 return mKeyHysteresisDistanceSquared; 50 } 51 getTouchX(int x)52 public int getTouchX(int x) { 53 return x + mCorrectionX; 54 } 55 getTouchY(int y)56 public int getTouchY(int y) { 57 return y + mCorrectionY; 58 } 59 getKeyboard()60 public Keyboard getKeyboard() { 61 if (mKeyboard == null) 62 throw new IllegalStateException("keyboard isn't set"); 63 return mKeyboard; 64 } 65 setProximityCorrectionEnabled(boolean enabled)66 public void setProximityCorrectionEnabled(boolean enabled) { 67 mProximityCorrectOn = enabled; 68 } 69 isProximityCorrectionEnabled()70 public boolean isProximityCorrectionEnabled() { 71 return mProximityCorrectOn; 72 } 73 alwaysAllowsSlidingInput()74 public boolean alwaysAllowsSlidingInput() { 75 return false; 76 } 77 78 /** 79 * Detect the key whose hitbox the touch point is in. 80 * 81 * @param x The x-coordinate of a touch point 82 * @param y The y-coordinate of a touch point 83 * @return the key that the touch point hits. 84 */ detectHitKey(int x, int y)85 public Key detectHitKey(int x, int y) { 86 final int touchX = getTouchX(x); 87 final int touchY = getTouchY(y); 88 89 int minDistance = Integer.MAX_VALUE; 90 Key primaryKey = null; 91 for (final Key key: mKeyboard.getNearestKeys(touchX, touchY)) { 92 final boolean isOnKey = key.isOnKey(touchX, touchY); 93 final int distance = key.squaredDistanceToEdge(touchX, touchY); 94 // To take care of hitbox overlaps, we compare mCode here too. 95 if (primaryKey == null || distance < minDistance 96 || (distance == minDistance && isOnKey && key.mCode > primaryKey.mCode)) { 97 minDistance = distance; 98 primaryKey = key; 99 } 100 } 101 return primaryKey; 102 } 103 printableCode(Key key)104 public static String printableCode(Key key) { 105 return key != null ? Keyboard.printableCode(key.mCode) : "none"; 106 } 107 printableCodes(int[] codes)108 public static String printableCodes(int[] codes) { 109 final StringBuilder sb = new StringBuilder(); 110 boolean addDelimiter = false; 111 for (final int code : codes) { 112 if (code == NOT_A_CODE) break; 113 if (addDelimiter) sb.append(", "); 114 sb.append(Keyboard.printableCode(code)); 115 addDelimiter = true; 116 } 117 return "[" + sb + "]"; 118 } 119 } 120