aboutsummaryrefslogtreecommitdiffstats
path: root/java/src
diff options
context:
space:
mode:
Diffstat (limited to 'java/src')
-rw-r--r--java/src/com/android/inputmethod/keyboard/Key.java33
-rw-r--r--java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java86
-rw-r--r--java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java71
3 files changed, 147 insertions, 43 deletions
diff --git a/java/src/com/android/inputmethod/keyboard/Key.java b/java/src/com/android/inputmethod/keyboard/Key.java
index cf3a437cf..f839376c0 100644
--- a/java/src/com/android/inputmethod/keyboard/Key.java
+++ b/java/src/com/android/inputmethod/keyboard/Key.java
@@ -105,6 +105,9 @@ public class Key {
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!";
/** Background type that represents different key background visual than normal one. */
public final int mBackgroundType;
@@ -232,10 +235,19 @@ public class Key {
mLabelFlags = style.getFlag(keyAttr, R.styleable.Keyboard_Key_keyLabelFlags);
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,
+ R.styleable.Keyboard_Key_maxMoreKeysColumn, params.mMaxMoreKeysKeyboardColumn);
+ }
final String[] additionalMoreKeys = style.getStringArray(
keyAttr, R.styleable.Keyboard_Key_additionalMoreKeys);
- final String[] moreKeys = KeySpecParser.insertAddtionalMoreKeys(style.getStringArray(
- keyAttr, R.styleable.Keyboard_Key_moreKeys), additionalMoreKeys);
+ moreKeys = KeySpecParser.insertAddtionalMoreKeys(moreKeys, additionalMoreKeys);
if (moreKeys != null) {
actionFlags |= ACTION_FLAGS_ENABLE_LONG_PRESS;
for (int i = 0; i < moreKeys.length; i++) {
@@ -245,8 +257,6 @@ public class Key {
}
mActionFlags = actionFlags;
mMoreKeys = moreKeys;
- mMaxMoreKeysColumn = style.getInt(keyAttr,
- R.styleable.Keyboard_Key_maxMoreKeysColumn, params.mMaxMoreKeysKeyboardColumn);
if ((mLabelFlags & LABEL_FLAGS_FROM_CUSTOM_ACTION_LABEL) != 0) {
mLabel = params.mId.mCustomActionLabel;
@@ -301,6 +311,21 @@ 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;
diff --git a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java
index 1597b1ebb..7d8181dda 100644
--- a/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java
+++ b/java/src/com/android/inputmethod/keyboard/MoreKeysKeyboard.java
@@ -37,9 +37,11 @@ public class MoreKeysKeyboard extends Keyboard {
private final String[] mMoreKeys;
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.
@@ -58,14 +60,17 @@ public class MoreKeysKeyboard extends Keyboard {
* 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 maxColumnsAndFlags number of maximum columns of this more keys keyboard.
+ * This might have {@link Key#MORE_KEYS_FIXED_COLUMN_ORDER} flag.
* @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.
*/
- public void setParameters(int numKeys, int maxColumns, int keyWidth, int rowHeight,
- int coordXInParent, int parentKeyboardWidth) {
+ 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;
if (parentKeyboardWidth / keyWidth < maxColumns) {
throw new IllegalArgumentException(
"Keyboard is too small to hold more keys keyboard: "
@@ -76,8 +81,11 @@ public class MoreKeysKeyboard extends Keyboard {
final int numRows = (numKeys + maxColumns - 1) / maxColumns;
mNumRows = numRows;
- final int numColumns = getOptimizedColumns(numKeys, maxColumns);
+ 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.
@@ -110,28 +118,68 @@ public class MoreKeysKeyboard extends Keyboard {
mLeftKeys = leftKeys;
mRightKeys = rightKeys;
- // Centering of the top row.
- if (numRows < 2 || getTopRowEmptySlots(numKeys, numColumns) % 2 == 0) {
- mTopRowAdjustment = 0;
- } else if (mLeftKeys < mRightKeys - 1) {
- mTopRowAdjustment = 1;
- } else {
- mTopRowAdjustment = -1;
- }
-
+ // Adjustment of the top row.
+ mTopRowAdjustment = mIsFixedOrder ? getFixedOrderTopRowAdjustment()
+ : getAutoOrderTopRowAdjustment();
mBaseWidth = mOccupiedWidth = mNumColumns * mDefaultKeyWidth;
// 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;
@@ -146,7 +194,7 @@ public class MoreKeysKeyboard extends Keyboard {
if (i >= col)
break;
// Assign left key if available.
- if (left < mLeftKeys) {
+ if (left < leftKeys) {
left++;
pos = -left;
i++;
@@ -158,12 +206,8 @@ public class MoreKeysKeyboard extends Keyboard {
}
private static int getTopRowEmptySlots(int numKeys, int numColumns) {
- final int remainingKeys = numKeys % numColumns;
- if (remainingKeys == 0) {
- return 0;
- } else {
- return numColumns - remainingKeys;
- }
+ final int remainings = numKeys % numColumns;
+ return remainings == 0 ? 0 : numColumns - remainings;
}
private int getOptimizedColumns(int numKeys, int maxColumns) {
@@ -198,7 +242,7 @@ public class MoreKeysKeyboard extends Keyboard {
}
private boolean isTopRow(int rowCount) {
- return rowCount == mNumRows - 1;
+ return mNumRows > 1 && rowCount == mNumRows - 1;
}
}
diff --git a/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java b/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java
index 1626a140b..f61eefda5 100644
--- a/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java
+++ b/java/src/com/android/inputmethod/keyboard/internal/KeySpecParser.java
@@ -206,9 +206,51 @@ public class KeySpecParser {
return KeyboardIconsSet.ICON_UNDEFINED;
}
- public static String[] insertAddtionalMoreKeys(String[] moreKeys, String[] additionalMoreKeys) {
- final int moreKeysCount = (moreKeys != null) ? moreKeys.length : 0;
- final int additionalCount = (additionalMoreKeys != null) ? additionalMoreKeys.length : 0;
+ private static <T> ArrayList<T> arrayAsList(T[] array, int start, int end) {
+ if (array == null) {
+ throw new NullPointerException();
+ }
+ if (start < 0 || start > end || end > array.length) {
+ throw new IllegalArgumentException();
+ }
+
+ final ArrayList<T> list = new ArrayList<T>(end - start);
+ for (int i = start; i < end; i++) {
+ list.add(array[i]);
+ }
+ return list;
+ }
+
+ private static final String[] EMPTY_STRING_ARRAY = new String[0];
+
+ private static String[] filterOutEmptyString(String[] array) {
+ if (array == null) {
+ return EMPTY_STRING_ARRAY;
+ }
+ ArrayList<String> out = null;
+ for (int i = 0; i < array.length; i++) {
+ final String entry = array[i];
+ if (TextUtils.isEmpty(entry)) {
+ if (out == null) {
+ out = arrayAsList(array, 0, i);
+ }
+ } else if (out != null) {
+ out.add(entry);
+ }
+ }
+ if (out == null) {
+ return array;
+ } else {
+ return out.toArray(new String[out.size()]);
+ }
+ }
+
+ public static String[] insertAddtionalMoreKeys(String[] moreKeySpecs,
+ String[] additionalMoreKeySpecs) {
+ final String[] moreKeys = filterOutEmptyString(moreKeySpecs);
+ final String[] additionalMoreKeys = filterOutEmptyString(additionalMoreKeySpecs);
+ final int moreKeysCount = moreKeys.length;
+ final int additionalCount = additionalMoreKeys.length;
ArrayList<String> out = null;
int additionalIndex = 0;
for (int moreKeyIndex = 0; moreKeyIndex < moreKeysCount; moreKeyIndex++) {
@@ -226,10 +268,7 @@ public class KeySpecParser {
} else {
// Filter out excessive '%' marker.
if (out == null) {
- out = new ArrayList<String>(moreKeyIndex);
- for (int i = 0; i < moreKeyIndex; i++) {
- out.add(moreKeys[i]);
- }
+ out = arrayAsList(moreKeys, 0, moreKeyIndex);
}
}
} else {
@@ -246,10 +285,7 @@ public class KeySpecParser {
+ " moreKeys=" + Arrays.toString(moreKeys)
+ " additionalMoreKeys=" + Arrays.toString(additionalMoreKeys));
}
- out = new ArrayList<String>(additionalCount + moreKeysCount);
- for (int i = additionalIndex; i < additionalCount; i++) {
- out.add(additionalMoreKeys[i]);
- }
+ out = arrayAsList(additionalMoreKeys, additionalIndex, additionalCount);
for (int i = 0; i < moreKeysCount; i++) {
out.add(moreKeys[i]);
}
@@ -261,18 +297,17 @@ public class KeySpecParser {
+ " moreKeys=" + Arrays.toString(moreKeys)
+ " additionalMoreKeys=" + Arrays.toString(additionalMoreKeys));
}
- out = new ArrayList<String>(moreKeysCount);
- for (int i = 0; i < moreKeysCount; i++) {
- out.add(moreKeys[i]);
- }
+ out = arrayAsList(moreKeys, 0, moreKeysCount);
for (int i = additionalIndex; i < additionalCount; i++) {
out.add(additionalMoreKeys[additionalIndex]);
}
}
- if (out != null) {
- return out.size() > 0 ? out.toArray(new String[out.size()]) : null;
- } else {
+ if (out == null && moreKeysCount > 0) {
return moreKeys;
+ } else if (out != null && out.size() > 0) {
+ return out.toArray(new String[out.size()]);
+ } else {
+ return null;
}
}