mAltCodeKeysWhileTyping = CollectionUtils.newArrayList();
- public final KeyboardIconsSet mIconsSet = new KeyboardIconsSet();
- public final KeyboardCodesSet mCodesSet = new KeyboardCodesSet();
- public final KeyboardTextsSet mTextsSet = new KeyboardTextsSet();
- public final KeyStyles mKeyStyles = new KeyStyles(mTextsSet);
-
- public KeyboardLayoutSet.KeysCache mKeysCache;
-
- public int mMostCommonKeyHeight = 0;
- public int mMostCommonKeyWidth = 0;
-
- public boolean mProximityCharsCorrectionEnabled;
-
- public final TouchPositionCorrection mTouchPositionCorrection =
- new TouchPositionCorrection();
-
- public static class TouchPositionCorrection {
- private static final int TOUCH_POSITION_CORRECTION_RECORD_SIZE = 3;
-
- public boolean mEnabled;
- public float[] mXs;
- public float[] mYs;
- public float[] mRadii;
-
- public void load(String[] data) {
- final int dataLength = data.length;
- if (dataLength % TOUCH_POSITION_CORRECTION_RECORD_SIZE != 0) {
- if (LatinImeLogger.sDBG) {
- throw new RuntimeException(
- "the size of touch position correction data is invalid");
- }
- return;
- }
-
- final int length = dataLength / TOUCH_POSITION_CORRECTION_RECORD_SIZE;
- mXs = new float[length];
- mYs = new float[length];
- mRadii = new float[length];
- try {
- for (int i = 0; i < dataLength; ++i) {
- final int type = i % TOUCH_POSITION_CORRECTION_RECORD_SIZE;
- final int index = i / TOUCH_POSITION_CORRECTION_RECORD_SIZE;
- final float value = Float.parseFloat(data[i]);
- if (type == 0) {
- mXs[index] = value;
- } else if (type == 1) {
- mYs[index] = value;
- } else {
- mRadii[index] = value;
- }
- }
- } catch (NumberFormatException e) {
- if (LatinImeLogger.sDBG) {
- throw new RuntimeException(
- "the number format for touch position correction data is invalid");
- }
- mXs = null;
- mYs = null;
- mRadii = null;
- }
- }
-
- // TODO: Remove this method.
- public void setEnabled(boolean enabled) {
- mEnabled = enabled;
- }
-
- public boolean isValid() {
- return mEnabled && mXs != null && mYs != null && mRadii != null
- && mXs.length > 0 && mYs.length > 0 && mRadii.length > 0;
- }
- }
-
- protected void clearKeys() {
- mKeys.clear();
- mShiftKeys.clear();
- clearHistogram();
- }
-
- public void onAddKey(Key newKey) {
- final Key key = (mKeysCache != null) ? mKeysCache.get(newKey) : newKey;
- final boolean zeroWidthSpacer = key.isSpacer() && key.mWidth == 0;
- if (!zeroWidthSpacer) {
- mKeys.add(key);
- updateHistogram(key);
- }
- if (key.mCode == Keyboard.CODE_SHIFT) {
- mShiftKeys.add(key);
- }
- if (key.altCodeWhileTyping()) {
- mAltCodeKeysWhileTyping.add(key);
- }
- }
-
- private int mMaxHeightCount = 0;
- private int mMaxWidthCount = 0;
- private final SparseIntArray mHeightHistogram = new SparseIntArray();
- private final SparseIntArray mWidthHistogram = new SparseIntArray();
-
- private void clearHistogram() {
- mMostCommonKeyHeight = 0;
- mMaxHeightCount = 0;
- mHeightHistogram.clear();
-
- mMaxWidthCount = 0;
- mMostCommonKeyWidth = 0;
- mWidthHistogram.clear();
- }
-
- private static int updateHistogramCounter(SparseIntArray histogram, int key) {
- final int index = histogram.indexOfKey(key);
- final int count = (index >= 0 ? histogram.get(key) : 0) + 1;
- histogram.put(key, count);
- return count;
- }
-
- private void updateHistogram(Key key) {
- final int height = key.mHeight + key.mVerticalGap;
- final int heightCount = updateHistogramCounter(mHeightHistogram, height);
- if (heightCount > mMaxHeightCount) {
- mMaxHeightCount = heightCount;
- mMostCommonKeyHeight = height;
- }
-
- final int width = key.mWidth + key.mHorizontalGap;
- final int widthCount = updateHistogramCounter(mWidthHistogram, width);
- if (widthCount > mMaxWidthCount) {
- mMaxWidthCount = widthCount;
- mMostCommonKeyWidth = width;
- }
- }
- }
-
/**
* Returns the array of the keys that are closest to the given point.
* @param x the x-coordinate of the point
@@ -397,14 +213,14 @@ public class Keyboard {
* @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(int x, int y) {
+ 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);
}
- public static String printableCode(int code) {
+ public static String printableCode(final int code) {
switch (code) {
case CODE_SHIFT: return "shift";
case CODE_SWITCH_ALPHA_SYMBOL: return "symbol";
@@ -426,944 +242,4 @@ public class Keyboard {
return String.format("'\\u%04x'", code);
}
}
-
- /**
- * Keyboard Building helper.
- *
- * This class parses Keyboard XML file and eventually build a Keyboard.
- * The Keyboard XML file looks like:
- *
- * <!-- xml/keyboard.xml -->
- * <Keyboard keyboard_attributes*>
- * <!-- Keyboard Content -->
- * <Row row_attributes*>
- * <!-- Row Content -->
- * <Key key_attributes* />
- * <Spacer horizontalGap="32.0dp" />
- * <include keyboardLayout="@xml/other_keys">
- * ...
- * </Row>
- * <include keyboardLayout="@xml/other_rows">
- * ...
- * </Keyboard>
- *
- * The XML file which is included in other file must have <merge> as root element,
- * such as:
- *
- * <!-- xml/other_keys.xml -->
- * <merge>
- * <Key key_attributes* />
- * ...
- * </merge>
- *
- * and
- *
- * <!-- xml/other_rows.xml -->
- * <merge>
- * <Row row_attributes*>
- * <Key key_attributes* />
- * </Row>
- * ...
- * </merge>
- *
- * You can also use switch-case-default tags to select Rows and Keys.
- *
- * <switch>
- * <case case_attribute*>
- * <!-- Any valid tags at switch position -->
- * </case>
- * ...
- * <default>
- * <!-- Any valid tags at switch position -->
- * </default>
- * </switch>
- *
- * You can declare Key style and specify styles within Key tags.
- *
- * <switch>
- * <case mode="email">
- * <key-style styleName="f1-key" parentStyle="modifier-key"
- * keyLabel=".com"
- * />
- * </case>
- * <case mode="url">
- * <key-style styleName="f1-key" parentStyle="modifier-key"
- * keyLabel="http://"
- * />
- * </case>
- * </switch>
- * ...
- * <Key keyStyle="shift-key" ... />
- *
- */
-
- public static class Builder {
- private static final String BUILDER_TAG = "Keyboard.Builder";
- private static final boolean DEBUG = false;
-
- // Keyboard XML Tags
- private static final String TAG_KEYBOARD = "Keyboard";
- private static final String TAG_ROW = "Row";
- private static final String TAG_KEY = "Key";
- private static final String TAG_SPACER = "Spacer";
- private static final String TAG_INCLUDE = "include";
- private static final String TAG_MERGE = "merge";
- private static final String TAG_SWITCH = "switch";
- private static final String TAG_CASE = "case";
- private static final String TAG_DEFAULT = "default";
- public static final String TAG_KEY_STYLE = "key-style";
-
- private static final int DEFAULT_KEYBOARD_COLUMNS = 10;
- private static final int DEFAULT_KEYBOARD_ROWS = 4;
-
- protected final KP mParams;
- protected final Context mContext;
- protected final Resources mResources;
- private final DisplayMetrics mDisplayMetrics;
-
- private int mCurrentY = 0;
- private Row mCurrentRow = null;
- private boolean mLeftEdge;
- private boolean mTopEdge;
- private Key mRightEdgeKey = null;
-
- /**
- * Container for keys in the keyboard. All keys in a row are at the same Y-coordinate.
- * Some of the key size defaults can be overridden per row from what the {@link Keyboard}
- * defines.
- */
- public static class Row {
- // keyWidth enum constants
- private static final int KEYWIDTH_NOT_ENUM = 0;
- private static final int KEYWIDTH_FILL_RIGHT = -1;
-
- private final Params mParams;
- /** Default width of a key in this row. */
- private float mDefaultKeyWidth;
- /** Default height of a key in this row. */
- public final int mRowHeight;
- /** Default keyLabelFlags in this row. */
- private int mDefaultKeyLabelFlags;
- /** Default backgroundType for this row */
- private int mDefaultBackgroundType;
-
- private final int mCurrentY;
- // Will be updated by {@link Key}'s constructor.
- private float mCurrentX;
-
- public Row(Resources res, Params params, XmlPullParser parser, int y) {
- mParams = params;
- TypedArray keyboardAttr = res.obtainAttributes(Xml.asAttributeSet(parser),
- R.styleable.Keyboard);
- mRowHeight = (int)Builder.getDimensionOrFraction(keyboardAttr,
- R.styleable.Keyboard_rowHeight,
- params.mBaseHeight, params.mDefaultRowHeight);
- keyboardAttr.recycle();
- TypedArray keyAttr = res.obtainAttributes(Xml.asAttributeSet(parser),
- R.styleable.Keyboard_Key);
- mDefaultKeyWidth = Builder.getDimensionOrFraction(keyAttr,
- R.styleable.Keyboard_Key_keyWidth,
- params.mBaseWidth, params.mDefaultKeyWidth);
- mDefaultBackgroundType = keyAttr.getInt(R.styleable.Keyboard_Key_backgroundType,
- Key.BACKGROUND_TYPE_NORMAL);
- keyAttr.recycle();
-
- // TODO: Initialize this with attribute as backgroundType is done.
- mDefaultKeyLabelFlags = 0;
- mCurrentY = y;
- mCurrentX = 0.0f;
- }
-
- public float getDefaultKeyWidth() {
- return mDefaultKeyWidth;
- }
-
- public void setDefaultKeyWidth(float defaultKeyWidth) {
- mDefaultKeyWidth = defaultKeyWidth;
- }
-
- public int getDefaultKeyLabelFlags() {
- return mDefaultKeyLabelFlags;
- }
-
- public void setDefaultKeyLabelFlags(int keyLabelFlags) {
- mDefaultKeyLabelFlags = keyLabelFlags;
- }
-
- public int getDefaultBackgroundType() {
- return mDefaultBackgroundType;
- }
-
- public void setDefaultBackgroundType(int backgroundType) {
- mDefaultBackgroundType = backgroundType;
- }
-
- public void setXPos(float keyXPos) {
- mCurrentX = keyXPos;
- }
-
- public void advanceXPos(float width) {
- mCurrentX += width;
- }
-
- public int getKeyY() {
- return mCurrentY;
- }
-
- public float getKeyX(TypedArray keyAttr) {
- final int keyboardRightEdge = mParams.mOccupiedWidth
- - mParams.mHorizontalEdgesPadding;
- if (keyAttr.hasValue(R.styleable.Keyboard_Key_keyXPos)) {
- final float keyXPos = Builder.getDimensionOrFraction(keyAttr,
- R.styleable.Keyboard_Key_keyXPos, mParams.mBaseWidth, 0);
- if (keyXPos < 0) {
- // If keyXPos is negative, the actual x-coordinate will be
- // keyboardWidth + keyXPos.
- // keyXPos shouldn't be less than mCurrentX because drawable area for this
- // key starts at mCurrentX. Or, this key will overlaps the adjacent key on
- // its left hand side.
- return Math.max(keyXPos + keyboardRightEdge, mCurrentX);
- } else {
- return keyXPos + mParams.mHorizontalEdgesPadding;
- }
- }
- return mCurrentX;
- }
-
- public float getKeyWidth(TypedArray keyAttr) {
- return getKeyWidth(keyAttr, mCurrentX);
- }
-
- public float getKeyWidth(TypedArray keyAttr, float keyXPos) {
- final int widthType = Builder.getEnumValue(keyAttr,
- R.styleable.Keyboard_Key_keyWidth, KEYWIDTH_NOT_ENUM);
- switch (widthType) {
- case KEYWIDTH_FILL_RIGHT:
- final int keyboardRightEdge =
- mParams.mOccupiedWidth - mParams.mHorizontalEdgesPadding;
- // If keyWidth is fillRight, the actual key width will be determined to fill
- // out the area up to the right edge of the keyboard.
- return keyboardRightEdge - keyXPos;
- default: // KEYWIDTH_NOT_ENUM
- return Builder.getDimensionOrFraction(keyAttr,
- R.styleable.Keyboard_Key_keyWidth,
- mParams.mBaseWidth, mDefaultKeyWidth);
- }
- }
- }
-
- public Builder(Context context, KP params) {
- mContext = context;
- final Resources res = context.getResources();
- mResources = res;
- mDisplayMetrics = res.getDisplayMetrics();
-
- mParams = params;
-
- params.GRID_WIDTH = res.getInteger(R.integer.config_keyboard_grid_width);
- params.GRID_HEIGHT = res.getInteger(R.integer.config_keyboard_grid_height);
- }
-
- public void setAutoGenerate(KeyboardLayoutSet.KeysCache keysCache) {
- mParams.mKeysCache = keysCache;
- }
-
- public Builder load(int xmlId, KeyboardId id) {
- mParams.mId = id;
- final XmlResourceParser parser = mResources.getXml(xmlId);
- try {
- parseKeyboard(parser);
- } catch (XmlPullParserException e) {
- Log.w(BUILDER_TAG, "keyboard XML parse error: " + e);
- throw new IllegalArgumentException(e);
- } catch (IOException e) {
- Log.w(BUILDER_TAG, "keyboard XML parse error: " + e);
- throw new RuntimeException(e);
- } finally {
- parser.close();
- }
- return this;
- }
-
- // TODO: Remove this method.
- public void setTouchPositionCorrectionEnabled(boolean enabled) {
- mParams.mTouchPositionCorrection.setEnabled(enabled);
- }
-
- public void setProximityCharsCorrectionEnabled(boolean enabled) {
- mParams.mProximityCharsCorrectionEnabled = enabled;
- }
-
- public Keyboard build() {
- return new Keyboard(mParams);
- }
-
- private int mIndent;
- private static final String SPACES = " ";
-
- private static String spaces(int count) {
- return (count < SPACES.length()) ? SPACES.substring(0, count) : SPACES;
- }
-
- private void startTag(String format, Object ... args) {
- Log.d(BUILDER_TAG, String.format(spaces(++mIndent * 2) + format, args));
- }
-
- private void endTag(String format, Object ... args) {
- Log.d(BUILDER_TAG, String.format(spaces(mIndent-- * 2) + format, args));
- }
-
- private void startEndTag(String format, Object ... args) {
- Log.d(BUILDER_TAG, String.format(spaces(++mIndent * 2) + format, args));
- mIndent--;
- }
-
- private void parseKeyboard(XmlPullParser parser)
- throws XmlPullParserException, IOException {
- if (DEBUG) startTag("<%s> %s", TAG_KEYBOARD, mParams.mId);
- int event;
- while ((event = parser.next()) != XmlPullParser.END_DOCUMENT) {
- if (event == XmlPullParser.START_TAG) {
- final String tag = parser.getName();
- if (TAG_KEYBOARD.equals(tag)) {
- parseKeyboardAttributes(parser);
- startKeyboard();
- parseKeyboardContent(parser, false);
- break;
- } else {
- throw new XmlParseUtils.IllegalStartTag(parser, TAG_KEYBOARD);
- }
- }
- }
- }
-
- private void parseKeyboardAttributes(XmlPullParser parser) {
- final int displayWidth = mDisplayMetrics.widthPixels;
- final TypedArray keyboardAttr = mContext.obtainStyledAttributes(
- Xml.asAttributeSet(parser), R.styleable.Keyboard, R.attr.keyboardStyle,
- R.style.Keyboard);
- final TypedArray keyAttr = mResources.obtainAttributes(Xml.asAttributeSet(parser),
- R.styleable.Keyboard_Key);
- try {
- final int displayHeight = mDisplayMetrics.heightPixels;
- final String keyboardHeightString = Utils.getDeviceOverrideValue(
- mResources, R.array.keyboard_heights, null);
- final float keyboardHeight;
- if (keyboardHeightString != null) {
- keyboardHeight = Float.parseFloat(keyboardHeightString)
- * mDisplayMetrics.density;
- } else {
- keyboardHeight = keyboardAttr.getDimension(
- R.styleable.Keyboard_keyboardHeight, displayHeight / 2);
- }
- final float maxKeyboardHeight = getDimensionOrFraction(keyboardAttr,
- R.styleable.Keyboard_maxKeyboardHeight, displayHeight, displayHeight / 2);
- float minKeyboardHeight = getDimensionOrFraction(keyboardAttr,
- R.styleable.Keyboard_minKeyboardHeight, displayHeight, displayHeight / 2);
- if (minKeyboardHeight < 0) {
- // Specified fraction was negative, so it should be calculated against display
- // width.
- minKeyboardHeight = -getDimensionOrFraction(keyboardAttr,
- R.styleable.Keyboard_minKeyboardHeight, displayWidth, displayWidth / 2);
- }
- final Params params = mParams;
- // Keyboard height will not exceed maxKeyboardHeight and will not be less than
- // minKeyboardHeight.
- params.mOccupiedHeight = (int)Math.max(
- Math.min(keyboardHeight, maxKeyboardHeight), minKeyboardHeight);
- params.mOccupiedWidth = params.mId.mWidth;
- params.mTopPadding = (int)getDimensionOrFraction(keyboardAttr,
- R.styleable.Keyboard_keyboardTopPadding, params.mOccupiedHeight, 0);
- params.mBottomPadding = (int)getDimensionOrFraction(keyboardAttr,
- R.styleable.Keyboard_keyboardBottomPadding, params.mOccupiedHeight, 0);
- params.mHorizontalEdgesPadding = (int)getDimensionOrFraction(keyboardAttr,
- R.styleable.Keyboard_keyboardHorizontalEdgesPadding,
- mParams.mOccupiedWidth, 0);
-
- params.mBaseWidth = params.mOccupiedWidth - params.mHorizontalEdgesPadding * 2
- - params.mHorizontalCenterPadding;
- params.mDefaultKeyWidth = (int)getDimensionOrFraction(keyAttr,
- R.styleable.Keyboard_Key_keyWidth, params.mBaseWidth,
- params.mBaseWidth / DEFAULT_KEYBOARD_COLUMNS);
- params.mHorizontalGap = (int)getDimensionOrFraction(keyboardAttr,
- R.styleable.Keyboard_horizontalGap, params.mBaseWidth, 0);
- params.mVerticalGap = (int)getDimensionOrFraction(keyboardAttr,
- R.styleable.Keyboard_verticalGap, params.mOccupiedHeight, 0);
- params.mBaseHeight = params.mOccupiedHeight - params.mTopPadding
- - params.mBottomPadding + params.mVerticalGap;
- params.mDefaultRowHeight = (int)getDimensionOrFraction(keyboardAttr,
- R.styleable.Keyboard_rowHeight, params.mBaseHeight,
- params.mBaseHeight / DEFAULT_KEYBOARD_ROWS);
-
- params.mMoreKeysTemplate = keyboardAttr.getResourceId(
- R.styleable.Keyboard_moreKeysTemplate, 0);
- params.mMaxMoreKeysKeyboardColumn = keyAttr.getInt(
- R.styleable.Keyboard_Key_maxMoreKeysColumn, 5);
-
- params.mThemeId = keyboardAttr.getInt(R.styleable.Keyboard_themeId, 0);
- params.mIconsSet.loadIcons(keyboardAttr);
- final String language = params.mId.mLocale.getLanguage();
- params.mCodesSet.setLanguage(language);
- params.mTextsSet.setLanguage(language);
- final RunInLocale job = new RunInLocale() {
- @Override
- protected Void job(Resources res) {
- params.mTextsSet.loadStringResources(mContext);
- return null;
- }
- };
- // Null means the current system locale.
- final Locale locale = SubtypeLocale.isNoLanguage(params.mId.mSubtype)
- ? null : params.mId.mLocale;
- job.runInLocale(mResources, locale);
-
- final int resourceId = keyboardAttr.getResourceId(
- R.styleable.Keyboard_touchPositionCorrectionData, 0);
- params.mTouchPositionCorrection.setEnabled(resourceId != 0);
- if (resourceId != 0) {
- final String[] data = mResources.getStringArray(resourceId);
- params.mTouchPositionCorrection.load(data);
- }
- } finally {
- keyAttr.recycle();
- keyboardAttr.recycle();
- }
- }
-
- private void parseKeyboardContent(XmlPullParser parser, boolean skip)
- throws XmlPullParserException, IOException {
- int event;
- while ((event = parser.next()) != XmlPullParser.END_DOCUMENT) {
- if (event == XmlPullParser.START_TAG) {
- final String tag = parser.getName();
- if (TAG_ROW.equals(tag)) {
- Row row = parseRowAttributes(parser);
- if (DEBUG) startTag("<%s>%s", TAG_ROW, skip ? " skipped" : "");
- if (!skip) {
- startRow(row);
- }
- parseRowContent(parser, row, skip);
- } else if (TAG_INCLUDE.equals(tag)) {
- parseIncludeKeyboardContent(parser, skip);
- } else if (TAG_SWITCH.equals(tag)) {
- parseSwitchKeyboardContent(parser, skip);
- } else if (TAG_KEY_STYLE.equals(tag)) {
- parseKeyStyle(parser, skip);
- } else {
- throw new XmlParseUtils.IllegalStartTag(parser, TAG_ROW);
- }
- } else if (event == XmlPullParser.END_TAG) {
- final String tag = parser.getName();
- if (DEBUG) endTag("%s>", tag);
- if (TAG_KEYBOARD.equals(tag)) {
- endKeyboard();
- break;
- } else if (TAG_CASE.equals(tag) || TAG_DEFAULT.equals(tag)
- || TAG_MERGE.equals(tag)) {
- break;
- } else {
- throw new XmlParseUtils.IllegalEndTag(parser, TAG_ROW);
- }
- }
- }
- }
-
- private Row parseRowAttributes(XmlPullParser parser) throws XmlPullParserException {
- final TypedArray a = mResources.obtainAttributes(Xml.asAttributeSet(parser),
- R.styleable.Keyboard);
- try {
- if (a.hasValue(R.styleable.Keyboard_horizontalGap)) {
- throw new XmlParseUtils.IllegalAttribute(parser, "horizontalGap");
- }
- if (a.hasValue(R.styleable.Keyboard_verticalGap)) {
- throw new XmlParseUtils.IllegalAttribute(parser, "verticalGap");
- }
- return new Row(mResources, mParams, parser, mCurrentY);
- } finally {
- a.recycle();
- }
- }
-
- private void parseRowContent(XmlPullParser parser, Row row, boolean skip)
- throws XmlPullParserException, IOException {
- int event;
- while ((event = parser.next()) != XmlPullParser.END_DOCUMENT) {
- if (event == XmlPullParser.START_TAG) {
- final String tag = parser.getName();
- if (TAG_KEY.equals(tag)) {
- parseKey(parser, row, skip);
- } else if (TAG_SPACER.equals(tag)) {
- parseSpacer(parser, row, skip);
- } else if (TAG_INCLUDE.equals(tag)) {
- parseIncludeRowContent(parser, row, skip);
- } else if (TAG_SWITCH.equals(tag)) {
- parseSwitchRowContent(parser, row, skip);
- } else if (TAG_KEY_STYLE.equals(tag)) {
- parseKeyStyle(parser, skip);
- } else {
- throw new XmlParseUtils.IllegalStartTag(parser, TAG_KEY);
- }
- } else if (event == XmlPullParser.END_TAG) {
- final String tag = parser.getName();
- if (DEBUG) endTag("%s>", tag);
- if (TAG_ROW.equals(tag)) {
- if (!skip) {
- endRow(row);
- }
- break;
- } else if (TAG_CASE.equals(tag) || TAG_DEFAULT.equals(tag)
- || TAG_MERGE.equals(tag)) {
- break;
- } else {
- throw new XmlParseUtils.IllegalEndTag(parser, TAG_KEY);
- }
- }
- }
- }
-
- private void parseKey(XmlPullParser parser, Row row, boolean skip)
- throws XmlPullParserException, IOException {
- if (skip) {
- XmlParseUtils.checkEndTag(TAG_KEY, parser);
- if (DEBUG) {
- startEndTag("<%s /> skipped", TAG_KEY);
- }
- } else {
- final Key key = new Key(mResources, mParams, row, parser);
- if (DEBUG) {
- startEndTag("<%s%s %s moreKeys=%s />", TAG_KEY,
- (key.isEnabled() ? "" : " disabled"), key,
- Arrays.toString(key.mMoreKeys));
- }
- XmlParseUtils.checkEndTag(TAG_KEY, parser);
- endKey(key);
- }
- }
-
- private void parseSpacer(XmlPullParser parser, Row row, boolean skip)
- throws XmlPullParserException, IOException {
- if (skip) {
- XmlParseUtils.checkEndTag(TAG_SPACER, parser);
- if (DEBUG) startEndTag("<%s /> skipped", TAG_SPACER);
- } else {
- final Key.Spacer spacer = new Key.Spacer(mResources, mParams, row, parser);
- if (DEBUG) startEndTag("<%s />", TAG_SPACER);
- XmlParseUtils.checkEndTag(TAG_SPACER, parser);
- endKey(spacer);
- }
- }
-
- private void parseIncludeKeyboardContent(XmlPullParser parser, boolean skip)
- throws XmlPullParserException, IOException {
- parseIncludeInternal(parser, null, skip);
- }
-
- private void parseIncludeRowContent(XmlPullParser parser, Row row, boolean skip)
- throws XmlPullParserException, IOException {
- parseIncludeInternal(parser, row, skip);
- }
-
- private void parseIncludeInternal(XmlPullParser parser, Row row, boolean skip)
- throws XmlPullParserException, IOException {
- if (skip) {
- XmlParseUtils.checkEndTag(TAG_INCLUDE, parser);
- if (DEBUG) startEndTag("%s> skipped", TAG_INCLUDE);
- } else {
- final AttributeSet attr = Xml.asAttributeSet(parser);
- final TypedArray keyboardAttr = mResources.obtainAttributes(attr,
- R.styleable.Keyboard_Include);
- final TypedArray keyAttr = mResources.obtainAttributes(attr,
- R.styleable.Keyboard_Key);
- int keyboardLayout = 0;
- float savedDefaultKeyWidth = 0;
- int savedDefaultKeyLabelFlags = 0;
- int savedDefaultBackgroundType = Key.BACKGROUND_TYPE_NORMAL;
- try {
- XmlParseUtils.checkAttributeExists(keyboardAttr,
- R.styleable.Keyboard_Include_keyboardLayout, "keyboardLayout",
- TAG_INCLUDE, parser);
- keyboardLayout = keyboardAttr.getResourceId(
- R.styleable.Keyboard_Include_keyboardLayout, 0);
- if (row != null) {
- if (keyAttr.hasValue(R.styleable.Keyboard_Key_keyXPos)) {
- // Override current x coordinate.
- row.setXPos(row.getKeyX(keyAttr));
- }
- // TODO: Remove this if-clause and do the same as backgroundType below.
- savedDefaultKeyWidth = row.getDefaultKeyWidth();
- if (keyAttr.hasValue(R.styleable.Keyboard_Key_keyWidth)) {
- // Override default key width.
- row.setDefaultKeyWidth(row.getKeyWidth(keyAttr));
- }
- savedDefaultKeyLabelFlags = row.getDefaultKeyLabelFlags();
- // Bitwise-or default keyLabelFlag if exists.
- row.setDefaultKeyLabelFlags(keyAttr.getInt(
- R.styleable.Keyboard_Key_keyLabelFlags, 0)
- | savedDefaultKeyLabelFlags);
- savedDefaultBackgroundType = row.getDefaultBackgroundType();
- // Override default backgroundType if exists.
- row.setDefaultBackgroundType(keyAttr.getInt(
- R.styleable.Keyboard_Key_backgroundType,
- savedDefaultBackgroundType));
- }
- } finally {
- keyboardAttr.recycle();
- keyAttr.recycle();
- }
-
- XmlParseUtils.checkEndTag(TAG_INCLUDE, parser);
- if (DEBUG) {
- startEndTag("<%s keyboardLayout=%s />",TAG_INCLUDE,
- mResources.getResourceEntryName(keyboardLayout));
- }
- final XmlResourceParser parserForInclude = mResources.getXml(keyboardLayout);
- try {
- parseMerge(parserForInclude, row, skip);
- } finally {
- if (row != null) {
- // Restore default keyWidth, keyLabelFlags, and backgroundType.
- row.setDefaultKeyWidth(savedDefaultKeyWidth);
- row.setDefaultKeyLabelFlags(savedDefaultKeyLabelFlags);
- row.setDefaultBackgroundType(savedDefaultBackgroundType);
- }
- parserForInclude.close();
- }
- }
- }
-
- private void parseMerge(XmlPullParser parser, Row row, boolean skip)
- throws XmlPullParserException, IOException {
- if (DEBUG) startTag("<%s>", TAG_MERGE);
- int event;
- while ((event = parser.next()) != XmlPullParser.END_DOCUMENT) {
- if (event == XmlPullParser.START_TAG) {
- final String tag = parser.getName();
- if (TAG_MERGE.equals(tag)) {
- if (row == null) {
- parseKeyboardContent(parser, skip);
- } else {
- parseRowContent(parser, row, skip);
- }
- break;
- } else {
- throw new XmlParseUtils.ParseException(
- "Included keyboard layout must have root element", parser);
- }
- }
- }
- }
-
- private void parseSwitchKeyboardContent(XmlPullParser parser, boolean skip)
- throws XmlPullParserException, IOException {
- parseSwitchInternal(parser, null, skip);
- }
-
- private void parseSwitchRowContent(XmlPullParser parser, Row row, boolean skip)
- throws XmlPullParserException, IOException {
- parseSwitchInternal(parser, row, skip);
- }
-
- private void parseSwitchInternal(XmlPullParser parser, Row row, boolean skip)
- throws XmlPullParserException, IOException {
- if (DEBUG) startTag("<%s> %s", TAG_SWITCH, mParams.mId);
- boolean selected = false;
- int event;
- while ((event = parser.next()) != XmlPullParser.END_DOCUMENT) {
- if (event == XmlPullParser.START_TAG) {
- final String tag = parser.getName();
- if (TAG_CASE.equals(tag)) {
- selected |= parseCase(parser, row, selected ? true : skip);
- } else if (TAG_DEFAULT.equals(tag)) {
- selected |= parseDefault(parser, row, selected ? true : skip);
- } else {
- throw new XmlParseUtils.IllegalStartTag(parser, TAG_KEY);
- }
- } else if (event == XmlPullParser.END_TAG) {
- final String tag = parser.getName();
- if (TAG_SWITCH.equals(tag)) {
- if (DEBUG) endTag("%s>", TAG_SWITCH);
- break;
- } else {
- throw new XmlParseUtils.IllegalEndTag(parser, TAG_KEY);
- }
- }
- }
- }
-
- private boolean parseCase(XmlPullParser parser, Row row, boolean skip)
- throws XmlPullParserException, IOException {
- final boolean selected = parseCaseCondition(parser);
- if (row == null) {
- // Processing Rows.
- parseKeyboardContent(parser, selected ? skip : true);
- } else {
- // Processing Keys.
- parseRowContent(parser, row, selected ? skip : true);
- }
- return selected;
- }
-
- private boolean parseCaseCondition(XmlPullParser parser) {
- final KeyboardId id = mParams.mId;
- if (id == null) {
- return true;
- }
- final TypedArray a = mResources.obtainAttributes(Xml.asAttributeSet(parser),
- R.styleable.Keyboard_Case);
- try {
- final boolean keyboardLayoutSetElementMatched = matchTypedValue(a,
- R.styleable.Keyboard_Case_keyboardLayoutSetElement, id.mElementId,
- KeyboardId.elementIdToName(id.mElementId));
- final boolean modeMatched = matchTypedValue(a,
- R.styleable.Keyboard_Case_mode, id.mMode, KeyboardId.modeName(id.mMode));
- final boolean navigateNextMatched = matchBoolean(a,
- R.styleable.Keyboard_Case_navigateNext, id.navigateNext());
- final boolean navigatePreviousMatched = matchBoolean(a,
- R.styleable.Keyboard_Case_navigatePrevious, id.navigatePrevious());
- final boolean passwordInputMatched = matchBoolean(a,
- R.styleable.Keyboard_Case_passwordInput, id.passwordInput());
- final boolean clobberSettingsKeyMatched = matchBoolean(a,
- R.styleable.Keyboard_Case_clobberSettingsKey, id.mClobberSettingsKey);
- final boolean shortcutKeyEnabledMatched = matchBoolean(a,
- R.styleable.Keyboard_Case_shortcutKeyEnabled, id.mShortcutKeyEnabled);
- final boolean hasShortcutKeyMatched = matchBoolean(a,
- R.styleable.Keyboard_Case_hasShortcutKey, id.mHasShortcutKey);
- final boolean languageSwitchKeyEnabledMatched = matchBoolean(a,
- R.styleable.Keyboard_Case_languageSwitchKeyEnabled,
- id.mLanguageSwitchKeyEnabled);
- final boolean isMultiLineMatched = matchBoolean(a,
- R.styleable.Keyboard_Case_isMultiLine, id.isMultiLine());
- final boolean imeActionMatched = matchInteger(a,
- R.styleable.Keyboard_Case_imeAction, id.imeAction());
- final boolean localeCodeMatched = matchString(a,
- R.styleable.Keyboard_Case_localeCode, id.mLocale.toString());
- final boolean languageCodeMatched = matchString(a,
- R.styleable.Keyboard_Case_languageCode, id.mLocale.getLanguage());
- final boolean countryCodeMatched = matchString(a,
- R.styleable.Keyboard_Case_countryCode, id.mLocale.getCountry());
- final boolean selected = keyboardLayoutSetElementMatched && modeMatched
- && navigateNextMatched && navigatePreviousMatched && passwordInputMatched
- && clobberSettingsKeyMatched && shortcutKeyEnabledMatched
- && hasShortcutKeyMatched && languageSwitchKeyEnabledMatched
- && isMultiLineMatched && imeActionMatched && localeCodeMatched
- && languageCodeMatched && countryCodeMatched;
-
- if (DEBUG) {
- startTag("<%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s>%s", TAG_CASE,
- textAttr(a.getString(
- R.styleable.Keyboard_Case_keyboardLayoutSetElement),
- "keyboardLayoutSetElement"),
- textAttr(a.getString(R.styleable.Keyboard_Case_mode), "mode"),
- textAttr(a.getString(R.styleable.Keyboard_Case_imeAction),
- "imeAction"),
- booleanAttr(a, R.styleable.Keyboard_Case_navigateNext,
- "navigateNext"),
- booleanAttr(a, R.styleable.Keyboard_Case_navigatePrevious,
- "navigatePrevious"),
- booleanAttr(a, R.styleable.Keyboard_Case_clobberSettingsKey,
- "clobberSettingsKey"),
- booleanAttr(a, R.styleable.Keyboard_Case_passwordInput,
- "passwordInput"),
- booleanAttr(a, R.styleable.Keyboard_Case_shortcutKeyEnabled,
- "shortcutKeyEnabled"),
- booleanAttr(a, R.styleable.Keyboard_Case_hasShortcutKey,
- "hasShortcutKey"),
- booleanAttr(a, R.styleable.Keyboard_Case_languageSwitchKeyEnabled,
- "languageSwitchKeyEnabled"),
- booleanAttr(a, R.styleable.Keyboard_Case_isMultiLine,
- "isMultiLine"),
- textAttr(a.getString(R.styleable.Keyboard_Case_localeCode),
- "localeCode"),
- textAttr(a.getString(R.styleable.Keyboard_Case_languageCode),
- "languageCode"),
- textAttr(a.getString(R.styleable.Keyboard_Case_countryCode),
- "countryCode"),
- selected ? "" : " skipped");
- }
-
- return selected;
- } finally {
- a.recycle();
- }
- }
-
- private static boolean matchInteger(TypedArray a, int index, int value) {
- // If does not have "index" attribute, that means this is wild-card for
- // the attribute.
- return !a.hasValue(index) || a.getInt(index, 0) == value;
- }
-
- private static boolean matchBoolean(TypedArray a, int index, boolean value) {
- // If does not have "index" attribute, that means this is wild-card for
- // the attribute.
- return !a.hasValue(index) || a.getBoolean(index, false) == value;
- }
-
- private static boolean matchString(TypedArray a, int index, String value) {
- // If does not have "index" attribute, that means this is wild-card for
- // the attribute.
- return !a.hasValue(index)
- || stringArrayContains(a.getString(index).split("\\|"), value);
- }
-
- private static boolean matchTypedValue(TypedArray a, int index, int intValue,
- String strValue) {
- // If does not have "index" attribute, that means this is wild-card for
- // the attribute.
- final TypedValue v = a.peekValue(index);
- if (v == null) {
- return true;
- }
- if (isIntegerValue(v)) {
- return intValue == a.getInt(index, 0);
- } else if (isStringValue(v)) {
- return stringArrayContains(a.getString(index).split("\\|"), strValue);
- }
- return false;
- }
-
- private static boolean stringArrayContains(String[] array, String value) {
- for (final String elem : array) {
- if (elem.equals(value)) {
- return true;
- }
- }
- return false;
- }
-
- private boolean parseDefault(XmlPullParser parser, Row row, boolean skip)
- throws XmlPullParserException, IOException {
- if (DEBUG) startTag("<%s>", TAG_DEFAULT);
- if (row == null) {
- parseKeyboardContent(parser, skip);
- } else {
- parseRowContent(parser, row, skip);
- }
- return true;
- }
-
- private void parseKeyStyle(XmlPullParser parser, boolean skip)
- throws XmlPullParserException, IOException {
- TypedArray keyStyleAttr = mResources.obtainAttributes(Xml.asAttributeSet(parser),
- R.styleable.Keyboard_KeyStyle);
- TypedArray keyAttrs = mResources.obtainAttributes(Xml.asAttributeSet(parser),
- R.styleable.Keyboard_Key);
- try {
- if (!keyStyleAttr.hasValue(R.styleable.Keyboard_KeyStyle_styleName)) {
- throw new XmlParseUtils.ParseException("<" + TAG_KEY_STYLE
- + "/> needs styleName attribute", parser);
- }
- if (DEBUG) {
- startEndTag("<%s styleName=%s />%s", TAG_KEY_STYLE,
- keyStyleAttr.getString(R.styleable.Keyboard_KeyStyle_styleName),
- skip ? " skipped" : "");
- }
- if (!skip) {
- mParams.mKeyStyles.parseKeyStyleAttributes(keyStyleAttr, keyAttrs, parser);
- }
- } finally {
- keyStyleAttr.recycle();
- keyAttrs.recycle();
- }
- XmlParseUtils.checkEndTag(TAG_KEY_STYLE, parser);
- }
-
- private void startKeyboard() {
- mCurrentY += mParams.mTopPadding;
- mTopEdge = true;
- }
-
- private void startRow(Row row) {
- addEdgeSpace(mParams.mHorizontalEdgesPadding, row);
- mCurrentRow = row;
- mLeftEdge = true;
- mRightEdgeKey = null;
- }
-
- private void endRow(Row row) {
- if (mCurrentRow == null) {
- throw new InflateException("orphan end row tag");
- }
- if (mRightEdgeKey != null) {
- mRightEdgeKey.markAsRightEdge(mParams);
- mRightEdgeKey = null;
- }
- addEdgeSpace(mParams.mHorizontalEdgesPadding, row);
- mCurrentY += row.mRowHeight;
- mCurrentRow = null;
- mTopEdge = false;
- }
-
- private void endKey(Key key) {
- mParams.onAddKey(key);
- if (mLeftEdge) {
- key.markAsLeftEdge(mParams);
- mLeftEdge = false;
- }
- if (mTopEdge) {
- key.markAsTopEdge(mParams);
- }
- mRightEdgeKey = key;
- }
-
- private void endKeyboard() {
- // nothing to do here.
- }
-
- private void addEdgeSpace(float width, Row row) {
- row.advanceXPos(width);
- mLeftEdge = false;
- mRightEdgeKey = null;
- }
-
- public static float getDimensionOrFraction(TypedArray a, int index, int base,
- float defValue) {
- final TypedValue value = a.peekValue(index);
- if (value == null) {
- return defValue;
- }
- if (isFractionValue(value)) {
- return a.getFraction(index, base, base, defValue);
- } else if (isDimensionValue(value)) {
- return a.getDimension(index, defValue);
- }
- return defValue;
- }
-
- public static int getEnumValue(TypedArray a, int index, int defValue) {
- final TypedValue value = a.peekValue(index);
- if (value == null) {
- return defValue;
- }
- if (isIntegerValue(value)) {
- return a.getInt(index, defValue);
- }
- return defValue;
- }
-
- private static boolean isFractionValue(TypedValue v) {
- return v.type == TypedValue.TYPE_FRACTION;
- }
-
- private static boolean isDimensionValue(TypedValue v) {
- return v.type == TypedValue.TYPE_DIMENSION;
- }
-
- private static boolean isIntegerValue(TypedValue v) {
- return v.type >= TypedValue.TYPE_FIRST_INT && v.type <= TypedValue.TYPE_LAST_INT;
- }
-
- private static boolean isStringValue(TypedValue v) {
- return v.type == TypedValue.TYPE_STRING;
- }
-
- private static String textAttr(String value, String name) {
- return value != null ? String.format(" %s=%s", name, value) : "";
- }
-
- private static String booleanAttr(TypedArray a, int index, String name) {
- return a.hasValue(index)
- ? String.format(" %s=%s", name, a.getBoolean(index, false)) : "";
- }
- }
}
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java b/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java
index 76ac3de22..aaccf63ba 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardLayoutSet.java
@@ -35,7 +35,9 @@ import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodSubtype;
import com.android.inputmethod.compat.EditorInfoCompatUtils;
-import com.android.inputmethod.keyboard.KeyboardLayoutSet.Params.ElementParams;
+import com.android.inputmethod.keyboard.internal.KeyboardBuilder;
+import com.android.inputmethod.keyboard.internal.KeyboardParams;
+import com.android.inputmethod.keyboard.internal.KeysCache;
import com.android.inputmethod.latin.CollectionUtils;
import com.android.inputmethod.latin.InputAttributes;
import com.android.inputmethod.latin.InputTypeUtils;
@@ -78,31 +80,19 @@ public class KeyboardLayoutSet {
public static class KeyboardLayoutSetException extends RuntimeException {
public final KeyboardId mKeyboardId;
- public KeyboardLayoutSetException(Throwable cause, KeyboardId keyboardId) {
+ public KeyboardLayoutSetException(final Throwable cause, final KeyboardId keyboardId) {
super(cause);
mKeyboardId = keyboardId;
}
}
- public static class KeysCache {
- private final HashMap mMap = CollectionUtils.newHashMap();
-
- public void clear() {
- mMap.clear();
- }
-
- public Key get(Key key) {
- final Key existingKey = mMap.get(key);
- if (existingKey != null) {
- // Reuse the existing element that equals to "key" without adding "key" to the map.
- return existingKey;
- }
- mMap.put(key, key);
- return key;
- }
+ private static class ElementParams {
+ int mKeyboardXmlId;
+ boolean mProximityCharsCorrectionEnabled;
+ public ElementParams() {}
}
- static class Params {
+ private static class Params {
String mKeyboardLayoutSetName;
int mMode;
EditorInfo mEditorInfo;
@@ -118,11 +108,7 @@ public class KeyboardLayoutSet {
// Sparse array of KeyboardLayoutSet element parameters indexed by element's id.
final SparseArray mKeyboardLayoutSetElementIdToParamsMap =
CollectionUtils.newSparseArray();
-
- static class ElementParams {
- int mKeyboardXmlId;
- boolean mProximityCharsCorrectionEnabled;
- }
+ public Params() {}
}
public static void clearKeyboardCache() {
@@ -130,12 +116,12 @@ public class KeyboardLayoutSet {
sKeysCache.clear();
}
- private KeyboardLayoutSet(Context context, Params params) {
+ KeyboardLayoutSet(final Context context, final Params params) {
mContext = context;
mParams = params;
}
- public Keyboard getKeyboard(int baseKeyboardLayoutSetElementId) {
+ public Keyboard getKeyboard(final int baseKeyboardLayoutSetElementId) {
final int keyboardLayoutSetElementId;
switch (mParams.mMode) {
case KeyboardId.MODE_PHONE:
@@ -170,12 +156,12 @@ public class KeyboardLayoutSet {
}
}
- private Keyboard getKeyboard(ElementParams elementParams, final KeyboardId id) {
+ private Keyboard getKeyboard(final ElementParams elementParams, final KeyboardId id) {
final SoftReference ref = sKeyboardCache.get(id);
Keyboard keyboard = (ref == null) ? null : ref.get();
if (keyboard == null) {
- final Keyboard.Builder builder =
- new Keyboard.Builder(mContext, new Keyboard.Params());
+ final KeyboardBuilder builder =
+ new KeyboardBuilder(mContext, new KeyboardParams());
if (id.isAlphabetKeyboard()) {
builder.setAutoGenerate(sKeysCache);
}
@@ -202,7 +188,7 @@ public class KeyboardLayoutSet {
// KeyboardLayoutSet element id that is a key in keyboard_set.xml. Also that file specifies
// which XML layout should be used for each keyboard. The KeyboardId is an internal key for
// Keyboard object.
- private KeyboardId getKeyboardId(int keyboardLayoutSetElementId) {
+ private KeyboardId getKeyboardId(final int keyboardLayoutSetElementId) {
final Params params = mParams;
final boolean isSymbols = (keyboardLayoutSetElementId == KeyboardId.ELEMENT_SYMBOLS
|| keyboardLayoutSetElementId == KeyboardId.ELEMENT_SYMBOLS_SHIFTED);
@@ -225,7 +211,7 @@ public class KeyboardLayoutSet {
private static final EditorInfo EMPTY_EDITOR_INFO = new EditorInfo();
- public Builder(Context context, EditorInfo editorInfo) {
+ public Builder(final Context context, final EditorInfo editorInfo) {
mContext = context;
mPackageName = context.getPackageName();
mResources = context.getResources();
@@ -238,7 +224,8 @@ public class KeyboardLayoutSet {
mPackageName, NO_SETTINGS_KEY, mEditorInfo);
}
- public Builder setScreenGeometry(int deviceFormFactor, int orientation, int widthPixels) {
+ public Builder setScreenGeometry(final int deviceFormFactor, final int orientation,
+ final int widthPixels) {
final Params params = mParams;
params.mDeviceFormFactor = deviceFormFactor;
params.mOrientation = orientation;
@@ -246,7 +233,7 @@ public class KeyboardLayoutSet {
return this;
}
- public Builder setSubtype(InputMethodSubtype subtype) {
+ public Builder setSubtype(final InputMethodSubtype subtype) {
final boolean asciiCapable = subtype.containsExtraValueKey(ASCII_CAPABLE);
@SuppressWarnings("deprecation")
final boolean deprecatedForceAscii = InputAttributes.inPrivateImeOptions(
@@ -263,8 +250,8 @@ public class KeyboardLayoutSet {
return this;
}
- public Builder setOptions(boolean voiceKeyEnabled, boolean voiceKeyOnMain,
- boolean languageSwitchKeyEnabled) {
+ public Builder setOptions(final boolean voiceKeyEnabled, final boolean voiceKeyOnMain,
+ final boolean languageSwitchKeyEnabled) {
@SuppressWarnings("deprecation")
final boolean deprecatedNoMicrophone = InputAttributes.inPrivateImeOptions(
null, NO_MICROPHONE_COMPAT, mEditorInfo);
@@ -277,7 +264,7 @@ public class KeyboardLayoutSet {
return this;
}
- public void setTouchPositionCorrectionEnabled(boolean enabled) {
+ public void setTouchPositionCorrectionEnabled(final boolean enabled) {
mParams.mTouchPositionCorrectionEnabled = enabled;
}
@@ -298,7 +285,7 @@ public class KeyboardLayoutSet {
return new KeyboardLayoutSet(mContext, mParams);
}
- private void parseKeyboardLayoutSet(Resources res, int resId)
+ private void parseKeyboardLayoutSet(final Resources res, final int resId)
throws XmlPullParserException, IOException {
final XmlResourceParser parser = res.getXml(resId);
try {
@@ -318,7 +305,7 @@ public class KeyboardLayoutSet {
}
}
- private void parseKeyboardLayoutSetContent(XmlPullParser parser)
+ private void parseKeyboardLayoutSetContent(final XmlPullParser parser)
throws XmlPullParserException, IOException {
int event;
while ((event = parser.next()) != XmlPullParser.END_DOCUMENT) {
@@ -340,7 +327,7 @@ public class KeyboardLayoutSet {
}
}
- private void parseKeyboardLayoutSetElement(XmlPullParser parser)
+ private void parseKeyboardLayoutSetElement(final XmlPullParser parser)
throws XmlPullParserException, IOException {
final TypedArray a = mResources.obtainAttributes(Xml.asAttributeSet(parser),
R.styleable.KeyboardLayoutSet_Element);
@@ -367,7 +354,7 @@ public class KeyboardLayoutSet {
}
}
- private static int getKeyboardMode(EditorInfo editorInfo) {
+ private static int getKeyboardMode(final EditorInfo editorInfo) {
if (editorInfo == null)
return KeyboardId.MODE_TEXT;
diff --git a/java/src/com/android/inputmethod/keyboard/KeyboardView.java b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
index 127ac7160..cf89567f8 100644
--- a/java/src/com/android/inputmethod/keyboard/KeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/KeyboardView.java
@@ -38,6 +38,9 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
+import com.android.inputmethod.keyboard.internal.KeyDrawParams;
+import com.android.inputmethod.keyboard.internal.KeyPreviewDrawParams;
+import com.android.inputmethod.keyboard.internal.KeyVisualAttributes;
import com.android.inputmethod.keyboard.internal.PreviewPlacerView;
import com.android.inputmethod.latin.CollectionUtils;
import com.android.inputmethod.latin.Constants;
@@ -53,43 +56,64 @@ import java.util.HashSet;
/**
* A view that renders a virtual {@link Keyboard}.
*
- * @attr ref R.styleable#KeyboardView_backgroundDimAlpha
* @attr ref R.styleable#KeyboardView_keyBackground
- * @attr ref R.styleable#KeyboardView_keyLetterRatio
- * @attr ref R.styleable#KeyboardView_keyLargeLetterRatio
- * @attr ref R.styleable#KeyboardView_keyLabelRatio
- * @attr ref R.styleable#KeyboardView_keyHintLetterRatio
- * @attr ref R.styleable#KeyboardView_keyShiftedLetterHintRatio
- * @attr ref R.styleable#KeyboardView_keyHintLabelRatio
+ * @attr ref R.styleable#KeyboardView_moreKeysLayout
+ * @attr ref R.styleable#KeyboardView_keyPreviewLayout
+ * @attr ref R.styleable#KeyboardView_keyPreviewOffset
+ * @attr ref R.styleable#KeyboardView_keyPreviewHeight
+ * @attr ref R.styleable#KeyboardView_keyPreviewLingerTimeout
* @attr ref R.styleable#KeyboardView_keyLabelHorizontalPadding
* @attr ref R.styleable#KeyboardView_keyHintLetterPadding
* @attr ref R.styleable#KeyboardView_keyPopupHintLetterPadding
* @attr ref R.styleable#KeyboardView_keyShiftedLetterHintPadding
- * @attr ref R.styleable#KeyboardView_keyTextStyle
- * @attr ref R.styleable#KeyboardView_keyPreviewLayout
- * @attr ref R.styleable#KeyboardView_keyPreviewTextRatio
- * @attr ref R.styleable#KeyboardView_keyPreviewOffset
- * @attr ref R.styleable#KeyboardView_keyPreviewHeight
- * @attr ref R.styleable#KeyboardView_keyTextColor
- * @attr ref R.styleable#KeyboardView_keyTextColorDisabled
- * @attr ref R.styleable#KeyboardView_keyHintLetterColor
- * @attr ref R.styleable#KeyboardView_keyHintLabelColor
- * @attr ref R.styleable#KeyboardView_keyShiftedLetterHintInactivatedColor
- * @attr ref R.styleable#KeyboardView_keyShiftedLetterHintActivatedColor
- * @attr ref R.styleable#KeyboardView_shadowColor
- * @attr ref R.styleable#KeyboardView_shadowRadius
+ * @attr ref R.styleable#KeyboardView_keyTextShadowRadius
+ * @attr ref R.styleable#KeyboardView_backgroundDimAlpha
+ * @attr ref R.styleable#KeyboardView_gestureFloatingPreviewTextSize
+ * @attr ref R.styleable#KeyboardView_gestureFloatingPreviewTextColor
+ * @attr ref R.styleable#KeyboardView_gestureFloatingPreviewTextOffset
+ * @attr ref R.styleable#KeyboardView_gestureFloatingPreviewColor
+ * @attr ref R.styleable#KeyboardView_gestureFloatingPreviewHorizontalPadding
+ * @attr ref R.styleable#KeyboardView_gestureFloatingPreviewVerticalPadding
+ * @attr ref R.styleable#KeyboardView_gestureFloatingPreviewRoundRadius
+ * @attr ref R.styleable#KeyboardView_gestureFloatingPreviewTextLingerTimeout
+ * @attr ref R.styleable#KeyboardView_gesturePreviewTrailFadeoutStartDelay
+ * @attr ref R.styleable#KeyboardView_gesturePreviewTrailFadeoutDuration
+ * @attr ref R.styleable#KeyboardView_gesturePreviewTrailUpdateInterval
+ * @attr ref R.styleable#KeyboardView_gesturePreviewTrailColor
+ * @attr ref R.styleable#KeyboardView_gesturePreviewTrailWidth
+ * @attr ref R.styleable#KeyboardView_verticalCorrection
+ * @attr ref R.styleable#Keyboard_Key_keyTypeface
+ * @attr ref R.styleable#Keyboard_Key_keyLetterSize
+ * @attr ref R.styleable#Keyboard_Key_keyLabelSize
+ * @attr ref R.styleable#Keyboard_Key_keyLargeLetterRatio
+ * @attr ref R.styleable#Keyboard_Key_keyLargeLabelRatio
+ * @attr ref R.styleable#Keyboard_Key_keyHintLetterRatio
+ * @attr ref R.styleable#Keyboard_Key_keyShiftedLetterHintRatio
+ * @attr ref R.styleable#Keyboard_Key_keyHintLabelRatio
+ * @attr ref R.styleable#Keyboard_Key_keyPreviewTextRatio
+ * @attr ref R.styleable#Keyboard_Key_keyTextColor
+ * @attr ref R.styleable#Keyboard_Key_keyTextColorDisabled
+ * @attr ref R.styleable#Keyboard_Key_keyTextShadowColor
+ * @attr ref R.styleable#Keyboard_Key_keyHintLetterColor
+ * @attr ref R.styleable#Keyboard_Key_keyHintLabelColor
+ * @attr ref R.styleable#Keyboard_Key_keyShiftedLetterHintInactivatedColor
+ * @attr ref R.styleable#Keyboard_Key_keyShiftedLetterHintActivatedColor
+ * @attr ref R.styleable#Keyboard_Key_keyPreviewTextColor
*/
public class KeyboardView extends View implements PointerTracker.DrawingProxy {
private static final String TAG = KeyboardView.class.getSimpleName();
- // Miscellaneous constants
- private static final int[] LONG_PRESSABLE_STATE_SET = { android.R.attr.state_long_pressable };
- private static final float UNDEFINED_RATIO = -1.0f;
- private static final int UNDEFINED_DIMENSION = -1;
-
// XML attributes
+ private final KeyVisualAttributes mKeyVisualAttributes;
+ private final int mKeyLabelHorizontalPadding;
+ private final float mKeyHintLetterPadding;
+ private final float mKeyPopupHintLetterPadding;
+ private final float mKeyShiftedLetterHintPadding;
+ private final float mKeyTextShadowRadius;
protected final float mVerticalCorrection;
protected final int mMoreKeysLayout;
+ protected final Drawable mKeyBackground;
+ protected final Rect mKeyBackgroundPadding = new Rect();
private final int mBackgroundDimAlpha;
// HORIZONTAL ELLIPSIS "...", character for popup hint.
@@ -105,15 +129,44 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
// Main keyboard
private Keyboard mKeyboard;
- protected final KeyDrawParams mKeyDrawParams;
+ protected final KeyDrawParams mKeyDrawParams = new KeyDrawParams();
+
+ // Preview placer view
+ private final PreviewPlacerView mPreviewPlacerView;
+ private final int[] mCoordinates = new int[2];
// Key preview
+ private static final int PREVIEW_ALPHA = 240;
private final int mKeyPreviewLayoutId;
+ private final int mPreviewOffset;
+ private final int mPreviewHeight;
+ private final int mPreviewLingerTimeout;
private final SparseArray mKeyPreviewTexts = CollectionUtils.newSparseArray();
- protected final KeyPreviewDrawParams mKeyPreviewDrawParams;
+ protected final KeyPreviewDrawParams mKeyPreviewDrawParams = new KeyPreviewDrawParams();
private boolean mShowKeyPreviewPopup = true;
private int mDelayAfterPreview;
- private final PreviewPlacerView mPreviewPlacerView;
+ // Background state set
+ private static final int[][][] KEY_PREVIEW_BACKGROUND_STATE_TABLE = {
+ { // STATE_MIDDLE
+ EMPTY_STATE_SET,
+ { R.attr.state_has_morekeys }
+ },
+ { // STATE_LEFT
+ { R.attr.state_left_edge },
+ { R.attr.state_left_edge, R.attr.state_has_morekeys }
+ },
+ { // STATE_RIGHT
+ { R.attr.state_right_edge },
+ { R.attr.state_right_edge, R.attr.state_has_morekeys }
+ }
+ };
+ private static final int STATE_MIDDLE = 0;
+ private static final int STATE_LEFT = 1;
+ private static final int STATE_RIGHT = 2;
+ private static final int STATE_NORMAL = 0;
+ private static final int STATE_HAS_MOREKEYS = 1;
+ private static final int[] KEY_PREVIEW_BACKGROUND_DEFAULT_STATE =
+ KEY_PREVIEW_BACKGROUND_STATE_TABLE[STATE_MIDDLE][STATE_NORMAL];
// Drawing
/** True if the entire keyboard needs to be dimmed. */
@@ -129,7 +182,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
private final Region mClipRegion = new Region();
private Bitmap mOffscreenBuffer;
/** The canvas for the above mutable keyboard bitmap */
- private Canvas mOffscreenCanvas;
+ private final Canvas mOffscreenCanvas = new Canvas();
private final Paint mPaint = new Paint();
private final Paint.FontMetrics mFontMetrics = new Paint.FontMetrics();
// This sparse array caches key label text height in pixel indexed by key label text size.
@@ -144,12 +197,12 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
public static class DrawingHandler extends StaticInnerHandlerWrapper {
private static final int MSG_DISMISS_KEY_PREVIEW = 0;
- public DrawingHandler(KeyboardView outerInstance) {
+ public DrawingHandler(final KeyboardView outerInstance) {
super(outerInstance);
}
@Override
- public void handleMessage(Message msg) {
+ public void handleMessage(final Message msg) {
final KeyboardView keyboardView = getOuterInstance();
if (keyboardView == null) return;
final PointerTracker tracker = (PointerTracker) msg.obj;
@@ -163,11 +216,11 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
}
}
- public void dismissKeyPreview(long delay, PointerTracker tracker) {
+ public void dismissKeyPreview(final long delay, final PointerTracker tracker) {
sendMessageDelayed(obtainMessage(MSG_DISMISS_KEY_PREVIEW, tracker), delay);
}
- public void cancelDismissKeyPreview(PointerTracker tracker) {
+ public void cancelDismissKeyPreview(final PointerTracker tracker) {
removeMessages(MSG_DISMISS_KEY_PREVIEW, tracker);
}
@@ -180,228 +233,60 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
}
}
- protected static class KeyDrawParams {
- // XML attributes
- public final int mKeyTextColor;
- public final int mKeyTextInactivatedColor;
- public final Typeface mKeyTextStyle;
- public final float mKeyLabelHorizontalPadding;
- public final float mKeyHintLetterPadding;
- public final float mKeyPopupHintLetterPadding;
- public final float mKeyShiftedLetterHintPadding;
- public final int mShadowColor;
- public final float mShadowRadius;
- public final Drawable mKeyBackground;
- public final int mKeyHintLetterColor;
- public final int mKeyHintLabelColor;
- public final int mKeyShiftedLetterHintInactivatedColor;
- public final int mKeyShiftedLetterHintActivatedColor;
-
- /* package */ final float mKeyLetterRatio;
- private final float mKeyLargeLetterRatio;
- private final float mKeyLabelRatio;
- private final float mKeyLargeLabelRatio;
- private final float mKeyHintLetterRatio;
- private final float mKeyShiftedLetterHintRatio;
- private final float mKeyHintLabelRatio;
-
- public final Rect mPadding = new Rect();
- public int mKeyLetterSize;
- public int mKeyLargeLetterSize;
- public int mKeyLabelSize;
- public int mKeyLargeLabelSize;
- public int mKeyHintLetterSize;
- public int mKeyShiftedLetterHintSize;
- public int mKeyHintLabelSize;
- public int mAnimAlpha;
-
- public KeyDrawParams(final TypedArray a) {
- mKeyBackground = a.getDrawable(R.styleable.KeyboardView_keyBackground);
- if (!isValidFraction(mKeyLetterRatio = getFraction(a,
- R.styleable.KeyboardView_keyLetterSize))) {
- mKeyLetterSize = getDimensionPixelSize(a, R.styleable.KeyboardView_keyLetterSize);
- }
- if (!isValidFraction(mKeyLabelRatio = getFraction(a,
- R.styleable.KeyboardView_keyLabelSize))) {
- mKeyLabelSize = getDimensionPixelSize(a, R.styleable.KeyboardView_keyLabelSize);
- }
- mKeyLargeLabelRatio = getFraction(a, R.styleable.KeyboardView_keyLargeLabelRatio);
- mKeyLargeLetterRatio = getFraction(a, R.styleable.KeyboardView_keyLargeLetterRatio);
- mKeyHintLetterRatio = getFraction(a, R.styleable.KeyboardView_keyHintLetterRatio);
- mKeyShiftedLetterHintRatio = getFraction(a,
- R.styleable.KeyboardView_keyShiftedLetterHintRatio);
- mKeyHintLabelRatio = getFraction(a, R.styleable.KeyboardView_keyHintLabelRatio);
- mKeyLabelHorizontalPadding = a.getDimension(
- R.styleable.KeyboardView_keyLabelHorizontalPadding, 0);
- mKeyHintLetterPadding = a.getDimension(
- R.styleable.KeyboardView_keyHintLetterPadding, 0);
- mKeyPopupHintLetterPadding = a.getDimension(
- R.styleable.KeyboardView_keyPopupHintLetterPadding, 0);
- mKeyShiftedLetterHintPadding = a.getDimension(
- R.styleable.KeyboardView_keyShiftedLetterHintPadding, 0);
- mKeyTextColor = a.getColor(R.styleable.KeyboardView_keyTextColor, 0xFF000000);
- mKeyTextInactivatedColor = a.getColor(
- R.styleable.KeyboardView_keyTextInactivatedColor, 0xFF000000);
- mKeyHintLetterColor = a.getColor(R.styleable.KeyboardView_keyHintLetterColor, 0);
- mKeyHintLabelColor = a.getColor(R.styleable.KeyboardView_keyHintLabelColor, 0);
- mKeyShiftedLetterHintInactivatedColor = a.getColor(
- R.styleable.KeyboardView_keyShiftedLetterHintInactivatedColor, 0);
- mKeyShiftedLetterHintActivatedColor = a.getColor(
- R.styleable.KeyboardView_keyShiftedLetterHintActivatedColor, 0);
- mKeyTextStyle = Typeface.defaultFromStyle(
- a.getInt(R.styleable.KeyboardView_keyTextStyle, Typeface.NORMAL));
- mShadowColor = a.getColor(R.styleable.KeyboardView_shadowColor, 0);
- mShadowRadius = a.getFloat(R.styleable.KeyboardView_shadowRadius, 0f);
-
- mKeyBackground.getPadding(mPadding);
- }
-
- public void updateKeyHeight(int keyHeight) {
- if (isValidFraction(mKeyLetterRatio)) {
- mKeyLetterSize = (int)(keyHeight * mKeyLetterRatio);
- }
- if (isValidFraction(mKeyLabelRatio)) {
- mKeyLabelSize = (int)(keyHeight * mKeyLabelRatio);
- }
- mKeyLargeLabelSize = (int)(keyHeight * mKeyLargeLabelRatio);
- mKeyLargeLetterSize = (int)(keyHeight * mKeyLargeLetterRatio);
- mKeyHintLetterSize = (int)(keyHeight * mKeyHintLetterRatio);
- mKeyShiftedLetterHintSize = (int)(keyHeight * mKeyShiftedLetterHintRatio);
- mKeyHintLabelSize = (int)(keyHeight * mKeyHintLabelRatio);
- }
-
- public void blendAlpha(Paint paint) {
- final int color = paint.getColor();
- paint.setARGB((paint.getAlpha() * mAnimAlpha) / Constants.Color.ALPHA_OPAQUE,
- Color.red(color), Color.green(color), Color.blue(color));
- }
- }
-
- /* package */ static class KeyPreviewDrawParams {
- // XML attributes.
- public final Drawable mPreviewBackground;
- public final Drawable mPreviewLeftBackground;
- public final Drawable mPreviewRightBackground;
- public final int mPreviewTextColor;
- public final int mPreviewOffset;
- public final int mPreviewHeight;
- public final Typeface mKeyTextStyle;
- public final int mLingerTimeout;
-
- private final float mPreviewTextRatio;
- private final float mKeyLetterRatio;
-
- // The graphical geometry of the key preview.
- // <-width->
- // +-------+ ^
- // | | |
- // |preview| height (visible)
- // | | |
- // + + ^ v
- // \ / |offset
- // +-\ /-+ v
- // | +-+ |
- // |parent |
- // | key|
- // +-------+
- // The background of a {@link TextView} being used for a key preview may have invisible
- // paddings. To align the more keys keyboard panel's visible part with the visible part of
- // the background, we need to record the width and height of key preview that don't include
- // invisible paddings.
- public int mPreviewVisibleWidth;
- public int mPreviewVisibleHeight;
- // The key preview may have an arbitrary offset and its background that may have a bottom
- // padding. To align the more keys keyboard and the key preview we also need to record the
- // offset between the top edge of parent key and the bottom of the visible part of key
- // preview background.
- public int mPreviewVisibleOffset;
-
- public int mPreviewTextSize;
- public int mKeyLetterSize;
- public final int[] mCoordinates = new int[2];
-
- private static final int PREVIEW_ALPHA = 240;
-
- public KeyPreviewDrawParams(TypedArray a, KeyDrawParams keyDrawParams) {
- mPreviewBackground = a.getDrawable(R.styleable.KeyboardView_keyPreviewBackground);
- mPreviewLeftBackground = a.getDrawable(
- R.styleable.KeyboardView_keyPreviewLeftBackground);
- mPreviewRightBackground = a.getDrawable(
- R.styleable.KeyboardView_keyPreviewRightBackground);
- setAlpha(mPreviewBackground, PREVIEW_ALPHA);
- setAlpha(mPreviewLeftBackground, PREVIEW_ALPHA);
- setAlpha(mPreviewRightBackground, PREVIEW_ALPHA);
- mPreviewOffset = a.getDimensionPixelOffset(
- R.styleable.KeyboardView_keyPreviewOffset, 0);
- mPreviewHeight = a.getDimensionPixelSize(
- R.styleable.KeyboardView_keyPreviewHeight, 80);
- mPreviewTextRatio = getFraction(a, R.styleable.KeyboardView_keyPreviewTextRatio);
- mPreviewTextColor = a.getColor(R.styleable.KeyboardView_keyPreviewTextColor, 0);
- mLingerTimeout = a.getInt(R.styleable.KeyboardView_keyPreviewLingerTimeout, 0);
-
- mKeyLetterRatio = keyDrawParams.mKeyLetterRatio;
- mKeyTextStyle = keyDrawParams.mKeyTextStyle;
- }
-
- public void updateKeyHeight(int keyHeight) {
- if (mPreviewTextRatio >= 0.0f) {
- mPreviewTextSize = (int)(keyHeight * mPreviewTextRatio);
- }
- if (mKeyLetterRatio >= 0.0f) {
- mKeyLetterSize = (int)(keyHeight * mKeyLetterRatio);
- }
- }
-
- private static void setAlpha(Drawable drawable, int alpha) {
- if (drawable == null) return;
- drawable.setAlpha(alpha);
- }
- }
-
- public KeyboardView(Context context, AttributeSet attrs) {
+ public KeyboardView(final Context context, final AttributeSet attrs) {
this(context, attrs, R.attr.keyboardViewStyle);
}
- public KeyboardView(Context context, AttributeSet attrs, int defStyle) {
+ public KeyboardView(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
- final TypedArray a = context.obtainStyledAttributes(
- attrs, R.styleable.KeyboardView, defStyle, R.style.KeyboardView);
- mKeyDrawParams = new KeyDrawParams(a);
- mKeyPreviewDrawParams = new KeyPreviewDrawParams(a, mKeyDrawParams);
- mDelayAfterPreview = mKeyPreviewDrawParams.mLingerTimeout;
- mKeyPreviewLayoutId = a.getResourceId(R.styleable.KeyboardView_keyPreviewLayout, 0);
+ final TypedArray keyboardViewAttr = context.obtainStyledAttributes(attrs,
+ R.styleable.KeyboardView, defStyle, R.style.KeyboardView);
+ mKeyBackground = keyboardViewAttr.getDrawable(R.styleable.KeyboardView_keyBackground);
+ mKeyBackground.getPadding(mKeyBackgroundPadding);
+ mPreviewOffset = keyboardViewAttr.getDimensionPixelOffset(
+ R.styleable.KeyboardView_keyPreviewOffset, 0);
+ mPreviewHeight = keyboardViewAttr.getDimensionPixelSize(
+ R.styleable.KeyboardView_keyPreviewHeight, 80);
+ mPreviewLingerTimeout = keyboardViewAttr.getInt(
+ R.styleable.KeyboardView_keyPreviewLingerTimeout, 0);
+ mDelayAfterPreview = mPreviewLingerTimeout;
+ mKeyLabelHorizontalPadding = keyboardViewAttr.getDimensionPixelOffset(
+ R.styleable.KeyboardView_keyLabelHorizontalPadding, 0);
+ mKeyHintLetterPadding = keyboardViewAttr.getDimension(
+ R.styleable.KeyboardView_keyHintLetterPadding, 0);
+ mKeyPopupHintLetterPadding = keyboardViewAttr.getDimension(
+ R.styleable.KeyboardView_keyPopupHintLetterPadding, 0);
+ mKeyShiftedLetterHintPadding = keyboardViewAttr.getDimension(
+ R.styleable.KeyboardView_keyShiftedLetterHintPadding, 0);
+ mKeyTextShadowRadius = keyboardViewAttr.getFloat(
+ R.styleable.KeyboardView_keyTextShadowRadius, 0.0f);
+ mKeyPreviewLayoutId = keyboardViewAttr.getResourceId(
+ R.styleable.KeyboardView_keyPreviewLayout, 0);
if (mKeyPreviewLayoutId == 0) {
mShowKeyPreviewPopup = false;
}
- mVerticalCorrection = a.getDimensionPixelOffset(
+ mVerticalCorrection = keyboardViewAttr.getDimension(
R.styleable.KeyboardView_verticalCorrection, 0);
- mMoreKeysLayout = a.getResourceId(R.styleable.KeyboardView_moreKeysLayout, 0);
- mBackgroundDimAlpha = a.getInt(R.styleable.KeyboardView_backgroundDimAlpha, 0);
- a.recycle();
+ mMoreKeysLayout = keyboardViewAttr.getResourceId(
+ R.styleable.KeyboardView_moreKeysLayout, 0);
+ mBackgroundDimAlpha = keyboardViewAttr.getInt(
+ R.styleable.KeyboardView_backgroundDimAlpha, 0);
+ keyboardViewAttr.recycle();
+
+ final TypedArray keyAttr = context.obtainStyledAttributes(attrs,
+ R.styleable.Keyboard_Key, defStyle, R.style.KeyboardView);
+ mKeyVisualAttributes = KeyVisualAttributes.newInstance(keyAttr);
+ keyAttr.recycle();
mPreviewPlacerView = new PreviewPlacerView(context, attrs);
mPaint.setAntiAlias(true);
}
- static boolean isValidFraction(final float fraction) {
- return fraction >= 0.0f;
- }
-
- static float getFraction(final TypedArray a, final int index) {
- final TypedValue value = a.peekValue(index);
- if (value == null || value.type != TypedValue.TYPE_FRACTION) {
- return UNDEFINED_RATIO;
- }
- return a.getFraction(index, 1, 1, UNDEFINED_RATIO);
- }
-
- public static int getDimensionPixelSize(final TypedArray a, final int index) {
- final TypedValue value = a.peekValue(index);
- if (value == null || value.type != TypedValue.TYPE_DIMENSION) {
- return UNDEFINED_DIMENSION;
- }
- return a.getDimensionPixelSize(index, UNDEFINED_DIMENSION);
+ private static void blendAlpha(final Paint paint, final int alpha) {
+ final int color = paint.getColor();
+ paint.setARGB((paint.getAlpha() * alpha) / Constants.Color.ALPHA_OPAQUE,
+ Color.red(color), Color.green(color), Color.blue(color));
}
/**
@@ -411,14 +296,14 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
* @see #getKeyboard()
* @param keyboard the keyboard to display in this view
*/
- public void setKeyboard(Keyboard keyboard) {
+ public void setKeyboard(final Keyboard keyboard) {
mKeyboard = keyboard;
LatinImeLogger.onSetKeyboard(keyboard);
requestLayout();
invalidateAllKeys();
final int keyHeight = keyboard.mMostCommonKeyHeight - keyboard.mVerticalGap;
- mKeyDrawParams.updateKeyHeight(keyHeight);
- mKeyPreviewDrawParams.updateKeyHeight(keyHeight);
+ mKeyDrawParams.updateParams(keyHeight, mKeyVisualAttributes);
+ mKeyDrawParams.updateParams(keyHeight, keyboard.mKeyVisualAttributes);
}
/**
@@ -437,7 +322,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
* @param delay the delay after which the preview is dismissed
* @see #isKeyPreviewPopupEnabled()
*/
- public void setKeyPreviewPopupEnabled(boolean previewEnabled, int delay) {
+ public void setKeyPreviewPopupEnabled(final boolean previewEnabled, final int delay) {
mShowKeyPreviewPopup = previewEnabled;
mDelayAfterPreview = delay;
}
@@ -451,14 +336,14 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
return mShowKeyPreviewPopup;
}
- public void setGesturePreviewMode(boolean drawsGesturePreviewTrail,
- boolean drawsGestureFloatingPreviewText) {
+ public void setGesturePreviewMode(final boolean drawsGesturePreviewTrail,
+ final boolean drawsGestureFloatingPreviewText) {
mPreviewPlacerView.setGesturePreviewMode(
drawsGesturePreviewTrail, drawsGestureFloatingPreviewText);
}
@Override
- protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
if (mKeyboard != null) {
// The main keyboard expands to the display width.
final int height = mKeyboard.mOccupiedHeight + getPaddingTop() + getPaddingBottom();
@@ -469,7 +354,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
}
@Override
- public void onDraw(Canvas canvas) {
+ public void onDraw(final Canvas canvas) {
super.onDraw(canvas);
if (canvas.isHardwareAccelerated()) {
onDrawKeyboard(canvas);
@@ -480,7 +365,8 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
if (bufferNeedsUpdates || mOffscreenBuffer == null) {
if (maybeAllocateOffscreenBuffer()) {
mInvalidateAllKeys = true;
- maybeCreateOffscreenCanvas();
+ // TODO: Stop using the offscreen canvas even when in software rendering
+ mOffscreenCanvas.setBitmap(mOffscreenBuffer);
}
onDrawKeyboard(mOffscreenCanvas);
}
@@ -509,22 +395,12 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
}
}
- private void maybeCreateOffscreenCanvas() {
- // TODO: Stop using the offscreen canvas even when in software rendering
- if (mOffscreenCanvas != null) {
- mOffscreenCanvas.setBitmap(mOffscreenBuffer);
- } else {
- mOffscreenCanvas = new Canvas(mOffscreenBuffer);
- }
- }
-
private void onDrawKeyboard(final Canvas canvas) {
if (mKeyboard == null) return;
final int width = getWidth();
final int height = getHeight();
final Paint paint = mPaint;
- final KeyDrawParams params = mKeyDrawParams;
// Calculate clip region and set.
final boolean drawAllKeys = mInvalidateAllKeys || mInvalidatedKeys.isEmpty();
@@ -557,13 +433,13 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
if (drawAllKeys || isHardwareAccelerated) {
// Draw all keys.
for (final Key key : mKeyboard.mKeys) {
- onDrawKey(key, canvas, paint, params);
+ onDrawKey(key, canvas, paint);
}
} else {
// Draw invalidated keys.
for (final Key key : mInvalidatedKeys) {
if (mKeyboard.hasKey(key)) {
- onDrawKey(key, canvas, paint, params);
+ onDrawKey(key, canvas, paint);
}
}
}
@@ -587,7 +463,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
mInvalidateAllKeys = false;
}
- public void dimEntireKeyboard(boolean dimmed) {
+ public void dimEntireKeyboard(final boolean dimmed) {
final boolean needsRedrawing = mNeedsToDimEntireKeyboard != dimmed;
mNeedsToDimEntireKeyboard = dimmed;
if (needsRedrawing) {
@@ -595,14 +471,18 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
}
}
- private void onDrawKey(Key key, Canvas canvas, Paint paint, KeyDrawParams params) {
- final int keyDrawX = key.mX + key.mVisualInsetsLeft + getPaddingLeft();
+ private void onDrawKey(final Key key, final Canvas canvas, final Paint paint) {
+ final int keyDrawX = key.getDrawX() + getPaddingLeft();
final int keyDrawY = key.mY + getPaddingTop();
canvas.translate(keyDrawX, keyDrawY);
+ final int keyHeight = mKeyboard.mMostCommonKeyHeight - mKeyboard.mVerticalGap;
+ final KeyVisualAttributes attr = key.mKeyVisualAttributes;
+ final KeyDrawParams params = mKeyDrawParams.mayCloneAndUpdateParams(keyHeight, attr);
params.mAnimAlpha = Constants.Color.ALPHA_OPAQUE;
+
if (!key.isSpacer()) {
- onDrawKeyBackground(key, canvas, params);
+ onDrawKeyBackground(key, canvas);
}
onDrawKeyTopVisuals(key, canvas, paint, params);
@@ -610,14 +490,14 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
}
// Draw key background.
- protected void onDrawKeyBackground(Key key, Canvas canvas, KeyDrawParams params) {
- final int bgWidth = key.mWidth - key.mVisualInsetsLeft - key.mVisualInsetsRight
- + params.mPadding.left + params.mPadding.right;
- final int bgHeight = key.mHeight + params.mPadding.top + params.mPadding.bottom;
- final int bgX = -params.mPadding.left;
- final int bgY = -params.mPadding.top;
+ protected void onDrawKeyBackground(final Key key, final Canvas canvas) {
+ final Rect padding = mKeyBackgroundPadding;
+ final int bgWidth = key.getDrawWidth() + padding.left + padding.right;
+ final int bgHeight = key.mHeight + padding.top + padding.bottom;
+ final int bgX = -padding.left;
+ final int bgY = -padding.top;
final int[] drawableState = key.getCurrentDrawableState();
- final Drawable background = params.mKeyBackground;
+ final Drawable background = mKeyBackground;
background.setState(drawableState);
final Rect bounds = background.getBounds();
if (bgWidth != bounds.right || bgHeight != bounds.bottom) {
@@ -632,8 +512,9 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
}
// Draw key top visuals.
- protected void onDrawKeyTopVisuals(Key key, Canvas canvas, Paint paint, KeyDrawParams params) {
- final int keyWidth = key.mWidth - key.mVisualInsetsLeft - key.mVisualInsetsRight;
+ protected void onDrawKeyTopVisuals(final Key key, final Canvas canvas, final Paint paint,
+ final KeyDrawParams params) {
+ final int keyWidth = key.getDrawWidth();
final int keyHeight = key.mHeight;
final float centerX = keyWidth * 0.5f;
final float centerY = keyHeight * 0.5f;
@@ -647,12 +528,8 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
float positionX = centerX;
if (key.mLabel != null) {
final String label = key.mLabel;
- // For characters, use large font. For labels like "Done", use smaller font.
- paint.setTypeface(key.selectTypeface(params.mKeyTextStyle));
- final int labelSize = key.selectTextSize(params.mKeyLetterSize,
- params.mKeyLargeLetterSize, params.mKeyLabelSize, params.mKeyLargeLabelSize,
- params.mKeyHintLabelSize);
- paint.setTextSize(labelSize);
+ paint.setTypeface(key.selectTypeface(params));
+ paint.setTextSize(key.selectTextSize(params));
final float labelCharHeight = getCharHeight(KEY_LABEL_REFERENCE_CHAR, paint);
final float labelCharWidth = getCharWidth(KEY_LABEL_REFERENCE_CHAR, paint);
@@ -662,10 +539,10 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
// Horizontal label text alignment
float labelWidth = 0;
if (key.isAlignLeft()) {
- positionX = (int)params.mKeyLabelHorizontalPadding;
+ positionX = mKeyLabelHorizontalPadding;
paint.setTextAlign(Align.LEFT);
} else if (key.isAlignRight()) {
- positionX = keyWidth - (int)params.mKeyLabelHorizontalPadding;
+ positionX = keyWidth - mKeyLabelHorizontalPadding;
paint.setTextAlign(Align.RIGHT);
} else if (key.isAlignLeftOfCenter()) {
// TODO: Parameterise this?
@@ -690,16 +567,15 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
Math.min(1.0f, (keyWidth * MAX_LABEL_RATIO) / getLabelWidth(label, paint)));
}
- paint.setColor(key.isShiftedLetterActivated()
- ? params.mKeyTextInactivatedColor : params.mKeyTextColor);
+ paint.setColor(key.selectTextColor(params));
if (key.isEnabled()) {
// Set a drop shadow for the text
- paint.setShadowLayer(params.mShadowRadius, 0, 0, params.mShadowColor);
+ paint.setShadowLayer(mKeyTextShadowRadius, 0, 0, params.mTextShadowColor);
} else {
// Make label invisible
paint.setColor(Color.TRANSPARENT);
}
- params.blendAlpha(paint);
+ blendAlpha(paint, params.mAnimAlpha);
canvas.drawText(label, 0, label.length(), positionX, baseline, paint);
// Turn off drop shadow and reset x-scale.
paint.setShadowLayer(0, 0, 0, 0);
@@ -727,25 +603,10 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
// Draw hint label.
if (key.mHintLabel != null) {
- final String hint = key.mHintLabel;
- final int hintColor;
- final int hintSize;
- if (key.hasHintLabel()) {
- hintColor = params.mKeyHintLabelColor;
- hintSize = params.mKeyHintLabelSize;
- paint.setTypeface(Typeface.DEFAULT);
- } else if (key.hasShiftedLetterHint()) {
- hintColor = key.isShiftedLetterActivated()
- ? params.mKeyShiftedLetterHintActivatedColor
- : params.mKeyShiftedLetterHintInactivatedColor;
- hintSize = params.mKeyShiftedLetterHintSize;
- } else { // key.hasHintLetter()
- hintColor = params.mKeyHintLetterColor;
- hintSize = params.mKeyHintLetterSize;
- }
- paint.setColor(hintColor);
- params.blendAlpha(paint);
- paint.setTextSize(hintSize);
+ final String hintLabel = key.mHintLabel;
+ paint.setTextSize(key.selectHintTextSize(params));
+ paint.setColor(key.selectHintTextColor(params));
+ blendAlpha(paint, params.mAnimAlpha);
final float hintX, hintY;
if (key.hasHintLabel()) {
// The hint label is placed just right of the key label. Used mainly on
@@ -756,19 +617,19 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
paint.setTextAlign(Align.LEFT);
} else if (key.hasShiftedLetterHint()) {
// The hint label is placed at top-right corner of the key. Used mainly on tablet.
- hintX = keyWidth - params.mKeyShiftedLetterHintPadding
+ hintX = keyWidth - mKeyShiftedLetterHintPadding
- getCharWidth(KEY_LABEL_REFERENCE_CHAR, paint) / 2;
paint.getFontMetrics(mFontMetrics);
hintY = -mFontMetrics.top;
paint.setTextAlign(Align.CENTER);
} else { // key.hasHintLetter()
// The hint letter is placed at top-right corner of the key. Used mainly on phone.
- hintX = keyWidth - params.mKeyHintLetterPadding
+ hintX = keyWidth - mKeyHintLetterPadding
- getCharWidth(KEY_NUMERIC_HINT_LABEL_REFERENCE_CHAR, paint) / 2;
hintY = -paint.ascent();
paint.setTextAlign(Align.CENTER);
}
- canvas.drawText(hint, 0, hint.length(), hintX, hintY, paint);
+ canvas.drawText(hintLabel, 0, hintLabel.length(), hintX, hintY, paint);
if (LatinImeLogger.sVISUALDEBUG) {
final Paint line = new Paint();
@@ -779,15 +640,15 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
// Draw key icon.
if (key.mLabel == null && icon != null) {
- final int iconWidth = icon.getIntrinsicWidth();
+ final int iconWidth = Math.min(icon.getIntrinsicWidth(), keyWidth);
final int iconHeight = icon.getIntrinsicHeight();
final int iconX, alignX;
final int iconY = (keyHeight - iconHeight) / 2;
if (key.isAlignLeft()) {
- iconX = (int)params.mKeyLabelHorizontalPadding;
+ iconX = mKeyLabelHorizontalPadding;
alignX = iconX;
} else if (key.isAlignRight()) {
- iconX = keyWidth - (int)params.mKeyLabelHorizontalPadding - iconWidth;
+ iconX = keyWidth - mKeyLabelHorizontalPadding - iconWidth;
alignX = iconX + iconWidth;
} else { // Align center
iconX = (keyWidth - iconWidth) / 2;
@@ -808,17 +669,18 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
}
// Draw popup hint "..." at the bottom right corner of the key.
- protected void drawKeyPopupHint(Key key, Canvas canvas, Paint paint, KeyDrawParams params) {
- final int keyWidth = key.mWidth - key.mVisualInsetsLeft - key.mVisualInsetsRight;
+ protected void drawKeyPopupHint(final Key key, final Canvas canvas, final Paint paint,
+ final KeyDrawParams params) {
+ final int keyWidth = key.getDrawWidth();
final int keyHeight = key.mHeight;
- paint.setTypeface(params.mKeyTextStyle);
- paint.setTextSize(params.mKeyHintLetterSize);
- paint.setColor(params.mKeyHintLabelColor);
+ paint.setTypeface(params.mTypeface);
+ paint.setTextSize(params.mHintLetterSize);
+ paint.setColor(params.mHintLabelColor);
paint.setTextAlign(Align.CENTER);
- final float hintX = keyWidth - params.mKeyHintLetterPadding
+ final float hintX = keyWidth - mKeyHintLetterPadding
- getCharWidth(KEY_LABEL_REFERENCE_CHAR, paint) / 2;
- final float hintY = keyHeight - params.mKeyPopupHintLetterPadding;
+ final float hintY = keyHeight - mKeyPopupHintLetterPadding;
canvas.drawText(POPUP_HINT_CHAR, hintX, hintY, paint);
if (LatinImeLogger.sVISUALDEBUG) {
@@ -828,7 +690,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
}
}
- private static int getCharGeometryCacheKey(char referenceChar, Paint paint) {
+ private static int getCharGeometryCacheKey(final char referenceChar, final Paint paint) {
final int labelSize = (int)paint.getTextSize();
final Typeface face = paint.getTypeface();
final int codePointOffset = referenceChar << 15;
@@ -846,7 +708,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
// Working variable for the following methods.
private final Rect mTextBounds = new Rect();
- private float getCharHeight(char[] referenceChar, Paint paint) {
+ private float getCharHeight(final char[] referenceChar, final Paint paint) {
final int key = getCharGeometryCacheKey(referenceChar[0], paint);
final Float cachedValue = sTextHeightCache.get(key);
if (cachedValue != null)
@@ -858,7 +720,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
return height;
}
- private float getCharWidth(char[] referenceChar, Paint paint) {
+ private float getCharWidth(final char[] referenceChar, final Paint paint) {
final int key = getCharGeometryCacheKey(referenceChar[0], paint);
final Float cachedValue = sTextWidthCache.get(key);
if (cachedValue != null)
@@ -870,36 +732,37 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
return width;
}
- public float getLabelWidth(String label, Paint paint) {
- paint.getTextBounds(label.toString(), 0, label.length(), mTextBounds);
+ public float getLabelWidth(final String label, final Paint paint) {
+ paint.getTextBounds(label, 0, label.length(), mTextBounds);
return mTextBounds.width();
}
- protected static void drawIcon(Canvas canvas, Drawable icon, int x, int y, int width,
- int height) {
+ protected static void drawIcon(final Canvas canvas, final Drawable icon, final int x,
+ final int y, final int width, final int height) {
canvas.translate(x, y);
icon.setBounds(0, 0, width, height);
icon.draw(canvas);
canvas.translate(-x, -y);
}
- private static void drawHorizontalLine(Canvas canvas, float y, float w, int color,
- Paint paint) {
+ private static void drawHorizontalLine(final Canvas canvas, final float y, final float w,
+ final int color, final Paint paint) {
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(1.0f);
paint.setColor(color);
canvas.drawLine(0, y, w, y, paint);
}
- private static void drawVerticalLine(Canvas canvas, float x, float h, int color, Paint paint) {
+ private static void drawVerticalLine(final Canvas canvas, final float x, final float h,
+ final int color, final Paint paint) {
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(1.0f);
paint.setColor(color);
canvas.drawLine(x, 0, x, h, paint);
}
- private static void drawRectangle(Canvas canvas, float x, float y, float w, float h, int color,
- Paint paint) {
+ private static void drawRectangle(final Canvas canvas, final float x, final float y,
+ final float w, final float h, final int color, final Paint paint) {
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(1.0f);
paint.setColor(color);
@@ -911,8 +774,8 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
public Paint newDefaultLabelPaint() {
final Paint paint = new Paint();
paint.setAntiAlias(true);
- paint.setTypeface(mKeyDrawParams.mKeyTextStyle);
- paint.setTextSize(mKeyDrawParams.mKeyLabelSize);
+ paint.setTypeface(mKeyDrawParams.mTypeface);
+ paint.setTextSize(mKeyDrawParams.mLabelSize);
return paint;
}
@@ -950,11 +813,11 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
}
@Override
- public void dismissKeyPreview(PointerTracker tracker) {
+ public void dismissKeyPreview(final PointerTracker tracker) {
mDrawingHandler.dismissKeyPreview(mDelayAfterPreview, tracker);
}
- private void addKeyPreview(TextView keyPreview) {
+ private void addKeyPreview(final TextView keyPreview) {
locatePreviewPlacerView();
mPreviewPlacerView.addView(
keyPreview, ViewLayoutUtils.newLayoutParam(mPreviewPlacerView, 0, 0));
@@ -981,7 +844,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
}
}
- public void showGestureFloatingPreviewText(String gestureFloatingPreviewText) {
+ public void showGestureFloatingPreviewText(final String gestureFloatingPreviewText) {
locatePreviewPlacerView();
mPreviewPlacerView.setGestureFloatingPreviewText(gestureFloatingPreviewText);
}
@@ -992,15 +855,19 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
}
@Override
- public void showGesturePreviewTrail(PointerTracker tracker) {
+ public void showGesturePreviewTrail(final PointerTracker tracker,
+ final boolean isOldestTracker) {
locatePreviewPlacerView();
- mPreviewPlacerView.invalidatePointer(tracker);
+ mPreviewPlacerView.invalidatePointer(tracker, isOldestTracker);
}
- @SuppressWarnings("deprecation") // setBackgroundDrawable is replaced by setBackground in API16
@Override
- public void showKeyPreview(PointerTracker tracker) {
- if (!mShowKeyPreviewPopup) return;
+ public void showKeyPreview(final PointerTracker tracker) {
+ final KeyPreviewDrawParams previewParams = mKeyPreviewDrawParams;
+ if (!mShowKeyPreviewPopup) {
+ previewParams.mPreviewVisibleOffset = -mKeyboard.mVerticalGap;
+ return;
+ }
final TextView previewText = getKeyPreviewText(tracker.mPointerId);
// If the key preview has no parent view yet, add it to the ViewGroup which can place
@@ -1014,21 +881,28 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
// If key is invalid or IME is already closed, we must not show key preview.
// Trying to show key preview while root window is closed causes
// WindowManager.BadTokenException.
- if (key == null)
+ if (key == null) {
return;
+ }
- final KeyPreviewDrawParams params = mKeyPreviewDrawParams;
+ final KeyDrawParams drawParams = mKeyDrawParams;
+ previewText.setTextColor(drawParams.mPreviewTextColor);
+ final Drawable background = previewText.getBackground();
+ if (background != null) {
+ background.setState(KEY_PREVIEW_BACKGROUND_DEFAULT_STATE);
+ background.setAlpha(PREVIEW_ALPHA);
+ }
final String label = key.isShiftedLetterActivated() ? key.mHintLabel : key.mLabel;
- // What we show as preview should match what we show on a key top in onBufferDraw().
+ // What we show as preview should match what we show on a key top in onDraw().
if (label != null) {
// TODO Should take care of temporaryShiftLabel here.
previewText.setCompoundDrawables(null, null, null, null);
if (StringUtils.codePointCount(label) > 1) {
- previewText.setTextSize(TypedValue.COMPLEX_UNIT_PX, params.mKeyLetterSize);
+ previewText.setTextSize(TypedValue.COMPLEX_UNIT_PX, drawParams.mLetterSize);
previewText.setTypeface(Typeface.DEFAULT_BOLD);
} else {
- previewText.setTextSize(TypedValue.COMPLEX_UNIT_PX, params.mPreviewTextSize);
- previewText.setTypeface(params.mKeyTextStyle);
+ previewText.setTextSize(TypedValue.COMPLEX_UNIT_PX, drawParams.mPreviewTextSize);
+ previewText.setTypeface(key.selectTypeface(drawParams));
}
previewText.setText(label);
} else {
@@ -1036,48 +910,44 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
key.getPreviewIcon(mKeyboard.mIconsSet));
previewText.setText(null);
}
- previewText.setBackgroundDrawable(params.mPreviewBackground);
previewText.measure(
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
- final int keyDrawWidth = key.mWidth - key.mVisualInsetsLeft - key.mVisualInsetsRight;
+ final int keyDrawWidth = key.getDrawWidth();
final int previewWidth = previewText.getMeasuredWidth();
- final int previewHeight = params.mPreviewHeight;
+ final int previewHeight = mPreviewHeight;
// The width and height of visible part of the key preview background. The content marker
// of the background 9-patch have to cover the visible part of the background.
- params.mPreviewVisibleWidth = previewWidth - previewText.getPaddingLeft()
+ previewParams.mPreviewVisibleWidth = previewWidth - previewText.getPaddingLeft()
- previewText.getPaddingRight();
- params.mPreviewVisibleHeight = previewHeight - previewText.getPaddingTop()
+ previewParams.mPreviewVisibleHeight = previewHeight - previewText.getPaddingTop()
- previewText.getPaddingBottom();
// The distance between the top edge of the parent key and the bottom of the visible part
// of the key preview background.
- params.mPreviewVisibleOffset = params.mPreviewOffset - previewText.getPaddingBottom();
- getLocationInWindow(params.mCoordinates);
+ previewParams.mPreviewVisibleOffset = mPreviewOffset - previewText.getPaddingBottom();
+ getLocationInWindow(mCoordinates);
// The key preview is horizontally aligned with the center of the visible part of the
// parent key. If it doesn't fit in this {@link KeyboardView}, it is moved inward to fit and
// the left/right background is used if such background is specified.
- int previewX = key.mX + key.mVisualInsetsLeft - (previewWidth - keyDrawWidth) / 2
- + params.mCoordinates[0];
+ final int statePosition;
+ int previewX = key.getDrawX() - (previewWidth - keyDrawWidth) / 2 + mCoordinates[0];
if (previewX < 0) {
previewX = 0;
- if (params.mPreviewLeftBackground != null) {
- previewText.setBackgroundDrawable(params.mPreviewLeftBackground);
- }
+ statePosition = STATE_LEFT;
} else if (previewX > getWidth() - previewWidth) {
previewX = getWidth() - previewWidth;
- if (params.mPreviewRightBackground != null) {
- previewText.setBackgroundDrawable(params.mPreviewRightBackground);
- }
+ statePosition = STATE_RIGHT;
+ } else {
+ statePosition = STATE_MIDDLE;
}
// The key preview is placed vertically above the top edge of the parent key with an
// arbitrary offset.
- final int previewY = key.mY - previewHeight + params.mPreviewOffset
- + params.mCoordinates[1];
+ final int previewY = key.mY - previewHeight + mPreviewOffset + mCoordinates[1];
- // Set the preview background state
- previewText.getBackground().setState(
- key.mMoreKeys != null ? LONG_PRESSABLE_STATE_SET : EMPTY_STATE_SET);
- previewText.setTextColor(params.mPreviewTextColor);
+ if (background != null) {
+ final int hasMoreKeys = (key.mMoreKeys != null) ? STATE_HAS_MOREKEYS : STATE_NORMAL;
+ background.setState(KEY_PREVIEW_BACKGROUND_STATE_TABLE[statePosition][hasMoreKeys]);
+ }
ViewLayoutUtils.placeViewAt(
previewText, previewX, previewY, previewWidth, previewHeight);
previewText.setVisibility(VISIBLE);
@@ -1103,7 +973,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
* @see #invalidateAllKeys
*/
@Override
- public void invalidateKey(Key key) {
+ public void invalidateKey(final Key key) {
if (mInvalidateAllKeys) return;
if (key == null) return;
mInvalidatedKeys.add(key);
diff --git a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
index df84271e8..4ed0f58e1 100644
--- a/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
+++ b/java/src/com/android/inputmethod/keyboard/MainKeyboardView.java
@@ -43,15 +43,16 @@ import com.android.inputmethod.accessibility.AccessibilityUtils;
import com.android.inputmethod.accessibility.AccessibleKeyboardViewProxy;
import com.android.inputmethod.keyboard.PointerTracker.DrawingProxy;
import com.android.inputmethod.keyboard.PointerTracker.TimerProxy;
+import com.android.inputmethod.keyboard.internal.KeyDrawParams;
import com.android.inputmethod.keyboard.internal.SuddenJumpingTouchEventHandler;
import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.LatinIME;
import com.android.inputmethod.latin.LatinImeLogger;
import com.android.inputmethod.latin.R;
+import com.android.inputmethod.latin.ResourceUtils;
import com.android.inputmethod.latin.StaticInnerHandlerWrapper;
import com.android.inputmethod.latin.StringUtils;
import com.android.inputmethod.latin.SubtypeLocale;
-import com.android.inputmethod.latin.Utils;
import com.android.inputmethod.latin.Utils.UsabilityStudyLogUtils;
import com.android.inputmethod.latin.define.ProductionFlag;
import com.android.inputmethod.research.ResearchLogger;
@@ -62,9 +63,25 @@ import java.util.WeakHashMap;
/**
* A view that is responsible for detecting key presses and touch movements.
*
- * @attr ref R.styleable#KeyboardView_keyHysteresisDistance
- * @attr ref R.styleable#KeyboardView_verticalCorrection
- * @attr ref R.styleable#KeyboardView_popupLayout
+ * @attr ref R.styleable#MainKeyboardView_autoCorrectionSpacebarLedEnabled
+ * @attr ref R.styleable#MainKeyboardView_autoCorrectionSpacebarLedIcon
+ * @attr ref R.styleable#MainKeyboardView_spacebarTextRatio
+ * @attr ref R.styleable#MainKeyboardView_spacebarTextColor
+ * @attr ref R.styleable#MainKeyboardView_spacebarTextShadowColor
+ * @attr ref R.styleable#MainKeyboardView_languageOnSpacebarFinalAlpha
+ * @attr ref R.styleable#MainKeyboardView_languageOnSpacebarFadeoutAnimator
+ * @attr ref R.styleable#MainKeyboardView_altCodeKeyWhileTypingFadeoutAnimator
+ * @attr ref R.styleable#MainKeyboardView_altCodeKeyWhileTypingFadeinAnimator
+ * @attr ref R.styleable#MainKeyboardView_keyHysteresisDistance
+ * @attr ref R.styleable#MainKeyboardView_touchNoiseThresholdTime
+ * @attr ref R.styleable#MainKeyboardView_touchNoiseThresholdDistance
+ * @attr ref R.styleable#MainKeyboardView_slidingKeyInputEnable
+ * @attr ref R.styleable#MainKeyboardView_keyRepeatStartTimeout
+ * @attr ref R.styleable#MainKeyboardView_keyRepeatInterval
+ * @attr ref R.styleable#MainKeyboardView_longPressKeyTimeout
+ * @attr ref R.styleable#MainKeyboardView_longPressShiftKeyTimeout
+ * @attr ref R.styleable#MainKeyboardView_ignoreAltCodeKeyTimeout
+ * @attr ref R.styleable#MainKeyboardView_showMoreKeysKeyboardAtTouchPoint
*/
public class MainKeyboardView extends KeyboardView implements PointerTracker.KeyEventHandler,
SuddenJumpingTouchEventHandler.ProcessMotionEvent {
@@ -149,7 +166,7 @@ public class MainKeyboardView extends KeyboardView implements PointerTracker.Key
}
@Override
- public void handleMessage(Message msg) {
+ public void handleMessage(final Message msg) {
final MainKeyboardView keyboardView = getOuterInstance();
final PointerTracker tracker = (PointerTracker) msg.obj;
switch (msg.what) {
@@ -173,14 +190,14 @@ public class MainKeyboardView extends KeyboardView implements PointerTracker.Key
}
}
- private void startKeyRepeatTimer(PointerTracker tracker, long delay) {
+ private void startKeyRepeatTimer(final PointerTracker tracker, final long delay) {
final Key key = tracker.getKey();
if (key == null) return;
sendMessageDelayed(obtainMessage(MSG_REPEAT_KEY, key.mCode, 0, tracker), delay);
}
@Override
- public void startKeyRepeatTimer(PointerTracker tracker) {
+ public void startKeyRepeatTimer(final PointerTracker tracker) {
startKeyRepeatTimer(tracker, mKeyRepeatStartTimeout);
}
@@ -194,7 +211,7 @@ public class MainKeyboardView extends KeyboardView implements PointerTracker.Key
}
@Override
- public void startLongPressTimer(int code) {
+ public void startLongPressTimer(final int code) {
cancelLongPressTimer();
final int delay;
switch (code) {
@@ -211,7 +228,7 @@ public class MainKeyboardView extends KeyboardView implements PointerTracker.Key
}
@Override
- public void startLongPressTimer(PointerTracker tracker) {
+ public void startLongPressTimer(final PointerTracker tracker) {
cancelLongPressTimer();
if (tracker == null) {
return;
@@ -265,7 +282,7 @@ public class MainKeyboardView extends KeyboardView implements PointerTracker.Key
}
@Override
- public void startTypingStateTimer(Key typedKey) {
+ public void startTypingStateTimer(final Key typedKey) {
if (typedKey.isModifier() || typedKey.altCodeWhileTyping()) {
return;
}
@@ -321,11 +338,11 @@ public class MainKeyboardView extends KeyboardView implements PointerTracker.Key
}
}
- public MainKeyboardView(Context context, AttributeSet attrs) {
+ public MainKeyboardView(final Context context, final AttributeSet attrs) {
this(context, attrs, R.attr.mainKeyboardViewStyle);
}
- public MainKeyboardView(Context context, AttributeSet attrs, int defStyle) {
+ public MainKeyboardView(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
mTouchScreenRegulator = new SuddenJumpingTouchEventHandler(getContext(), this);
@@ -334,7 +351,7 @@ public class MainKeyboardView extends KeyboardView implements PointerTracker.Key
.hasSystemFeature(PackageManager.FEATURE_TOUCHSCREEN_MULTITOUCH_DISTINCT);
final Resources res = getResources();
final boolean needsPhantomSuddenMoveEventHack = Boolean.parseBoolean(
- Utils.getDeviceOverrideValue(res,
+ ResourceUtils.getDeviceOverrideValue(res,
R.array.phantom_sudden_move_event_device_list, "false"));
PointerTracker.init(mHasDistinctMultitouch, needsPhantomSuddenMoveEventHack);
@@ -376,7 +393,7 @@ public class MainKeyboardView extends KeyboardView implements PointerTracker.Key
altCodeKeyWhileTypingFadeinAnimatorResId, this);
}
- private ObjectAnimator loadObjectAnimator(int resId, Object target) {
+ private ObjectAnimator loadObjectAnimator(final int resId, final Object target) {
if (resId == 0) return null;
final ObjectAnimator animator = (ObjectAnimator)AnimatorInflater.loadAnimator(
getContext(), resId);
@@ -391,7 +408,7 @@ public class MainKeyboardView extends KeyboardView implements PointerTracker.Key
return mLanguageOnSpacebarAnimAlpha;
}
- public void setLanguageOnSpacebarAnimAlpha(int alpha) {
+ public void setLanguageOnSpacebarAnimAlpha(final int alpha) {
mLanguageOnSpacebarAnimAlpha = alpha;
invalidateKey(mSpaceKey);
}
@@ -400,12 +417,12 @@ public class MainKeyboardView extends KeyboardView implements PointerTracker.Key
return mAltCodeKeyWhileTypingAnimAlpha;
}
- public void setAltCodeKeyWhileTypingAnimAlpha(int alpha) {
+ public void setAltCodeKeyWhileTypingAnimAlpha(final int alpha) {
mAltCodeKeyWhileTypingAnimAlpha = alpha;
updateAltCodeKeyWhileTyping();
}
- public void setKeyboardActionListener(KeyboardActionListener listener) {
+ public void setKeyboardActionListener(final KeyboardActionListener listener) {
mKeyboardActionListener = listener;
PointerTracker.setKeyboardActionListener(listener);
}
@@ -442,7 +459,7 @@ public class MainKeyboardView extends KeyboardView implements PointerTracker.Key
* @param keyboard the keyboard to display in this view
*/
@Override
- public void setKeyboard(Keyboard keyboard) {
+ public void setKeyboard(final Keyboard keyboard) {
// Remove any pending messages, except dismissing preview and key repeat.
mKeyTimerHandler.cancelLongPressTimer();
super.setKeyboard(keyboard);
@@ -467,11 +484,11 @@ public class MainKeyboardView extends KeyboardView implements PointerTracker.Key
}
// Note that this method is called from a non-UI thread.
- public void setMainDictionaryAvailability(boolean mainDictionaryAvailable) {
+ public void setMainDictionaryAvailability(final boolean mainDictionaryAvailable) {
PointerTracker.setMainDictionaryAvailability(mainDictionaryAvailable);
}
- public void setGestureHandlingEnabledByUser(boolean gestureHandlingEnabledByUser) {
+ public void setGestureHandlingEnabledByUser(final boolean gestureHandlingEnabledByUser) {
PointerTracker.setGestureHandlingEnabledByUser(gestureHandlingEnabledByUser);
}
@@ -483,7 +500,7 @@ public class MainKeyboardView extends KeyboardView implements PointerTracker.Key
return mHasDistinctMultitouch;
}
- public void setDistinctMultitouch(boolean hasDistinctMultitouch) {
+ public void setDistinctMultitouch(final boolean hasDistinctMultitouch) {
mHasDistinctMultitouch = hasDistinctMultitouch;
}
@@ -514,7 +531,8 @@ public class MainKeyboardView extends KeyboardView implements PointerTracker.Key
super.cancelAllMessages();
}
- private boolean openMoreKeysKeyboardIfRequired(Key parentKey, PointerTracker tracker) {
+ private boolean openMoreKeysKeyboardIfRequired(final Key parentKey,
+ final PointerTracker tracker) {
// Check if we have a popup layout specified first.
if (mMoreKeysLayout == 0) {
return false;
@@ -529,7 +547,7 @@ public class MainKeyboardView extends KeyboardView implements PointerTracker.Key
}
// This default implementation returns a more keys panel.
- protected MoreKeysPanel onCreateMoreKeysPanel(Key parentKey) {
+ protected MoreKeysPanel onCreateMoreKeysPanel(final Key parentKey) {
if (parentKey.mMoreKeys == null)
return null;
@@ -555,7 +573,7 @@ public class MainKeyboardView extends KeyboardView implements PointerTracker.Key
* @return true if the long press is handled, false otherwise. Subclasses should call the
* method on the base class if the subclass doesn't wish to handle the call.
*/
- protected boolean onLongPress(Key parentKey, PointerTracker tracker) {
+ protected boolean onLongPress(final Key parentKey, final PointerTracker tracker) {
if (ProductionFlag.IS_EXPERIMENTAL) {
ResearchLogger.mainKeyboardView_onLongPress();
}
@@ -579,20 +597,20 @@ public class MainKeyboardView extends KeyboardView implements PointerTracker.Key
return openMoreKeysPanel(parentKey, tracker);
}
- private boolean invokeCustomRequest(int code) {
+ private boolean invokeCustomRequest(final int code) {
return mKeyboardActionListener.onCustomRequest(code);
}
- private void invokeCodeInput(int primaryCode) {
+ private void invokeCodeInput(final int primaryCode) {
mKeyboardActionListener.onCodeInput(
primaryCode, Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE);
}
- private void invokeReleaseKey(int primaryCode) {
+ private void invokeReleaseKey(final int primaryCode) {
mKeyboardActionListener.onReleaseKey(primaryCode, false);
}
- private boolean openMoreKeysPanel(Key parentKey, PointerTracker tracker) {
+ private boolean openMoreKeysPanel(final Key parentKey, final PointerTracker tracker) {
MoreKeysPanel moreKeysPanel = mMoreKeysPanelCache.get(parentKey);
if (moreKeysPanel == null) {
moreKeysPanel = onCreateMoreKeysPanel(parentKey);
@@ -618,9 +636,9 @@ public class MainKeyboardView extends KeyboardView implements PointerTracker.Key
// The more keys keyboard is usually vertically aligned with the top edge of the parent key
// (plus vertical gap). If the key preview is enabled, the more keys keyboard is vertically
// aligned with the bottom edge of the visible part of the key preview.
- final int pointY = parentKey.mY + (keyPreviewEnabled
- ? mKeyPreviewDrawParams.mPreviewVisibleOffset
- : -parentKey.mVerticalGap);
+ // {@code mPreviewVisibleOffset} has been set appropriately in
+ // {@link KeyboardView#showKeyPreview(PointerTracker)}.
+ final int pointY = parentKey.mY + mKeyPreviewDrawParams.mPreviewVisibleOffset;
moreKeysPanel.showMoreKeysPanel(
this, this, pointX, pointY, mMoreKeysWindow, mKeyboardActionListener);
final int translatedX = moreKeysPanel.translateX(tracker.getLastX());
@@ -643,7 +661,15 @@ public class MainKeyboardView extends KeyboardView implements PointerTracker.Key
}
@Override
- public boolean onTouchEvent(MotionEvent me) {
+ public boolean dispatchTouchEvent(MotionEvent event) {
+ if (AccessibilityUtils.getInstance().isTouchExplorationEnabled()) {
+ return AccessibleKeyboardViewProxy.getInstance().dispatchTouchEvent(event);
+ }
+ return super.dispatchTouchEvent(event);
+ }
+
+ @Override
+ public boolean onTouchEvent(final MotionEvent me) {
if (getKeyboard() == null) {
return false;
}
@@ -651,7 +677,7 @@ public class MainKeyboardView extends KeyboardView implements PointerTracker.Key
}
@Override
- public boolean processMotionEvent(MotionEvent me) {
+ public boolean processMotionEvent(final MotionEvent me) {
final boolean nonDistinctMultitouch = !mHasDistinctMultitouch;
final int action = me.getActionMasked();
final int pointerCount = me.getPointerCount();
@@ -818,7 +844,7 @@ public class MainKeyboardView extends KeyboardView implements PointerTracker.Key
* otherwise
*/
@Override
- public boolean dispatchHoverEvent(MotionEvent event) {
+ public boolean dispatchHoverEvent(final MotionEvent event) {
if (AccessibilityUtils.getInstance().isTouchExplorationEnabled()) {
final PointerTracker tracker = PointerTracker.getPointerTracker(0, this);
return AccessibleKeyboardViewProxy.getInstance().dispatchHoverEvent(event, tracker);
@@ -828,7 +854,7 @@ public class MainKeyboardView extends KeyboardView implements PointerTracker.Key
return false;
}
- public void updateShortcutKey(boolean available) {
+ public void updateShortcutKey(final boolean available) {
final Keyboard keyboard = getKeyboard();
if (keyboard == null) return;
final Key shortcutKey = keyboard.getKey(Keyboard.CODE_SHORTCUT);
@@ -845,8 +871,8 @@ public class MainKeyboardView extends KeyboardView implements PointerTracker.Key
}
}
- public void startDisplayLanguageOnSpacebar(boolean subtypeChanged,
- boolean needsToDisplayLanguage, boolean hasMultipleEnabledIMEsOrSubtypes) {
+ public void startDisplayLanguageOnSpacebar(final boolean subtypeChanged,
+ final boolean needsToDisplayLanguage, final boolean hasMultipleEnabledIMEsOrSubtypes) {
mNeedsToDisplayLanguage = needsToDisplayLanguage;
mHasMultipleEnabledIMEsOrSubtypes = hasMultipleEnabledIMEsOrSubtypes;
final ObjectAnimator animator = mLanguageOnSpacebarFadeoutAnimator;
@@ -868,14 +894,15 @@ public class MainKeyboardView extends KeyboardView implements PointerTracker.Key
invalidateKey(mSpaceKey);
}
- public void updateAutoCorrectionState(boolean isAutoCorrection) {
+ public void updateAutoCorrectionState(final boolean isAutoCorrection) {
if (!mAutoCorrectionSpacebarLedEnabled) return;
mAutoCorrectionSpacebarLedOn = isAutoCorrection;
invalidateKey(mSpaceKey);
}
@Override
- protected void onDrawKeyTopVisuals(Key key, Canvas canvas, Paint paint, KeyDrawParams params) {
+ protected void onDrawKeyTopVisuals(final Key key, final Canvas canvas, final Paint paint,
+ final KeyDrawParams params) {
if (key.altCodeWhileTyping() && key.isEnabled()) {
params.mAnimAlpha = mAltCodeKeyWhileTypingAnimAlpha;
}
@@ -893,7 +920,7 @@ public class MainKeyboardView extends KeyboardView implements PointerTracker.Key
}
}
- private boolean fitsTextIntoWidth(final int width, String text, Paint paint) {
+ private boolean fitsTextIntoWidth(final int width, final String text, final Paint paint) {
paint.setTextScaleX(1.0f);
final float textWidth = getLabelWidth(text, paint);
if (textWidth < width) return true;
@@ -906,7 +933,7 @@ public class MainKeyboardView extends KeyboardView implements PointerTracker.Key
}
// Layout language name on spacebar.
- private String layoutLanguageOnSpacebar(Paint paint, InputMethodSubtype subtype,
+ private String layoutLanguageOnSpacebar(final Paint paint, final InputMethodSubtype subtype,
final int width) {
// Choose appropriate language name to fit into the width.
String text = getFullDisplayName(subtype, getResources());
@@ -927,7 +954,7 @@ public class MainKeyboardView extends KeyboardView implements PointerTracker.Key
return "";
}
- private void drawSpacebar(Key key, Canvas canvas, Paint paint) {
+ private void drawSpacebar(final Key key, final Canvas canvas, final Paint paint) {
final int width = key.mWidth;
final int height = key.mHeight;
@@ -982,7 +1009,7 @@ public class MainKeyboardView extends KeyboardView implements PointerTracker.Key
// zz azerty T AZERTY AZERTY
// Get InputMethodSubtype's full display name in its locale.
- static String getFullDisplayName(InputMethodSubtype subtype, Resources res) {
+ static String getFullDisplayName(final InputMethodSubtype subtype, final Resources res) {
if (SubtypeLocale.isNoLanguage(subtype)) {
return SubtypeLocale.getKeyboardLayoutSetDisplayName(subtype);
}
@@ -991,7 +1018,7 @@ public class MainKeyboardView extends KeyboardView implements PointerTracker.Key
}
// Get InputMethodSubtype's short display name in its locale.
- static String getShortDisplayName(InputMethodSubtype subtype) {
+ static String getShortDisplayName(final InputMethodSubtype subtype) {
if (SubtypeLocale.isNoLanguage(subtype)) {
return "";
}
@@ -1000,7 +1027,7 @@ public class MainKeyboardView extends KeyboardView implements PointerTracker.Key
}
// Get InputMethodSubtype's middle display name in its locale.
- static String getMiddleDisplayName(InputMethodSubtype subtype) {
+ static String getMiddleDisplayName(final InputMethodSubtype subtype) {
if (SubtypeLocale.isNoLanguage(subtype)) {
return SubtypeLocale.getKeyboardLayoutSetDisplayName(subtype);
}
diff --git a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java
index a3741a2d8..c9af888f9 100644
--- a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java
@@ -20,15 +20,17 @@ import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.view.View;
-import com.android.inputmethod.keyboard.internal.KeySpecParser.MoreKeySpec;
+import com.android.inputmethod.keyboard.internal.KeyboardBuilder;
import com.android.inputmethod.keyboard.internal.KeyboardIconsSet;
+import com.android.inputmethod.keyboard.internal.KeyboardParams;
+import com.android.inputmethod.keyboard.internal.MoreKeySpec;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.StringUtils;
public class MoreKeysKeyboard extends Keyboard {
private final int mDefaultKeyCoordX;
- MoreKeysKeyboard(Builder.MoreKeysKeyboardParams params) {
+ MoreKeysKeyboard(final MoreKeysKeyboardParams params) {
super(params);
mDefaultKeyCoordX = params.getDefaultKeyCoordX() + params.mDefaultKeyWidth / 2;
}
@@ -37,220 +39,222 @@ public class MoreKeysKeyboard extends Keyboard {
return mDefaultKeyCoordX;
}
- public static class Builder extends Keyboard.Builder {
+ /* package for test */
+ static class MoreKeysKeyboardParams extends KeyboardParams {
+ public boolean mIsFixedOrder;
+ /* package */int mTopRowAdjustment;
+ public int mNumRows;
+ public int mNumColumns;
+ public int mTopKeys;
+ public int mLeftKeys;
+ public int mRightKeys; // includes default key.
+ public int mDividerWidth;
+ public int mColumnWidth;
+
+ public MoreKeysKeyboardParams() {
+ super();
+ }
+
+ /**
+ * Set keyboard parameters of more keys keyboard.
+ *
+ * @param numKeys number of keys in this more keys keyboard.
+ * @param maxColumns number of maximum columns of this more keys keyboard.
+ * @param keyWidth more keys keyboard key width in pixel, including horizontal gap.
+ * @param rowHeight more keys keyboard row height in pixel, including vertical gap.
+ * @param coordXInParent coordinate x of the key preview in parent keyboard.
+ * @param parentKeyboardWidth parent keyboard width in pixel.
+ * @param isFixedColumnOrder if true, more keys should be laid out in fixed order.
+ * @param dividerWidth width of divider, zero for no dividers.
+ */
+ public void setParameters(final int numKeys, final int maxColumns, final int keyWidth,
+ final int rowHeight, final int coordXInParent, final int parentKeyboardWidth,
+ final boolean isFixedColumnOrder, final int dividerWidth) {
+ mIsFixedOrder = isFixedColumnOrder;
+ if (parentKeyboardWidth / keyWidth < maxColumns) {
+ throw new IllegalArgumentException(
+ "Keyboard is too small to hold more keys keyboard: "
+ + parentKeyboardWidth + " " + keyWidth + " " + maxColumns);
+ }
+ mDefaultKeyWidth = keyWidth;
+ mDefaultRowHeight = rowHeight;
+
+ final int numRows = (numKeys + maxColumns - 1) / maxColumns;
+ mNumRows = numRows;
+ final int numColumns = mIsFixedOrder ? Math.min(numKeys, maxColumns)
+ : getOptimizedColumns(numKeys, maxColumns);
+ mNumColumns = numColumns;
+ final int topKeys = numKeys % numColumns;
+ mTopKeys = topKeys == 0 ? numColumns : topKeys;
+
+ final int numLeftKeys = (numColumns - 1) / 2;
+ final int numRightKeys = numColumns - numLeftKeys; // including default key.
+ // Maximum number of keys we can layout both side of the parent key
+ final int maxLeftKeys = coordXInParent / keyWidth;
+ final int maxRightKeys = (parentKeyboardWidth - coordXInParent) / keyWidth;
+ int leftKeys, rightKeys;
+ if (numLeftKeys > maxLeftKeys) {
+ leftKeys = maxLeftKeys;
+ rightKeys = numColumns - leftKeys;
+ } else if (numRightKeys > maxRightKeys + 1) {
+ rightKeys = maxRightKeys + 1; // include default key
+ leftKeys = numColumns - rightKeys;
+ } else {
+ leftKeys = numLeftKeys;
+ rightKeys = numRightKeys;
+ }
+ // If the left keys fill the left side of the parent key, entire more keys keyboard
+ // should be shifted to the right unless the parent key is on the left edge.
+ if (maxLeftKeys == leftKeys && leftKeys > 0) {
+ leftKeys--;
+ rightKeys++;
+ }
+ // If the right keys fill the right side of the parent key, entire more keys
+ // should be shifted to the left unless the parent key is on the right edge.
+ if (maxRightKeys == rightKeys - 1 && rightKeys > 1) {
+ leftKeys++;
+ rightKeys--;
+ }
+ mLeftKeys = leftKeys;
+ mRightKeys = rightKeys;
+
+ // Adjustment of the top row.
+ mTopRowAdjustment = mIsFixedOrder ? getFixedOrderTopRowAdjustment()
+ : getAutoOrderTopRowAdjustment();
+ mDividerWidth = dividerWidth;
+ mColumnWidth = mDefaultKeyWidth + mDividerWidth;
+ mBaseWidth = mOccupiedWidth = mNumColumns * mColumnWidth - mDividerWidth;
+ // Need to subtract the bottom row's gutter only.
+ mBaseHeight = mOccupiedHeight = mNumRows * mDefaultRowHeight - mVerticalGap
+ + mTopPadding + mBottomPadding;
+ }
+
+ private int getFixedOrderTopRowAdjustment() {
+ if (mNumRows == 1 || mTopKeys % 2 == 1 || mTopKeys == mNumColumns
+ || mLeftKeys == 0 || mRightKeys == 1) {
+ return 0;
+ }
+ return -1;
+ }
+
+ private int getAutoOrderTopRowAdjustment() {
+ if (mNumRows == 1 || mTopKeys == 1 || mNumColumns % 2 == mTopKeys % 2
+ || mLeftKeys == 0 || mRightKeys == 1) {
+ return 0;
+ }
+ return -1;
+ }
+
+ // Return key position according to column count (0 is default).
+ /* package */int getColumnPos(final int n) {
+ return mIsFixedOrder ? getFixedOrderColumnPos(n) : getAutomaticColumnPos(n);
+ }
+
+ private int getFixedOrderColumnPos(final int n) {
+ final int col = n % mNumColumns;
+ final int row = n / mNumColumns;
+ if (!isTopRow(row)) {
+ return col - mLeftKeys;
+ }
+ final int rightSideKeys = mTopKeys / 2;
+ final int leftSideKeys = mTopKeys - (rightSideKeys + 1);
+ final int pos = col - leftSideKeys;
+ final int numLeftKeys = mLeftKeys + mTopRowAdjustment;
+ final int numRightKeys = mRightKeys - 1;
+ if (numRightKeys >= rightSideKeys && numLeftKeys >= leftSideKeys) {
+ return pos;
+ } else if (numRightKeys < rightSideKeys) {
+ return pos - (rightSideKeys - numRightKeys);
+ } else { // numLeftKeys < leftSideKeys
+ return pos + (leftSideKeys - numLeftKeys);
+ }
+ }
+
+ private int getAutomaticColumnPos(final int n) {
+ final int col = n % mNumColumns;
+ final int row = n / mNumColumns;
+ int leftKeys = mLeftKeys;
+ if (isTopRow(row)) {
+ leftKeys += mTopRowAdjustment;
+ }
+ if (col == 0) {
+ // default position.
+ return 0;
+ }
+
+ int pos = 0;
+ int right = 1; // include default position key.
+ int left = 0;
+ int i = 0;
+ while (true) {
+ // Assign right key if available.
+ if (right < mRightKeys) {
+ pos = right;
+ right++;
+ i++;
+ }
+ if (i >= col)
+ break;
+ // Assign left key if available.
+ if (left < leftKeys) {
+ left++;
+ pos = -left;
+ i++;
+ }
+ if (i >= col)
+ break;
+ }
+ return pos;
+ }
+
+ private static int getTopRowEmptySlots(final int numKeys, final int numColumns) {
+ final int remainings = numKeys % numColumns;
+ return remainings == 0 ? 0 : numColumns - remainings;
+ }
+
+ private int getOptimizedColumns(final int numKeys, final int maxColumns) {
+ int numColumns = Math.min(numKeys, maxColumns);
+ while (getTopRowEmptySlots(numKeys, numColumns) >= mNumRows) {
+ numColumns--;
+ }
+ return numColumns;
+ }
+
+ public int getDefaultKeyCoordX() {
+ return mLeftKeys * mColumnWidth;
+ }
+
+ public int getX(final int n, final int row) {
+ final int x = getColumnPos(n) * mColumnWidth + getDefaultKeyCoordX();
+ if (isTopRow(row)) {
+ return x + mTopRowAdjustment * (mColumnWidth / 2);
+ }
+ return x;
+ }
+
+ public int getY(final int row) {
+ return (mNumRows - 1 - row) * mDefaultRowHeight + mTopPadding;
+ }
+
+ public void markAsEdgeKey(final Key key, final int row) {
+ if (row == 0)
+ key.markAsTopEdge(this);
+ if (isTopRow(row))
+ key.markAsBottomEdge(this);
+ }
+
+ private boolean isTopRow(final int rowCount) {
+ return mNumRows > 1 && rowCount == mNumRows - 1;
+ }
+ }
+
+ public static class Builder extends KeyboardBuilder {
private final Key mParentKey;
private final Drawable mDivider;
private static final float LABEL_PADDING_RATIO = 0.2f;
private static final float DIVIDER_RATIO = 0.2f;
- public static class MoreKeysKeyboardParams extends Keyboard.Params {
- public boolean mIsFixedOrder;
- /* package */int mTopRowAdjustment;
- public int mNumRows;
- public int mNumColumns;
- public int mTopKeys;
- public int mLeftKeys;
- public int mRightKeys; // includes default key.
- public int mDividerWidth;
- public int mColumnWidth;
-
- public MoreKeysKeyboardParams() {
- super();
- }
-
- /**
- * Set keyboard parameters of more keys keyboard.
- *
- * @param numKeys number of keys in this more keys keyboard.
- * @param maxColumns number of maximum columns of this more keys keyboard.
- * @param keyWidth more keys keyboard key width in pixel, including horizontal gap.
- * @param rowHeight more keys keyboard row height in pixel, including vertical gap.
- * @param coordXInParent coordinate x of the key preview in parent keyboard.
- * @param parentKeyboardWidth parent keyboard width in pixel.
- * @param isFixedColumnOrder if true, more keys should be laid out in fixed order.
- * @param dividerWidth width of divider, zero for no dividers.
- */
- public void setParameters(int numKeys, int maxColumns, int keyWidth, int rowHeight,
- int coordXInParent, int parentKeyboardWidth, boolean isFixedColumnOrder,
- int dividerWidth) {
- mIsFixedOrder = isFixedColumnOrder;
- if (parentKeyboardWidth / keyWidth < maxColumns) {
- throw new IllegalArgumentException(
- "Keyboard is too small to hold more keys keyboard: "
- + parentKeyboardWidth + " " + keyWidth + " " + maxColumns);
- }
- mDefaultKeyWidth = keyWidth;
- mDefaultRowHeight = rowHeight;
-
- final int numRows = (numKeys + maxColumns - 1) / maxColumns;
- mNumRows = numRows;
- final int numColumns = mIsFixedOrder ? Math.min(numKeys, maxColumns)
- : getOptimizedColumns(numKeys, maxColumns);
- mNumColumns = numColumns;
- final int topKeys = numKeys % numColumns;
- mTopKeys = topKeys == 0 ? numColumns : topKeys;
-
- final int numLeftKeys = (numColumns - 1) / 2;
- final int numRightKeys = numColumns - numLeftKeys; // including default key.
- // Maximum number of keys we can layout both side of the parent key
- final int maxLeftKeys = coordXInParent / keyWidth;
- final int maxRightKeys = (parentKeyboardWidth - coordXInParent) / keyWidth;
- int leftKeys, rightKeys;
- if (numLeftKeys > maxLeftKeys) {
- leftKeys = maxLeftKeys;
- rightKeys = numColumns - leftKeys;
- } else if (numRightKeys > maxRightKeys + 1) {
- rightKeys = maxRightKeys + 1; // include default key
- leftKeys = numColumns - rightKeys;
- } else {
- leftKeys = numLeftKeys;
- rightKeys = numRightKeys;
- }
- // If the left keys fill the left side of the parent key, entire more keys keyboard
- // should be shifted to the right unless the parent key is on the left edge.
- if (maxLeftKeys == leftKeys && leftKeys > 0) {
- leftKeys--;
- rightKeys++;
- }
- // If the right keys fill the right side of the parent key, entire more keys
- // should be shifted to the left unless the parent key is on the right edge.
- if (maxRightKeys == rightKeys - 1 && rightKeys > 1) {
- leftKeys++;
- rightKeys--;
- }
- mLeftKeys = leftKeys;
- mRightKeys = rightKeys;
-
- // Adjustment of the top row.
- mTopRowAdjustment = mIsFixedOrder ? getFixedOrderTopRowAdjustment()
- : getAutoOrderTopRowAdjustment();
- mDividerWidth = dividerWidth;
- mColumnWidth = mDefaultKeyWidth + mDividerWidth;
- mBaseWidth = mOccupiedWidth = mNumColumns * mColumnWidth - mDividerWidth;
- // Need to subtract the bottom row's gutter only.
- mBaseHeight = mOccupiedHeight = mNumRows * mDefaultRowHeight - mVerticalGap
- + mTopPadding + mBottomPadding;
- }
-
- private int getFixedOrderTopRowAdjustment() {
- if (mNumRows == 1 || mTopKeys % 2 == 1 || mTopKeys == mNumColumns
- || mLeftKeys == 0 || mRightKeys == 1) {
- return 0;
- }
- return -1;
- }
-
- private int getAutoOrderTopRowAdjustment() {
- if (mNumRows == 1 || mTopKeys == 1 || mNumColumns % 2 == mTopKeys % 2
- || mLeftKeys == 0 || mRightKeys == 1) {
- return 0;
- }
- return -1;
- }
-
- // Return key position according to column count (0 is default).
- /* package */int getColumnPos(int n) {
- return mIsFixedOrder ? getFixedOrderColumnPos(n) : getAutomaticColumnPos(n);
- }
-
- private int getFixedOrderColumnPos(int n) {
- final int col = n % mNumColumns;
- final int row = n / mNumColumns;
- if (!isTopRow(row)) {
- return col - mLeftKeys;
- }
- final int rightSideKeys = mTopKeys / 2;
- final int leftSideKeys = mTopKeys - (rightSideKeys + 1);
- final int pos = col - leftSideKeys;
- final int numLeftKeys = mLeftKeys + mTopRowAdjustment;
- final int numRightKeys = mRightKeys - 1;
- if (numRightKeys >= rightSideKeys && numLeftKeys >= leftSideKeys) {
- return pos;
- } else if (numRightKeys < rightSideKeys) {
- return pos - (rightSideKeys - numRightKeys);
- } else { // numLeftKeys < leftSideKeys
- return pos + (leftSideKeys - numLeftKeys);
- }
- }
-
- private int getAutomaticColumnPos(int n) {
- final int col = n % mNumColumns;
- final int row = n / mNumColumns;
- int leftKeys = mLeftKeys;
- if (isTopRow(row)) {
- leftKeys += mTopRowAdjustment;
- }
- if (col == 0) {
- // default position.
- return 0;
- }
-
- int pos = 0;
- int right = 1; // include default position key.
- int left = 0;
- int i = 0;
- while (true) {
- // Assign right key if available.
- if (right < mRightKeys) {
- pos = right;
- right++;
- i++;
- }
- if (i >= col)
- break;
- // Assign left key if available.
- if (left < leftKeys) {
- left++;
- pos = -left;
- i++;
- }
- if (i >= col)
- break;
- }
- return pos;
- }
-
- private static int getTopRowEmptySlots(int numKeys, int numColumns) {
- final int remainings = numKeys % numColumns;
- return remainings == 0 ? 0 : numColumns - remainings;
- }
-
- private int getOptimizedColumns(int numKeys, int maxColumns) {
- int numColumns = Math.min(numKeys, maxColumns);
- while (getTopRowEmptySlots(numKeys, numColumns) >= mNumRows) {
- numColumns--;
- }
- return numColumns;
- }
-
- public int getDefaultKeyCoordX() {
- return mLeftKeys * mColumnWidth;
- }
-
- public int getX(int n, int row) {
- final int x = getColumnPos(n) * mColumnWidth + getDefaultKeyCoordX();
- if (isTopRow(row)) {
- return x + mTopRowAdjustment * (mColumnWidth / 2);
- }
- return x;
- }
-
- public int getY(int row) {
- return (mNumRows - 1 - row) * mDefaultRowHeight + mTopPadding;
- }
-
- public void markAsEdgeKey(Key key, int row) {
- if (row == 0)
- key.markAsTopEdge(this);
- if (isTopRow(row))
- key.markAsBottomEdge(this);
- }
-
- private boolean isTopRow(int rowCount) {
- return mNumRows > 1 && rowCount == mNumRows - 1;
- }
- }
/**
* The builder of MoreKeysKeyboard.
@@ -258,7 +262,8 @@ public class MoreKeysKeyboard extends Keyboard {
* @param parentKey the {@link Key} that invokes more keys keyboard.
* @param parentKeyboardView the {@link KeyboardView} that contains the parentKey.
*/
- public Builder(View containerView, Key parentKey, KeyboardView parentKeyboardView) {
+ public Builder(final View containerView, final Key parentKey,
+ final KeyboardView parentKeyboardView) {
super(containerView.getContext(), new MoreKeysKeyboardParams());
final Keyboard parentKeyboard = parentKeyboardView.getKeyboard();
load(parentKeyboard.mMoreKeysTemplate, parentKeyboard.mId);
@@ -300,14 +305,14 @@ public class MoreKeysKeyboard extends Keyboard {
dividerWidth);
}
- private static int getMaxKeyWidth(KeyboardView view, Key parentKey, int minKeyWidth) {
+ private static int getMaxKeyWidth(final KeyboardView view, final Key parentKey,
+ final int minKeyWidth) {
final int padding = (int)(view.getResources()
.getDimension(R.dimen.more_keys_keyboard_key_horizontal_padding)
+ (parentKey.hasLabelsInMoreKeys() ? minKeyWidth * LABEL_PADDING_RATIO : 0));
final Paint paint = view.newDefaultLabelPaint();
- paint.setTextSize(parentKey.hasLabelsInMoreKeys()
- ? view.mKeyDrawParams.mKeyLabelSize
- : view.mKeyDrawParams.mKeyLetterSize);
+ paint.setTypeface(parentKey.selectTypeface(view.mKeyDrawParams));
+ paint.setTextSize(parentKey.selectMoreKeyTextSize(view.mKeyDrawParams));
int maxWidth = minKeyWidth;
for (final MoreKeySpec spec : parentKey.mMoreKeys) {
final String label = spec.mLabel;
@@ -322,24 +327,6 @@ public class MoreKeysKeyboard extends Keyboard {
return maxWidth;
}
- private static class MoreKeyDivider extends Key.Spacer {
- private final Drawable mIcon;
-
- public MoreKeyDivider(MoreKeysKeyboardParams params, Drawable icon, int x, int y) {
- super(params, x, y, params.mDividerWidth, params.mDefaultRowHeight);
- mIcon = icon;
- }
-
- @Override
- public Drawable getIcon(KeyboardIconsSet iconSet, int alpha) {
- // KeyboardIconsSet and alpha are unused. Use the icon that has been passed to the
- // constructor.
- // TODO: Drawable itself should have an alpha value.
- mIcon.setAlpha(128);
- return mIcon;
- }
- }
-
@Override
public MoreKeysKeyboard build() {
final MoreKeysKeyboardParams params = mParams;
@@ -368,4 +355,23 @@ public class MoreKeysKeyboard extends Keyboard {
return new MoreKeysKeyboard(params);
}
}
+
+ private static class MoreKeyDivider extends Key.Spacer {
+ private final Drawable mIcon;
+
+ public MoreKeyDivider(final MoreKeysKeyboardParams params, final Drawable icon,
+ final int x, final int y) {
+ super(params, x, y, params.mDividerWidth, params.mDefaultRowHeight);
+ mIcon = icon;
+ }
+
+ @Override
+ public Drawable getIcon(final KeyboardIconsSet iconSet, final int alpha) {
+ // KeyboardIconsSet and alpha are unused. Use the icon that has been passed to the
+ // constructor.
+ // TODO: Drawable itself should have an alpha value.
+ mIcon.setAlpha(128);
+ return mIcon;
+ }
+ }
}
diff --git a/java/src/com/android/inputmethod/keyboard/PointerTracker.java b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
index be101cfb0..a6439c46a 100644
--- a/java/src/com/android/inputmethod/keyboard/PointerTracker.java
+++ b/java/src/com/android/inputmethod/keyboard/PointerTracker.java
@@ -80,7 +80,7 @@ public class PointerTracker implements PointerTrackerQueue.Element {
public void invalidateKey(Key key);
public void showKeyPreview(PointerTracker tracker);
public void dismissKeyPreview(PointerTracker tracker);
- public void showGesturePreviewTrail(PointerTracker tracker);
+ public void showGesturePreviewTrail(PointerTracker tracker, boolean isOldestTracker);
}
public interface TimerProxy {
@@ -330,10 +330,10 @@ public class PointerTracker implements PointerTrackerQueue.Element {
final int y) {
final boolean ignoreModifierKey = mIgnoreModifierKey && key.isModifier();
final boolean altersCode = key.altCodeWhileTyping() && mTimerProxy.isTypingState();
- final int code = altersCode ? key.mAltCode : primaryCode;
+ final int code = altersCode ? key.getAltCode() : primaryCode;
if (DEBUG_LISTENER) {
- Log.d(TAG, "onCodeInput: " + Keyboard.printableCode(code) + " text=" + key.mOutputText
- + " x=" + x + " y=" + y
+ Log.d(TAG, "onCodeInput: " + Keyboard.printableCode(code)
+ + " text=" + key.getOutputText() + " x=" + x + " y=" + y
+ " ignoreModifier=" + ignoreModifierKey + " altersCode=" + altersCode
+ " enabled=" + key.isEnabled());
}
@@ -347,7 +347,7 @@ public class PointerTracker implements PointerTrackerQueue.Element {
// Even if the key is disabled, it should respond if it is in the altCodeWhileTyping state.
if (key.isEnabled() || altersCode) {
if (code == Keyboard.CODE_OUTPUT_TEXT) {
- mListener.onTextInput(key.mOutputText);
+ mListener.onTextInput(key.getOutputText());
} else if (code != Keyboard.CODE_UNSPECIFIED) {
mListener.onCodeInput(code, x, y);
}
@@ -440,13 +440,13 @@ public class PointerTracker implements PointerTrackerQueue.Element {
}
if (key.altCodeWhileTyping()) {
- final int altCode = key.mAltCode;
+ final int altCode = key.getAltCode();
final Key altKey = mKeyboard.getKey(altCode);
if (altKey != null) {
updateReleaseKeyGraphics(altKey);
}
for (final Key k : mKeyboard.mAltCodeKeysWhileTyping) {
- if (k != key && k.mAltCode == altCode) {
+ if (k != key && k.getAltCode() == altCode) {
updateReleaseKeyGraphics(k);
}
}
@@ -479,13 +479,13 @@ public class PointerTracker implements PointerTrackerQueue.Element {
}
if (key.altCodeWhileTyping() && mTimerProxy.isTypingState()) {
- final int altCode = key.mAltCode;
+ final int altCode = key.getAltCode();
final Key altKey = mKeyboard.getKey(altCode);
if (altKey != null) {
updatePressKeyGraphics(altKey);
}
for (final Key k : mKeyboard.mAltCodeKeysWhileTyping) {
- if (k != key && k.mAltCode == altCode) {
+ if (k != key && k.getAltCode() == altCode) {
updatePressKeyGraphics(k);
}
}
@@ -545,12 +545,16 @@ public class PointerTracker implements PointerTrackerQueue.Element {
}
private void startBatchInput() {
+ if (sInGesture || !mGestureStrokeWithPreviewTrail.isStartOfAGesture()) {
+ return;
+ }
if (DEBUG_LISTENER) {
Log.d(TAG, "onStartBatchInput");
}
sInGesture = true;
mListener.onStartBatchInput();
- mDrawingProxy.showGesturePreviewTrail(this);
+ final boolean isOldestTracker = sPointerTrackerQueue.getOldestElement() == this;
+ mDrawingProxy.showGesturePreviewTrail(this, isOldestTracker);
}
private void updateBatchInput(final long eventTime) {
@@ -567,12 +571,14 @@ public class PointerTracker implements PointerTrackerQueue.Element {
mListener.onUpdateBatchInput(sAggregratedPointers);
}
}
- mDrawingProxy.showGesturePreviewTrail(this);
+ final boolean isOldestTracker = sPointerTrackerQueue.getOldestElement() == this;
+ mDrawingProxy.showGesturePreviewTrail(this, isOldestTracker);
}
private void endBatchInput() {
synchronized (sAggregratedPointers) {
mGestureStrokeWithPreviewTrail.appendAllBatchPoints(sAggregratedPointers);
+ mGestureStrokeWithPreviewTrail.reset();
if (getActivePointerTrackerCount() == 1) {
if (DEBUG_LISTENER) {
Log.d(TAG, "onEndBatchInput: batchPoints="
@@ -583,7 +589,8 @@ public class PointerTracker implements PointerTrackerQueue.Element {
clearBatchInputPointsOfAllPointerTrackers();
}
}
- mDrawingProxy.showGesturePreviewTrail(this);
+ final boolean isOldestTracker = sPointerTrackerQueue.getOldestElement() == this;
+ mDrawingProxy.showGesturePreviewTrail(this, isOldestTracker);
}
private static void abortBatchInput() {
@@ -719,12 +726,8 @@ public class PointerTracker implements PointerTrackerQueue.Element {
final boolean isHistorical, final Key key) {
final int gestureTime = (int)(eventTime - sGestureFirstDownTime);
if (mIsDetectingGesture) {
- final GestureStroke stroke = mGestureStrokeWithPreviewTrail;
- stroke.addPoint(x, y, gestureTime, isHistorical);
- if (!sInGesture && stroke.isStartOfAGesture()) {
- startBatchInput();
- }
-
+ mGestureStrokeWithPreviewTrail.addPoint(x, y, gestureTime, isHistorical);
+ startBatchInput();
if (sInGesture && key != null) {
updateBatchInput(eventTime);
}
diff --git a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java
index 71bf31faa..e1b082c16 100644
--- a/java/src/com/android/inputmethod/keyboard/ProximityInfo.java
+++ b/java/src/com/android/inputmethod/keyboard/ProximityInfo.java
@@ -19,7 +19,7 @@ package com.android.inputmethod.keyboard;
import android.graphics.Rect;
import android.text.TextUtils;
-import com.android.inputmethod.keyboard.Keyboard.Params.TouchPositionCorrection;
+import com.android.inputmethod.keyboard.internal.TouchPositionCorrection;
import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.JniUtils;
@@ -48,9 +48,10 @@ public class ProximityInfo {
private final Key[][] mGridNeighbors;
private final String mLocaleStr;
- ProximityInfo(String localeStr, int gridWidth, int gridHeight, int minWidth, int height,
- int mostCommonKeyWidth, int mostCommonKeyHeight, final Key[] keys,
- TouchPositionCorrection touchPositionCorrection) {
+ ProximityInfo(final String localeStr, final int gridWidth, final int gridHeight,
+ final int minWidth, final int height, final int mostCommonKeyWidth,
+ final int mostCommonKeyHeight, final Key[] keys,
+ final TouchPositionCorrection touchPositionCorrection) {
if (TextUtils.isEmpty(localeStr)) {
mLocaleStr = "";
} else {
@@ -81,7 +82,7 @@ public class ProximityInfo {
}
public static ProximityInfo createSpellCheckerProximityInfo(final int[] proximity,
- int rowSize, int gridWidth, int gridHeight) {
+ final int rowSize, final int gridWidth, final int gridHeight) {
final ProximityInfo spellCheckerProximityInfo = createDummyProximityInfo();
spellCheckerProximityInfo.mNativeProximityInfo =
spellCheckerProximityInfo.setProximityInfoNative("",
diff --git a/java/src/com/android/inputmethod/keyboard/ViewLayoutUtils.java b/java/src/com/android/inputmethod/keyboard/ViewLayoutUtils.java
index ee5047083..dc12fa468 100644
--- a/java/src/com/android/inputmethod/keyboard/ViewLayoutUtils.java
+++ b/java/src/com/android/inputmethod/keyboard/ViewLayoutUtils.java
@@ -22,7 +22,7 @@ import android.view.ViewGroup.MarginLayoutParams;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;
-public class ViewLayoutUtils {
+public final class ViewLayoutUtils {
private ViewLayoutUtils() {
// This utility class is not publicly instantiable.
}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/GesturePreviewTrail.java b/java/src/com/android/inputmethod/keyboard/internal/GesturePreviewTrail.java
index e814d8009..4311fa775 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/GesturePreviewTrail.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/GesturePreviewTrail.java
@@ -17,44 +17,53 @@ package com.android.inputmethod.keyboard.internal;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
+import android.graphics.Rect;
import android.os.SystemClock;
import com.android.inputmethod.latin.Constants;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.ResizableIntArray;
-class GesturePreviewTrail {
+final class GesturePreviewTrail {
private static final int DEFAULT_CAPACITY = GestureStrokeWithPreviewTrail.PREVIEW_CAPACITY;
- private final GesturePreviewTrailParams mPreviewParams;
private final ResizableIntArray mXCoordinates = new ResizableIntArray(DEFAULT_CAPACITY);
private final ResizableIntArray mYCoordinates = new ResizableIntArray(DEFAULT_CAPACITY);
private final ResizableIntArray mEventTimes = new ResizableIntArray(DEFAULT_CAPACITY);
private int mCurrentStrokeId = -1;
- private long mCurrentDownTime;
+ // The wall time of the zero value in {@link #mEventTimes}
+ private long mCurrentTimeBase;
private int mTrailStartIndex;
- // Use this value as imaginary zero because x-coordinates may be zero.
- private static final int DOWN_EVENT_MARKER = -128;
-
- static class GesturePreviewTrailParams {
+ static final class Params {
+ public final int mTrailColor;
+ public final float mTrailStartWidth;
+ public final float mTrailEndWidth;
public final int mFadeoutStartDelay;
public final int mFadeoutDuration;
public final int mUpdateInterval;
- public GesturePreviewTrailParams(final TypedArray keyboardViewAttr) {
+ public final int mTrailLingerDuration;
+
+ public Params(final TypedArray keyboardViewAttr) {
+ mTrailColor = keyboardViewAttr.getColor(
+ R.styleable.KeyboardView_gesturePreviewTrailColor, 0);
+ mTrailStartWidth = keyboardViewAttr.getDimension(
+ R.styleable.KeyboardView_gesturePreviewTrailStartWidth, 0.0f);
+ mTrailEndWidth = keyboardViewAttr.getDimension(
+ R.styleable.KeyboardView_gesturePreviewTrailEndWidth, 0.0f);
mFadeoutStartDelay = keyboardViewAttr.getInt(
R.styleable.KeyboardView_gesturePreviewTrailFadeoutStartDelay, 0);
mFadeoutDuration = keyboardViewAttr.getInt(
R.styleable.KeyboardView_gesturePreviewTrailFadeoutDuration, 0);
+ mTrailLingerDuration = mFadeoutStartDelay + mFadeoutDuration;
mUpdateInterval = keyboardViewAttr.getInt(
R.styleable.KeyboardView_gesturePreviewTrailUpdateInterval, 0);
}
}
- public GesturePreviewTrail(final GesturePreviewTrailParams params) {
- mPreviewParams = params;
- }
+ // Use this value as imaginary zero because x-coordinates may be zero.
+ private static final int DOWN_EVENT_MARKER = -128;
private static int markAsDownEvent(final int xCoord) {
return DOWN_EVENT_MARKER - xCoord;
@@ -70,47 +79,53 @@ class GesturePreviewTrail {
}
public void addStroke(final GestureStrokeWithPreviewTrail stroke, final long downTime) {
- final int strokeId = stroke.getGestureStrokeId();
- final boolean isNewStroke = strokeId != mCurrentStrokeId;
final int trailSize = mEventTimes.getLength();
stroke.appendPreviewStroke(mEventTimes, mXCoordinates, mYCoordinates);
- final int newTrailSize = mEventTimes.getLength();
- if (stroke.getGestureStrokePreviewSize() == 0) {
+ if (mEventTimes.getLength() == trailSize) {
return;
}
- if (isNewStroke) {
- final int elapsedTime = (int)(downTime - mCurrentDownTime);
- final int[] eventTimes = mEventTimes.getPrimitiveArray();
+ final int[] eventTimes = mEventTimes.getPrimitiveArray();
+ final int strokeId = stroke.getGestureStrokeId();
+ if (strokeId != mCurrentStrokeId) {
+ final int elapsedTime = (int)(downTime - mCurrentTimeBase);
for (int i = mTrailStartIndex; i < trailSize; i++) {
+ // Decay the previous strokes' event times.
eventTimes[i] -= elapsedTime;
}
-
- if (newTrailSize > trailSize) {
- final int[] xCoords = mXCoordinates.getPrimitiveArray();
- xCoords[trailSize] = markAsDownEvent(xCoords[trailSize]);
- }
- mCurrentDownTime = downTime;
+ final int[] xCoords = mXCoordinates.getPrimitiveArray();
+ final int downIndex = trailSize;
+ xCoords[downIndex] = markAsDownEvent(xCoords[downIndex]);
+ mCurrentTimeBase = downTime - eventTimes[downIndex];
mCurrentStrokeId = strokeId;
}
}
- private int getAlpha(final int elapsedTime) {
- if (elapsedTime < mPreviewParams.mFadeoutStartDelay) {
+ private static int getAlpha(final int elapsedTime, final Params params) {
+ if (elapsedTime < params.mFadeoutStartDelay) {
return Constants.Color.ALPHA_OPAQUE;
}
final int decreasingAlpha = Constants.Color.ALPHA_OPAQUE
- * (elapsedTime - mPreviewParams.mFadeoutStartDelay)
- / mPreviewParams.mFadeoutDuration;
+ * (elapsedTime - params.mFadeoutStartDelay)
+ / params.mFadeoutDuration;
return Constants.Color.ALPHA_OPAQUE - decreasingAlpha;
}
+ private static float getWidth(final int elapsedTime, final Params params) {
+ return Math.max((params.mTrailLingerDuration - elapsedTime)
+ * (params.mTrailStartWidth - params.mTrailEndWidth)
+ / params.mTrailLingerDuration, 0.0f);
+ }
+
/**
* Draw gesture preview trail
* @param canvas The canvas to draw the gesture preview trail
* @param paint The paint object to be used to draw the gesture preview trail
+ * @param outBoundsRect the bounding box of this gesture trail drawing
+ * @param params The drawing parameters of gesture preview trail
* @return true if some gesture preview trails remain to be drawn
*/
- public boolean drawGestureTrail(final Canvas canvas, final Paint paint) {
+ public boolean drawGestureTrail(final Canvas canvas, final Paint paint,
+ final Rect outBoundsRect, final Params params) {
final int trailSize = mEventTimes.getLength();
if (trailSize == 0) {
return false;
@@ -119,34 +134,47 @@ class GesturePreviewTrail {
final int[] eventTimes = mEventTimes.getPrimitiveArray();
final int[] xCoords = mXCoordinates.getPrimitiveArray();
final int[] yCoords = mYCoordinates.getPrimitiveArray();
- final int sinceDown = (int)(SystemClock.uptimeMillis() - mCurrentDownTime);
- final int lingeringDuration = mPreviewParams.mFadeoutStartDelay
- + mPreviewParams.mFadeoutDuration;
+ final int sinceDown = (int)(SystemClock.uptimeMillis() - mCurrentTimeBase);
int startIndex;
for (startIndex = mTrailStartIndex; startIndex < trailSize; startIndex++) {
final int elapsedTime = sinceDown - eventTimes[startIndex];
// Skip too old trail points.
- if (elapsedTime < lingeringDuration) {
+ if (elapsedTime < params.mTrailLingerDuration) {
break;
}
}
mTrailStartIndex = startIndex;
if (startIndex < trailSize) {
+ paint.setColor(params.mTrailColor);
+ paint.setStyle(Paint.Style.STROKE);
+ paint.setStrokeCap(Paint.Cap.ROUND);
int lastX = getXCoordValue(xCoords[startIndex]);
int lastY = yCoords[startIndex];
+ float maxWidth = getWidth(sinceDown - eventTimes[startIndex], params);
+ // Initialize bounds rectangle.
+ outBoundsRect.set(lastX, lastY, lastX, lastY);
for (int i = startIndex + 1; i < trailSize - 1; i++) {
final int x = xCoords[i];
final int y = yCoords[i];
final int elapsedTime = sinceDown - eventTimes[i];
// Draw trail line only when the current point isn't a down point.
if (!isDownEventXCoord(x)) {
- paint.setAlpha(getAlpha(elapsedTime));
+ final int alpha = getAlpha(elapsedTime, params);
+ paint.setAlpha(alpha);
+ final float width = getWidth(elapsedTime, params);
+ paint.setStrokeWidth(width);
canvas.drawLine(lastX, lastY, x, y, paint);
+ // Take union for the bounds.
+ outBoundsRect.union(x, y);
+ maxWidth = Math.max(maxWidth, width);
}
lastX = getXCoordValue(x);
lastY = y;
}
+ // Take care of trail line width.
+ final int inset = -((int)maxWidth + 1);
+ outBoundsRect.inset(inset, inset);
}
final int newSize = trailSize - startIndex;
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyDrawParams.java b/java/src/com/android/inputmethod/keyboard/internal/KeyDrawParams.java
new file mode 100644
index 000000000..5dcd842f7
--- /dev/null
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyDrawParams.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2012 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.internal;
+
+import android.graphics.Typeface;
+
+import com.android.inputmethod.latin.ResourceUtils;
+
+public final class KeyDrawParams {
+ public Typeface mTypeface;
+
+ public int mLetterSize;
+ public int mLabelSize;
+ public int mLargeLetterSize;
+ public int mLargeLabelSize;
+ public int mHintLetterSize;
+ public int mShiftedLetterHintSize;
+ public int mHintLabelSize;
+ public int mPreviewTextSize;
+
+ public int mTextColor;
+ public int mTextInactivatedColor;
+ public int mTextShadowColor;
+ public int mHintLetterColor;
+ public int mHintLabelColor;
+ public int mShiftedLetterHintInactivatedColor;
+ public int mShiftedLetterHintActivatedColor;
+ public int mPreviewTextColor;
+
+ public int mAnimAlpha;
+
+ public KeyDrawParams() {}
+
+ private KeyDrawParams(final KeyDrawParams copyFrom) {
+ mTypeface = copyFrom.mTypeface;
+
+ mLetterSize = copyFrom.mLetterSize;
+ mLabelSize = copyFrom.mLabelSize;
+ mLargeLetterSize = copyFrom.mLargeLetterSize;
+ mLargeLabelSize = copyFrom.mLargeLabelSize;
+ mHintLetterSize = copyFrom.mHintLetterSize;
+ mShiftedLetterHintSize = copyFrom.mShiftedLetterHintSize;
+ mHintLabelSize = copyFrom.mHintLabelSize;
+ mPreviewTextSize = copyFrom.mPreviewTextSize;
+
+ mTextColor = copyFrom.mTextColor;
+ mTextInactivatedColor = copyFrom.mTextInactivatedColor;
+ mTextShadowColor = copyFrom.mTextShadowColor;
+ mHintLetterColor = copyFrom.mHintLetterColor;
+ mHintLabelColor = copyFrom.mHintLabelColor;
+ mShiftedLetterHintInactivatedColor = copyFrom.mShiftedLetterHintInactivatedColor;
+ mShiftedLetterHintActivatedColor = copyFrom.mShiftedLetterHintActivatedColor;
+ mPreviewTextColor = copyFrom.mPreviewTextColor;
+
+ mAnimAlpha = copyFrom.mAnimAlpha;
+ }
+
+ public void updateParams(final int keyHeight, final KeyVisualAttributes attr) {
+ if (attr == null) {
+ return;
+ }
+
+ if (attr.mTypeface != null) {
+ mTypeface = attr.mTypeface;
+ }
+
+ mLetterSize = selectTextSizeFromDimensionOrRatio(keyHeight,
+ attr.mLetterSize, attr.mLetterRatio, mLetterSize);
+ mLabelSize = selectTextSizeFromDimensionOrRatio(keyHeight,
+ attr.mLabelSize, attr.mLabelRatio, mLabelSize);
+ mLargeLabelSize = selectTextSize(keyHeight, attr.mLargeLabelRatio, mLargeLabelSize);
+ mLargeLetterSize = selectTextSize(keyHeight, attr.mLargeLetterRatio, mLargeLetterSize);
+ mHintLetterSize = selectTextSize(keyHeight, attr.mHintLetterRatio, mHintLetterSize);
+ mShiftedLetterHintSize = selectTextSize(keyHeight,
+ attr.mShiftedLetterHintRatio, mShiftedLetterHintSize);
+ mHintLabelSize = selectTextSize(keyHeight, attr.mHintLabelRatio, mHintLabelSize);
+ mPreviewTextSize = selectTextSize(keyHeight, attr.mPreviewTextRatio, mPreviewTextSize);
+
+ mTextColor = selectColor(attr.mTextColor, mTextColor);
+ mTextInactivatedColor = selectColor(attr.mTextInactivatedColor, mTextInactivatedColor);
+ mTextShadowColor = selectColor(attr.mTextShadowColor, mTextShadowColor);
+ mHintLetterColor = selectColor(attr.mHintLetterColor, mHintLetterColor);
+ mHintLabelColor = selectColor(attr.mHintLabelColor, mHintLabelColor);
+ mShiftedLetterHintInactivatedColor = selectColor(
+ attr.mShiftedLetterHintInactivatedColor, mShiftedLetterHintInactivatedColor);
+ mShiftedLetterHintActivatedColor = selectColor(
+ attr.mShiftedLetterHintActivatedColor, mShiftedLetterHintActivatedColor);
+ mPreviewTextColor = selectColor(attr.mPreviewTextColor, mPreviewTextColor);
+ }
+
+ public KeyDrawParams mayCloneAndUpdateParams(final int keyHeight,
+ final KeyVisualAttributes attr) {
+ if (attr == null) {
+ return this;
+ }
+ final KeyDrawParams newParams = new KeyDrawParams(this);
+ newParams.updateParams(keyHeight, attr);
+ return newParams;
+ }
+
+ private static final int selectTextSizeFromDimensionOrRatio(final int keyHeight,
+ final int dimens, final float ratio, final int defaultDimens) {
+ if (ResourceUtils.isValidDimensionPixelSize(dimens)) {
+ return dimens;
+ }
+ if (ResourceUtils.isValidFraction(ratio)) {
+ return (int)(keyHeight * ratio);
+ }
+ return defaultDimens;
+ }
+
+ private static final int selectTextSize(final int keyHeight, final float ratio,
+ final int defaultSize) {
+ if (ResourceUtils.isValidFraction(ratio)) {
+ return (int)(keyHeight * ratio);
+ }
+ return defaultSize;
+ }
+
+ private static final int selectColor(final int attrColor, final int defaultColor) {
+ if (attrColor != 0) {
+ return attrColor;
+ }
+ return defaultColor;
+ }
+}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyPreviewDrawParams.java b/java/src/com/android/inputmethod/keyboard/internal/KeyPreviewDrawParams.java
new file mode 100644
index 000000000..609d1a57f
--- /dev/null
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyPreviewDrawParams.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2012 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.internal;
+
+public final class KeyPreviewDrawParams {
+ // The graphical geometry of the key preview.
+ // <-width->
+ // +-------+ ^
+ // | | |
+ // |preview| height (visible)
+ // | | |
+ // + + ^ v
+ // \ / |offset
+ // +-\ /-+ v
+ // | +-+ |
+ // |parent |
+ // | key|
+ // +-------+
+ // The background of a {@link TextView} being used for a key preview may have invisible
+ // paddings. To align the more keys keyboard panel's visible part with the visible part of
+ // the background, we need to record the width and height of key preview that don't include
+ // invisible paddings.
+ public int mPreviewVisibleWidth;
+ public int mPreviewVisibleHeight;
+ // The key preview may have an arbitrary offset and its background that may have a bottom
+ // padding. To align the more keys keyboard and the key preview we also need to record the
+ // offset between the top edge of parent key and the bottom of the visible part of key
+ // preview background.
+ public int mPreviewVisibleOffset;
+}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java b/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java
index 13214bb9f..2a57caa5f 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java
@@ -56,59 +56,20 @@ public class KeySpecParser {
private static final char ESCAPE_CHAR = '\\';
private static final char LABEL_END = '|';
private static final String PREFIX_TEXT = "!text/";
- private static final String PREFIX_ICON = "!icon/";
+ static final String PREFIX_ICON = "!icon/";
private static final String PREFIX_CODE = "!code/";
private static final String PREFIX_HEX = "0x";
private static final String ADDITIONAL_MORE_KEY_MARKER = "%";
- public static class MoreKeySpec {
- public final int mCode;
- public final String mLabel;
- public final String mOutputText;
- public final int mIconId;
-
- public MoreKeySpec(final String moreKeySpec, boolean needsToUpperCase, Locale locale,
- final KeyboardCodesSet codesSet) {
- mLabel = toUpperCaseOfStringForLocale(getLabel(moreKeySpec),
- needsToUpperCase, locale);
- final int code = toUpperCaseOfCodeForLocale(getCode(moreKeySpec, codesSet),
- needsToUpperCase, locale);
- if (code == Keyboard.CODE_UNSPECIFIED) {
- // Some letter, for example German Eszett (U+00DF: "ß"), has multiple characters
- // upper case representation ("SS").
- mCode = Keyboard.CODE_OUTPUT_TEXT;
- mOutputText = mLabel;
- } else {
- mCode = code;
- mOutputText = toUpperCaseOfStringForLocale(getOutputText(moreKeySpec),
- needsToUpperCase, locale);
- }
- mIconId = getIconId(moreKeySpec);
- }
-
- @Override
- public String toString() {
- final String label = (mIconId == KeyboardIconsSet.ICON_UNDEFINED ? mLabel
- : PREFIX_ICON + KeyboardIconsSet.getIconName(mIconId));
- final String output = (mCode == Keyboard.CODE_OUTPUT_TEXT ? mOutputText
- : Keyboard.printableCode(mCode));
- if (StringUtils.codePointCount(label) == 1 && label.codePointAt(0) == mCode) {
- return output;
- } else {
- return label + "|" + output;
- }
- }
- }
-
private KeySpecParser() {
// Intentional empty constructor for utility class.
}
- private static boolean hasIcon(String moreKeySpec) {
+ private static boolean hasIcon(final String moreKeySpec) {
return moreKeySpec.startsWith(PREFIX_ICON);
}
- private static boolean hasCode(String moreKeySpec) {
+ private static boolean hasCode(final String moreKeySpec) {
final int end = indexOfLabelEnd(moreKeySpec, 0);
if (end > 0 && end + 1 < moreKeySpec.length() && moreKeySpec.startsWith(
PREFIX_CODE, end + 1)) {
@@ -117,7 +78,7 @@ public class KeySpecParser {
return false;
}
- private static String parseEscape(String text) {
+ private static String parseEscape(final String text) {
if (text.indexOf(ESCAPE_CHAR) < 0) {
return text;
}
@@ -136,7 +97,7 @@ public class KeySpecParser {
return sb.toString();
}
- private static int indexOfLabelEnd(String moreKeySpec, int start) {
+ private static int indexOfLabelEnd(final String moreKeySpec, final int start) {
if (moreKeySpec.indexOf(ESCAPE_CHAR, start) < 0) {
final int end = moreKeySpec.indexOf(LABEL_END, start);
if (end == 0) {
@@ -157,7 +118,7 @@ public class KeySpecParser {
return -1;
}
- public static String getLabel(String moreKeySpec) {
+ public static String getLabel(final String moreKeySpec) {
if (hasIcon(moreKeySpec)) {
return null;
}
@@ -170,7 +131,7 @@ public class KeySpecParser {
return label;
}
- private static String getOutputTextInternal(String moreKeySpec) {
+ private static String getOutputTextInternal(final String moreKeySpec) {
final int end = indexOfLabelEnd(moreKeySpec, 0);
if (end <= 0) {
return null;
@@ -181,7 +142,7 @@ public class KeySpecParser {
return parseEscape(moreKeySpec.substring(end + /* LABEL_END */1));
}
- static String getOutputText(String moreKeySpec) {
+ static String getOutputText(final String moreKeySpec) {
if (hasCode(moreKeySpec)) {
return null;
}
@@ -205,7 +166,7 @@ public class KeySpecParser {
return (StringUtils.codePointCount(label) == 1) ? null : label;
}
- static int getCode(String moreKeySpec, KeyboardCodesSet codesSet) {
+ static int getCode(final String moreKeySpec, final KeyboardCodesSet codesSet) {
if (hasCode(moreKeySpec)) {
final int end = indexOfLabelEnd(moreKeySpec, 0);
if (indexOfLabelEnd(moreKeySpec, end + 1) >= 0) {
@@ -230,7 +191,8 @@ public class KeySpecParser {
return Keyboard.CODE_OUTPUT_TEXT;
}
- public static int parseCode(String text, KeyboardCodesSet codesSet, int defCode) {
+ public static int parseCode(final String text, final KeyboardCodesSet codesSet,
+ final int defCode) {
if (text == null) return defCode;
if (text.startsWith(PREFIX_CODE)) {
return codesSet.getCode(text.substring(PREFIX_CODE.length()));
@@ -241,7 +203,7 @@ public class KeySpecParser {
}
}
- public static int getIconId(String moreKeySpec) {
+ public static int getIconId(final String moreKeySpec) {
if (moreKeySpec != null && hasIcon(moreKeySpec)) {
final int end = moreKeySpec.indexOf(LABEL_END, PREFIX_ICON.length());
final String name = (end < 0) ? moreKeySpec.substring(PREFIX_ICON.length())
@@ -251,7 +213,7 @@ public class KeySpecParser {
return KeyboardIconsSet.ICON_UNDEFINED;
}
- private static ArrayList arrayAsList(T[] array, int start, int end) {
+ private static ArrayList arrayAsList(final T[] array, final int start, final int end) {
if (array == null) {
throw new NullPointerException();
}
@@ -268,7 +230,7 @@ public class KeySpecParser {
private static final String[] EMPTY_STRING_ARRAY = new String[0];
- private static String[] filterOutEmptyString(String[] array) {
+ private static String[] filterOutEmptyString(final String[] array) {
if (array == null) {
return EMPTY_STRING_ARRAY;
}
@@ -289,8 +251,8 @@ public class KeySpecParser {
return out.toArray(new String[out.size()]);
}
- public static String[] insertAdditionalMoreKeys(String[] moreKeySpecs,
- String[] additionalMoreKeySpecs) {
+ public static String[] insertAdditionalMoreKeys(final String[] moreKeySpecs,
+ final String[] additionalMoreKeySpecs) {
final String[] moreKeys = filterOutEmptyString(moreKeySpecs);
final String[] additionalMoreKeys = filterOutEmptyString(additionalMoreKeySpecs);
final int moreKeysCount = moreKeys.length;
@@ -357,12 +319,13 @@ public class KeySpecParser {
@SuppressWarnings("serial")
public static class KeySpecParserError extends RuntimeException {
- public KeySpecParserError(String message) {
+ public KeySpecParserError(final String message) {
super(message);
}
}
- public static String resolveTextReference(String rawText, KeyboardTextsSet textsSet) {
+ public static String resolveTextReference(final String rawText,
+ final KeyboardTextsSet textsSet) {
int level = 0;
String text = rawText;
StringBuilder sb;
@@ -408,7 +371,7 @@ public class KeySpecParser {
return text;
}
- private static int searchTextNameEnd(String text, int start) {
+ private static int searchTextNameEnd(final String text, final int start) {
final int size = text.length();
for (int pos = start; pos < size; pos++) {
final char c = text.charAt(pos);
@@ -421,7 +384,7 @@ public class KeySpecParser {
return size;
}
- public static String[] parseCsvString(String rawText, KeyboardTextsSet textsSet) {
+ public static String[] parseCsvString(final String rawText, final KeyboardTextsSet textsSet) {
final String text = resolveTextReference(rawText, textsSet);
final int size = text.length();
if (size == 0) {
@@ -460,7 +423,8 @@ public class KeySpecParser {
return list.toArray(new String[list.size()]);
}
- public static int getIntValue(String[] moreKeys, String key, int defaultValue) {
+ public static int getIntValue(final String[] moreKeys, final String key,
+ final int defaultValue) {
if (moreKeys == null) {
return defaultValue;
}
@@ -486,7 +450,7 @@ public class KeySpecParser {
return value;
}
- public static boolean getBooleanValue(String[] moreKeys, String key) {
+ public static boolean getBooleanValue(final String[] moreKeys, final String key) {
if (moreKeys == null) {
return false;
}
@@ -502,8 +466,8 @@ public class KeySpecParser {
return value;
}
- public static int toUpperCaseOfCodeForLocale(int code, boolean needsToUpperCase,
- Locale locale) {
+ public static int toUpperCaseOfCodeForLocale(final int code, final boolean needsToUpperCase,
+ final Locale locale) {
if (!Keyboard.isLetterCode(code) || !needsToUpperCase) return code;
final String text = new String(new int[] { code } , 0, 1);
final String casedText = KeySpecParser.toUpperCaseOfStringForLocale(
@@ -512,8 +476,8 @@ public class KeySpecParser {
? casedText.codePointAt(0) : CODE_UNSPECIFIED;
}
- public static String toUpperCaseOfStringForLocale(String text, boolean needsToUpperCase,
- Locale locale) {
+ public static String toUpperCaseOfStringForLocale(final String text,
+ final boolean needsToUpperCase, final Locale locale) {
if (text == null || !needsToUpperCase) return text;
return text.toUpperCase(locale);
}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyStyle.java b/java/src/com/android/inputmethod/keyboard/internal/KeyStyle.java
new file mode 100644
index 000000000..e8cacf9e7
--- /dev/null
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyStyle.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2012 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.internal;
+
+import android.content.res.TypedArray;
+
+public abstract class KeyStyle {
+ private final KeyboardTextsSet mTextsSet;
+
+ public abstract String[] getStringArray(TypedArray a, int index);
+ public abstract String getString(TypedArray a, int index);
+ public abstract int getInt(TypedArray a, int index, int defaultValue);
+ public abstract int getFlag(TypedArray a, int index);
+
+ protected KeyStyle(final KeyboardTextsSet textsSet) {
+ mTextsSet = textsSet;
+ }
+
+ protected String parseString(final TypedArray a, final int index) {
+ if (a.hasValue(index)) {
+ return KeySpecParser.resolveTextReference(a.getString(index), mTextsSet);
+ }
+ return null;
+ }
+
+ protected String[] parseStringArray(final TypedArray a, final int index) {
+ if (a.hasValue(index)) {
+ return KeySpecParser.parseCsvString(a.getString(index), mTextsSet);
+ }
+ return null;
+ }
+}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java b/java/src/com/android/inputmethod/keyboard/internal/KeyStylesSet.java
similarity index 73%
rename from java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java
rename to java/src/com/android/inputmethod/keyboard/internal/KeyStylesSet.java
index e40cf45cc..71fd30563 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeyStyles.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeyStylesSet.java
@@ -20,7 +20,6 @@ import android.content.res.TypedArray;
import android.util.Log;
import android.util.SparseArray;
-import com.android.inputmethod.keyboard.Keyboard;
import com.android.inputmethod.latin.CollectionUtils;
import com.android.inputmethod.latin.R;
import com.android.inputmethod.latin.XmlParseUtils;
@@ -30,75 +29,62 @@ import org.xmlpull.v1.XmlPullParserException;
import java.util.HashMap;
-public class KeyStyles {
- private static final String TAG = KeyStyles.class.getSimpleName();
+public class KeyStylesSet {
+ private static final String TAG = KeyStylesSet.class.getSimpleName();
private static final boolean DEBUG = false;
- final HashMap mStyles = CollectionUtils.newHashMap();
+ private final HashMap mStyles = CollectionUtils.newHashMap();
- final KeyboardTextsSet mTextsSet;
+ private final KeyboardTextsSet mTextsSet;
private final KeyStyle mEmptyKeyStyle;
private static final String EMPTY_STYLE_NAME = "";
- public KeyStyles(KeyboardTextsSet textsSet) {
+ public KeyStylesSet(final KeyboardTextsSet textsSet) {
mTextsSet = textsSet;
- mEmptyKeyStyle = new EmptyKeyStyle();
+ mEmptyKeyStyle = new EmptyKeyStyle(textsSet);
mStyles.put(EMPTY_STYLE_NAME, mEmptyKeyStyle);
}
- public abstract class KeyStyle {
- public abstract String[] getStringArray(TypedArray a, int index);
- public abstract String getString(TypedArray a, int index);
- public abstract int getInt(TypedArray a, int index, int defaultValue);
- public abstract int getFlag(TypedArray a, int index);
-
- protected String parseString(TypedArray a, int index) {
- if (a.hasValue(index)) {
- return KeySpecParser.resolveTextReference(a.getString(index), mTextsSet);
- }
- return null;
+ private static class EmptyKeyStyle extends KeyStyle {
+ EmptyKeyStyle(final KeyboardTextsSet textsSet) {
+ super(textsSet);
}
- protected String[] parseStringArray(TypedArray a, int index) {
- if (a.hasValue(index)) {
- return KeySpecParser.parseCsvString(a.getString(index), mTextsSet);
- }
- return null;
- }
- }
-
- class EmptyKeyStyle extends KeyStyle {
@Override
- public String[] getStringArray(TypedArray a, int index) {
+ public String[] getStringArray(final TypedArray a, final int index) {
return parseStringArray(a, index);
}
@Override
- public String getString(TypedArray a, int index) {
+ public String getString(final TypedArray a, final int index) {
return parseString(a, index);
}
@Override
- public int getInt(TypedArray a, int index, int defaultValue) {
+ public int getInt(final TypedArray a, final int index, final int defaultValue) {
return a.getInt(index, defaultValue);
}
@Override
- public int getFlag(TypedArray a, int index) {
+ public int getFlag(final TypedArray a, final int index) {
return a.getInt(index, 0);
}
}
- private class DeclaredKeyStyle extends KeyStyle {
+ private static class DeclaredKeyStyle extends KeyStyle {
+ private final HashMap mStyles;
private final String mParentStyleName;
private final SparseArray