Home | History | Annotate | Download | only in internal
      1 /*
      2  * Copyright (C) 2011 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.internal;
     18 
     19 import android.graphics.drawable.Drawable;
     20 
     21 import com.android.inputmethod.keyboard.Key;
     22 import com.android.inputmethod.keyboard.Keyboard;
     23 import com.android.inputmethod.keyboard.KeyboardId;
     24 import com.android.inputmethod.latin.LatinImeLogger;
     25 
     26 import java.util.ArrayList;
     27 import java.util.HashMap;
     28 import java.util.HashSet;
     29 import java.util.List;
     30 import java.util.Map;
     31 import java.util.Set;
     32 
     33 public class KeyboardParams {
     34     public KeyboardId mId;
     35     public int mThemeId;
     36 
     37     /** Total height and width of the keyboard, including the paddings and keys */
     38     public int mOccupiedHeight;
     39     public int mOccupiedWidth;
     40 
     41     /** Base height and width of the keyboard used to calculate rows' or keys' heights and widths */
     42     public int mBaseHeight;
     43     public int mBaseWidth;
     44 
     45     public int mTopPadding;
     46     public int mBottomPadding;
     47     public int mHorizontalEdgesPadding;
     48     public int mHorizontalCenterPadding;
     49 
     50     public int mDefaultRowHeight;
     51     public int mDefaultKeyWidth;
     52     public int mHorizontalGap;
     53     public int mVerticalGap;
     54 
     55     public boolean mIsRtlKeyboard;
     56     public int mMoreKeysTemplate;
     57     public int mMaxMiniKeyboardColumn;
     58 
     59     public int GRID_WIDTH;
     60     public int GRID_HEIGHT;
     61 
     62     public final List<Key> mKeys = new ArrayList<Key>();
     63     public final List<Key> mShiftKeys = new ArrayList<Key>();
     64     public final Set<Key> mShiftLockKeys = new HashSet<Key>();
     65     public final Map<Key, Drawable> mShiftedIcons = new HashMap<Key, Drawable>();
     66     public final Map<Key, Drawable> mUnshiftedIcons = new HashMap<Key, Drawable>();
     67     public final KeyboardIconsSet mIconsSet = new KeyboardIconsSet();
     68 
     69     public int mMostCommonKeyHeight = 0;
     70     public int mMostCommonKeyWidth = 0;
     71 
     72     public final TouchPositionCorrection mTouchPositionCorrection = new TouchPositionCorrection();
     73 
     74     public static class TouchPositionCorrection {
     75         private static final int TOUCH_POSITION_CORRECTION_RECORD_SIZE = 3;
     76 
     77         public boolean mEnabled;
     78         public float[] mXs;
     79         public float[] mYs;
     80         public float[] mRadii;
     81 
     82         public void load(String[] data) {
     83             final int dataLength = data.length;
     84             if (dataLength % TOUCH_POSITION_CORRECTION_RECORD_SIZE != 0) {
     85                 if (LatinImeLogger.sDBG)
     86                     throw new RuntimeException(
     87                             "the size of touch position correction data is invalid");
     88                 return;
     89             }
     90 
     91             final int length = dataLength / TOUCH_POSITION_CORRECTION_RECORD_SIZE;
     92             mXs = new float[length];
     93             mYs = new float[length];
     94             mRadii = new float[length];
     95             try {
     96                 for (int i = 0; i < dataLength; ++i) {
     97                     final int type = i % TOUCH_POSITION_CORRECTION_RECORD_SIZE;
     98                     final int index = i / TOUCH_POSITION_CORRECTION_RECORD_SIZE;
     99                     final float value = Float.parseFloat(data[i]);
    100                     if (type == 0) {
    101                         mXs[index] = value;
    102                     } else if (type == 1) {
    103                         mYs[index] = value;
    104                     } else {
    105                         mRadii[index] = value;
    106                     }
    107                 }
    108             } catch (NumberFormatException e) {
    109                 if (LatinImeLogger.sDBG) {
    110                     throw new RuntimeException(
    111                             "the number format for touch position correction data is invalid");
    112                 }
    113                 mXs = null;
    114                 mYs = null;
    115                 mRadii = null;
    116             }
    117         }
    118 
    119         public void setEnabled(boolean enabled) {
    120             mEnabled = enabled;
    121         }
    122 
    123         public boolean isValid() {
    124             return mEnabled && mXs != null && mYs != null && mRadii != null
    125                 && mXs.length > 0 && mYs.length > 0 && mRadii.length > 0;
    126         }
    127     }
    128 
    129     protected void clearKeys() {
    130         mKeys.clear();
    131         mShiftKeys.clear();
    132         mShiftLockKeys.clear();
    133         mShiftedIcons.clear();
    134         mUnshiftedIcons.clear();
    135         clearHistogram();
    136     }
    137 
    138     public void onAddKey(Key key) {
    139         mKeys.add(key);
    140         updateHistogram(key);
    141         if (key.mCode == Keyboard.CODE_SHIFT) {
    142             mShiftKeys.add(key);
    143             if (key.isSticky()) {
    144                 mShiftLockKeys.add(key);
    145             }
    146         }
    147     }
    148 
    149     public void addShiftedIcon(Key key, Drawable icon) {
    150         mUnshiftedIcons.put(key, key.getIcon());
    151         mShiftedIcons.put(key, icon);
    152     }
    153 
    154     private int mMaxHeightCount = 0;
    155     private int mMaxWidthCount = 0;
    156     private final Map<Integer, Integer> mHeightHistogram = new HashMap<Integer, Integer>();
    157     private final Map<Integer, Integer> mWidthHistogram = new HashMap<Integer, Integer>();
    158 
    159     private void clearHistogram() {
    160         mMostCommonKeyHeight = 0;
    161         mMaxHeightCount = 0;
    162         mHeightHistogram.clear();
    163 
    164         mMaxWidthCount = 0;
    165         mMostCommonKeyWidth = 0;
    166         mWidthHistogram.clear();
    167     }
    168 
    169     private static int updateHistogramCounter(Map<Integer, Integer> histogram, Integer key) {
    170         final int count = (histogram.containsKey(key) ? histogram.get(key) : 0) + 1;
    171         histogram.put(key, count);
    172         return count;
    173     }
    174 
    175     private void updateHistogram(Key key) {
    176         final Integer height = key.mHeight + key.mVerticalGap;
    177         final int heightCount = updateHistogramCounter(mHeightHistogram, height);
    178         if (heightCount > mMaxHeightCount) {
    179             mMaxHeightCount = heightCount;
    180             mMostCommonKeyHeight = height;
    181         }
    182 
    183         final Integer width = key.mWidth + key.mHorizontalGap;
    184         final int widthCount = updateHistogramCounter(mWidthHistogram, width);
    185         if (widthCount > mMaxWidthCount) {
    186             mMaxWidthCount = widthCount;
    187             mMostCommonKeyWidth = width;
    188         }
    189     }
    190 }
    191