diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java index f839376c0..8c71237f6 100644 --- a/java/src/com/android/inputmethod/keyboard/Key.java +++ b/java/src/com/android/inputmethod/keyboard/Key.java @@ -103,11 +103,12 @@ public class Key { public final CharSequence mOutputText; /** More keys */ public final String[] mMoreKeys; - /** More keys maximum column number */ - public final int mMaxMoreKeysColumn; - public static final int MORE_KEYS_FIXED_COLUMN_ORDER = 0x80000000; - private static final String AUTO_COLUMN_ORDER = "!autoColumnOrder!"; - private static final String FIXED_COLUMN_ORDER = "!fixedColumnOrder!"; + /** More keys column number and flags */ + private final int mMoreKeysColumnAndFlags; + private static final int MORE_KEYS_COLUMN_MASK = 0x000000ff; + private static final int MORE_KEYS_FLAGS_FIXED_COLUMN_ORDER = 0x80000000; + private static final String MORE_KEYS_AUTO_COLUMN_ORDER = "!autoColumnOrder!"; + private static final String MORE_KEYS_FIXED_COLUMN_ORDER = "!fixedColumnOrder!"; /** Background type that represents different key background visual than normal one. */ public final int mBackgroundType; @@ -146,7 +147,7 @@ public class Key { * This constructor is being used only for key in popup suggestions pane. */ public Key(Keyboard.Params params, String label, String hintLabel, int iconId, - int code, CharSequence outputText, int x, int y, int width, int height) { + int code, String outputText, int x, int y, int width, int height) { mHeight = height - params.mVerticalGap; mHorizontalGap = params.mHorizontalGap; mVerticalGap = params.mVerticalGap; @@ -157,7 +158,7 @@ public class Key { mBackgroundType = BACKGROUND_TYPE_NORMAL; mActionFlags = 0; mMoreKeys = null; - mMaxMoreKeysColumn = 0; + mMoreKeysColumnAndFlags = 0; mLabel = label; mOutputText = outputText; mCode = code; @@ -236,15 +237,18 @@ public class Key { final boolean preserveCase = (mLabelFlags & LABEL_FLAGS_PRESERVE_CASE) != 0; int actionFlags = style.getFlag(keyAttr, R.styleable.Keyboard_Key_keyActionFlags); String[] moreKeys = style.getStringArray(keyAttr, R.styleable.Keyboard_Key_moreKeys); - int column; - if ((column = parseMoreKeysColumnOrder(moreKeys, AUTO_COLUMN_ORDER)) > 0) { - mMaxMoreKeysColumn = column; - } else if ((column = parseMoreKeysColumnOrder(moreKeys, FIXED_COLUMN_ORDER)) > 0) { - mMaxMoreKeysColumn = column | MORE_KEYS_FIXED_COLUMN_ORDER; - } else { - mMaxMoreKeysColumn = style.getInt(keyAttr, + + int moreKeysColumn = style.getInt(keyAttr, R.styleable.Keyboard_Key_maxMoreKeysColumn, params.mMaxMoreKeysKeyboardColumn); + int value; + if ((value = KeySpecParser.getIntValue(moreKeys, MORE_KEYS_AUTO_COLUMN_ORDER, -1)) > 0) { + moreKeysColumn = value & MORE_KEYS_COLUMN_MASK; } + if ((value = KeySpecParser.getIntValue(moreKeys, MORE_KEYS_FIXED_COLUMN_ORDER, -1)) > 0) { + moreKeysColumn = MORE_KEYS_FLAGS_FIXED_COLUMN_ORDER | (value & MORE_KEYS_COLUMN_MASK); + } + mMoreKeysColumnAndFlags = moreKeysColumn; + final String[] additionalMoreKeys = style.getStringArray( keyAttr, R.styleable.Keyboard_Key_additionalMoreKeys); moreKeys = KeySpecParser.insertAddtionalMoreKeys(moreKeys, additionalMoreKeys); @@ -311,21 +315,6 @@ public class Key { } } - private static int parseMoreKeysColumnOrder(String[] moreKeys, String key) { - if (moreKeys == null || moreKeys.length == 0 || moreKeys[0] == null - || !moreKeys[0].startsWith(key)) { - return -1; - } - try { - final int column = Integer.parseInt(moreKeys[0].substring(key.length())); - moreKeys[0] = null; - return column; - } catch (NumberFormatException e) { - Log.w(TAG, "column number should follow after " + key); - return 0; - } - } - private static int adjustCaseOfCodeForKeyboardId(int code, boolean preserveCase, KeyboardId id) { if (!Keyboard.isLetterCode(code) || preserveCase) return code; @@ -532,6 +521,14 @@ public class Key { return (mLabelFlags & LABEL_FLAGS_SHIFTED_LETTER_ACTIVATED) != 0; } + public int getMoreKeysColumn() { + return mMoreKeysColumnAndFlags & MORE_KEYS_COLUMN_MASK; + } + + public boolean isFixedColumnOrderMoreKeys() { + return (mMoreKeysColumnAndFlags & MORE_KEYS_FLAGS_FIXED_COLUMN_ORDER) != 0; + } + public Drawable getIcon(KeyboardIconsSet iconSet) { return iconSet.getIconDrawable(mIconId); } diff --git a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java index 7d8181dda..a6dcd883d 100644 --- a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java +++ b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java @@ -34,7 +34,7 @@ public class MoreKeysKeyboard extends Keyboard { } public static class Builder extends Keyboard.Builder { - private final String[] mMoreKeys; + private final Key mParentKey; public static class MoreKeysKeyboardParams extends Keyboard.Params { public boolean mIsFixedOrder; @@ -49,28 +49,20 @@ public class MoreKeysKeyboard extends Keyboard { super(); } - /* package for test */MoreKeysKeyboardParams(int numKeys, int maxColumns, int keyWidth, - int rowHeight, int coordXInParent, int parentKeyboardWidth) { - super(); - setParameters(numKeys, maxColumns, keyWidth, rowHeight, coordXInParent, - parentKeyboardWidth); - } - /** * Set keyboard parameters of more keys keyboard. * * @param numKeys number of keys in this more keys keyboard. - * @param maxColumnsAndFlags number of maximum columns of this more keys keyboard. - * This might have {@link Key#MORE_KEYS_FIXED_COLUMN_ORDER} flag. + * @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. */ - public void setParameters(int numKeys, int maxColumnsAndFlags, int keyWidth, - int rowHeight, int coordXInParent, int parentKeyboardWidth) { - mIsFixedOrder = (maxColumnsAndFlags & Key.MORE_KEYS_FIXED_COLUMN_ORDER) != 0; - final int maxColumns = maxColumnsAndFlags & ~Key.MORE_KEYS_FIXED_COLUMN_ORDER; + public void setParameters(int numKeys, int maxColumns, int keyWidth, int rowHeight, + int coordXInParent, int parentKeyboardWidth, boolean isFixedColumnOrder) { + mIsFixedOrder = isFixedColumnOrder; if (parentKeyboardWidth / keyWidth < maxColumns) { throw new IllegalArgumentException( "Keyboard is too small to hold more keys keyboard: " @@ -253,7 +245,7 @@ public class MoreKeysKeyboard extends Keyboard { // TODO: More keys keyboard's vertical gap is currently calculated heuristically. // Should revise the algorithm. mParams.mVerticalGap = parentKeyboard.mVerticalGap / 2; - mMoreKeys = parentKey.mMoreKeys; + mParentKey = parentKey; final int previewWidth = view.mKeyPreviewDrawParams.mPreviewBackgroundWidth; final int previewHeight = view.mKeyPreviewDrawParams.mPreviewBackgroundHeight; @@ -261,20 +253,24 @@ public class MoreKeysKeyboard extends Keyboard { // Use pre-computed width and height if these values are available and more keys // keyboard has only one key to mitigate visual flicker between key preview and more // keys keyboard. - if (view.isKeyPreviewPopupEnabled() && mMoreKeys.length == 1 && previewWidth > 0 - && previewHeight > 0) { + final boolean validKeyPreview = view.isKeyPreviewPopupEnabled() && (previewWidth > 0) + && (previewHeight > 0); + final boolean singleMoreKeyWithPreview = validKeyPreview + && parentKey.mMoreKeys.length == 1; + if (singleMoreKeyWithPreview) { width = previewWidth; height = previewHeight + mParams.mVerticalGap; } else { width = getMaxKeyWidth(view, parentKey.mMoreKeys, mParams.mDefaultKeyWidth); height = parentKeyboard.mMostCommonKeyHeight; } - mParams.setParameters(mMoreKeys.length, parentKey.mMaxMoreKeysColumn, width, height, - parentKey.mX + parentKey.mWidth / 2, view.getMeasuredWidth()); + mParams.setParameters(parentKey.mMoreKeys.length, parentKey.getMoreKeysColumn(), + width, height, parentKey.mX + parentKey.mWidth / 2, view.getMeasuredWidth(), + parentKey.isFixedColumnOrderMoreKeys()); } private static int getMaxKeyWidth(KeyboardView view, String[] moreKeys, int minKeyWidth) { - final int padding = (int) view.getContext().getResources() + final int padding = (int) view.getResources() .getDimension(R.dimen.more_keys_keyboard_key_horizontal_padding); Paint paint = null; int maxWidth = minKeyWidth; @@ -298,8 +294,9 @@ public class MoreKeysKeyboard extends Keyboard { @Override public MoreKeysKeyboard build() { final MoreKeysKeyboardParams params = mParams; - for (int n = 0; n < mMoreKeys.length; n++) { - final String moreKeySpec = mMoreKeys[n]; + final String[] moreKeys = mParentKey.mMoreKeys; + for (int n = 0; n < moreKeys.length; n++) { + final String moreKeySpec = moreKeys[n]; final int row = n / params.mNumColumns; final Key key = new Key(mResources, params, moreKeySpec, params.getX(n, row), params.getY(row), params.mDefaultKeyWidth, params.mDefaultRowHeight); diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java b/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java index f61eefda5..32f5fbc47 100644 --- a/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java +++ b/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java @@ -426,4 +426,28 @@ public class KeySpecParser { return list.toArray(new String[list.size()]); } } + + public static int getIntValue(String[] moreKeys, String key, int defaultValue) { + if (moreKeys == null) { + return defaultValue; + } + boolean foundValue = false; + int value = defaultValue; + for (int i = 0; i < moreKeys.length; i++) { + final String moreKeySpec = moreKeys[i]; + if (moreKeySpec == null || !moreKeySpec.startsWith(key)) { + continue; + } + moreKeys[i] = null; + try { + if (!foundValue) { + value = Integer.parseInt(moreKeySpec.substring(key.length())); + } + } catch (NumberFormatException e) { + throw new RuntimeException( + "integer should follow after " + key + ": " + moreKeySpec); + } + } + return value; + } } diff --git a/tests/src/com/android/inputmethod/keyboard/MoreKeysKeyboardBuilderFixedOrderTests.java b/tests/src/com/android/inputmethod/keyboard/MoreKeysKeyboardBuilderFixedOrderTests.java index c0b3445e0..afd3df40b 100644 --- a/tests/src/com/android/inputmethod/keyboard/MoreKeysKeyboardBuilderFixedOrderTests.java +++ b/tests/src/com/android/inputmethod/keyboard/MoreKeysKeyboardBuilderFixedOrderTests.java @@ -41,10 +41,12 @@ public class MoreKeysKeyboardBuilderFixedOrderTests extends AndroidTestCase { super.setUp(); } - private static MoreKeysKeyboardParams createParams(int numKeys, int fixColumns, + private static MoreKeysKeyboardParams createParams(int numKeys, int columnNum, int coordXInParnet) { - return new MoreKeysKeyboardParams(numKeys, fixColumns | Key.MORE_KEYS_FIXED_COLUMN_ORDER, - WIDTH, HEIGHT, coordXInParnet, KEYBOARD_WIDTH); + final MoreKeysKeyboardParams params = new MoreKeysKeyboardParams(); + params.setParameters(numKeys, columnNum, WIDTH, HEIGHT, coordXInParnet, KEYBOARD_WIDTH, + /* isFixedOrderColumn */true); + return params; } public void testLayoutError() { diff --git a/tests/src/com/android/inputmethod/keyboard/MoreKeysKeyboardBuilderTests.java b/tests/src/com/android/inputmethod/keyboard/MoreKeysKeyboardBuilderTests.java index 90bbf7eff..456247bae 100644 --- a/tests/src/com/android/inputmethod/keyboard/MoreKeysKeyboardBuilderTests.java +++ b/tests/src/com/android/inputmethod/keyboard/MoreKeysKeyboardBuilderTests.java @@ -43,8 +43,10 @@ public class MoreKeysKeyboardBuilderTests extends AndroidTestCase { private static MoreKeysKeyboardParams createParams(int numKeys, int maxColumns, int coordXInParnet) { - return new MoreKeysKeyboardParams(numKeys, maxColumns, WIDTH, HEIGHT, coordXInParnet, - KEYBOARD_WIDTH); + final MoreKeysKeyboardParams params = new MoreKeysKeyboardParams(); + params.setParameters(numKeys, maxColumns, WIDTH, HEIGHT, coordXInParnet, KEYBOARD_WIDTH, + /* isFixedOrderColumn */false); + return params; } public void testLayoutError() {