Home | History | Annotate | Download | only in keyboard
      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      */
     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     public int getTouchY(int y) {
     57         return y + mCorrectionY;
     58     }
     59 
     60     public Keyboard getKeyboard() {
     61         if (mKeyboard == null)
     62             throw new IllegalStateException("keyboard isn't set");
     63         return mKeyboard;
     64     }
     65 
     66     public void setProximityCorrectionEnabled(boolean enabled) {
     67         mProximityCorrectOn = enabled;
     68     }
     69 
     70     public boolean isProximityCorrectionEnabled() {
     71         return mProximityCorrectOn;
     72     }
     73 
     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      */
     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 
    104     public static String printableCode(Key key) {
    105         return key != null ? Keyboard.printableCode(key.mCode) : "none";
    106     }
    107 
    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