2010-12-02 09:46:21 +00:00
|
|
|
/*
|
2011-05-20 03:09:57 +00:00
|
|
|
* Copyright (C) 2010 The Android Open Source Project
|
2010-12-02 09:46:21 +00:00
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
|
2011-06-23 12:23:44 +00:00
|
|
|
package com.android.inputmethod.keyboard;
|
2010-12-02 09:46:21 +00:00
|
|
|
|
|
|
|
import android.content.res.Resources;
|
|
|
|
import android.content.res.TypedArray;
|
2011-09-28 09:51:57 +00:00
|
|
|
import android.graphics.Rect;
|
2011-06-25 10:38:55 +00:00
|
|
|
import android.graphics.Typeface;
|
2010-12-02 09:46:21 +00:00
|
|
|
import android.graphics.drawable.Drawable;
|
|
|
|
import android.text.TextUtils;
|
2011-12-12 03:52:42 +00:00
|
|
|
import android.util.Log;
|
2010-12-02 09:46:21 +00:00
|
|
|
import android.util.Xml;
|
|
|
|
|
2011-06-23 12:23:44 +00:00
|
|
|
import com.android.inputmethod.keyboard.internal.KeyStyles;
|
2011-06-25 10:38:55 +00:00
|
|
|
import com.android.inputmethod.keyboard.internal.KeyStyles.KeyStyle;
|
2011-08-30 09:35:56 +00:00
|
|
|
import com.android.inputmethod.keyboard.internal.KeyboardIconsSet;
|
2012-02-02 06:41:11 +00:00
|
|
|
import com.android.inputmethod.keyboard.internal.KeySpecParser;
|
2011-06-21 14:38:42 +00:00
|
|
|
import com.android.inputmethod.latin.R;
|
2012-02-02 06:41:11 +00:00
|
|
|
import com.android.inputmethod.latin.Utils;
|
2011-12-18 10:54:08 +00:00
|
|
|
import com.android.inputmethod.latin.XmlParseUtils;
|
2011-06-21 14:38:42 +00:00
|
|
|
|
2011-10-06 09:40:32 +00:00
|
|
|
import org.xmlpull.v1.XmlPullParser;
|
2011-12-14 09:11:27 +00:00
|
|
|
import org.xmlpull.v1.XmlPullParserException;
|
2011-10-06 09:40:32 +00:00
|
|
|
|
2011-12-16 06:32:24 +00:00
|
|
|
import java.util.Arrays;
|
2011-01-06 13:37:39 +00:00
|
|
|
|
2010-12-02 09:46:21 +00:00
|
|
|
/**
|
|
|
|
* Class for describing the position and characteristics of a single key in the keyboard.
|
|
|
|
*/
|
|
|
|
public class Key {
|
2011-12-12 03:52:42 +00:00
|
|
|
private static final String TAG = Key.class.getSimpleName();
|
|
|
|
|
2010-12-02 09:46:21 +00:00
|
|
|
/**
|
2010-12-20 11:30:26 +00:00
|
|
|
* The key code (unicode or custom code) that this key generates.
|
2010-12-02 09:46:21 +00:00
|
|
|
*/
|
2010-12-20 11:30:26 +00:00
|
|
|
public final int mCode;
|
2011-11-30 08:54:58 +00:00
|
|
|
public final int mAltCode;
|
2010-12-02 09:46:21 +00:00
|
|
|
|
|
|
|
/** Label to display */
|
2012-01-25 08:01:53 +00:00
|
|
|
public final String mLabel;
|
2011-06-25 10:38:55 +00:00
|
|
|
/** Hint label to display on the key in conjunction with the label */
|
2012-01-25 08:01:53 +00:00
|
|
|
public final String mHintLabel;
|
2011-11-22 03:55:38 +00:00
|
|
|
/** Flags of the label */
|
|
|
|
private final int mLabelFlags;
|
|
|
|
private static final int LABEL_FLAGS_ALIGN_LEFT = 0x01;
|
|
|
|
private static final int LABEL_FLAGS_ALIGN_RIGHT = 0x02;
|
|
|
|
private static final int LABEL_FLAGS_ALIGN_LEFT_OF_CENTER = 0x08;
|
|
|
|
private static final int LABEL_FLAGS_LARGE_LETTER = 0x10;
|
|
|
|
private static final int LABEL_FLAGS_FONT_NORMAL = 0x20;
|
|
|
|
private static final int LABEL_FLAGS_FONT_MONO_SPACE = 0x40;
|
|
|
|
private static final int LABEL_FLAGS_FOLLOW_KEY_LETTER_RATIO = 0x80;
|
|
|
|
private static final int LABEL_FLAGS_FOLLOW_KEY_HINT_LABEL_RATIO = 0x100;
|
|
|
|
private static final int LABEL_FLAGS_HAS_POPUP_HINT = 0x200;
|
2012-01-26 09:03:30 +00:00
|
|
|
private static final int LABEL_FLAGS_HAS_SHIFTED_LETTER_HINT = 0x400;
|
2011-11-22 03:55:38 +00:00
|
|
|
private static final int LABEL_FLAGS_HAS_HINT_LABEL = 0x800;
|
|
|
|
private static final int LABEL_FLAGS_WITH_ICON_LEFT = 0x1000;
|
|
|
|
private static final int LABEL_FLAGS_WITH_ICON_RIGHT = 0x2000;
|
|
|
|
private static final int LABEL_FLAGS_AUTO_X_SCALE = 0x4000;
|
2012-01-25 10:43:13 +00:00
|
|
|
private static final int LABEL_FLAGS_PRESERVE_CASE = 0x8000;
|
2012-01-26 09:03:30 +00:00
|
|
|
private static final int LABEL_FLAGS_SHIFTED_LETTER_ACTIVATED = 0x10000;
|
2010-12-02 09:46:21 +00:00
|
|
|
|
|
|
|
/** Icon to display instead of a label. Icon takes precedence over a label */
|
2012-01-25 05:54:28 +00:00
|
|
|
private final int mIconAttrId;
|
|
|
|
// TODO: Remove this variable.
|
2010-12-03 04:17:26 +00:00
|
|
|
private Drawable mIcon;
|
2011-12-18 16:11:09 +00:00
|
|
|
/** Icon for disabled state */
|
2012-01-25 05:54:28 +00:00
|
|
|
private final int mDisabledIconAttrId;
|
2010-12-02 09:46:21 +00:00
|
|
|
/** Preview version of the icon, for the preview popup */
|
2012-01-25 05:54:28 +00:00
|
|
|
public final int mPreviewIconAttrId;
|
2010-12-02 09:46:21 +00:00
|
|
|
|
|
|
|
/** Width of the key, not including the gap */
|
2010-12-03 04:17:26 +00:00
|
|
|
public final int mWidth;
|
2010-12-02 09:46:21 +00:00
|
|
|
/** Height of the key, not including the gap */
|
2010-12-03 04:17:26 +00:00
|
|
|
public final int mHeight;
|
2011-04-11 02:30:15 +00:00
|
|
|
/** The horizontal gap around this key */
|
2011-08-01 23:50:08 +00:00
|
|
|
public final int mHorizontalGap;
|
|
|
|
/** The vertical gap below this key */
|
|
|
|
public final int mVerticalGap;
|
2011-04-11 02:30:15 +00:00
|
|
|
/** The visual insets */
|
|
|
|
public final int mVisualInsetsLeft;
|
|
|
|
public final int mVisualInsetsRight;
|
2010-12-02 09:46:21 +00:00
|
|
|
/** X coordinate of the key in the keyboard layout */
|
2010-12-03 04:17:26 +00:00
|
|
|
public final int mX;
|
2010-12-02 09:46:21 +00:00
|
|
|
/** Y coordinate of the key in the keyboard layout */
|
2010-12-03 04:17:26 +00:00
|
|
|
public final int mY;
|
2011-09-28 09:51:57 +00:00
|
|
|
/** Hit bounding box of the key */
|
|
|
|
public final Rect mHitBox = new Rect();
|
|
|
|
|
2010-12-02 09:46:21 +00:00
|
|
|
/** Text to output when pressed. This can be multiple characters, like ".com" */
|
2010-12-03 04:17:26 +00:00
|
|
|
public final CharSequence mOutputText;
|
2011-08-31 06:26:32 +00:00
|
|
|
/** More keys */
|
2012-01-20 04:18:06 +00:00
|
|
|
public final String[] mMoreKeys;
|
2011-08-31 06:26:32 +00:00
|
|
|
/** More keys maximum column number */
|
|
|
|
public final int mMaxMoreKeysColumn;
|
2010-12-02 09:46:21 +00:00
|
|
|
|
2011-09-15 05:21:46 +00:00
|
|
|
/** Background type that represents different key background visual than normal one. */
|
|
|
|
public final int mBackgroundType;
|
|
|
|
public static final int BACKGROUND_TYPE_NORMAL = 0;
|
|
|
|
public static final int BACKGROUND_TYPE_FUNCTIONAL = 1;
|
2011-09-15 07:13:04 +00:00
|
|
|
public static final int BACKGROUND_TYPE_ACTION = 2;
|
2012-01-26 09:03:30 +00:00
|
|
|
public static final int BACKGROUND_TYPE_STICKY_OFF = 3;
|
|
|
|
public static final int BACKGROUND_TYPE_STICKY_ON = 4;
|
2011-09-15 05:21:46 +00:00
|
|
|
|
2011-11-22 03:55:38 +00:00
|
|
|
private final int mActionFlags;
|
|
|
|
private static final int ACTION_FLAGS_IS_REPEATABLE = 0x01;
|
|
|
|
private static final int ACTION_FLAGS_NO_KEY_PREVIEW = 0x02;
|
2011-11-30 08:54:58 +00:00
|
|
|
private static final int ACTION_FLAGS_ALT_CODE_WHILE_TYPING = 0x04;
|
2012-02-01 06:07:25 +00:00
|
|
|
private static final int ACTION_FLAGS_ENABLE_LONG_PRESS = 0x08;
|
2010-12-02 09:46:21 +00:00
|
|
|
|
2011-12-16 06:32:24 +00:00
|
|
|
private final int mHashCode;
|
|
|
|
|
2010-12-03 04:17:26 +00:00
|
|
|
/** The current pressed state of this key */
|
2011-06-23 12:23:44 +00:00
|
|
|
private boolean mPressed;
|
2011-02-18 02:28:17 +00:00
|
|
|
/** Key is enabled and responds on press */
|
2011-06-23 12:23:44 +00:00
|
|
|
private boolean mEnabled = true;
|
2010-12-02 09:46:21 +00:00
|
|
|
|
2011-12-18 10:54:08 +00:00
|
|
|
private static Drawable getIcon(Keyboard.Params params, String moreKeySpec) {
|
2012-02-02 06:41:11 +00:00
|
|
|
final int iconAttrId = KeySpecParser.getIconAttrId(moreKeySpec);
|
2012-01-20 10:57:07 +00:00
|
|
|
if (iconAttrId == KeyboardIconsSet.ICON_UNDEFINED) {
|
|
|
|
return null;
|
|
|
|
} else {
|
|
|
|
return params.mIconsSet.getIconByAttrId(iconAttrId);
|
|
|
|
}
|
2011-08-30 12:41:52 +00:00
|
|
|
}
|
|
|
|
|
2010-12-14 06:31:47 +00:00
|
|
|
/**
|
2011-08-31 06:26:32 +00:00
|
|
|
* This constructor is being used only for key in more keys keyboard.
|
2010-12-14 06:31:47 +00:00
|
|
|
*/
|
2011-12-18 10:54:08 +00:00
|
|
|
public Key(Resources res, Keyboard.Params params, String moreKeySpec,
|
2011-09-28 09:51:57 +00:00
|
|
|
int x, int y, int width, int height) {
|
2012-02-02 06:41:11 +00:00
|
|
|
this(params, KeySpecParser.getLabel(moreKeySpec), null, getIcon(params, moreKeySpec),
|
|
|
|
KeySpecParser.getCode(res, moreKeySpec),
|
|
|
|
KeySpecParser.getOutputText(moreKeySpec),
|
2011-09-28 09:51:57 +00:00
|
|
|
x, y, width, height);
|
2011-08-30 09:35:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This constructor is being used only for key in popup suggestions pane.
|
|
|
|
*/
|
2012-01-25 08:01:53 +00:00
|
|
|
public Key(Keyboard.Params params, String label, String hintLabel, Drawable icon,
|
2011-09-28 09:51:57 +00:00
|
|
|
int code, CharSequence outputText, int x, int y, int width, int height) {
|
2011-07-29 00:05:40 +00:00
|
|
|
mHeight = height - params.mVerticalGap;
|
|
|
|
mHorizontalGap = params.mHorizontalGap;
|
|
|
|
mVerticalGap = params.mVerticalGap;
|
2011-04-11 02:30:15 +00:00
|
|
|
mVisualInsetsLeft = mVisualInsetsRight = 0;
|
2011-08-01 23:50:08 +00:00
|
|
|
mWidth = width - mHorizontalGap;
|
2011-08-30 09:35:56 +00:00
|
|
|
mHintLabel = hintLabel;
|
2011-11-22 03:55:38 +00:00
|
|
|
mLabelFlags = 0;
|
2011-09-15 05:21:46 +00:00
|
|
|
mBackgroundType = BACKGROUND_TYPE_NORMAL;
|
2011-11-22 03:55:38 +00:00
|
|
|
mActionFlags = 0;
|
2011-08-31 06:26:32 +00:00
|
|
|
mMoreKeys = null;
|
|
|
|
mMaxMoreKeysColumn = 0;
|
2011-08-30 12:41:52 +00:00
|
|
|
mLabel = label;
|
|
|
|
mOutputText = outputText;
|
2011-08-30 09:35:56 +00:00
|
|
|
mCode = code;
|
2012-01-10 08:24:00 +00:00
|
|
|
mAltCode = Keyboard.CODE_UNSPECIFIED;
|
2012-01-25 05:54:28 +00:00
|
|
|
mIconAttrId = KeyboardIconsSet.ATTR_UNDEFINED;
|
2011-08-30 12:41:52 +00:00
|
|
|
mIcon = icon;
|
2012-01-25 05:54:28 +00:00
|
|
|
mDisabledIconAttrId = KeyboardIconsSet.ATTR_UNDEFINED;
|
|
|
|
mPreviewIconAttrId = KeyboardIconsSet.ATTR_UNDEFINED;
|
2010-12-03 04:17:26 +00:00
|
|
|
// Horizontal gap is divided equally to both sides of the key.
|
2011-08-01 23:50:08 +00:00
|
|
|
mX = x + mHorizontalGap / 2;
|
2010-12-03 04:17:26 +00:00
|
|
|
mY = y;
|
2011-09-28 09:51:57 +00:00
|
|
|
mHitBox.set(x, y, x + width + 1, y + height);
|
2011-12-16 06:32:24 +00:00
|
|
|
|
|
|
|
mHashCode = hashCode(this);
|
2010-12-02 09:46:21 +00:00
|
|
|
}
|
|
|
|
|
2010-12-14 06:31:47 +00:00
|
|
|
/**
|
|
|
|
* Create a key with the given top-left coordinate and extract its attributes from the XML
|
|
|
|
* parser.
|
2010-12-02 09:46:21 +00:00
|
|
|
* @param res resources associated with the caller's context
|
2011-07-29 00:05:40 +00:00
|
|
|
* @param params the keyboard building parameters.
|
2011-09-02 04:48:27 +00:00
|
|
|
* @param row the row that this key belongs to. row's x-coordinate will be the right edge of
|
|
|
|
* this key.
|
2010-12-02 09:46:21 +00:00
|
|
|
* @param parser the XML parser containing the attributes for this key
|
2011-05-30 11:05:50 +00:00
|
|
|
* @param keyStyles active key styles set
|
2011-12-14 09:11:27 +00:00
|
|
|
* @throws XmlPullParserException
|
2010-12-02 09:46:21 +00:00
|
|
|
*/
|
2011-12-18 10:54:08 +00:00
|
|
|
public Key(Resources res, Keyboard.Params params, Keyboard.Builder.Row row,
|
2011-12-14 09:11:27 +00:00
|
|
|
XmlPullParser parser, KeyStyles keyStyles) throws XmlPullParserException {
|
2011-09-26 02:26:38 +00:00
|
|
|
final float horizontalGap = isSpacer() ? 0 : params.mHorizontalGap;
|
2011-09-28 09:51:57 +00:00
|
|
|
final int keyHeight = row.mRowHeight;
|
2011-09-02 08:05:24 +00:00
|
|
|
mVerticalGap = params.mVerticalGap;
|
2011-09-28 09:51:57 +00:00
|
|
|
mHeight = keyHeight - mVerticalGap;
|
2010-12-02 09:46:21 +00:00
|
|
|
|
2010-12-14 06:31:47 +00:00
|
|
|
final TypedArray keyAttr = res.obtainAttributes(Xml.asAttributeSet(parser),
|
|
|
|
R.styleable.Keyboard_Key);
|
2010-12-08 08:07:25 +00:00
|
|
|
|
2011-09-02 08:05:24 +00:00
|
|
|
final KeyStyle style;
|
|
|
|
if (keyAttr.hasValue(R.styleable.Keyboard_Key_keyStyle)) {
|
|
|
|
String styleName = keyAttr.getString(R.styleable.Keyboard_Key_keyStyle);
|
|
|
|
style = keyStyles.getKeyStyle(styleName);
|
|
|
|
if (style == null)
|
2011-12-14 09:11:27 +00:00
|
|
|
throw new XmlParseUtils.ParseException(
|
|
|
|
"Unknown key style: " + styleName, parser);
|
2011-09-02 08:05:24 +00:00
|
|
|
} else {
|
2011-10-28 04:31:31 +00:00
|
|
|
style = KeyStyles.getEmptyKeyStyle();
|
2011-09-02 08:05:24 +00:00
|
|
|
}
|
|
|
|
|
2011-09-26 02:26:38 +00:00
|
|
|
final float keyXPos = row.getKeyX(keyAttr);
|
|
|
|
final float keyWidth = row.getKeyWidth(keyAttr, keyXPos);
|
2011-09-28 09:51:57 +00:00
|
|
|
final int keyYPos = row.getKeyY();
|
2011-05-30 11:05:50 +00:00
|
|
|
|
2011-09-02 08:05:24 +00:00
|
|
|
// Horizontal gap is divided equally to both sides of the key.
|
|
|
|
mX = (int) (keyXPos + horizontalGap / 2);
|
2011-09-28 09:51:57 +00:00
|
|
|
mY = keyYPos;
|
2011-09-02 08:05:24 +00:00
|
|
|
mWidth = (int) (keyWidth - horizontalGap);
|
|
|
|
mHorizontalGap = (int) horizontalGap;
|
2011-09-28 09:51:57 +00:00
|
|
|
mHitBox.set((int)keyXPos, keyYPos, (int)(keyXPos + keyWidth) + 1, keyYPos + keyHeight);
|
2011-09-02 08:05:24 +00:00
|
|
|
// Update row to have current x coordinate.
|
2011-09-26 02:26:38 +00:00
|
|
|
row.setXPos(keyXPos + keyWidth);
|
2011-09-02 08:05:24 +00:00
|
|
|
|
2011-09-26 02:26:38 +00:00
|
|
|
mBackgroundType = style.getInt(keyAttr,
|
|
|
|
R.styleable.Keyboard_Key_backgroundType, BACKGROUND_TYPE_NORMAL);
|
2011-09-02 08:05:24 +00:00
|
|
|
|
|
|
|
final KeyboardIconsSet iconsSet = params.mIconsSet;
|
2011-12-18 10:54:08 +00:00
|
|
|
mVisualInsetsLeft = (int) Keyboard.Builder.getDimensionOrFraction(keyAttr,
|
2011-09-26 02:26:38 +00:00
|
|
|
R.styleable.Keyboard_Key_visualInsetsLeft, params.mBaseWidth, 0);
|
2011-12-18 10:54:08 +00:00
|
|
|
mVisualInsetsRight = (int) Keyboard.Builder.getDimensionOrFraction(keyAttr,
|
2011-09-26 02:26:38 +00:00
|
|
|
R.styleable.Keyboard_Key_visualInsetsRight, params.mBaseWidth, 0);
|
2012-01-25 05:54:28 +00:00
|
|
|
mPreviewIconAttrId = KeyboardIconsSet.getIconAttrId(style.getInt(keyAttr,
|
2011-09-02 08:05:24 +00:00
|
|
|
R.styleable.Keyboard_Key_keyIconPreview, KeyboardIconsSet.ICON_UNDEFINED));
|
2012-01-25 05:54:28 +00:00
|
|
|
mIconAttrId = KeyboardIconsSet.getIconAttrId(style.getInt(keyAttr,
|
2011-12-18 16:11:09 +00:00
|
|
|
R.styleable.Keyboard_Key_keyIcon, KeyboardIconsSet.ICON_UNDEFINED));
|
2012-01-25 05:54:28 +00:00
|
|
|
mIcon = iconsSet.getIconByAttrId(mIconAttrId);
|
|
|
|
mDisabledIconAttrId = KeyboardIconsSet.getIconAttrId(style.getInt(keyAttr,
|
2011-12-18 16:11:09 +00:00
|
|
|
R.styleable.Keyboard_Key_keyIconDisabled, KeyboardIconsSet.ICON_UNDEFINED));
|
2011-09-02 08:05:24 +00:00
|
|
|
|
2011-11-22 03:55:38 +00:00
|
|
|
mLabelFlags = style.getFlag(keyAttr, R.styleable.Keyboard_Key_keyLabelFlags, 0);
|
2012-01-25 10:43:13 +00:00
|
|
|
final boolean preserveCase = (mLabelFlags & LABEL_FLAGS_PRESERVE_CASE) != 0;
|
2012-02-01 06:07:25 +00:00
|
|
|
int actionFlags = style.getFlag(keyAttr, R.styleable.Keyboard_Key_keyActionFlags, 0);
|
2012-01-30 02:14:45 +00:00
|
|
|
final String[] additionalMoreKeys = style.getStringArray(
|
|
|
|
keyAttr, R.styleable.Keyboard_Key_additionalMoreKeys);
|
2012-02-02 06:41:11 +00:00
|
|
|
final String[] moreKeys = KeySpecParser.insertAddtionalMoreKeys(style.getStringArray(
|
2012-01-30 02:14:45 +00:00
|
|
|
keyAttr, R.styleable.Keyboard_Key_moreKeys), additionalMoreKeys);
|
2012-01-25 10:43:13 +00:00
|
|
|
if (moreKeys != null) {
|
2012-02-01 06:07:25 +00:00
|
|
|
actionFlags |= ACTION_FLAGS_ENABLE_LONG_PRESS;
|
2012-01-25 10:43:13 +00:00
|
|
|
for (int i = 0; i < moreKeys.length; i++) {
|
|
|
|
moreKeys[i] = adjustCaseOfStringForKeyboardId(
|
|
|
|
moreKeys[i], preserveCase, params.mId);
|
|
|
|
}
|
|
|
|
}
|
2012-02-01 06:07:25 +00:00
|
|
|
mActionFlags = actionFlags;
|
2012-01-30 02:14:45 +00:00
|
|
|
mMoreKeys = moreKeys;
|
2012-01-25 10:43:13 +00:00
|
|
|
mMaxMoreKeysColumn = style.getInt(keyAttr,
|
|
|
|
R.styleable.Keyboard_Key_maxMoreKeysColumn, params.mMaxMiniKeyboardColumn);
|
|
|
|
|
|
|
|
mLabel = adjustCaseOfStringForKeyboardId(style.getString(
|
|
|
|
keyAttr, R.styleable.Keyboard_Key_keyLabel), preserveCase, params.mId);
|
|
|
|
mHintLabel = adjustCaseOfStringForKeyboardId(style.getString(
|
|
|
|
keyAttr, R.styleable.Keyboard_Key_keyHintLabel), preserveCase, params.mId);
|
2012-01-26 09:03:30 +00:00
|
|
|
String outputText = adjustCaseOfStringForKeyboardId(style.getString(
|
2012-01-25 10:43:13 +00:00
|
|
|
keyAttr, R.styleable.Keyboard_Key_keyOutputText), preserveCase, params.mId);
|
2012-01-26 09:03:30 +00:00
|
|
|
final int code = style.getInt(
|
|
|
|
keyAttr, R.styleable.Keyboard_Key_code, Keyboard.CODE_UNSPECIFIED);
|
|
|
|
// Choose the first letter of the label as primary code if not specified.
|
|
|
|
if (code == Keyboard.CODE_UNSPECIFIED && TextUtils.isEmpty(outputText)
|
2011-12-12 03:52:42 +00:00
|
|
|
&& !TextUtils.isEmpty(mLabel)) {
|
2012-02-02 06:41:11 +00:00
|
|
|
if (Utils.codePointCount(mLabel) == 1) {
|
2012-01-26 09:03:30 +00:00
|
|
|
// Use the first letter of the hint label if shiftedLetterActivated flag is
|
|
|
|
// specified.
|
|
|
|
if (hasShiftedLetterHint() && isShiftedLetterActivated()
|
|
|
|
&& !TextUtils.isEmpty(mHintLabel)) {
|
2012-02-01 10:43:58 +00:00
|
|
|
mCode = mHintLabel.codePointAt(0);
|
2012-01-26 09:03:30 +00:00
|
|
|
} else {
|
2012-02-01 10:43:58 +00:00
|
|
|
mCode = mLabel.codePointAt(0);
|
2012-01-26 09:03:30 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// In some locale and case, the character might be represented by multiple code
|
|
|
|
// points, such as upper case Eszett of German alphabet.
|
|
|
|
outputText = mLabel;
|
|
|
|
mCode = Keyboard.CODE_OUTPUT_TEXT;
|
2011-12-12 03:52:42 +00:00
|
|
|
}
|
2012-01-26 09:03:30 +00:00
|
|
|
} else if (code == Keyboard.CODE_UNSPECIFIED && outputText != null) {
|
2012-01-10 08:24:00 +00:00
|
|
|
mCode = Keyboard.CODE_OUTPUT_TEXT;
|
2011-09-02 08:05:24 +00:00
|
|
|
} else {
|
2012-01-26 09:03:30 +00:00
|
|
|
mCode = adjustCaseOfCodeForKeyboardId(code, preserveCase, params.mId);
|
2011-09-02 08:05:24 +00:00
|
|
|
}
|
2012-01-26 09:03:30 +00:00
|
|
|
mOutputText = outputText;
|
2012-01-25 10:43:13 +00:00
|
|
|
mAltCode = adjustCaseOfCodeForKeyboardId(style.getInt(keyAttr,
|
|
|
|
R.styleable.Keyboard_Key_altCode, Keyboard.CODE_UNSPECIFIED), preserveCase,
|
|
|
|
params.mId);
|
2011-12-16 06:32:24 +00:00
|
|
|
mHashCode = hashCode(this);
|
2011-09-02 08:05:24 +00:00
|
|
|
|
|
|
|
keyAttr.recycle();
|
2012-01-26 09:03:30 +00:00
|
|
|
|
|
|
|
if (hasShiftedLetterHint() && TextUtils.isEmpty(mHintLabel)) {
|
|
|
|
Log.w(TAG, "hasShiftedLetterHint specified without keyHintLabel: " + this);
|
|
|
|
}
|
2011-12-16 06:32:24 +00:00
|
|
|
}
|
|
|
|
|
2012-01-25 10:43:13 +00:00
|
|
|
private static int adjustCaseOfCodeForKeyboardId(int code, boolean preserveCase,
|
|
|
|
KeyboardId id) {
|
|
|
|
if (!Keyboard.isLetterCode(code) || preserveCase) return code;
|
|
|
|
final String text = new String(new int[] { code } , 0, 1);
|
|
|
|
final String casedText = adjustCaseOfStringForKeyboardId(text, preserveCase, id);
|
2012-02-02 06:41:11 +00:00
|
|
|
return Utils.codePointCount(casedText) == 1
|
2012-01-26 09:03:30 +00:00
|
|
|
? casedText.codePointAt(0) : Keyboard.CODE_UNSPECIFIED;
|
2012-01-25 10:43:13 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private static String adjustCaseOfStringForKeyboardId(String text, boolean preserveCase,
|
|
|
|
KeyboardId id) {
|
|
|
|
if (text == null || preserveCase) return text;
|
|
|
|
switch (id.mElementId) {
|
|
|
|
case KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED:
|
|
|
|
case KeyboardId.ELEMENT_ALPHABET_AUTOMATIC_SHIFTED:
|
|
|
|
case KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCKED:
|
|
|
|
case KeyboardId.ELEMENT_ALPHABET_SHIFT_LOCK_SHIFTED:
|
|
|
|
return text.toUpperCase(id.mLocale);
|
|
|
|
default:
|
|
|
|
return text;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-12-16 06:32:24 +00:00
|
|
|
private static int hashCode(Key key) {
|
|
|
|
return Arrays.hashCode(new Object[] {
|
|
|
|
key.mX,
|
|
|
|
key.mY,
|
|
|
|
key.mWidth,
|
|
|
|
key.mHeight,
|
|
|
|
key.mCode,
|
|
|
|
key.mLabel,
|
|
|
|
key.mHintLabel,
|
2012-01-25 05:54:28 +00:00
|
|
|
key.mIconAttrId,
|
2012-01-26 09:03:30 +00:00
|
|
|
key.mBackgroundType,
|
2011-12-16 06:32:24 +00:00
|
|
|
// Key can be distinguishable without the following members.
|
|
|
|
// key.mAltCode,
|
|
|
|
// key.mOutputText,
|
|
|
|
// key.mActionFlags,
|
|
|
|
// key.mLabelFlags,
|
|
|
|
// key.mIcon,
|
2012-01-25 05:54:28 +00:00
|
|
|
// key.mDisabledIconAttrId,
|
|
|
|
// key.mPreviewIconAttrId,
|
2011-12-16 06:32:24 +00:00
|
|
|
// key.mHorizontalGap,
|
|
|
|
// key.mVerticalGap,
|
|
|
|
// key.mVisualInsetLeft,
|
|
|
|
// key.mVisualInsetRight,
|
|
|
|
// Arrays.hashCode(key.mMoreKeys),
|
|
|
|
// key.mMaxMoreKeysColumn,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
private boolean equals(Key o) {
|
|
|
|
if (this == o) return true;
|
|
|
|
return o.mX == mX
|
|
|
|
&& o.mY == mY
|
|
|
|
&& o.mWidth == mWidth
|
|
|
|
&& o.mHeight == mHeight
|
|
|
|
&& o.mCode == mCode
|
|
|
|
&& TextUtils.equals(o.mLabel, mLabel)
|
2012-01-26 09:03:30 +00:00
|
|
|
&& TextUtils.equals(o.mHintLabel, mHintLabel)
|
|
|
|
&& o.mIconAttrId != mIconAttrId
|
|
|
|
&& o.mBackgroundType != mBackgroundType;
|
2011-12-16 06:32:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public int hashCode() {
|
|
|
|
return mHashCode;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean equals(Object o) {
|
|
|
|
return o instanceof Key && equals((Key)o);
|
2010-12-03 04:17:26 +00:00
|
|
|
}
|
|
|
|
|
2012-01-26 09:03:30 +00:00
|
|
|
@Override
|
|
|
|
public String toString() {
|
|
|
|
String top = Keyboard.printableCode(mCode);
|
2012-02-02 06:41:11 +00:00
|
|
|
if (Utils.codePointCount(mLabel) != 1) {
|
2012-01-26 09:03:30 +00:00
|
|
|
top += "/\"" + mLabel + '"';
|
|
|
|
}
|
|
|
|
return String.format("%s %d,%d", top, mX, mY);
|
|
|
|
}
|
|
|
|
|
2011-12-18 10:54:08 +00:00
|
|
|
public void markAsLeftEdge(Keyboard.Params params) {
|
2011-09-28 09:51:57 +00:00
|
|
|
mHitBox.left = params.mHorizontalEdgesPadding;
|
|
|
|
}
|
|
|
|
|
2011-12-18 10:54:08 +00:00
|
|
|
public void markAsRightEdge(Keyboard.Params params) {
|
2011-09-28 09:51:57 +00:00
|
|
|
mHitBox.right = params.mOccupiedWidth - params.mHorizontalEdgesPadding;
|
|
|
|
}
|
|
|
|
|
2011-12-18 10:54:08 +00:00
|
|
|
public void markAsTopEdge(Keyboard.Params params) {
|
2011-09-28 09:51:57 +00:00
|
|
|
mHitBox.top = params.mTopPadding;
|
|
|
|
}
|
|
|
|
|
2011-12-18 10:54:08 +00:00
|
|
|
public void markAsBottomEdge(Keyboard.Params params) {
|
2011-09-28 09:51:57 +00:00
|
|
|
mHitBox.bottom = params.mOccupiedHeight + params.mBottomPadding;
|
2011-07-19 00:14:50 +00:00
|
|
|
}
|
|
|
|
|
2011-09-08 08:19:23 +00:00
|
|
|
public boolean isSpacer() {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2011-11-29 07:56:27 +00:00
|
|
|
public boolean isShift() {
|
|
|
|
return mCode == Keyboard.CODE_SHIFT;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isModifier() {
|
|
|
|
return mCode == Keyboard.CODE_SHIFT || mCode == Keyboard.CODE_SWITCH_ALPHA_SYMBOL;
|
|
|
|
}
|
|
|
|
|
2011-11-22 03:55:38 +00:00
|
|
|
public boolean isRepeatable() {
|
|
|
|
return (mActionFlags & ACTION_FLAGS_IS_REPEATABLE) != 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
public boolean noKeyPreview() {
|
|
|
|
return (mActionFlags & ACTION_FLAGS_NO_KEY_PREVIEW) != 0;
|
|
|
|
}
|
|
|
|
|
2011-11-30 08:54:58 +00:00
|
|
|
public boolean altCodeWhileTyping() {
|
|
|
|
return (mActionFlags & ACTION_FLAGS_ALT_CODE_WHILE_TYPING) != 0;
|
2011-11-23 02:07:43 +00:00
|
|
|
}
|
|
|
|
|
2012-02-01 06:07:25 +00:00
|
|
|
public boolean isLongPressEnabled() {
|
|
|
|
// We need not start long press timer on the key which has activated shifted letter.
|
|
|
|
return (mActionFlags & ACTION_FLAGS_ENABLE_LONG_PRESS) != 0
|
|
|
|
&& (mLabelFlags & LABEL_FLAGS_SHIFTED_LETTER_ACTIVATED) == 0;
|
|
|
|
}
|
|
|
|
|
2011-06-25 10:38:55 +00:00
|
|
|
public Typeface selectTypeface(Typeface defaultTypeface) {
|
|
|
|
// TODO: Handle "bold" here too?
|
2011-11-22 03:55:38 +00:00
|
|
|
if ((mLabelFlags & LABEL_FLAGS_FONT_NORMAL) != 0) {
|
2011-06-25 10:38:55 +00:00
|
|
|
return Typeface.DEFAULT;
|
2011-11-22 03:55:38 +00:00
|
|
|
} else if ((mLabelFlags & LABEL_FLAGS_FONT_MONO_SPACE) != 0) {
|
2011-06-25 10:38:55 +00:00
|
|
|
return Typeface.MONOSPACE;
|
|
|
|
} else {
|
|
|
|
return defaultTypeface;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public int selectTextSize(int letter, int largeLetter, int label, int hintLabel) {
|
|
|
|
if (mLabel.length() > 1
|
2011-11-22 03:55:38 +00:00
|
|
|
&& (mLabelFlags & (LABEL_FLAGS_FOLLOW_KEY_LETTER_RATIO
|
|
|
|
| LABEL_FLAGS_FOLLOW_KEY_HINT_LABEL_RATIO)) == 0) {
|
2011-06-25 10:38:55 +00:00
|
|
|
return label;
|
2011-11-22 03:55:38 +00:00
|
|
|
} else if ((mLabelFlags & LABEL_FLAGS_FOLLOW_KEY_HINT_LABEL_RATIO) != 0) {
|
2011-06-25 10:38:55 +00:00
|
|
|
return hintLabel;
|
2011-11-22 03:55:38 +00:00
|
|
|
} else if ((mLabelFlags & LABEL_FLAGS_LARGE_LETTER) != 0) {
|
2011-06-25 10:38:55 +00:00
|
|
|
return largeLetter;
|
|
|
|
} else {
|
|
|
|
return letter;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-08-03 04:29:24 +00:00
|
|
|
public boolean isAlignLeft() {
|
2011-11-22 03:55:38 +00:00
|
|
|
return (mLabelFlags & LABEL_FLAGS_ALIGN_LEFT) != 0;
|
2011-08-03 04:29:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isAlignRight() {
|
2011-11-22 03:55:38 +00:00
|
|
|
return (mLabelFlags & LABEL_FLAGS_ALIGN_RIGHT) != 0;
|
2011-08-03 04:29:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public boolean isAlignLeftOfCenter() {
|
2011-11-22 03:55:38 +00:00
|
|
|
return (mLabelFlags & LABEL_FLAGS_ALIGN_LEFT_OF_CENTER) != 0;
|
2011-08-03 04:29:24 +00:00
|
|
|
}
|
|
|
|
|
2011-06-15 03:36:53 +00:00
|
|
|
public boolean hasPopupHint() {
|
2011-11-22 03:55:38 +00:00
|
|
|
return (mLabelFlags & LABEL_FLAGS_HAS_POPUP_HINT) != 0;
|
2011-06-15 03:36:53 +00:00
|
|
|
}
|
|
|
|
|
2012-01-26 09:03:30 +00:00
|
|
|
public boolean hasShiftedLetterHint() {
|
|
|
|
return (mLabelFlags & LABEL_FLAGS_HAS_SHIFTED_LETTER_HINT) != 0;
|
2011-06-15 03:36:53 +00:00
|
|
|
}
|
|
|
|
|
2011-06-25 10:38:55 +00:00
|
|
|
public boolean hasHintLabel() {
|
2011-11-22 03:55:38 +00:00
|
|
|
return (mLabelFlags & LABEL_FLAGS_HAS_HINT_LABEL) != 0;
|
2011-06-25 10:38:55 +00:00
|
|
|
}
|
|
|
|
|
2011-08-03 04:29:24 +00:00
|
|
|
public boolean hasLabelWithIconLeft() {
|
2011-11-22 03:55:38 +00:00
|
|
|
return (mLabelFlags & LABEL_FLAGS_WITH_ICON_LEFT) != 0;
|
2011-08-03 04:29:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public boolean hasLabelWithIconRight() {
|
2011-11-22 03:55:38 +00:00
|
|
|
return (mLabelFlags & LABEL_FLAGS_WITH_ICON_RIGHT) != 0;
|
2011-08-03 04:29:24 +00:00
|
|
|
}
|
|
|
|
|
2011-09-12 07:29:24 +00:00
|
|
|
public boolean needsXScale() {
|
2011-11-22 03:55:38 +00:00
|
|
|
return (mLabelFlags & LABEL_FLAGS_AUTO_X_SCALE) != 0;
|
2011-11-18 21:47:48 +00:00
|
|
|
}
|
|
|
|
|
2012-01-26 09:03:30 +00:00
|
|
|
public boolean isShiftedLetterActivated() {
|
|
|
|
return (mLabelFlags & LABEL_FLAGS_SHIFTED_LETTER_ACTIVATED) != 0;
|
2012-01-27 09:10:19 +00:00
|
|
|
}
|
|
|
|
|
2012-01-25 05:54:28 +00:00
|
|
|
// TODO: Get rid of this method.
|
|
|
|
public Drawable getIcon(KeyboardIconsSet iconSet) {
|
|
|
|
return mEnabled ? mIcon : iconSet.getIconByAttrId(mDisabledIconAttrId);
|
2010-12-03 04:17:26 +00:00
|
|
|
}
|
|
|
|
|
2011-12-16 03:47:34 +00:00
|
|
|
// TODO: Get rid of this method.
|
2010-12-03 04:17:26 +00:00
|
|
|
public void setIcon(Drawable icon) {
|
|
|
|
mIcon = icon;
|
|
|
|
}
|
|
|
|
|
2010-12-02 09:46:21 +00:00
|
|
|
/**
|
|
|
|
* Informs the key that it has been pressed, in case it needs to change its appearance or
|
|
|
|
* state.
|
2011-04-07 07:12:00 +00:00
|
|
|
* @see #onReleased()
|
2010-12-02 09:46:21 +00:00
|
|
|
*/
|
|
|
|
public void onPressed() {
|
2011-04-07 07:12:00 +00:00
|
|
|
mPressed = true;
|
2010-12-02 09:46:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2011-04-07 07:12:00 +00:00
|
|
|
* Informs the key that it has been released, in case it needs to change its appearance or
|
|
|
|
* state.
|
2010-12-02 09:46:21 +00:00
|
|
|
* @see #onPressed()
|
|
|
|
*/
|
2011-04-07 07:12:00 +00:00
|
|
|
public void onReleased() {
|
|
|
|
mPressed = false;
|
2010-12-02 09:46:21 +00:00
|
|
|
}
|
|
|
|
|
2011-06-23 12:23:44 +00:00
|
|
|
public boolean isEnabled() {
|
|
|
|
return mEnabled;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setEnabled(boolean enabled) {
|
|
|
|
mEnabled = enabled;
|
|
|
|
}
|
|
|
|
|
2010-12-02 09:46:21 +00:00
|
|
|
/**
|
2010-12-03 00:39:42 +00:00
|
|
|
* Detects if a point falls on this key.
|
2010-12-02 09:46:21 +00:00
|
|
|
* @param x the x-coordinate of the point
|
|
|
|
* @param y the y-coordinate of the point
|
2011-12-14 09:11:27 +00:00
|
|
|
* @return whether or not the point falls on the key. If the key is attached to an edge, it
|
|
|
|
* will assume that all points between the key and the edge are considered to be on the key.
|
2012-01-10 08:24:00 +00:00
|
|
|
* @see #markAsLeftEdge(Keyboard.Params) etc.
|
2010-12-02 09:46:21 +00:00
|
|
|
*/
|
2010-12-03 00:39:42 +00:00
|
|
|
public boolean isOnKey(int x, int y) {
|
2011-09-28 09:51:57 +00:00
|
|
|
return mHitBox.contains(x, y);
|
2010-12-02 09:46:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the square of the distance to the nearest edge of the key and the given point.
|
|
|
|
* @param x the x-coordinate of the point
|
|
|
|
* @param y the y-coordinate of the point
|
|
|
|
* @return the square of the distance of the point from the nearest edge of the key
|
|
|
|
*/
|
|
|
|
public int squaredDistanceToEdge(int x, int y) {
|
2011-04-28 14:39:49 +00:00
|
|
|
final int left = mX;
|
|
|
|
final int right = left + mWidth;
|
|
|
|
final int top = mY;
|
|
|
|
final int bottom = top + mHeight;
|
2010-12-02 09:46:21 +00:00
|
|
|
final int edgeX = x < left ? left : (x > right ? right : x);
|
|
|
|
final int edgeY = y < top ? top : (y > bottom ? bottom : y);
|
|
|
|
final int dx = x - edgeX;
|
|
|
|
final int dy = y - edgeY;
|
|
|
|
return dx * dx + dy * dy;
|
|
|
|
}
|
|
|
|
|
2011-09-15 08:54:21 +00:00
|
|
|
private final static int[] KEY_STATE_NORMAL_HIGHLIGHT_ON = {
|
|
|
|
android.R.attr.state_checkable,
|
|
|
|
android.R.attr.state_checked
|
|
|
|
};
|
|
|
|
|
|
|
|
private final static int[] KEY_STATE_PRESSED_HIGHLIGHT_ON = {
|
|
|
|
android.R.attr.state_pressed,
|
|
|
|
android.R.attr.state_checkable,
|
|
|
|
android.R.attr.state_checked
|
|
|
|
};
|
|
|
|
|
|
|
|
private final static int[] KEY_STATE_NORMAL_HIGHLIGHT_OFF = {
|
|
|
|
android.R.attr.state_checkable
|
|
|
|
};
|
|
|
|
|
|
|
|
private final static int[] KEY_STATE_PRESSED_HIGHLIGHT_OFF = {
|
|
|
|
android.R.attr.state_pressed,
|
|
|
|
android.R.attr.state_checkable
|
|
|
|
};
|
|
|
|
|
|
|
|
private final static int[] KEY_STATE_NORMAL = {
|
|
|
|
};
|
|
|
|
|
|
|
|
private final static int[] KEY_STATE_PRESSED = {
|
|
|
|
android.R.attr.state_pressed
|
|
|
|
};
|
|
|
|
|
|
|
|
// functional normal state (with properties)
|
|
|
|
private static final int[] KEY_STATE_FUNCTIONAL_NORMAL = {
|
|
|
|
android.R.attr.state_single
|
|
|
|
};
|
|
|
|
|
|
|
|
// functional pressed state (with properties)
|
|
|
|
private static final int[] KEY_STATE_FUNCTIONAL_PRESSED = {
|
|
|
|
android.R.attr.state_single,
|
|
|
|
android.R.attr.state_pressed
|
|
|
|
};
|
|
|
|
|
|
|
|
// action normal state (with properties)
|
|
|
|
private static final int[] KEY_STATE_ACTIVE_NORMAL = {
|
|
|
|
android.R.attr.state_active
|
|
|
|
};
|
|
|
|
|
|
|
|
// action pressed state (with properties)
|
|
|
|
private static final int[] KEY_STATE_ACTIVE_PRESSED = {
|
|
|
|
android.R.attr.state_active,
|
|
|
|
android.R.attr.state_pressed
|
|
|
|
};
|
|
|
|
|
2010-12-02 09:46:21 +00:00
|
|
|
/**
|
|
|
|
* Returns the drawable state for the key, based on the current state and type of the key.
|
|
|
|
* @return the drawable state of the key.
|
|
|
|
* @see android.graphics.drawable.StateListDrawable#setState(int[])
|
|
|
|
*/
|
|
|
|
public int[] getCurrentDrawableState() {
|
2011-09-15 07:13:04 +00:00
|
|
|
switch (mBackgroundType) {
|
|
|
|
case BACKGROUND_TYPE_FUNCTIONAL:
|
2012-01-26 09:03:30 +00:00
|
|
|
return mPressed ? KEY_STATE_FUNCTIONAL_PRESSED : KEY_STATE_FUNCTIONAL_NORMAL;
|
2011-09-15 07:13:04 +00:00
|
|
|
case BACKGROUND_TYPE_ACTION:
|
2012-01-26 09:03:30 +00:00
|
|
|
return mPressed ? KEY_STATE_ACTIVE_PRESSED : KEY_STATE_ACTIVE_NORMAL;
|
|
|
|
case BACKGROUND_TYPE_STICKY_OFF:
|
|
|
|
return mPressed ? KEY_STATE_PRESSED_HIGHLIGHT_OFF : KEY_STATE_NORMAL_HIGHLIGHT_OFF;
|
|
|
|
case BACKGROUND_TYPE_STICKY_ON:
|
|
|
|
return mPressed ? KEY_STATE_PRESSED_HIGHLIGHT_ON : KEY_STATE_NORMAL_HIGHLIGHT_ON;
|
2011-09-15 07:13:04 +00:00
|
|
|
default: /* BACKGROUND_TYPE_NORMAL */
|
2012-01-26 09:03:30 +00:00
|
|
|
return mPressed ? KEY_STATE_PRESSED : KEY_STATE_NORMAL;
|
2010-12-02 09:46:21 +00:00
|
|
|
}
|
|
|
|
}
|
2011-09-08 08:19:23 +00:00
|
|
|
|
|
|
|
public static class Spacer extends Key {
|
2011-12-18 10:54:08 +00:00
|
|
|
public Spacer(Resources res, Keyboard.Params params, Keyboard.Builder.Row row,
|
2011-12-14 09:11:27 +00:00
|
|
|
XmlPullParser parser, KeyStyles keyStyles) throws XmlPullParserException {
|
2011-09-08 08:19:23 +00:00
|
|
|
super(res, params, row, parser, keyStyles);
|
|
|
|
}
|
|
|
|
|
2011-09-08 09:57:44 +00:00
|
|
|
/**
|
|
|
|
* This constructor is being used only for divider in more keys keyboard.
|
|
|
|
*/
|
2011-12-18 10:54:08 +00:00
|
|
|
public Spacer(Keyboard.Params params, Drawable icon, int x, int y, int width, int height) {
|
2012-01-10 08:24:00 +00:00
|
|
|
super(params, null, null, icon, Keyboard.CODE_UNSPECIFIED, null, x, y, width, height);
|
2011-09-08 09:57:44 +00:00
|
|
|
}
|
|
|
|
|
2011-09-08 08:19:23 +00:00
|
|
|
@Override
|
|
|
|
public boolean isSpacer() {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
2010-12-02 09:46:21 +00:00
|
|
|
}
|