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
|
|
|
*
|
2013-01-21 12:52:57 +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
|
2010-12-02 09:46:21 +00:00
|
|
|
*
|
2013-01-21 12:52:57 +00:00
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
2010-12-02 09:46:21 +00:00
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
2013-01-21 12:52:57 +00:00
|
|
|
* 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.
|
2010-12-02 09:46:21 +00:00
|
|
|
*/
|
|
|
|
|
2011-06-23 12:23:44 +00:00
|
|
|
package com.android.inputmethod.keyboard;
|
2010-12-02 09:46:21 +00:00
|
|
|
|
2012-04-19 21:24:51 +00:00
|
|
|
import static com.android.inputmethod.keyboard.internal.KeyboardIconsSet.ICON_UNDEFINED;
|
2012-10-29 05:46:34 +00:00
|
|
|
import static com.android.inputmethod.latin.Constants.CODE_OUTPUT_TEXT;
|
|
|
|
import static com.android.inputmethod.latin.Constants.CODE_SHIFT;
|
|
|
|
import static com.android.inputmethod.latin.Constants.CODE_SWITCH_ALPHA_SYMBOL;
|
|
|
|
import static com.android.inputmethod.latin.Constants.CODE_UNSPECIFIED;
|
2012-04-19 21:24:51 +00:00
|
|
|
|
2010-12-02 09:46:21 +00:00
|
|
|
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;
|
|
|
|
|
2012-08-30 08:42:49 +00:00
|
|
|
import com.android.inputmethod.keyboard.internal.KeyDrawParams;
|
2012-02-02 15:18:47 +00:00
|
|
|
import com.android.inputmethod.keyboard.internal.KeySpecParser;
|
2012-08-30 05:22:40 +00:00
|
|
|
import com.android.inputmethod.keyboard.internal.KeyStyle;
|
2012-08-30 08:42:49 +00:00
|
|
|
import com.android.inputmethod.keyboard.internal.KeyVisualAttributes;
|
2011-08-30 09:35:56 +00:00
|
|
|
import com.android.inputmethod.keyboard.internal.KeyboardIconsSet;
|
2012-08-30 05:22:40 +00:00
|
|
|
import com.android.inputmethod.keyboard.internal.KeyboardParams;
|
|
|
|
import com.android.inputmethod.keyboard.internal.KeyboardRow;
|
|
|
|
import com.android.inputmethod.keyboard.internal.MoreKeySpec;
|
2012-10-29 05:46:34 +00:00
|
|
|
import com.android.inputmethod.latin.Constants;
|
2011-06-21 14:38:42 +00:00
|
|
|
import com.android.inputmethod.latin.R;
|
2013-06-23 16:11:32 +00:00
|
|
|
import com.android.inputmethod.latin.utils.StringUtils;
|
2011-06-21 14:38:42 +00:00
|
|
|
|
2011-12-16 06:32:24 +00:00
|
|
|
import java.util.Arrays;
|
2012-05-26 04:23:34 +00:00
|
|
|
import java.util.Locale;
|
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.
|
|
|
|
*/
|
2012-09-11 10:15:00 +00:00
|
|
|
public class Key implements Comparable<Key> {
|
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
|
|
|
*/
|
2013-08-12 09:05:11 +00:00
|
|
|
private final int mCode;
|
2010-12-02 09:46:21 +00:00
|
|
|
|
|
|
|
/** Label to display */
|
2013-08-12 09:05:11 +00:00
|
|
|
private final String mLabel;
|
2011-06-25 10:38:55 +00:00
|
|
|
/** Hint label to display on the key in conjunction with the label */
|
2013-08-12 09:05:11 +00:00
|
|
|
private final String mHintLabel;
|
2011-11-22 03:55:38 +00:00
|
|
|
/** Flags of the label */
|
|
|
|
private final int mLabelFlags;
|
2014-08-07 14:44:34 +00:00
|
|
|
private static final int LABEL_FLAGS_ALIGN_HINT_LABEL_TO_BOTTOM = 0x02;
|
2014-08-07 03:32:59 +00:00
|
|
|
private static final int LABEL_FLAGS_ALIGN_ICON_TO_BOTTOM = 0x04;
|
2014-08-07 14:31:47 +00:00
|
|
|
private static final int LABEL_FLAGS_ALIGN_LABEL_OFF_CENTER = 0x08;
|
2014-07-07 07:54:00 +00:00
|
|
|
// Font typeface specification.
|
|
|
|
private static final int LABEL_FLAGS_FONT_MASK = 0x30;
|
2012-04-11 03:34:30 +00:00
|
|
|
private static final int LABEL_FLAGS_FONT_NORMAL = 0x10;
|
|
|
|
private static final int LABEL_FLAGS_FONT_MONO_SPACE = 0x20;
|
2014-07-07 07:54:00 +00:00
|
|
|
private static final int LABEL_FLAGS_FONT_DEFAULT = 0x30;
|
2012-05-17 10:30:38 +00:00
|
|
|
// Start of key text ratio enum values
|
|
|
|
private static final int LABEL_FLAGS_FOLLOW_KEY_TEXT_RATIO_MASK = 0x1C0;
|
2012-04-11 03:34:30 +00:00
|
|
|
private static final int LABEL_FLAGS_FOLLOW_KEY_LARGE_LETTER_RATIO = 0x40;
|
|
|
|
private static final int LABEL_FLAGS_FOLLOW_KEY_LETTER_RATIO = 0x80;
|
|
|
|
private static final int LABEL_FLAGS_FOLLOW_KEY_LABEL_RATIO = 0xC0;
|
2012-05-17 10:30:38 +00:00
|
|
|
private static final int LABEL_FLAGS_FOLLOW_KEY_HINT_LABEL_RATIO = 0x140;
|
|
|
|
// End of key text ratio mask enum values
|
2011-11-22 03:55:38 +00:00
|
|
|
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;
|
2013-12-13 08:09:16 +00:00
|
|
|
// The bit to calculate the ratio of key label width against key width. If autoXScale bit is on
|
|
|
|
// and autoYScale bit is off, the key label may be shrunk only for X-direction.
|
|
|
|
// If both autoXScale and autoYScale bits are on, the key label text size may be auto scaled.
|
2011-11-22 03:55:38 +00:00
|
|
|
private static final int LABEL_FLAGS_AUTO_X_SCALE = 0x4000;
|
2013-12-13 08:09:16 +00:00
|
|
|
private static final int LABEL_FLAGS_AUTO_Y_SCALE = 0x8000;
|
|
|
|
private static final int LABEL_FLAGS_AUTO_SCALE = LABEL_FLAGS_AUTO_X_SCALE
|
|
|
|
| LABEL_FLAGS_AUTO_Y_SCALE;
|
|
|
|
private static final int LABEL_FLAGS_PRESERVE_CASE = 0x10000;
|
|
|
|
private static final int LABEL_FLAGS_SHIFTED_LETTER_ACTIVATED = 0x20000;
|
|
|
|
private static final int LABEL_FLAGS_FROM_CUSTOM_ACTION_LABEL = 0x40000;
|
2014-05-15 06:39:01 +00:00
|
|
|
private static final int LABEL_FLAGS_FOLLOW_FUNCTIONAL_TEXT_COLOR = 0x80000;
|
2014-09-09 04:05:31 +00:00
|
|
|
private static final int LABEL_FLAGS_KEEP_BACKGROUND_ASPECT_RATIO = 0x100000;
|
2012-03-12 07:30:59 +00:00
|
|
|
private static final int LABEL_FLAGS_DISABLE_HINT_LABEL = 0x40000000;
|
|
|
|
private static final int LABEL_FLAGS_DISABLE_ADDITIONAL_MORE_KEYS = 0x80000000;
|
2010-12-02 09:46:21 +00:00
|
|
|
|
|
|
|
/** Icon to display instead of a label. Icon takes precedence over a label */
|
2012-02-02 15:18:47 +00:00
|
|
|
private final int mIconId;
|
2010-12-02 09:46:21 +00:00
|
|
|
|
2014-08-26 07:40:18 +00:00
|
|
|
/** Width of the key, excluding the gap */
|
2013-08-12 09:05:11 +00:00
|
|
|
private final int mWidth;
|
2014-08-26 07:40:18 +00:00
|
|
|
/** Height of the key, excluding the gap */
|
2013-08-12 09:05:11 +00:00
|
|
|
private final int mHeight;
|
2014-09-03 21:15:44 +00:00
|
|
|
/**
|
|
|
|
* The combined width in pixels of the horizontal gaps belonging to this key, both to the left
|
|
|
|
* and to the right. I.e., mWidth + mHorizontalGap = total width belonging to the key.
|
|
|
|
*/
|
|
|
|
private final int mHorizontalGap;
|
|
|
|
/**
|
|
|
|
* The combined height in pixels of the vertical gaps belonging to this key, both above and
|
|
|
|
* below. I.e., mHeight + mVerticalGap = total height belonging to the key.
|
|
|
|
*/
|
|
|
|
private final int mVerticalGap;
|
2014-08-26 07:40:18 +00:00
|
|
|
/** X coordinate of the top-left corner of the key in the keyboard layout, excluding the gap. */
|
2013-08-12 09:05:11 +00:00
|
|
|
private final int mX;
|
2014-08-26 07:40:18 +00:00
|
|
|
/** Y coordinate of the top-left corner of the key in the keyboard layout, excluding the gap. */
|
2013-08-12 09:05:11 +00:00
|
|
|
private final int mY;
|
2011-09-28 09:51:57 +00:00
|
|
|
/** Hit bounding box of the key */
|
2013-08-12 09:05:11 +00:00
|
|
|
private final Rect mHitBox = new Rect();
|
2011-09-28 09:51:57 +00:00
|
|
|
|
2013-05-13 06:05:37 +00:00
|
|
|
/** More keys. It is guaranteed that this is null or an array of one or more elements */
|
2013-08-12 09:05:11 +00:00
|
|
|
private final MoreKeySpec[] mMoreKeys;
|
2012-03-01 04:09:39 +00:00
|
|
|
/** More keys column number and flags */
|
|
|
|
private final int mMoreKeysColumnAndFlags;
|
2014-08-23 12:10:42 +00:00
|
|
|
private static final int MORE_KEYS_COLUMN_NUMBER_MASK = 0x000000ff;
|
|
|
|
// If this flag is specified, more keys keyboard should have the specified number of columns.
|
|
|
|
// Otherwise more keys keyboard should have less than or equal to the specified maximum number
|
|
|
|
// of columns.
|
|
|
|
private static final int MORE_KEYS_FLAGS_FIXED_COLUMN = 0x00000100;
|
|
|
|
// If this flag is specified, the order of more keys is determined by the order in the more
|
|
|
|
// keys' specification. Otherwise the order of more keys is automatically determined.
|
|
|
|
private static final int MORE_KEYS_FLAGS_FIXED_ORDER = 0x00000200;
|
|
|
|
private static final int MORE_KEYS_MODE_MAX_COLUMN_WITH_AUTO_ORDER = 0;
|
|
|
|
private static final int MORE_KEYS_MODE_FIXED_COLUMN_WITH_AUTO_ORDER =
|
|
|
|
MORE_KEYS_FLAGS_FIXED_COLUMN;
|
|
|
|
private static final int MORE_KEYS_MODE_FIXED_COLUMN_WITH_FIXED_ORDER =
|
|
|
|
(MORE_KEYS_FLAGS_FIXED_COLUMN | MORE_KEYS_FLAGS_FIXED_ORDER);
|
2012-02-29 09:45:13 +00:00
|
|
|
private static final int MORE_KEYS_FLAGS_HAS_LABELS = 0x40000000;
|
2012-03-07 09:41:38 +00:00
|
|
|
private static final int MORE_KEYS_FLAGS_NEEDS_DIVIDERS = 0x20000000;
|
2013-05-22 00:14:31 +00:00
|
|
|
private static final int MORE_KEYS_FLAGS_NO_PANEL_AUTO_MORE_KEY = 0x10000000;
|
2014-08-23 12:10:42 +00:00
|
|
|
// TODO: Rename these specifiers to !autoOrder! and !fixedOrder! respectively.
|
2012-03-01 04:09:39 +00:00
|
|
|
private static final String MORE_KEYS_AUTO_COLUMN_ORDER = "!autoColumnOrder!";
|
|
|
|
private static final String MORE_KEYS_FIXED_COLUMN_ORDER = "!fixedColumnOrder!";
|
2012-02-29 09:45:13 +00:00
|
|
|
private static final String MORE_KEYS_HAS_LABELS = "!hasLabels!";
|
2012-02-29 13:21:57 +00:00
|
|
|
private static final String MORE_KEYS_NEEDS_DIVIDERS = "!needsDividers!";
|
2013-05-22 00:14:31 +00:00
|
|
|
private static final String MORE_KEYS_NO_PANEL_AUTO_MORE_KEY = "!noPanelAutoMoreKey!";
|
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. */
|
2013-08-12 09:05:11 +00:00
|
|
|
private final int mBackgroundType;
|
2013-08-14 08:55:21 +00:00
|
|
|
public static final int BACKGROUND_TYPE_EMPTY = 0;
|
|
|
|
public static final int BACKGROUND_TYPE_NORMAL = 1;
|
|
|
|
public static final int BACKGROUND_TYPE_FUNCTIONAL = 2;
|
2014-08-06 08:23:14 +00:00
|
|
|
public static final int BACKGROUND_TYPE_STICKY_OFF = 3;
|
|
|
|
public static final int BACKGROUND_TYPE_STICKY_ON = 4;
|
|
|
|
public static final int BACKGROUND_TYPE_ACTION = 5;
|
2014-09-03 01:52:56 +00:00
|
|
|
public static final int BACKGROUND_TYPE_SPACEBAR = 6;
|
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
|
|
|
|
2013-08-12 09:05:11 +00:00
|
|
|
private final KeyVisualAttributes mKeyVisualAttributes;
|
2012-08-30 08:42:49 +00:00
|
|
|
|
2012-08-28 08:19:49 +00:00
|
|
|
private final OptionalAttributes mOptionalAttributes;
|
|
|
|
|
2012-09-27 09:16:16 +00:00
|
|
|
private static final class OptionalAttributes {
|
2012-08-28 08:19:49 +00:00
|
|
|
/** Text to output when pressed. This can be multiple characters, like ".com" */
|
|
|
|
public final String mOutputText;
|
|
|
|
public final int mAltCode;
|
|
|
|
/** Icon for disabled state */
|
|
|
|
public final int mDisabledIconId;
|
|
|
|
/** The visual insets */
|
|
|
|
public final int mVisualInsetsLeft;
|
|
|
|
public final int mVisualInsetsRight;
|
|
|
|
|
2013-08-12 09:05:11 +00:00
|
|
|
private OptionalAttributes(final String outputText, final int altCode,
|
2014-07-08 08:36:11 +00:00
|
|
|
final int disabledIconId, final int visualInsetsLeft, final int visualInsetsRight) {
|
2012-08-28 08:19:49 +00:00
|
|
|
mOutputText = outputText;
|
|
|
|
mAltCode = altCode;
|
|
|
|
mDisabledIconId = disabledIconId;
|
|
|
|
mVisualInsetsLeft = visualInsetsLeft;
|
|
|
|
mVisualInsetsRight = visualInsetsRight;
|
|
|
|
}
|
2013-08-12 09:05:11 +00:00
|
|
|
|
|
|
|
public static OptionalAttributes newInstance(final String outputText, final int altCode,
|
2014-07-08 08:36:11 +00:00
|
|
|
final int disabledIconId, final int visualInsetsLeft, final int visualInsetsRight) {
|
2013-08-12 09:05:11 +00:00
|
|
|
if (outputText == null && altCode == CODE_UNSPECIFIED
|
2014-07-08 08:36:11 +00:00
|
|
|
&& disabledIconId == ICON_UNDEFINED && visualInsetsLeft == 0
|
|
|
|
&& visualInsetsRight == 0) {
|
2013-08-12 09:05:11 +00:00
|
|
|
return null;
|
|
|
|
}
|
2014-07-08 08:36:11 +00:00
|
|
|
return new OptionalAttributes(outputText, altCode, disabledIconId, visualInsetsLeft,
|
|
|
|
visualInsetsRight);
|
2013-08-12 09:05:11 +00:00
|
|
|
}
|
2012-08-28 08:19:49 +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
|
|
|
|
2010-12-14 06:31:47 +00:00
|
|
|
/**
|
2014-02-09 14:24:02 +00:00
|
|
|
* Constructor for a key on <code>MoreKeyKeyboard</code>, on <code>MoreSuggestions</code>,
|
|
|
|
* and in a <GridRows/>.
|
2011-08-30 09:35:56 +00:00
|
|
|
*/
|
2014-02-09 14:24:02 +00:00
|
|
|
public Key(final String label, final int iconId, final int code, final String outputText,
|
|
|
|
final String hintLabel, final int labelFlags, final int backgroundType, final int x,
|
|
|
|
final int y, final int width, final int height, final int horizontalGap,
|
|
|
|
final int verticalGap) {
|
|
|
|
mWidth = width - horizontalGap;
|
2014-09-03 21:15:44 +00:00
|
|
|
mHeight = height - verticalGap;
|
|
|
|
mHorizontalGap = horizontalGap;
|
|
|
|
mVerticalGap = verticalGap;
|
2011-08-30 09:35:56 +00:00
|
|
|
mHintLabel = hintLabel;
|
2012-02-29 09:45:13 +00:00
|
|
|
mLabelFlags = labelFlags;
|
2013-08-14 08:55:21 +00:00
|
|
|
mBackgroundType = backgroundType;
|
2014-06-13 02:01:36 +00:00
|
|
|
// TODO: Pass keyActionFlags as an argument.
|
|
|
|
mActionFlags = ACTION_FLAGS_NO_KEY_PREVIEW;
|
2011-08-31 06:26:32 +00:00
|
|
|
mMoreKeys = null;
|
2012-03-01 04:09:39 +00:00
|
|
|
mMoreKeysColumnAndFlags = 0;
|
2011-08-30 12:41:52 +00:00
|
|
|
mLabel = label;
|
2013-08-12 09:05:11 +00:00
|
|
|
mOptionalAttributes = OptionalAttributes.newInstance(outputText, CODE_UNSPECIFIED,
|
2014-07-08 08:36:11 +00:00
|
|
|
ICON_UNDEFINED, 0 /* visualInsetsLeft */, 0 /* visualInsetsRight */);
|
2011-08-30 09:35:56 +00:00
|
|
|
mCode = code;
|
2012-04-19 21:24:51 +00:00
|
|
|
mEnabled = (code != CODE_UNSPECIFIED);
|
2012-02-02 15:18:47 +00:00
|
|
|
mIconId = iconId;
|
2010-12-03 04:17:26 +00:00
|
|
|
// Horizontal gap is divided equally to both sides of the key.
|
2014-09-03 21:15:44 +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);
|
2012-08-30 08:42:49 +00:00
|
|
|
mKeyVisualAttributes = null;
|
2011-12-16 06:32:24 +00:00
|
|
|
|
2012-03-22 09:09:19 +00:00
|
|
|
mHashCode = computeHashCode(this);
|
2010-12-02 09:46:21 +00:00
|
|
|
}
|
|
|
|
|
2010-12-14 06:31:47 +00:00
|
|
|
/**
|
2014-02-09 14:24:02 +00:00
|
|
|
* Create a key with the given top-left coordinate and extract its attributes from a key
|
|
|
|
* specification string, Key attribute array, key style, and etc.
|
|
|
|
*
|
|
|
|
* @param keySpec the key specification.
|
|
|
|
* @param keyAttr the Key XML attributes array.
|
2014-05-14 06:30:37 +00:00
|
|
|
* @param style the {@link KeyStyle} of this key.
|
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
|
|
|
*/
|
2014-02-09 14:24:02 +00:00
|
|
|
public Key(final String keySpec, final TypedArray keyAttr, final KeyStyle style,
|
|
|
|
final KeyboardParams params, final KeyboardRow row) {
|
2014-09-03 21:15:44 +00:00
|
|
|
mHorizontalGap = isSpacer() ? 0 : params.mHorizontalGap;
|
|
|
|
mVerticalGap = params.mVerticalGap;
|
|
|
|
|
|
|
|
final float horizontalGapFloat = mHorizontalGap;
|
2013-08-19 02:00:52 +00:00
|
|
|
final int rowHeight = row.getRowHeight();
|
2014-09-03 21:15:44 +00:00
|
|
|
mHeight = rowHeight - mVerticalGap;
|
2010-12-02 09:46:21 +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.
|
2014-09-03 21:15:44 +00:00
|
|
|
mX = Math.round(keyXPos + horizontalGapFloat / 2);
|
2011-09-28 09:51:57 +00:00
|
|
|
mY = keyYPos;
|
2014-09-03 21:15:44 +00:00
|
|
|
mWidth = Math.round(keyWidth - horizontalGapFloat);
|
2012-05-28 07:13:11 +00:00
|
|
|
mHitBox.set(Math.round(keyXPos), keyYPos, Math.round(keyXPos + keyWidth) + 1,
|
2013-01-29 09:30:42 +00:00
|
|
|
keyYPos + rowHeight);
|
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,
|
2012-06-05 18:28:55 +00:00
|
|
|
R.styleable.Keyboard_Key_backgroundType, row.getDefaultBackgroundType());
|
2011-09-02 08:05:24 +00:00
|
|
|
|
2013-01-29 09:30:42 +00:00
|
|
|
final int baseWidth = params.mBaseWidth;
|
|
|
|
final int visualInsetsLeft = Math.round(keyAttr.getFraction(
|
|
|
|
R.styleable.Keyboard_Key_visualInsetsLeft, baseWidth, baseWidth, 0));
|
|
|
|
final int visualInsetsRight = Math.round(keyAttr.getFraction(
|
|
|
|
R.styleable.Keyboard_Key_visualInsetsRight, baseWidth, baseWidth, 0));
|
2011-09-02 08:05:24 +00:00
|
|
|
|
2013-08-19 02:02:44 +00:00
|
|
|
mLabelFlags = style.getFlags(keyAttr, R.styleable.Keyboard_Key_keyLabelFlags)
|
2012-03-12 07:30:59 +00:00
|
|
|
| row.getDefaultKeyLabelFlags();
|
2012-05-26 04:23:34 +00:00
|
|
|
final boolean needsToUpperCase = needsToUpperCase(mLabelFlags, params.mId.mElementId);
|
|
|
|
final Locale locale = params.mId.mLocale;
|
2013-08-19 02:02:44 +00:00
|
|
|
int actionFlags = style.getFlags(keyAttr, R.styleable.Keyboard_Key_keyActionFlags);
|
2012-02-13 22:34:09 +00:00
|
|
|
String[] moreKeys = style.getStringArray(keyAttr, R.styleable.Keyboard_Key_moreKeys);
|
2012-03-01 04:09:39 +00:00
|
|
|
|
2014-08-23 12:10:42 +00:00
|
|
|
// Get maximum column order number and set a relevant mode value.
|
|
|
|
int moreKeysColumnAndFlags = MORE_KEYS_MODE_MAX_COLUMN_WITH_AUTO_ORDER
|
|
|
|
| style.getInt(keyAttr, R.styleable.Keyboard_Key_maxMoreKeysColumn,
|
|
|
|
params.mMaxMoreKeysKeyboardColumn);
|
2012-03-01 04:09:39 +00:00
|
|
|
int value;
|
2014-01-31 06:58:14 +00:00
|
|
|
if ((value = MoreKeySpec.getIntValue(moreKeys, MORE_KEYS_AUTO_COLUMN_ORDER, -1)) > 0) {
|
2014-08-23 12:10:42 +00:00
|
|
|
// Override with fixed column order number and set a relevant mode value.
|
|
|
|
moreKeysColumnAndFlags = MORE_KEYS_MODE_FIXED_COLUMN_WITH_AUTO_ORDER
|
|
|
|
| (value & MORE_KEYS_COLUMN_NUMBER_MASK);
|
2012-03-01 04:09:39 +00:00
|
|
|
}
|
2014-01-31 06:58:14 +00:00
|
|
|
if ((value = MoreKeySpec.getIntValue(moreKeys, MORE_KEYS_FIXED_COLUMN_ORDER, -1)) > 0) {
|
2014-08-23 12:10:42 +00:00
|
|
|
// Override with fixed column order number and set a relevant mode value.
|
|
|
|
moreKeysColumnAndFlags = MORE_KEYS_MODE_FIXED_COLUMN_WITH_FIXED_ORDER
|
|
|
|
| (value & MORE_KEYS_COLUMN_NUMBER_MASK);
|
2012-02-13 22:34:09 +00:00
|
|
|
}
|
2014-01-31 06:58:14 +00:00
|
|
|
if (MoreKeySpec.getBooleanValue(moreKeys, MORE_KEYS_HAS_LABELS)) {
|
2014-08-23 12:10:42 +00:00
|
|
|
moreKeysColumnAndFlags |= MORE_KEYS_FLAGS_HAS_LABELS;
|
2012-02-29 09:45:13 +00:00
|
|
|
}
|
2014-01-31 06:58:14 +00:00
|
|
|
if (MoreKeySpec.getBooleanValue(moreKeys, MORE_KEYS_NEEDS_DIVIDERS)) {
|
2014-08-23 12:10:42 +00:00
|
|
|
moreKeysColumnAndFlags |= MORE_KEYS_FLAGS_NEEDS_DIVIDERS;
|
2012-02-29 13:21:57 +00:00
|
|
|
}
|
2014-01-31 06:58:14 +00:00
|
|
|
if (MoreKeySpec.getBooleanValue(moreKeys, MORE_KEYS_NO_PANEL_AUTO_MORE_KEY)) {
|
2014-08-23 12:10:42 +00:00
|
|
|
moreKeysColumnAndFlags |= MORE_KEYS_FLAGS_NO_PANEL_AUTO_MORE_KEY;
|
2012-03-05 02:39:07 +00:00
|
|
|
}
|
2014-08-23 12:10:42 +00:00
|
|
|
mMoreKeysColumnAndFlags = moreKeysColumnAndFlags;
|
2012-03-01 04:09:39 +00:00
|
|
|
|
2012-03-12 07:30:59 +00:00
|
|
|
final String[] additionalMoreKeys;
|
|
|
|
if ((mLabelFlags & LABEL_FLAGS_DISABLE_ADDITIONAL_MORE_KEYS) != 0) {
|
|
|
|
additionalMoreKeys = null;
|
|
|
|
} else {
|
2012-04-19 21:24:51 +00:00
|
|
|
additionalMoreKeys = style.getStringArray(keyAttr,
|
|
|
|
R.styleable.Keyboard_Key_additionalMoreKeys);
|
2012-03-12 07:30:59 +00:00
|
|
|
}
|
2014-01-31 06:58:14 +00:00
|
|
|
moreKeys = MoreKeySpec.insertAdditionalMoreKeys(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-04-09 08:48:32 +00:00
|
|
|
mMoreKeys = new MoreKeySpec[moreKeys.length];
|
2012-01-25 10:43:13 +00:00
|
|
|
for (int i = 0; i < moreKeys.length; i++) {
|
2014-02-10 08:48:35 +00:00
|
|
|
mMoreKeys[i] = new MoreKeySpec(moreKeys[i], needsToUpperCase, locale);
|
2012-01-25 10:43:13 +00:00
|
|
|
}
|
2012-04-09 08:48:32 +00:00
|
|
|
} else {
|
|
|
|
mMoreKeys = null;
|
2012-01-25 10:43:13 +00:00
|
|
|
}
|
2012-02-01 06:07:25 +00:00
|
|
|
mActionFlags = actionFlags;
|
2012-01-25 10:43:13 +00:00
|
|
|
|
2014-02-06 02:34:12 +00:00
|
|
|
mIconId = KeySpecParser.getIconId(keySpec);
|
2014-02-05 09:14:47 +00:00
|
|
|
final int disabledIconId = KeySpecParser.getIconId(style.getString(keyAttr,
|
|
|
|
R.styleable.Keyboard_Key_keyIconDisabled));
|
|
|
|
|
2014-02-10 08:48:35 +00:00
|
|
|
final int code = KeySpecParser.getCode(keySpec);
|
2012-02-07 08:07:23 +00:00
|
|
|
if ((mLabelFlags & LABEL_FLAGS_FROM_CUSTOM_ACTION_LABEL) != 0) {
|
|
|
|
mLabel = params.mId.mCustomActionLabel;
|
2013-08-07 06:18:20 +00:00
|
|
|
} else if (code >= Character.MIN_SUPPLEMENTARY_CODE_POINT) {
|
|
|
|
// This is a workaround to have a key that has a supplementary code point in its label.
|
|
|
|
// Because we can put a string in resource neither as a XML entity of a supplementary
|
|
|
|
// code point nor as a surrogate pair.
|
|
|
|
mLabel = new StringBuilder().appendCodePoint(code).toString();
|
2012-02-07 08:07:23 +00:00
|
|
|
} else {
|
2014-02-05 09:14:47 +00:00
|
|
|
mLabel = StringUtils.toUpperCaseOfStringForLocale(
|
|
|
|
KeySpecParser.getLabel(keySpec), needsToUpperCase, locale);
|
2012-02-07 08:07:23 +00:00
|
|
|
}
|
2012-03-12 07:30:59 +00:00
|
|
|
if ((mLabelFlags & LABEL_FLAGS_DISABLE_HINT_LABEL) != 0) {
|
|
|
|
mHintLabel = null;
|
|
|
|
} else {
|
2014-01-31 05:20:15 +00:00
|
|
|
mHintLabel = StringUtils.toUpperCaseOfStringForLocale(style.getString(keyAttr,
|
2012-05-26 04:23:34 +00:00
|
|
|
R.styleable.Keyboard_Key_keyHintLabel), needsToUpperCase, locale);
|
2012-03-12 07:30:59 +00:00
|
|
|
}
|
2014-02-05 09:14:47 +00:00
|
|
|
String outputText = StringUtils.toUpperCaseOfStringForLocale(
|
2014-02-05 09:26:14 +00:00
|
|
|
KeySpecParser.getOutputText(keySpec), needsToUpperCase, locale);
|
2012-01-26 09:03:30 +00:00
|
|
|
// Choose the first letter of the label as primary code if not specified.
|
2012-04-19 21:24:51 +00:00
|
|
|
if (code == CODE_UNSPECIFIED && TextUtils.isEmpty(outputText)
|
2011-12-12 03:52:42 +00:00
|
|
|
&& !TextUtils.isEmpty(mLabel)) {
|
2012-03-08 08:07:02 +00:00
|
|
|
if (StringUtils.codePointCount(mLabel) == 1) {
|
2012-01-26 09:03:30 +00:00
|
|
|
// Use the first letter of the hint label if shiftedLetterActivated flag is
|
|
|
|
// specified.
|
2013-12-13 09:33:11 +00:00
|
|
|
if (hasShiftedLetterHint() && isShiftedLetterActivated()) {
|
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;
|
2012-04-19 21:24:51 +00:00
|
|
|
mCode = CODE_OUTPUT_TEXT;
|
2011-12-12 03:52:42 +00:00
|
|
|
}
|
2012-04-19 21:24:51 +00:00
|
|
|
} else if (code == CODE_UNSPECIFIED && outputText != null) {
|
2012-03-08 08:07:02 +00:00
|
|
|
if (StringUtils.codePointCount(outputText) == 1) {
|
2012-02-07 11:42:07 +00:00
|
|
|
mCode = outputText.codePointAt(0);
|
|
|
|
outputText = null;
|
|
|
|
} else {
|
2012-04-19 21:24:51 +00:00
|
|
|
mCode = CODE_OUTPUT_TEXT;
|
2012-02-07 11:42:07 +00:00
|
|
|
}
|
2011-09-02 08:05:24 +00:00
|
|
|
} else {
|
2014-01-31 05:20:15 +00:00
|
|
|
mCode = StringUtils.toUpperCaseOfCodeForLocale(code, needsToUpperCase, locale);
|
2011-09-02 08:05:24 +00:00
|
|
|
}
|
2014-02-10 08:48:35 +00:00
|
|
|
final int altCodeInAttr = KeySpecParser.parseCode(
|
|
|
|
style.getString(keyAttr, R.styleable.Keyboard_Key_altCode), CODE_UNSPECIFIED);
|
2014-01-31 05:20:15 +00:00
|
|
|
final int altCode = StringUtils.toUpperCaseOfCodeForLocale(
|
2014-02-06 02:34:12 +00:00
|
|
|
altCodeInAttr, needsToUpperCase, locale);
|
2013-08-12 09:05:11 +00:00
|
|
|
mOptionalAttributes = OptionalAttributes.newInstance(outputText, altCode,
|
2014-07-08 08:36:11 +00:00
|
|
|
disabledIconId, visualInsetsLeft, visualInsetsRight);
|
2012-08-30 08:42:49 +00:00
|
|
|
mKeyVisualAttributes = KeyVisualAttributes.newInstance(keyAttr);
|
|
|
|
mHashCode = computeHashCode(this);
|
2011-12-16 06:32:24 +00:00
|
|
|
}
|
|
|
|
|
2013-08-12 09:05:11 +00:00
|
|
|
/**
|
2014-02-09 14:24:02 +00:00
|
|
|
* Copy constructor for DynamicGridKeyboard.GridKey.
|
2013-08-12 09:05:11 +00:00
|
|
|
*
|
|
|
|
* @param key the original key.
|
|
|
|
*/
|
|
|
|
protected Key(final Key key) {
|
2014-09-24 06:52:11 +00:00
|
|
|
this(key, key.mMoreKeys);
|
|
|
|
}
|
|
|
|
|
|
|
|
private Key(final Key key, final MoreKeySpec[] moreKeys) {
|
2013-08-12 09:05:11 +00:00
|
|
|
// Final attributes.
|
|
|
|
mCode = key.mCode;
|
|
|
|
mLabel = key.mLabel;
|
|
|
|
mHintLabel = key.mHintLabel;
|
|
|
|
mLabelFlags = key.mLabelFlags;
|
|
|
|
mIconId = key.mIconId;
|
|
|
|
mWidth = key.mWidth;
|
|
|
|
mHeight = key.mHeight;
|
2014-09-03 21:15:44 +00:00
|
|
|
mHorizontalGap = key.mHorizontalGap;
|
|
|
|
mVerticalGap = key.mVerticalGap;
|
2013-08-12 09:05:11 +00:00
|
|
|
mX = key.mX;
|
|
|
|
mY = key.mY;
|
|
|
|
mHitBox.set(key.mHitBox);
|
2014-09-24 06:52:11 +00:00
|
|
|
mMoreKeys = moreKeys;
|
2013-08-12 09:05:11 +00:00
|
|
|
mMoreKeysColumnAndFlags = key.mMoreKeysColumnAndFlags;
|
|
|
|
mBackgroundType = key.mBackgroundType;
|
|
|
|
mActionFlags = key.mActionFlags;
|
|
|
|
mKeyVisualAttributes = key.mKeyVisualAttributes;
|
|
|
|
mOptionalAttributes = key.mOptionalAttributes;
|
|
|
|
mHashCode = key.mHashCode;
|
|
|
|
// Key state.
|
|
|
|
mPressed = key.mPressed;
|
|
|
|
mEnabled = key.mEnabled;
|
|
|
|
}
|
|
|
|
|
2014-09-24 06:52:11 +00:00
|
|
|
public static Key removeRedundantMoreKeys(final Key key,
|
|
|
|
final MoreKeySpec.LettersOnBaseLayout lettersOnBaseLayout) {
|
|
|
|
final MoreKeySpec[] moreKeys = key.getMoreKeys();
|
|
|
|
final MoreKeySpec[] filteredMoreKeys = MoreKeySpec.removeRedundantMoreKeys(
|
|
|
|
moreKeys, lettersOnBaseLayout);
|
|
|
|
return (filteredMoreKeys == moreKeys) ? key : new Key(key, filteredMoreKeys);
|
|
|
|
}
|
|
|
|
|
2012-08-30 05:22:40 +00:00
|
|
|
private static boolean needsToUpperCase(final int labelFlags, final int keyboardElementId) {
|
2012-05-26 04:23:34 +00:00
|
|
|
if ((labelFlags & LABEL_FLAGS_PRESERVE_CASE) != 0) return false;
|
|
|
|
switch (keyboardElementId) {
|
2012-01-25 10:43:13 +00:00
|
|
|
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:
|
2012-05-26 04:23:34 +00:00
|
|
|
return true;
|
2012-01-25 10:43:13 +00:00
|
|
|
default:
|
2012-05-26 04:23:34 +00:00
|
|
|
return false;
|
2012-01-25 10:43:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-08-30 05:22:40 +00:00
|
|
|
private static int computeHashCode(final Key key) {
|
2011-12-16 06:32:24 +00:00
|
|
|
return Arrays.hashCode(new Object[] {
|
|
|
|
key.mX,
|
|
|
|
key.mY,
|
|
|
|
key.mWidth,
|
|
|
|
key.mHeight,
|
|
|
|
key.mCode,
|
|
|
|
key.mLabel,
|
|
|
|
key.mHintLabel,
|
2012-02-02 15:18:47 +00:00
|
|
|
key.mIconId,
|
2012-01-26 09:03:30 +00:00
|
|
|
key.mBackgroundType,
|
2012-02-09 18:17:39 +00:00
|
|
|
Arrays.hashCode(key.mMoreKeys),
|
2012-08-28 08:19:49 +00:00
|
|
|
key.getOutputText(),
|
2012-02-09 18:17:39 +00:00
|
|
|
key.mActionFlags,
|
|
|
|
key.mLabelFlags,
|
2011-12-16 06:32:24 +00:00
|
|
|
// Key can be distinguishable without the following members.
|
2012-08-28 08:19:49 +00:00
|
|
|
// key.mOptionalAttributes.mAltCode,
|
|
|
|
// key.mOptionalAttributes.mDisabledIconId,
|
|
|
|
// key.mOptionalAttributes.mPreviewIconId,
|
2011-12-16 06:32:24 +00:00
|
|
|
// key.mHorizontalGap,
|
|
|
|
// key.mVerticalGap,
|
2012-08-28 08:19:49 +00:00
|
|
|
// key.mOptionalAttributes.mVisualInsetLeft,
|
|
|
|
// key.mOptionalAttributes.mVisualInsetRight,
|
2011-12-16 06:32:24 +00:00
|
|
|
// key.mMaxMoreKeysColumn,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2012-09-11 10:15:00 +00:00
|
|
|
private boolean equalsInternal(final Key o) {
|
2011-12-16 06:32:24 +00:00
|
|
|
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)
|
2012-02-02 15:18:47 +00:00
|
|
|
&& o.mIconId == mIconId
|
2012-02-09 18:17:39 +00:00
|
|
|
&& o.mBackgroundType == mBackgroundType
|
|
|
|
&& Arrays.equals(o.mMoreKeys, mMoreKeys)
|
2012-08-28 08:19:49 +00:00
|
|
|
&& TextUtils.equals(o.getOutputText(), getOutputText())
|
2012-02-09 18:17:39 +00:00
|
|
|
&& o.mActionFlags == mActionFlags
|
|
|
|
&& o.mLabelFlags == mLabelFlags;
|
2011-12-16 06:32:24 +00:00
|
|
|
}
|
|
|
|
|
2012-09-11 10:15:00 +00:00
|
|
|
@Override
|
|
|
|
public int compareTo(Key o) {
|
|
|
|
if (equalsInternal(o)) return 0;
|
|
|
|
if (mHashCode > o.mHashCode) return 1;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2011-12-16 06:32:24 +00:00
|
|
|
@Override
|
|
|
|
public int hashCode() {
|
|
|
|
return mHashCode;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2012-08-30 05:22:40 +00:00
|
|
|
public boolean equals(final Object o) {
|
2012-09-11 10:15:00 +00:00
|
|
|
return o instanceof Key && equalsInternal((Key)o);
|
2010-12-03 04:17:26 +00:00
|
|
|
}
|
|
|
|
|
2012-01-26 09:03:30 +00:00
|
|
|
@Override
|
|
|
|
public String toString() {
|
2014-06-03 04:30:38 +00:00
|
|
|
return toShortString() + " " + getX() + "," + getY() + " " + getWidth() + "x" + getHeight();
|
|
|
|
}
|
|
|
|
|
|
|
|
public String toShortString() {
|
|
|
|
final int code = getCode();
|
|
|
|
if (code == Constants.CODE_OUTPUT_TEXT) {
|
|
|
|
return getOutputText();
|
2012-07-30 06:51:41 +00:00
|
|
|
}
|
2014-06-03 04:30:38 +00:00
|
|
|
return Constants.printableCode(code);
|
|
|
|
}
|
|
|
|
|
|
|
|
public String toLongString() {
|
|
|
|
final int iconId = getIconId();
|
|
|
|
final String topVisual = (iconId == KeyboardIconsSet.ICON_UNDEFINED)
|
|
|
|
? KeyboardIconsSet.PREFIX_ICON + KeyboardIconsSet.getIconName(iconId) : getLabel();
|
|
|
|
final String hintLabel = getHintLabel();
|
|
|
|
final String visual = (hintLabel == null) ? topVisual : topVisual + "^" + hintLabel;
|
|
|
|
return toString() + " " + visual + "/" + backgroundName(mBackgroundType);
|
2012-02-02 12:24:09 +00:00
|
|
|
}
|
|
|
|
|
2012-08-30 05:22:40 +00:00
|
|
|
private static String backgroundName(final int backgroundType) {
|
2012-02-02 12:24:09 +00:00
|
|
|
switch (backgroundType) {
|
2013-08-14 08:55:21 +00:00
|
|
|
case BACKGROUND_TYPE_EMPTY: return "empty";
|
2012-02-02 12:24:09 +00:00
|
|
|
case BACKGROUND_TYPE_NORMAL: return "normal";
|
|
|
|
case BACKGROUND_TYPE_FUNCTIONAL: return "functional";
|
|
|
|
case BACKGROUND_TYPE_STICKY_OFF: return "stickyOff";
|
|
|
|
case BACKGROUND_TYPE_STICKY_ON: return "stickyOn";
|
2014-08-06 08:23:14 +00:00
|
|
|
case BACKGROUND_TYPE_ACTION: return "action";
|
2014-09-03 01:52:56 +00:00
|
|
|
case BACKGROUND_TYPE_SPACEBAR: return "spacebar";
|
2012-02-02 12:24:09 +00:00
|
|
|
default: return null;
|
2012-01-26 09:03:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-08-12 09:05:11 +00:00
|
|
|
public int getCode() {
|
|
|
|
return mCode;
|
|
|
|
}
|
|
|
|
|
|
|
|
public String getLabel() {
|
|
|
|
return mLabel;
|
|
|
|
}
|
|
|
|
|
|
|
|
public String getHintLabel() {
|
|
|
|
return mHintLabel;
|
|
|
|
}
|
|
|
|
|
|
|
|
public MoreKeySpec[] getMoreKeys() {
|
|
|
|
return mMoreKeys;
|
|
|
|
}
|
|
|
|
|
2012-08-30 05:22:40 +00:00
|
|
|
public void markAsLeftEdge(final KeyboardParams params) {
|
2013-01-30 04:08:44 +00:00
|
|
|
mHitBox.left = params.mLeftPadding;
|
2011-09-28 09:51:57 +00:00
|
|
|
}
|
|
|
|
|
2012-08-30 05:22:40 +00:00
|
|
|
public void markAsRightEdge(final KeyboardParams params) {
|
2013-01-30 04:08:44 +00:00
|
|
|
mHitBox.right = params.mOccupiedWidth - params.mRightPadding;
|
2011-09-28 09:51:57 +00:00
|
|
|
}
|
|
|
|
|
2012-08-30 05:22:40 +00:00
|
|
|
public void markAsTopEdge(final KeyboardParams params) {
|
2011-09-28 09:51:57 +00:00
|
|
|
mHitBox.top = params.mTopPadding;
|
|
|
|
}
|
|
|
|
|
2012-08-30 05:22:40 +00:00
|
|
|
public void markAsBottomEdge(final KeyboardParams params) {
|
2011-09-28 09:51:57 +00:00
|
|
|
mHitBox.bottom = params.mOccupiedHeight + params.mBottomPadding;
|
2011-07-19 00:14:50 +00:00
|
|
|
}
|
|
|
|
|
2012-02-02 15:18:47 +00:00
|
|
|
public final boolean isSpacer() {
|
|
|
|
return this instanceof Spacer;
|
2011-09-08 08:19:23 +00:00
|
|
|
}
|
|
|
|
|
2014-08-22 09:36:09 +00:00
|
|
|
public final boolean isActionKey() {
|
|
|
|
return mBackgroundType == BACKGROUND_TYPE_ACTION;
|
|
|
|
}
|
|
|
|
|
2012-08-30 08:42:49 +00:00
|
|
|
public final boolean isShift() {
|
2012-04-19 21:24:51 +00:00
|
|
|
return mCode == CODE_SHIFT;
|
2011-11-29 07:56:27 +00:00
|
|
|
}
|
|
|
|
|
2012-08-30 08:42:49 +00:00
|
|
|
public final boolean isModifier() {
|
2012-04-19 21:24:51 +00:00
|
|
|
return mCode == CODE_SHIFT || mCode == CODE_SWITCH_ALPHA_SYMBOL;
|
2011-11-29 07:56:27 +00:00
|
|
|
}
|
|
|
|
|
2012-08-30 08:42:49 +00:00
|
|
|
public final boolean isRepeatable() {
|
2011-11-22 03:55:38 +00:00
|
|
|
return (mActionFlags & ACTION_FLAGS_IS_REPEATABLE) != 0;
|
|
|
|
}
|
|
|
|
|
2012-08-30 08:42:49 +00:00
|
|
|
public final boolean noKeyPreview() {
|
2011-11-22 03:55:38 +00:00
|
|
|
return (mActionFlags & ACTION_FLAGS_NO_KEY_PREVIEW) != 0;
|
|
|
|
}
|
|
|
|
|
2012-08-30 08:42:49 +00:00
|
|
|
public final boolean altCodeWhileTyping() {
|
2011-11-30 08:54:58 +00:00
|
|
|
return (mActionFlags & ACTION_FLAGS_ALT_CODE_WHILE_TYPING) != 0;
|
2011-11-23 02:07:43 +00:00
|
|
|
}
|
|
|
|
|
2012-08-30 08:42:49 +00:00
|
|
|
public final boolean isLongPressEnabled() {
|
2012-02-01 06:07:25 +00:00
|
|
|
// 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;
|
|
|
|
}
|
|
|
|
|
2013-08-12 09:05:11 +00:00
|
|
|
public KeyVisualAttributes getVisualAttributes() {
|
|
|
|
return mKeyVisualAttributes;
|
|
|
|
}
|
|
|
|
|
2012-08-30 08:42:49 +00:00
|
|
|
public final Typeface selectTypeface(final KeyDrawParams params) {
|
2014-07-07 07:54:00 +00:00
|
|
|
switch (mLabelFlags & LABEL_FLAGS_FONT_MASK) {
|
|
|
|
case LABEL_FLAGS_FONT_NORMAL:
|
2011-06-25 10:38:55 +00:00
|
|
|
return Typeface.DEFAULT;
|
2014-07-07 07:54:00 +00:00
|
|
|
case LABEL_FLAGS_FONT_MONO_SPACE:
|
2011-06-25 10:38:55 +00:00
|
|
|
return Typeface.MONOSPACE;
|
2014-07-07 07:54:00 +00:00
|
|
|
case LABEL_FLAGS_FONT_DEFAULT:
|
|
|
|
default:
|
|
|
|
// The type-face is specified by keyTypeface attribute.
|
|
|
|
return params.mTypeface;
|
2011-06-25 10:38:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-08-30 08:42:49 +00:00
|
|
|
public final int selectTextSize(final KeyDrawParams params) {
|
2012-05-17 10:30:38 +00:00
|
|
|
switch (mLabelFlags & LABEL_FLAGS_FOLLOW_KEY_TEXT_RATIO_MASK) {
|
2012-04-11 03:34:30 +00:00
|
|
|
case LABEL_FLAGS_FOLLOW_KEY_LETTER_RATIO:
|
2012-08-30 08:42:49 +00:00
|
|
|
return params.mLetterSize;
|
2012-05-18 08:07:14 +00:00
|
|
|
case LABEL_FLAGS_FOLLOW_KEY_LARGE_LETTER_RATIO:
|
2012-08-30 08:42:49 +00:00
|
|
|
return params.mLargeLetterSize;
|
2012-04-11 03:34:30 +00:00
|
|
|
case LABEL_FLAGS_FOLLOW_KEY_LABEL_RATIO:
|
2012-08-30 08:42:49 +00:00
|
|
|
return params.mLabelSize;
|
2012-04-11 03:34:30 +00:00
|
|
|
case LABEL_FLAGS_FOLLOW_KEY_HINT_LABEL_RATIO:
|
2012-08-30 08:42:49 +00:00
|
|
|
return params.mHintLabelSize;
|
2012-04-11 03:34:30 +00:00
|
|
|
default: // No follow key ratio flag specified.
|
2012-08-30 08:42:49 +00:00
|
|
|
return StringUtils.codePointCount(mLabel) == 1 ? params.mLetterSize : params.mLabelSize;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public final int selectTextColor(final KeyDrawParams params) {
|
2014-05-15 06:39:01 +00:00
|
|
|
if ((mLabelFlags & LABEL_FLAGS_FOLLOW_FUNCTIONAL_TEXT_COLOR) != 0) {
|
|
|
|
return params.mFunctionalTextColor;
|
|
|
|
}
|
2014-02-24 08:42:28 +00:00
|
|
|
return isShiftedLetterActivated() ? params.mTextInactivatedColor : params.mTextColor;
|
2012-08-30 08:42:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public final int selectHintTextSize(final KeyDrawParams params) {
|
|
|
|
if (hasHintLabel()) {
|
|
|
|
return params.mHintLabelSize;
|
2013-03-08 09:57:55 +00:00
|
|
|
}
|
|
|
|
if (hasShiftedLetterHint()) {
|
2012-08-30 08:42:49 +00:00
|
|
|
return params.mShiftedLetterHintSize;
|
2011-06-25 10:38:55 +00:00
|
|
|
}
|
2013-03-08 09:57:55 +00:00
|
|
|
return params.mHintLetterSize;
|
2011-06-25 10:38:55 +00:00
|
|
|
}
|
|
|
|
|
2012-08-30 08:42:49 +00:00
|
|
|
public final int selectHintTextColor(final KeyDrawParams params) {
|
|
|
|
if (hasHintLabel()) {
|
|
|
|
return params.mHintLabelColor;
|
2013-03-08 09:57:55 +00:00
|
|
|
}
|
|
|
|
if (hasShiftedLetterHint()) {
|
2012-08-30 08:42:49 +00:00
|
|
|
return isShiftedLetterActivated() ? params.mShiftedLetterHintActivatedColor
|
|
|
|
: params.mShiftedLetterHintInactivatedColor;
|
|
|
|
}
|
2013-03-08 09:57:55 +00:00
|
|
|
return params.mHintLetterColor;
|
2012-08-30 08:42:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public final int selectMoreKeyTextSize(final KeyDrawParams params) {
|
|
|
|
return hasLabelsInMoreKeys() ? params.mLabelSize : params.mLetterSize;
|
|
|
|
}
|
|
|
|
|
2013-03-08 09:57:55 +00:00
|
|
|
public final String getPreviewLabel() {
|
|
|
|
return isShiftedLetterActivated() ? mHintLabel : mLabel;
|
|
|
|
}
|
|
|
|
|
|
|
|
private boolean previewHasLetterSize() {
|
|
|
|
return (mLabelFlags & LABEL_FLAGS_FOLLOW_KEY_LETTER_RATIO) != 0
|
|
|
|
|| StringUtils.codePointCount(getPreviewLabel()) == 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
public final int selectPreviewTextSize(final KeyDrawParams params) {
|
|
|
|
if (previewHasLetterSize()) {
|
|
|
|
return params.mPreviewTextSize;
|
|
|
|
}
|
|
|
|
return params.mLetterSize;
|
|
|
|
}
|
|
|
|
|
|
|
|
public Typeface selectPreviewTypeface(final KeyDrawParams params) {
|
|
|
|
if (previewHasLetterSize()) {
|
|
|
|
return selectTypeface(params);
|
|
|
|
}
|
|
|
|
return Typeface.DEFAULT_BOLD;
|
|
|
|
}
|
|
|
|
|
2014-08-07 14:44:34 +00:00
|
|
|
public final boolean isAlignHintLabelToBottom(final int defaultFlags) {
|
|
|
|
return ((mLabelFlags | defaultFlags) & LABEL_FLAGS_ALIGN_HINT_LABEL_TO_BOTTOM) != 0;
|
|
|
|
}
|
|
|
|
|
2014-08-07 03:32:59 +00:00
|
|
|
public final boolean isAlignIconToBottom() {
|
|
|
|
return (mLabelFlags & LABEL_FLAGS_ALIGN_ICON_TO_BOTTOM) != 0;
|
|
|
|
}
|
|
|
|
|
2014-08-07 14:31:47 +00:00
|
|
|
public final boolean isAlignLabelOffCenter() {
|
|
|
|
return (mLabelFlags & LABEL_FLAGS_ALIGN_LABEL_OFF_CENTER) != 0;
|
2011-08-03 04:29:24 +00:00
|
|
|
}
|
|
|
|
|
2012-08-30 08:42:49 +00:00
|
|
|
public final 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-08-30 08:42:49 +00:00
|
|
|
public final boolean hasShiftedLetterHint() {
|
2013-12-13 09:33:11 +00:00
|
|
|
return (mLabelFlags & LABEL_FLAGS_HAS_SHIFTED_LETTER_HINT) != 0
|
|
|
|
&& !TextUtils.isEmpty(mHintLabel);
|
2011-06-15 03:36:53 +00:00
|
|
|
}
|
|
|
|
|
2012-08-30 08:42:49 +00:00
|
|
|
public final 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
|
|
|
}
|
|
|
|
|
2013-12-13 08:09:16 +00:00
|
|
|
public final boolean needsAutoXScale() {
|
2011-11-22 03:55:38 +00:00
|
|
|
return (mLabelFlags & LABEL_FLAGS_AUTO_X_SCALE) != 0;
|
2011-11-18 21:47:48 +00:00
|
|
|
}
|
|
|
|
|
2013-12-13 08:09:16 +00:00
|
|
|
public final boolean needsAutoScale() {
|
|
|
|
return (mLabelFlags & LABEL_FLAGS_AUTO_SCALE) == LABEL_FLAGS_AUTO_SCALE;
|
|
|
|
}
|
|
|
|
|
2014-09-09 04:05:31 +00:00
|
|
|
public final boolean needsToKeepBackgroundAspectRatio(final int defaultFlags) {
|
|
|
|
return ((mLabelFlags | defaultFlags) & LABEL_FLAGS_KEEP_BACKGROUND_ASPECT_RATIO) != 0;
|
|
|
|
}
|
|
|
|
|
2014-09-16 08:56:18 +00:00
|
|
|
public final boolean hasCustomActionLabel() {
|
|
|
|
return (mLabelFlags & LABEL_FLAGS_FROM_CUSTOM_ACTION_LABEL) != 0;
|
|
|
|
}
|
|
|
|
|
2013-12-13 09:33:11 +00:00
|
|
|
private final boolean isShiftedLetterActivated() {
|
|
|
|
return (mLabelFlags & LABEL_FLAGS_SHIFTED_LETTER_ACTIVATED) != 0
|
|
|
|
&& !TextUtils.isEmpty(mHintLabel);
|
2012-01-27 09:10:19 +00:00
|
|
|
}
|
|
|
|
|
2014-08-23 12:10:42 +00:00
|
|
|
public final int getMoreKeysColumnNumber() {
|
|
|
|
return mMoreKeysColumnAndFlags & MORE_KEYS_COLUMN_NUMBER_MASK;
|
2012-03-01 04:09:39 +00:00
|
|
|
}
|
|
|
|
|
2014-08-23 12:10:42 +00:00
|
|
|
public final boolean isMoreKeysFixedColumn() {
|
|
|
|
return (mMoreKeysColumnAndFlags & MORE_KEYS_FLAGS_FIXED_COLUMN) != 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
public final boolean isMoreKeysFixedOrder() {
|
|
|
|
return (mMoreKeysColumnAndFlags & MORE_KEYS_FLAGS_FIXED_ORDER) != 0;
|
2012-03-01 04:09:39 +00:00
|
|
|
}
|
|
|
|
|
2012-08-30 08:42:49 +00:00
|
|
|
public final boolean hasLabelsInMoreKeys() {
|
2012-02-29 09:45:13 +00:00
|
|
|
return (mMoreKeysColumnAndFlags & MORE_KEYS_FLAGS_HAS_LABELS) != 0;
|
|
|
|
}
|
|
|
|
|
2012-08-30 08:42:49 +00:00
|
|
|
public final int getMoreKeyLabelFlags() {
|
2014-08-11 06:22:19 +00:00
|
|
|
final int labelSizeFlag = hasLabelsInMoreKeys()
|
2012-04-11 03:34:30 +00:00
|
|
|
? LABEL_FLAGS_FOLLOW_KEY_LABEL_RATIO
|
|
|
|
: LABEL_FLAGS_FOLLOW_KEY_LETTER_RATIO;
|
2014-08-11 06:22:19 +00:00
|
|
|
return labelSizeFlag | LABEL_FLAGS_AUTO_X_SCALE;
|
2012-04-11 03:34:30 +00:00
|
|
|
}
|
|
|
|
|
2012-08-30 08:42:49 +00:00
|
|
|
public final boolean needsDividersInMoreKeys() {
|
2012-02-29 13:21:57 +00:00
|
|
|
return (mMoreKeysColumnAndFlags & MORE_KEYS_FLAGS_NEEDS_DIVIDERS) != 0;
|
|
|
|
}
|
|
|
|
|
2013-05-22 00:14:31 +00:00
|
|
|
public final boolean hasNoPanelAutoMoreKey() {
|
|
|
|
return (mMoreKeysColumnAndFlags & MORE_KEYS_FLAGS_NO_PANEL_AUTO_MORE_KEY) != 0;
|
2012-03-05 02:39:07 +00:00
|
|
|
}
|
|
|
|
|
2012-08-30 08:42:49 +00:00
|
|
|
public final String getOutputText() {
|
2012-08-28 08:19:49 +00:00
|
|
|
final OptionalAttributes attrs = mOptionalAttributes;
|
|
|
|
return (attrs != null) ? attrs.mOutputText : null;
|
|
|
|
}
|
|
|
|
|
2012-08-30 08:42:49 +00:00
|
|
|
public final int getAltCode() {
|
2012-08-28 08:19:49 +00:00
|
|
|
final OptionalAttributes attrs = mOptionalAttributes;
|
|
|
|
return (attrs != null) ? attrs.mAltCode : CODE_UNSPECIFIED;
|
|
|
|
}
|
|
|
|
|
2014-02-17 06:37:43 +00:00
|
|
|
public int getIconId() {
|
|
|
|
return mIconId;
|
|
|
|
}
|
|
|
|
|
2012-08-30 05:22:40 +00:00
|
|
|
public Drawable getIcon(final KeyboardIconsSet iconSet, final int alpha) {
|
2012-08-28 08:19:49 +00:00
|
|
|
final OptionalAttributes attrs = mOptionalAttributes;
|
|
|
|
final int disabledIconId = (attrs != null) ? attrs.mDisabledIconId : ICON_UNDEFINED;
|
2014-02-17 06:37:43 +00:00
|
|
|
final int iconId = mEnabled ? getIconId() : disabledIconId;
|
2012-05-16 08:41:56 +00:00
|
|
|
final Drawable icon = iconSet.getIconDrawable(iconId);
|
|
|
|
if (icon != null) {
|
|
|
|
icon.setAlpha(alpha);
|
|
|
|
}
|
|
|
|
return icon;
|
2010-12-03 04:17:26 +00:00
|
|
|
}
|
|
|
|
|
2012-08-30 05:22:40 +00:00
|
|
|
public Drawable getPreviewIcon(final KeyboardIconsSet iconSet) {
|
2014-07-08 08:36:11 +00:00
|
|
|
return iconSet.getIconDrawable(getIconId());
|
2012-08-28 08:19:49 +00:00
|
|
|
}
|
|
|
|
|
2014-08-26 07:40:18 +00:00
|
|
|
/**
|
|
|
|
* Gets the width of the key in pixels, excluding the gap.
|
|
|
|
* @return The width of the key in pixels, excluding the gap.
|
|
|
|
*/
|
2013-08-12 09:05:11 +00:00
|
|
|
public int getWidth() {
|
|
|
|
return mWidth;
|
|
|
|
}
|
|
|
|
|
2014-08-26 07:40:18 +00:00
|
|
|
/**
|
|
|
|
* Gets the height of the key in pixels, excluding the gap.
|
|
|
|
* @return The height of the key in pixels, excluding the gap.
|
|
|
|
*/
|
2013-08-12 09:05:11 +00:00
|
|
|
public int getHeight() {
|
|
|
|
return mHeight;
|
|
|
|
}
|
|
|
|
|
2014-09-03 21:15:44 +00:00
|
|
|
/**
|
|
|
|
* The combined width in pixels of the horizontal gaps belonging to this key, both above and
|
|
|
|
* below. I.e., getWidth() + getHorizontalGap() = total width belonging to the key.
|
|
|
|
* @return Horizontal gap belonging to this key.
|
|
|
|
*/
|
|
|
|
public int getHorizontalGap() {
|
|
|
|
return mHorizontalGap;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The combined height in pixels of the vertical gaps belonging to this key, both above and
|
|
|
|
* below. I.e., getHeight() + getVerticalGap() = total height belonging to the key.
|
|
|
|
* @return Vertical gap belonging to this key.
|
|
|
|
*/
|
|
|
|
public int getVerticalGap() {
|
|
|
|
return mVerticalGap;
|
|
|
|
}
|
|
|
|
|
2014-08-26 07:40:18 +00:00
|
|
|
/**
|
|
|
|
* Gets the x-coordinate of the top-left corner of the key in pixels, excluding the gap.
|
|
|
|
* @return The x-coordinate of the top-left corner of the key in pixels, excluding the gap.
|
|
|
|
*/
|
2013-08-12 09:05:11 +00:00
|
|
|
public int getX() {
|
|
|
|
return mX;
|
|
|
|
}
|
|
|
|
|
2014-08-26 07:40:18 +00:00
|
|
|
/**
|
|
|
|
* Gets the y-coordinate of the top-left corner of the key in pixels, excluding the gap.
|
|
|
|
* @return The y-coordinate of the top-left corner of the key in pixels, excluding the gap.
|
|
|
|
*/
|
2013-08-12 09:05:11 +00:00
|
|
|
public int getY() {
|
|
|
|
return mY;
|
|
|
|
}
|
|
|
|
|
2012-08-30 08:42:49 +00:00
|
|
|
public final int getDrawX() {
|
2013-08-27 23:58:57 +00:00
|
|
|
final int x = getX();
|
2012-08-28 08:19:49 +00:00
|
|
|
final OptionalAttributes attrs = mOptionalAttributes;
|
2013-08-27 23:58:57 +00:00
|
|
|
return (attrs == null) ? x : x + attrs.mVisualInsetsLeft;
|
2012-08-28 08:19:49 +00:00
|
|
|
}
|
|
|
|
|
2012-08-30 08:42:49 +00:00
|
|
|
public final int getDrawWidth() {
|
2012-08-28 08:19:49 +00:00
|
|
|
final OptionalAttributes attrs = mOptionalAttributes;
|
|
|
|
return (attrs == null) ? mWidth
|
|
|
|
: mWidth - attrs.mVisualInsetsLeft - attrs.mVisualInsetsRight;
|
2010-12-03 04:17:26 +00:00
|
|
|
}
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2012-08-30 08:42:49 +00:00
|
|
|
public final boolean isEnabled() {
|
2011-06-23 12:23:44 +00:00
|
|
|
return mEnabled;
|
|
|
|
}
|
|
|
|
|
2012-08-30 05:22:40 +00:00
|
|
|
public void setEnabled(final boolean enabled) {
|
2011-06-23 12:23:44 +00:00
|
|
|
mEnabled = enabled;
|
|
|
|
}
|
|
|
|
|
2013-08-12 09:05:11 +00:00
|
|
|
public Rect getHitBox() {
|
|
|
|
return mHitBox;
|
|
|
|
}
|
|
|
|
|
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-08-30 05:22:40 +00:00
|
|
|
* @see #markAsLeftEdge(KeyboardParams) etc.
|
2010-12-02 09:46:21 +00:00
|
|
|
*/
|
2012-08-30 05:22:40 +00:00
|
|
|
public boolean isOnKey(final int x, final 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
|
|
|
|
*/
|
2012-08-30 05:22:40 +00:00
|
|
|
public int squaredDistanceToEdge(final int x, final int y) {
|
2013-08-27 23:58:57 +00:00
|
|
|
final int left = getX();
|
2011-04-28 14:39:49 +00:00
|
|
|
final int right = left + mWidth;
|
2013-08-27 23:58:57 +00:00
|
|
|
final int top = getY();
|
2011-04-28 14:39:49 +00:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2014-08-06 08:23:14 +00:00
|
|
|
static class KeyBackgroundState {
|
|
|
|
private final int[] mReleasedState;
|
|
|
|
private final int[] mPressedState;
|
2011-09-15 08:54:21 +00:00
|
|
|
|
2014-08-06 08:23:14 +00:00
|
|
|
private KeyBackgroundState(final int ... attrs) {
|
|
|
|
mReleasedState = attrs;
|
|
|
|
mPressedState = Arrays.copyOf(attrs, attrs.length + 1);
|
|
|
|
mPressedState[attrs.length] = android.R.attr.state_pressed;
|
|
|
|
}
|
2013-08-14 08:55:21 +00:00
|
|
|
|
2014-08-06 08:23:14 +00:00
|
|
|
public int[] getState(final boolean pressed) {
|
|
|
|
return pressed ? mPressedState : mReleasedState;
|
|
|
|
}
|
2011-09-15 08:54:21 +00:00
|
|
|
|
2014-08-06 08:23:14 +00:00
|
|
|
public static final KeyBackgroundState[] STATES = {
|
|
|
|
// 0: BACKGROUND_TYPE_EMPTY
|
|
|
|
new KeyBackgroundState(android.R.attr.state_empty),
|
|
|
|
// 1: BACKGROUND_TYPE_NORMAL
|
|
|
|
new KeyBackgroundState(),
|
|
|
|
// 2: BACKGROUND_TYPE_FUNCTIONAL
|
|
|
|
new KeyBackgroundState(),
|
|
|
|
// 3: BACKGROUND_TYPE_STICKY_OFF
|
|
|
|
new KeyBackgroundState(android.R.attr.state_checkable),
|
|
|
|
// 4: BACKGROUND_TYPE_STICKY_ON
|
|
|
|
new KeyBackgroundState(android.R.attr.state_checkable, android.R.attr.state_checked),
|
|
|
|
// 5: BACKGROUND_TYPE_ACTION
|
|
|
|
new KeyBackgroundState(android.R.attr.state_active),
|
2014-09-03 01:52:56 +00:00
|
|
|
// 6: BACKGROUND_TYPE_SPACEBAR
|
|
|
|
new KeyBackgroundState(),
|
2014-08-06 08:23:14 +00:00
|
|
|
};
|
|
|
|
}
|
2011-09-15 08:54:21 +00:00
|
|
|
|
2010-12-02 09:46:21 +00:00
|
|
|
/**
|
2014-05-14 06:30:37 +00:00
|
|
|
* Returns the background drawable for the key, based on the current state and type of the key.
|
|
|
|
* @return the background drawable of the key.
|
2010-12-02 09:46:21 +00:00
|
|
|
* @see android.graphics.drawable.StateListDrawable#setState(int[])
|
|
|
|
*/
|
2014-05-14 06:30:37 +00:00
|
|
|
public final Drawable selectBackgroundDrawable(final Drawable keyBackground,
|
|
|
|
final Drawable functionalKeyBackground, final Drawable spacebarBackground) {
|
|
|
|
final Drawable background;
|
|
|
|
if (mBackgroundType == BACKGROUND_TYPE_FUNCTIONAL) {
|
|
|
|
background = functionalKeyBackground;
|
2014-09-03 01:52:56 +00:00
|
|
|
} else if (mBackgroundType == BACKGROUND_TYPE_SPACEBAR) {
|
2014-05-14 06:30:37 +00:00
|
|
|
background = spacebarBackground;
|
|
|
|
} else {
|
|
|
|
background = keyBackground;
|
|
|
|
}
|
2014-08-06 08:23:14 +00:00
|
|
|
final int[] state = KeyBackgroundState.STATES[mBackgroundType].getState(mPressed);
|
|
|
|
background.setState(state);
|
2014-05-14 06:30:37 +00:00
|
|
|
return background;
|
2010-12-02 09:46:21 +00:00
|
|
|
}
|
2011-09-08 08:19:23 +00:00
|
|
|
|
|
|
|
public static class Spacer extends Key {
|
2014-02-09 14:24:02 +00:00
|
|
|
public Spacer(final TypedArray keyAttr, final KeyStyle keyStyle,
|
|
|
|
final KeyboardParams params, final KeyboardRow row) {
|
|
|
|
super(null /* keySpec */, keyAttr, keyStyle, params, row);
|
2011-09-08 08:19:23 +00:00
|
|
|
}
|
|
|
|
|
2011-09-08 09:57:44 +00:00
|
|
|
/**
|
|
|
|
* This constructor is being used only for divider in more keys keyboard.
|
|
|
|
*/
|
2012-08-30 05:22:40 +00:00
|
|
|
protected Spacer(final KeyboardParams params, final int x, final int y, final int width,
|
|
|
|
final int height) {
|
2014-02-09 14:24:02 +00:00
|
|
|
super(null /* label */, ICON_UNDEFINED, CODE_UNSPECIFIED, null /* outputText */,
|
|
|
|
null /* hintLabel */, 0 /* labelFlags */, BACKGROUND_TYPE_EMPTY, x, y, width,
|
|
|
|
height, params.mHorizontalGap, params.mVerticalGap);
|
2011-09-08 08:19:23 +00:00
|
|
|
}
|
|
|
|
}
|
2010-12-02 09:46:21 +00:00
|
|
|
}
|