Keyboard.java revision 8171b5182f5f07d33c9dfdf2dd8f0f6ae9588039
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008-2009 Google Inc. 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); you may not 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * use this file except in compliance with the License. You may obtain a copy of 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * License for the specific language governing permissions and limitations under 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.inputmethodservice; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport org.xmlpull.v1.XmlPullParserException; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.Resources; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.TypedArray; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.XmlResourceParser; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.graphics.drawable.Drawable; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.text.TextUtils; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.TypedValue; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Xml; 3058feea74b42bbaaa0552d76af23873bdd0b5dca2Mitsuru Oshimaimport android.util.DisplayMetrics; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList; 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.List; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.StringTokenizer; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Loads an XML description of a keyboard and stores the attributes of the keys. A keyboard 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * consists of rows of keys. 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>The layout file for a keyboard contains XML that looks like the following snippet:</p> 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre> 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <Keyboard 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * android:keyWidth="%10p" 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * android:keyHeight="50px" 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * android:horizontalGap="2px" 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * android:verticalGap="2px" > 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <Row android:keyWidth="32px" > 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <Key android:keyLabel="A" /> 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * ... 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </Row> 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * ... 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </Keyboard> 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </pre> 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#Keyboard_keyWidth 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#Keyboard_keyHeight 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#Keyboard_horizontalGap 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#Keyboard_verticalGap 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class Keyboard { 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static final String TAG = "Keyboard"; 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Keyboard XML Tags 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG_KEYBOARD = "Keyboard"; 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG_ROW = "Row"; 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG_KEY = "Key"; 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int EDGE_LEFT = 0x01; 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int EDGE_RIGHT = 0x02; 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int EDGE_TOP = 0x04; 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int EDGE_BOTTOM = 0x08; 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int KEYCODE_SHIFT = -1; 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int KEYCODE_MODE_CHANGE = -2; 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int KEYCODE_CANCEL = -3; 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int KEYCODE_DONE = -4; 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int KEYCODE_DELETE = -5; 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final int KEYCODE_ALT = -6; 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Keyboard label **/ 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private CharSequence mLabel; 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Horizontal gap default for all rows */ 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mDefaultHorizontalGap; 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Default key width */ 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mDefaultWidth; 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Default key height */ 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mDefaultHeight; 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Default gap between rows */ 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mDefaultVerticalGap; 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Is the keyboard in the shifted state */ 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mShifted; 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Key instance for the shift key, if present */ 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Key mShiftKey; 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Key index for the shift key, if present */ 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mShiftKeyIndex = -1; 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Current key width, while loading the keyboard */ 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mKeyWidth; 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Current key height, while loading the keyboard */ 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mKeyHeight; 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Total height of the keyboard, including the padding and keys */ 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mTotalHeight; 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Total width of the keyboard, including left side gaps and keys, but not any gaps on the 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * right side. 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mTotalWidth; 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** List of keys in this keyboard */ 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private List<Key> mKeys; 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** List of modifier keys such as Shift & Alt, if any */ 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private List<Key> mModifierKeys; 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Width of the screen available to fit the keyboard */ 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mDisplayWidth; 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Height of the screen */ 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mDisplayHeight; 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Keyboard mode, or zero, if none. */ 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mKeyboardMode; 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Variables for pre-computing nearest keys. 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GRID_WIDTH = 10; 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GRID_HEIGHT = 5; 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GRID_SIZE = GRID_WIDTH * GRID_HEIGHT; 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mCellWidth; 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mCellHeight; 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int[][] mGridNeighbors; 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mProximityThreshold; 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Number of key widths from current touch point to search for nearest keys. */ 145ae09878698ba6ad56ea43843f5a0895c94c32d90Amith Yamasani private static float SEARCH_DISTANCE = 1.8f; 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Container for keys in the keyboard. All keys in a row are at the same Y-coordinate. 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Some of the key size defaults can be overridden per row from what the {@link Keyboard} 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * defines. 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#Keyboard_keyWidth 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#Keyboard_keyHeight 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#Keyboard_horizontalGap 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#Keyboard_verticalGap 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#Keyboard_Row_rowEdgeFlags 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#Keyboard_Row_keyboardMode 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static class Row { 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Default width of a key in this row. */ 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int defaultWidth; 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Default height of a key in this row. */ 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int defaultHeight; 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Default horizontal gap between keys in this row. */ 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int defaultHorizontalGap; 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Vertical gap following this row. */ 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int verticalGap; 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Edge flags for this row of keys. Possible values that can be assigned are 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link Keyboard#EDGE_TOP EDGE_TOP} and {@link Keyboard#EDGE_BOTTOM EDGE_BOTTOM} 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int rowEdgeFlags; 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** The keyboard mode for this row */ 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int mode; 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Keyboard parent; 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Row(Keyboard parent) { 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.parent = parent; 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Row(Resources res, Keyboard parent, XmlResourceParser parser) { 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.parent = parent; 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TypedArray a = res.obtainAttributes(Xml.asAttributeSet(parser), 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.styleable.Keyboard); 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project defaultWidth = getDimensionOrFraction(a, 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.styleable.Keyboard_keyWidth, 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project parent.mDisplayWidth, parent.mDefaultWidth); 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project defaultHeight = getDimensionOrFraction(a, 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.styleable.Keyboard_keyHeight, 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project parent.mDisplayHeight, parent.mDefaultHeight); 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project defaultHorizontalGap = getDimensionOrFraction(a, 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.styleable.Keyboard_horizontalGap, 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project parent.mDisplayWidth, parent.mDefaultHorizontalGap); 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project verticalGap = getDimensionOrFraction(a, 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.styleable.Keyboard_verticalGap, 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project parent.mDisplayHeight, parent.mDefaultVerticalGap); 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a.recycle(); 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a = res.obtainAttributes(Xml.asAttributeSet(parser), 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.styleable.Keyboard_Row); 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project rowEdgeFlags = a.getInt(com.android.internal.R.styleable.Keyboard_Row_rowEdgeFlags, 0); 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mode = a.getResourceId(com.android.internal.R.styleable.Keyboard_Row_keyboardMode, 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 0); 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Class for describing the position and characteristics of a single key in the keyboard. 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#Keyboard_keyWidth 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#Keyboard_keyHeight 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#Keyboard_horizontalGap 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#Keyboard_Key_codes 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#Keyboard_Key_keyIcon 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#Keyboard_Key_keyLabel 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#Keyboard_Key_iconPreview 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#Keyboard_Key_isSticky 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#Keyboard_Key_isRepeatable 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#Keyboard_Key_isModifier 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#Keyboard_Key_popupKeyboard 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#Keyboard_Key_popupCharacters 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#Keyboard_Key_keyOutputText 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @attr ref android.R.styleable#Keyboard_Key_keyEdgeFlags 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static class Key { 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * All the key codes (unicode or custom code) that this key could generate, zero'th 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * being the most important. 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int[] codes; 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Label to display */ 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public CharSequence label; 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Icon to display instead of a label. Icon takes precedence over a label */ 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Drawable icon; 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Preview version of the icon, for the preview popup */ 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Drawable iconPreview; 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Width of the key, not including the gap */ 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int width; 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Height of the key, not including the gap */ 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int height; 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** The horizontal gap before this key */ 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int gap; 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Whether this key is sticky, i.e., a toggle key */ 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean sticky; 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** X coordinate of the key in the keyboard layout */ 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int x; 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Y coordinate of the key in the keyboard layout */ 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int y; 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** The current pressed state of this key */ 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean pressed; 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** If this is a sticky key, is it on? */ 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean on; 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Text to output when pressed. This can be multiple characters, like ".com" */ 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public CharSequence text; 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Popup characters */ 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public CharSequence popupCharacters; 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Flags that specify the anchoring to edges of the keyboard for detecting touch events 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * that are just out of the boundary of the key. This is a bit mask of 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link Keyboard#EDGE_LEFT}, {@link Keyboard#EDGE_RIGHT}, {@link Keyboard#EDGE_TOP} and 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link Keyboard#EDGE_BOTTOM}. 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int edgeFlags; 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Whether this is a modifier key, such as Shift or Alt */ 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean modifier; 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** The keyboard that this key belongs to */ 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Keyboard keyboard; 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If this key pops up a mini keyboard, this is the resource id for the XML layout for that 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * keyboard. 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int popupResId; 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Whether this key repeats itself when held down */ 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean repeatable; 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final static int[] KEY_STATE_NORMAL_ON = { 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project android.R.attr.state_checkable, 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project android.R.attr.state_checked 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final static int[] KEY_STATE_PRESSED_ON = { 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project android.R.attr.state_pressed, 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project android.R.attr.state_checkable, 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project android.R.attr.state_checked 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final static int[] KEY_STATE_NORMAL_OFF = { 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project android.R.attr.state_checkable 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final static int[] KEY_STATE_PRESSED_OFF = { 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project android.R.attr.state_pressed, 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project android.R.attr.state_checkable 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final static int[] KEY_STATE_NORMAL = { 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final static int[] KEY_STATE_PRESSED = { 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project android.R.attr.state_pressed 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Create an empty key with no attributes. */ 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Key(Row parent) { 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project keyboard = parent.parent; 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** Create a key with the given top-left coordinate and extract its attributes from 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the XML parser. 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param res resources associated with the caller's context 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param parent the row that this key belongs to. The row must already be attached to 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a {@link Keyboard}. 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param x the x coordinate of the top-left 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param y the y coordinate of the top-left 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param parser the XML parser containing the attributes for this key 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Key(Resources res, Row parent, int x, int y, XmlResourceParser parser) { 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this(parent); 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.x = x; 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.y = y; 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TypedArray a = res.obtainAttributes(Xml.asAttributeSet(parser), 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.styleable.Keyboard); 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project width = getDimensionOrFraction(a, 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.styleable.Keyboard_keyWidth, 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project keyboard.mDisplayWidth, parent.defaultWidth); 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project height = getDimensionOrFraction(a, 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.styleable.Keyboard_keyHeight, 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project keyboard.mDisplayHeight, parent.defaultHeight); 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project gap = getDimensionOrFraction(a, 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.styleable.Keyboard_horizontalGap, 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project keyboard.mDisplayWidth, parent.defaultHorizontalGap); 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a.recycle(); 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a = res.obtainAttributes(Xml.asAttributeSet(parser), 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.styleable.Keyboard_Key); 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this.x += gap; 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TypedValue codesValue = new TypedValue(); 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a.getValue(com.android.internal.R.styleable.Keyboard_Key_codes, 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project codesValue); 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (codesValue.type == TypedValue.TYPE_INT_DEC 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || codesValue.type == TypedValue.TYPE_INT_HEX) { 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project codes = new int[] { codesValue.data }; 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (codesValue.type == TypedValue.TYPE_STRING) { 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project codes = parseCSV(codesValue.string.toString()); 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project iconPreview = a.getDrawable(com.android.internal.R.styleable.Keyboard_Key_iconPreview); 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (iconPreview != null) { 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project iconPreview.setBounds(0, 0, iconPreview.getIntrinsicWidth(), 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project iconPreview.getIntrinsicHeight()); 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project popupCharacters = a.getText( 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.styleable.Keyboard_Key_popupCharacters); 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project popupResId = a.getResourceId( 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.styleable.Keyboard_Key_popupKeyboard, 0); 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project repeatable = a.getBoolean( 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.styleable.Keyboard_Key_isRepeatable, false); 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project modifier = a.getBoolean( 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.styleable.Keyboard_Key_isModifier, false); 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sticky = a.getBoolean( 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.styleable.Keyboard_Key_isSticky, false); 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project edgeFlags = a.getInt(com.android.internal.R.styleable.Keyboard_Key_keyEdgeFlags, 0); 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project edgeFlags |= parent.rowEdgeFlags; 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project icon = a.getDrawable( 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.styleable.Keyboard_Key_keyIcon); 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (icon != null) { 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project icon.setBounds(0, 0, icon.getIntrinsicWidth(), icon.getIntrinsicHeight()); 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project label = a.getText(com.android.internal.R.styleable.Keyboard_Key_keyLabel); 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project text = a.getText(com.android.internal.R.styleable.Keyboard_Key_keyOutputText); 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (codes == null && !TextUtils.isEmpty(label)) { 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project codes = new int[] { label.charAt(0) }; 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a.recycle(); 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Informs the key that it has been pressed, in case it needs to change its appearance or 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * state. 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #onReleased(boolean) 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onPressed() { 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pressed = !pressed; 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Changes the pressed state of the key. If it is a sticky key, it will also change the 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * toggled state of the key if the finger was release inside. 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param inside whether the finger was released inside the key 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #onPressed() 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onReleased(boolean inside) { 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pressed = !pressed; 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sticky) { 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project on = !on; 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int[] parseCSV(String value) { 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int count = 0; 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int lastIndex = 0; 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value.length() > 0) { 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project count++; 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while ((lastIndex = value.indexOf(",", lastIndex + 1)) > 0) { 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project count++; 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int[] values = new int[count]; 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project count = 0; 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project StringTokenizer st = new StringTokenizer(value, ","); 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (st.hasMoreTokens()) { 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project values[count++] = Integer.parseInt(st.nextToken()); 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (NumberFormatException nfe) { 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "Error parsing keycodes " + value); 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return values; 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Detects if a point falls inside this key. 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param x the x-coordinate of the point 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param y the y-coordinate of the point 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return whether or not the point falls inside the key. If the key is attached to an edge, 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * it will assume that all points between the key and the edge are considered to be inside 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the key. 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isInside(int x, int y) { 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean leftEdge = (edgeFlags & EDGE_LEFT) > 0; 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean rightEdge = (edgeFlags & EDGE_RIGHT) > 0; 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean topEdge = (edgeFlags & EDGE_TOP) > 0; 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean bottomEdge = (edgeFlags & EDGE_BOTTOM) > 0; 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((x >= this.x || (leftEdge && x <= this.x + this.width)) 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && (x < this.x + this.width || (rightEdge && x >= this.x)) 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && (y >= this.y || (topEdge && y <= this.y + this.height)) 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && (y < this.y + this.height || (bottomEdge && y >= this.y))) { 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the square of the distance between the center of the key and the given point. 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param x the x-coordinate of the point 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param y the y-coordinate of the point 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the square of the distance of the point from the center of the key 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int squaredDistanceFrom(int x, int y) { 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int xDist = this.x + width / 2 - x; 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int yDist = this.y + height / 2 - y; 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return xDist * xDist + yDist * yDist; 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the drawable state for the key, based on the current state and type of the key. 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the drawable state of the key. 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see android.graphics.drawable.StateListDrawable#setState(int[]) 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int[] getCurrentDrawableState() { 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int[] states = KEY_STATE_NORMAL; 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (on) { 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pressed) { 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project states = KEY_STATE_PRESSED_ON; 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project states = KEY_STATE_NORMAL_ON; 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sticky) { 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pressed) { 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project states = KEY_STATE_PRESSED_OFF; 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project states = KEY_STATE_NORMAL_OFF; 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (pressed) { 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project states = KEY_STATE_PRESSED; 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return states; 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Creates a keyboard from the given xml key layout file. 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param context the application or service context 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param xmlLayoutResId the resource file that contains the keyboard layout and keys. 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Keyboard(Context context, int xmlLayoutResId) { 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this(context, xmlLayoutResId, 0); 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5038171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung 5048171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung /** 5058171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung * Creates a keyboard from the given xml key layout file. Weeds out rows 5068171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung * that have a keyboard mode defined but don't match the specified mode. 5078171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung * @param context the application or service context 5088171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung * @param xmlLayoutResId the resource file that contains the keyboard layout and keys. 5098171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung * @param modeId keyboard mode identifier 5108171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung * @param width sets width of keyboard 5118171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung * @param height sets height of keyboard 5128171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung */ 5138171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung public Keyboard(Context context, int xmlLayoutResId, int modeId, int width, int height) { 5148171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung mDisplayWidth = width; 5158171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung mDisplayHeight = height; 5168171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung 5178171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung mDefaultHorizontalGap = 0; 5188171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung mDefaultWidth = mDisplayWidth / 10; 5198171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung mDefaultVerticalGap = 0; 5208171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung mDefaultHeight = mDefaultWidth; 5218171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung mKeys = new ArrayList<Key>(); 5228171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung mModifierKeys = new ArrayList<Key>(); 5238171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung mKeyboardMode = modeId; 5248171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung loadKeyboard(context, context.getResources().getXml(xmlLayoutResId)); 5258171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung } 5268171b5182f5f07d33c9dfdf2dd8f0f6ae9588039Jae Yong Sung 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Creates a keyboard from the given xml key layout file. Weeds out rows 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * that have a keyboard mode defined but don't match the specified mode. 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param context the application or service context 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param xmlLayoutResId the resource file that contains the keyboard layout and keys. 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param modeId keyboard mode identifier 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Keyboard(Context context, int xmlLayoutResId, int modeId) { 53558feea74b42bbaaa0552d76af23873bdd0b5dca2Mitsuru Oshima DisplayMetrics dm = context.getResources().getDisplayMetrics(); 53658feea74b42bbaaa0552d76af23873bdd0b5dca2Mitsuru Oshima mDisplayWidth = dm.widthPixels; 53758feea74b42bbaaa0552d76af23873bdd0b5dca2Mitsuru Oshima mDisplayHeight = dm.heightPixels; 53858feea74b42bbaaa0552d76af23873bdd0b5dca2Mitsuru Oshima //Log.v(TAG, "keyboard's display metrics:" + dm); 53958feea74b42bbaaa0552d76af23873bdd0b5dca2Mitsuru Oshima 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDefaultHorizontalGap = 0; 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDefaultWidth = mDisplayWidth / 10; 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDefaultVerticalGap = 0; 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDefaultHeight = mDefaultWidth; 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mKeys = new ArrayList<Key>(); 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mModifierKeys = new ArrayList<Key>(); 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mKeyboardMode = modeId; 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project loadKeyboard(context, context.getResources().getXml(xmlLayoutResId)); 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>Creates a blank keyboard from the given resource file and populates it with the specified 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * characters in left-to-right, top-to-bottom fashion, using the specified number of columns. 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * </p> 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>If the specified number of columns is -1, then the keyboard will fit as many keys as 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * possible in each row.</p> 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param context the application or service context 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param layoutTemplateResId the layout template file, containing no keys. 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param characters the list of characters to display on the keyboard. One key will be created 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * for each character. 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param columns the number of columns of keys to display. If this number is greater than the 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * number of keys that can fit in a row, it will be ignored. If this number is -1, the 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * keyboard will fit as many keys as possible in each row. 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Keyboard(Context context, int layoutTemplateResId, 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project CharSequence characters, int columns, int horizontalPadding) { 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this(context, layoutTemplateResId); 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int x = 0; 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int y = 0; 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int column = 0; 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTotalWidth = 0; 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Row row = new Row(this); 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project row.defaultHeight = mDefaultHeight; 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project row.defaultWidth = mDefaultWidth; 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project row.defaultHorizontalGap = mDefaultHorizontalGap; 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project row.verticalGap = mDefaultVerticalGap; 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project row.rowEdgeFlags = EDGE_TOP | EDGE_BOTTOM; 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int maxColumns = columns == -1 ? Integer.MAX_VALUE : columns; 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < characters.length(); i++) { 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char c = characters.charAt(i); 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (column >= maxColumns 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || x + mDefaultWidth + horizontalPadding > mDisplayWidth) { 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x = 0; 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project y += mDefaultVerticalGap + mDefaultHeight; 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project column = 0; 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Key key = new Key(row); 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project key.x = x; 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project key.y = y; 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project key.width = mDefaultWidth; 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project key.height = mDefaultHeight; 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project key.gap = mDefaultHorizontalGap; 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project key.label = String.valueOf(c); 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project key.codes = new int[] { c }; 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project column++; 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x += key.width + key.gap; 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mKeys.add(key); 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (x > mTotalWidth) { 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTotalWidth = x; 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTotalHeight = y + mDefaultHeight; 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public List<Key> getKeys() { 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mKeys; 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public List<Key> getModifierKeys() { 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mModifierKeys; 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected int getHorizontalGap() { 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mDefaultHorizontalGap; 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void setHorizontalGap(int gap) { 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDefaultHorizontalGap = gap; 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected int getVerticalGap() { 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mDefaultVerticalGap; 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void setVerticalGap(int gap) { 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDefaultVerticalGap = gap; 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected int getKeyHeight() { 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mDefaultHeight; 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void setKeyHeight(int height) { 6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDefaultHeight = height; 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected int getKeyWidth() { 6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mDefaultWidth; 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void setKeyWidth(int width) { 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDefaultWidth = width; 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the total height of the keyboard 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the total height of the keyboard 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getHeight() { 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mTotalHeight; 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getMinWidth() { 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mTotalWidth; 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean setShifted(boolean shiftState) { 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mShiftKey != null) { 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mShiftKey.on = shiftState; 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mShifted != shiftState) { 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mShifted = shiftState; 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isShifted() { 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mShifted; 6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getShiftKeyIndex() { 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mShiftKeyIndex; 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void computeNearestNeighbors() { 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Round-up so we don't have any pixels outside the grid 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCellWidth = (getMinWidth() + GRID_WIDTH - 1) / GRID_WIDTH; 6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCellHeight = (getHeight() + GRID_HEIGHT - 1) / GRID_HEIGHT; 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mGridNeighbors = new int[GRID_SIZE][]; 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int[] indices = new int[mKeys.size()]; 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int gridWidth = GRID_WIDTH * mCellWidth; 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int gridHeight = GRID_HEIGHT * mCellHeight; 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int x = 0; x < gridWidth; x += mCellWidth) { 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int y = 0; y < gridHeight; y += mCellHeight) { 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int count = 0; 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < mKeys.size(); i++) { 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Key key = mKeys.get(i); 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (key.squaredDistanceFrom(x, y) < mProximityThreshold || 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project key.squaredDistanceFrom(x + mCellWidth - 1, y) < mProximityThreshold || 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project key.squaredDistanceFrom(x + mCellWidth - 1, y + mCellHeight - 1) 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project < mProximityThreshold || 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project key.squaredDistanceFrom(x, y + mCellHeight - 1) < mProximityThreshold) { 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project indices[count++] = i; 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int [] cell = new int[count]; 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.arraycopy(indices, 0, cell, 0, count); 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mGridNeighbors[(y / mCellHeight) * GRID_WIDTH + (x / mCellWidth)] = cell; 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the indices of the keys that are closest to the given point. 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param x the x-coordinate of the point 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param y the y-coordinate of the point 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the array of integer indices for the nearest keys to the given point. If the given 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * point is out of range, then an array of size zero is returned. 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int[] getNearestKeys(int x, int y) { 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mGridNeighbors == null) computeNearestNeighbors(); 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (x >= 0 && x < getMinWidth() && y >= 0 && y < getHeight()) { 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int index = (y / mCellHeight) * GRID_WIDTH + (x / mCellWidth); 7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (index < GRID_SIZE) { 7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mGridNeighbors[index]; 7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new int[0]; 7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected Row createRowFromXml(Resources res, XmlResourceParser parser) { 7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new Row(res, this, parser); 7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected Key createKeyFromXml(Resources res, Row parent, int x, int y, 7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project XmlResourceParser parser) { 7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return new Key(res, parent, x, y, parser); 7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void loadKeyboard(Context context, XmlResourceParser parser) { 7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean inKey = false; 7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean inRow = false; 7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean leftMostKey = false; 7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int row = 0; 7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int x = 0; 7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int y = 0; 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Key key = null; 7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Row currentRow = null; 7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Resources res = context.getResources(); 7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean skipRow = false; 7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int event; 7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while ((event = parser.next()) != XmlResourceParser.END_DOCUMENT) { 7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (event == XmlResourceParser.START_TAG) { 7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String tag = parser.getName(); 7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (TAG_ROW.equals(tag)) { 7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project inRow = true; 7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x = 0; 7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project currentRow = createRowFromXml(res, parser); 7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project skipRow = currentRow.mode != 0 && currentRow.mode != mKeyboardMode; 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (skipRow) { 7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project skipToEndOfRow(parser); 7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project inRow = false; 7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (TAG_KEY.equals(tag)) { 7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project inKey = true; 7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project key = createKeyFromXml(res, currentRow, x, y, parser); 7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mKeys.add(key); 7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (key.codes[0] == KEYCODE_SHIFT) { 7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mShiftKey = key; 7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mShiftKeyIndex = mKeys.size()-1; 7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mModifierKeys.add(key); 7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (key.codes[0] == KEYCODE_ALT) { 7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mModifierKeys.add(key); 7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (TAG_KEYBOARD.equals(tag)) { 7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project parseKeyboardAttributes(res, parser); 7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (event == XmlResourceParser.END_TAG) { 7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (inKey) { 7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project inKey = false; 7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project x += key.gap + key.width; 7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (x > mTotalWidth) { 7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTotalWidth = x; 7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (inRow) { 7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project inRow = false; 7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project y += currentRow.verticalGap; 7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project y += currentRow.defaultHeight; 7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project row++; 7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // TODO: error or extend? 7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Exception e) { 7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "Parse error:" + e); 7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project e.printStackTrace(); 7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTotalHeight = y - mDefaultVerticalGap; 7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void skipToEndOfRow(XmlResourceParser parser) 7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws XmlPullParserException, IOException { 7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int event; 7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while ((event = parser.next()) != XmlResourceParser.END_DOCUMENT) { 7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (event == XmlResourceParser.END_TAG 8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && parser.getName().equals(TAG_ROW)) { 8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void parseKeyboardAttributes(Resources res, XmlResourceParser parser) { 8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TypedArray a = res.obtainAttributes(Xml.asAttributeSet(parser), 8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.styleable.Keyboard); 8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDefaultWidth = getDimensionOrFraction(a, 8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.styleable.Keyboard_keyWidth, 8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDisplayWidth, mDisplayWidth / 10); 8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDefaultHeight = getDimensionOrFraction(a, 8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.styleable.Keyboard_keyHeight, 8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDisplayHeight, 50); 8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDefaultHorizontalGap = getDimensionOrFraction(a, 8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.styleable.Keyboard_horizontalGap, 8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDisplayWidth, 0); 8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDefaultVerticalGap = getDimensionOrFraction(a, 8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.styleable.Keyboard_verticalGap, 8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDisplayHeight, 0); 8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mProximityThreshold = (int) (mDefaultWidth * SEARCH_DISTANCE); 8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mProximityThreshold = mProximityThreshold * mProximityThreshold; // Square it for comparison 8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a.recycle(); 8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static int getDimensionOrFraction(TypedArray a, int index, int base, int defValue) { 8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TypedValue value = a.peekValue(index); 8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value == null) return defValue; 8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value.type == TypedValue.TYPE_DIMENSION) { 8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return a.getDimensionPixelOffset(index, defValue); 8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (value.type == TypedValue.TYPE_FRACTION) { 8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Round it to avoid values like 47.9999 from getting truncated 8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return Math.round(a.getFraction(index, base, base, defValue)); 8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return defValue; 8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 839