| /* |
| * Copyright (C) 2010 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package com.android.inputmethod.keyboard; |
| |
| import android.util.SparseArray; |
| |
| import com.android.inputmethod.keyboard.internal.KeyVisualAttributes; |
| import com.android.inputmethod.keyboard.internal.KeyboardIconsSet; |
| import com.android.inputmethod.keyboard.internal.KeyboardParams; |
| import com.android.inputmethod.latin.CollectionUtils; |
| import com.android.inputmethod.latin.Constants; |
| |
| /** |
| * Loads an XML description of a keyboard and stores the attributes of the keys. A keyboard |
| * consists of rows of keys. |
| * <p>The layout file for a keyboard contains XML that looks like the following snippet:</p> |
| * <pre> |
| * <Keyboard |
| * latin:keyWidth="10%p" |
| * latin:rowHeight="50px" |
| * latin:horizontalGap="2%p" |
| * latin:verticalGap="2%p" > |
| * <Row latin:keyWidth="10%p" > |
| * <Key latin:keyLabel="A" /> |
| * ... |
| * </Row> |
| * ... |
| * </Keyboard> |
| * </pre> |
| */ |
| public class Keyboard { |
| public final KeyboardId mId; |
| public final int mThemeId; |
| |
| /** Total height of the keyboard, including the padding and keys */ |
| public final int mOccupiedHeight; |
| /** Total width of the keyboard, including the padding and keys */ |
| public final int mOccupiedWidth; |
| |
| /** The padding above the keyboard */ |
| public final int mTopPadding; |
| /** Default gap between rows */ |
| public final int mVerticalGap; |
| |
| /** Per keyboard key visual parameters */ |
| public final KeyVisualAttributes mKeyVisualAttributes; |
| |
| public final int mMostCommonKeyHeight; |
| public final int mMostCommonKeyWidth; |
| |
| /** More keys keyboard template */ |
| public final int mMoreKeysTemplate; |
| |
| /** Maximum column for more keys keyboard */ |
| public final int mMaxMoreKeysKeyboardColumn; |
| |
| /** Array of keys and icons in this keyboard */ |
| public final Key[] mKeys; |
| public final Key[] mShiftKeys; |
| public final Key[] mAltCodeKeysWhileTyping; |
| public final KeyboardIconsSet mIconsSet; |
| |
| private final SparseArray<Key> mKeyCache = CollectionUtils.newSparseArray(); |
| |
| private final ProximityInfo mProximityInfo; |
| private final boolean mProximityCharsCorrectionEnabled; |
| |
| public Keyboard(final KeyboardParams params) { |
| mId = params.mId; |
| mThemeId = params.mThemeId; |
| mOccupiedHeight = params.mOccupiedHeight; |
| mOccupiedWidth = params.mOccupiedWidth; |
| mMostCommonKeyHeight = params.mMostCommonKeyHeight; |
| mMostCommonKeyWidth = params.mMostCommonKeyWidth; |
| mMoreKeysTemplate = params.mMoreKeysTemplate; |
| mMaxMoreKeysKeyboardColumn = params.mMaxMoreKeysKeyboardColumn; |
| mKeyVisualAttributes = params.mKeyVisualAttributes; |
| mTopPadding = params.mTopPadding; |
| mVerticalGap = params.mVerticalGap; |
| |
| mKeys = params.mKeys.toArray(new Key[params.mKeys.size()]); |
| mShiftKeys = params.mShiftKeys.toArray(new Key[params.mShiftKeys.size()]); |
| mAltCodeKeysWhileTyping = params.mAltCodeKeysWhileTyping.toArray( |
| new Key[params.mAltCodeKeysWhileTyping.size()]); |
| mIconsSet = params.mIconsSet; |
| |
| mProximityInfo = new ProximityInfo(params.mId.mLocale.toString(), |
| params.GRID_WIDTH, params.GRID_HEIGHT, mOccupiedWidth, mOccupiedHeight, |
| mMostCommonKeyWidth, mMostCommonKeyHeight, mKeys, params.mTouchPositionCorrection); |
| mProximityCharsCorrectionEnabled = params.mProximityCharsCorrectionEnabled; |
| } |
| |
| public boolean hasProximityCharsCorrection(final int code) { |
| if (!mProximityCharsCorrectionEnabled) { |
| return false; |
| } |
| // Note: The native code has the main keyboard layout only at this moment. |
| // TODO: Figure out how to handle proximity characters information of all layouts. |
| final boolean canAssumeNativeHasProximityCharsInfoOfAllKeys = ( |
| mId.mElementId == KeyboardId.ELEMENT_ALPHABET |
| || mId.mElementId == KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED); |
| return canAssumeNativeHasProximityCharsInfoOfAllKeys || Character.isLetter(code); |
| } |
| |
| public ProximityInfo getProximityInfo() { |
| return mProximityInfo; |
| } |
| |
| public Key getKey(final int code) { |
| if (code == Constants.CODE_UNSPECIFIED) { |
| return null; |
| } |
| synchronized (mKeyCache) { |
| final int index = mKeyCache.indexOfKey(code); |
| if (index >= 0) { |
| return mKeyCache.valueAt(index); |
| } |
| |
| for (final Key key : mKeys) { |
| if (key.mCode == code) { |
| mKeyCache.put(code, key); |
| return key; |
| } |
| } |
| mKeyCache.put(code, null); |
| return null; |
| } |
| } |
| |
| public boolean hasKey(final Key aKey) { |
| if (mKeyCache.indexOfValue(aKey) >= 0) { |
| return true; |
| } |
| |
| for (final Key key : mKeys) { |
| if (key == aKey) { |
| mKeyCache.put(key.mCode, key); |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| @Override |
| public String toString() { |
| return mId.toString(); |
| } |
| |
| /** |
| * Returns the array of the keys that are closest to the given point. |
| * @param x the x-coordinate of the point |
| * @param y the y-coordinate of the point |
| * @return the array of the nearest keys to the given point. If the given |
| * point is out of range, then an array of size zero is returned. |
| */ |
| public Key[] getNearestKeys(final int x, final int y) { |
| // Avoid dead pixels at edges of the keyboard |
| final int adjustedX = Math.max(0, Math.min(x, mOccupiedWidth - 1)); |
| final int adjustedY = Math.max(0, Math.min(y, mOccupiedHeight - 1)); |
| return mProximityInfo.getNearestKeys(adjustedX, adjustedY); |
| } |
| } |